From 8ad198285493f2c7f68b8472cd04d739ccc79a25 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 5 Mar 2013 17:30:27 +0200 Subject: [PATCH] compositor: Keep a z-ordered list of planes 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 | 22 ++++---------- src/compositor.c | 69 ++++++++++++++++++++++++++++++-------------- src/compositor.h | 7 +++++ 3 files changed, 60 insertions(+), 38 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 3e93162e..fa21495c 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -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); } diff --git a/src/compositor.c b/src/compositor.c index a2860fd0..50d782e1 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -1096,6 +1096,38 @@ surface_accumulate_damage(struct weston_surface *surface, pixman_region32_union(opaque, opaque, &surface->transform.opaque); } +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) { @@ -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; diff --git a/src/compositor.h b/src/compositor.h index 4a0c1e3b..89f0639c 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -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; @@ -576,6 +578,11 @@ weston_plane_init(struct weston_plane *plane, int32_t x, int32_t y); 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