[mutter/gbsneto/charts: 3/4] Add frame time chart
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/gbsneto/charts: 3/4] Add frame time chart
- Date: Fri, 22 Mar 2019 01:34:31 +0000 (UTC)
commit fa30d7ce6431a71a5edd760244cadc656f4759b1
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Fri Mar 22 01:29:36 2019 +0000
Add frame time chart
Add a chart at the bottom 10% of the screen where each
bar represents the time the frame took to be painted. The
red line represents the maximum time to draw. For example,
if you are on a 60Hz monitor, the red line means 16.6667
miliseconds.
This covers both layout time (green) and paint time (blue).
Enjoy.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/502
clutter/clutter/clutter-main.c | 1 +
clutter/clutter/clutter-main.h | 1 +
clutter/clutter/clutter-stage-private.h | 4 ++
clutter/clutter/clutter-stage.c | 9 +++
clutter/clutter/cogl/clutter-stage-cogl.c | 113 ++++++++++++++++++++++++++++++
5 files changed, 128 insertions(+)
---
diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c
index 7616eaae0..cff072331 100644
--- a/clutter/clutter/clutter-main.c
+++ b/clutter/clutter/clutter-main.c
@@ -143,6 +143,7 @@ static const GDebugKey clutter_paint_debug_keys[] = {
{ "continuous-redraw", CLUTTER_DEBUG_CONTINUOUS_REDRAW },
{ "paint-deform-tiles", CLUTTER_DEBUG_PAINT_DEFORM_TILES },
{ "damage-region", CLUTTER_DEBUG_PAINT_DAMAGE_REGION },
+ { "frame-time", CLUTTER_DEBUG_PAINT_FRAME_TIME },
};
static void
diff --git a/clutter/clutter/clutter-main.h b/clutter/clutter/clutter-main.h
index e0f10c892..6846cef7a 100644
--- a/clutter/clutter/clutter-main.h
+++ b/clutter/clutter/clutter-main.h
@@ -74,6 +74,7 @@ typedef enum
CLUTTER_DEBUG_CONTINUOUS_REDRAW = 1 << 6,
CLUTTER_DEBUG_PAINT_DEFORM_TILES = 1 << 7,
CLUTTER_DEBUG_PAINT_DAMAGE_REGION = 1 << 8,
+ CLUTTER_DEBUG_PAINT_FRAME_TIME = 1 << 9,
} ClutterDrawDebugFlag;
/**
diff --git a/clutter/clutter/clutter-stage-private.h b/clutter/clutter/clutter-stage-private.h
index 4799c29e1..04c13ce04 100644
--- a/clutter/clutter/clutter-stage-private.h
+++ b/clutter/clutter/clutter-stage-private.h
@@ -134,6 +134,10 @@ void _clutter_stage_presented (ClutterStage *stag
GList * _clutter_stage_peek_stage_views (ClutterStage *stage);
+void clutter_stage_get_frame_times (ClutterStage *stage,
+ double *paint_time,
+ double *layout_time);
+
G_END_DECLS
#endif /* __CLUTTER_STAGE_PRIVATE_H__ */
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index 25ce9d899..98622c4a1 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -5091,3 +5091,12 @@ _clutter_stage_get_max_view_scale_factor_for_rect (ClutterStage *stage,
*view_scale = scale;
return TRUE;
}
+
+void
+clutter_stage_get_frame_times (ClutterStage *stage,
+ double *paint_time,
+ double *layout_time)
+{
+ *paint_time = stage->priv->last_paint_time;
+ *layout_time = stage->priv->last_layout_time;
+}
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c
index e0c39185b..c6efbc080 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.c
+++ b/clutter/clutter/cogl/clutter-stage-cogl.c
@@ -405,6 +405,115 @@ paint_damage_region (ClutterStageWindow *stage_window,
cogl_framebuffer_pop_matrix (framebuffer);
}
+#define CHART_COLUMN_WIDTH 6 //px
+#define THRESHOLD_LINE_HEIGHT 2 //px
+
+static void
+paint_frame_time_chart (ClutterStageWindow *stage_window,
+ ClutterStageView *view)
+{
+ CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
+ CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
+ ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
+ ClutterActor *actor = CLUTTER_ACTOR (stage_cogl->wrapper);
+ static CoglPipeline *threshold_pipeline = NULL;
+ static CoglPipeline *paint_time_pipeline = NULL;
+ static CoglPipeline *layout_time_pipeline = NULL;
+ static GArray *frame_times = NULL;
+ CoglMatrix modelview;
+ double paint_time;
+ double layout_time;
+ float green_line_y;
+ int width, height;
+ int n_points;
+ int i;
+
+ if (G_UNLIKELY (paint_time_pipeline == NULL))
+ {
+ paint_time_pipeline = cogl_pipeline_new (ctx);
+ cogl_pipeline_set_color4ub (paint_time_pipeline, 0x00, 0x00, 0x60, 0xa0);
+ }
+
+ if (G_UNLIKELY (layout_time_pipeline == NULL))
+ {
+ layout_time_pipeline = cogl_pipeline_new (ctx);
+ cogl_pipeline_set_color4ub (layout_time_pipeline, 0x00, 0x60, 0x00, 0xa0);
+ }
+
+ if (G_UNLIKELY (threshold_pipeline == NULL))
+ {
+ threshold_pipeline = cogl_pipeline_new (ctx);
+ cogl_pipeline_set_color4ub (threshold_pipeline, 0x40, 0x00, 0x00, 0x80);
+ }
+
+ cogl_framebuffer_push_matrix (framebuffer);
+ cogl_matrix_init_identity (&modelview);
+ _clutter_actor_apply_modelview_transform (actor, &modelview);
+ cogl_framebuffer_set_modelview_matrix (framebuffer, &modelview);
+
+ width = cogl_framebuffer_get_width (framebuffer);
+ height = cogl_framebuffer_get_height (framebuffer);
+
+ /* Frame times array composed by (paint_time, layout_time) pairs */
+ n_points = width / CHART_COLUMN_WIDTH;
+
+ if (G_UNLIKELY (frame_times == NULL))
+ frame_times = g_array_sized_new (FALSE, TRUE, sizeof (double), n_points * 2);
+
+ clutter_stage_get_frame_times (stage_cogl->wrapper, &paint_time, &layout_time);
+
+ g_array_append_val (frame_times, paint_time);
+ g_array_append_val (frame_times, layout_time);
+
+ if (frame_times->len > n_points)
+ g_array_remove_range (frame_times, 0, frame_times->len - n_points);
+
+ /* Chart */
+ for (i = 0; i < MIN (frame_times->len, n_points); i++)
+ {
+ int element = frame_times->len - i - 1;
+ double paint_time_entry = g_array_index (frame_times, double, element);
+ double layout_time_entry = g_array_index (frame_times, double, element + 1);
+ double refresh_rate_ms = 1000.0 / stage_cogl->refresh_rate;
+ double refresh_rate_bar_height = height * 0.1;
+ double x_1 = width - (i + 1) * CHART_COLUMN_WIDTH;
+ double x_2 = width - i * CHART_COLUMN_WIDTH;
+ double layout_bar_height;
+ double paint_bar_height;
+
+ /* Layout time section */
+ layout_bar_height =
+ layout_time_entry / refresh_rate_ms * refresh_rate_bar_height;
+ cogl_framebuffer_draw_rectangle (framebuffer,
+ layout_time_pipeline,
+ x_1,
+ height - layout_bar_height,
+ x_2,
+ height);
+
+ /* Paint time section */
+ paint_bar_height =
+ paint_time_entry / refresh_rate_ms * refresh_rate_bar_height;
+ cogl_framebuffer_draw_rectangle (framebuffer,
+ paint_time_pipeline,
+ x_1,
+ height - paint_bar_height - layout_bar_height,
+ x_2,
+ height - layout_bar_height);
+ }
+
+ /* Green line (16.667ms) */
+ green_line_y = height * 0.9;
+ cogl_framebuffer_draw_rectangle (framebuffer,
+ threshold_pipeline,
+ 0.0f,
+ green_line_y,
+ width,
+ green_line_y + THRESHOLD_LINE_HEIGHT);
+
+ cogl_framebuffer_pop_matrix (framebuffer);
+}
+
static gboolean
swap_framebuffer (ClutterStageWindow *stage_window,
ClutterStageView *view,
@@ -427,6 +536,9 @@ swap_framebuffer (ClutterStageWindow *stage_window,
if (G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION)))
paint_damage_region (stage_window, view, swap_region);
+ if (G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_FRAME_TIME)))
+ paint_frame_time_chart (stage_window, view);
+
if (cogl_is_onscreen (framebuffer))
{
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
@@ -572,6 +684,7 @@ is_buffer_age_enabled (void)
/* Buffer age is disabled when running with CLUTTER_PAINT=damage-region,
* to ensure the red damage represents the currently damaged area */
return !(clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION) &&
+ !(clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_FRAME_TIME) &&
cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]