cursor-renderer/native: Don't put opaque buffers in cursor plane

Cursor planes tend to be ARGB8888 and support no other format (ideally
we should not hard code this, but un-hard-coding that is for another
day), and if we put e.g. a XRGB8888 buffer in there, it'll either result
in the gbm_bo allocation failing (it doesn't allow USE_CURSOR with any
other format) or mode setting failing if using  dumb buffers directly.
In the former case, we'll fall back to OpenGL indefinitely, and in the
latter, we'll have failed mode sets as long as we try to set the invalid
cursor buffer as the cursor plane.

Change things to process all buffers that are not ARGB8888 using the
scale/rotate machinery we already have, turning XRGB8888 into ARGB8888.

Related: https://gitlab.gnome.org/GNOME/mutter/-/issues/2477
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2698>
This commit is contained in:
Jonas Ådahl 2022-11-16 16:32:24 +01:00 committed by Marge Bot
parent 6b77532a23
commit a1d14a6176

View File

@ -1464,6 +1464,7 @@ is_cursor_scale_and_transform_valid (MetaCursorRenderer *renderer,
static cairo_surface_t *
scale_and_transform_cursor_sprite_cpu (uint8_t *pixels,
cairo_format_t pixel_format,
int width,
int height,
int rowstride,
@ -1521,7 +1522,7 @@ scale_and_transform_cursor_sprite_cpu (uint8_t *pixels,
cairo_scale (cr, scale, scale);
source_surface = cairo_image_surface_create_for_data (pixels,
CAIRO_FORMAT_ARGB32,
pixel_format,
width,
height,
rowstride);
@ -1534,6 +1535,21 @@ scale_and_transform_cursor_sprite_cpu (uint8_t *pixels,
return target_surface;
}
static cairo_format_t
gbm_format_to_cairo_format (uint32_t gbm_format)
{
switch (gbm_format)
{
case GBM_FORMAT_XRGB8888:
return CAIRO_FORMAT_RGB24;
default:
g_warn_if_reached ();
G_GNUC_FALLTHROUGH;
case GBM_FORMAT_ARGB8888:
return CAIRO_FORMAT_ARGB32;
}
}
static void
load_scaled_and_transformed_cursor_sprite (MetaCursorRendererNative *native,
MetaGpuKms *gpu_kms,
@ -1547,11 +1563,15 @@ load_scaled_and_transformed_cursor_sprite (MetaCursorRendererNative *native,
uint32_t gbm_format)
{
if (!G_APPROX_VALUE (relative_scale, 1.f, FLT_EPSILON) ||
relative_transform != META_MONITOR_TRANSFORM_NORMAL)
relative_transform != META_MONITOR_TRANSFORM_NORMAL ||
gbm_format != GBM_FORMAT_ARGB8888)
{
cairo_surface_t *surface;
cairo_format_t cairo_format;
cairo_format = gbm_format_to_cairo_format (gbm_format),
surface = scale_and_transform_cursor_sprite_cpu (data,
cairo_format,
width,
height,
rowstride,
@ -1565,7 +1585,7 @@ load_scaled_and_transformed_cursor_sprite (MetaCursorRendererNative *native,
cairo_image_surface_get_width (surface),
cairo_image_surface_get_width (surface),
cairo_image_surface_get_stride (surface),
gbm_format);
GBM_FORMAT_ARGB8888);
cairo_surface_destroy (surface);
}