clutter: Add a max render time debug HUD

Not sure how to update the damage or redraw clip or something; at least
this works properly when under a constantly-redrawing window, which is
ok for debugging purposes.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1762>
This commit is contained in:
Ivan Molodetskikh 2020-11-27 21:49:19 +03:00 committed by Marge Bot
parent f55c9af618
commit a5d1d48bf1
5 changed files with 95 additions and 0 deletions

View File

@ -678,6 +678,51 @@ clutter_frame_clock_record_flip_time (ClutterFrameClock *frame_clock,
frame_clock->last_flip_time_us = flip_time_us; frame_clock->last_flip_time_us = flip_time_us;
} }
GString *
clutter_frame_clock_get_max_render_time_debug_info (ClutterFrameClock *frame_clock)
{
int64_t max_dispatch_to_swap_us = 0;
int64_t max_swap_to_rendering_done_us = 0;
int64_t max_swap_to_flip_us = 0;
int i;
GString *string;
string = g_string_new (NULL);
g_string_append_printf (string, "Max render time: %ld µs",
clutter_frame_clock_compute_max_render_time_us (frame_clock));
if (frame_clock->got_measurements_last_frame)
g_string_append_printf (string, " =");
else
g_string_append_printf (string, " (no measurements last frame)");
for (i = 0; i < ESTIMATE_QUEUE_LENGTH; ++i)
{
max_dispatch_to_swap_us =
MAX (max_dispatch_to_swap_us,
frame_clock->dispatch_to_swap_us.values[i]);
max_swap_to_rendering_done_us =
MAX (max_swap_to_rendering_done_us,
frame_clock->swap_to_rendering_done_us.values[i]);
max_swap_to_flip_us =
MAX (max_swap_to_flip_us,
frame_clock->swap_to_flip_us.values[i]);
}
g_string_append_printf (string, "\nVblank duration: %ld µs +",
frame_clock->vblank_duration_us);
g_string_append_printf (string, "\nDispatch to swap: %ld µs +",
max_dispatch_to_swap_us);
g_string_append_printf (string, "\nmax(Swap to rendering done: %ld µs,",
max_swap_to_rendering_done_us);
g_string_append_printf (string, "\nSwap to flip: %ld µs) +",
max_swap_to_flip_us);
g_string_append_printf (string, "\nConstant: %d µs",
clutter_max_render_time_constant_us);
return string;
}
static GSourceFuncs frame_clock_source_funcs = { static GSourceFuncs frame_clock_source_funcs = {
NULL, NULL,
NULL, NULL,

View File

@ -94,4 +94,6 @@ float clutter_frame_clock_get_refresh_rate (ClutterFrameClock *frame_clock);
void clutter_frame_clock_record_flip_time (ClutterFrameClock *frame_clock, void clutter_frame_clock_record_flip_time (ClutterFrameClock *frame_clock,
int64_t flip_time_us); int64_t flip_time_us);
GString * clutter_frame_clock_get_max_render_time_debug_info (ClutterFrameClock *frame_clock);
#endif /* CLUTTER_FRAME_CLOCK_H */ #endif /* CLUTTER_FRAME_CLOCK_H */

View File

@ -136,6 +136,7 @@ static const GDebugKey clutter_paint_debug_keys[] = {
{ "paint-deform-tiles", CLUTTER_DEBUG_PAINT_DEFORM_TILES }, { "paint-deform-tiles", CLUTTER_DEBUG_PAINT_DEFORM_TILES },
{ "damage-region", CLUTTER_DEBUG_PAINT_DAMAGE_REGION }, { "damage-region", CLUTTER_DEBUG_PAINT_DAMAGE_REGION },
{ "disable-dynamic-max-render-time", CLUTTER_DEBUG_DISABLE_DYNAMIC_MAX_RENDER_TIME }, { "disable-dynamic-max-render-time", CLUTTER_DEBUG_DISABLE_DYNAMIC_MAX_RENDER_TIME },
{ "max-render-time", CLUTTER_DEBUG_PAINT_MAX_RENDER_TIME },
}; };
gboolean gboolean

View File

@ -73,6 +73,7 @@ typedef enum
CLUTTER_DEBUG_PAINT_DEFORM_TILES = 1 << 7, CLUTTER_DEBUG_PAINT_DEFORM_TILES = 1 << 7,
CLUTTER_DEBUG_PAINT_DAMAGE_REGION = 1 << 8, CLUTTER_DEBUG_PAINT_DAMAGE_REGION = 1 << 8,
CLUTTER_DEBUG_DISABLE_DYNAMIC_MAX_RENDER_TIME = 1 << 9, CLUTTER_DEBUG_DISABLE_DYNAMIC_MAX_RENDER_TIME = 1 << 9,
CLUTTER_DEBUG_PAINT_MAX_RENDER_TIME = 1 << 10,
} ClutterDrawDebugFlag; } ClutterDrawDebugFlag;
/** /**

View File

@ -1312,6 +1312,51 @@ clutter_stage_real_paint_view (ClutterStage *stage,
clutter_stage_do_paint_view (stage, view, redraw_clip); clutter_stage_do_paint_view (stage, view, redraw_clip);
} }
static void
clutter_stage_paint (ClutterActor *actor,
ClutterPaintContext *paint_context)
{
ClutterStageView *view;
CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->paint (actor, paint_context);
view = clutter_paint_context_get_stage_view (paint_context);
if (view &&
G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_MAX_RENDER_TIME))
{
cairo_rectangle_int_t view_layout;
ClutterFrameClock *frame_clock;
g_autoptr (GString) string = NULL;
PangoLayout *layout;
PangoRectangle logical;
ClutterColor color;
g_autoptr (ClutterPaintNode) node = NULL;
ClutterActorBox box;
clutter_stage_view_get_layout (view, &view_layout);
frame_clock = clutter_stage_view_get_frame_clock (view);
string = clutter_frame_clock_get_max_render_time_debug_info (frame_clock);
layout = clutter_actor_create_pango_layout (actor, string->str);
pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
pango_layout_get_pixel_extents (layout, NULL, &logical);
clutter_color_init (&color, 255, 255, 255, 255);
node = clutter_text_node_new (layout, &color);
box.x1 = view_layout.x;
box.y1 = view_layout.y + 30;
box.x2 = box.x1 + logical.width;
box.y2 = box.y1 + logical.height;
clutter_paint_node_add_rectangle (node, &box);
clutter_paint_node_paint (node, paint_context);
g_object_unref (layout);
}
}
static void static void
clutter_stage_class_init (ClutterStageClass *klass) clutter_stage_class_init (ClutterStageClass *klass)
{ {
@ -1335,6 +1380,7 @@ clutter_stage_class_init (ClutterStageClass *klass)
actor_class->hide_all = clutter_stage_hide_all; actor_class->hide_all = clutter_stage_hide_all;
actor_class->queue_relayout = clutter_stage_real_queue_relayout; actor_class->queue_relayout = clutter_stage_real_queue_relayout;
actor_class->apply_transform = clutter_stage_real_apply_transform; actor_class->apply_transform = clutter_stage_real_apply_transform;
actor_class->paint = clutter_stage_paint;
klass->paint_view = clutter_stage_real_paint_view; klass->paint_view = clutter_stage_real_paint_view;