[mutter/gbsneto/screencast-improvements: 15/18] clutter/stage: Add ClutterStage:paint-view



commit 4a196288290223b3cf9bc51e7865792a63922f9d
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Mon Jun 17 21:33:42 2019 -0300

    clutter/stage: Add ClutterStage:paint-view
    
    Now that ClutterStageView is embraced as part of the public
    set of Clutter classes, is it possible to give consumers
    of this API more information and control over the drawing
    routines of ClutterStage.
    
    Introduce ClutterStage:paint-view, a signal that is emitted
    for painting a specific view. It's defined as a RUN_LAST
    signal to give anyone connecting to it the ability to run
    before the view is actually painted, or after (using the
    G_CONNECT_AFTER flag, or g_signal_connect_after).
    
    This signal has a corresponding class handler, which allows
    Mutter to have much finer control over the painting routines.
    In fact, this will allow us to implement a "paint phase watcher"
    mechanism in the following patches.
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/623

 clutter/clutter/clutter-stage.c | 47 ++++++++++++++++++++++++++++++++++++++++-
 clutter/clutter/clutter-stage.h |  5 ++++-
 2 files changed, 50 insertions(+), 2 deletions(-)
---
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index bb7227221..c95c47327 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -149,6 +149,8 @@ struct _ClutterStagePrivate
   gpointer paint_data;
   GDestroyNotify paint_notify;
 
+  cairo_rectangle_int_t view_clip;
+
   int update_freeze_count;
 
   guint relayout_pending       : 1;
@@ -186,6 +188,7 @@ enum
   DEACTIVATE,
   DELETE_EVENT,
   AFTER_PAINT,
+  PAINT_VIEW,
   PRESENTED,
 
   LAST_SIGNAL
@@ -682,7 +685,15 @@ _clutter_stage_paint_view (ClutterStage                *stage,
 
   COGL_TRACE_BEGIN_SCOPED (ClutterStagePaintView, "Paint (view)");
 
-  clutter_stage_do_paint_view (stage, view, clip);
+  priv->view_clip = *clip;
+
+  if (g_signal_has_handler_pending (stage, stage_signals[PAINT_VIEW],
+                                    0, TRUE))
+    g_signal_emit (stage, stage_signals[PAINT_VIEW], 0, view);
+  else
+    CLUTTER_STAGE_GET_CLASS (stage)->paint_view (stage, view);
+
+  priv->view_clip = (cairo_rectangle_int_t) { 0 };
 }
 
 void
@@ -1851,6 +1862,16 @@ clutter_stage_finalize (GObject *object)
   G_OBJECT_CLASS (clutter_stage_parent_class)->finalize (object);
 }
 
+static void
+clutter_stage_real_paint_view (ClutterStage     *stage,
+                               ClutterStageView *view)
+{
+  ClutterStagePrivate *priv = stage->priv;
+  const cairo_rectangle_int_t *clip = &priv->view_clip;
+
+  clutter_stage_do_paint_view (stage, view, clip);
+}
+
 static void
 clutter_stage_class_init (ClutterStageClass *klass)
 {
@@ -1880,6 +1901,8 @@ clutter_stage_class_init (ClutterStageClass *klass)
   actor_class->queue_redraw = clutter_stage_real_queue_redraw;
   actor_class->apply_transform = clutter_stage_real_apply_transform;
 
+  klass->paint_view = clutter_stage_real_paint_view;
+
   /**
    * ClutterStage:cursor-visible:
    *
@@ -2123,6 +2146,28 @@ clutter_stage_class_init (ClutterStageClass *klass)
                   NULL, NULL, NULL,
                   G_TYPE_NONE, 0);
 
+  /**
+   * ClutterStage::paint-view:
+   * @stage: the stage that received the event
+   * @view: a #ClutterStageView
+   *
+   * The ::paint-view signal is emitted before a #ClutterStageView is being
+   * painted.
+   *
+   * The view is painted in the default handler. Hence, if you want to perform
+   * some action after the view is painted, like reading the contents of the
+   * framebuffer, use g_signal_connect_after() or pass %G_CONNECT_AFTER.
+   */
+  stage_signals[PAINT_VIEW] =
+    g_signal_new (I_("paint-view"),
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (ClutterStageClass, paint_view),
+                  NULL, NULL,
+                  _clutter_marshal_VOID__OBJECT,
+                  G_TYPE_NONE, 1,
+                  CLUTTER_TYPE_STAGE_VIEW);
+
   /**
    * ClutterStage::presented: (skip)
    * @stage: the stage that received the event
diff --git a/clutter/clutter/clutter-stage.h b/clutter/clutter/clutter-stage.h
index f7e697f2c..c28904bd0 100644
--- a/clutter/clutter/clutter-stage.h
+++ b/clutter/clutter/clutter-stage.h
@@ -84,9 +84,12 @@ struct _ClutterStageClass
   gboolean (* delete_event) (ClutterStage *stage,
                              ClutterEvent *event);
 
+  void (* paint_view) (ClutterStage     *stage,
+                       ClutterStageView *view);
+
   /*< private >*/
   /* padding for future expansion */
-  gpointer _padding_dummy[31];
+  gpointer _padding_dummy[30];
 };
 
 /**


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