backend-drm: keep track of the reason why promoting view to a plane failed
Add enum try_view_on_plane_failure_reasons to help us to keep track of the reason why promoting view to a plane failed. We also add a variable to struct weston_paint_node so that we can update this information in each output repaint. This will be used in the next commits, in which we add proper surface dma-buf feedback support. Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com> Reviewed-by: Daniel Stone <daniels@collabora.com>
This commit is contained in:
parent
8eb8414fcd
commit
0a7034c0cb
@ -227,6 +227,17 @@ enum wdrm_crtc_property {
|
||||
WDRM_CRTC__COUNT
|
||||
};
|
||||
|
||||
/**
|
||||
* Reasons why placing a view on a plane failed. Needed by the dma-buf feedback.
|
||||
*/
|
||||
enum try_view_on_plane_failure_reasons {
|
||||
FAILURE_REASONS_NONE = 0,
|
||||
FAILURE_REASONS_FORCE_RENDERER = (1 << 0),
|
||||
FAILURE_REASONS_FB_FORMAT_INCOMPATIBLE = (1 << 1),
|
||||
FAILURE_REASONS_DMABUF_MODIFIER_INVALID = (1 << 2),
|
||||
FAILURE_REASONS_ADD_FB_FAILED = (1 << 3),
|
||||
};
|
||||
|
||||
struct drm_backend {
|
||||
struct weston_backend base;
|
||||
struct weston_compositor *compositor;
|
||||
@ -694,13 +705,15 @@ drm_output_set_cursor_view(struct drm_output *output, struct weston_view *ev);
|
||||
|
||||
#ifdef BUILD_DRM_GBM
|
||||
extern struct drm_fb *
|
||||
drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev);
|
||||
drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev,
|
||||
uint32_t *try_view_on_plane_failure_reasons);
|
||||
extern bool
|
||||
drm_can_scanout_dmabuf(struct weston_compositor *ec,
|
||||
struct linux_dmabuf_buffer *dmabuf);
|
||||
#else
|
||||
static inline struct drm_fb *
|
||||
drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev)
|
||||
drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev,
|
||||
uint32_t *try_view_on_plane_failure_reasons)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -220,7 +220,8 @@ drm_fb_destroy_dmabuf(struct drm_fb *fb)
|
||||
|
||||
static struct drm_fb *
|
||||
drm_fb_get_from_dmabuf(struct linux_dmabuf_buffer *dmabuf,
|
||||
struct drm_backend *backend, bool is_opaque)
|
||||
struct drm_backend *backend, bool is_opaque,
|
||||
uint32_t *try_view_on_plane_failure_reasons)
|
||||
{
|
||||
#ifndef HAVE_GBM_FD_IMPORT
|
||||
/* Importing a buffer to KMS requires explicit modifiers, so
|
||||
@ -245,8 +246,12 @@ drm_fb_get_from_dmabuf(struct linux_dmabuf_buffer *dmabuf,
|
||||
* KMS driver can't know. So giving the buffer to KMS is not safe, as
|
||||
* not knowing its layout can result in garbage being displayed. In
|
||||
* short, importing a buffer to KMS requires explicit modifiers. */
|
||||
if (dmabuf->attributes.modifier[0] == DRM_FORMAT_MOD_INVALID)
|
||||
if (dmabuf->attributes.modifier[0] == DRM_FORMAT_MOD_INVALID) {
|
||||
if (try_view_on_plane_failure_reasons)
|
||||
*try_view_on_plane_failure_reasons |=
|
||||
FAILURE_REASONS_DMABUF_MODIFIER_INVALID;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* XXX: TODO:
|
||||
*
|
||||
@ -313,8 +318,12 @@ drm_fb_get_from_dmabuf(struct linux_dmabuf_buffer *dmabuf,
|
||||
fb->handles[i] = handle.u32;
|
||||
}
|
||||
|
||||
if (drm_fb_addfb(backend, fb) != 0)
|
||||
if (drm_fb_addfb(backend, fb) != 0) {
|
||||
if (try_view_on_plane_failure_reasons)
|
||||
*try_view_on_plane_failure_reasons |=
|
||||
FAILURE_REASONS_ADD_FB_FAILED;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
return fb;
|
||||
|
||||
@ -455,7 +464,7 @@ drm_can_scanout_dmabuf(struct weston_compositor *ec,
|
||||
struct drm_backend *b = to_drm_backend(ec);
|
||||
bool ret = false;
|
||||
|
||||
fb = drm_fb_get_from_dmabuf(dmabuf, b, true);
|
||||
fb = drm_fb_get_from_dmabuf(dmabuf, b, true, NULL);
|
||||
if (fb)
|
||||
ret = true;
|
||||
|
||||
@ -466,7 +475,8 @@ drm_can_scanout_dmabuf(struct weston_compositor *ec,
|
||||
}
|
||||
|
||||
struct drm_fb *
|
||||
drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev)
|
||||
drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev,
|
||||
uint32_t *try_view_on_plane_failure_reasons)
|
||||
{
|
||||
struct drm_output *output = state->output;
|
||||
struct drm_backend *b = to_drm_backend(output->base.compositor);
|
||||
@ -497,7 +507,8 @@ drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev)
|
||||
|
||||
dmabuf = linux_dmabuf_buffer_get(buffer->resource);
|
||||
if (dmabuf) {
|
||||
fb = drm_fb_get_from_dmabuf(dmabuf, b, is_opaque);
|
||||
fb = drm_fb_get_from_dmabuf(dmabuf, b, is_opaque,
|
||||
try_view_on_plane_failure_reasons);
|
||||
if (!fb)
|
||||
return NULL;
|
||||
} else {
|
||||
|
@ -654,7 +654,8 @@ drm_output_prepare_plane_view(struct drm_output_state *state,
|
||||
struct weston_view *ev,
|
||||
enum drm_output_propose_state_mode mode,
|
||||
struct drm_plane_state *scanout_state,
|
||||
uint64_t current_lowest_zpos)
|
||||
uint64_t current_lowest_zpos,
|
||||
uint32_t *try_view_on_plane_failure_reasons)
|
||||
{
|
||||
struct drm_output *output = state->output;
|
||||
struct drm_backend *b = to_drm_backend(output->base.compositor);
|
||||
@ -676,7 +677,7 @@ drm_output_prepare_plane_view(struct drm_output_state *state,
|
||||
|
||||
buffer = ev->surface->buffer_ref.buffer;
|
||||
shmbuf = wl_shm_buffer_get(buffer->resource);
|
||||
fb = drm_fb_get_from_view(state, ev);
|
||||
fb = drm_fb_get_from_view(state, ev, try_view_on_plane_failure_reasons);
|
||||
|
||||
/* assemble a list with possible candidates */
|
||||
wl_list_for_each(plane, &b->plane_list, link) {
|
||||
@ -730,6 +731,8 @@ drm_output_prepare_plane_view(struct drm_output_state *state,
|
||||
}
|
||||
|
||||
if (!drm_output_plane_view_has_valid_format(plane, state, ev, fb)) {
|
||||
*try_view_on_plane_failure_reasons |=
|
||||
FAILURE_REASONS_FB_FORMAT_INCOMPATIBLE;
|
||||
drm_debug(b, "\t\t\t\t[plane] not adding plane %d to "
|
||||
"candidate list: invalid pixel format\n",
|
||||
plane->plane_id);
|
||||
@ -960,7 +963,18 @@ drm_output_propose_state(struct weston_output *output_base,
|
||||
current_lowest_zpos);
|
||||
ps = drm_output_prepare_plane_view(state, ev, mode,
|
||||
scanout_state,
|
||||
current_lowest_zpos);
|
||||
current_lowest_zpos,
|
||||
&pnode->try_view_on_plane_failure_reasons);
|
||||
/* If we were able to place the view in a plane, set
|
||||
* failure reasons to none. */
|
||||
if (ps)
|
||||
pnode->try_view_on_plane_failure_reasons =
|
||||
FAILURE_REASONS_NONE;
|
||||
} else {
|
||||
/* We are forced to place the view in the renderer, set
|
||||
* the failure reason accordingly. */
|
||||
pnode->try_view_on_plane_failure_reasons =
|
||||
FAILURE_REASONS_FORCE_RENDERER;
|
||||
}
|
||||
|
||||
if (ps) {
|
||||
|
@ -416,6 +416,8 @@ struct weston_paint_node {
|
||||
|
||||
struct weston_surface_color_transform surf_xform;
|
||||
bool surf_xform_valid;
|
||||
|
||||
uint32_t try_view_on_plane_failure_reasons;
|
||||
};
|
||||
|
||||
struct weston_paint_node *
|
||||
|
Loading…
Reference in New Issue
Block a user