[gtk+/wip/frame-synchronization: 4/33] GdkPaintClock: Make the phase explicit when requesting the frame
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/frame-synchronization: 4/33] GdkPaintClock: Make the phase explicit when requesting the frame
- Date: Tue, 4 Dec 2012 17:58:22 +0000 (UTC)
commit 8e9a30c4c133cc76765af3cd3bbf9cff56ab6f52
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Wed Oct 3 19:38:40 2012 -0400
GdkPaintClock: Make the phase explicit when requesting the frame
Instead of having gdk_paint_clock_request_frame() have
gdk_paint_clock_request_phase() where we can say what phase we need.
This allows us to know if we get a frame-request during layout whether
it's just a request for drawing from the layout, or whether another
layout phase is needed.
https://bugzilla.gnome.org/show_bug.cgi?id=685460
gdk/gdkpaintclock.c | 43 ++++++-------------------
gdk/gdkpaintclock.h | 23 ++++++++++---
gdk/gdkpaintclockidle.c | 79 ++++++++++++++++++++++++++++++++++-------------
gdk/gdkwindow.c | 3 +-
gtk/gtkcontainer.c | 6 ++-
gtk/gtkwidget.c | 2 +-
6 files changed, 91 insertions(+), 65 deletions(-)
---
diff --git a/gdk/gdkpaintclock.c b/gdk/gdkpaintclock.c
index c27839a..5de34d6 100644
--- a/gdk/gdkpaintclock.c
+++ b/gdk/gdkpaintclock.c
@@ -47,7 +47,7 @@
* for example.
*
* A paint clock is idle until someone requests a frame with
- * gdk_paint_clock_request_frame(). At that time, the paint clock
+ * gdk_paint_clock_request_phase(). At that time, the paint clock
* emits its GdkPaintClock:frame-requested signal if no frame was
* already pending.
*
@@ -203,7 +203,7 @@ gdk_paint_clock_get_frame_time (GdkPaintClock *clock)
}
/**
- * gdk_paint_clock_request_frame:
+ * gdk_paint_clock_request_phase:
* @clock: the clock
*
* Asks the frame clock to paint a frame. The frame
@@ -217,15 +217,17 @@ gdk_paint_clock_get_frame_time (GdkPaintClock *clock)
* Since: 3.0
*/
void
-gdk_paint_clock_request_frame (GdkPaintClock *clock)
+gdk_paint_clock_request_phase (GdkPaintClock *clock,
+ GdkPaintClockPhase phase)
{
g_return_if_fail (GDK_IS_PAINT_CLOCK (clock));
- GDK_PAINT_CLOCK_GET_IFACE (clock)->request_frame (clock);
+ GDK_PAINT_CLOCK_GET_IFACE (clock)->request_phase (clock, phase);
}
+
/**
- * gdk_paint_clock_get_frame_requested:
+ * gdk_paint_clock_get_requested:
* @clock: the clock
*
* Gets whether a frame paint has been requested but has not been
@@ -235,12 +237,12 @@ gdk_paint_clock_request_frame (GdkPaintClock *clock)
* Since: 3.0
* Return value: TRUE if a frame paint is pending
*/
-gboolean
-gdk_paint_clock_get_frame_requested (GdkPaintClock *clock)
+GdkPaintClockPhase
+gdk_paint_clock_get_requested (GdkPaintClock *clock)
{
g_return_val_if_fail (GDK_IS_PAINT_CLOCK (clock), FALSE);
- return GDK_PAINT_CLOCK_GET_IFACE (clock)->get_frame_requested (clock);
+ return GDK_PAINT_CLOCK_GET_IFACE (clock)->get_requested (clock);
}
/**
@@ -281,28 +283,3 @@ gdk_paint_clock_frame_requested (GdkPaintClock *clock)
g_signal_emit (G_OBJECT (clock),
signals[FRAME_REQUESTED], 0);
}
-
-/**
- * gdk_paint_clock_paint:
- * @clock: the clock
- *
- * Emits the before-paint, paint, and after-paint signals. Used in
- * implementations of the #GdkPaintClock interface.
- */
-void
-gdk_paint_clock_paint (GdkPaintClock *clock)
-{
- g_return_if_fail (GDK_IS_PAINT_CLOCK (clock));
-
- g_signal_emit (G_OBJECT (clock),
- signals[BEFORE_PAINT], 0);
-
- g_signal_emit (G_OBJECT (clock),
- signals[LAYOUT], 0);
-
- g_signal_emit (G_OBJECT (clock),
- signals[PAINT], 0);
-
- g_signal_emit (G_OBJECT (clock),
- signals[AFTER_PAINT], 0);
-}
diff --git a/gdk/gdkpaintclock.h b/gdk/gdkpaintclock.h
index 40d92da..0bafc1e 100644
--- a/gdk/gdkpaintclock.h
+++ b/gdk/gdkpaintclock.h
@@ -43,18 +43,28 @@ G_BEGIN_DECLS
typedef struct _GdkPaintClock GdkPaintClock;
typedef struct _GdkPaintClockInterface GdkPaintClockInterface;
+typedef enum {
+ GDK_PAINT_CLOCK_PHASE_NONE = 0,
+ GDK_PAINT_CLOCK_PHASE_BEFORE_PAINT = 1 << 0,
+ GDK_PAINT_CLOCK_PHASE_LAYOUT = 1 << 1,
+ GDK_PAINT_CLOCK_PHASE_PAINT = 1 << 2,
+ GDK_PAINT_CLOCK_PHASE_AFTER_PAINT = 1 << 3
+} GdkPaintClockPhase;
+
struct _GdkPaintClockInterface
{
GTypeInterface base_iface;
guint64 (* get_frame_time) (GdkPaintClock *clock);
- void (* request_frame) (GdkPaintClock *clock);
- gboolean (* get_frame_requested) (GdkPaintClock *clock);
+
+ void (* request_phase) (GdkPaintClock *clock,
+ GdkPaintClockPhase phase);
+ GdkPaintClockPhase (* get_requested) (GdkPaintClock *clock);
/* signals */
/* void (* frame_requested) (GdkPaintClock *clock); */
/* void (* before_paint) (GdkPaintClock *clock); */
- /* void (* layout) 1(GdkPaintClock *clock); */
+ /* void (* layout) (GdkPaintClock *clock); */
/* void (* paint) (GdkPaintClock *clock); */
/* void (* after_paint) (GdkPaintClock *clock); */
};
@@ -62,8 +72,10 @@ struct _GdkPaintClockInterface
GType gdk_paint_clock_get_type (void) G_GNUC_CONST;
guint64 gdk_paint_clock_get_frame_time (GdkPaintClock *clock);
-void gdk_paint_clock_request_frame (GdkPaintClock *clock);
-gboolean gdk_paint_clock_get_frame_requested (GdkPaintClock *clock);
+
+void gdk_paint_clock_request_phase (GdkPaintClock *clock,
+ GdkPaintClockPhase phase);
+GdkPaintClockPhase gdk_paint_clock_get_requested (GdkPaintClock *clock);
/* Convenience API */
void gdk_paint_clock_get_frame_time_val (GdkPaintClock *clock,
@@ -71,7 +83,6 @@ void gdk_paint_clock_get_frame_time_val (GdkPaintClock *clock,
/* Signal emitters (used in paint clock implementations) */
void gdk_paint_clock_frame_requested (GdkPaintClock *clock);
-void gdk_paint_clock_paint (GdkPaintClock *clock);
G_END_DECLS
diff --git a/gdk/gdkpaintclockidle.c b/gdk/gdkpaintclockidle.c
index c967af54..adbdbe7 100644
--- a/gdk/gdkpaintclockidle.c
+++ b/gdk/gdkpaintclockidle.c
@@ -38,9 +38,12 @@ struct _GdkPaintClockIdlePrivate
guint idle_id;
- unsigned int in_paint : 1;
+ GdkPaintClockPhase requested;
+ GdkPaintClockPhase phase;
};
+static gboolean gdk_paint_clock_paint_idle (void *data);
+
static void gdk_paint_clock_idle_finalize (GObject *object);
static void gdk_paint_clock_idle_interface_init (GdkPaintClockInterface *iface);
@@ -113,7 +116,7 @@ gdk_paint_clock_idle_get_frame_time (GdkPaintClock *clock)
guint64 computed_frame_time;
/* can't change frame time during a paint */
- if (priv->in_paint)
+ if (priv->phase != GDK_PAINT_CLOCK_PHASE_NONE)
return priv->frame_time;
/* Outside a paint, pick something close to "now" */
@@ -130,6 +133,22 @@ gdk_paint_clock_idle_get_frame_time (GdkPaintClock *clock)
return priv->frame_time;
}
+static void
+maybe_start_idle (GdkPaintClockIdle *clock_idle)
+{
+ GdkPaintClockIdlePrivate *priv = clock_idle->priv;
+
+ if (priv->idle_id == 0 && priv->requested != 0)
+ {
+ priv->idle_id = gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
+ gdk_paint_clock_paint_idle,
+ g_object_ref (clock_idle),
+ (GDestroyNotify) g_object_unref);
+
+ gdk_paint_clock_frame_requested (GDK_PAINT_CLOCK (clock_idle));
+ }
+}
+
static gboolean
gdk_paint_clock_paint_idle (void *data)
{
@@ -139,44 +158,60 @@ gdk_paint_clock_paint_idle (void *data)
priv->idle_id = 0;
- priv->in_paint = TRUE;
priv->frame_time = compute_frame_time (clock_idle);
- gdk_paint_clock_paint (clock);
-
- priv->in_paint = FALSE;
+ priv->phase = GDK_PAINT_CLOCK_PHASE_BEFORE_PAINT;
+ priv->requested &= ~GDK_PAINT_CLOCK_PHASE_BEFORE_PAINT;
+ g_signal_emit_by_name (G_OBJECT (clock), "before-paint");
+ priv->phase = GDK_PAINT_CLOCK_PHASE_LAYOUT;
+ priv->requested &= ~GDK_PAINT_CLOCK_PHASE_LAYOUT;
+ g_signal_emit_by_name (G_OBJECT (clock), "layout");
+ priv->phase = GDK_PAINT_CLOCK_PHASE_PAINT;
+ priv->requested &= ~GDK_PAINT_CLOCK_PHASE_PAINT;
+ g_signal_emit_by_name (G_OBJECT (clock), "paint");
+ priv->phase = GDK_PAINT_CLOCK_PHASE_AFTER_PAINT;
+ priv->requested &= ~GDK_PAINT_CLOCK_PHASE_AFTER_PAINT;
+ g_signal_emit_by_name (G_OBJECT (clock), "after-paint");
+ priv->phase = GDK_PAINT_CLOCK_PHASE_NONE;
+
+ maybe_start_idle (clock_idle);
return FALSE;
}
static void
-gdk_paint_clock_idle_request_frame (GdkPaintClock *clock)
+gdk_paint_clock_idle_request_phase (GdkPaintClock *clock,
+ GdkPaintClockPhase phase)
{
- GdkPaintClockIdlePrivate *priv = GDK_PAINT_CLOCK_IDLE (clock)->priv;
-
- if (priv->idle_id == 0)
- {
- priv->idle_id = gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
- gdk_paint_clock_paint_idle,
- g_object_ref (clock),
- (GDestroyNotify) g_object_unref);
+ GdkPaintClockIdle *clock_idle = GDK_PAINT_CLOCK_IDLE (clock);
+ GdkPaintClockIdlePrivate *priv = clock_idle->priv;
- gdk_paint_clock_frame_requested (clock);
- }
+ priv->requested |= phase;
+ maybe_start_idle (clock_idle);
}
-static gboolean
-gdk_paint_clock_idle_get_frame_requested (GdkPaintClock *clock)
+static GdkPaintClockPhase
+gdk_paint_clock_idle_get_requested (GdkPaintClock *clock)
{
GdkPaintClockIdlePrivate *priv = GDK_PAINT_CLOCK_IDLE (clock)->priv;
- return priv->idle_id != 0;
+ return priv->requested;
}
static void
gdk_paint_clock_idle_interface_init (GdkPaintClockInterface *iface)
{
iface->get_frame_time = gdk_paint_clock_idle_get_frame_time;
- iface->request_frame = gdk_paint_clock_idle_request_frame;
- iface->get_frame_requested = gdk_paint_clock_idle_get_frame_requested;
+ iface->request_phase = gdk_paint_clock_idle_request_phase;
+ iface->get_requested = gdk_paint_clock_idle_get_requested;
+}
+
+GdkPaintClock *
+_gdk_paint_clock_idle_new (void)
+{
+ GdkPaintClockIdle *clock;
+
+ clock = g_object_new (GDK_TYPE_PAINT_CLOCK_IDLE, NULL);
+
+ return GDK_PAINT_CLOCK (clock);
}
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index e35d31b..5d65c08 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -3879,7 +3879,8 @@ gdk_window_schedule_update (GdkWindow *window)
gdk_window_is_toplevel_frozen (window)))
return;
- gdk_paint_clock_request_frame (gdk_window_get_paint_clock (window));
+ gdk_paint_clock_request_phase (gdk_window_get_paint_clock (window),
+ GDK_PAINT_CLOCK_PHASE_PAINT);
}
void
diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c
index 7ecb7c9..345fe3b 100644
--- a/gtk/gtkcontainer.c
+++ b/gtk/gtkcontainer.c
@@ -1685,7 +1685,8 @@ gtk_container_idle_sizer (GdkPaintClock *clock,
}
else
{
- gdk_paint_clock_request_frame (clock);
+ gdk_paint_clock_request_phase (clock,
+ GDK_PAINT_CLOCK_PHASE_LAYOUT);
}
}
@@ -1704,7 +1705,8 @@ gtk_container_start_idle_sizer (GtkContainer *container)
container->priv->resize_clock = clock;
container->priv->resize_handler = g_signal_connect (clock, "layout",
G_CALLBACK (gtk_container_idle_sizer), container);
- gdk_paint_clock_request_frame (clock);
+ gdk_paint_clock_request_phase (clock,
+ GDK_PAINT_CLOCK_PHASE_LAYOUT);
}
static void
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 0ae4baa..1562877 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -4691,7 +4691,7 @@ gtk_widget_queue_resize_no_redraw (GtkWidget *widget)
* then update the animation by calling
* gdk_paint_clock_get_frame_time() again during each repaint.
*
- * gdk_paint_clock_request_frame() will result in a new frame on the
+ * gdk_paint_clock_request_phase() will result in a new frame on the
* clock, but won't necessarily repaint any widgets. To repaint a
* widget, you have to use gtk_widget_queue_draw() which invalidates
* the widget (thus scheduling it to receive a draw on the next
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]