mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-05-05 09:58:14 +02:00
nested: Add the buffer reference semantics from Weston
This copies the buffer reference busy count implementation from Weston to the nested compositor example and adds an internal nested_buffer struct that we could eventually use to attach data. This will be useful to adapt the example to use subsurfaces so that we can attach our compositor-side buffer to the resource.
This commit is contained in:
parent
8fbe3a68d4
commit
6bf23879e9
1 changed files with 95 additions and 4 deletions
|
|
@ -66,9 +66,21 @@ struct nested_region {
|
|||
pixman_region32_t region;
|
||||
};
|
||||
|
||||
struct nested_buffer {
|
||||
struct wl_resource *resource;
|
||||
struct wl_signal destroy_signal;
|
||||
struct wl_listener destroy_listener;
|
||||
uint32_t busy_count;
|
||||
};
|
||||
|
||||
struct nested_buffer_reference {
|
||||
struct nested_buffer *buffer;
|
||||
struct wl_listener destroy_listener;
|
||||
};
|
||||
|
||||
struct nested_surface {
|
||||
struct wl_resource *resource;
|
||||
struct wl_resource *buffer_resource;
|
||||
struct nested_buffer_reference buffer_ref;
|
||||
struct nested *nested;
|
||||
EGLImageKHR *image;
|
||||
GLuint texture;
|
||||
|
|
@ -88,6 +100,83 @@ static PFNEGLBINDWAYLANDDISPLAYWL bind_display;
|
|||
static PFNEGLUNBINDWAYLANDDISPLAYWL unbind_display;
|
||||
static PFNEGLQUERYWAYLANDBUFFERWL query_buffer;
|
||||
|
||||
static void
|
||||
nested_buffer_destroy_handler(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct nested_buffer *buffer =
|
||||
container_of(listener, struct nested_buffer, destroy_listener);
|
||||
|
||||
wl_signal_emit(&buffer->destroy_signal, buffer);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
static struct nested_buffer *
|
||||
nested_buffer_from_resource(struct wl_resource *resource)
|
||||
{
|
||||
struct nested_buffer *buffer;
|
||||
struct wl_listener *listener;
|
||||
|
||||
listener =
|
||||
wl_resource_get_destroy_listener(resource,
|
||||
nested_buffer_destroy_handler);
|
||||
|
||||
if (listener)
|
||||
return container_of(listener, struct nested_buffer,
|
||||
destroy_listener);
|
||||
|
||||
buffer = zalloc(sizeof *buffer);
|
||||
if (buffer == NULL)
|
||||
return NULL;
|
||||
|
||||
buffer->resource = resource;
|
||||
wl_signal_init(&buffer->destroy_signal);
|
||||
buffer->destroy_listener.notify = nested_buffer_destroy_handler;
|
||||
wl_resource_add_destroy_listener(resource, &buffer->destroy_listener);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
nested_buffer_reference_handle_destroy(struct wl_listener *listener,
|
||||
void *data)
|
||||
{
|
||||
struct nested_buffer_reference *ref =
|
||||
container_of(listener, struct nested_buffer_reference,
|
||||
destroy_listener);
|
||||
|
||||
assert((struct nested_buffer *)data == ref->buffer);
|
||||
ref->buffer = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
nested_buffer_reference(struct nested_buffer_reference *ref,
|
||||
struct nested_buffer *buffer)
|
||||
{
|
||||
if (buffer == ref->buffer)
|
||||
return;
|
||||
|
||||
if (ref->buffer) {
|
||||
ref->buffer->busy_count--;
|
||||
if (ref->buffer->busy_count == 0) {
|
||||
assert(wl_resource_get_client(ref->buffer->resource));
|
||||
wl_resource_queue_event(ref->buffer->resource,
|
||||
WL_BUFFER_RELEASE);
|
||||
}
|
||||
wl_list_remove(&ref->destroy_listener.link);
|
||||
}
|
||||
|
||||
if (buffer) {
|
||||
buffer->busy_count++;
|
||||
wl_signal_add(&buffer->destroy_signal,
|
||||
&ref->destroy_listener);
|
||||
|
||||
ref->destroy_listener.notify =
|
||||
nested_buffer_reference_handle_destroy;
|
||||
}
|
||||
|
||||
ref->buffer = buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
frame_callback(void *data, struct wl_callback *callback, uint32_t time)
|
||||
{
|
||||
|
|
@ -265,6 +354,8 @@ destroy_surface(struct wl_resource *resource)
|
|||
{
|
||||
struct nested_surface *surface = wl_resource_get_user_data(resource);
|
||||
|
||||
nested_buffer_reference(&surface->buffer_ref, NULL);
|
||||
|
||||
wl_list_remove(&surface->link);
|
||||
|
||||
free(surface);
|
||||
|
|
@ -285,11 +376,11 @@ surface_attach(struct wl_client *client,
|
|||
struct nested *nested = surface->nested;
|
||||
EGLint format, width, height;
|
||||
cairo_device_t *device;
|
||||
struct nested_buffer *buffer =
|
||||
nested_buffer_from_resource(buffer_resource);
|
||||
|
||||
if (surface->buffer_resource)
|
||||
wl_buffer_send_release(surface->buffer_resource);
|
||||
nested_buffer_reference(&surface->buffer_ref, buffer);
|
||||
|
||||
surface->buffer_resource = buffer_resource;
|
||||
if (!query_buffer(nested->egl_display, (void *) buffer_resource,
|
||||
EGL_TEXTURE_FORMAT, &format)) {
|
||||
fprintf(stderr, "attaching non-egl wl_buffer\n");
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue