From 267f6cc6a130bfd16233b670a8837cf296aa06e5 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Thu, 18 Nov 2021 15:17:53 +0000 Subject: [PATCH] backend-drm: Move drm_fb reference to state-propose Currently we take a reference on the underlying client buffer every time we materialise a drm_fb from a view, and release it when the drm_fb is destroyed. This means that we need to create and destroy a drm_fb every time we want to use it, which is pathologically unperformant on some platforms. To start working towards being able to cache drm_fb, only take the reference when we apply it to a plane state. Signed-off-by: Daniel Stone --- libweston/backend-drm/fb.c | 13 ------------- libweston/backend-drm/state-propose.c | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/libweston/backend-drm/fb.c b/libweston/backend-drm/fb.c index 017422f2..a0581dac 100644 --- a/libweston/backend-drm/fb.c +++ b/libweston/backend-drm/fb.c @@ -410,17 +410,6 @@ err_free: free(fb); return NULL; } - -static void -drm_fb_set_buffer(struct drm_fb *fb, struct weston_buffer *buffer, - struct weston_buffer_release *buffer_release) -{ - assert(fb->buffer_ref.buffer == NULL); - assert(fb->type == BUFFER_CLIENT || fb->type == BUFFER_DMABUF); - weston_buffer_reference(&fb->buffer_ref, buffer); - weston_buffer_release_reference(&fb->buffer_release_ref, - buffer_release); -} #endif void @@ -528,8 +517,6 @@ drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev, drm_debug(b, "\t\t\t[view] view %p format: %s\n", ev, fb->format->drm_format_name); - drm_fb_set_buffer(fb, buffer, - ev->surface->buffer_release_ref.buffer_release); return fb; } #endif diff --git a/libweston/backend-drm/state-propose.c b/libweston/backend-drm/state-propose.c index 7ddecd7b..7242af9e 100644 --- a/libweston/backend-drm/state-propose.c +++ b/libweston/backend-drm/state-propose.c @@ -532,6 +532,7 @@ drm_output_try_view_on_plane(struct drm_plane *plane, struct drm_plane *scanout_plane = state->output->scanout_plane; struct drm_plane_state *ps = NULL; const char *p_name = drm_output_get_plane_type_name(plane); + struct weston_surface *surface = ev->surface; enum { NO_PLANES, /* generic err-handle */ NO_PLANES_ACCEPTED, @@ -603,6 +604,19 @@ out: plane->plane_id, ev, p_name); break; case PLACED_ON_PLANE: + /* Take a reference on the buffer so that we don't release it + * back to the client until we're done with it; cursor buffers + * don't require a reference since we copy them. */ + assert(fb->buffer_ref.buffer == NULL); + assert(fb->buffer_release_ref.buffer_release == NULL); + if (ps->plane->type == WDRM_PLANE_TYPE_CURSOR) { + assert(ps->fb->type == BUFFER_CURSOR); + } else if (fb->type == BUFFER_CLIENT || fb->type == BUFFER_DMABUF) { + assert(ps->fb == fb); + weston_buffer_reference(&fb->buffer_ref, surface->buffer_ref.buffer); + weston_buffer_release_reference(&fb->buffer_release_ref, + surface->buffer_release_ref.buffer_release); + } break; }