[mutter] stage: Implement buffer-transform support in MetaOverlay



commit f804fe3a822ad75b9be4d3f82fe1e50cb8a4ae31
Author: Robert Mader <robert mader posteo de>
Date:   Wed Jun 22 14:08:24 2022 +0200

    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>

 src/backends/meta-cursor-renderer.c | 13 ++++++++-----
 src/backends/meta-stage-private.h   |  9 +++++----
 src/backends/meta-stage.c           | 32 ++++++++++++++++++++++++--------
 3 files changed, 37 insertions(+), 17 deletions(-)
---
diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c
index c4fdbf19e5..feab16f5f8 100644
--- a/src/backends/meta-cursor-renderer.c
+++ b/src/backends/meta-cursor-renderer.c
@@ -135,8 +135,9 @@ meta_cursor_renderer_update_stage_overlay (MetaCursorRenderer *renderer,
 {
   MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
   ClutterActor *stage = meta_backend_get_stage (priv->backend);
-  CoglTexture *texture;
+  CoglTexture *texture = NULL;
   graphene_rect_t rect = GRAPHENE_RECT_INIT_ZERO;
+  MetaMonitorTransform buffer_transform = META_MONITOR_TRANSFORM_NORMAL;
 
   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));
 
   if (cursor_sprite)
-    texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
-  else
-    texture = NULL;
+    {
+      texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
+      buffer_transform =
+        meta_cursor_sprite_get_texture_transform (cursor_sprite);
+    }
 
   meta_overlay_set_visible (priv->stage_overlay, !priv->handled_by_backend);
   meta_stage_update_cursor_overlay (META_STAGE (stage), priv->stage_overlay,
-                                    texture, &rect);
+                                    texture, &rect, buffer_transform);
 }
 
 static void
diff --git a/src/backends/meta-stage-private.h b/src/backends/meta-stage-private.h
index 07534f6e39..e296e274e2 100644
--- a/src/backends/meta-stage-private.h
+++ b/src/backends/meta-stage-private.h
@@ -50,10 +50,11 @@ MetaOverlay      *meta_stage_create_cursor_overlay   (MetaStage   *stage);
 void              meta_stage_remove_cursor_overlay   (MetaStage   *stage,
                                                      MetaOverlay *overlay);
 
-void              meta_stage_update_cursor_overlay   (MetaStage       *stage,
-                                                      MetaOverlay     *overlay,
-                                                      CoglTexture     *texture,
-                                                      graphene_rect_t *rect);
+void              meta_stage_update_cursor_overlay   (MetaStage            *stage,
+                                                      MetaOverlay          *overlay,
+                                                      CoglTexture          *texture,
+                                                      graphene_rect_t      *rect,
+                                                      MetaMonitorTransform  buffer_transform);
 
 void meta_overlay_set_visible (MetaOverlay *overlay,
                                gboolean     is_visible);
diff --git a/src/backends/meta-stage.c b/src/backends/meta-stage.c
index 6f8e3feaed..107265fa63 100644
--- a/src/backends/meta-stage.c
+++ b/src/backends/meta-stage.c
@@ -58,6 +58,8 @@ struct _MetaOverlay
   CoglPipeline *pipeline;
   CoglTexture *texture;
 
+  MetaMonitorTransform buffer_transform;
+
   graphene_rect_t current_rect;
   graphene_rect_t previous_rect;
   gboolean previous_is_valid;
@@ -102,9 +104,10 @@ meta_overlay_free (MetaOverlay *overlay)
 }
 
 static void
-meta_overlay_set (MetaOverlay     *overlay,
-                  CoglTexture     *texture,
-                  graphene_rect_t *rect)
+meta_overlay_set (MetaOverlay          *overlay,
+                  CoglTexture          *texture,
+                  graphene_rect_t      *rect,
+                  MetaMonitorTransform  buffer_transform)
 {
   if (overlay->texture != texture)
     {
@@ -116,6 +119,18 @@ meta_overlay_set (MetaOverlay     *overlay,
         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;
 }
 
@@ -404,12 +419,13 @@ meta_stage_remove_cursor_overlay (MetaStage   *stage,
 }
 
 void
-meta_stage_update_cursor_overlay (MetaStage       *stage,
-                                  MetaOverlay     *overlay,
-                                  CoglTexture     *texture,
-                                  graphene_rect_t *rect)
+meta_stage_update_cursor_overlay (MetaStage            *stage,
+                                  MetaOverlay          *overlay,
+                                  CoglTexture          *texture,
+                                  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);
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]