cursor-renderer/native: Replace HW cursor with KMS cursor manager

This removes the old hardware cursor management code and outsources it
to MetaKmsCursorManager. What the native cursor renderer still does,
however, is the preprocessing i.e. rotating/scaling cursor that wouldn't
otherwise be fit for a cursor plane.

The cursor DRM buffers are instead of being per cursor sprite now per
CRTC, meaning we don't need to stop doing hardware cursors if part of
the cursor is on an output that doesn't support it. This is why the
whole scale/transform code changed from being per GPU to per CRTC.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
This commit is contained in:
Jonas Ådahl 2022-12-21 18:59:55 +01:00
parent ade2aa71ed
commit e52641c4b6
4 changed files with 570 additions and 1266 deletions

View File

@ -327,12 +327,11 @@ meta_cursor_renderer_init (MetaCursorRenderer *renderer)
{ {
} }
graphene_rect_t static gboolean
meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer, calculate_sprite_geometry (MetaCursorSprite *cursor_sprite,
MetaCursorSprite *cursor_sprite) graphene_size_t *size,
graphene_point_t *hotspot)
{ {
MetaCursorRendererPrivate *priv =
meta_cursor_renderer_get_instance_private (renderer);
CoglTexture *texture; CoglTexture *texture;
int hot_x, hot_y; int hot_x, hot_y;
int width, height; int width, height;
@ -341,23 +340,39 @@ meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
meta_cursor_sprite_realize_texture (cursor_sprite); meta_cursor_sprite_realize_texture (cursor_sprite);
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite); texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
if (!texture) if (!texture)
return (graphene_rect_t) GRAPHENE_RECT_INIT_ZERO; return FALSE;
meta_cursor_sprite_get_hotspot (cursor_sprite, &hot_x, &hot_y); meta_cursor_sprite_get_hotspot (cursor_sprite, &hot_x, &hot_y);
texture_scale = meta_cursor_sprite_get_texture_scale (cursor_sprite); texture_scale = meta_cursor_sprite_get_texture_scale (cursor_sprite);
width = cogl_texture_get_width (texture); width = cogl_texture_get_width (texture);
height = cogl_texture_get_height (texture); height = cogl_texture_get_height (texture);
return (graphene_rect_t) { *size = (graphene_size_t) {
.origin = { .width = width * texture_scale,
.x = priv->current_x - (hot_x * texture_scale), .height = height * texture_scale
.y = priv->current_y - (hot_y * texture_scale)
},
.size = {
.width = width * texture_scale,
.height = height * texture_scale
}
}; };
*hotspot = (graphene_point_t) {
.x = hot_x * texture_scale,
.y = hot_y * texture_scale
};
return TRUE;
}
graphene_rect_t
meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
{
MetaCursorRendererPrivate *priv =
meta_cursor_renderer_get_instance_private (renderer);
graphene_rect_t rect = GRAPHENE_RECT_INIT_ZERO;
graphene_point_t hotspot;
if (!calculate_sprite_geometry (cursor_sprite, &rect.size, &hotspot))
return GRAPHENE_RECT_INIT_ZERO;
rect.origin = (graphene_point_t) { .x = -hotspot.x, .y = -hotspot.y };
graphene_rect_offset (&rect, priv->current_x, priv->current_y);
return rect;
} }
static float static float

File diff suppressed because it is too large Load Diff

View File

