[metacity] theme-viewer: add back benchmark



commit 862301ee3c338daa7110a1123db3a4b06c4a1ef5
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Tue Jun 7 02:23:08 2016 +0300

    theme-viewer: add back benchmark

 data/ui/theme-viewer-window.ui     |  156 +++++++++++++++++++++---
 theme-viewer/theme-viewer-window.c |  237 +++++++++++++++++++++++++++++++++++-
 2 files changed, 372 insertions(+), 21 deletions(-)
---
diff --git a/data/ui/theme-viewer-window.ui b/data/ui/theme-viewer-window.ui
index 0c510b1..133892d 100644
--- a/data/ui/theme-viewer-window.ui
+++ b/data/ui/theme-viewer-window.ui
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.19.0 -->
+<!-- Generated with glade 3.20.0 -->
 <interface domain="metacity">
-  <requires lib="gtk+" version="3.18"/>
+  <requires lib="gtk+" version="3.20"/>
   <template class="ThemeViewerWindow" parent="GtkWindow">
     <property name="can_focus">False</property>
     <property name="default_width">1024</property>
@@ -305,9 +305,6 @@
                         <property name="position">4</property>
                       </packing>
                     </child>
-                    <child>
-                      <placeholder/>
-                    </child>
                   </object>
                 </child>
               </object>
@@ -358,28 +355,157 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkEventBox" id="theme_box">
+                  <object class="GtkNotebook" id="notebook">
                     <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <signal name="button-press-event" handler="theme_box_button_press_event_cb" 
swapped="no"/>
-                    <signal name="button-release-event" handler="theme_box_button_release_event_cb" 
swapped="no"/>
-                    <signal name="draw" handler="theme_box_draw_cb" swapped="no"/>
-                    <signal name="motion-notify-event" handler="theme_box_motion_notify_event_cb" 
swapped="no"/>
+                    <property name="can_focus">True</property>
+                    <signal name="switch-page" handler="notebook_switch_page_cb" swapped="no"/>
                     <child>
-                      <placeholder/>
+                      <object class="GtkEventBox" id="theme_box">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <signal name="button-press-event" handler="theme_box_button_press_event_cb" 
swapped="no"/>
+                        <signal name="button-release-event" handler="theme_box_button_release_event_cb" 
swapped="no"/>
+                        <signal name="draw" handler="theme_box_draw_cb" swapped="no"/>
+                        <signal name="motion-notify-event" handler="theme_box_motion_notify_event_cb" 
swapped="no"/>
+                        <child>
+                          <placeholder/>
+                        </child>
+                      </object>
+                    </child>
+                    <child type="tab">
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Preview</property>
+                      </object>
+                      <packing>
+                        <property name="tab_fill">False</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkBox">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="valign">center</property>
+                        <property name="margin_left">60</property>
+                        <property name="margin_right">60</property>
+                        <property name="orientation">vertical</property>
+                        <property name="spacing">12</property>
+                        <child>
+                          <object class="GtkFrame" id="benchmark_frame">
+                            <property name="can_focus">False</property>
+                            <property name="label_xalign">0</property>
+                            <property name="label_yalign">1</property>
+                            <child>
+                              <object class="GtkAlignment">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <child>
+                                  <object class="GtkBox">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="margin_left">12</property>
+                                    <property name="margin_right">12</property>
+                                    <property name="margin_top">12</property>
+                                    <property name="margin_bottom">12</property>
+                                    <property name="orientation">vertical</property>
+                                    <property name="spacing">12</property>
+                                    <child>
+                                      <object class="GtkLabel" id="load_time">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">False</property>
+                                        <property name="wrap">True</property>
+                                      </object>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="fill">True</property>
+                                        <property name="position">0</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkLabel" id="get_borders_time">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">False</property>
+                                        <property name="wrap">True</property>
+                                      </object>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="fill">True</property>
+                                        <property name="position">1</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkLabel" id="draw_time">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">False</property>
+                                        <property name="wrap">True</property>
+                                      </object>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="fill">True</property>
+                                        <property name="position">2</property>
+                                      </packing>
+                                    </child>
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
+                            <child type="label_item">
+                              <placeholder/>
+                            </child>
+                            <style>
+                              <class name="view"/>
+                            </style>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkButton" id="benchmark_button">
+                            <property name="label" translatable="yes">Run</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="halign">center</property>
+                            <signal name="clicked" handler="benchmark_button_clicked_cb" swapped="no"/>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child type="tab">
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Benchmark</property>
+                      </object>
+                      <packing>
+                        <property name="position">1</property>
+                        <property name="tab_fill">False</property>
+                      </packing>
                     </child>
                   </object>
                   <packing>
