[mutter/gbsneto/screencast-improvements: 7/9] stage: Introduce MetaStageWatch and family
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/gbsneto/screencast-improvements: 7/9] stage: Introduce MetaStageWatch and family
- Date: Tue, 18 Jun 2019 01:08:02 +0000 (UTC)
commit e5197ee3496a2ca8b1541b30bfe660a9691000e6
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Mon Jun 17 21:43:05 2019 -0300
stage: Introduce MetaStageWatch and family
MetaStageWatch, watch modes and the watch function are part
of the new stage view watching API. It's design does not
rely on signals on purpose; the number of signals that would
be emitted would be too high, and would impact performance.
MetaStageWatch is an opaque structure outside of MetaStage.
This will be used by the screencast code to monitor a single
view, which has a one-to-one relatioship to logical monitors.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/623
src/backends/meta-stage-private.h | 21 ++++++++
src/backends/meta-stage.c | 103 ++++++++++++++++++++++++++++++++++++++
2 files changed, 124 insertions(+)
---
diff --git a/src/backends/meta-stage-private.h b/src/backends/meta-stage-private.h
index 639d2372c..a8dcc02a1 100644
--- a/src/backends/meta-stage-private.h
+++ b/src/backends/meta-stage-private.h
@@ -27,8 +27,20 @@
G_BEGIN_DECLS
+typedef struct _MetaStageWatch MetaStageWatch;
typedef struct _MetaOverlay MetaOverlay;
+typedef void (*MetaStageWatchFunc) (MetaStage *stage,
+ ClutterStageView *view,
+ gpointer user_data);
+typedef enum
+{
+ META_WATCH_MODE_BEFORE_PAINT,
+ META_WATCH_MODE_AFTER_ACTOR_PAINT,
+ META_WATCH_MODE_AFTER_OVERLAY_PAINT,
+ META_WATCH_MODE_AFTER_PAINT,
+} MetaWatchMode;
+
ClutterActor *meta_stage_new (MetaBackend *backend);
MetaOverlay *meta_stage_create_cursor_overlay (MetaStage *stage);
@@ -43,6 +55,15 @@ void meta_stage_update_cursor_overlay (MetaStage *stage,
void meta_stage_set_active (MetaStage *stage,
gboolean is_active);
+MetaStageWatch * meta_stage_watch_view (MetaStage *stage,
+ ClutterStageView *view,
+ MetaWatchMode watch_mode,
+ MetaStageWatchFunc callback,
+ gpointer user_data);
+
+void meta_stage_remove_watch (MetaStage *stage,
+ MetaStageWatch *watch);
+
G_END_DECLS
#endif /* META_STAGE_PRIVATE_H */
diff --git a/src/backends/meta-stage.c b/src/backends/meta-stage.c
index a98cbc7e2..11475fbc6 100644
--- a/src/backends/meta-stage.c
+++ b/src/backends/meta-stage.c
@@ -30,6 +30,8 @@
#include "meta/meta-monitor-manager.h"
#include "meta/util.h"
+#define N_WATCH_MODES 4
+
enum
{
ACTORS_PAINTED,
@@ -39,6 +41,13 @@ enum
static guint signals[N_SIGNALS];
+struct _MetaStageWatch
+{
+ ClutterStageView *view;
+ MetaStageWatchFunc callback;
+ gpointer user_data;
+};
+
struct _MetaOverlay
{
gboolean enabled;
@@ -55,6 +64,9 @@ struct _MetaStage
{
ClutterStage parent;
+ GPtrArray *watchers[N_WATCH_MODES];
+ ClutterStageView *current_view;
+
GList *overlays;
gboolean is_active;
};
@@ -135,6 +147,7 @@ meta_stage_finalize (GObject *object)
{
MetaStage *stage = META_STAGE (object);
GList *l;
+ int i;
l = stage->overlays;
while (l)
@@ -143,9 +156,33 @@ meta_stage_finalize (GObject *object)
l = g_list_delete_link (l, l);
}
+ for (i = 0; i < N_WATCH_MODES; i++)
+ g_clear_pointer (&stage->watchers[i], g_ptr_array_unref);
+
G_OBJECT_CLASS (meta_stage_parent_class)->finalize (object);
}
+static void
+notify_watchers_for_mode (MetaStage *stage,
+ ClutterStageView *view,
+ MetaWatchMode watch_mode)
+{
+ GPtrArray *watchers;
+ int i;
+
+ watchers = stage->watchers[watch_mode];
+
+ for (i = 0; i < watchers->len; i++)
+ {
+ MetaStageWatch *watch = g_ptr_array_index (watchers, i);
+
+ if (view != watch->view)
+ continue;
+
+ watch->callback (stage, view, watch->user_data);
+ }
+}
+
static void
meta_stage_paint (ClutterActor *actor)
{
@@ -154,10 +191,30 @@ meta_stage_paint (ClutterActor *actor)
CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor);
+ notify_watchers_for_mode (stage, stage->current_view,
+ META_WATCH_MODE_AFTER_ACTOR_PAINT);
+
g_signal_emit (stage, signals[ACTORS_PAINTED], 0);
for (l = stage->overlays; l; l = l->next)
meta_overlay_paint (l->data);
+
+ notify_watchers_for_mode (stage, stage->current_view,
+ META_WATCH_MODE_AFTER_OVERLAY_PAINT);
+}
+
+static void
+meta_stage_paint_view (ClutterStage *stage,
+ ClutterStageView *view)
+{
+ MetaStage *meta_stage = META_STAGE (stage);
+
+ notify_watchers_for_mode (meta_stage, view, META_WATCH_MODE_BEFORE_PAINT);
+
+ meta_stage->current_view = view;
+ CLUTTER_STAGE_CLASS (meta_stage_parent_class)->paint_view (stage, view);
+
+ notify_watchers_for_mode (meta_stage, view, META_WATCH_MODE_AFTER_PAINT);
}
static void
@@ -202,6 +259,7 @@ meta_stage_class_init (MetaStageClass *klass)
stage_class->activate = meta_stage_activate;
stage_class->deactivate = meta_stage_deactivate;
+ stage_class->paint_view = meta_stage_paint_view;
signals[ACTORS_PAINTED] = g_signal_new ("actors-painted",
G_TYPE_FROM_CLASS (klass),
@@ -214,6 +272,10 @@ meta_stage_class_init (MetaStageClass *klass)
static void
meta_stage_init (MetaStage *stage)
{
+ int i;
+
+ for (i = 0; i < N_WATCH_MODES; i++)
+ stage->watchers[i] = g_ptr_array_new_with_free_func (g_free);
}
ClutterActor *
@@ -345,3 +407,44 @@ meta_stage_set_active (MetaStage *stage,
*/
clutter_stage_event (CLUTTER_STAGE (stage), &event);
}
+
+MetaStageWatch *
+meta_stage_watch_view (MetaStage *stage,
+ ClutterStageView *view,
+ MetaWatchMode watch_mode,
+ MetaStageWatchFunc callback,
+ gpointer user_data)
+{
+ MetaStageWatch *watch;
+ GPtrArray *watchers;
+
+ watch = g_new (MetaStageWatch, 1);
+ watch->view = view;
+ watch->callback = callback;
+ watch->user_data = user_data;
+
+ watchers = stage->watchers[watch_mode];
+ g_ptr_array_add (watchers, watch);
+
+ return watch;
+}
+
+void
+meta_stage_remove_watch (MetaStage *stage,
+ MetaStageWatch *watch)
+{
+ GPtrArray *watchers;
+ gboolean removed = FALSE;
+ int i;
+
+ for (i = 0; i < N_WATCH_MODES; i++)
+ {
+ watchers = stage->watchers[i];
+ removed = g_ptr_array_remove_fast (watchers, watch);
+
+ if (removed)
+ break;
+ }
+
+ g_assert (removed);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]