compositor: Store opaque clip for previous frame in weston_surface
authorKristian Høgsberg <krh@bitplanet.net>
Wed, 29 Feb 2012 03:31:58 +0000 (22:31 -0500)
committerKristian Høgsberg <krh@bitplanet.net>
Thu, 1 Mar 2012 17:47:23 +0000 (12:47 -0500)
src/compositor-drm.c
src/compositor-wayland.c
src/compositor-x11.c
src/compositor.c
src/compositor.h

index cfaad15..d2a5652 100644 (file)
@@ -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();
 
index f8b5a32..f23c357 100644 (file)
@@ -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);
 
index 53998d2..c227063 100644 (file)
@@ -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);
 
index 069ea74..434c493 100644 (file)
@@ -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;
 
index 8c57e4f..9f29c4b 100644 (file)
@@ -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,