compositor: make wl_surface.attach double-buffered
This change depends on the Wayland commit "protocol: double-buffered state for wl_surface". Clients are now required to issue wl_surface.commit for the wl_surface.attach to take effect. While changing this, change the surface argument to weston_surface_attach() from wl_surface into weston_surface, for consistency. Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
This commit is contained in:
committed by
Kristian Høgsberg
parent
fa80e11c84
commit
5df44de6a9
+59
-21
@@ -193,6 +193,16 @@ surface_handle_buffer_destroy(struct wl_listener *listener, void *data)
|
|||||||
es->buffer = NULL;
|
es->buffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 const pixman_region32_data_t undef_region_data;
|
static const pixman_region32_data_t undef_region_data;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -262,6 +272,9 @@ weston_surface_create(struct weston_compositor *compositor)
|
|||||||
pixman_region32_init(&surface->transform.boundingbox);
|
pixman_region32_init(&surface->transform.boundingbox);
|
||||||
surface->geometry.dirty = 1;
|
surface->geometry.dirty = 1;
|
||||||
|
|
||||||
|
surface->pending.buffer_destroy_listener.notify =
|
||||||
|
surface_handle_pending_buffer_destroy;
|
||||||
|
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -767,6 +780,9 @@ destroy_surface(struct wl_resource *resource)
|
|||||||
if (weston_surface_is_mapped(surface))
|
if (weston_surface_is_mapped(surface))
|
||||||
weston_surface_unmap(surface);
|
weston_surface_unmap(surface);
|
||||||
|
|
||||||
|
if (surface->pending.buffer)
|
||||||
|
wl_list_remove(&surface->pending.buffer_destroy_listener.link);
|
||||||
|
|
||||||
if (surface->buffer)
|
if (surface->buffer)
|
||||||
wl_list_remove(&surface->buffer_destroy_listener.link);
|
wl_list_remove(&surface->buffer_destroy_listener.link);
|
||||||
|
|
||||||
@@ -797,33 +813,31 @@ weston_surface_destroy(struct weston_surface *surface)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer)
|
weston_surface_attach(struct weston_surface *surface, struct wl_buffer *buffer)
|
||||||
{
|
{
|
||||||
struct weston_surface *es = (struct weston_surface *) surface;
|
if (surface->buffer) {
|
||||||
|
weston_buffer_post_release(surface->buffer);
|
||||||
if (es->buffer) {
|
wl_list_remove(&surface->buffer_destroy_listener.link);
|
||||||
weston_buffer_post_release(es->buffer);
|
|
||||||
wl_list_remove(&es->buffer_destroy_listener.link);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
buffer->busy_count++;
|
buffer->busy_count++;
|
||||||
wl_signal_add(&buffer->resource.destroy_signal,
|
wl_signal_add(&buffer->resource.destroy_signal,
|
||||||
&es->buffer_destroy_listener);
|
&surface->buffer_destroy_listener);
|
||||||
|
|
||||||
if (es->geometry.width != buffer->width ||
|
if (surface->geometry.width != buffer->width ||
|
||||||
es->geometry.height != buffer->height) {
|
surface->geometry.height != buffer->height) {
|
||||||
undef_region(&es->input);
|
undef_region(&surface->input);
|
||||||
pixman_region32_fini(&es->opaque);
|
pixman_region32_fini(&surface->opaque);
|
||||||
pixman_region32_init(&es->opaque);
|
pixman_region32_init(&surface->opaque);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (weston_surface_is_mapped(es))
|
if (weston_surface_is_mapped(surface))
|
||||||
weston_surface_unmap(es);
|
weston_surface_unmap(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
es->compositor->renderer->attach(es, buffer);
|
surface->compositor->renderer->attach(surface, buffer);
|
||||||
es->buffer = buffer;
|
surface->buffer = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
WL_EXPORT void
|
WL_EXPORT void
|
||||||
@@ -1126,16 +1140,25 @@ surface_attach(struct wl_client *client,
|
|||||||
struct wl_resource *resource,
|
struct wl_resource *resource,
|
||||||
struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
|
struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
|
||||||
{
|
{
|
||||||
struct weston_surface *es = resource->data;
|
struct weston_surface *surface = resource->data;
|
||||||
struct wl_buffer *buffer = NULL;
|
struct wl_buffer *buffer = NULL;
|
||||||
|
|
||||||
if (buffer_resource)
|
if (buffer_resource)
|
||||||
buffer = buffer_resource->data;
|
buffer = buffer_resource->data;
|
||||||
|
|
||||||
weston_surface_attach(&es->surface, buffer);
|
if (surface->pending.buffer)
|
||||||
|
wl_list_remove(&surface->pending.buffer_destroy_listener.link);
|
||||||
|
|
||||||
if (buffer && es->configure)
|
surface->pending.sx = sx;
|
||||||
es->configure(es, sx, sy);
|
surface->pending.sy = sy;
|
||||||
|
surface->pending.buffer = buffer;
|
||||||
|
if (buffer) {
|
||||||
|
wl_signal_add(&buffer->resource.destroy_signal,
|
||||||
|
&surface->pending.buffer_destroy_listener);
|
||||||
|
surface->pending.remove_contents = 0;
|
||||||
|
} else {
|
||||||
|
surface->pending.remove_contents = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1230,13 +1253,28 @@ surface_set_input_region(struct wl_client *client,
|
|||||||
weston_surface_schedule_repaint(surface);
|
weston_surface_schedule_repaint(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
surface_commit(struct wl_client *client, struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
struct weston_surface *surface = resource->data;
|
||||||
|
|
||||||
|
/* wl_surface.attach */
|
||||||
|
if (surface->pending.buffer || surface->pending.remove_contents)
|
||||||
|
weston_surface_attach(surface, surface->pending.buffer);
|
||||||
|
|
||||||
|
if (surface->buffer && surface->configure)
|
||||||
|
surface->configure(surface, surface->pending.sx,
|
||||||
|
surface->pending.sy);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct wl_surface_interface surface_interface = {
|
static const struct wl_surface_interface surface_interface = {
|
||||||
surface_destroy,
|
surface_destroy,
|
||||||
surface_attach,
|
surface_attach,
|
||||||
surface_damage,
|
surface_damage,
|
||||||
surface_frame,
|
surface_frame,
|
||||||
surface_set_opaque_region,
|
surface_set_opaque_region,
|
||||||
surface_set_input_region
|
surface_set_input_region,
|
||||||
|
surface_commit
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@@ -466,6 +466,16 @@ struct weston_surface {
|
|||||||
struct wl_buffer *buffer;
|
struct wl_buffer *buffer;
|
||||||
struct wl_listener buffer_destroy_listener;
|
struct wl_listener buffer_destroy_listener;
|
||||||
|
|
||||||
|
/* All the pending state, that wl_surface.commit will apply. */
|
||||||
|
struct {
|
||||||
|
/* wl_surface.attach */
|
||||||
|
int remove_contents;
|
||||||
|
struct wl_buffer *buffer;
|
||||||
|
struct wl_listener buffer_destroy_listener;
|
||||||
|
int32_t sx;
|
||||||
|
int32_t sy;
|
||||||
|
} pending;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If non-NULL, this function will be called on surface::attach after
|
* If non-NULL, this function will be called on surface::attach after
|
||||||
* a new buffer has been set up for this surface. The integer params
|
* a new buffer has been set up for this surface. The integer params
|
||||||
|
|||||||
Reference in New Issue
Block a user