Skip to content

Instantly share code, notes, and snippets.

@itzexor

itzexor/README Secret

Last active January 11, 2019 08:31
Show Gist options
  • Save itzexor/8d7058a5ed909c7ff71aca23276bcceb to your computer and use it in GitHub Desktop.
Save itzexor/8d7058a5ed909c7ff71aca23276bcceb to your computer and use it in GitHub Desktop.
crude a/b frametime testing
perf.sh: a shell script that runs xdotool to navigate the menu via keyboard then restarts cinnamon
cinnamon.patch: -changes PopupBaseMenuItem to have a toggle to use custom allocation logic or not
-makes menu applet disable custom allocation
-makes cinnamon run a shell script if CINNAMON_RUN_PERF=1
muffin.patch: crude frame time dumping via clutter master clock if CLUTTER_DUMP_FRAME_TIME=1
graph shows run with and without custom logic enabled
repro steps:
1. apply patches
2. perf.sh in ~/ and executable
3. cpu locked at 2ghz or whatever
$ sudo cpupower frequency-set -d 2000Mhz -u 2000Mhz
4. via ssh with a different log for each run:
$ DISPLAY=:0 CLUTTER_DUMP_FRAME_TIME=1 CINNAMON_RUN_PERF=1 cinnamon --replace |& tee ft1.log
5. trim log to when the script starts (there is a warning about spawn on recent cinnamon editions that marks it, or you can add a log line there in main.js)
graph: https://docs.google.com/spreadsheets/d/1VPTHhimlnGNpQQXOOkNpp9WkB1fyyc2DXizw3G6KS_Q/edit?usp=sharing
both runs used the modified codes with only the following change:
to disable the st.boxlayout mode this line in popupmenu.js:
this._customLayout = params.customLayout;
was changed to:
this._customLayout = true; //params.customLayout;
diff --git a/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js b/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js
index 830fc621..ec50b48f 100644
--- a/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js
+++ b/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js
@@ -101,7 +101,7 @@ class VisibleChildIterator {
class ApplicationContextMenuItem extends PopupMenu.PopupBaseMenuItem {
constructor(appButton, label, action, iconName) {
- super({focusOnHover: false});
+ super({focusOnHover: false, customLayout: false});
this._appButton = appButton;
this._action = action;
@@ -170,7 +170,7 @@ class ApplicationContextMenuItem extends PopupMenu.PopupBaseMenuItem {
class GenericApplicationButton extends PopupMenu.PopupBaseMenuItem {
constructor(appsMenuButton, app, withMenu) {
- super({hover: false});
+ super({hover: false, customLayout: false});
this.app = app;
this.appsMenuButton = appsMenuButton;
@@ -286,7 +286,7 @@ class GenericApplicationButton extends PopupMenu.PopupBaseMenuItem {
class TransientButton extends PopupMenu.PopupBaseMenuItem {
constructor(appsMenuButton, pathOrCommand) {
- super({hover: false});
+ super({hover: false, customLayout: false});
let displayPath = pathOrCommand;
if (pathOrCommand.charAt(0) == '~') {
pathOrCommand = pathOrCommand.slice(1);
@@ -430,7 +430,7 @@ class ApplicationButton extends GenericApplicationButton {
class SearchProviderResultButton extends PopupMenu.PopupBaseMenuItem {
constructor(appsMenuButton, provider, result) {
- super({hover: false});
+ super({hover: false, customLayout: false});
this.provider = provider;
this.result = result;
@@ -498,7 +498,7 @@ class SearchProviderResultButton extends PopupMenu.PopupBaseMenuItem {
class PlaceButton extends PopupMenu.PopupBaseMenuItem {
constructor(appsMenuButton, place, button_name, showIcon) {
- super({hover: false});
+ super({hover: false, customLayout: false});
this.appsMenuButton = appsMenuButton;
this.place = place;
this.button_name = button_name;
@@ -536,7 +536,7 @@ class PlaceButton extends PopupMenu.PopupBaseMenuItem {
class RecentContextMenuItem extends PopupMenu.PopupBaseMenuItem {
constructor(recentButton, label, is_default, callback) {
- super({focusOnHover: false});
+ super({focusOnHover: false, customLayout: false});
this._recentButton = recentButton;
this._callback = callback;
@@ -555,7 +555,7 @@ class RecentContextMenuItem extends PopupMenu.PopupBaseMenuItem {
class RecentButton extends PopupMenu.PopupBaseMenuItem {
constructor(appsMenuButton, file, showIcon) {
- super({hover: false});
+ super({hover: false, customLayout: false});
this.mimeType = file.mimeType;
this.uri = file.uri;
this.uriDecoded = file.uriDecoded;
@@ -723,7 +723,7 @@ class RecentButton extends PopupMenu.PopupBaseMenuItem {
class NoRecentDocsButton extends PopupMenu.PopupBaseMenuItem {
constructor(label, icon, reactive, callback) {
- super({hover: false});
+ super({hover: false, customLayout: false});
this.actor.set_style_class_name('menu-application-button');
this.actor._delegate = this;
this.button_name = "";
@@ -753,7 +753,7 @@ class NoRecentDocsButton extends PopupMenu.PopupBaseMenuItem {
class RecentClearButton extends PopupMenu.PopupBaseMenuItem {
constructor(appsMenuButton) {
- super({hover: false});
+ super({hover: false, customLayout: false});
this.appsMenuButton = appsMenuButton;
this.actor.set_style_class_name('menu-application-button');
this.button_name = _("Clear list");
@@ -779,7 +779,7 @@ class RecentClearButton extends PopupMenu.PopupBaseMenuItem {
class CategoryButton extends PopupMenu.PopupBaseMenuItem {
constructor(category, showIcon) {
- super({hover: false});
+ super({hover: false, customLayout: false});
this.actor.set_style_class_name('menu-category-button');
var label;
@@ -816,7 +816,7 @@ class CategoryButton extends PopupMenu.PopupBaseMenuItem {
class PlaceCategoryButton extends PopupMenu.PopupBaseMenuItem {
constructor(category, showIcon) {
- super({hover: false});
+ super({hover: false, customLayout: false});
this.actor.set_style_class_name('menu-category-button');
this.actor._delegate = this;
this.label = new St.Label({ text: _("Places"), style_class: 'menu-category-button-label' });
@@ -834,7 +834,7 @@ class PlaceCategoryButton extends PopupMenu.PopupBaseMenuItem {
class RecentCategoryButton extends PopupMenu.PopupBaseMenuItem {
constructor(category, showIcon) {
- super({hover: false});
+ super({hover: false, customLayout: false});
this.actor.set_style_class_name('menu-category-button');
this.actor._delegate = this;
this.label = new St.Label({ text: _("Recent Files"), style_class: 'menu-category-button-label' });
@@ -891,7 +891,7 @@ class FavoritesButton extends GenericApplicationButton {
class SystemButton extends PopupMenu.PopupBaseMenuItem {
constructor(icon, nbFavorites, name, desc) {
- super({hover: false});
+ super({hover: false, customLayout: false});
this.name = name;
this.desc = desc;
diff --git a/js/ui/main.js b/js/ui/main.js
index 033209be..a0ff7a62 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -515,6 +515,8 @@ function start() {
global.connect('shutdown', do_shutdown_sequence);
global.log('Cinnamon took %d ms to start'.format(new Date().getTime() - cinnamonStartTime));
+ if (GLib.getenv('CINNAMON_RUN_PERF'))
+ Mainloop.timeout_add(5000, () => {Util.spawn([GLib.get_home_dir() + '/perf.sh']); return false;});
});
}
diff --git a/js/ui/popupMenu.js b/js/ui/popupMenu.js
index 3bcee59f..92a6de94 100644
--- a/js/ui/popupMenu.js
+++ b/js/ui/popupMenu.js
@@ -104,18 +104,26 @@ var PopupBaseMenuItem = class PopupBaseMenuItem {
hover: true,
sensitive: true,
style_class: null,
- focusOnHover: true
+ focusOnHover: true,
+ customLayout: true
});
+ this._customLayout = params.customLayout;
this._signals = new SignalManager.SignalManager(null);
- this.actor = new Cinnamon.GenericContainer({ style_class: 'popup-menu-item',
- reactive: params.reactive,
- track_hover: params.reactive,
- can_focus: params.reactive,
- accessible_role: Atk.Role.MENU_ITEM });
- this._signals.connect(this.actor, 'get-preferred-width', Lang.bind(this, this._getPreferredWidth));
- this._signals.connect(this.actor, 'get-preferred-height', Lang.bind(this, this._getPreferredHeight));
- this._signals.connect(this.actor, 'allocate', Lang.bind(this, this._allocate));
- this._signals.connect(this.actor, 'style-changed', Lang.bind(this, this._onStyleChanged));
+ let actorParams = { style_class: 'popup-menu-item',
+ reactive: params.reactive,
+ track_hover: params.reactive,
+ can_focus: params.reactive,
+ accessible_role: Atk.Role.MENU_ITEM };
+
+ this.actor = this._customLayout ? new Cinnamon.GenericContainer(actorParams)
+ : new St.BoxLayout(actorParams);
+
+ if (this._customLayout) {
+ this._signals.connect(this.actor, 'get-preferred-width', Lang.bind(this, this._getPreferredWidth));
+ this._signals.connect(this.actor, 'get-preferred-height', Lang.bind(this, this._getPreferredHeight));
+ this._signals.connect(this.actor, 'allocate', Lang.bind(this, this._allocate));
+ this._signals.connect(this.actor, 'style-changed', Lang.bind(this, this._onStyleChanged));
+ }
this.actor._delegate = this;
this._children = [];
diff --git a/clutter/clutter/clutter-master-clock-default.c b/clutter/clutter/clutter-master-clock-default.c
index 6488ee4..389eccf 100644
--- a/clutter/clutter/clutter-master-clock-default.c
+++ b/clutter/clutter/clutter-master-clock-default.c
@@ -29,6 +29,7 @@
* of #ClutterMasterClock.
*/
+#include <inttypes.h>
#ifdef HAVE_CONFIG_H
#include "clutter-build-config.h"
#endif
@@ -90,7 +91,7 @@ struct _ClutterMasterClockDefault
gint64 frame_budget;
gint64 remaining_budget;
#endif
-
+ gboolean dump_ft;
/* an idle source, used by the Master Clock to queue
* a redraw on the stage and drive the animations
*/
@@ -545,6 +546,7 @@ clutter_clock_dispatch (GSource *source,
ClutterMasterClockDefault *master_clock = clock_source->master_clock;
gboolean stages_updated = FALSE;
GSList *stages;
+ gint64 start_time;
CLUTTER_NOTE (SCHEDULER, "Master clock [tick]");
@@ -552,7 +554,6 @@ clutter_clock_dispatch (GSource *source,
/* Get the time to use for this frame */
master_clock->cur_tick = master_clock_next_frame_time (master_clock);
-
#ifdef CLUTTER_ENABLE_DEBUG
master_clock->remaining_budget = master_clock->frame_budget;
#endif
@@ -565,6 +566,9 @@ clutter_clock_dispatch (GSource *source,
master_clock->idle = FALSE;
+ if (master_clock->dump_ft)
+ start_time = g_get_monotonic_time();
+
/* Each frame is split into three separate phases: */
/* 1. process all the events; each stage goes through its events queue
@@ -579,6 +583,8 @@ clutter_clock_dispatch (GSource *source,
/* 3. relayout and redraw the stages */
stages_updated = master_clock_update_stages (master_clock, stages);
+ if (master_clock->dump_ft)
+ g_message ("ft: %"PRId64, g_get_monotonic_time() - start_time);
/* The master clock goes idle if no stages were updated and falls back
* to polling for timeline progressions... */
if (!stages_updated)
@@ -634,6 +640,7 @@ clutter_master_clock_default_init (ClutterMasterClockDefault *self)
#ifdef CLUTTER_ENABLE_DEBUG
self->frame_budget = G_USEC_PER_SEC / 60;
#endif
+ self->dump_ft = g_getenv("CLUTTER_DUMP_FRAME_TIME") != NULL;
g_source_set_priority (source, CLUTTER_PRIORITY_REDRAW);
g_source_set_can_recurse (source, FALSE);
#!/bin/bash
xdotool key SUPER sleep 0.5 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key Down sleep 0.25 key SUPER sleep 0.5 keydown Control_L keydown Alt_L keydown Escape keyup Control_L keyup Alt_L keyup Escape
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment