compositor-x11: Only repaint the damaged region

Set a clip on the GC when painting the damaged region so that
we don't copy the entire shadow buffer each time.
Alexander Larsson 12 years ago committed by Kristian Høgsberg
parent 4ea9552d05
commit 80f9163ad6
  1. 106
      src/compositor-x11.c

@ -354,6 +354,111 @@ x11_output_repaint_gl(struct weston_output *output_base,
wl_event_source_timer_update(output->finish_frame_timer, 10);
}
static void
set_clip_for_output(struct weston_output *output_base, pixman_region32_t *region)
{
struct x11_output *output = (struct x11_output *)output_base;
struct weston_compositor *ec = output->base.compositor;
struct x11_compositor *c = (struct x11_compositor *)ec;
pixman_box32_t *rects;
xcb_rectangle_t *output_rects;
pixman_box32_t rect, transformed_rect;
xcb_void_cookie_t cookie;
int width, height, nrects, i;
xcb_generic_error_t *err;
rects = pixman_region32_rectangles(region, &nrects);
output_rects = calloc(nrects, sizeof(xcb_rectangle_t));
if (output_rects == NULL)
return;
width = output_base->width;
height = output_base->height;
for (i = 0; i < nrects; i++) {
rect = rects[i];
rect.x1 -= output_base->x;
rect.y1 -= output_base->y;
rect.x2 -= output_base->x;
rect.y2 -= output_base->y;
switch (output_base->transform) {
default:
case WL_OUTPUT_TRANSFORM_NORMAL:
transformed_rect.x1 = rect.x1;
transformed_rect.y1 = rect.y1;
transformed_rect.x2 = rect.x2;
transformed_rect.y2 = rect.y2;
break;
case WL_OUTPUT_TRANSFORM_90:
transformed_rect.x1 = height - rect.y2;
transformed_rect.y1 = rect.x1;
transformed_rect.x2 = height - rect.y1;
transformed_rect.y2 = rect.x2;
break;
case WL_OUTPUT_TRANSFORM_180:
transformed_rect.x1 = width - rect.x2;
transformed_rect.y1 = height - rect.y2;
transformed_rect.x2 = width - rect.x1;
transformed_rect.y2 = height - rect.y1;
break;
case WL_OUTPUT_TRANSFORM_270:
transformed_rect.x1 = rect.y1;
transformed_rect.y1 = width - rect.x2;
transformed_rect.x2 = rect.y2;
transformed_rect.y2 = width - rect.x1;
break;
case WL_OUTPUT_TRANSFORM_FLIPPED:
transformed_rect.x1 = width - rect.x2;
transformed_rect.y1 = rect.y1;
transformed_rect.x2 = width - rect.x1;
transformed_rect.y2 = rect.y2;
break;
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
transformed_rect.x1 = height - rect.y2;
transformed_rect.y1 = width - rect.x2;
transformed_rect.x2 = height - rect.y1;
transformed_rect.y2 = width - rect.x1;
break;
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
transformed_rect.x1 = rect.x1;
transformed_rect.y1 = height - rect.y2;
transformed_rect.x2 = rect.x2;
transformed_rect.y2 = height - rect.y1;
break;
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
transformed_rect.x1 = rect.y1;
transformed_rect.y1 = rect.x1;
transformed_rect.x2 = rect.y2;
transformed_rect.y2 = rect.x2;
break;
}
transformed_rect.x1 *= output_base->scale;
transformed_rect.y1 *= output_base->scale;
transformed_rect.x2 *= output_base->scale;
transformed_rect.y2 *= output_base->scale;
output_rects[i].x = transformed_rect.x1;
output_rects[i].y = transformed_rect.y1;
output_rects[i].width = transformed_rect.x2 - transformed_rect.x1;
output_rects[i].height = transformed_rect.y2 - transformed_rect.y1;
}
cookie = xcb_set_clip_rectangles_checked(c->conn, XCB_CLIP_ORDERING_UNSORTED,
output->gc,
0, 0, nrects,
output_rects);
err = xcb_request_check(c->conn, cookie);
if (err != NULL) {
weston_log("Failed to set clip rects, err: %d\n", err->error_code);
free(err);
}
free(output_rects);
}
static void
x11_output_repaint_shm(struct weston_output *output_base,
pixman_region32_t *damage)
@ -369,6 +474,7 @@ x11_output_repaint_shm(struct weston_output *output_base,
pixman_region32_subtract(&ec->primary_plane.damage,
&ec->primary_plane.damage, damage);
set_clip_for_output(output_base, damage);
cookie = xcb_shm_put_image_checked(c->conn, output->window, output->gc,
pixman_image_get_width(output->hw_surface),
pixman_image_get_height(output->hw_surface),

Loading…
Cancel
Save