From: Matthias Clasen Date: Sat, 19 May 2018 19:24:21 +0000 (+0100) Subject: frame clock: Add tracing X-Git-Tag: archive/raspbian/4.4.1+ds1-2+rpi1^2~18^2~20^2~1694^2~5 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=1660bac6bda835e8ec5eb46ed28eff4de48abad2;p=gtk4.git frame clock: Add tracing Emit tracing data for frames. For now, we emit the entire frame, and the layout and paint phases. Also emit frames-per-second. --- diff --git a/gdk/gdkframeclockidle.c b/gdk/gdkframeclockidle.c index 5a72624d76..ae6443a798 100644 --- a/gdk/gdkframeclockidle.c +++ b/gdk/gdkframeclockidle.c @@ -29,6 +29,7 @@ #include "gdkinternals.h" #include "gdkframeclockprivate.h" #include "gdk.h" +#include "gdkprofilerprivate.h" #ifdef G_OS_WIN32 #include @@ -113,6 +114,96 @@ get_sleep_serial (void) return sleep_serial; } +static guint fps_counter = 0; + +static void +add_timings_to_profiler (GdkFrameTimings *timings) +{ + gdk_profiler_add_mark (timings->frame_time * 1000, + (timings->frame_end_time - timings->frame_time) * 1000, + "frame", ""); + if (timings->layout_start_time != 0) + gdk_profiler_add_mark (timings->layout_start_time * 1000, + (timings->paint_start_time - timings->layout_start_time) * 1000, + "layout", ""); + + if (timings->paint_start_time != 0) + gdk_profiler_add_mark (timings->paint_start_time * 1000, + (timings->frame_end_time - timings->paint_start_time) * 1000, + "paint", ""); +} + +static gint64 +guess_refresh_interval (GdkFrameClock *frame_clock) +{ + gint64 interval; + gint64 i; + + interval = G_MAXINT64; + + for (i = gdk_frame_clock_get_history_start (frame_clock); + i < gdk_frame_clock_get_frame_counter (frame_clock); + i++) + { + GdkFrameTimings *t, *before; + gint64 ts, before_ts; + + t = gdk_frame_clock_get_timings (frame_clock, i); + before = gdk_frame_clock_get_timings (frame_clock, i - 1); + if (t == NULL || before == NULL) + continue; + + ts = gdk_frame_timings_get_frame_time (t); + before_ts = gdk_frame_timings_get_frame_time (before); + if (ts == 0 || before_ts == 0) + continue; + + interval = MIN (interval, ts - before_ts); + } + + if (interval == G_MAXINT64) + return 0; + + return interval; +} + +static double +frame_clock_get_fps (GdkFrameClock *frame_clock) +{ + GdkFrameTimings *start, *end; + gint64 start_counter, end_counter; + gint64 start_timestamp, end_timestamp; + gint64 interval; + + start_counter = gdk_frame_clock_get_history_start (frame_clock); + end_counter = gdk_frame_clock_get_frame_counter (frame_clock); + start = gdk_frame_clock_get_timings (frame_clock, start_counter); + for (end = gdk_frame_clock_get_timings (frame_clock, end_counter); + end_counter > start_counter && end != NULL && !gdk_frame_timings_get_complete (end); + end = gdk_frame_clock_get_timings (frame_clock, end_counter)) + end_counter--; + if (end_counter - start_counter < 4) + return 0.0; + + start_timestamp = gdk_frame_timings_get_presentation_time (start); + end_timestamp = gdk_frame_timings_get_presentation_time (end); + if (start_timestamp == 0 || end_timestamp == 0) + { + start_timestamp = gdk_frame_timings_get_frame_time (start); + end_timestamp = gdk_frame_timings_get_frame_time (end); + } + + interval = gdk_frame_timings_get_refresh_interval (end); + if (interval == 0) + { + interval = guess_refresh_interval (frame_clock); + if (interval == 0) + return 0.0; + } + + return ((double) end_counter - start_counter) * G_USEC_PER_SEC / (end_timestamp - start_timestamp); +} + static void gdk_frame_clock_idle_init (GdkFrameClockIdle *frame_clock_idle) { @@ -123,6 +214,11 @@ gdk_frame_clock_idle_init (GdkFrameClockIdle *frame_clock_idle) priv->frame_time = g_get_monotonic_time (); /* more sane than zero */ priv->freeze_count = 0; + +#ifdef G_ENABLE_DEBUG + if (fps_counter == 0) + fps_counter = gdk_profiler_define_counter ("fps", "Frames per Second"); +#endif } static void @@ -405,7 +501,7 @@ gdk_frame_clock_paint_idle (void *data) { int iter; #ifdef G_ENABLE_DEBUG - if (GDK_DEBUG_CHECK (FRAMES)) + if (GDK_DEBUG_CHECK (FRAMES) || gdk_profiler_is_running ()) { if (priv->phase != GDK_FRAME_CLOCK_PHASE_LAYOUT && (priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT)) @@ -435,7 +531,7 @@ gdk_frame_clock_paint_idle (void *data) if (priv->freeze_count == 0) { #ifdef G_ENABLE_DEBUG - if (GDK_DEBUG_CHECK (FRAMES)) + if (GDK_DEBUG_CHECK (FRAMES) || gdk_profiler_is_running ()) { if (priv->phase != GDK_FRAME_CLOCK_PHASE_PAINT && (priv->requested & GDK_FRAME_CLOCK_PHASE_PAINT)) @@ -462,7 +558,7 @@ gdk_frame_clock_paint_idle (void *data) priv->phase = GDK_FRAME_CLOCK_PHASE_NONE; #ifdef G_ENABLE_DEBUG - if (GDK_DEBUG_CHECK (FRAMES)) + if (GDK_DEBUG_CHECK (FRAMES) || gdk_profiler_is_running ()) timings->frame_end_time = g_get_monotonic_time (); #endif /* G_ENABLE_DEBUG */ } @@ -475,6 +571,12 @@ gdk_frame_clock_paint_idle (void *data) } #ifdef G_ENABLE_DEBUG + if (gdk_profiler_is_running ()) + { + add_timings_to_profiler (timings); + gdk_profiler_set_counter (fps_counter, timings->frame_end_time * 1000, frame_clock_get_fps (clock)); + } + if (GDK_DEBUG_CHECK (FRAMES)) { if (timings && timings->complete)