Skip to content

Instantly share code, notes, and snippets.

@sonald
Created January 20, 2017 01:52
Show Gist options
  • Save sonald/2b7fd83c2e357fe92b815e34150e858f to your computer and use it in GitHub Desktop.
Save sonald/2b7fd83c2e357fe92b815e34150e858f to your computer and use it in GitHub Desktop.
From e5a8564a214e32e9c83478547ede7f79ac412cf7 Mon Sep 17 00:00:00 2001
From: Sian Cao <yinshuiboy@gmail.com>
Date: Mon, 28 Nov 2016 11:10:32 +0800
Subject: [PATCH] Support actors(blur) to be always redrawn
Blur actors needs to be redrawn every frame which obey clutter's redraw
policy. So we need a way to bypass it.
---
clutter/clutter-stage.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++
clutter/clutter-stage.h | 10 ++++++++-
2 files changed, 64 insertions(+), 1 deletion(-)
diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c
index 2c67ca3..663a7ec 100644
--- a/clutter/clutter-stage.c
+++ b/clutter/clutter-stage.c
@@ -129,6 +129,7 @@ struct _ClutterStagePrivate
ClutterPlane current_clip_planes[4];
GList *pending_queue_redraws;
+ GList *always_redraw_actors;
CoglFramebuffer *active_framebuffer;
@@ -1335,6 +1336,47 @@ clutter_stage_get_redraw_clip_bounds (ClutterStage *stage,
}
}
+void
+clutter_stage_add_always_redraw_clip (ClutterStage *stage,
+ cairo_rectangle_int_t *clip)
+{
+ ClutterStageWindow *stage_window;
+
+ stage_window = _clutter_stage_get_window (stage);
+ if (stage_window == NULL)
+ return;
+
+ _clutter_stage_window_add_redraw_clip (stage_window, clip);
+}
+
+void
+clutter_stage_add_always_redraw_actor (ClutterStage *stage,
+ ClutterActor *actor)
+{
+ ClutterStagePrivate *priv;
+
+ g_return_if_fail (CLUTTER_IS_STAGE (stage));
+ g_return_if_fail (CLUTTER_IS_ACTOR (actor));
+
+ priv = stage->priv;
+
+ priv->always_redraw_actors = g_list_prepend (priv->always_redraw_actors, actor);
+}
+
+void
+clutter_stage_remove_always_redraw_actor (ClutterStage *stage,
+ ClutterActor *actor)
+{
+ ClutterStagePrivate *priv;
+
+ g_return_if_fail (CLUTTER_IS_STAGE (stage));
+ g_return_if_fail (CLUTTER_IS_ACTOR (actor));
+
+ priv = stage->priv;
+
+ priv->always_redraw_actors = g_list_remove (priv->always_redraw_actors, actor);
+}
+
static void
read_pixels_to_file (char *filename_stem,
int x,
@@ -1721,6 +1763,9 @@ clutter_stage_dispose (GObject *object)
(GDestroyNotify) free_queue_redraw_entry);
priv->pending_queue_redraws = NULL;
+ g_list_free (priv->always_redraw_actors);
+ priv->always_redraw_actors = NULL;
+
/* this will release the reference on the stage */
stage_manager = clutter_stage_manager_get_default ();
_clutter_stage_manager_remove_stage (stage_manager, stage);
@@ -4049,6 +4094,16 @@ _clutter_stage_queue_redraw_entry_invalidate (ClutterStageQueueRedrawEntry *entr
static void
clutter_stage_maybe_finish_queue_redraws (ClutterStage *stage)
{
+ /**
+ * add always_redraws
+ */
+ {
+ GList *l = stage->priv->always_redraw_actors;
+ for (; l; l = l->next) {
+ clutter_actor_queue_redraw(l->data);
+ }
+ }
+
/* Note: we have to repeat until the pending_queue_redraws list is
* empty because actors are allowed to queue redraws in response to
* the queue-redraw signal. For example Clone actors or
diff --git a/clutter/clutter-stage.h b/clutter/clutter-stage.h
index 8a55efb..fdea52b 100644
--- a/clutter/clutter-stage.h
+++ b/clutter/clutter-stage.h
@@ -229,7 +229,15 @@ guchar * clutter_stage_read_pixels (ClutterStage
CLUTTER_AVAILABLE_IN_ALL
void clutter_stage_get_redraw_clip_bounds (ClutterStage *stage,
cairo_rectangle_int_t *clip);
-
+CLUTTER_AVAILABLE_IN_ALL
+void clutter_stage_add_always_redraw_clip (ClutterStage *stage,
+ cairo_rectangle_int_t *clip);
+CLUTTER_AVAILABLE_IN_ALL
+void clutter_stage_add_always_redraw_actor (ClutterStage *stage,
+ ClutterActor *actor);
+CLUTTER_AVAILABLE_IN_ALL
+void clutter_stage_remove_always_redraw_actor (ClutterStage *stage,
+ ClutterActor *actor);
CLUTTER_AVAILABLE_IN_ALL
void clutter_stage_ensure_current (ClutterStage *stage);
CLUTTER_AVAILABLE_IN_ALL
--
2.8.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment