[mutter] stage: Refactor the cursor drawing code into a generic "overlay" system



commit c7fa446ee7b7096ea6494baf66e4ddd61fb2cfca
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Thu Aug 21 14:47:39 2014 -0400

    stage: Refactor the cursor drawing code into a generic "overlay" system
    
    This isn't really anything but a really small actor system. This will be
    used for DND cursors as well.

 src/backends/meta-stage.c |  142 +++++++++++++++++++++++++++------------------
 1 files changed, 85 insertions(+), 57 deletions(-)
---
diff --git a/src/backends/meta-stage.c b/src/backends/meta-stage.c
index a09e417..d331ec1 100644
--- a/src/backends/meta-stage.c
+++ b/src/backends/meta-stage.c
@@ -28,75 +28,102 @@
 #include <meta/meta-backend.h>
 #include <meta/util.h>
 
-struct _MetaStagePrivate {
-  CoglPipeline *pipeline;
+typedef struct {
+  gboolean enabled;
 
-  MetaCursorReference *cursor;
+  CoglPipeline *pipeline;
+  CoglTexture *texture;
 
   MetaRectangle current_rect;
   MetaRectangle previous_rect;
   gboolean previous_is_valid;
+} MetaOverlay;
+
+struct _MetaStagePrivate {
+  MetaOverlay cursor_overlay;
 };
 typedef struct _MetaStagePrivate MetaStagePrivate;
 
 G_DEFINE_TYPE_WITH_PRIVATE (MetaStage, meta_stage, CLUTTER_TYPE_STAGE);
 
 static void
-update_pipeline (MetaStage *stage)
+meta_overlay_init (MetaOverlay *overlay)
 {
-  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
+  CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
 
-  if (priv->cursor)
-    {
-      CoglTexture *texture = meta_cursor_reference_get_cogl_texture (priv->cursor, NULL, NULL);
-      cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture);
-    }
-  else
-    cogl_pipeline_set_layer_texture (priv->pipeline, 0, NULL);
+  overlay->pipeline = cogl_pipeline_new (ctx);
 }
 
 static void
-meta_stage_finalize (GObject *object)
+meta_overlay_free (MetaOverlay *overlay)
 {
-  MetaStage *stage = META_STAGE (object);
-  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
-
-  if (priv->pipeline)
-    cogl_object_unref (priv->pipeline);
+  if (overlay->pipeline)
+    cogl_object_unref (overlay->pipeline);
 }
 
 static void
-paint_cursor (MetaStage *stage)
+meta_overlay_set (MetaOverlay   *overlay,
+                  CoglTexture   *texture,
+                  MetaRectangle *rect)
 {
-  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
+  if (overlay->texture != texture)
+    {
+      overlay->texture = texture;
+
+      if (texture)
+        {
+          cogl_pipeline_set_layer_texture (overlay->pipeline, 0, texture);
+          overlay->enabled = TRUE;
+        }
+      else
+        {
+          cogl_pipeline_set_layer_texture (overlay->pipeline, 0, NULL);
+          overlay->enabled = FALSE;
+        }
+    }
+
+  overlay->current_rect = *rect;
+}
 
+static void
+meta_overlay_paint (MetaOverlay *overlay)
+{
   g_assert (meta_is_wayland_compositor ());
 
-  if (!priv->cursor)
+  if (!overlay->enabled)
     return;
 
   cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
-                                   priv->pipeline,
-                                   priv->current_rect.x,
-                                   priv->current_rect.y,
-                                   priv->current_rect.x +
-                                   priv->current_rect.width,
-                                   priv->current_rect.y +
-                                   priv->current_rect.height);
-
-  priv->previous_rect = priv->current_rect;
-  priv->previous_is_valid = TRUE;
+                                   overlay->pipeline,
+                                   overlay->current_rect.x,
+                                   overlay->current_rect.y,
+                                   overlay->current_rect.x +
+                                   overlay->current_rect.width,
+                                   overlay->current_rect.y +
+                                   overlay->current_rect.height);
+
+  overlay->previous_rect = overlay->current_rect;
+  overlay->previous_is_valid = TRUE;
+}
+
+static void
+meta_stage_finalize (GObject *object)
+{
+  MetaStage *stage = META_STAGE (object);
+  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
+
+  meta_overlay_free (&priv->cursor_overlay);
 }
 
 static void
 meta_stage_paint (ClutterActor *actor)
 {
   MetaStage *stage = META_STAGE (actor);
+  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
 
   CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor);
 
-  if (meta_is_wayland_compositor ())
-    paint_cursor (stage);
+  meta_overlay_paint (&priv->cursor_overlay);
 }
 
 static void
@@ -113,10 +140,9 @@ meta_stage_class_init (MetaStageClass *klass)
 static void
 meta_stage_init (MetaStage *stage)
 {
-  CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
   MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
 
-  priv->pipeline = cogl_pipeline_new (ctx);
+  meta_overlay_init (&priv->cursor_overlay);
 
   clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), FALSE);
 }
@@ -130,29 +156,29 @@ meta_stage_new (void)
 }
 
 static void
-queue_redraw (MetaStage *stage)
+queue_redraw_for_overlay (MetaStage   *stage,
+                          MetaOverlay *overlay)
 {
-  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
   cairo_rectangle_int_t clip;
 
-  /* Clear the location the cursor was at before, if we need to. */
-  if (priv->previous_is_valid)
+  /* Clear the location the overlay was at before, if we need to. */
+  if (overlay->previous_is_valid)
     {
-      clip.x = priv->previous_rect.x;
-      clip.y = priv->previous_rect.y;
-      clip.width = priv->previous_rect.width;
-      clip.height = priv->previous_rect.height;
+      clip.x = overlay->previous_rect.x;
+      clip.y = overlay->previous_rect.y;
+      clip.width = overlay->previous_rect.width;
+      clip.height = overlay->previous_rect.height;
       clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip);
-      priv->previous_is_valid = FALSE;
+      overlay->previous_is_valid = FALSE;
     }
 
-  /* And queue a redraw for the current cursor location. */
-  if (priv->cursor)
+  /* Draw the overlay at the new position */
+  if (overlay->enabled)
     {
-      clip.x = priv->current_rect.x;
-      clip.y = priv->current_rect.y;
-      clip.width = priv->current_rect.width;
-      clip.height = priv->current_rect.height;
+      clip.x = overlay->current_rect.x;
+      clip.y = overlay->current_rect.y;
+      clip.width = overlay->current_rect.width;
+      clip.height = overlay->current_rect.height;
       clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip);
     }
 }
@@ -163,13 +189,15 @@ meta_stage_set_cursor (MetaStage           *stage,
                        MetaRectangle       *rect)
 {
   MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
+  CoglTexture *texture;
 
-  if (priv->cursor != cursor)
-    {
-      priv->cursor = cursor;
-      update_pipeline (stage);
-    }
+  g_assert (meta_is_wayland_compositor ());
+
+  if (cursor)
+    texture = meta_cursor_reference_get_cogl_texture (cursor, NULL, NULL);
+  else
+    texture = NULL;
 
-  priv->current_rect = *rect;
-  queue_redraw (stage);
+  meta_overlay_set (&priv->cursor_overlay, texture, rect);
+  queue_redraw_for_overlay (stage, &priv->cursor_overlay);
 }


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