mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-16 07:04:29 +00:00
Merge branch 'wip/otte/correct-fps' into 'main'
Fix fps display See merge request GNOME/gtk!7003
This commit is contained in:
commit
1dbc1d67f5
@ -79,14 +79,23 @@ static guint signals[LAST_SIGNAL];
|
||||
|
||||
static guint fps_counter;
|
||||
|
||||
#define FRAME_HISTORY_MAX_LENGTH 128
|
||||
/* 60Hz plus some extra for monotonic time inaccuracy */
|
||||
#define FRAME_HISTORY_DEFAULT_LENGTH 64
|
||||
|
||||
#define frame_timings_unref(x) gdk_frame_timings_unref((GdkFrameTimings *) (x))
|
||||
|
||||
#define GDK_ARRAY_NAME timings
|
||||
#define GDK_ARRAY_TYPE_NAME Timings
|
||||
#define GDK_ARRAY_ELEMENT_TYPE GdkFrameTimings *
|
||||
#define GDK_ARRAY_PREALLOC FRAME_HISTORY_DEFAULT_LENGTH
|
||||
#define GDK_ARRAY_FREE_FUNC frame_timings_unref
|
||||
#include "gdk/gdkarrayimpl.c"
|
||||
|
||||
struct _GdkFrameClockPrivate
|
||||
{
|
||||
gint64 frame_counter;
|
||||
int n_timings;
|
||||
int current;
|
||||
GdkFrameTimings *timings[FRAME_HISTORY_MAX_LENGTH];
|
||||
Timings timings;
|
||||
int n_freeze_inhibitors;
|
||||
};
|
||||
|
||||
@ -99,11 +108,8 @@ static void
|
||||
gdk_frame_clock_finalize (GObject *object)
|
||||
{
|
||||
GdkFrameClockPrivate *priv = GDK_FRAME_CLOCK (object)->priv;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < FRAME_HISTORY_MAX_LENGTH; i++)
|
||||
if (priv->timings[i] != 0)
|
||||
gdk_frame_timings_unref (priv->timings[i]);
|
||||
timings_clear (&priv->timings);
|
||||
|
||||
G_OBJECT_CLASS (gdk_frame_clock_parent_class)->finalize (object);
|
||||
}
|
||||
@ -257,7 +263,8 @@ gdk_frame_clock_init (GdkFrameClock *clock)
|
||||
clock->priv = priv = gdk_frame_clock_get_instance_private (clock);
|
||||
|
||||
priv->frame_counter = -1;
|
||||
priv->current = FRAME_HISTORY_MAX_LENGTH - 1;
|
||||
priv->current = 0;
|
||||
timings_init (&priv->timings);
|
||||
|
||||
if (fps_counter == 0)
|
||||
fps_counter = gdk_profiler_define_counter ("fps", "Frames per Second");
|
||||
@ -416,7 +423,7 @@ gdk_frame_clock_get_frame_counter (GdkFrameClock *frame_clock)
|
||||
static inline gint64
|
||||
_gdk_frame_clock_get_history_start (GdkFrameClock *frame_clock)
|
||||
{
|
||||
return frame_clock->priv->frame_counter + 1 - frame_clock->priv->n_timings;
|
||||
return frame_clock->priv->frame_counter + 1 - timings_get_size (&frame_clock->priv->timings);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -445,31 +452,44 @@ gdk_frame_clock_get_history_start (GdkFrameClock *frame_clock)
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_frame_clock_begin_frame (GdkFrameClock *frame_clock)
|
||||
_gdk_frame_clock_begin_frame (GdkFrameClock *frame_clock,
|
||||
gint64 monotonic_time)
|
||||
{
|
||||
GdkFrameClockPrivate *priv;
|
||||
|
||||
g_return_if_fail (GDK_IS_FRAME_CLOCK (frame_clock));
|
||||
|
||||
priv = frame_clock->priv;
|
||||
|
||||
priv->frame_counter++;
|
||||
priv->current = (priv->current + 1) % FRAME_HISTORY_MAX_LENGTH;
|
||||
|
||||
/* Try to steal the previous frame timing instead of discarding
|
||||
* and allocating a new one.
|
||||
*/
|
||||
if G_LIKELY (priv->n_timings == FRAME_HISTORY_MAX_LENGTH &&
|
||||
_gdk_frame_timings_steal (priv->timings[priv->current],
|
||||
priv->frame_counter))
|
||||
return;
|
||||
|
||||
if (priv->n_timings < FRAME_HISTORY_MAX_LENGTH)
|
||||
priv->n_timings++;
|
||||
if (G_UNLIKELY (timings_get_size (&priv->timings) == 0))
|
||||
timings_append (&priv->timings, _gdk_frame_timings_new (priv->frame_counter));
|
||||
else
|
||||
gdk_frame_timings_unref (priv->timings[priv->current]);
|
||||
{
|
||||
GdkFrameTimings *timings;
|
||||
|
||||
priv->timings[priv->current] = _gdk_frame_timings_new (priv->frame_counter);
|
||||
priv->current = (priv->current + 1) % timings_get_size (&priv->timings);
|
||||
|
||||
timings = timings_get (&priv->timings, priv->current);
|
||||
|
||||
if (timings->frame_time + G_USEC_PER_SEC > monotonic_time)
|
||||
{
|
||||
/* Keep the timings, not a second old yet */
|
||||
timings = _gdk_frame_timings_new (priv->frame_counter);
|
||||
timings_splice (&priv->timings, priv->current, 0, FALSE, &timings, 1);
|
||||
}
|
||||
else if (_gdk_frame_timings_steal (timings, priv->frame_counter))
|
||||
{
|
||||
/* Stole the previous frame timing instead of discarding
|
||||
* and allocating a new one, so nothing to do
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
timings = _gdk_frame_timings_new (priv->frame_counter);
|
||||
timings_splice (&priv->timings, priv->current, 1, FALSE, &timings, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline GdkFrameTimings *
|
||||
@ -477,17 +497,21 @@ _gdk_frame_clock_get_timings (GdkFrameClock *frame_clock,
|
||||
gint64 frame_counter)
|
||||
{
|
||||
GdkFrameClockPrivate *priv = frame_clock->priv;
|
||||
int pos;
|
||||
gsize size, pos;
|
||||
|
||||
if (frame_counter > priv->frame_counter)
|
||||
return NULL;
|
||||
|
||||
if (frame_counter <= priv->frame_counter - priv->n_timings)
|
||||
size = timings_get_size (&priv->timings);
|
||||
if (G_UNLIKELY (size == 0))
|
||||
return NULL;
|
||||
|
||||
pos = (priv->current - (priv->frame_counter - frame_counter) + FRAME_HISTORY_MAX_LENGTH) % FRAME_HISTORY_MAX_LENGTH;
|
||||
if (priv->frame_counter - frame_counter >= size)
|
||||
return NULL;
|
||||
|
||||
return priv->timings[pos];
|
||||
pos = (priv->current - (priv->frame_counter - frame_counter) + size) % size;
|
||||
|
||||
return timings_get (&priv->timings, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -779,7 +803,10 @@ gdk_frame_clock_get_fps (GdkFrameClock *frame_clock)
|
||||
|
||||
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 (start = _gdk_frame_clock_get_timings (frame_clock, start_counter);
|
||||
end_counter > start_counter && start != NULL && !gdk_frame_timings_get_complete (start);
|
||||
start = _gdk_frame_clock_get_timings (frame_clock, start_counter))
|
||||
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))
|
||||
|
@ -555,7 +555,7 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
priv->smoothed_frame_time_period = frame_interval;
|
||||
priv->smoothed_frame_time_reported = priv->smoothed_frame_time_base;
|
||||
|
||||
_gdk_frame_clock_begin_frame (clock);
|
||||
_gdk_frame_clock_begin_frame (clock, priv->frame_time);
|
||||
/* Note "current" is different now so timings != prev_timings */
|
||||
timings = gdk_frame_clock_get_current_timings (clock);
|
||||
|
||||
|
@ -106,7 +106,8 @@ struct _GdkFrameTimings
|
||||
void _gdk_frame_clock_inhibit_freeze (GdkFrameClock *clock);
|
||||
void _gdk_frame_clock_uninhibit_freeze (GdkFrameClock *clock);
|
||||
|
||||
void _gdk_frame_clock_begin_frame (GdkFrameClock *clock);
|
||||
void _gdk_frame_clock_begin_frame (GdkFrameClock *clock,
|
||||
gint64 monotonic_time);
|
||||
void _gdk_frame_clock_debug_print_timings (GdkFrameClock *clock,
|
||||
GdkFrameTimings *timings);
|
||||
void _gdk_frame_clock_add_timings_to_profiler (GdkFrameClock *frame_clock,
|
||||
|
@ -83,7 +83,7 @@ gtk_fps_info_new (GtkWidget *widget)
|
||||
|
||||
info = g_new0 (GtkFpsInfo, 1);
|
||||
|
||||
layout = gtk_widget_create_pango_layout (widget, "0000.00 fps");
|
||||
layout = gtk_widget_create_pango_layout (widget, "000000.00 fps");
|
||||
attrs = pango_attr_list_new ();
|
||||
pango_attr_list_insert (attrs, pango_attr_font_features_new ("tnum=1"));
|
||||
pango_layout_set_attributes (layout, attrs);
|
||||
@ -202,23 +202,37 @@ gtk_fps_overlay_snapshot (GtkInspectorOverlay *overlay,
|
||||
|
||||
if (overlay_opacity < 1.0)
|
||||
gtk_snapshot_push_opacity (snapshot, overlay_opacity);
|
||||
gtk_snapshot_append_color (snapshot,
|
||||
&(GdkRGBA) { 0, 0, 0, 0.5 },
|
||||
&GRAPHENE_RECT_INIT (-1, -1, info->width + 2, info->height + 2));
|
||||
|
||||
fps = gtk_fps_overlay_get_fps (widget);
|
||||
if (fps != 0.0)
|
||||
{
|
||||
GskRenderNode *fps_node;
|
||||
char fps_string[40];
|
||||
gboolean bg_drawn = FALSE;
|
||||
float bg_x = 0;
|
||||
|
||||
g_snprintf (fps_string, sizeof (fps_string), "%7.2f fps", fps);
|
||||
for (int i = 0; i < 7; i++)
|
||||
g_snprintf (fps_string, sizeof (fps_string), "%9.2f fps", fps);
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
if (g_ascii_isdigit (fps_string[i]))
|
||||
info->glyphs->glyphs[i].glyph = info->digits->glyphs[fps_string[i] - '0'].glyph;
|
||||
else if (fps_string[i] == ' ')
|
||||
info->glyphs->glyphs[i].glyph = info->digits->glyphs[10].glyph;
|
||||
if (fps_string[i] == ' ')
|
||||
{
|
||||
info->glyphs->glyphs[i].glyph = info->digits->glyphs[10].glyph;
|
||||
bg_x += (float) info->glyphs->glyphs[i].geometry.width / PANGO_SCALE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!bg_drawn)
|
||||
{
|
||||
gtk_snapshot_append_color (snapshot,
|
||||
&(GdkRGBA) { 0, 0, 0, 0.5 },
|
||||
&GRAPHENE_RECT_INIT (bg_x - 1, -1,
|
||||
info->width + 2 - bg_x, info->height + 2));
|
||||
bg_drawn = TRUE;
|
||||
}
|
||||
|
||||
if (g_ascii_isdigit (fps_string[i]))
|
||||
info->glyphs->glyphs[i].glyph = info->digits->glyphs[fps_string[i] - '0'].glyph;
|
||||
}
|
||||
}
|
||||
|
||||
fps_node = gsk_text_node_new (info->font,
|
||||
|
Loading…
Reference in New Issue
Block a user