mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-28 06:21:14 +00:00
demo: Move benchmarking implementation to fishbowl widget
This commit is contained in:
parent
8756748525
commit
db5b8ca997
@ -9,162 +9,6 @@
|
|||||||
|
|
||||||
#include "gtkfishbowl.h"
|
#include "gtkfishbowl.h"
|
||||||
|
|
||||||
GtkWidget *info_label;
|
|
||||||
GtkWidget *allow_changes;
|
|
||||||
|
|
||||||
#define N_STATS 5
|
|
||||||
|
|
||||||
#define STATS_UPDATE_TIME G_USEC_PER_SEC
|
|
||||||
|
|
||||||
typedef struct _Stats Stats;
|
|
||||||
struct _Stats {
|
|
||||||
gint last_suggestion;
|
|
||||||
};
|
|
||||||
|
|
||||||
static Stats *
|
|
||||||
get_stats (GtkWidget *widget)
|
|
||||||
{
|
|
||||||
static GQuark stats_quark = 0;
|
|
||||||
Stats *stats;
|
|
||||||
|
|
||||||
if (G_UNLIKELY (stats_quark == 0))
|
|
||||||
stats_quark = g_quark_from_static_string ("stats");
|
|
||||||
|
|
||||||
stats = g_object_get_qdata (G_OBJECT (widget), stats_quark);
|
|
||||||
if (stats == NULL)
|
|
||||||
{
|
|
||||||
stats = g_new0 (Stats, 1);
|
|
||||||
g_object_set_qdata_full (G_OBJECT (widget), stats_quark, stats, g_free);
|
|
||||||
}
|
|
||||||
|
|
||||||
return stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gint64
|
|
||||||
guess_refresh_interval (GdkFrameClock *frame_clock)
|
|
||||||
{
|
|
||||||
gint64 interval;
|
|
||||||
gint64 i;
|
|
||||||
|
|
||||||
interval = G_MAXINT64;
|
|
||||||
|
|
||||||
for (i = gdk_frame_clock_get_history_start (frame_clock);
|
|
||||||
i < gdk_frame_clock_get_frame_counter (frame_clock);
|
|
||||||
i++)
|
|
||||||
{
|
|
||||||
GdkFrameTimings *t, *before;
|
|
||||||
gint64 ts, before_ts;
|
|
||||||
|
|
||||||
t = gdk_frame_clock_get_timings (frame_clock, i);
|
|
||||||
before = gdk_frame_clock_get_timings (frame_clock, i - 1);
|
|
||||||
if (t == NULL || before == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ts = gdk_frame_timings_get_frame_time (t);
|
|
||||||
before_ts = gdk_frame_timings_get_frame_time (before);
|
|
||||||
if (ts == 0 || before_ts == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
interval = MIN (interval, ts - before_ts);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interval == G_MAXINT64)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return interval;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
do_stats (GtkWidget *widget,
|
|
||||||
gint *suggested_change)
|
|
||||||
{
|
|
||||||
GdkFrameClock *frame_clock;
|
|
||||||
Stats *stats;
|
|
||||||
GdkFrameTimings *start, *end;
|
|
||||||
gint64 start_counter, end_counter;
|
|
||||||
gint64 n_frames, expected_frames;
|
|
||||||
gint64 start_timestamp, end_timestamp;
|
|
||||||
gint64 interval;
|
|
||||||
char *new_label;
|
|
||||||
|
|
||||||
stats = get_stats (widget);
|
|
||||||
frame_clock = gtk_widget_get_frame_clock (widget);
|
|
||||||
if (frame_clock == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
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 (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))
|
|
||||||
end_counter--;
|
|
||||||
if (end_counter - start_counter < 4)
|
|
||||||
return;
|
|
||||||
|
|
||||||
start_timestamp = gdk_frame_timings_get_presentation_time (start);
|
|
||||||
end_timestamp = gdk_frame_timings_get_presentation_time (end);
|
|
||||||
if (start_timestamp == 0 || end_timestamp == 0)
|
|
||||||
{
|
|
||||||
start_timestamp = gdk_frame_timings_get_frame_time (start);
|
|
||||||
end_timestamp = gdk_frame_timings_get_frame_time (end);
|
|
||||||
}
|
|
||||||
|
|
||||||
interval = gdk_frame_timings_get_refresh_interval (end);
|
|
||||||
if (interval == 0)
|
|
||||||
{
|
|
||||||
interval = guess_refresh_interval (frame_clock);
|
|
||||||
if (interval == 0)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
n_frames = end_counter - start_counter;
|
|
||||||
expected_frames = round ((double) (end_timestamp - start_timestamp) / interval);
|
|
||||||
|
|
||||||
new_label = g_strdup_printf ("icons - %.1f fps",
|
|
||||||
((double) n_frames) * G_USEC_PER_SEC / (end_timestamp - start_timestamp));
|
|
||||||
gtk_label_set_label (GTK_LABEL (info_label), new_label);
|
|
||||||
g_free (new_label);
|
|
||||||
|
|
||||||
if (n_frames >= expected_frames)
|
|
||||||
{
|
|
||||||
if (stats->last_suggestion > 0)
|
|
||||||
stats->last_suggestion *= 2;
|
|
||||||
else
|
|
||||||
stats->last_suggestion = 1;
|
|
||||||
}
|
|
||||||
else if (n_frames + 1 < expected_frames)
|
|
||||||
{
|
|
||||||
if (stats->last_suggestion < 0)
|
|
||||||
stats->last_suggestion--;
|
|
||||||
else
|
|
||||||
stats->last_suggestion = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stats->last_suggestion = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (suggested_change)
|
|
||||||
*suggested_change = stats->last_suggestion;
|
|
||||||
else
|
|
||||||
stats->last_suggestion = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
move_fish (gpointer bowl)
|
|
||||||
{
|
|
||||||
gint suggested_change = 0, new_count;
|
|
||||||
|
|
||||||
do_stats (bowl,
|
|
||||||
!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (allow_changes)) ? &suggested_change : NULL);
|
|
||||||
|
|
||||||
new_count = gtk_fishbowl_get_count (GTK_FISHBOWL (bowl)) + suggested_change;
|
|
||||||
new_count = MAX (1, new_count);
|
|
||||||
gtk_fishbowl_set_count (GTK_FISHBOWL (bowl), new_count);
|
|
||||||
|
|
||||||
return G_SOURCE_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
do_fishbowl (GtkWidget *do_widget)
|
do_fishbowl (GtkWidget *do_widget)
|
||||||
{
|
{
|
||||||
@ -182,19 +26,12 @@ do_fishbowl (GtkWidget *do_widget)
|
|||||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||||
bowl = GTK_WIDGET (gtk_builder_get_object (builder, "bowl"));
|
bowl = GTK_WIDGET (gtk_builder_get_object (builder, "bowl"));
|
||||||
gtk_fishbowl_set_use_icons (GTK_FISHBOWL (bowl), TRUE);
|
gtk_fishbowl_set_use_icons (GTK_FISHBOWL (bowl), TRUE);
|
||||||
info_label = GTK_WIDGET (gtk_builder_get_object (builder, "info_label"));
|
|
||||||
allow_changes = GTK_WIDGET (gtk_builder_get_object (builder, "changes_allow"));
|
|
||||||
gtk_window_set_display (GTK_WINDOW (window),
|
gtk_window_set_display (GTK_WINDOW (window),
|
||||||
gtk_widget_get_display (do_widget));
|
gtk_widget_get_display (do_widget));
|
||||||
g_signal_connect (window, "destroy",
|
g_signal_connect (window, "destroy",
|
||||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||||
|
|
||||||
gtk_widget_realize (window);
|
gtk_widget_realize (window);
|
||||||
g_timeout_add_seconds_full (G_PRIORITY_DEFAULT_IDLE,
|
|
||||||
1,
|
|
||||||
move_fish,
|
|
||||||
bowl,
|
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
|
@ -7,7 +7,24 @@
|
|||||||
<object class="GtkHeaderBar" id="">
|
<object class="GtkHeaderBar" id="">
|
||||||
<property name="show-title-buttons">1</property>
|
<property name="show-title-buttons">1</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="info_label">
|
<object class="GtkLabel">
|
||||||
|
<property name="label">fps</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="pack-type">end</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label" bind-source="bowl" bind-property="framerate"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="pack-type">end</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">Icons, </property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="pack-type">end</property>
|
<property name="pack-type">end</property>
|
||||||
@ -48,6 +65,7 @@
|
|||||||
<object class="GtkFishbowl" id="bowl">
|
<object class="GtkFishbowl" id="bowl">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="animating">True</property>
|
<property name="animating">True</property>
|
||||||
|
<property name="benchmark" bind-source="changes_allow" bind-property="active" bind-flags="invert-boolean">True</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
@ -28,9 +28,14 @@ struct _GtkFishbowlPrivate
|
|||||||
guint count;
|
guint count;
|
||||||
|
|
||||||
gint64 last_frame_time;
|
gint64 last_frame_time;
|
||||||
|
gint64 update_delay;
|
||||||
guint tick_id;
|
guint tick_id;
|
||||||
|
|
||||||
guint use_icons: 1;
|
double framerate;
|
||||||
|
int last_benchmark_change;
|
||||||
|
|
||||||
|
guint use_icons : 1;
|
||||||
|
guint benchmark : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GtkFishbowlChild
|
struct _GtkFishbowlChild
|
||||||
@ -45,7 +50,10 @@ struct _GtkFishbowlChild
|
|||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_ANIMATING,
|
PROP_ANIMATING,
|
||||||
|
PROP_BENCHMARK,
|
||||||
PROP_COUNT,
|
PROP_COUNT,
|
||||||
|
PROP_FRAMERATE,
|
||||||
|
PROP_UPDATE_DELAY,
|
||||||
NUM_PROPERTIES
|
NUM_PROPERTIES
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -56,7 +64,11 @@ G_DEFINE_TYPE_WITH_PRIVATE (GtkFishbowl, gtk_fishbowl, GTK_TYPE_CONTAINER)
|
|||||||
static void
|
static void
|
||||||
gtk_fishbowl_init (GtkFishbowl *fishbowl)
|
gtk_fishbowl_init (GtkFishbowl *fishbowl)
|
||||||
{
|
{
|
||||||
|
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||||
|
|
||||||
gtk_widget_set_has_surface (GTK_WIDGET (fishbowl), FALSE);
|
gtk_widget_set_has_surface (GTK_WIDGET (fishbowl), FALSE);
|
||||||
|
|
||||||
|
priv->update_delay = G_USEC_PER_SEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -264,10 +276,18 @@ gtk_fishbowl_set_property (GObject *object,
|
|||||||
gtk_fishbowl_set_animating (fishbowl, g_value_get_boolean (value));
|
gtk_fishbowl_set_animating (fishbowl, g_value_get_boolean (value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_BENCHMARK:
|
||||||
|
gtk_fishbowl_set_benchmark (fishbowl, g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
|
|
||||||
case PROP_COUNT:
|
case PROP_COUNT:
|
||||||
gtk_fishbowl_set_count (fishbowl, g_value_get_uint (value));
|
gtk_fishbowl_set_count (fishbowl, g_value_get_uint (value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_UPDATE_DELAY:
|
||||||
|
gtk_fishbowl_set_update_delay (fishbowl, g_value_get_int64 (value));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -288,10 +308,22 @@ gtk_fishbowl_get_property (GObject *object,
|
|||||||
g_value_set_boolean (value, gtk_fishbowl_get_animating (fishbowl));
|
g_value_set_boolean (value, gtk_fishbowl_get_animating (fishbowl));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_BENCHMARK:
|
||||||
|
g_value_set_boolean (value, gtk_fishbowl_get_benchmark (fishbowl));
|
||||||
|
break;
|
||||||
|
|
||||||
case PROP_COUNT:
|
case PROP_COUNT:
|
||||||
g_value_set_uint (value, gtk_fishbowl_get_count (fishbowl));
|
g_value_set_uint (value, gtk_fishbowl_get_count (fishbowl));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_FRAMERATE:
|
||||||
|
g_value_set_double (value, gtk_fishbowl_get_framerate (fishbowl));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_UPDATE_DELAY:
|
||||||
|
g_value_set_int64 (value, gtk_fishbowl_get_update_delay (fishbowl));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -323,14 +355,37 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
|
|||||||
FALSE,
|
FALSE,
|
||||||
G_PARAM_READWRITE);
|
G_PARAM_READWRITE);
|
||||||
|
|
||||||
|
props[PROP_BENCHMARK] =
|
||||||
|
g_param_spec_boolean ("benchmark",
|
||||||
|
"Benchmark",
|
||||||
|
"Adapt the count property to hit the maximum framerate",
|
||||||
|
FALSE,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
|
||||||
props[PROP_COUNT] =
|
props[PROP_COUNT] =
|
||||||
g_param_spec_uint ("count",
|
g_param_spec_uint ("count",
|
||||||
"Count",
|
"Count",
|
||||||
"Number of widgets",
|
"Number of widgets",
|
||||||
0, G_MAXUINT,
|
0, G_MAXUINT,
|
||||||
0,
|
0,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
|
||||||
|
props[PROP_FRAMERATE] =
|
||||||
|
g_param_spec_double ("framerate",
|
||||||
|
"Framerate",
|
||||||
|
"Framerate of this widget in frames per second",
|
||||||
|
0, G_MAXDOUBLE,
|
||||||
|
0,
|
||||||
G_PARAM_READABLE);
|
G_PARAM_READABLE);
|
||||||
|
|
||||||
|
props[PROP_UPDATE_DELAY] =
|
||||||
|
g_param_spec_int64 ("update-delay",
|
||||||
|
"Update delay",
|
||||||
|
"Number of usecs between updates",
|
||||||
|
0, G_MAXINT64,
|
||||||
|
G_USEC_PER_SEC,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
|
||||||
g_object_class_install_properties (object_class, NUM_PROPERTIES, props);
|
g_object_class_install_properties (object_class, NUM_PROPERTIES, props);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,6 +487,30 @@ gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
|
|||||||
g_object_thaw_notify (G_OBJECT (fishbowl));
|
g_object_thaw_notify (G_OBJECT (fishbowl));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gtk_fishbowl_get_benchmark (GtkFishbowl *fishbowl)
|
||||||
|
{
|
||||||
|
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||||
|
|
||||||
|
return priv->benchmark;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gtk_fishbowl_set_benchmark (GtkFishbowl *fishbowl,
|
||||||
|
gboolean benchmark)
|
||||||
|
{
|
||||||
|
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||||
|
|
||||||
|
if (priv->benchmark == benchmark)
|
||||||
|
return;
|
||||||
|
|
||||||
|
priv->benchmark = benchmark;
|
||||||
|
if (!benchmark)
|
||||||
|
priv->last_benchmark_change = 0;
|
||||||
|
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_BENCHMARK]);
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gtk_fishbowl_get_animating (GtkFishbowl *fishbowl)
|
gtk_fishbowl_get_animating (GtkFishbowl *fishbowl)
|
||||||
{
|
{
|
||||||
@ -440,6 +519,111 @@ gtk_fishbowl_get_animating (GtkFishbowl *fishbowl)
|
|||||||
return priv->tick_id != 0;
|
return priv->tick_id != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gint64
|
||||||
|
guess_refresh_interval (GdkFrameClock *frame_clock)
|
||||||
|
{
|
||||||
|
gint64 interval;
|
||||||
|
gint64 i;
|
||||||
|
|
||||||
|
interval = G_MAXINT64;
|
||||||
|
|
||||||
|
for (i = gdk_frame_clock_get_history_start (frame_clock);
|
||||||
|
i < gdk_frame_clock_get_frame_counter (frame_clock);
|
||||||
|
i++)
|
||||||
|
{
|
||||||
|
GdkFrameTimings *t, *before;
|
||||||
|
gint64 ts, before_ts;
|
||||||
|
|
||||||
|
t = gdk_frame_clock_get_timings (frame_clock, i);
|
||||||
|
before = gdk_frame_clock_get_timings (frame_clock, i - 1);
|
||||||
|
if (t == NULL || before == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ts = gdk_frame_timings_get_frame_time (t);
|
||||||
|
before_ts = gdk_frame_timings_get_frame_time (before);
|
||||||
|
if (ts == 0 || before_ts == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
interval = MIN (interval, ts - before_ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interval == G_MAXINT64)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_fishbowl_do_update (GtkFishbowl *fishbowl)
|
||||||
|
{
|
||||||
|
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||||
|
GdkFrameClock *frame_clock;
|
||||||
|
GdkFrameTimings *start, *end;
|
||||||
|
gint64 start_counter, end_counter;
|
||||||
|
gint64 n_frames, expected_frames;
|
||||||
|
gint64 start_timestamp, end_timestamp;
|
||||||
|
gint64 interval;
|
||||||
|
|
||||||
|
frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (fishbowl));
|
||||||
|
if (frame_clock == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
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 (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))
|
||||||
|
end_counter--;
|
||||||
|
if (end_counter - start_counter < 4)
|
||||||
|
return;
|
||||||
|
|
||||||
|
start_timestamp = gdk_frame_timings_get_presentation_time (start);
|
||||||
|
end_timestamp = gdk_frame_timings_get_presentation_time (end);
|
||||||
|
if (start_timestamp == 0 || end_timestamp == 0)
|
||||||
|
{
|
||||||
|
start_timestamp = gdk_frame_timings_get_frame_time (start);
|
||||||
|
end_timestamp = gdk_frame_timings_get_frame_time (end);
|
||||||
|
}
|
||||||
|
|
||||||
|
n_frames = end_counter - start_counter;
|
||||||
|
priv->framerate = ((double) n_frames) * G_USEC_PER_SEC / (end_timestamp - start_timestamp);
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_FRAMERATE]);
|
||||||
|
|
||||||
|
if (!priv->benchmark)
|
||||||
|
return;
|
||||||
|
|
||||||
|
interval = gdk_frame_timings_get_refresh_interval (end);
|
||||||
|
if (interval == 0)
|
||||||
|
{
|
||||||
|
interval = guess_refresh_interval (frame_clock);
|
||||||
|
if (interval == 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
expected_frames = round ((double) (end_timestamp - start_timestamp) / interval);
|
||||||
|
|
||||||
|
if (n_frames >= expected_frames)
|
||||||
|
{
|
||||||
|
if (priv->last_benchmark_change > 0)
|
||||||
|
priv->last_benchmark_change *= 2;
|
||||||
|
else
|
||||||
|
priv->last_benchmark_change = 1;
|
||||||
|
}
|
||||||
|
else if (n_frames + 1 < expected_frames)
|
||||||
|
{
|
||||||
|
if (priv->last_benchmark_change < 0)
|
||||||
|
priv->last_benchmark_change--;
|
||||||
|
else
|
||||||
|
priv->last_benchmark_change = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
priv->last_benchmark_change = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_fishbowl_set_count (fishbowl, MAX (1, priv->count + priv->last_benchmark_change));
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gtk_fishbowl_tick (GtkWidget *widget,
|
gtk_fishbowl_tick (GtkWidget *widget,
|
||||||
GdkFrameClock *frame_clock,
|
GdkFrameClock *frame_clock,
|
||||||
@ -450,9 +634,11 @@ gtk_fishbowl_tick (GtkWidget *widget,
|
|||||||
GtkFishbowlChild *child;
|
GtkFishbowlChild *child;
|
||||||
GList *l;
|
GList *l;
|
||||||
gint64 frame_time, elapsed;
|
gint64 frame_time, elapsed;
|
||||||
|
gboolean do_update;
|
||||||
|
|
||||||
frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
|
frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
|
||||||
elapsed = frame_time - priv->last_frame_time;
|
elapsed = frame_time - priv->last_frame_time;
|
||||||
|
do_update = frame_time / priv->update_delay != priv->last_frame_time / priv->update_delay;
|
||||||
priv->last_frame_time = frame_time;
|
priv->last_frame_time = frame_time;
|
||||||
|
|
||||||
/* last frame was 0, so we're just starting to animate */
|
/* last frame was 0, so we're just starting to animate */
|
||||||
@ -491,6 +677,9 @@ gtk_fishbowl_tick (GtkWidget *widget,
|
|||||||
|
|
||||||
gtk_widget_queue_allocate (widget);
|
gtk_widget_queue_allocate (widget);
|
||||||
|
|
||||||
|
if (do_update)
|
||||||
|
gtk_fishbowl_do_update (fishbowl);
|
||||||
|
|
||||||
return G_SOURCE_CONTINUE;
|
return G_SOURCE_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -515,8 +704,40 @@ gtk_fishbowl_set_animating (GtkFishbowl *fishbowl,
|
|||||||
priv->last_frame_time = 0;
|
priv->last_frame_time = 0;
|
||||||
gtk_widget_remove_tick_callback (GTK_WIDGET (fishbowl), priv->tick_id);
|
gtk_widget_remove_tick_callback (GTK_WIDGET (fishbowl), priv->tick_id);
|
||||||
priv->tick_id = 0;
|
priv->tick_id = 0;
|
||||||
|
priv->framerate = 0;
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_FRAMERATE]);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_ANIMATING]);
|
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_ANIMATING]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
gtk_fishbowl_get_framerate (GtkFishbowl *fishbowl)
|
||||||
|
{
|
||||||
|
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||||
|
|
||||||
|
return priv->framerate;
|
||||||
|
}
|
||||||
|
|
||||||
|
gint64
|
||||||
|
gtk_fishbowl_get_update_delay (GtkFishbowl *fishbowl)
|
||||||
|
{
|
||||||
|
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||||
|
|
||||||
|
return priv->update_delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gtk_fishbowl_set_update_delay (GtkFishbowl *fishbowl,
|
||||||
|
gint64 update_delay)
|
||||||
|
{
|
||||||
|
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||||
|
|
||||||
|
if (priv->update_delay == update_delay)
|
||||||
|
return;
|
||||||
|
|
||||||
|
priv->update_delay = update_delay;
|
||||||
|
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_UPDATE_DELAY]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -55,6 +55,13 @@ void gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
|
|||||||
gboolean gtk_fishbowl_get_animating (GtkFishbowl *fishbowl);
|
gboolean gtk_fishbowl_get_animating (GtkFishbowl *fishbowl);
|
||||||
void gtk_fishbowl_set_animating (GtkFishbowl *fishbowl,
|
void gtk_fishbowl_set_animating (GtkFishbowl *fishbowl,
|
||||||
gboolean animating);
|
gboolean animating);
|
||||||
|
gboolean gtk_fishbowl_get_benchmark (GtkFishbowl *fishbowl);
|
||||||
|
void gtk_fishbowl_set_benchmark (GtkFishbowl *fishbowl,
|
||||||
|
gboolean animating);
|
||||||
|
double gtk_fishbowl_get_framerate (GtkFishbowl *fishbowl);
|
||||||
|
gint64 gtk_fishbowl_get_update_delay (GtkFishbowl *fishbowl);
|
||||||
|
void gtk_fishbowl_set_update_delay (GtkFishbowl *fishbowl,
|
||||||
|
gint64 update_delay);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user