[gtk/frame-rate-benchmark] Add a frame benchmark




commit 43a1641dd725ecb8b3bb2016d04828bbb2b838d0
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Mar 29 08:26:17 2021 -0400

    Add a frame benchmark
    
    This can be used to gauge what fps we can hope for
    in the best case, on a given system.

 demos/gtk-demo/demo.gresource.xml |   4 +
 demos/gtk-demo/frames.c           | 165 ++++++++++++++++++++++++++++++++++++++
 demos/gtk-demo/frames.ui          |  24 ++++++
 demos/gtk-demo/meson.build        |   1 +
 4 files changed, 194 insertions(+)
---
diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml
index a0ccb783d9..09709d48d8 100644
--- a/demos/gtk-demo/demo.gresource.xml
+++ b/demos/gtk-demo/demo.gresource.xml
@@ -128,6 +128,9 @@
     <file>gtkfishbowl.c</file>
     <file>gtkfishbowl.h</file>
   </gresource>
+  <gresource prefix="/frames">
+    <file>frames.ui</file>
+  </gresource>
   <gresource prefix="/gears">
     <file>gtkgears.c</file>
     <file>gtkgears.h</file>
@@ -276,6 +279,7 @@
     <file>fishbowl.c</file>
     <file>fixed.c</file>
     <file>flowbox.c</file>
+    <file>frames.c</file>
     <file>font_features.c</file>
     <file>fontplane.c</file>
     <file>fontrendering.c</file>
