clutter/stage-view: Reimplement CLUTTER_SHOW_FPS

Since a9a9a0d1c5 it didn't print anything. Now we reimplement it to
show FPS to a higher precision than in 3.36, add update/render times,
and separate stats per view/CRTC.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/154>
This commit is contained in:
Daniel van Vugt 2021-01-25 17:45:47 +08:00 committed by Marge Bot
parent 1d5713ed3b
commit 7e32c4196e

View File

@ -81,6 +81,14 @@ typedef struct _ClutterStageViewPrivate
float refresh_rate; float refresh_rate;
ClutterFrameClock *frame_clock; ClutterFrameClock *frame_clock;
struct {
int frame_count;
int64_t last_print_time_us;
int64_t cumulative_draw_time_us;
int64_t began_draw_time_us;
int64_t worst_draw_time_us;
} frame_timings;
guint dirty_viewport : 1; guint dirty_viewport : 1;
guint dirty_projection : 1; guint dirty_projection : 1;
} ClutterStageViewPrivate; } ClutterStageViewPrivate;
@ -1065,6 +1073,70 @@ handle_frame_clock_before_frame (ClutterFrameClock *frame_clock,
_clutter_stage_process_queued_events (priv->stage); _clutter_stage_process_queued_events (priv->stage);
} }
static void
begin_frame_timing_measurement (ClutterStageView *view)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
priv->frame_timings.began_draw_time_us = g_get_monotonic_time ();
}
static void
end_frame_timing_measurement (ClutterStageView *view)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
int64_t now_us = g_get_monotonic_time ();
int64_t draw_time_us;
draw_time_us = now_us - priv->frame_timings.began_draw_time_us;
priv->frame_timings.frame_count++;
priv->frame_timings.cumulative_draw_time_us += draw_time_us;
if (draw_time_us > priv->frame_timings.worst_draw_time_us)
priv->frame_timings.worst_draw_time_us = draw_time_us;
if (priv->frame_timings.frame_count && priv->frame_timings.last_print_time_us)
{
float time_since_last_print_s;
time_since_last_print_s =
(now_us - priv->frame_timings.last_print_time_us) /
(float) G_USEC_PER_SEC;
if (time_since_last_print_s >= 1.0)
{
float avg_fps, avg_draw_time_ms, worst_draw_time_ms;
avg_fps = priv->frame_timings.frame_count / time_since_last_print_s;
avg_draw_time_ms =
(priv->frame_timings.cumulative_draw_time_us / 1000.0) /
priv->frame_timings.frame_count;
worst_draw_time_ms = priv->frame_timings.worst_draw_time_us / 1000.0;
g_print ("*** %s frame timings over %.01fs: "
"%.02f FPS, average: %.01fms, peak: %.01fms\n",
priv->name,
time_since_last_print_s,
avg_fps,
avg_draw_time_ms,
worst_draw_time_ms);
priv->frame_timings.frame_count = 0;
priv->frame_timings.cumulative_draw_time_us = 0;
priv->frame_timings.worst_draw_time_us = 0;
priv->frame_timings.last_print_time_us = now_us;
}
}
else if (!priv->frame_timings.last_print_time_us)
{
priv->frame_timings.last_print_time_us = now_us;
}
}
static ClutterFrameResult static ClutterFrameResult
handle_frame_clock_frame (ClutterFrameClock *frame_clock, handle_frame_clock_frame (ClutterFrameClock *frame_clock,
int64_t frame_count, int64_t frame_count,
@ -1088,6 +1160,9 @@ handle_frame_clock_frame (ClutterFrameClock *frame_clock,
if (!clutter_actor_is_mapped (CLUTTER_ACTOR (stage))) if (!clutter_actor_is_mapped (CLUTTER_ACTOR (stage)))
return CLUTTER_FRAME_RESULT_IDLE; return CLUTTER_FRAME_RESULT_IDLE;
if (_clutter_context_get_show_fps ())
begin_frame_timing_measurement (view);
_clutter_run_repaint_functions (CLUTTER_REPAINT_FLAGS_PRE_PAINT); _clutter_run_repaint_functions (CLUTTER_REPAINT_FLAGS_PRE_PAINT);
clutter_stage_emit_before_update (stage, view); clutter_stage_emit_before_update (stage, view);
@ -1108,6 +1183,9 @@ handle_frame_clock_frame (ClutterFrameClock *frame_clock,
_clutter_stage_window_redraw_view (stage_window, view, &frame); _clutter_stage_window_redraw_view (stage_window, view, &frame);
clutter_stage_emit_after_paint (stage, view); clutter_stage_emit_after_paint (stage, view);
if (_clutter_context_get_show_fps ())
end_frame_timing_measurement (view);
} }
_clutter_stage_window_finish_frame (stage_window, view, &frame); _clutter_stage_window_finish_frame (stage_window, view, &frame);