Compare commits

...

6 Commits

Author SHA1 Message Date
Georges Basile Stavracas Neto
d748dc273f
clutter/stage: Cast the stage just when needed
If we use a variable, and the debug notes are disabled at
compile time, the variable becomes unused and we are warned.

Remove this variable and instead cast inline.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/502
2019-04-17 19:26:23 -03:00
Georges Basile Stavracas Neto
a9b642540c
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
2019-04-17 19:26:23 -03:00
Georges Basile Stavracas Neto
6350efc28e
clutter/stage: Add private getter to sync delay
It will be used by the frame chart to correctly place
the red bar. The math is essentially:

  ms_per_frame = (1 / refresh rate) * 1000 - sync delay

https://gitlab.gnome.org/GNOME/mutter/merge_requests/502
2019-04-17 17:42:35 -03:00
Georges Basile Stavracas Neto
f7321d235f
Allow changing Clutter debug flags at runtime
This way, we can literally pop up the Looking Glass and
call:

 >>> Meta.add_clutter_debug_flags(Clutter.DebugFlag.FRAME_TIME, 0, 0)

And measure specific actions or events on GNOME Shell.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/502
2019-04-17 17:42:35 -03:00
Georges Basile Stavracas Neto
4904430083
clutter/stage: Account for frame times
Instead of accumulating frames, simply calculate and
debug-dump the time each frame takes to be drawn.

Because we're using Clutter's debug machinery, it is
structured and can be parsed by scripts.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/502
2019-04-17 17:42:35 -03:00
Georges Basile Stavracas Neto
290f48f29a
Replace CLUTTER_SHOW_FPS by a proper debug flag
Instead of CLUTTER_SHOW_FPS=1, it should be passed now
CLUTTER_DEBUG=frame-time.

Also remove the legacy code related to the FPS counter.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/502
2019-04-17 17:42:32 -03:00
11 changed files with 374 additions and 120 deletions

View File

@ -6,46 +6,6 @@
G_BEGIN_DECLS
typedef enum
{
CLUTTER_DEBUG_MISC = 1 << 0,
CLUTTER_DEBUG_ACTOR = 1 << 1,
CLUTTER_DEBUG_TEXTURE = 1 << 2,
CLUTTER_DEBUG_EVENT = 1 << 3,
CLUTTER_DEBUG_PAINT = 1 << 4,
CLUTTER_DEBUG_PANGO = 1 << 5,
CLUTTER_DEBUG_BACKEND = 1 << 6,
CLUTTER_DEBUG_SCHEDULER = 1 << 7,
CLUTTER_DEBUG_SCRIPT = 1 << 8,
CLUTTER_DEBUG_SHADER = 1 << 9,
CLUTTER_DEBUG_MULTISTAGE = 1 << 10,
CLUTTER_DEBUG_ANIMATION = 1 << 11,
CLUTTER_DEBUG_LAYOUT = 1 << 12,
CLUTTER_DEBUG_PICK = 1 << 13,
CLUTTER_DEBUG_EVENTLOOP = 1 << 14,
CLUTTER_DEBUG_CLIPPING = 1 << 15,
CLUTTER_DEBUG_OOB_TRANSFORMS = 1 << 16
} ClutterDebugFlag;
typedef enum
{
CLUTTER_DEBUG_NOP_PICKING = 1 << 0,
CLUTTER_DEBUG_DUMP_PICK_BUFFERS = 1 << 1
} ClutterPickDebugFlag;
typedef enum
{
CLUTTER_DEBUG_DISABLE_SWAP_EVENTS = 1 << 0,
CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS = 1 << 1,
CLUTTER_DEBUG_REDRAWS = 1 << 2,
CLUTTER_DEBUG_PAINT_VOLUMES = 1 << 3,
CLUTTER_DEBUG_DISABLE_CULLING = 1 << 4,
CLUTTER_DEBUG_DISABLE_OFFSCREEN_REDIRECT = 1 << 5,
CLUTTER_DEBUG_CONTINUOUS_REDRAW = 1 << 6,
CLUTTER_DEBUG_PAINT_DEFORM_TILES = 1 << 7,
CLUTTER_DEBUG_PAINT_DAMAGE_REGION = 1 << 8,
} ClutterDrawDebugFlag;
#ifdef CLUTTER_ENABLE_DEBUG
#define CLUTTER_HAS_DEBUG(type) ((clutter_debug_flags & CLUTTER_DEBUG_##type) != FALSE)

