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 <daniels@collabora.com>
This commit is contained in:
@@ -410,17 +410,6 @@ err_free:
|
|||||||
free(fb);
|
free(fb);
|
||||||
return NULL;
|
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
|
#endif
|
||||||
|
|
||||||
void
|
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",
|
drm_debug(b, "\t\t\t[view] view %p format: %s\n",
|
||||||
ev, fb->format->drm_format_name);
|
ev, fb->format->drm_format_name);
|
||||||
drm_fb_set_buffer(fb, buffer,
|
|
||||||
ev->surface->buffer_release_ref.buffer_release);
|
|
||||||
return fb;
|
return fb;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -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 *scanout_plane = state->output->scanout_plane;
|
||||||
struct drm_plane_state *ps = NULL;
|
struct drm_plane_state *ps = NULL;
|
||||||
const char *p_name = drm_output_get_plane_type_name(plane);
|
const char *p_name = drm_output_get_plane_type_name(plane);
|
||||||
|
struct weston_surface *surface = ev->surface;
|
||||||
enum {
|
enum {
|
||||||
NO_PLANES, /* generic err-handle */
|
NO_PLANES, /* generic err-handle */
|
||||||
NO_PLANES_ACCEPTED,
|
NO_PLANES_ACCEPTED,
|
||||||
@@ -603,6 +604,19 @@ out:
|
|||||||
plane->plane_id, ev, p_name);
|
plane->plane_id, ev, p_name);
|
||||||
break;
|
break;
|
||||||
case PLACED_ON_PLANE:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user