2010-05-09 13:42:35 -04:00
|
|
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
|
|
|
|
|
|
const Main = imports.ui.main;
|
|
|
|
const Scripting = imports.ui.scripting;
|
|
|
|
|
|
|
|
// This performance script measure the most important (core) performance
|
|
|
|
// metrics for the shell. By looking at the output metrics of this script
|
|
|
|
// someone should be able to get an idea of how well the shell is performing
|
|
|
|
// on a particular system.
|
|
|
|
|
|
|
|
let METRICS = {
|
2010-05-17 14:04:09 -04:00
|
|
|
overviewLatencyFirst:
|
|
|
|
{ description: "Time to first frame after triggering overview, first time",
|
|
|
|
units: "us" },
|
2010-05-24 10:27:13 -04:00
|
|
|
overviewFpsFirst:
|
|
|
|
{ description: "Frame rate when going to the overview, first time",
|
|
|
|
units: "frames / s" },
|
2010-05-17 14:04:09 -04:00
|
|
|
overviewLatencySubsequent:
|
|
|
|
{ description: "Time to first frame after triggering overview, second time",
|
|
|
|
units: "us"},
|
2010-05-24 10:27:13 -04:00
|
|
|
overviewFpsSubsequent:
|
|
|
|
{ description: "Frames rate when going to the overview, second time",
|
|
|
|
units: "frames / s" },
|
2010-05-17 14:04:09 -04:00
|
|
|
usedAfterOverview:
|
|
|
|
{ description: "Malloc'ed bytes after the overview is shown once",
|
|
|
|
units: "B" },
|
|
|
|
leakedAfterOverview:
|
|
|
|
{ description: "Additional malloc'ed bytes the second time the overview is shown",
|
|
|
|
units: "B" }
|
2010-05-09 13:42:35 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
function run() {
|
|
|
|
Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview");
|
|
|
|
Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing");
|
2010-05-11 15:53:55 -04:00
|
|
|
Scripting.defineScriptEvent("afterShowHide", "After a show/hide cycle for the overview");
|
2010-05-09 13:42:35 -04:00
|
|
|
|
2010-05-24 10:27:13 -04:00
|
|
|
Main.overview.connect('shown', function() {
|
|
|
|
Scripting.scriptEvent('overviewShowDone');
|
|
|
|
});
|
|
|
|
|
2010-05-09 13:42:35 -04:00
|
|
|
yield Scripting.sleep(1000);
|
|
|
|
yield Scripting.waitLeisure();
|
|
|
|
for (let i = 0; i < 2; i++) {
|
|
|
|
Scripting.scriptEvent('overviewShowStart');
|
|
|
|
Main.overview.show();
|
2010-05-11 15:53:55 -04:00
|
|
|
|
2010-05-24 10:27:13 -04:00
|
|
|
yield Scripting.waitLeisure();
|
2010-05-09 13:42:35 -04:00
|
|
|
Main.overview.hide();
|
|
|
|
yield Scripting.waitLeisure();
|
2010-05-11 15:53:55 -04:00
|
|
|
|
|
|
|
global.gc();
|
|
|
|
yield Scripting.sleep(1000);
|
|
|
|
Scripting.collectStatistics();
|
|
|
|
Scripting.scriptEvent('afterShowHide');
|
2010-05-09 13:42:35 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let showingOverview = false;
|
2010-05-24 10:27:13 -04:00
|
|
|
let finishedShowingOverview = false;
|
2010-05-09 13:42:35 -04:00
|
|
|
let overviewShowStart;
|
|
|
|
let overviewFrames;
|
|
|
|
let overviewLatency;
|
2010-05-11 15:53:55 -04:00
|
|
|
let mallocUsedSize = 0;
|
|
|
|
let overviewShowCount = 0;
|
|
|
|
let firstOverviewUsedSize;
|
2010-05-24 10:27:13 -04:00
|
|
|
let haveSwapComplete = false;
|
2010-05-09 13:42:35 -04:00
|
|
|
|
|
|
|
function script_overviewShowStart(time) {
|
|
|
|
showingOverview = true;
|
2010-05-24 10:27:13 -04:00
|
|
|
finishedShowingOverview = false;
|
2010-05-09 13:42:35 -04:00
|
|
|
overviewShowStart = time;
|
|
|
|
overviewFrames = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
function script_overviewShowDone(time) {
|
2010-05-24 10:27:13 -04:00
|
|
|
// We've set up the state at the end of the zoom out, but we
|
|
|
|
// need to wait for one more frame to paint before we count
|
|
|
|
// ourselves as done.
|
|
|
|
finishedShowingOverview = true;
|
2010-05-09 13:42:35 -04:00
|
|
|
}
|
|
|
|
|
2010-05-11 15:53:55 -04:00
|
|
|
function script_afterShowHide(time) {
|
|
|
|
if (overviewShowCount == 1) {
|
2010-05-17 14:04:09 -04:00
|
|
|
METRICS.usedAfterOverview.value = mallocUsedSize;
|
2010-05-11 15:53:55 -04:00
|
|
|
} else {
|
2010-05-17 14:04:09 -04:00
|
|
|
METRICS.leakedAfterOverview.value = mallocUsedSize - METRICS.usedAfterOverview.value;
|
2010-05-11 15:53:55 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function malloc_usedSize(time, bytes) {
|
|
|
|
mallocUsedSize = bytes;
|
|
|
|
}
|
|
|
|
|
2010-05-24 10:27:13 -04:00
|
|
|
function _frameDone(time) {
|
2010-05-09 13:42:35 -04:00
|
|
|
if (showingOverview) {
|
|
|
|
if (overviewFrames == 0)
|
|
|
|
overviewLatency = time - overviewShowStart;
|
|
|
|
|
|
|
|
overviewFrames++;
|
|
|
|
}
|
2010-05-24 10:27:13 -04:00
|
|
|
|
|
|
|
if (finishedShowingOverview) {
|
|
|
|
showingOverview = false;
|
|
|
|
finishedShowingOverview = false;
|
|
|
|
overviewShowCount++;
|
|
|
|
|
|
|
|
let dt = (time - (overviewShowStart + overviewLatency)) / 1000000;
|
|
|
|
|
|
|
|
// If we see a start frame and an end frame, that would
|
|
|
|
// be 1 frame for a FPS computation, hence the '- 1'
|
|
|
|
let fps = (overviewFrames - 1) / dt;
|
|
|
|
|
|
|
|
if (overviewShowCount == 1) {
|
|
|
|
METRICS.overviewLatencyFirst.value = overviewLatency;
|
|
|
|
METRICS.overviewFpsFirst.value = fps;
|
|
|
|
} else {
|
|
|
|
METRICS.overviewLatencySubsequent.value = overviewLatency;
|
|
|
|
METRICS.overviewFpsSubsequent.value = fps;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function glx_swapComplete(time, swapTime) {
|
|
|
|
haveSwapComplete = true;
|
|
|
|
|
|
|
|
_frameDone(swapTime);
|
|
|
|
}
|
|
|
|
|
|
|
|
function clutter_stagePaintDone(time) {
|
|
|
|
// If we aren't receiving GLXBufferSwapComplete events, then we approximate
|
|
|
|
// the time the user sees a frame with the time we finished doing drawing
|
|
|
|
// commands for the frame. This doesn't take into account the time for
|
|
|
|
// the GPU to finish painting, and the time for waiting for the buffer
|
|
|
|
// swap, but if this are uniform - every frame takes the same time to draw -
|
|
|
|
// then it won't upset our FPS calculation, though the latency value
|
|
|
|
// will be slightly too low.
|
|
|
|
|
|
|
|
if (!haveSwapComplete)
|
|
|
|
_frameDone(time);
|
2010-05-09 13:42:35 -04:00
|
|
|
}
|