Merge pull request #915 from emersion/redesign-compositor-resources

compositor: redesign how resources are managed
This commit is contained in:
Drew DeVault 2018-04-26 19:01:16 +02:00 committed by GitHub
commit daa293da93
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 76 deletions

View file

@ -6,9 +6,11 @@
struct wl_resource;
/*
* Implements the given resource as region.
* Creates a new region resource with the provided new ID. If `resource_list` is
* non-NULL, adds the region's resource to the list.
*/
struct wl_resource *wlr_region_create(struct wl_client *client, uint32_t id);
struct wl_resource *wlr_region_create(struct wl_client *client,
uint32_t version, uint32_t id, struct wl_list *resource_list);
pixman_region32_t *wlr_region_from_resource(struct wl_resource *resource);

View file

@ -80,10 +80,6 @@ struct wlr_surface {
struct wl_signal destroy;
} events;
// destroy listener used by compositor
struct wl_listener compositor_listener;
void *compositor_data;
// surface commit callback for the role that runs before all others
void (*role_committed)(struct wlr_surface *surface, void *role_data);
void *role_data;
@ -102,8 +98,14 @@ typedef void (*wlr_surface_iterator_func_t)(struct wlr_surface *surface,
int sx, int sy, void *data);
struct wlr_renderer;
struct wlr_surface *wlr_surface_create(struct wl_resource *res,
struct wlr_renderer *renderer);
/**
* Create a new surface resource with the provided new ID. If `resource_list`
* is non-NULL, adds the surface's resource to the list.
*/
struct wlr_surface *wlr_surface_create(struct wl_client *client,
uint32_t version, uint32_t id, struct wlr_renderer *renderer,
struct wl_list *resource_list);
/**
* Set the lifetime role for this surface. Returns 0 on success or -1 if the
@ -121,10 +123,12 @@ int wlr_surface_set_role(struct wlr_surface *surface, const char *role,
bool wlr_surface_has_buffer(struct wlr_surface *surface);
/**
* Create the subsurface implementation for this surface.
* Create a new subsurface resource with the provided new ID. If `resource_list`
* is non-NULL, adds the subsurface's resource to the list.
*/
struct wlr_subsurface *wlr_surface_make_subsurface(struct wlr_surface *surface,
struct wlr_surface *parent, uint32_t id);
struct wlr_subsurface *wlr_subsurface_create(struct wlr_surface *surface,
struct wlr_surface *parent, uint32_t version, uint32_t id,
struct wl_list *resource_list);
/**
* Get the root of the subsurface tree for this surface.

View file

@ -75,14 +75,8 @@ static void subcompositor_handle_get_subsurface(struct wl_client *client,
return;
}
struct wlr_subsurface *subsurface =
wlr_surface_make_subsurface(surface, parent, id);
if (subsurface == NULL) {
return;
}
wl_list_insert(&subcompositor->subsurface_resources,
wl_resource_get_link(subsurface->resource));
wlr_subsurface_create(surface, parent, wl_resource_get_version(resource),
id, &subcompositor->subsurface_resources);
}
static const struct wl_subcompositor_interface subcompositor_impl = {
@ -142,36 +136,17 @@ static struct wlr_compositor *compositor_from_resource(
return wl_resource_get_user_data(resource);
}
static void compositor_handle_surface_destroy(struct wl_listener *listener,
void *data) {
wl_list_remove(wl_resource_get_link(data));
}
static void wl_compositor_create_surface(struct wl_client *client,
struct wl_resource *resource, uint32_t id) {
struct wlr_compositor *compositor = compositor_from_resource(resource);
struct wl_resource *surface_resource = wl_resource_create(client,
&wl_surface_interface, wl_resource_get_version(resource), id);
if (surface_resource == NULL) {
wl_resource_post_no_memory(resource);
return;
}
struct wlr_surface *surface = wlr_surface_create(surface_resource,
compositor->renderer);
struct wlr_surface *surface = wlr_surface_create(client,
wl_resource_get_version(resource), id, compositor->renderer,
&compositor->surface_resources);
if (surface == NULL) {
wl_resource_destroy(surface_resource);
wl_resource_post_no_memory(resource);
return;
}
surface->compositor_data = compositor;
surface->compositor_listener.notify = compositor_handle_surface_destroy;
wl_resource_add_destroy_listener(surface_resource,
&surface->compositor_listener);
wl_list_insert(&compositor->surface_resources,
wl_resource_get_link(surface_resource));
wlr_signal_emit_safe(&compositor->events.new_surface, surface);
}
@ -179,14 +154,7 @@ static void wl_compositor_create_region(struct wl_client *client,
struct wl_resource *resource, uint32_t id) {
struct wlr_compositor *compositor = compositor_from_resource(resource);
struct wl_resource *region_resource = wlr_region_create(client, id);
if (region_resource == NULL) {
wl_resource_post_no_memory(resource);
return;
}
wl_list_insert(&compositor->region_resources,
wl_resource_get_link(region_resource));
wlr_region_create(client, 1, id, &compositor->region_resources);
}
static const struct wl_compositor_interface compositor_impl = {

View file

@ -34,29 +34,40 @@ static const struct wl_region_interface region_impl = {
static void region_handle_resource_destroy(struct wl_resource *resource) {
pixman_region32_t *reg = wlr_region_from_resource(resource);
wl_list_remove(wl_resource_get_link(resource));
pixman_region32_fini(reg);
free(reg);
// Set by wlr_compositor
wl_list_remove(wl_resource_get_link(resource));
}
struct wl_resource *wlr_region_create(struct wl_client *client, uint32_t id) {
struct wl_resource *wlr_region_create(struct wl_client *client,
uint32_t version, uint32_t id, struct wl_list *resource_list) {
pixman_region32_t *region = calloc(1, sizeof(pixman_region32_t));
if (region == NULL) {
wl_client_post_no_memory(client);
return NULL;
}
pixman_region32_init(region);
struct wl_resource *region_resource = wl_resource_create(client,
&wl_region_interface, 1, id);
&wl_region_interface, version, id);
if (region_resource == NULL) {
free(region);
wl_client_post_no_memory(client);
return NULL;
}
wl_resource_set_implementation(region_resource, &region_impl, region,
region_handle_resource_destroy);
struct wl_list *resource_link = wl_resource_get_link(region_resource);
if (resource_list != NULL) {
wl_list_insert(resource_list, resource_link);
} else {
wl_list_init(resource_link);
}
return region_resource;
}

View file

@ -615,6 +615,8 @@ static void subsurface_destroy(struct wlr_subsurface *subsurface) {
wl_list_remove(&subsurface->parent_destroy.link);
}
wl_list_remove(wl_resource_get_link(subsurface->resource));
wl_resource_set_user_data(subsurface->resource, NULL);
if (subsurface->surface) {
subsurface->surface->role_data = NULL;
@ -627,6 +629,9 @@ static void surface_handle_resource_destroy(struct wl_resource *resource) {
wlr_signal_emit_safe(&surface->events.destroy, surface);
wl_list_remove(wl_resource_get_link(surface->resource));
wl_list_remove(&surface->renderer_destroy.link);
wlr_texture_destroy(surface->texture);
surface_state_destroy(surface->pending);
surface_state_destroy(surface->current);
@ -641,16 +646,27 @@ static void surface_handle_renderer_destroy(struct wl_listener *listener,
wl_resource_destroy(surface->resource);
}
struct wlr_surface *wlr_surface_create(struct wl_resource *res,
struct wlr_renderer *renderer) {
struct wlr_surface *wlr_surface_create(struct wl_client *client,
uint32_t version, uint32_t id, struct wlr_renderer *renderer,
struct wl_list *resource_list) {
struct wlr_surface *surface = calloc(1, sizeof(struct wlr_surface));
if (!surface) {
wl_resource_post_no_memory(res);
wl_client_post_no_memory(client);
return NULL;
}
wlr_log(L_DEBUG, "New wlr_surface %p (res %p)", surface, res);
surface->resource = wl_resource_create(client, &wl_surface_interface,
version, id);
if (surface->resource == NULL) {
free(surface);
wl_client_post_no_memory(client);
return NULL;
}
wl_resource_set_implementation(surface->resource, &surface_interface,
surface, surface_handle_resource_destroy);
wlr_log(L_DEBUG, "New wlr_surface %p (res %p)", surface, surface->resource);
surface->renderer = renderer;
surface->resource = res;
surface->current = surface_state_create();
surface->pending = surface_state_create();
@ -660,12 +676,17 @@ struct wlr_surface *wlr_surface_create(struct wl_resource *res,
wl_signal_init(&surface->events.new_subsurface);
wl_list_init(&surface->subsurfaces);
wl_list_init(&surface->subsurface_pending_list);
wl_resource_set_implementation(res, &surface_interface,
surface, surface_handle_resource_destroy);
wl_signal_add(&renderer->events.destroy, &surface->renderer_destroy);
surface->renderer_destroy.notify = surface_handle_renderer_destroy;
struct wl_list *resource_link = wl_resource_get_link(surface->resource);
if (resource_list != NULL) {
wl_list_insert(resource_list, resource_link);
} else {
wl_list_init(resource_link);
}
return surface;
}
@ -838,8 +859,9 @@ static void subsurface_handle_surface_destroy(struct wl_listener *listener,
subsurface_destroy(subsurface);
}
struct wlr_subsurface *wlr_surface_make_subsurface(struct wlr_surface *surface,
struct wlr_surface *parent, uint32_t id) {
struct wlr_subsurface *wlr_subsurface_create(struct wlr_surface *surface,
struct wlr_surface *parent, uint32_t version, uint32_t id,
struct wl_list *resource_list) {
struct wl_client *client = wl_resource_get_client(surface->resource);
struct wlr_subsurface *subsurface =
@ -856,7 +878,20 @@ struct wlr_subsurface *wlr_surface_make_subsurface(struct wlr_surface *surface,
}
subsurface->synchronized = true;
subsurface->surface = surface;
subsurface->resource =
wl_resource_create(client, &wl_subsurface_interface, version, id);
if (subsurface->resource == NULL) {
surface_state_destroy(subsurface->cached);
free(subsurface);
wl_client_post_no_memory(client);
return NULL;
}
wl_resource_set_implementation(subsurface->resource,
&subsurface_implementation, subsurface,
subsurface_resource_destroy);
wl_signal_init(&subsurface->events.destroy);
wl_signal_add(&surface->events.destroy, &subsurface->surface_destroy);
subsurface->surface_destroy.notify = subsurface_handle_surface_destroy;
@ -868,21 +903,15 @@ struct wlr_subsurface *wlr_surface_make_subsurface(struct wlr_surface *surface,
wl_list_insert(&parent->subsurface_pending_list,
&subsurface->parent_pending_link);
subsurface->resource =
wl_resource_create(client, &wl_subsurface_interface, 1, id);
if (subsurface->resource == NULL) {
surface_state_destroy(subsurface->cached);
free(subsurface);
wl_client_post_no_memory(client);
return NULL;
}
wl_resource_set_implementation(subsurface->resource,
&subsurface_implementation, subsurface,
subsurface_resource_destroy);
surface->role_data = subsurface;
struct wl_list *resource_link = wl_resource_get_link(subsurface->resource);
if (resource_list != NULL) {
wl_list_insert(resource_list, resource_link);
} else {
wl_list_init(resource_link);
}
wlr_signal_emit_safe(&parent->events.new_subsurface, subsurface);
return subsurface;