[gtk+] Add GDK_DEBUG=frames
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] Add GDK_DEBUG=frames
- Date: Thu, 14 Feb 2013 22:25:28 +0000 (UTC)
commit 8855bf052d8bbbd8fdfce1cd5f4a3540661a9c8e
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Wed Nov 14 19:21:33 2012 -0500
Add GDK_DEBUG=frames
Add a debug option to print out detailed statistics about each frame drawn.
https://bugzilla.gnome.org/show_bug.cgi?id=685460
gdk/gdk.c | 3 +-
gdk/gdkframeclockidle.c | 45 ++++++++++++++++++++++++++++++++--
gdk/gdkframehistory.c | 41 +++++++++++++++++++++++++++++++
gdk/gdkframetimings.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++
gdk/gdkinternals.h | 23 +++++++++++++++++-
gdk/x11/gdkdisplay-x11.c | 5 ++++
gdk/x11/gdkwindow-x11.c | 12 +++++++++
7 files changed, 184 insertions(+), 5 deletions(-)
---
diff --git a/gdk/gdk.c b/gdk/gdk.c
index bc668d4..babe080 100644
--- a/gdk/gdk.c
+++ b/gdk/gdk.c
@@ -138,7 +138,8 @@ static const GDebugKey gdk_debug_keys[] = {
{"multihead", GDK_DEBUG_MULTIHEAD},
{"xinerama", GDK_DEBUG_XINERAMA},
{"draw", GDK_DEBUG_DRAW},
- {"eventloop", GDK_DEBUG_EVENTLOOP}
+ {"eventloop", GDK_DEBUG_EVENTLOOP},
+ {"frames", GDK_DEBUG_FRAMES}
};
static gboolean
diff --git a/gdk/gdkframeclockidle.c b/gdk/gdkframeclockidle.c
index f6e2d33..09624c4 100644
--- a/gdk/gdkframeclockidle.c
+++ b/gdk/gdkframeclockidle.c
@@ -26,6 +26,7 @@
#include "config.h"
+#include "gdkinternals.h"
#include "gdkframeclockidle.h"
#include "gdk.h"
@@ -271,6 +272,8 @@ gdk_frame_clock_paint_idle (void *data)
GdkFrameClockIdle *clock_idle = GDK_FRAME_CLOCK_IDLE (clock);
GdkFrameClockIdlePrivate *priv = clock_idle->priv;
gboolean skip_to_resume_events;
+ GdkFrameTimings *timings = NULL;
+ gint64 frame_counter = 0;
priv->paint_idle_id = 0;
priv->in_paint_idle = TRUE;
@@ -278,6 +281,12 @@ gdk_frame_clock_paint_idle (void *data)
skip_to_resume_events =
(priv->requested & ~(GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS | GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS)) == 0;
+ if (priv->phase > GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT)
+ {
+ frame_counter = gdk_frame_history_get_frame_counter (priv->history);
+ timings = gdk_frame_history_get_timings (priv->history, frame_counter);
+ }
+
if (!skip_to_resume_events)
{
switch (priv->phase)
@@ -288,13 +297,12 @@ gdk_frame_clock_paint_idle (void *data)
case GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT:
if (priv->freeze_count == 0)
{
- GdkFrameTimings *timings;
- gint64 frame_counter;
-
priv->frame_time = compute_frame_time (clock_idle);
+
gdk_frame_history_begin_frame (priv->history);
frame_counter = gdk_frame_history_get_frame_counter (priv->history);
timings = gdk_frame_history_get_timings (priv->history, frame_counter);
+
gdk_frame_timings_set_frame_time (timings, priv->frame_time);
gdk_frame_timings_set_slept_before (timings,
@@ -322,6 +330,15 @@ gdk_frame_clock_paint_idle (void *data)
case GDK_FRAME_CLOCK_PHASE_LAYOUT:
if (priv->freeze_count == 0)
{
+#ifdef G_ENABLE_DEBUG
+ if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
+ {
+ if (priv->phase != GDK_FRAME_CLOCK_PHASE_LAYOUT &&
+ (priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT))
+ _gdk_frame_timings_set_layout_start_time (timings, g_get_monotonic_time ());
+ }
+#endif /* G_ENABLE_DEBUG */
+
priv->phase = GDK_FRAME_CLOCK_PHASE_LAYOUT;
if (priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT)
{
@@ -332,6 +349,15 @@ gdk_frame_clock_paint_idle (void *data)
case GDK_FRAME_CLOCK_PHASE_PAINT:
if (priv->freeze_count == 0)
{
+#ifdef G_ENABLE_DEBUG
+ if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
+ {
+ if (priv->phase != GDK_FRAME_CLOCK_PHASE_PAINT &&
+ (priv->requested & GDK_FRAME_CLOCK_PHASE_PAINT))
+ _gdk_frame_timings_set_paint_start_time (timings, g_get_monotonic_time ());
+ }
+#endif /* G_ENABLE_DEBUG */
+
priv->phase = GDK_FRAME_CLOCK_PHASE_PAINT;
if (priv->requested & GDK_FRAME_CLOCK_PHASE_PAINT)
{
@@ -347,12 +373,25 @@ gdk_frame_clock_paint_idle (void *data)
/* the ::after-paint phase doesn't get repeated on freeze/thaw,
*/
priv->phase = GDK_FRAME_CLOCK_PHASE_NONE;
+
+#ifdef G_ENABLE_DEBUG
+ if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
+ _gdk_frame_timings_set_frame_end_time (timings, g_get_monotonic_time ());
+#endif /* G_ENABLE_DEBUG */
}
case GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS:
;
}
}
+#ifdef G_ENABLE_DEBUG
+ if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
+ {
+ if (gdk_frame_timings_get_complete (timings))
+ _gdk_frame_history_debug_print (priv->history, timings);
+ }
+#endif /* G_ENABLE_DEBUG */
+
if (priv->requested & GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS)
{
priv->requested &= ~GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS;
diff --git a/gdk/gdkframehistory.c b/gdk/gdkframehistory.c
index e993e5e..322467b 100644
--- a/gdk/gdkframehistory.c
+++ b/gdk/gdkframehistory.c
@@ -18,6 +18,7 @@
#include "config.h"
#include "gdkframehistory.h"
+#include "gdkinternals.h"
#define FRAME_HISTORY_MAX_LENGTH 16
@@ -141,3 +142,43 @@ gdk_frame_history_get_last_complete (GdkFrameHistory *history)
return NULL;
}
+
+#ifdef G_ENABLE_DEBUG
+void
+_gdk_frame_history_debug_print (GdkFrameHistory *history,
+ GdkFrameTimings *timings)
+{
+ gint64 frame_counter = gdk_frame_timings_get_frame_counter (timings);
+ gint64 layout_start_time = _gdk_frame_timings_get_layout_start_time (timings);
+ gint64 paint_start_time = _gdk_frame_timings_get_paint_start_time (timings);
+ gint64 frame_end_time = _gdk_frame_timings_get_frame_end_time (timings);
+ gint64 frame_time = gdk_frame_timings_get_frame_time (timings);
+ gint64 presentation_time = gdk_frame_timings_get_presentation_time (timings);
+ gint64 refresh_interval = gdk_frame_timings_get_refresh_interval (timings);
+ gint64 previous_frame_time = 0;
+ gboolean slept_before = gdk_frame_timings_get_slept_before (timings);
+ GdkFrameTimings *previous_timings = gdk_frame_history_get_timings (history,
+ frame_counter - 1);
+
+ if (previous_timings != NULL)
+ previous_frame_time = gdk_frame_timings_get_frame_time (previous_timings);
+
+ g_print ("%5" G_GINT64_FORMAT ":", frame_counter);
+ if (previous_frame_time != 0)
+ {
+ g_print (" interval=%-4.1f", (frame_time - previous_frame_time) / 1000.);
+ g_print (slept_before ? " (sleep)" : " ");
+ }
+ if (layout_start_time != 0)
+ g_print (" layout_start=%-4.1f", (layout_start_time - frame_time) / 1000.);
+ if (paint_start_time != 0)
+ g_print (" paint_start=%-4.1f", (paint_start_time - frame_time) / 1000.);
+ if (frame_end_time != 0)
+ g_print (" frame_end=%-4.1f", (frame_end_time - frame_time) / 1000.);
+ if (presentation_time != 0)
+ g_print (" present=%-4.1f", (presentation_time - frame_time) / 1000.);
+ if (refresh_interval != 0)
+ g_print (" refresh_interval=%-4.1f", refresh_interval / 1000.);
+ g_print ("\n");
+}
+#endif /* G_ENABLE_DEBUG */
diff --git a/gdk/gdkframetimings.c b/gdk/gdkframetimings.c
index a51912b..0813001 100644
--- a/gdk/gdkframetimings.c
+++ b/gdk/gdkframetimings.c
@@ -30,6 +30,12 @@ struct _GdkFrameTimings
gint64 presentation_time;
gint64 refresh_interval;
+#ifdef G_ENABLE_DEBUG
+ gint64 layout_start_time;
+ gint64 paint_start_time;
+ gint64 frame_end_time;
+#endif /* G_ENABLE_DEBUG */
+
guint complete : 1;
guint slept_before : 1;
};
@@ -197,3 +203,57 @@ gdk_frame_timings_set_refresh_interval (GdkFrameTimings *timings,
timings->refresh_interval = refresh_interval;
}
+
+#ifdef G_ENABLE_DEBUG
+gint64
+_gdk_frame_timings_get_layout_start_time (GdkFrameTimings *timings)
+{
+ g_return_val_if_fail (timings != NULL, 0);
+
+ return timings->layout_start_time;
+}
+
+void
+_gdk_frame_timings_set_layout_start_time (GdkFrameTimings *timings,
+ gint64 layout_start_time)
+{
+ g_return_if_fail (timings != NULL);
+
+ timings->layout_start_time = layout_start_time;
+}
+
+gint64
+_gdk_frame_timings_get_paint_start_time (GdkFrameTimings *timings)
+{
+ g_return_val_if_fail (timings != NULL, 0);
+
+ return timings->paint_start_time;
+}
+
+void
+_gdk_frame_timings_set_paint_start_time (GdkFrameTimings *timings,
+ gint64 paint_start_time)
+{
+ g_return_if_fail (timings != NULL);
+
+ timings->paint_start_time = paint_start_time;
+}
+
+gint64
+_gdk_frame_timings_get_frame_end_time (GdkFrameTimings *timings)
+{
+ g_return_val_if_fail (timings != NULL, 0);
+
+ return timings->frame_end_time;
+}
+
+void
+_gdk_frame_timings_set_frame_end_time (GdkFrameTimings *timings,
+ gint64 frame_end_time)
+{
+ g_return_if_fail (timings != NULL);
+
+ timings->frame_end_time = frame_end_time;
+}
+
+#endif /* G_ENABLE_DEBUG */
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index babef6e..4239188 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -82,7 +82,8 @@ typedef enum {
GDK_DEBUG_MULTIHEAD = 1 << 7,
GDK_DEBUG_XINERAMA = 1 << 8,
GDK_DEBUG_DRAW = 1 << 9,
- GDK_DEBUG_EVENTLOOP = 1 << 10
+ GDK_DEBUG_EVENTLOOP = 1 << 10,
+ GDK_DEBUG_FRAMES = 1 << 11
} GdkDebugFlag;
typedef enum {
@@ -428,6 +429,26 @@ cairo_surface_t * _gdk_offscreen_window_create_surface (GdkWindow *window,
gint width,
gint height);
+/********************************
+ * Debug-only frame statistics *
+ ********************************/
+
+#ifdef G_ENABLE_DEBUG
+
+gint64 _gdk_frame_timings_get_layout_start_time (GdkFrameTimings *timings);
+void _gdk_frame_timings_set_layout_start_time (GdkFrameTimings *timings,
+ gint64 layout_start_time);
+gint64 _gdk_frame_timings_get_paint_start_time (GdkFrameTimings *timings);
+void _gdk_frame_timings_set_paint_start_time (GdkFrameTimings *timings,
+ gint64 paint_time);
+gint64 _gdk_frame_timings_get_frame_end_time (GdkFrameTimings *timings);
+void _gdk_frame_timings_set_frame_end_time (GdkFrameTimings *timings,
+ gint64 frame_end_time);
+
+void _gdk_frame_history_debug_print (GdkFrameHistory *history,
+ GdkFrameTimings *timings);
+
+#endif /* G_ENABLE_DEBUG */
G_END_DECLS
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index ae4aaaf..888d87d 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -1155,6 +1155,11 @@ _gdk_wm_protocols_filter (GdkXEvent *xev,
gdk_frame_timings_set_refresh_interval (timings, refresh_interval);
gdk_frame_timings_set_complete (timings, TRUE);
+#ifdef G_ENABLE_DEBUG
+ if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
+ _gdk_frame_history_debug_print (gdk_frame_clock_get_history (clock),
+ timings);
+#endif /* G_ENABLE_DEBUG */
}
}
}
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index e70d3fd..ea74baa 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -322,6 +322,18 @@ gdk_x11_window_end_frame (GdkWindow *window)
if (impl->toplevel->current_counter_value % 2 == 1)
{
+#ifdef G_ENABLE_DEBUG
+ if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
+ {
+ XImage *image = XGetImage (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ 0, 0, 1, 1,
+ (1 << 24) - 1,
+ ZPixmap);
+ XDestroyImage (image);
+ }
+#endif /* G_ENABLE_DEBUG */
+
/* An increment of 3 means that the frame was not drawn as fast as possible,
* but rather at a particular time. This can trigger different handling from
* the compositor.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]