[gnome-shell] Use gnome-shell-perf-helper to control windows during perf tests



commit 821583acae732ede6ee18e2128c49703e82fb47f
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Tue Mar 8 18:48:07 2011 -0500

    Use gnome-shell-perf-helper to control windows during perf tests
    
    * Run gnome-shell-perf-helper during performance tests
    * Use MUTTER_WM_CLASS_FILTER to omit all other windows
    * Add new Scripting methods: createTestWindow,
      waitTestWindows, destroyTestWindows
    * Create a single 640x480 test window for testing overview
      animation performance.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=644265

 js/perf/core.js            |    4 ++
 js/ui/scripting.js         |   99 ++++++++++++++++++++++++++++++++++++++++++++
 src/gnome-shell-jhbuild.in |   35 +++++++++++++++
 3 files changed, 138 insertions(+), 0 deletions(-)
---
diff --git a/js/perf/core.js b/js/perf/core.js
index b7e6454..1bbeab7 100644
--- a/js/perf/core.js
+++ b/js/perf/core.js
@@ -38,6 +38,10 @@ function run() {
                               Scripting.scriptEvent('overviewShowDone');
                           });
 
+    Scripting.destroyTestWindows();
+    Scripting.createTestWindow(640, 480, false, false);
+    Scripting.waitTestWindows();
+
     yield Scripting.sleep(1000);
     yield Scripting.waitLeisure();
     for (let i = 0; i < 2; i++) {
diff --git a/js/ui/scripting.js b/js/ui/scripting.js
index b2537f2..2e38d10 100644
--- a/js/ui/scripting.js
+++ b/js/ui/scripting.js
@@ -1,5 +1,6 @@
 /* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
 
+const DBus = imports.dbus;
 const Gio = imports.gi.Gio;
 const Mainloop = imports.mainloop;
 
@@ -68,6 +69,104 @@ function waitLeisure() {
     };
 }
 
+const PerfHelperIface = {
+    name: 'org.gnome.Shell.PerfHelper',
+    methods: [{ name: 'CreateWindow', inSignature: 'iibb', outSignature: '' },
+              { name: 'WaitWindows', inSignature: '', outSignature: '' },
+              { name: 'DestroyWindows', inSignature: '', outSignature: ''}]
+};
+
+const PerfHelper = function () {
+    this._init();
+};
+
+PerfHelper.prototype = {
+     _init: function() {
+         DBus.session.proxifyObject(this, 'org.gnome.Shell.PerfHelper', '/org/gnome/Shell/PerfHelper');
+     }
+};
+
+DBus.proxifyPrototype(PerfHelper.prototype, PerfHelperIface);
+
+let _perfHelper = null;
+function _getPerfHelper() {
+    if (_perfHelper == null)
+        _perfHelper = new PerfHelper();
+
+    return _perfHelper;
+}
+
+/**
+ * createTestWindow:
+ * @width: width of window, in pixels
+ * @height: height of window, in pixels
+ * @alpha: whether the window should be alpha transparent
+ * @maximized: whethe the window should be created maximized
+ *
+ * Creates a window using gnome-shell-perf-helper for testing purposes.
+ * While this function can be used with yield in an automation
+ * script to pause until the D-Bus call to the helper process returns,
+ * because of the normal X asynchronous mapping process, to actually wait
+ * until the window has been mapped and exposed, use waitTestWindows().
+ */
+function createTestWindow(width, height, alpha, maximized) {
+    let cb;
+    let perfHelper = _getPerfHelper();
+
+    perfHelper.CreateWindowRemote(width, height, alpha, maximized,
+                                  function(result, excp) {
+                                      if (cb)
+                                          cb();
+                                  });
+
+    return function(callback) {
+        cb = callback;
+    };
+}
+
+/**
+ * waitTestWindows:
+ *
+ * Used within an automation script to pause until all windows previously
+ * created with createTestWindow have been mapped and exposed.
+ */
+function waitTestWindows() {
+    let cb;
+    let perfHelper = _getPerfHelper();
+
+    perfHelper.WaitWindowsRemote(function(result, excp) {
+                                     if (cb)
+                                         cb();
+                                 });
+
+    return function(callback) {
+        cb = callback;
+    };
+}
+
+/**
+ * destroyTestWindows:
+ *
+ * Destroys all windows previously created with createTestWindow().
+ * While this function can be used with yield in an automation
+ * script to pause until the D-Bus call to the helper process returns,
+ * this doesn't guarantee that Mutter has actually finished the destroy
+ * process because of normal X asynchronicity.
+ */
+function destroyTestWindows() {
+    let cb;
+    let perfHelper = _getPerfHelper();
+
+    perfHelper.DestroyWindowsRemote(function(result, excp) {
+                                        if (cb)
+                                            cb();
+                                    });
+
+    return function(callback) {
+        cb = callback;
+    };
+}
+
 /**
  * defineScriptEvent
  * @name: The event will be called script.<name>
diff --git a/src/gnome-shell-jhbuild.in b/src/gnome-shell-jhbuild.in
index 54dfed8..1cc4ef4 100755
--- a/src/gnome-shell-jhbuild.in
+++ b/src/gnome-shell-jhbuild.in
@@ -169,6 +169,29 @@ def start_dconf_await_service():
 
     wait_for_dbus_name (DCONF_NAME)
 
+PERF_HELPER_NAME = "org.gnome.Shell.PerfHelper"
+PERF_HELPER_IFACE = "org.gnome.Shell.PerfHelper"
+PERF_HELPER_PATH = "/org/gnome/Shell/PerfHelper"
+
+def start_perf_helper():
+    get_bus_iface() # connect to NameOwnerChanged signal
+
+    self_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
+    running_from_source_tree = os.path.exists(os.path.join(self_dir, 'gnome-shell-jhbuild.in'))
+
+    if running_from_source_tree:
+        perf_helper_path = os.path.join(self_dir, "gnome-shell-perf-helper")
+    else:
+        perf_helper_path = "@libexecdir@/gnome-shell-perf-helper"
+
+    subprocess.Popen([perf_helper_path])
+    wait_for_dbus_name (PERF_HELPER_NAME)
+
+def stop_perf_helper():
+    bus = get_bus()
+    proxy = bus.get_object(PERF_HELPER_NAME, PERF_HELPER_PATH)
+    proxy.Exit(dbus_interface=PERF_HELPER_IFACE)
+
 def start_shell(perf_output=None):
     self_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
     if os.path.exists(os.path.join(self_dir, 'gnome-shell-jhbuild.in')):
@@ -212,6 +235,7 @@ def start_shell(perf_output=None):
 
     if options.perf is not None:
         env['SHELL_PERF_MODULE'] = options.perf
+        env['MUTTER_WM_CLASS_FILTER'] = 'Gnome-shell-perf-helper'
 
     if perf_output is not None:
         env['SHELL_PERF_OUTPUT'] = perf_output
@@ -389,6 +413,8 @@ def run_performance_test():
     logs = []
     metric_summaries = {}
 
+    start_perf_helper()
+
     for i in xrange(0, iters):
         # We create an empty temporary file that the shell will overwrite
         # with the contents.
@@ -399,17 +425,24 @@ def run_performance_test():
         normal_exit = False
         try:
             normal_exit = run_shell(perf_output=output_file)
+        except:
+            stop_perf_helper()
+            raise
         finally:
             if not normal_exit:
                 os.remove(output_file)
 
         if not normal_exit:
+            stop_perf_helper()
             return False
 
         try:
             f = open(output_file)
             output = json.load(f)
             f.close()
+        except:
+            stop_perf_helper()
+            raise
         finally:
             os.remove(output_file)
 
@@ -436,6 +469,8 @@ def run_performance_test():
 
         logs.append(output['log'])
 
+    stop_perf_helper()
+
     if options.perf_output or options.perf_upload:
         # Write a complete report, formatted as JSON. The Javascript/C code that
         # generates the individual reports we are summarizing here is very careful



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