diff --git a/demos/gtk-demo/frames.c b/demos/gtk-demo/frames.c
new file mode 100644
index 0000000000..68f0a087e1
--- /dev/null
+++ b/demos/gtk-demo/frames.c
@@ -0,0 +1,165 @@
+/* Benchmark/Frames
+ *
+ * This demo is intentionally as simple as possible, to see what
+ * framerate the windowing system can deliver on its own.
+ *
+ * It does nothing but change the drawn color, for every frame.
+ */
+
+#include <gtk/gtk.h>
+
+typedef struct
+{
+  GtkWidget parent_instance;
+
+  GdkRGBA color1;
+  GdkRGBA color2;
+  guint64 time2;
+  float t;
+
+  guint tick_cb;
+} ColorWidget;
+
+typedef struct
+{
+  GtkWidgetClass parent_class;
+} ColorWidgetClass;
+
+G_DEFINE_TYPE (ColorWidget, color_widget, GTK_TYPE_WIDGET)
+
+#define TIME_SPAN (3.0 * G_TIME_SPAN_SECOND)
+
+static gboolean
+change_color (GtkWidget     *widget,
+              GdkFrameClock *frame_clock,
+              gpointer       data)
+{
+  ColorWidget *color = (ColorWidget *)widget;
+  gint64 time;
+
+  time = gdk_frame_clock_get_frame_time (frame_clock);
+
+  if (time >= color->time2)
+    {
+      color->time2 = time + TIME_SPAN;
+
+      color->color1 = color->color2;
+      color->color2.red = g_random_double_range (0, 1);
+      color->color2.green = g_random_double_range (0, 1);
+      color->color2.blue = g_random_double_range (0, 1);
+      color->color2.alpha = 1;
+    }
+
+  color->t = 1 - (color->time2 - time) / TIME_SPAN;
+
+  gtk_widget_queue_draw (widget);
+
+  return G_SOURCE_CONTINUE;
+}
+
+static void
+color_widget_snapshot (GtkWidget   *widget,
+                       GtkSnapshot *snapshot)
+{
+  ColorWidget *color = (ColorWidget *)widget;
+  float w, h;
+  GdkRGBA c;
+
+  w = gtk_widget_get_width (widget);
+  h = gtk_widget_get_height (widget);
+
+  c.red = (1 - color->t) * color->color1.red + color->t * color->color2.red;
+  c.green = (1 - color->t) * color->color1.green + color->t * color->color2.green;
+  c.blue = (1 - color->t) * color->color1.blue + color->t * color->color2.blue;
+  c.alpha = 1;
+
+  gtk_snapshot_append_color (snapshot, &c, &GRAPHENE_RECT_INIT (0, 0, w, h));
+}
+
+static void
+color_widget_init (ColorWidget *color)
+{
+  gtk_widget_add_tick_callback (GTK_WIDGET (color), change_color, NULL, NULL);
+  gtk_widget_set_hexpand (GTK_WIDGET (color), TRUE);
+  gtk_widget_set_vexpand (GTK_WIDGET (color), TRUE);
+}
+
+static void
+color_widget_class_init (ColorWidgetClass *class)
+{
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
+  widget_class->snapshot = color_widget_snapshot;
+}
+
+GtkWidget *
+color_widget_new (void)
+{
+  return g_object_new (color_widget_get_type (), NULL);
+}
+
+static gboolean
+update_fps_label (gpointer data)
+{
+  GtkWidget *label = GTK_WIDGET (data);
+  GdkFrameClock *frame_clock;
+
+  frame_clock = gtk_widget_get_frame_clock (label);
+
+  if (frame_clock)
+    {
+      char *fps;
+
+      fps = g_strdup_printf ("%.2f fps", gdk_frame_clock_get_fps (frame_clock));
+      gtk_label_set_label (GTK_LABEL (label), fps);
+      g_free (fps);
+    }
+  else
+    gtk_label_set_label (GTK_LABEL (label), "");
+
+  return G_SOURCE_CONTINUE;
+}
+
+static void
+remove_id (gpointer data)
+{
+  guint id = GPOINTER_TO_UINT (data);
+
+  g_source_remove (id);
+}
+
+GtkWidget *
+do_frames (GtkWidget *do_widget)
+{
+  static GtkWidget *window = NULL;
+
+  if (!window)
+    {
+      GtkBuilder *builder;
+      GtkWidget *box;
+      GtkWidget *label;
+      guint id;
+
+      builder = gtk_builder_new_from_resource ("/frames/frames.ui");
+      window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
+      g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
+      gtk_window_set_display (GTK_WINDOW (window),
+                              gtk_widget_get_display (do_widget));
+
+      label = GTK_WIDGET (gtk_builder_get_object (builder, "fps"));
+      box = GTK_WIDGET (gtk_builder_get_object (builder, "box"));
+
+      gtk_box_append (GTK_BOX (box), color_widget_new ());
+
+      id = g_timeout_add (500, update_fps_label, label);
+      g_object_set_data_full (G_OBJECT (label), "tick_cb",
+                              GUINT_TO_POINTER (id), remove_id);
+    }
+
+  if (!gtk_widget_get_visible (window))
+    gtk_widget_show (window);
+  else
+    gtk_window_destroy (GTK_WINDOW (window));
+
+  return window;
+}
diff --git a/demos/gtk-demo/frames.ui b/demos/gtk-demo/frames.ui
new file mode 100644
index 0000000000..79a27e4f97
--- /dev/null
+++ b/demos/gtk-demo/frames.ui
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <object class="GtkWindow" id="window">
+    <property name="resizable">1</property>
+    <property name="default-width">600</property>
+    <property name="default-height">400</property>
+    <property name="title">Frames</property>
+    <child type="titlebar">
+      <object class="GtkHeaderBar" id="header">
+        <child type="end">
+          <object class="GtkLabel" id="fps">
+            <attributes>
+              <attribute name="font-features" value="tnum=1"/>
+            </attributes>
+          </object>
+        </child>
+      </object>
+    </child>
+    <child>
+      <object class="GtkBox" id="box">
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/demos/gtk-demo/meson.build b/demos/gtk-demo/meson.build
index f2deff1c37..abfe033df4 100644
--- a/demos/gtk-demo/meson.build
+++ b/demos/gtk-demo/meson.build
@@ -29,6 +29,7 @@ demos = files([
   'fishbowl.c',
   'fixed.c',
   'fontrendering.c',
+  'frames.c',
   'gears.c',
   'gestures.c',
   'glarea.c',


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]