Create a weston_surface_state structure for storing pending surface state and move...
authorJason Ekstrand <jason@jlekstrand.net>
Tue, 20 May 2014 19:33:03 +0000 (14:33 -0500)
committerJason Ekstrand <jason.ekstrand@intel.com>
Mon, 7 Jul 2014 16:12:57 +0000 (09:12 -0700)
This new structure is used for both weston_surface.pending and
weston_subsurface.cached.

Signed-off-by: Jason Ekstrand <jason.ekstrand@intel.com>
Reviewed-by: Pekka Paalanen <ppaalanen@gmail.com>
src/compositor.c
src/compositor.h

index a882431..17fce8d 100644 (file)
@@ -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;
index 06f8b03..bef5e1d 100644 (file)
@@ -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;