libweston/linux-dmabuf: create surface feedback on demand

Unconditionally creating a surface feedback for each surface
creates unnecessary overhead and noise in the logs. Thus
create it when the first surface feedback resource for a
surface is requested and delete it again once all those
resources have been destroyed.

Signed-off-by: Robert Mader <robert.mader@collabora.com>
(cherry picked from commit 53a221ccaa)
dev
Robert Mader 3 years ago committed by Marius Vlad
parent 01af0e4e0e
commit f7c5fa175e
  1. 36
      libweston/compositor.c
  2. 67
      libweston/linux-dmabuf.c

@ -4048,54 +4048,22 @@ static const struct wl_surface_interface surface_interface = {
surface_damage_buffer surface_damage_buffer
}; };
static int
create_surface_dmabuf_feedback(struct weston_compositor *ec,
struct weston_surface *surface)
{
struct weston_dmabuf_feedback_tranche *tranche;
dev_t main_device = ec->default_dmabuf_feedback->main_device;
uint32_t flags = 0;
surface->dmabuf_feedback = weston_dmabuf_feedback_create(main_device);
if (!surface->dmabuf_feedback)
return -1;
tranche = weston_dmabuf_feedback_tranche_create(surface->dmabuf_feedback,
ec->dmabuf_feedback_format_table,
main_device, flags,
RENDERER_PREF);
if (!tranche) {
weston_dmabuf_feedback_destroy(surface->dmabuf_feedback);
surface->dmabuf_feedback = NULL;
return -1;
}
return 0;
}
static void static void
compositor_create_surface(struct wl_client *client, compositor_create_surface(struct wl_client *client,
struct wl_resource *resource, uint32_t id) struct wl_resource *resource, uint32_t id)
{ {
struct weston_compositor *ec = wl_resource_get_user_data(resource); struct weston_compositor *ec = wl_resource_get_user_data(resource);
struct weston_surface *surface; struct weston_surface *surface;
int ret;
surface = weston_surface_create(ec); surface = weston_surface_create(ec);
if (surface == NULL) if (surface == NULL)
goto err; goto err;
if (ec->default_dmabuf_feedback) {
ret = create_surface_dmabuf_feedback(ec, surface);
if (ret < 0)
goto err_dmabuf_feedback;
}
surface->resource = surface->resource =
wl_resource_create(client, &wl_surface_interface, wl_resource_create(client, &wl_surface_interface,
wl_resource_get_version(resource), id); wl_resource_get_version(resource), id);
if (surface->resource == NULL) if (surface->resource == NULL)
goto err_dmabuf_feedback; goto err_res;
wl_resource_set_implementation(surface->resource, &surface_interface, wl_resource_set_implementation(surface->resource, &surface_interface,
surface, destroy_surface); surface, destroy_surface);
@ -4103,7 +4071,7 @@ compositor_create_surface(struct wl_client *client,
return; return;
err_dmabuf_feedback: err_res:
weston_surface_destroy(surface); weston_surface_destroy(surface);
err: err:
wl_resource_post_no_memory(resource); wl_resource_post_no_memory(resource);

@ -684,6 +684,7 @@ weston_dmabuf_feedback_destroy(struct weston_dmabuf_feedback *dmabuf_feedback)
wl_resource_for_each_safe(res, res_tmp, &dmabuf_feedback->resource_list) { wl_resource_for_each_safe(res, res_tmp, &dmabuf_feedback->resource_list) {
wl_list_remove(wl_resource_get_link(res)); wl_list_remove(wl_resource_get_link(res));
wl_list_init(wl_resource_get_link(res)); wl_list_init(wl_resource_get_link(res));
wl_resource_set_user_data(res, NULL);
} }
free(dmabuf_feedback); free(dmabuf_feedback);
@ -786,6 +787,7 @@ weston_dmabuf_feedback_send_all(struct weston_dmabuf_feedback *dmabuf_feedback,
{ {
struct wl_resource *res; struct wl_resource *res;
assert(!wl_list_empty(&dmabuf_feedback->resource_list));
wl_resource_for_each(res, &dmabuf_feedback->resource_list) wl_resource_for_each(res, &dmabuf_feedback->resource_list)
weston_dmabuf_feedback_send(dmabuf_feedback, weston_dmabuf_feedback_send(dmabuf_feedback,
format_table, res, false); format_table, res, false);
@ -794,7 +796,16 @@ weston_dmabuf_feedback_send_all(struct weston_dmabuf_feedback *dmabuf_feedback,
static void static void
dmabuf_feedback_resource_destroy(struct wl_resource *resource) dmabuf_feedback_resource_destroy(struct wl_resource *resource)
{ {
struct weston_surface *surface =
wl_resource_get_user_data(resource);
wl_list_remove(wl_resource_get_link(resource)); wl_list_remove(wl_resource_get_link(resource));
if (surface &&
wl_list_empty(&surface->dmabuf_feedback->resource_list)) {
weston_dmabuf_feedback_destroy(surface->dmabuf_feedback);
surface->dmabuf_feedback = NULL;
}
} }
static void static void
@ -810,7 +821,8 @@ zwp_linux_dmabuf_feedback_implementation = {
static struct wl_resource * static struct wl_resource *
dmabuf_feedback_resource_create(struct wl_resource *dmabuf_resource, dmabuf_feedback_resource_create(struct wl_resource *dmabuf_resource,
struct wl_client *client, uint32_t dmabuf_feedback_id) struct wl_client *client, uint32_t dmabuf_feedback_id,
struct weston_surface *surface)
{ {
struct wl_resource *dmabuf_feedback_res; struct wl_resource *dmabuf_feedback_res;
uint32_t version; uint32_t version;
@ -826,7 +838,7 @@ dmabuf_feedback_resource_create(struct wl_resource *dmabuf_resource,
wl_list_init(wl_resource_get_link(dmabuf_feedback_res)); wl_list_init(wl_resource_get_link(dmabuf_feedback_res));
wl_resource_set_implementation(dmabuf_feedback_res, wl_resource_set_implementation(dmabuf_feedback_res,
&zwp_linux_dmabuf_feedback_implementation, &zwp_linux_dmabuf_feedback_implementation,
NULL, dmabuf_feedback_resource_destroy); surface, dmabuf_feedback_resource_destroy);
return dmabuf_feedback_res; return dmabuf_feedback_res;
} }
@ -842,7 +854,8 @@ linux_dmabuf_get_default_feedback(struct wl_client *client,
dmabuf_feedback_resource = dmabuf_feedback_resource =
dmabuf_feedback_resource_create(dmabuf_resource, dmabuf_feedback_resource_create(dmabuf_resource,
client, dmabuf_feedback_id); client, dmabuf_feedback_id,
NULL);
if (!dmabuf_feedback_resource) { if (!dmabuf_feedback_resource) {
wl_resource_post_no_memory(dmabuf_resource); wl_resource_post_no_memory(dmabuf_resource);
return; return;
@ -853,22 +866,55 @@ linux_dmabuf_get_default_feedback(struct wl_client *client,
dmabuf_feedback_resource, true); dmabuf_feedback_resource, true);
} }
static int
create_surface_dmabuf_feedback(struct weston_compositor *ec,
struct weston_surface *surface)
{
struct weston_dmabuf_feedback_tranche *tranche;
dev_t main_device = ec->default_dmabuf_feedback->main_device;
uint32_t flags = 0;
surface->dmabuf_feedback = weston_dmabuf_feedback_create(main_device);
if (!surface->dmabuf_feedback)
return -1;
tranche = weston_dmabuf_feedback_tranche_create(surface->dmabuf_feedback,
ec->dmabuf_feedback_format_table,
main_device, flags,
RENDERER_PREF);
if (!tranche) {
weston_dmabuf_feedback_destroy(surface->dmabuf_feedback);
surface->dmabuf_feedback = NULL;
return -1;
}
return 0;
}
static void static void
linux_dmabuf_get_per_surface_feedback(struct wl_client *client, linux_dmabuf_get_per_surface_feedback(struct wl_client *client,
struct wl_resource *dmabuf_resource, struct wl_resource *dmabuf_resource,
uint32_t dmabuf_feedback_id, uint32_t dmabuf_feedback_id,
struct wl_resource *surface_resource) struct wl_resource *surface_resource)
{ {
struct weston_compositor *compositor =
wl_resource_get_user_data(dmabuf_resource);
struct weston_surface *surface = struct weston_surface *surface =
wl_resource_get_user_data(surface_resource); wl_resource_get_user_data(surface_resource);
struct wl_resource *dmabuf_feedback_resource; struct wl_resource *dmabuf_feedback_resource;
int ret;
dmabuf_feedback_resource = dmabuf_feedback_resource =
dmabuf_feedback_resource_create(dmabuf_resource, dmabuf_feedback_resource_create(dmabuf_resource,
client, dmabuf_feedback_id); client, dmabuf_feedback_id,
if (!dmabuf_feedback_resource) { surface);
wl_resource_post_no_memory(dmabuf_resource); if (!dmabuf_feedback_resource)
return; goto err;
if (!surface->dmabuf_feedback) {
ret = create_surface_dmabuf_feedback(compositor, surface);
if (ret < 0)
goto err_feedback;
} }
/* Surface dma-buf feedback is dynamic and may need to be resent to /* Surface dma-buf feedback is dynamic and may need to be resent to
@ -879,6 +925,13 @@ linux_dmabuf_get_per_surface_feedback(struct wl_client *client,
weston_dmabuf_feedback_send(surface->dmabuf_feedback, weston_dmabuf_feedback_send(surface->dmabuf_feedback,
surface->compositor->dmabuf_feedback_format_table, surface->compositor->dmabuf_feedback_format_table,
dmabuf_feedback_resource, true); dmabuf_feedback_resource, true);
return;
err_feedback:
wl_resource_set_user_data(dmabuf_feedback_resource, NULL);
wl_resource_destroy(dmabuf_feedback_resource);
err:
wl_resource_post_no_memory(dmabuf_resource);
} }
/** Get the linux_dmabuf_buffer from a wl_buffer resource /** Get the linux_dmabuf_buffer from a wl_buffer resource

Loading…
Cancel
Save