From 658f66216ad8e2a62c981e50f0de31fd553044c8 Mon Sep 17 00:00:00 2001 From: Derek Foreman Date: Wed, 10 Sep 2025 13:26:12 -0500 Subject: [PATCH] drm: Fix crash on hardware without cursor planes In a2a6030902c780d265a3442c96fffb6968e0d3ba I introduced a crash when no cursor plane exists. Fix this by pulling the cursor plane tests into their own function and doing an early return when we have a conclusive no-cursor failure state. Fixes a2a6030902c780d265a3442c96fffb6968e0d3ba Signed-off-by: Derek Foreman --- libweston/backend-drm/state-propose.c | 69 +++++++++++++++++---------- 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/libweston/backend-drm/state-propose.c b/libweston/backend-drm/state-propose.c index 40999b2a6..13a827241 100644 --- a/libweston/backend-drm/state-propose.c +++ b/libweston/backend-drm/state-propose.c @@ -444,6 +444,48 @@ dmabuf_feedback_maybe_update(struct drm_device *device, struct weston_view *ev, dmabuf_feedback->action_needed = ACTION_NEEDED_NONE; } +static void +try_pnode_on_cursor_plane(struct drm_output *output, struct weston_paint_node *pnode) +{ + struct drm_device *device = output->device; + struct drm_backend *b = device->backend; + struct weston_buffer *buffer = pnode->view->surface->buffer_ref.buffer; + struct weston_view *ev = pnode->view; + + if (!output->cursor_plane || device->cursors_are_broken) { + pnode->try_view_on_plane_failure_reasons |= + FAILURE_REASONS_BUFFER_TYPE; + /* SHM buffers can only be placed on a cursor plane, so if + * cursors aren't available skip all the following tests, + * we already have the only failure reason that matters. + */ + return; + } + + /* Even though this is a SHM buffer, pixel_format stores + * the format code as DRM FourCC */ + if (buffer->pixel_format->format != DRM_FORMAT_ARGB8888) { + drm_debug(b, "\t\t\t\t[view] not placing view %p on " + "plane; SHM buffers must be ARGB8888 for " + "cursor view\n", ev); + pnode->try_view_on_plane_failure_reasons |= + FAILURE_REASONS_FB_FORMAT_INCOMPATIBLE; + } + + if (buffer->width > device->cursor_width || + buffer->height > device->cursor_height) { + drm_debug(b, "\t\t\t\t[view] not assigning view %p to plane " + "(buffer (%dx%d) too large for cursor plane)\n", + ev, buffer->width, buffer->height); + pnode->try_view_on_plane_failure_reasons |= + FAILURE_REASONS_BUFFER_TOO_BIG; + } + + if (!drm_paint_node_transform_supported(pnode, output->cursor_plane)) + pnode->try_view_on_plane_failure_reasons |= + FAILURE_REASONS_INCOMPATIBLE_TRANSFORM; +} + static struct drm_plane_state * drm_output_find_plane_for_view(struct drm_output_state *state, struct weston_paint_node *pnode, @@ -499,32 +541,7 @@ drm_output_find_plane_for_view(struct drm_output_state *state, pnode->try_view_on_plane_failure_reasons |= FAILURE_REASONS_BUFFER_TYPE; } else if (buffer->type == WESTON_BUFFER_SHM) { - if (!output->cursor_plane || device->cursors_are_broken) - pnode->try_view_on_plane_failure_reasons |= - FAILURE_REASONS_BUFFER_TYPE; - - /* Even though this is a SHM buffer, pixel_format stores - * the format code as DRM FourCC */ - if (buffer->pixel_format->format != DRM_FORMAT_ARGB8888) { - drm_debug(b, "\t\t\t\t[view] not placing view %p on " - "plane; SHM buffers must be ARGB8888 for " - "cursor view\n", ev); - pnode->try_view_on_plane_failure_reasons |= - FAILURE_REASONS_FB_FORMAT_INCOMPATIBLE; - } - - if (buffer->width > device->cursor_width || - buffer->height > device->cursor_height) { - drm_debug(b, "\t\t\t\t[view] not assigning view %p to plane " - "(buffer (%dx%d) too large for cursor plane)\n", - ev, buffer->width, buffer->height); - pnode->try_view_on_plane_failure_reasons |= - FAILURE_REASONS_BUFFER_TOO_BIG; - } - - if (!drm_paint_node_transform_supported(pnode, output->cursor_plane)) - pnode->try_view_on_plane_failure_reasons = - FAILURE_REASONS_INCOMPATIBLE_TRANSFORM; + try_pnode_on_cursor_plane(output, pnode); if (pnode->try_view_on_plane_failure_reasons == FAILURE_REASONS_NONE) possible_plane_mask = (1 << output->cursor_plane->plane_idx);