From 6ddcdaeb983edb3b952e32909d27458e28bdedb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 28 Feb 2012 22:31:58 -0500 Subject: [PATCH] compositor: Store opaque clip for previous frame in weston_surface --- src/compositor-drm.c | 5 +++-- src/compositor-wayland.c | 5 +++-- src/compositor-x11.c | 5 +++-- src/compositor.c | 48 ++++++++++++++++++++-------------------- src/compositor.h | 9 +++++--- 5 files changed, 39 insertions(+), 33 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index cfaad15d..d2a5652b 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -214,7 +214,8 @@ drm_output_prepare_scanout_surface(struct drm_output *output) } static void -drm_output_repaint(struct weston_output *output_base) +drm_output_repaint(struct weston_output *output_base, + pixman_region32_t *damage) { struct drm_output *output = (struct drm_output *) output_base; struct drm_compositor *compositor = @@ -235,7 +236,7 @@ drm_output_repaint(struct weston_output *output_base) drm_output_prepare_scanout_surface(output); wl_list_for_each_reverse(surface, &compositor->base.surface_list, link) - weston_surface_draw(surface, &output->base); + weston_surface_draw(surface, &output->base, damage); glFlush(); diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c index f8b5a32c..f23c357c 100644 --- a/src/compositor-wayland.c +++ b/src/compositor-wayland.c @@ -329,7 +329,8 @@ static const struct wl_callback_listener frame_listener = { }; static void -wayland_output_repaint(struct weston_output *output_base) +wayland_output_repaint(struct weston_output *output_base, + pixman_region32_t *damage) { struct wayland_output *output = (struct wayland_output *) output_base; struct wayland_compositor *compositor = @@ -344,7 +345,7 @@ wayland_output_repaint(struct weston_output *output_base) } wl_list_for_each_reverse(surface, &compositor->base.surface_list, link) - weston_surface_draw(surface, &output->base); + weston_surface_draw(surface, &output->base, damage); draw_border(output); diff --git a/src/compositor-x11.c b/src/compositor-x11.c index 53998d24..c227063b 100644 --- a/src/compositor-x11.c +++ b/src/compositor-x11.c @@ -186,7 +186,8 @@ x11_compositor_fini_egl(struct x11_compositor *compositor) } static void -x11_output_repaint(struct weston_output *output_base) +x11_output_repaint(struct weston_output *output_base, + pixman_region32_t *damage) { struct x11_output *output = (struct x11_output *)output_base; struct x11_compositor *compositor = @@ -200,7 +201,7 @@ x11_output_repaint(struct weston_output *output_base) } wl_list_for_each_reverse(surface, &compositor->base.surface_list, link) - weston_surface_draw(surface, &output->base); + weston_surface_draw(surface, &output->base, damage); eglSwapBuffers(compositor->base.display, output->egl_surface); diff --git a/src/compositor.c b/src/compositor.c index 069ea74d..434c4931 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -225,6 +225,7 @@ weston_surface_create(struct weston_compositor *compositor) pixman_region32_init(&surface->damage); pixman_region32_init(&surface->opaque); + pixman_region32_init(&surface->clip); undef_region(&surface->input); pixman_region32_init(&surface->transform.opaque); wl_list_init(&surface->frame_callback_list); @@ -647,6 +648,7 @@ destroy_surface(struct wl_resource *resource) pixman_region32_fini(&surface->transform.boundingbox); pixman_region32_fini(&surface->damage); pixman_region32_fini(&surface->opaque); + pixman_region32_fini(&surface->clip); if (!region_is_undefined(&surface->input)) pixman_region32_fini(&surface->input); @@ -762,7 +764,8 @@ texture_region(struct weston_surface *es, pixman_region32_t *region) } WL_EXPORT void -weston_surface_draw(struct weston_surface *es, struct weston_output *output) +weston_surface_draw(struct weston_surface *es, struct weston_output *output, + pixman_region32_t *damage) { struct weston_compositor *ec = es->compositor; GLfloat *v; @@ -771,12 +774,9 @@ weston_surface_draw(struct weston_surface *es, struct weston_output *output) int n; pixman_region32_init(&repaint); - pixman_region32_intersect(&repaint, &es->transform.boundingbox, - &output->region); - pixman_region32_intersect(&repaint, &repaint, &es->damage); - - /* Clear damage, assume outputs do not overlap. */ - pixman_region32_subtract(&es->damage, &es->damage, &output->region); + pixman_region32_intersect(&repaint, + &es->transform.boundingbox, damage); + pixman_region32_subtract(&repaint, &repaint, &es->clip); if (!pixman_region32_not_empty(&repaint)) goto out; @@ -937,7 +937,7 @@ weston_output_repaint(struct weston_output *output, int msecs) struct weston_surface *es; struct weston_animation *animation, *next; struct weston_frame_callback *cb, *cnext; - pixman_region32_t opaque, new_damage, total_damage; + pixman_region32_t opaque, new_damage, output_damage; int32_t width, height; weston_compositor_update_drag_surfaces(ec); @@ -948,9 +948,6 @@ weston_output_repaint(struct weston_output *output, int msecs) output->border.top + output->border.bottom; glViewport(0, 0, width, height); - pixman_region32_init(&new_damage); - pixman_region32_init(&opaque); - wl_list_for_each(es, &ec->surface_list, link) /* Update surface transform now to avoid calling it ever * again from the repaint sub-functions. */ @@ -965,33 +962,36 @@ weston_output_repaint(struct weston_output *output, int msecs) */ output->assign_planes(output); + pixman_region32_init(&new_damage); + pixman_region32_init(&opaque); + wl_list_for_each(es, &ec->surface_list, link) { pixman_region32_subtract(&es->damage, &es->damage, &opaque); pixman_region32_union(&new_damage, &new_damage, &es->damage); + empty_region(&es->damage); + pixman_region32_copy(&es->clip, &opaque); pixman_region32_union(&opaque, &opaque, &es->transform.opaque); } - pixman_region32_init(&total_damage); - pixman_region32_union(&total_damage, &new_damage, - &output->previous_damage); - pixman_region32_intersect(&output->previous_damage, - &new_damage, &output->region); + pixman_region32_union(&ec->damage, &ec->damage, &new_damage); + + pixman_region32_init(&output_damage); + pixman_region32_union(&output_damage, + &ec->damage, &output->previous_damage); + pixman_region32_copy(&output->previous_damage, &ec->damage); + pixman_region32_intersect(&output_damage, + &output_damage, &output->region); + pixman_region32_subtract(&ec->damage, &ec->damage, &output->region); pixman_region32_fini(&opaque); pixman_region32_fini(&new_damage); - wl_list_for_each(es, &ec->surface_list, link) { - pixman_region32_copy(&es->damage, &total_damage); - pixman_region32_subtract(&total_damage, - &total_damage, &es->transform.opaque); - } - if (output->dirty) weston_output_update_matrix(output); - output->repaint(output); + output->repaint(output, &output_damage); - pixman_region32_fini(&total_damage); + pixman_region32_fini(&output_damage); output->repaint_needed = 0; diff --git a/src/compositor.h b/src/compositor.h index 8c57e4f4..9f29c4b5 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -91,7 +91,8 @@ struct weston_output { struct weston_mode *current; struct wl_list mode_list; - void (*repaint)(struct weston_output *output); + void (*repaint)(struct weston_output *output, + pixman_region32_t *damage); void (*destroy)(struct weston_output *output); void (*assign_planes)(struct weston_output *output); @@ -198,8 +199,8 @@ struct weston_compositor { int idle_time; /* effective timeout, s */ /* Repaint state. */ - struct timespec previous_swap; struct wl_array vertices, indices; + pixman_region32_t damage; uint32_t focus; @@ -260,6 +261,7 @@ struct weston_surface { struct wl_surface surface; struct weston_compositor *compositor; GLuint texture; + pixman_region32_t clip; pixman_region32_t damage; pixman_region32_t opaque; pixman_region32_t input; @@ -341,7 +343,8 @@ void weston_surface_activate(struct weston_surface *surface, struct weston_input_device *device, uint32_t time); void -weston_surface_draw(struct weston_surface *es, struct weston_output *output); +weston_surface_draw(struct weston_surface *es, + struct weston_output *output, pixman_region32_t *damage); void notify_motion(struct wl_input_device *device,