stage: Implement buffer-transform support in MetaOverlay

This allows the GL fallback path to correctly paint the cursor
if clients pre-rotated the buffer using
`wl_surface::set_buffer_transform`, visually matching the
hardware cursor path.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/344>
This commit is contained in:
Robert Mader 2022-06-22 14:08:24 +02:00
parent df27017ba3
commit f804fe3a82
3 changed files with 37 additions and 17 deletions

View File

@ -135,8 +135,9 @@ meta_cursor_renderer_update_stage_overlay (MetaCursorRenderer *renderer,
{ {
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
ClutterActor *stage = meta_backend_get_stage (priv->backend); ClutterActor *stage = meta_backend_get_stage (priv->backend);
CoglTexture *texture; CoglTexture *texture = NULL;
graphene_rect_t rect = GRAPHENE_RECT_INIT_ZERO; graphene_rect_t rect = GRAPHENE_RECT_INIT_ZERO;
MetaMonitorTransform buffer_transform = META_MONITOR_TRANSFORM_NORMAL;
g_set_object (&priv->overlay_cursor, cursor_sprite); g_set_object (&priv->overlay_cursor, cursor_sprite);
@ -150,13 +151,15 @@ meta_cursor_renderer_update_stage_overlay (MetaCursorRenderer *renderer,
priv->stage_overlay = meta_stage_create_cursor_overlay (META_STAGE (stage)); priv->stage_overlay = meta_stage_create_cursor_overlay (META_STAGE (stage));
if (cursor_sprite) if (cursor_sprite)
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite); {
else texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
texture = NULL; buffer_transform =
meta_cursor_sprite_get_texture_transform (cursor_sprite);
}
meta_overlay_set_visible (priv->stage_overlay, !priv->handled_by_backend); meta_overlay_set_visible (priv->stage_overlay, !priv->handled_by_backend);
meta_stage_update_cursor_overlay (META_STAGE (stage), priv->stage_overlay, meta_stage_update_cursor_overlay (META_STAGE (stage), priv->stage_overlay,
texture, &rect); texture, &rect, buffer_transform);
} }
static void static void

View File

@ -50,10 +50,11 @@ MetaOverlay *meta_stage_create_cursor_overlay (MetaStage *stage);
void meta_stage_remove_cursor_overlay (MetaStage *stage, void meta_stage_remove_cursor_overlay (MetaStage *stage,
MetaOverlay *overlay); MetaOverlay *overlay);
void meta_stage_update_cursor_overlay (MetaStage *stage, void meta_stage_update_cursor_overlay (MetaStage *stage,
MetaOverlay *overlay, MetaOverlay *overlay,
CoglTexture *texture, CoglTexture *texture,
graphene_rect_t *rect); graphene_rect_t *rect,
MetaMonitorTransform buffer_transform);
void meta_overlay_set_visible (MetaOverlay *overlay, void meta_overlay_set_visible (MetaOverlay *overlay,
gboolean is_visible); gboolean is_visible);

View File

@ -58,6 +58,8 @@ struct _MetaOverlay
CoglPipeline *pipeline; CoglPipeline *pipeline;
CoglTexture *texture; CoglTexture *texture;
MetaMonitorTransform buffer_transform;
graphene_rect_t current_rect; graphene_rect_t current_rect;
graphene_rect_t previous_rect; graphene_rect_t previous_rect;
gboolean previous_is_valid; gboolean previous_is_valid;
@ -102,9 +104,10 @@ meta_overlay_free (MetaOverlay *overlay)
} }
static void static void
meta_overlay_set (MetaOverlay *overlay, meta_overlay_set (MetaOverlay *overlay,
CoglTexture *texture, CoglTexture *texture,
graphene_rect_t *rect) graphene_rect_t *rect,
MetaMonitorTransform buffer_transform)
{ {
if (overlay->texture != texture) if (overlay->texture != texture)
{ {
@ -116,6 +119,18 @@ meta_overlay_set (MetaOverlay *overlay,
cogl_pipeline_set_layer_texture (overlay->pipeline, 0, NULL); cogl_pipeline_set_layer_texture (overlay->pipeline, 0, NULL);
} }
if (overlay->buffer_transform != buffer_transform)
{
graphene_matrix_t matrix;
graphene_matrix_init_identity (&matrix);
meta_monitor_transform_transform_matrix (buffer_transform,
&matrix);
cogl_pipeline_set_layer_matrix (overlay->pipeline, 0, &matrix);
overlay->buffer_transform = buffer_transform;
}
overlay->current_rect = *rect; overlay->current_rect = *rect;
} }
@ -404,12 +419,13 @@ meta_stage_remove_cursor_overlay (MetaStage *stage,
} }
void void
meta_stage_update_cursor_overlay (MetaStage *stage, meta_stage_update_cursor_overlay (MetaStage *stage,
MetaOverlay *overlay, MetaOverlay *overlay,
CoglTexture *texture, CoglTexture *texture,
graphene_rect_t *rect) graphene_rect_t *rect,
MetaMonitorTransform buffer_transform)
{ {
meta_overlay_set (overlay, texture, rect); meta_overlay_set (overlay, texture, rect, buffer_transform);
queue_redraw_for_overlay (stage, overlay); queue_redraw_for_overlay (stage, overlay);
} }