From 7b9820766735f3b5184e9795d7945dcdd784a827 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Tue, 20 May 2014 14:33:03 -0500 Subject: [PATCH] Create a weston_surface_state structure for storing pending surface state and move the surface commit logic into weston_surface_commit_state This new structure is used for both weston_surface.pending and weston_subsurface.cached. Signed-off-by: Jason Ekstrand Reviewed-by: Pekka Paalanen --- src/compositor.c | 265 +++++++++++++++++++++++-------------------------------- src/compositor.h | 80 +++++++---------- 2 files changed, 141 insertions(+), 204 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index a882431..17fce8d 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -320,16 +320,6 @@ weston_client_launch(struct weston_compositor *compositor, } static void -surface_handle_pending_buffer_destroy(struct wl_listener *listener, void *data) -{ - struct weston_surface *surface = - container_of(listener, struct weston_surface, - pending.buffer_destroy_listener); - - surface->pending.buffer = NULL; -} - -static void region_init_infinite(pixman_region32_t *region) { pixman_region32_init_rect(region, INT32_MIN, INT32_MIN, @@ -382,6 +372,72 @@ struct weston_frame_callback { struct wl_list link; }; +static void +surface_state_handle_buffer_destroy(struct wl_listener *listener, void *data) +{ + struct weston_surface_state *state = + container_of(listener, struct weston_surface_state, + buffer_destroy_listener); + + state->buffer = NULL; +} + +static void +weston_surface_state_init(struct weston_surface_state *state) +{ + state->newly_attached = 0; + state->buffer = NULL; + state->buffer_destroy_listener.notify = + surface_state_handle_buffer_destroy; + state->sx = 0; + state->sy = 0; + + pixman_region32_init(&state->damage); + pixman_region32_init(&state->opaque); + region_init_infinite(&state->input); + + wl_list_init(&state->frame_callback_list); + + state->buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL; + state->buffer_viewport.buffer.scale = 1; + state->buffer_viewport.buffer.src_width = wl_fixed_from_int(-1); + state->buffer_viewport.surface.width = -1; + state->buffer_viewport.changed = 0; +} + +static void +weston_surface_state_fini(struct weston_surface_state *state) +{ + struct weston_frame_callback *cb, *next; + + wl_list_for_each_safe(cb, next, + &state->frame_callback_list, link) + wl_resource_destroy(cb->resource); + + pixman_region32_fini(&state->input); + pixman_region32_fini(&state->opaque); + pixman_region32_fini(&state->damage); + + if (state->buffer) + wl_list_remove(&state->buffer_destroy_listener.link); + state->buffer = NULL; +} + +static void +weston_surface_state_set_buffer(struct weston_surface_state *state, + struct weston_buffer *buffer) +{ + if (state->buffer == buffer) + return; + + if (state->buffer) + wl_list_remove(&state->buffer_destroy_listener.link); + state->buffer = buffer; + if (state->buffer) + wl_signal_add(&state->buffer->destroy_signal, + &state->buffer_destroy_listener); +} + WL_EXPORT struct weston_surface * weston_surface_create(struct weston_compositor *compositor) { @@ -402,10 +458,10 @@ weston_surface_create(struct weston_compositor *compositor) surface->buffer_viewport.buffer.scale = 1; surface->buffer_viewport.buffer.src_width = wl_fixed_from_int(-1); surface->buffer_viewport.surface.width = -1; - surface->pending.buffer_viewport.changed = 0; - surface->pending.buffer_viewport = surface->buffer_viewport; + + weston_surface_state_init(&surface->pending); + surface->output = NULL; - surface->pending.newly_attached = 0; surface->viewport_resource = NULL; @@ -417,13 +473,6 @@ weston_surface_create(struct weston_compositor *compositor) wl_list_init(&surface->frame_callback_list); - surface->pending.buffer_destroy_listener.notify = - surface_handle_pending_buffer_destroy; - pixman_region32_init(&surface->pending.damage); - pixman_region32_init(&surface->pending.opaque); - region_init_infinite(&surface->pending.input); - wl_list_init(&surface->pending.frame_callback_list); - wl_list_init(&surface->subsurface_list); wl_list_init(&surface->subsurface_list_pending); @@ -1353,9 +1402,7 @@ weston_surface_unmap(struct weston_surface *surface) static void weston_surface_reset_pending_buffer(struct weston_surface *surface) { - if (surface->pending.buffer) - wl_list_remove(&surface->pending.buffer_destroy_listener.link); - surface->pending.buffer = NULL; + weston_surface_state_set_buffer(&surface->pending, NULL); surface->pending.sx = 0; surface->pending.sy = 0; surface->pending.newly_attached = 0; @@ -1404,16 +1451,7 @@ weston_surface_destroy(struct weston_surface *surface) wl_list_for_each_safe(ev, nv, &surface->views, surface_link) weston_view_destroy(ev); - wl_list_for_each_safe(cb, next, - &surface->pending.frame_callback_list, link) - wl_resource_destroy(cb->resource); - - pixman_region32_fini(&surface->pending.input); - pixman_region32_fini(&surface->pending.opaque); - pixman_region32_fini(&surface->pending.damage); - - if (surface->pending.buffer) - wl_list_remove(&surface->pending.buffer_destroy_listener.link); + weston_surface_state_fini(&surface->pending); weston_buffer_reference(&surface->buffer_ref, NULL); @@ -1939,17 +1977,11 @@ surface_attach(struct wl_client *client, /* Attach, attach, without commit in between does not send * wl_buffer.release. */ - if (surface->pending.buffer) - wl_list_remove(&surface->pending.buffer_destroy_listener.link); + weston_surface_state_set_buffer(&surface->pending, buffer); surface->pending.sx = sx; surface->pending.sy = sy; - surface->pending.buffer = buffer; surface->pending.newly_attached = 1; - if (buffer) { - wl_signal_add(&buffer->destroy_signal, - &surface->pending.buffer_destroy_listener); - } } static void @@ -2048,7 +2080,8 @@ weston_surface_commit_subsurface_order(struct weston_surface *surface) } static void -weston_surface_commit(struct weston_surface *surface) +weston_surface_commit_state(struct weston_surface *surface, + struct weston_surface_state *state) { struct weston_view *view; pixman_region32_t opaque; @@ -2056,35 +2089,35 @@ weston_surface_commit(struct weston_surface *surface) /* wl_surface.set_buffer_transform */ /* wl_surface.set_buffer_scale */ /* wl_viewport.set */ - surface->buffer_viewport = surface->pending.buffer_viewport; + surface->buffer_viewport = state->buffer_viewport; /* wl_surface.attach */ - if (surface->pending.newly_attached) - weston_surface_attach(surface, surface->pending.buffer); + if (state->newly_attached) + weston_surface_attach(surface, state->buffer); + weston_surface_state_set_buffer(state, NULL); - if (surface->pending.newly_attached || - surface->pending.buffer_viewport.changed) { + if (state->newly_attached || state->buffer_viewport.changed) { weston_surface_update_size(surface); if (surface->configure) - surface->configure(surface, surface->pending.sx, - surface->pending.sy); + surface->configure(surface, state->sx, state->sy); } - weston_surface_reset_pending_buffer(surface); + state->sx = 0; + state->sy = 0; + state->newly_attached = 0; + state->buffer_viewport.changed = 0; /* wl_surface.damage */ pixman_region32_union(&surface->damage, &surface->damage, - &surface->pending.damage); + &state->damage); pixman_region32_intersect_rect(&surface->damage, &surface->damage, 0, 0, surface->width, surface->height); pixman_region32_clear(&surface->pending.damage); /* wl_surface.set_opaque_region */ - pixman_region32_init_rect(&opaque, 0, 0, - surface->width, - surface->height); - pixman_region32_intersect(&opaque, - &opaque, &surface->pending.opaque); + pixman_region32_init(&opaque); + pixman_region32_intersect_rect(&opaque, &state->opaque, + 0, 0, surface->width, surface->height); if (!pixman_region32_equal(&opaque, &surface->opaque)) { pixman_region32_copy(&surface->opaque, &opaque); @@ -2095,17 +2128,19 @@ weston_surface_commit(struct weston_surface *surface) pixman_region32_fini(&opaque); /* wl_surface.set_input_region */ - pixman_region32_fini(&surface->input); - pixman_region32_init_rect(&surface->input, 0, 0, - surface->width, - surface->height); - pixman_region32_intersect(&surface->input, - &surface->input, &surface->pending.input); + pixman_region32_intersect_rect(&surface->input, &state->input, + 0, 0, surface->width, surface->height); /* wl_surface.frame */ wl_list_insert_list(&surface->frame_callback_list, - &surface->pending.frame_callback_list); - wl_list_init(&surface->pending.frame_callback_list); + &state->frame_callback_list); + wl_list_init(&state->frame_callback_list); +} + +static void +weston_surface_commit(struct weston_surface *surface) +{ + weston_surface_commit_state(surface, &surface->pending); weston_surface_commit_subsurface_order(surface); @@ -2293,73 +2328,15 @@ static void weston_subsurface_commit_from_cache(struct weston_subsurface *sub) { struct weston_surface *surface = sub->surface; - struct weston_view *view; - pixman_region32_t opaque; - - /* wl_surface.set_buffer_transform */ - /* wl_surface.set_buffer_scale */ - /* wl_viewport.set */ - surface->buffer_viewport = sub->cached.buffer_viewport; - - /* wl_surface.attach */ - if (sub->cached.newly_attached) - weston_surface_attach(surface, sub->cached.buffer_ref.buffer); - weston_buffer_reference(&sub->cached.buffer_ref, NULL); - - if (sub->cached.newly_attached || sub->cached.buffer_viewport.changed) { - weston_surface_update_size(surface); - if (surface->configure) - surface->configure(surface, sub->cached.sx, - sub->cached.sy); - } - sub->cached.sx = 0; - sub->cached.sy = 0; - sub->cached.newly_attached = 0; - sub->cached.buffer_viewport.changed = 0; - - /* wl_surface.damage */ - pixman_region32_union(&surface->damage, &surface->damage, - &sub->cached.damage); - pixman_region32_intersect_rect(&surface->damage, &surface->damage, - 0, 0, - surface->width, - surface->height); - pixman_region32_clear(&sub->cached.damage); - - /* wl_surface.set_opaque_region */ - pixman_region32_init_rect(&opaque, 0, 0, - surface->width, - surface->height); - pixman_region32_intersect(&opaque, - &opaque, &sub->cached.opaque); - - if (!pixman_region32_equal(&opaque, &surface->opaque)) { - pixman_region32_copy(&surface->opaque, &opaque); - wl_list_for_each(view, &surface->views, surface_link) - weston_view_geometry_dirty(view); - } - - pixman_region32_fini(&opaque); - - /* wl_surface.set_input_region */ - pixman_region32_fini(&surface->input); - pixman_region32_init_rect(&surface->input, 0, 0, - surface->width, - surface->height); - pixman_region32_intersect(&surface->input, - &surface->input, &sub->cached.input); - - /* wl_surface.frame */ - wl_list_insert_list(&surface->frame_callback_list, - &sub->cached.frame_callback_list); - wl_list_init(&sub->cached.frame_callback_list); + weston_surface_commit_state(surface, &sub->cached); + weston_buffer_reference(&sub->cached_buffer_ref, NULL); weston_surface_commit_subsurface_order(surface); weston_surface_schedule_repaint(surface); - sub->cached.has_data = 0; + sub->has_cached_data = 0; } static void @@ -2381,7 +2358,9 @@ weston_subsurface_commit_to_cache(struct weston_subsurface *sub) if (surface->pending.newly_attached) { sub->cached.newly_attached = 1; - weston_buffer_reference(&sub->cached.buffer_ref, + weston_surface_state_set_buffer(&sub->cached, + surface->pending.buffer); + weston_buffer_reference(&sub->cached_buffer_ref, surface->pending.buffer); } sub->cached.sx += surface->pending.sx; @@ -2404,7 +2383,7 @@ weston_subsurface_commit_to_cache(struct weston_subsurface *sub) &surface->pending.frame_callback_list); wl_list_init(&surface->pending.frame_callback_list); - sub->cached.has_data = 1; + sub->has_cached_data = 1; } static int @@ -2433,7 +2412,7 @@ weston_subsurface_commit(struct weston_subsurface *sub) if (weston_subsurface_is_synchronized(sub)) { weston_subsurface_commit_to_cache(sub); } else { - if (sub->cached.has_data) { + if (sub->has_cached_data) { /* flush accumulated state from cache */ weston_subsurface_commit_to_cache(sub); weston_subsurface_commit_from_cache(sub); @@ -2460,7 +2439,7 @@ weston_subsurface_synchronized_commit(struct weston_subsurface *sub) * all the way down. */ - if (sub->cached.has_data) + if (sub->has_cached_data) weston_subsurface_commit_from_cache(sub); wl_list_for_each(tmp, &surface->subsurface_list, parent_link) { @@ -2666,30 +2645,6 @@ subsurface_set_desync(struct wl_client *client, struct wl_resource *resource) } static void -weston_subsurface_cache_init(struct weston_subsurface *sub) -{ - pixman_region32_init(&sub->cached.damage); - pixman_region32_init(&sub->cached.opaque); - pixman_region32_init(&sub->cached.input); - wl_list_init(&sub->cached.frame_callback_list); - sub->cached.buffer_ref.buffer = NULL; -} - -static void -weston_subsurface_cache_fini(struct weston_subsurface *sub) -{ - struct weston_frame_callback *cb, *tmp; - - wl_list_for_each_safe(cb, tmp, &sub->cached.frame_callback_list, link) - wl_resource_destroy(cb->resource); - - weston_buffer_reference(&sub->cached.buffer_ref, NULL); - pixman_region32_fini(&sub->cached.damage); - pixman_region32_fini(&sub->cached.opaque); - pixman_region32_fini(&sub->cached.input); -} - -static void weston_subsurface_unlink_parent(struct weston_subsurface *sub) { wl_list_remove(&sub->parent_link); @@ -2791,7 +2746,8 @@ weston_subsurface_destroy(struct weston_subsurface *sub) if (sub->parent) weston_subsurface_unlink_parent(sub); - weston_subsurface_cache_fini(sub); + weston_surface_state_fini(&sub->cached); + weston_buffer_reference(&sub->cached_buffer_ref, NULL); sub->surface->configure = NULL; sub->surface->configure_private = NULL; @@ -2840,7 +2796,8 @@ weston_subsurface_create(uint32_t id, struct weston_surface *surface, sub, subsurface_resource_destroy); weston_subsurface_link_surface(sub, surface); weston_subsurface_link_parent(sub, parent); - weston_subsurface_cache_init(sub); + weston_surface_state_init(&sub->cached); + sub->cached_buffer_ref.buffer = NULL; sub->synchronized = 1; return sub; diff --git a/src/compositor.h b/src/compositor.h index 06f8b03..bef5e1d 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -789,6 +789,32 @@ struct weston_view { uint32_t output_mask; }; +struct weston_surface_state { + /* wl_surface.attach */ + int newly_attached; + struct weston_buffer *buffer; + struct wl_listener buffer_destroy_listener; + int32_t sx; + int32_t sy; + + /* wl_surface.damage */ + pixman_region32_t damage; + + /* wl_surface.set_opaque_region */ + pixman_region32_t opaque; + + /* wl_surface.set_input_region */ + pixman_region32_t input; + + /* wl_surface.frame */ + struct wl_list frame_callback_list; + + /* wl_surface.set_buffer_transform */ + /* wl_surface.set_scaling_factor */ + /* wl_viewport.set */ + struct weston_buffer_viewport buffer_viewport; +}; + struct weston_surface { struct wl_resource *resource; struct wl_signal destroy_signal; @@ -833,31 +859,7 @@ struct weston_surface { struct wl_resource *viewport_resource; /* All the pending state, that wl_surface.commit will apply. */ - struct { - /* wl_surface.attach */ - int newly_attached; - struct weston_buffer *buffer; - struct wl_listener buffer_destroy_listener; - int32_t sx; - int32_t sy; - - /* wl_surface.damage */ - pixman_region32_t damage; - - /* wl_surface.set_opaque_region */ - pixman_region32_t opaque; - - /* wl_surface.set_input_region */ - pixman_region32_t input; - - /* wl_surface.frame */ - struct wl_list frame_callback_list; - - /* wl_surface.set_buffer_transform */ - /* wl_surface.set_scaling_factor */ - /* wl_viewport.set */ - struct weston_buffer_viewport buffer_viewport; - } pending; + struct weston_surface_state pending; /* * If non-NULL, this function will be called on @@ -895,31 +897,9 @@ struct weston_subsurface { int set; } position; - struct { - int has_data; - - /* wl_surface.attach */ - int newly_attached; - struct weston_buffer_reference buffer_ref; - int32_t sx; - int32_t sy; - - /* wl_surface.damage */ - pixman_region32_t damage; - - /* wl_surface.set_opaque_region */ - pixman_region32_t opaque; - - /* wl_surface.set_input_region */ - pixman_region32_t input; - - /* wl_surface.frame */ - struct wl_list frame_callback_list; - - /* wl_surface.set_buffer_transform */ - /* wl_surface.set_buffer_scale */ - struct weston_buffer_viewport buffer_viewport; - } cached; + int has_cached_data; + struct weston_surface_state cached; + struct weston_buffer_reference cached_buffer_ref; int synchronized; -- 2.7.4