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:
@@ -227,6 +227,17 @@ enum wdrm_crtc_property {
|
|||||||
WDRM_CRTC__COUNT
|
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 drm_backend {
|
||||||
struct weston_backend base;
|
struct weston_backend base;
|
||||||
struct weston_compositor *compositor;
|
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
|
#ifdef BUILD_DRM_GBM
|
||||||
extern struct drm_fb *
|
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
|
extern bool
|
||||||
drm_can_scanout_dmabuf(struct weston_compositor *ec,
|
drm_can_scanout_dmabuf(struct weston_compositor *ec,
|
||||||
struct linux_dmabuf_buffer *dmabuf);
|
struct linux_dmabuf_buffer *dmabuf);
|
||||||
#else
|
#else
|
||||||
static inline struct drm_fb *
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,7 +220,8 @@ drm_fb_destroy_dmabuf(struct drm_fb *fb)
|
|||||||
|
|
||||||
static struct drm_fb *
|
static struct drm_fb *
|
||||||
drm_fb_get_from_dmabuf(struct linux_dmabuf_buffer *dmabuf,
|
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
|
#ifndef HAVE_GBM_FD_IMPORT
|
||||||
/* Importing a buffer to KMS requires explicit modifiers, so
|
/* 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
|
* 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
|
* not knowing its layout can result in garbage being displayed. In
|
||||||
* short, importing a buffer to KMS requires explicit modifiers. */
|
* 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;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* XXX: TODO:
|
/* XXX: TODO:
|
||||||
*
|
*
|
||||||
@@ -313,8 +318,12 @@ drm_fb_get_from_dmabuf(struct linux_dmabuf_buffer *dmabuf,
|
|||||||
fb->handles[i] = handle.u32;
|
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;
|
goto err_free;
|
||||||
|
}
|
||||||
|
|
||||||
return fb;
|
return fb;
|
||||||
|
|
||||||
@@ -455,7 +464,7 @@ drm_can_scanout_dmabuf(struct weston_compositor *ec,
|
|||||||
struct drm_backend *b = to_drm_backend(ec);
|
struct drm_backend *b = to_drm_backend(ec);
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
fb = drm_fb_get_from_dmabuf(dmabuf, b, true);
|
fb = drm_fb_get_from_dmabuf(dmabuf, b, true, NULL);
|
||||||
if (fb)
|
if (fb)
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
@@ -466,7 +475,8 @@ drm_can_scanout_dmabuf(struct weston_compositor *ec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct drm_fb *
|
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_output *output = state->output;
|
||||||
struct drm_backend *b = to_drm_backend(output->base.compositor);
|
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);
|
dmabuf = linux_dmabuf_buffer_get(buffer->resource);
|
||||||
if (dmabuf) {
|
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)
|
if (!fb)
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -654,7 +654,8 @@ drm_output_prepare_plane_view(struct drm_output_state *state,
|
|||||||
struct weston_view *ev,
|
struct weston_view *ev,
|
||||||
enum drm_output_propose_state_mode mode,
|
enum drm_output_propose_state_mode mode,
|
||||||
struct drm_plane_state *scanout_state,
|
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_output *output = state->output;
|
||||||
struct drm_backend *b = to_drm_backend(output->base.compositor);
|
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;
|
buffer = ev->surface->buffer_ref.buffer;
|
||||||
shmbuf = wl_shm_buffer_get(buffer->resource);
|
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 */
|
/* assemble a list with possible candidates */
|
||||||
wl_list_for_each(plane, &b->plane_list, link) {
|
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)) {
|
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 "
|
drm_debug(b, "\t\t\t\t[plane] not adding plane %d to "
|
||||||
"candidate list: invalid pixel format\n",
|
"candidate list: invalid pixel format\n",
|
||||||
plane->plane_id);
|
plane->plane_id);
|
||||||
@@ -960,7 +963,18 @@ drm_output_propose_state(struct weston_output *output_base,
|
|||||||
current_lowest_zpos);
|
current_lowest_zpos);
|
||||||
ps = drm_output_prepare_plane_view(state, ev, mode,
|
ps = drm_output_prepare_plane_view(state, ev, mode,
|
||||||
scanout_state,
|
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) {
|
if (ps) {
|
||||||
|
|||||||
@@ -416,6 +416,8 @@ struct weston_paint_node {
|
|||||||
|
|
||||||
struct weston_surface_color_transform surf_xform;
|
struct weston_surface_color_transform surf_xform;
|
||||||
bool surf_xform_valid;
|
bool surf_xform_valid;
|
||||||
|
|
||||||
|
uint32_t try_view_on_plane_failure_reasons;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct weston_paint_node *
|
struct weston_paint_node *
|
||||||
|
|||||||
Reference in New Issue
Block a user