compositor: Keep a z-ordered list of planes
authorAnder Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Tue, 5 Mar 2013 15:30:27 +0000 (17:30 +0200)
committerKristian Høgsberg <krh@bitplanet.net>
Tue, 19 Mar 2013 01:13:45 +0000 (21:13 -0400)
This let us clear a plane's opaque region without adding code in the
backend, and will be used in a following commit to change how we track
damage.

src/compositor-drm.c
src/compositor.c
src/compositor.h

index 3e93162..fa21495 100644 (file)
@@ -920,26 +920,10 @@ drm_assign_planes(struct weston_output *output)
 {
        struct drm_compositor *c =
                (struct drm_compositor *) output->compositor;
-       struct drm_output *drm_output = (struct drm_output *) output;
-       struct drm_sprite *s;
        struct weston_surface *es, *next;
        pixman_region32_t overlap, surface_overlap;
        struct weston_plane *primary, *next_plane;
 
-       /* Reset the opaque region of the planes */
-       pixman_region32_fini(&drm_output->cursor_plane.opaque);
-       pixman_region32_init(&drm_output->cursor_plane.opaque);
-       pixman_region32_fini(&drm_output->fb_plane.opaque);
-       pixman_region32_init(&drm_output->fb_plane.opaque);
-
-       wl_list_for_each (s, &c->sprite_list, link) {
-               if (!drm_sprite_crtc_supported(output, s->possible_crtcs))
-                       continue;
-
-               pixman_region32_fini(&s->plane.opaque);
-               pixman_region32_init(&s->plane.opaque);
-       }
-
        /*
         * Find a surface for each sprite in the output using some heuristics:
         * 1) size
@@ -1643,6 +1627,10 @@ create_output_for_connector(struct drm_compositor *ec,
        weston_plane_init(&output->cursor_plane, 0, 0);
        weston_plane_init(&output->fb_plane, 0, 0);
 
+       weston_compositor_stack_plane(&ec->base, &output->cursor_plane, NULL);
+       weston_compositor_stack_plane(&ec->base, &output->fb_plane,
+                                     &ec->base.primary_plane);
+
        weston_log("Output %s, (connector %d, crtc %d)\n",
                   output->name, output->connector_id, output->crtc_id);
        wl_list_for_each(m, &output->base.mode_list, link)
@@ -1716,6 +1704,8 @@ create_sprites(struct drm_compositor *ec)
                       plane->count_formats * sizeof(plane->formats[0]));
                drmModeFreePlane(plane);
                weston_plane_init(&sprite->plane, 0, 0);
+               weston_compositor_stack_plane(&ec->base, &sprite->plane,
+                                             &ec->base.primary_plane);
 
                wl_list_insert(&ec->sprite_list, &sprite->link);
        }
index a2860fd..50d782e 100644 (file)
@@ -1097,6 +1097,38 @@ surface_accumulate_damage(struct weston_surface *surface,
 }
 
 static void
+compositor_accumulate_damage(struct weston_compositor *ec)
+{
+       struct weston_plane *plane;
+       struct weston_surface *es;
+       pixman_region32_t opaque;
+
+       pixman_region32_init(&opaque);
+
+       wl_list_for_each(plane, &ec->plane_list, link) {
+               pixman_region32_fini(&plane->opaque);
+               pixman_region32_init(&plane->opaque);
+       }
+
+       wl_list_for_each(es, &ec->surface_list, link) {
+               surface_accumulate_damage(es, &opaque);
+
+               /* Both the renderer and the backend have seen the buffer
+                * by now. If renderer needs the buffer, it has its own
+                * reference set. If the backend wants to keep the buffer
+                * around for migrating the surface into a non-primary plane
+                * later, keep_buffer is true. Otherwise, drop the core
+                * reference now, and allow early buffer release. This enables
+                * clients to use single-buffering.
+                */
+               if (!es->keep_buffer)
+                       weston_buffer_reference(&es->buffer_ref, NULL);
+       }
+
+       pixman_region32_fini(&opaque);
+}
+
+static void
 weston_output_repaint(struct weston_output *output, uint32_t msecs)
 {
        struct weston_compositor *ec = output->compositor;
@@ -1105,7 +1137,7 @@ weston_output_repaint(struct weston_output *output, uint32_t msecs)
        struct weston_animation *animation, *next;
        struct weston_frame_callback *cb, *cnext;
        struct wl_list frame_callback_list;
-       pixman_region32_t opaque, output_damage;
+       pixman_region32_t output_damage;
 
        weston_compositor_update_drag_surfaces(ec);
 
@@ -1130,27 +1162,7 @@ weston_output_repaint(struct weston_output *output, uint32_t msecs)
                wl_list_for_each(es, &ec->surface_list, link)
                        weston_surface_move_to_plane(es, &ec->primary_plane);
 
-       pixman_region32_init(&opaque);
-
-       pixman_region32_fini(&ec->primary_plane.opaque);
-       pixman_region32_init(&ec->primary_plane.opaque);
-
-       wl_list_for_each(es, &ec->surface_list, link) {
-               surface_accumulate_damage(es, &opaque);
-
-               /* Both the renderer and the backend have seen the buffer
-                * by now. If renderer needs the buffer, it has its own
-                * reference set. If the backend wants to keep the buffer
-                * around for migrating the surface into a non-primary plane
-                * later, keep_buffer is true. Otherwise, drop the core
-                * reference now, and allow early buffer release. This enables
-                * clients to use single-buffering.
-                */
-               if (!es->keep_buffer)
-                       weston_buffer_reference(&es->buffer_ref, NULL);
-       }
-
-       pixman_region32_fini(&opaque);
+       compositor_accumulate_damage(ec);
 
        pixman_region32_init(&output_damage);
        pixman_region32_intersect(&output_damage,
@@ -1672,6 +1684,17 @@ weston_plane_release(struct weston_plane *plane)
        pixman_region32_fini(&plane->opaque);
 }
 
+WL_EXPORT void
+weston_compositor_stack_plane(struct weston_compositor *ec,
+                             struct weston_plane *plane,
+                             struct weston_plane *above)
+{
+       if (above)
+               wl_list_insert(above->link.prev, &plane->link);
+       else
+               wl_list_insert(&ec->plane_list, &plane->link);
+}
+
 static  void
 weston_seat_update_drag_surface(struct weston_seat *seat, int dx, int dy);
 
@@ -3059,6 +3082,7 @@ weston_compositor_init(struct weston_compositor *ec,
                return -1;
 
        wl_list_init(&ec->surface_list);
+       wl_list_init(&ec->plane_list);
        wl_list_init(&ec->layer_list);
        wl_list_init(&ec->seat_list);
        wl_list_init(&ec->output_list);
@@ -3068,6 +3092,7 @@ weston_compositor_init(struct weston_compositor *ec,
        wl_list_init(&ec->debug_binding_list);
 
        weston_plane_init(&ec->primary_plane, 0, 0);
+       weston_compositor_stack_plane(ec, &ec->primary_plane, NULL);
 
        if (weston_compositor_xkb_init(ec, &xkb_names) < 0)
                return -1;
index 4a0c1e3..89f0639 100644 (file)
@@ -269,6 +269,7 @@ struct weston_plane {
        pixman_region32_t damage;
        pixman_region32_t opaque;
        int32_t x, y;
+       struct wl_list link;
 };
 
 struct weston_renderer {
@@ -314,6 +315,7 @@ struct weston_compositor {
        struct wl_list seat_list;
        struct wl_list layer_list;
        struct wl_list surface_list;
+       struct wl_list plane_list;
        struct wl_list key_binding_list;
        struct wl_list button_binding_list;
        struct wl_list axis_binding_list;
@@ -577,6 +579,11 @@ void
 weston_plane_release(struct weston_plane *plane);
 
 void
+weston_compositor_stack_plane(struct weston_compositor *ec,
+                             struct weston_plane *plane,
+                             struct weston_plane *above);
+
+void
 weston_output_finish_frame(struct weston_output *output, uint32_t msecs);
 void
 weston_output_schedule_repaint(struct weston_output *output);