From 7e4cae2f91f01db5083622b18d7173c8d9bf6540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 6 Feb 2025 17:34:47 +0100 Subject: [PATCH 1/3] cursor-renderer/native: Pass destination format to scale_and_transform Preparation for next commit, no functional change intended. Part-of: --- src/backends/native/meta-cursor-renderer-native.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c index 103d8e66e11..0db0dde022e 100644 --- a/src/backends/native/meta-cursor-renderer-native.c +++ b/src/backends/native/meta-cursor-renderer-native.c @@ -774,6 +774,7 @@ scale_and_transform_cursor_sprite_cpu (MetaCursorRendererNative *cursor_renderer int height, int rowstride, const graphene_matrix_t *matrix, + CoglPixelFormat dst_format, int dst_width, int dst_height, GError **error) @@ -801,7 +802,7 @@ scale_and_transform_cursor_sprite_cpu (MetaCursorRendererNative *cursor_renderer dst_texture = cogl_texture_2d_new_with_format (cogl_context, dst_width, dst_height, - COGL_PIXEL_FORMAT_BGRA_8888_PRE); + dst_format); offscreen = cogl_offscreen_new_with_texture (dst_texture); if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (offscreen), error)) return NULL; @@ -976,6 +977,7 @@ load_scaled_and_transformed_cursor_sprite (MetaCursorRendererNative *native, height, rowstride, &matrix, + COGL_PIXEL_FORMAT_BGRA_8888_PRE, crtc_dst_width, crtc_dst_height, &error); -- GitLab From 7c447b2627c3a8050a5189dd876b82ddcf317666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 6 Feb 2025 17:43:46 +0100 Subject: [PATCH 2/3] cursor-renderer/native: Store formats in MetaCursorRendererNativeGpuData Instead of hard-coding them everywhere. Preparation for next commit, no behaviour change intended. Part-of: --- .../native/meta-cursor-renderer-native.c | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c index 0db0dde022e..b4a45bfca71 100644 --- a/src/backends/native/meta-cursor-renderer-native.c +++ b/src/backends/native/meta-cursor-renderer-native.c @@ -99,6 +99,8 @@ typedef struct _MetaCursorRendererNativeGpuData { gboolean hw_cursor_broken; + uint32_t drm_format; + CoglPixelFormat cogl_format; uint64_t cursor_width; uint64_t cursor_height; } MetaCursorRendererNativeGpuData; @@ -849,7 +851,10 @@ load_scaled_and_transformed_cursor_sprite (MetaCursorRendererNative *native, { MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native); + MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data; MetaCrtc *crtc = META_CRTC (crtc_kms); + MetaGpu *gpu = meta_crtc_get_gpu (crtc); + MetaGpuKms *gpu_kms = META_GPU_KMS (gpu); MetaLogicalMonitor *logical_monitor; MetaMonitor *monitor; float monitor_scale; @@ -873,6 +878,9 @@ load_scaled_and_transformed_cursor_sprite (MetaCursorRendererNative *native, graphene_point_t hotspot; int hot_x, hot_y; + cursor_renderer_gpu_data = + meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms); + monitor = meta_output_get_monitor (meta_crtc_get_outputs (crtc)->data); logical_monitor = meta_monitor_get_logical_monitor (monitor); @@ -954,7 +962,7 @@ load_scaled_and_transformed_cursor_sprite (MetaCursorRendererNative *native, if (width != crtc_dst_width || height != crtc_dst_height || !graphene_matrix_is_identity (&matrix) || - gbm_format != GBM_FORMAT_ARGB8888 || + gbm_format != cursor_renderer_gpu_data->drm_format || !clutter_color_state_equals (cursor_color_state, target_color_state)) { const MetaFormatInfo *format_info; @@ -977,7 +985,7 @@ load_scaled_and_transformed_cursor_sprite (MetaCursorRendererNative *native, height, rowstride, &matrix, - COGL_PIXEL_FORMAT_BGRA_8888_PRE, + cursor_renderer_gpu_data->cogl_format, crtc_dst_width, crtc_dst_height, &error); @@ -989,11 +997,11 @@ load_scaled_and_transformed_cursor_sprite (MetaCursorRendererNative *native, } bpp = - cogl_pixel_format_get_bytes_per_pixel (COGL_PIXEL_FORMAT_BGRA_8888_PRE, + cogl_pixel_format_get_bytes_per_pixel (cursor_renderer_gpu_data->cogl_format, 0); cursor_rowstride = crtc_dst_width * bpp; cursor_data = g_malloc (crtc_dst_height * cursor_rowstride); - cogl_texture_get_data (texture, COGL_PIXEL_FORMAT_BGRA_8888_PRE, + cogl_texture_get_data (texture, cursor_renderer_gpu_data->cogl_format, cursor_rowstride, cursor_data); @@ -1007,7 +1015,7 @@ load_scaled_and_transformed_cursor_sprite (MetaCursorRendererNative *native, cursor_rowstride, &hotspot, relative_transform, - GBM_FORMAT_ARGB8888); + cursor_renderer_gpu_data->drm_format); } else { @@ -1020,7 +1028,7 @@ load_scaled_and_transformed_cursor_sprite (MetaCursorRendererNative *native, rowstride, &hotspot, MTK_MONITOR_TRANSFORM_NORMAL, - GBM_FORMAT_ARGB8888); + cursor_renderer_gpu_data->drm_format); } return retval; @@ -1285,6 +1293,9 @@ init_hw_cursor_support_for_gpu (MetaGpuKms *gpu_kms) cursor_renderer_gpu_data = meta_create_cursor_renderer_native_gpu_data (gpu_kms); + cursor_renderer_gpu_data->drm_format = DRM_FORMAT_ARGB8888; + cursor_renderer_gpu_data->cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE; + if (!meta_kms_device_get_cursor_size (kms_device, &width, &height)) { width = 64; -- GitLab From f459472cfe121d491ee97fd09a8abdd970dc900a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 6 Feb 2025 18:31:16 +0100 Subject: [PATCH 3/3] cursor-renderer/native: Probe formats supported by cursor planes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Probe all RGBA 8888 variants. If there's a GBM device, prefer a format also supported by GBM, if any. Fall back to dumb BOs otherwise. This allows the HW cursor to work correctly using BGRA8888 on s390x. v2: * Rename get_cursor_format_info → find_cursor_format_info. * Log device path if we can't find any suitable cursor plane format. v3: * Split cursor_planes_support_format helper out of find_cursor_format_info to make logic clearer. (Sebastian Wick) Part-of: --- .../native/meta-cursor-renderer-native.c | 101 +++++++++++++++++- 1 file changed, 96 insertions(+), 5 deletions(-) diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c index b4a45bfca71..7581d9b492c 100644 --- a/src/backends/native/meta-cursor-renderer-native.c +++ b/src/backends/native/meta-cursor-renderer-native.c @@ -51,6 +51,7 @@ #include "backends/native/meta-renderer-native.h" #include "backends/native/meta-seat-native.h" #include "common/meta-cogl-drm-formats.h" +#include "common/meta-drm-format-helpers.h" #include "core/boxes-private.h" #include "meta/boxes.h" #include "meta/meta-backend.h" @@ -99,6 +100,7 @@ typedef struct _MetaCursorRendererNativeGpuData { gboolean hw_cursor_broken; + gboolean use_gbm; uint32_t drm_format; CoglPixelFormat cogl_format; uint64_t cursor_width; @@ -546,11 +548,13 @@ create_cursor_drm_buffer (MetaGpuKms *gpu_kms, uint32_t format, GError **error) { - struct gbm_device *gbm_device; + MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data = + meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms); - gbm_device = meta_gbm_device_from_gpu (gpu_kms); - if (gbm_device) + if (cursor_renderer_gpu_data->use_gbm) { + struct gbm_device *gbm_device = meta_gbm_device_from_gpu (gpu_kms); + return create_cursor_drm_buffer_gbm (gpu_kms, device_file, gbm_device, pixels, width, height, stride, @@ -1283,18 +1287,105 @@ on_monitors_changed (MetaMonitorManager *monitors, meta_cursor_renderer_force_update (renderer); } +static gboolean +cursor_planes_support_format (MetaKmsDevice *kms_device, + const uint32_t format) +{ + gboolean supported = FALSE; + GList *l; + + for (l = meta_kms_device_get_planes (kms_device); l; l = l->next) + { + MetaKmsPlane *plane = l->data; + + if (meta_kms_plane_get_plane_type (plane) != META_KMS_PLANE_TYPE_CURSOR) + continue; + + if (!meta_kms_plane_is_format_supported (plane, format)) + return FALSE; + + supported = TRUE; + } + + return supported; +} + +static const MetaFormatInfo * +find_cursor_format_info (MetaGpuKms *gpu_kms, + struct gbm_device *gbm_device) +{ + MetaKmsDevice *kms_device = meta_gpu_kms_get_kms_device (gpu_kms); + uint32_t formats[] = { + DRM_FORMAT_ARGB8888, + DRM_FORMAT_RGBA8888, + DRM_FORMAT_BGRA8888, + DRM_FORMAT_ABGR8888 + }; + int i; + + for (i = 0; i < G_N_ELEMENTS (formats); i++) + { + if (gbm_device && + !gbm_device_is_format_supported (gbm_device, formats[i], + GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE)) + { + meta_topic (META_DEBUG_KMS, + "GBM doesn't support format 0x%x for %s", + formats[i], meta_kms_device_get_path (kms_device)); + continue; + } + + if (cursor_planes_support_format (kms_device, formats[i])) + return meta_format_info_from_drm_format (formats[i]); + + meta_topic (META_DEBUG_KMS, + "Cursor plane doesn't support format 0x%x for %s", + formats[i], meta_kms_device_get_path (kms_device)); + } + + return NULL; +} + static void init_hw_cursor_support_for_gpu (MetaGpuKms *gpu_kms) { MetaKmsDevice *kms_device = meta_gpu_kms_get_kms_device (gpu_kms); MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data; + const MetaFormatInfo *format_info; + struct gbm_device *gbm_device; uint64_t width, height; + MetaDrmFormatBuf tmp; cursor_renderer_gpu_data = meta_create_cursor_renderer_native_gpu_data (gpu_kms); - cursor_renderer_gpu_data->drm_format = DRM_FORMAT_ARGB8888; - cursor_renderer_gpu_data->cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE; + gbm_device = meta_gbm_device_from_gpu (gpu_kms); + format_info = find_cursor_format_info (gpu_kms, gbm_device); + if (!format_info && gbm_device) + { + gbm_device = NULL; + format_info = find_cursor_format_info (gpu_kms, NULL); + } + + if (!format_info) + { + g_warning ("Couldn't find suitable cursor plane format for %s, " + "disabling HW cursor", + meta_kms_device_get_path (kms_device)); + cursor_renderer_gpu_data->hw_cursor_broken = TRUE; + return; + } + + cursor_renderer_gpu_data->use_gbm = gbm_device != NULL; + cursor_renderer_gpu_data->drm_format = format_info->drm_format; + cursor_renderer_gpu_data->cogl_format = format_info->cogl_format; + + meta_topic (META_DEBUG_KMS, + "Using cursor plane format %s (0x%x) for %s, use_gbm=%d", + meta_drm_format_to_string (&tmp, format_info->drm_format), + format_info->drm_format, + meta_kms_device_get_path (kms_device), + cursor_renderer_gpu_data->use_gbm); if (!meta_kms_device_get_cursor_size (kms_device, &width, &height)) { -- GitLab