-                    <property name="expand">False</property>
+                    <property name="expand">True</property>
                     <property name="fill">True</property>
-                    <property name="position">1</property>
+                    <property name="position">2</property>
                   </packing>
                 </child>
               </object>
               <packing>
                 <property name="expand">True</property>
                 <property name="fill">True</property>
-                <property name="position">0</property>
+                <property name="position">1</property>
               </packing>
             </child>
           </object>
diff --git a/theme-viewer/theme-viewer-window.c b/theme-viewer/theme-viewer-window.c
index e66f5de..5d46f29 100644
--- a/theme-viewer/theme-viewer-window.c
+++ b/theme-viewer/theme-viewer-window.c
@@ -19,9 +19,12 @@
 
 #include <glib/gi18n.h>
 #include <libmetacity/meta-theme.h>
+#include <time.h>
 
 #include "theme-viewer-window.h"
 
+#define BENCHMARK_ITERATIONS 100
+
 #define PADDING 60
 #define MINI_ICON_SIZE 16
 #define ICON_SIZE 96
@@ -38,6 +41,7 @@ struct _ThemeViewerWindow
   GtkWidget        *sidebar;
 
   GtkWidget        *choose_theme;
+  GtkWidget        *notebook;
   GtkWidget        *theme_box;
 
   GtkWidget        *has_focus;
@@ -67,11 +71,193 @@ struct _ThemeViewerWindow
 
   GdkPixbuf        *mini_icon;
   GdkPixbuf        *icon;
+
+  GtkWidget        *benchmark_frame;
+  GtkWidget        *load_time;
+  GtkWidget        *get_borders_time;
+  GtkWidget        *draw_time;
+
+  GtkWidget        *benchmark_button;
 };
 
 G_DEFINE_TYPE (ThemeViewerWindow, theme_viewer_window, GTK_TYPE_WINDOW)
 
 static void
