[mutter] cursor-renderer: Always keep the cursor overlay on the stage



commit fcf7c4d0c77f9d03bbfdc65f2b7a4316c18e50fa
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Wed Jul 29 10:32:58 2020 +0200

    cursor-renderer: Always keep the cursor overlay on the stage
    
    Only when the cursor isn't handled by the backend is the overlay made
    visible. This is intended to be used when painting the stage to an
    offscreen using clutter_stage_paint_to_(frame)buffer() in a way where
    the cursor is always included.
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1391

 src/backends/meta-cursor-renderer.c         | 19 ++++-------
 src/backends/meta-stage-private.h           |  5 +++
 src/backends/meta-stage.c                   | 49 +++++++++++++++++++----------
 src/backends/x11/meta-cursor-renderer-x11.c |  2 +-
 4 files changed, 44 insertions(+), 31 deletions(-)
---
diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c
index 5580136fc8..27c9d73001 100644
--- a/src/backends/meta-cursor-renderer.c
+++ b/src/backends/meta-cursor-renderer.c
@@ -124,8 +124,8 @@ align_cursor_position (MetaCursorRenderer *renderer,
 }
 
 static void
-queue_redraw (MetaCursorRenderer *renderer,
-              MetaCursorSprite   *cursor_sprite)
+update_stage_overlay (MetaCursorRenderer *renderer,
+                      MetaCursorSprite   *cursor_sprite)
 {
   MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
   ClutterActor *stage = meta_backend_get_stage (priv->backend);
@@ -145,11 +145,12 @@ queue_redraw (MetaCursorRenderer *renderer,
   if (!priv->stage_overlay)
     priv->stage_overlay = meta_stage_create_cursor_overlay (META_STAGE (stage));
 
-  if (cursor_sprite && !priv->handled_by_backend)
+  if (cursor_sprite)
     texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
   else
     texture = NULL;
 
+  meta_overlay_set_visible (priv->stage_overlay, !priv->handled_by_backend);
   meta_stage_update_cursor_overlay (META_STAGE (stage), priv->stage_overlay,
                                     texture, &rect);
 }
@@ -334,7 +335,6 @@ meta_cursor_renderer_update_cursor (MetaCursorRenderer *renderer,
 {
   MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
   gboolean handled_by_backend;
-  gboolean should_redraw = FALSE;
 
   if (cursor_sprite)
     meta_cursor_sprite_prepare_at (cursor_sprite,
@@ -345,16 +345,9 @@ meta_cursor_renderer_update_cursor (MetaCursorRenderer *renderer,
     META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer,
                                                               cursor_sprite);
   if (handled_by_backend != priv->handled_by_backend)
-    {
-      priv->handled_by_backend = handled_by_backend;
-      should_redraw = TRUE;
-    }
-
-  if (!handled_by_backend)
-    should_redraw = TRUE;
+    priv->handled_by_backend = handled_by_backend;
 
-  if (should_redraw)
-    queue_redraw (renderer, cursor_sprite);
+  update_stage_overlay (renderer, cursor_sprite);
 }
 
 MetaCursorRenderer *
diff --git a/src/backends/meta-stage-private.h b/src/backends/meta-stage-private.h
index 6a264637c3..03214218fd 100644
--- a/src/backends/meta-stage-private.h
+++ b/src/backends/meta-stage-private.h
@@ -54,6 +54,11 @@ void              meta_stage_update_cursor_overlay   (MetaStage       *stage,
                                                       CoglTexture     *texture,
                                                       graphene_rect_t *rect);
 
+void meta_overlay_set_visible (MetaOverlay *overlay,
+                               gboolean     is_visible);
+
+gboolean meta_overlay_is_visible (MetaOverlay *overlay);
+
 void meta_stage_set_active (MetaStage *stage,
                             gboolean   is_active);
 
diff --git a/src/backends/meta-stage.c b/src/backends/meta-stage.c
index 7d5a5c172d..af56a18f55 100644
--- a/src/backends/meta-stage.c
+++ b/src/backends/meta-stage.c
@@ -50,7 +50,9 @@ struct _MetaStageWatch
 
 struct _MetaOverlay
 {
-  gboolean enabled;
+  MetaStage *stage;
+
+  gboolean is_visible;
 
   CoglPipeline *pipeline;
   CoglTexture *texture;
@@ -75,12 +77,15 @@ struct _MetaStage
 G_DEFINE_TYPE (MetaStage, meta_stage, CLUTTER_TYPE_STAGE);
 
 static MetaOverlay *
-meta_overlay_new (void)
+meta_overlay_new (MetaStage *stage)
 {
+  ClutterBackend *clutter_backend =
+    meta_backend_get_clutter_backend (stage->backend);
+  CoglContext *ctx = clutter_backend_get_cogl_context (clutter_backend);
   MetaOverlay *overlay;
-  CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
 
   overlay = g_slice_new0 (MetaOverlay);
+  overlay->stage = stage;
   overlay->pipeline = cogl_pipeline_new (ctx);
 
   return overlay;
@@ -105,15 +110,9 @@ meta_overlay_set (MetaOverlay     *overlay,
       overlay->texture = texture;
 
       if (texture)
-        {
-          cogl_pipeline_set_layer_texture (overlay->pipeline, 0, texture);
-          overlay->enabled = TRUE;
-        }
+        cogl_pipeline_set_layer_texture (overlay->pipeline, 0, texture);
       else
-        {
-          cogl_pipeline_set_layer_texture (overlay->pipeline, 0, NULL);
-          overlay->enabled = FALSE;
-        }
+        cogl_pipeline_set_layer_texture (overlay->pipeline, 0, NULL);
     }
 
   overlay->current_rect = *rect;
@@ -125,10 +124,11 @@ meta_overlay_paint (MetaOverlay         *overlay,
 {
   CoglFramebuffer *framebuffer;
 
-  if (!overlay->enabled)
+  if (!overlay->texture)
     return;
 
-  g_assert (meta_is_wayland_compositor ());
+  if (!overlay->is_visible)
+    return;
 
   framebuffer = clutter_paint_context_get_framebuffer (paint_context);
   cogl_framebuffer_draw_rectangle (framebuffer,
@@ -345,7 +345,7 @@ queue_redraw_for_overlay (MetaStage   *stage,
     }
 
   /* Draw the overlay at the new position */
-  if (overlay->enabled)
+  if (overlay->is_visible && overlay->texture)
     queue_redraw_clutter_rect (stage, overlay, &overlay->current_rect);
 }
 
@@ -354,7 +354,7 @@ meta_stage_create_cursor_overlay (MetaStage *stage)
 {
   MetaOverlay *overlay;
 
-  overlay = meta_overlay_new ();
+  overlay = meta_overlay_new (stage);
   stage->overlays = g_list_prepend (stage->overlays, overlay);
 
   return overlay;
@@ -380,12 +380,27 @@ meta_stage_update_cursor_overlay (MetaStage       *stage,
                                   CoglTexture     *texture,
                                   graphene_rect_t *rect)
 {
-  g_assert (meta_is_wayland_compositor () || texture == NULL);
-
   meta_overlay_set (overlay, texture, rect);
   queue_redraw_for_overlay (stage, overlay);
 }
 
+void
+meta_overlay_set_visible (MetaOverlay *overlay,
+                          gboolean     is_visible)
+{
+  if (overlay->is_visible == is_visible)
+    return;
+
+  overlay->is_visible = is_visible;
+  queue_redraw_for_overlay (overlay->stage, overlay);
+}
+
+gboolean
+meta_overlay_is_visible (MetaOverlay *overlay)
+{
+  return overlay->is_visible;
+}
+
 void
 meta_stage_set_active (MetaStage *stage,
                        gboolean   is_active)
diff --git a/src/backends/x11/meta-cursor-renderer-x11.c b/src/backends/x11/meta-cursor-renderer-x11.c
index 1f198c130c..4d81f80274 100644
--- a/src/backends/x11/meta-cursor-renderer-x11.c
+++ b/src/backends/x11/meta-cursor-renderer-x11.c
@@ -90,7 +90,7 @@ meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer,
       priv->server_cursor_visible = has_server_cursor;
     }
 
-  if (!priv->server_cursor_visible && cursor_sprite)
+  if (cursor_sprite)
     meta_cursor_sprite_realize_texture (cursor_sprite);
 
   return priv->server_cursor_visible;


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