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 <jason.ekstrand@intel.com> Reviewed-by: Pekka Paalanen <ppaalanen@gmail.com>
This commit is contained in:
parent
108865de88
commit
7b98207667
265
src/compositor.c
265
src/compositor.c
@ -319,16 +319,6 @@ weston_client_launch(struct weston_compositor *compositor,
|
||||
return client;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -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) {
|
||||
@ -2665,30 +2644,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)
|
||||
{
|
||||
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user