+benchmark_load_time (ThemeViewerWindow *window,
+                     MetaTheme         *theme,
+                     MetaThemeType      type,
+                     const gchar       *name)
+{
+  clock_t start;
+  clock_t end;
+  clock_t elapsed;
+  gdouble seconds;
+  const gchar *type_string;
+  gchar *message;
+
+  start = clock ();
+  meta_theme_load (theme, name, NULL);
+  end = clock ();
+
+  elapsed = end - start;
+  seconds = (gdouble) elapsed / CLOCKS_PER_SEC;
+
+  type_string = type == META_THEME_TYPE_GTK ? "GTK+" : "Metacity";
+  message = g_strdup_printf (_("Loaded <b>%s</b> theme <b>%s</b> in <b>%f</b> seconds."),
+                             type_string, name, seconds);
+
+  gtk_label_set_markup (GTK_LABEL (window->load_time), message);
+  gtk_widget_show (window->load_time);
+  g_free (message);
+}
+
+static void
+benchmark_get_borders (ThemeViewerWindow *window,
+                       MetaTheme         *theme,
+                       MetaFrameBorders  *borders)
+{
+  clock_t start;
+  clock_t end;
+  clock_t elapsed;
+  gdouble seconds;
+  gchar *message;
+
+  start = clock ();
+
+  meta_theme_get_frame_borders (theme, window->theme_variant,
+                                window->frame_type, window->frame_flags,
+                                borders);
+
+  end = clock ();
+
+  elapsed = end - start;
+  seconds = (gdouble) elapsed / CLOCKS_PER_SEC;
+
+  message = g_strdup_printf (_("Got MetaFrameBorders in <b>%f</b> seconds (CSS loading, PangoFontDescription 
creation and title height calculation)."),
+                             seconds);
+
+  gtk_label_set_markup (GTK_LABEL (window->get_borders_time), message);
+  gtk_widget_show (window->get_borders_time);
+  g_free (message);
+}
+
+static void
+benchmark_draw_time (ThemeViewerWindow *window,
+                     MetaTheme         *theme,
+                     MetaFrameBorders  *borders)
+{
+  GTimer *timer;
+  clock_t start;
+  clock_t end;
+  clock_t elapsed;
+  gdouble seconds;
+  gdouble wall_seconds;
+  gchar *message;
+
+  timer = g_timer_new ();
+  start = clock ();
+
+  {
+    GdkWindow *gdk_window;
+    gint client_width;
+    gint client_height;
+    gint inc;
+    gint i;
+
+    gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
+    client_width = 200;
+    client_height = 120;
+    inc = 1000 / BENCHMARK_ITERATIONS;
+    i = 0;
+
+    while (i < BENCHMARK_ITERATIONS)
+      {
+        gint width;
+        gint height;
+        cairo_surface_t *surface;
+        cairo_t *cr;
+
+        width = client_width + borders->total.left + borders->total.right;
+        height = client_height + borders->total.top + borders->total.bottom;
+        surface = gdk_window_create_similar_surface (gdk_window,
+                                                     CAIRO_CONTENT_COLOR,
+                                                     width, height);
+
+        cr = cairo_create (surface);
+
+        meta_theme_draw_frame (theme, window->theme_variant, cr,
+                               window->frame_type, window->frame_flags,
+                               width, height, window->title_layout,
+                               &window->button_layout, window->button_states,
+                               window->mini_icon, window->icon);
+
+        cairo_destroy (cr);
+        cairo_surface_destroy (surface);
+
+        client_width += inc;
+        client_height += inc;
+        ++i;
+      }
+  }
+
+  end = clock ();
+  g_timer_stop (timer);
+
+  g_object_unref (theme);
+
+  elapsed = end - start;
+  seconds = (gdouble) elapsed / CLOCKS_PER_SEC;
+  wall_seconds = g_timer_elapsed (timer, NULL);
+
+  message = g_strdup_printf (_("Drew <b>%d</b> frames in <b>%f</b> client-side seconds (<b>%f</b> 
milliseconds per frame) and <b>%f</b> seconds wall clock time including X server resources (<b>%f</b> 
milliseconds per frame)."),
+                             BENCHMARK_ITERATIONS,
+                             seconds, (seconds / BENCHMARK_ITERATIONS) * 1000,
+                             wall_seconds, (wall_seconds / BENCHMARK_ITERATIONS) * 1000);
+
+  g_timer_destroy (timer);
+
+  gtk_label_set_markup (GTK_LABEL (window->draw_time), message);
+  gtk_widget_show (window->draw_time);
+  g_free (message);
+}
+
+static void
+run_benchmark (ThemeViewerWindow *window)
+{
+  MetaThemeType theme_type;
+  const gchar *theme_name;
+  MetaTheme *theme;
+  MetaFrameBorders borders;
+
+  gtk_widget_set_sensitive (window->benchmark_button, FALSE);
+  gtk_widget_show (window->benchmark_frame);
+
+  theme_type = gtk_combo_box_get_active (GTK_COMBO_BOX (window->type_combo_box));
+  theme_name = gtk_combo_box_get_active_id (GTK_COMBO_BOX (window->theme_combo_box));
+
+  theme = meta_theme_new (theme_type);
+
+  /* 1. benchmark load time */
+  benchmark_load_time (window, theme, theme_type, theme_name);
+
+  /* 2. benchmark get borders */
+  benchmark_get_borders (window, theme, &borders);
+
+  /* 3. benchmark draw time */
+  benchmark_draw_time (window, theme, &borders);
+
+  gtk_button_set_label (GTK_BUTTON (window->benchmark_button), _("Run again"));
+  gtk_widget_set_sensitive (window->benchmark_button, TRUE);
+}
+
+static void
+reset_benchmark_page (ThemeViewerWindow *window)
+{
+  gtk_widget_hide (window->benchmark_frame);
+  gtk_button_set_label (GTK_BUTTON (window->benchmark_button), _("Run"));
+}
+
+static void
 update_frame_flags_sensitivity (ThemeViewerWindow *window)
 {
   gtk_widget_set_sensitive (window->has_focus, TRUE);
@@ -344,7 +530,7 @@ static void
 clear_theme (ThemeViewerWindow *window)
 {
   gtk_widget_show (window->choose_theme);
-  gtk_widget_hide (window->theme_box);
+  gtk_widget_hide (window->notebook);
 
   gtk_widget_set_sensitive (window->sidebar, FALSE);
 
@@ -479,6 +665,7 @@ type_combo_box_changed_cb (GtkComboBox       *combo_box,
   gtk_widget_set_sensitive (window->reload_button, FALSE);
 
   clear_theme (window);
+  reset_benchmark_page (window);
 
   type = gtk_combo_box_get_active (combo_box);
   themes = NULL;
@@ -517,6 +704,7 @@ theme_combo_box_changed_cb (GtkComboBox       *combo_box,
 {
   const gchar *theme;
   MetaThemeType type;
+  gboolean sensitive;
 
   theme = gtk_combo_box_get_active_id (combo_box);
 
@@ -529,6 +717,8 @@ theme_combo_box_changed_cb (GtkComboBox       *combo_box,
       return;
     }
 
+  reset_benchmark_page (window);
+
   type = gtk_combo_box_get_active (GTK_COMBO_BOX (window->type_combo_box));
 
   window->theme = meta_theme_new (type);
@@ -540,14 +730,14 @@ theme_combo_box_changed_cb (GtkComboBox       *combo_box,
   update_button_layout (window);
 
   gtk_widget_hide (window->choose_theme);
+  gtk_widget_show (window->notebook);
 
-  if (gtk_widget_is_visible (window->theme_box))
-    gtk_widget_queue_draw (window->theme_box);
-  else
-    gtk_widget_show (window->theme_box);
+  sensitive = gtk_notebook_get_current_page (GTK_NOTEBOOK (window->notebook)) == 0;
 
   gtk_widget_set_sensitive (window->sidebar, TRUE);
-  gtk_widget_set_sensitive (window->reload_button, TRUE);
+  gtk_widget_set_sensitive (window->reload_button, sensitive);
+
+  gtk_widget_queue_draw (window->theme_box);
 }
 
 static void
@@ -698,6 +888,26 @@ composited_state_set_cb (GtkSwitch         *widget,
 }
 
 static void
+notebook_switch_page_cb (GtkNotebook       *notebook,
+                         GtkWidget         *page,
+                         guint              page_num,
+                         ThemeViewerWindow *window)
+{
+  gboolean sensitive;
+
+  sensitive = page_num == 0 && window->theme != NULL;
+
+  gtk_widget_set_sensitive (window->reload_button, sensitive);
+}
+
+static void
+benchmark_button_clicked_cb (GtkButton         *button,
+                             ThemeViewerWindow *window)
+{
+  run_benchmark (window);
+}
+
+static void
 theme_viewer_window_class_init (ThemeViewerWindowClass *window_class)
 {
   GObjectClass *object_class;
@@ -726,6 +936,7 @@ theme_viewer_window_class_init (ThemeViewerWindowClass *window_class)
   gtk_widget_class_bind_template_child (widget_class, ThemeViewerWindow, sidebar);
 
   gtk_widget_class_bind_template_child (widget_class, ThemeViewerWindow, choose_theme);
+  gtk_widget_class_bind_template_child (widget_class, ThemeViewerWindow, notebook);
 
   gtk_widget_class_bind_template_child (widget_class, ThemeViewerWindow, theme_box);
   gtk_widget_class_bind_template_callback (widget_class, theme_box_draw_cb);
@@ -746,6 +957,16 @@ theme_viewer_window_class_init (ThemeViewerWindowClass *window_class)
   gtk_widget_class_bind_template_callback (widget_class, dark_theme_state_set_cb);
   gtk_widget_class_bind_template_callback (widget_class, frame_type_combo_box_changed_cb);
   gtk_widget_class_bind_template_callback (widget_class, composited_state_set_cb);
+
+  gtk_widget_class_bind_template_callback (widget_class, notebook_switch_page_cb);
+
+  gtk_widget_class_bind_template_child (widget_class, ThemeViewerWindow, benchmark_frame);
+  gtk_widget_class_bind_template_child (widget_class, ThemeViewerWindow, load_time);
+  gtk_widget_class_bind_template_child (widget_class, ThemeViewerWindow, get_borders_time);
+  gtk_widget_class_bind_template_child (widget_class, ThemeViewerWindow, draw_time);
+
+  gtk_widget_class_bind_template_child (widget_class, ThemeViewerWindow, benchmark_button);
+  gtk_widget_class_bind_template_callback (widget_class, benchmark_button_clicked_cb);
 }
 
 static void
@@ -759,6 +980,10 @@ theme_viewer_window_init (ThemeViewerWindow *window)
   gtk_widget_add_events (window->theme_box, GDK_POINTER_MOTION_MASK);
 
   type_combo_box_changed_cb (GTK_COMBO_BOX (window->type_combo_box), window);
+
+  gtk_label_set_xalign (GTK_LABEL (window->load_time), 0.0);
+  gtk_label_set_xalign (GTK_LABEL (window->get_borders_time), 0.0);
+  gtk_label_set_xalign (GTK_LABEL (window->draw_time), 0.0);
 }
 
 GtkWidget *


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