@ -41,8 +41,4 @@ void meta_cursor_renderer_native_prepare_frame (MetaCursorRendererNative *cursor
MetaCursorRendererNative * meta_cursor_renderer_native_new (MetaBackend *backend, MetaCursorRendererNative * meta_cursor_renderer_native_new (MetaBackend *backend,
ClutterInputDevice *device); ClutterInputDevice *device);
void meta_cursor_renderer_native_invalidate_gpu_state (MetaCursorRendererNative *native,
MetaCursorSprite *cursor_sprite,
MetaGpuKms *gpu_kms);
#endif /* META_CURSOR_RENDERER_NATIVE_H */ #endif /* META_CURSOR_RENDERER_NATIVE_H */

View File

@ -55,6 +55,7 @@
#include "backends/native/meta-crtc-kms.h" #include "backends/native/meta-crtc-kms.h"
#include "backends/native/meta-crtc-virtual.h" #include "backends/native/meta-crtc-virtual.h"
#include "backends/native/meta-device-pool.h" #include "backends/native/meta-device-pool.h"
#include "backends/native/meta-kms-cursor-manager.h"
#include "backends/native/meta-kms-device.h" #include "backends/native/meta-kms-device.h"
#include "backends/native/meta-kms.h" #include "backends/native/meta-kms.h"
#include "backends/native/meta-onscreen-native.h" #include "backends/native/meta-onscreen-native.h"
@ -134,11 +135,7 @@ meta_get_renderer_native_parent_vtable (void)
static void static void
meta_renderer_native_gpu_data_free (MetaRendererNativeGpuData *renderer_gpu_data) meta_renderer_native_gpu_data_free (MetaRendererNativeGpuData *renderer_gpu_data)
{ {
MetaRenderer *renderer = META_RENDERER (renderer_gpu_data->renderer_native);
MetaBackend *backend = meta_renderer_get_backend (renderer);
MetaCursorRenderer *cursor_renderer;
MetaGpuKms *gpu_kms = renderer_gpu_data->gpu_kms; MetaGpuKms *gpu_kms = renderer_gpu_data->gpu_kms;
GList *l;
if (renderer_gpu_data->secondary.egl_context != EGL_NO_CONTEXT) if (renderer_gpu_data->secondary.egl_context != EGL_NO_CONTEXT)
{ {
@ -154,26 +151,6 @@ meta_renderer_native_gpu_data_free (MetaRendererNativeGpuData *renderer_gpu_data
NULL); NULL);
} }
cursor_renderer = meta_backend_get_cursor_renderer (backend);
if (cursor_renderer && gpu_kms)
{
MetaCursorRendererNative *cursor_renderer_native =
META_CURSOR_RENDERER_NATIVE (cursor_renderer);
MetaCursorTracker *cursor_tracker =
meta_backend_get_cursor_tracker (backend);
GList *cursor_sprites =
meta_cursor_tracker_peek_cursor_sprites (cursor_tracker);
for (l = cursor_sprites; l; l = l->next)
{
MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (l->data);
meta_cursor_renderer_native_invalidate_gpu_state (cursor_renderer_native,
cursor_sprite,
gpu_kms);
}
}
if (renderer_gpu_data->crtc_needs_flush_handler_id) if (renderer_gpu_data->crtc_needs_flush_handler_id)
{ {
g_clear_signal_handler (&renderer_gpu_data->crtc_needs_flush_handler_id, g_clear_signal_handler (&renderer_gpu_data->crtc_needs_flush_handler_id,
@ -1107,7 +1084,13 @@ static void
meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native) meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native)
{ {
MetaRenderer *renderer = META_RENDERER (renderer_native); MetaRenderer *renderer = META_RENDERER (renderer_native);
MetaBackend *backend = meta_renderer_get_backend (renderer);
MetaKms *kms = meta_backend_native_get_kms (META_BACKEND_NATIVE (backend));
MetaKmsCursorManager *kms_cursor_manager = meta_kms_get_cursor_manager (kms);
GList *l; GList *l;
g_autoptr (GArray) crtc_layouts = NULL;
crtc_layouts = g_array_new (FALSE, TRUE, sizeof (MetaKmsCrtcLayout));
g_clear_list (&renderer_native->pending_mode_set_views, NULL); g_clear_list (&renderer_native->pending_mode_set_views, NULL);
for (l = meta_renderer_get_views (renderer); l; l = l->next) for (l = meta_renderer_get_views (renderer); l; l = l->next)
@ -1118,13 +1101,39 @@ meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native)
if (COGL_IS_ONSCREEN (framebuffer)) if (COGL_IS_ONSCREEN (framebuffer))
{ {
MetaOnscreenNative *onscreen_native =
META_ONSCREEN_NATIVE (framebuffer);
MetaCrtc *crtc;
MetaKmsCrtc *kms_crtc;
MetaRectangle view_layout;
float view_scale;
MetaKmsCrtcLayout crtc_layout;
renderer_native->pending_mode_set_views = renderer_native->pending_mode_set_views =
g_list_prepend (renderer_native->pending_mode_set_views, g_list_prepend (renderer_native->pending_mode_set_views,
stage_view); stage_view);
meta_onscreen_native_invalidate (onscreen_native);
crtc = meta_onscreen_native_get_crtc (onscreen_native);
kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
clutter_stage_view_get_layout (stage_view, &view_layout);
view_scale = clutter_stage_view_get_scale (stage_view);
crtc_layout = (MetaKmsCrtcLayout) {
.crtc = kms_crtc,
.layout = GRAPHENE_RECT_INIT (view_layout.x,
view_layout.y,
view_layout.width,
view_layout.height),
.scale = view_scale,
};
g_array_append_val (crtc_layouts, crtc_layout);
} }
} }
renderer_native->pending_mode_set = TRUE; renderer_native->pending_mode_set = TRUE;
meta_kms_cursor_manager_update_crtc_layout (kms_cursor_manager, crtc_layouts);
meta_topic (META_DEBUG_KMS, "Queue mode set"); meta_topic (META_DEBUG_KMS, "Queue mode set");
} }