View File

@ -89,7 +89,6 @@ static GCallback clutter_threads_unlock = NULL;
/* command line options */
static gboolean clutter_is_initialized = FALSE;
static gboolean clutter_show_fps = FALSE;
static gboolean clutter_fatal_warnings = FALSE;
static gboolean clutter_disable_mipmap_text = FALSE;
static gboolean clutter_use_fuzzy_picking = FALSE;
@ -125,6 +124,7 @@ static const GDebugKey clutter_debug_keys[] = {
{ "layout", CLUTTER_DEBUG_LAYOUT },
{ "clipping", CLUTTER_DEBUG_CLIPPING },
{ "oob-transforms", CLUTTER_DEBUG_OOB_TRANSFORMS },
{ "frame-time", CLUTTER_DEBUG_FRAME_TIME },
};
#endif /* CLUTTER_ENABLE_DEBUG */
@ -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
@ -204,16 +205,6 @@ clutter_config_read_from_key_file (GKeyFile *keyfile)
g_free (str_value);
bool_value =
g_key_file_get_boolean (keyfile, ENVIRONMENT_GROUP,
"ShowFps",
&key_error);
if (key_error != NULL)
g_clear_error (&key_error);
else
clutter_show_fps = bool_value;
bool_value =
g_key_file_get_boolean (keyfile, ENVIRONMENT_GROUP,
"DisableMipmappedText",
@ -382,36 +373,6 @@ clutter_config_read (void)
g_free (config_path);
}
/**
* clutter_get_show_fps:
*
* Returns whether Clutter should print out the frames per second on the
* console. You can enable this setting either using the
* <literal>CLUTTER_SHOW_FPS</literal> environment variable or passing
* the <literal>--clutter-show-fps</literal> command line argument. *
*
* Return value: %TRUE if Clutter should show the FPS.
*
* Since: 0.4
*
* Deprecated: 1.10: This function does not do anything. Use the environment
* variable or the configuration file to determine whether Clutter should
* print out the FPS counter on the console.
*/
gboolean
clutter_get_show_fps (void)
{
return FALSE;
}
gboolean
_clutter_context_get_show_fps (void)
{
ClutterMainContext *context = _clutter_context_get_default ();
return context->show_fps;
}
/**
* clutter_get_accessibility_enabled:
*
@ -1370,8 +1331,6 @@ clutter_init_real (GError **error)
}
static GOptionEntry clutter_args[] = {
{ "clutter-show-fps", 0, 0, G_OPTION_ARG_NONE, &clutter_show_fps,
N_("Show frames per second"), NULL },
{ "clutter-default-fps", 0, 0, G_OPTION_ARG_INT, &clutter_default_fps,
N_("Default frame rate"), "FPS" },
{ "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &clutter_fatal_warnings,
@ -1450,10 +1409,6 @@ pre_parse_hook (GOptionContext *context,
env_string = NULL;
}
env_string = g_getenv ("CLUTTER_SHOW_FPS");
if (env_string)
clutter_show_fps = TRUE;
env_string = g_getenv ("CLUTTER_DEFAULT_FPS");
if (env_string)
{
@ -1502,7 +1457,6 @@ post_parse_hook (GOptionContext *context,
}
clutter_context->frame_rate = clutter_default_fps;
clutter_context->show_fps = clutter_show_fps;
clutter_context->options_parsed = TRUE;
/* If not asked to defer display setup, call clutter_init_real(),
@ -3604,6 +3558,36 @@ clutter_check_windowing_backend (const char *backend_type)
return FALSE;
}
/**
* clutter_add_debug_flags: (skip)
*
* Adds the debug flags passed to the list of debug flags.
*/
void
clutter_add_debug_flags (ClutterDebugFlag debug_flags,
ClutterDrawDebugFlag draw_flags,
ClutterPickDebugFlag pick_flags)
{
clutter_debug_flags |= debug_flags;
clutter_paint_debug_flags |= draw_flags;
clutter_pick_debug_flags |= pick_flags;
}
/**
* clutter_remove_debug_flags: (skip)
*
* Removes the debug flags passed from the list of debug flags.
*/
void
clutter_remove_debug_flags (ClutterDebugFlag debug_flags,
ClutterDrawDebugFlag draw_flags,
ClutterPickDebugFlag pick_flags)
{
clutter_debug_flags &= ~debug_flags;
clutter_paint_debug_flags &= ~draw_flags;
clutter_pick_debug_flags &= ~pick_flags;
}
void
_clutter_set_sync_to_vblank (gboolean sync_to_vblank)
{

View File

@ -34,6 +34,49 @@
G_BEGIN_DECLS
typedef enum
{
CLUTTER_DEBUG_MISC = 1 << 0,
CLUTTER_DEBUG_ACTOR = 1 << 1,
CLUTTER_DEBUG_TEXTURE = 1 << 2,
CLUTTER_DEBUG_EVENT = 1 << 3,
CLUTTER_DEBUG_PAINT = 1 << 4,
CLUTTER_DEBUG_PANGO = 1 << 5,
CLUTTER_DEBUG_BACKEND = 1 << 6,
CLUTTER_DEBUG_SCHEDULER = 1 << 7,
CLUTTER_DEBUG_SCRIPT = 1 << 8,
CLUTTER_DEBUG_SHADER = 1 << 9,
CLUTTER_DEBUG_MULTISTAGE = 1 << 10,
CLUTTER_DEBUG_ANIMATION = 1 << 11,
CLUTTER_DEBUG_LAYOUT = 1 << 12,
CLUTTER_DEBUG_PICK = 1 << 13,
CLUTTER_DEBUG_EVENTLOOP = 1 << 14,
CLUTTER_DEBUG_CLIPPING = 1 << 15,
CLUTTER_DEBUG_OOB_TRANSFORMS = 1 << 16,
CLUTTER_DEBUG_FRAME_TIME = 1 << 17,
} ClutterDebugFlag;
typedef enum
{
CLUTTER_DEBUG_NOP_PICKING = 1 << 0,
CLUTTER_DEBUG_DUMP_PICK_BUFFERS = 1 << 1
} ClutterPickDebugFlag;
typedef enum
{
CLUTTER_DEBUG_DISABLE_SWAP_EVENTS = 1 << 0,
CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS = 1 << 1,
CLUTTER_DEBUG_REDRAWS = 1 << 2,
CLUTTER_DEBUG_PAINT_VOLUMES = 1 << 3,
CLUTTER_DEBUG_DISABLE_CULLING = 1 << 4,
CLUTTER_DEBUG_DISABLE_OFFSCREEN_REDIRECT = 1 << 5,
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;
/**
* CLUTTER_INIT_ERROR:
*
@ -174,6 +217,15 @@ guint clutter_get_default_frame_rate (void);
CLUTTER_EXPORT
gboolean clutter_check_windowing_backend (const char *backend_type);
CLUTTER_EXPORT
void clutter_add_debug_flags (ClutterDebugFlag debug_flags,
ClutterDrawDebugFlag draw_flags,
ClutterPickDebugFlag pick_flags);
CLUTTER_EXPORT
void clutter_remove_debug_flags (ClutterDebugFlag debug_flags,
ClutterDrawDebugFlag draw_flags,
ClutterPickDebugFlag pick_flags);
G_END_DECLS

View File

@ -176,7 +176,6 @@ struct _ClutterMainContext
guint motion_events_per_actor : 1;
guint defer_display_setup : 1;
guint options_parsed : 1;
guint show_fps : 1;
};
/* shared between clutter-main.c and clutter-frame-source.c */
@ -202,7 +201,6 @@ void _clutter_context_push_shader_stack (Clutter
ClutterActor * _clutter_context_pop_shader_stack (ClutterActor *actor);
ClutterActor * _clutter_context_peek_shader_stack (void);
gboolean _clutter_context_get_motion_events_enabled (void);
gboolean _clutter_context_get_show_fps (void);
gboolean _clutter_feature_init (GError **error);

View File

@ -134,6 +134,12 @@ void _clutter_stage_presented (ClutterStage *stag
GList * _clutter_stage_peek_stage_views (ClutterStage *stage);
int clutter_stage_get_sync_delay (ClutterStage *stage);
void clutter_stage_get_frame_times (ClutterStage *stage,
double *paint_time,
double *layout_time);
G_END_DECLS
#endif /* __CLUTTER_STAGE_PRIVATE_H__ */

View File

@ -133,9 +133,6 @@ struct _ClutterStagePrivate
gint sync_delay;
GTimer *fps_timer;
gint32 timer_n_frames;
ClutterIDPool *pick_id_pool;
#ifdef CLUTTER_ENABLE_DEBUG
@ -149,6 +146,9 @@ struct _ClutterStagePrivate
int update_freeze_count;
double last_layout_time;
double last_paint_time;
guint relayout_pending : 1;
guint redraw_pending : 1;
guint is_fullscreen : 1;
@ -1074,11 +1074,15 @@ _clutter_stage_maybe_relayout (ClutterActor *actor)
/* avoid reentrancy */
if (!CLUTTER_ACTOR_IN_RELAYOUT (stage))
{
int64_t start, end;
priv->relayout_pending = FALSE;
priv->stage_was_relayout = TRUE;
CLUTTER_NOTE (ACTOR, "Recomputing layout");
start = g_get_monotonic_time ();
CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_IN_RELAYOUT);
natural_width = natural_height = 0;
@ -1099,14 +1103,20 @@ _clutter_stage_maybe_relayout (ClutterActor *actor)
&box, CLUTTER_ALLOCATION_NONE);
CLUTTER_UNSET_PRIVATE_FLAGS (stage, CLUTTER_IN_RELAYOUT);
end = g_get_monotonic_time ();
priv->last_layout_time = (end - start) / 1000.0;
CLUTTER_NOTE (FRAME_TIME, "LAYOUT: %lf", priv->last_layout_time);
}
}
static void
clutter_stage_do_redraw (ClutterStage *stage)
{
ClutterActor *actor = CLUTTER_ACTOR (stage);
ClutterStagePrivate *priv = stage->priv;
int64_t start;
int64_t end;
if (CLUTTER_ACTOR_IN_DESTRUCTION (stage))
return;
@ -1115,34 +1125,20 @@ clutter_stage_do_redraw (ClutterStage *stage)
return;
CLUTTER_NOTE (PAINT, "Redraw started for stage '%s'[%p]",
_clutter_actor_get_debug_name (actor),
_clutter_actor_get_debug_name (CLUTTER_ACTOR (stage)),
stage);
if (_clutter_context_get_show_fps ())
{
if (priv->fps_timer == NULL)
priv->fps_timer = g_timer_new ();
}
start = g_get_monotonic_time ();
_clutter_stage_window_redraw (priv->impl);
if (_clutter_context_get_show_fps ())
{
priv->timer_n_frames += 1;
end = g_get_monotonic_time ();
if (g_timer_elapsed (priv->fps_timer, NULL) >= 1.0)
{
g_print ("*** FPS for %s: %i ***\n",
_clutter_actor_get_debug_name (actor),
priv->timer_n_frames);
priv->timer_n_frames = 0;
g_timer_start (priv->fps_timer);
}
}
priv->last_paint_time = (end - start) / 1000.0;
CLUTTER_NOTE (FRAME_TIME, "PAINT: %lf", priv->last_paint_time);
CLUTTER_NOTE (PAINT, "Redraw finished for stage '%s'[%p]",
_clutter_actor_get_debug_name (actor),
_clutter_actor_get_debug_name (CLUTTER_ACTOR (stage)),
stage);
}
@ -1886,9 +1882,6 @@ clutter_stage_finalize (GObject *object)
_clutter_id_pool_free (priv->pick_id_pool);
if (priv->fps_timer != NULL)
g_timer_destroy (priv->fps_timer);
if (priv->paint_notify != NULL)
priv->paint_notify (priv->paint_data);
@ -4728,6 +4721,14 @@ clutter_stage_set_sync_delay (ClutterStage *stage,
stage->priv->sync_delay = sync_delay;
}
int
clutter_stage_get_sync_delay (ClutterStage *stage)
{
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), -1);
return stage->priv->sync_delay;
}
/**
* clutter_stage_skip_sync_delay:
* @stage: a #ClutterStage
@ -5097,3 +5098,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;
}

View File

@ -405,6 +405,215 @@ paint_damage_region (ClutterStageWindow *stage_window,
cogl_framebuffer_pop_matrix (framebuffer);
}
#define CHART_COLUMN_WIDTH 6 //px
#define THRESHOLD_LINE_HEIGHT 2 //px
#define MAX_FRAME_TIME_INFO_ENTRIES 1000
typedef struct
{
double layout_time;
double paint_time;
} FrameTimeInfo;
static void
get_frame_time_chart_region (ClutterStageWindow *stage_window,
ClutterStageView *view,
cairo_rectangle_int_t *region)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
cairo_rectangle_int_t painted_region;
cairo_rectangle_int_t layout;
double refresh_rate_bar_height;
double ms_per_frame;
float green_line_y;
int sync_delay;
int n_points;
int i;
clutter_stage_view_get_layout (view, &layout);
painted_region = (cairo_rectangle_int_t) {
.x = layout.x,
.y = layout.y + layout.height,
.width = layout.width,
.height = 0,
};
n_points = layout.width / CHART_COLUMN_WIDTH;
/* Chart */
sync_delay = clutter_stage_get_sync_delay (stage_cogl->wrapper);
ms_per_frame = 1000.0 / stage_cogl->refresh_rate - sync_delay;
refresh_rate_bar_height = layout.height * 0.1;
for (i = 0; i < MIN (stage_cogl->frame_times->len, n_points); i++)
{
int element = stage_cogl->frame_times->len - i - 1;
FrameTimeInfo *info = &g_array_index (stage_cogl->frame_times, FrameTimeInfo, element);
double layout_bar_height;
double paint_bar_height;
/* Layout time section */
layout_bar_height =
info->layout_time / ms_per_frame * refresh_rate_bar_height;
/* Paint time section */
paint_bar_height =
info->paint_time / ms_per_frame * refresh_rate_bar_height;
painted_region.height = MAX (painted_region.height,
paint_bar_height + layout_bar_height);
}
/* Green line (16.667ms) */
green_line_y = layout.height * 0.9;
painted_region.height = MAX (painted_region.height, green_line_y);
/* Update the swap region rectangle */
painted_region.y -= MIN (layout.height, painted_region.height);
_clutter_util_rectangle_union (region, &painted_region, region);
}
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);
cairo_rectangle_int_t layout;
static CoglPipeline *threshold_pipeline = NULL;
static CoglPipeline *paint_time_pipeline = NULL;
static CoglPipeline *layout_time_pipeline = NULL;
CoglMatrix modelview;
double refresh_rate_bar_height;
double ms_per_frame;
float green_line_y;
int sync_delay;
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);
clutter_stage_view_get_layout (view, &layout);
n_points = layout.width / CHART_COLUMN_WIDTH;
/* Chart */
sync_delay = clutter_stage_get_sync_delay (stage_cogl->wrapper);
ms_per_frame = 1000.0 / stage_cogl->refresh_rate - sync_delay;
refresh_rate_bar_height = layout.height * 0.1;
for (i = 0; i < MIN (stage_cogl->frame_times->len, n_points); i++)
{
int element = stage_cogl->frame_times->len - i - 1;
FrameTimeInfo *info = &g_array_index (stage_cogl->frame_times, FrameTimeInfo, element);
double x_1 = layout.width - (i + 1) * CHART_COLUMN_WIDTH;
double x_2 = layout.width - i * CHART_COLUMN_WIDTH;
double layout_bar_height;
double paint_bar_height;
/* Layout time section */
layout_bar_height =
info->layout_time / ms_per_frame * refresh_rate_bar_height;
cogl_framebuffer_draw_rectangle (framebuffer,
layout_time_pipeline,
x_1,
layout.height - layout_bar_height,
x_2,
layout.height);
/* Paint time section */
paint_bar_height =
info->paint_time / ms_per_frame * refresh_rate_bar_height;
cogl_framebuffer_draw_rectangle (framebuffer,
paint_time_pipeline,
x_1,
layout.height - paint_bar_height - layout_bar_height,
x_2,
layout.height - layout_bar_height);
}
/* Green line (16.667ms) */
green_line_y = layout.height * 0.9;
cogl_framebuffer_draw_rectangle (framebuffer,
threshold_pipeline,
0.0f,
green_line_y,
layout.width,
green_line_y + THRESHOLD_LINE_HEIGHT);
cogl_framebuffer_pop_matrix (framebuffer);
}
static inline void
append_frame_time_info (ClutterStageCogl *stage_cogl)
{
FrameTimeInfo previous_frame_info;
if (G_LIKELY (!(clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_FRAME_TIME)))
return;
if (G_UNLIKELY (stage_cogl->frame_times == NULL))
stage_cogl->frame_times = g_array_sized_new (FALSE, TRUE,
sizeof (FrameTimeInfo),
MAX_FRAME_TIME_INFO_ENTRIES);
clutter_stage_get_frame_times (stage_cogl->wrapper,
&previous_frame_info.paint_time,
&previous_frame_info.layout_time);
g_array_append_val (stage_cogl->frame_times, previous_frame_info);
if (stage_cogl->frame_times->len > MAX_FRAME_TIME_INFO_ENTRIES)
g_array_remove_range (stage_cogl->frame_times, 0,
stage_cogl->frame_times->len - MAX_FRAME_TIME_INFO_ENTRIES);
}
static inline void
maybe_paint_frame_times (ClutterStageWindow *stage_window,
ClutterStageView *view)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
if (G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_FRAME_TIME)))
{
paint_frame_time_chart (stage_window, view);
stage_cogl->painting_frame_chart = TRUE;
}
else if (stage_cogl->painting_frame_chart)
{
g_array_free (stage_cogl->frame_times, TRUE);
stage_cogl->frame_times = NULL;
stage_cogl->painting_frame_chart = FALSE;
}
}
static gboolean
swap_framebuffer (ClutterStageWindow *stage_window,
ClutterStageView *view,
@ -672,6 +881,9 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
fb_clip_region = (cairo_rectangle_int_t) { 0 };
}
if (G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_FRAME_TIME)))
get_frame_time_chart_region (stage_window, view, &fb_clip_region);
if (may_use_clipped_redraw &&
G_LIKELY (!(clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS)))
use_clipped_redraw = TRUE;
@ -827,6 +1039,9 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
else
paint_stage (stage_cogl, view, &view_rect);
}
maybe_paint_frame_times (stage_window, view);
cogl_pop_framebuffer ();
if (may_use_clipped_redraw &&
@ -931,6 +1146,8 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
gboolean swap_event = FALSE;
GList *l;
append_frame_time_info (stage_cogl);
for (l = _clutter_stage_window_get_views (stage_window); l; l = l->next)
{
ClutterStageView *view = l->data;

View File

@ -66,6 +66,9 @@ struct _ClutterStageCogl
/* TRUE if the current paint cycle has a clipped redraw. In that
case bounding_redraw_clip specifies the the bounds. */
guint using_clipped_redraw : 1;
gboolean painting_frame_chart;
GArray *frame_times;
};
struct _ClutterStageCoglClass

View File

@ -77,9 +77,6 @@ gulong clutter_get_timestamp (void);
CLUTTER_DEPRECATED
gboolean clutter_get_debug_enabled (void);
CLUTTER_DEPRECATED
gboolean clutter_get_show_fps (void);
G_END_DECLS
#endif /* __CLUTTER_MAIN_DEPRECATED_H__ */

View File

@ -1012,5 +1012,22 @@ meta_generate_random_id (GRand *rand,
return id;
}
void
meta_add_clutter_debug_flags (ClutterDebugFlag debug_flags,
ClutterDrawDebugFlag draw_flags,
ClutterPickDebugFlag pick_flags)
{
clutter_add_debug_flags (debug_flags, draw_flags, pick_flags);
}
void
meta_remove_clutter_debug_flags (ClutterDebugFlag debug_flags,
ClutterDrawDebugFlag draw_flags,
ClutterPickDebugFlag pick_flags)
{
clutter_remove_debug_flags (debug_flags, draw_flags, pick_flags);
}
/* eof util.c */

View File

@ -226,4 +226,14 @@ typedef enum
META_EXPORT
MetaLocaleDirection meta_get_locale_direction (void);
META_EXPORT
void meta_add_clutter_debug_flags (ClutterDebugFlag debug_flags,
ClutterDrawDebugFlag draw_flags,
ClutterPickDebugFlag pick_flags);
META_EXPORT
void meta_remove_clutter_debug_flags (ClutterDebugFlag debug_flags,
ClutterDrawDebugFlag draw_flags,
ClutterPickDebugFlag pick_flags);
#endif /* META_UTIL_H */