[perf] replace frame count with accurately computed frame rate

Compute a frame rate for the period between:

 - User sees first frame of overview animation
 - User sees fully zoomed-out overview

And replace the current Frames count metrics with this. The
previous frame count metrics were actually over the period from
the start of the animation until the window labels finished
animating in; here we are careful to look at a more restricted
period.

https://bugzilla.gnome.org/show_bug.cgi?id=619521
This commit is contained in:
Owen W. Taylor 2010-05-24 10:27:13 -04:00
parent 0eeb62794d
commit 15dd1164b7

View File

@ -12,15 +12,15 @@ let METRICS = {
overviewLatencyFirst: overviewLatencyFirst:
{ description: "Time to first frame after triggering overview, first time", { description: "Time to first frame after triggering overview, first time",
units: "us" }, units: "us" },
overviewFramesFirst: overviewFpsFirst:
{ description: "Frames displayed when going to overview, first time", { description: "Frame rate when going to the overview, first time",
units: "frames" }, units: "frames / s" },
overviewLatencySubsequent: overviewLatencySubsequent:
{ description: "Time to first frame after triggering overview, second time", { description: "Time to first frame after triggering overview, second time",
units: "us"}, units: "us"},
overviewFramesSubsequent: overviewFpsSubsequent:
{ description: "Frames displayed when going to overview, second time", { description: "Frames rate when going to the overview, second time",
units: "us" }, units: "frames / s" },
usedAfterOverview: usedAfterOverview:
{ description: "Malloc'ed bytes after the overview is shown once", { description: "Malloc'ed bytes after the overview is shown once",
units: "B" }, units: "B" },
@ -34,14 +34,17 @@ function run() {
Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing"); Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing");
Scripting.defineScriptEvent("afterShowHide", "After a show/hide cycle for the overview"); Scripting.defineScriptEvent("afterShowHide", "After a show/hide cycle for the overview");
Main.overview.connect('shown', function() {
Scripting.scriptEvent('overviewShowDone');
});
yield Scripting.sleep(1000); yield Scripting.sleep(1000);
yield Scripting.waitLeisure(); yield Scripting.waitLeisure();
for (let i = 0; i < 2; i++) { for (let i = 0; i < 2; i++) {
Scripting.scriptEvent('overviewShowStart'); Scripting.scriptEvent('overviewShowStart');
Main.overview.show(); Main.overview.show();
yield Scripting.waitLeisure();
Scripting.scriptEvent('overviewShowDone');
yield Scripting.waitLeisure();
Main.overview.hide(); Main.overview.hide();
yield Scripting.waitLeisure(); yield Scripting.waitLeisure();
@ -53,31 +56,27 @@ function run() {
} }
let showingOverview = false; let showingOverview = false;
let finishedShowingOverview = false;
let overviewShowStart; let overviewShowStart;
let overviewFrames; let overviewFrames;
let overviewLatency; let overviewLatency;
let mallocUsedSize = 0; let mallocUsedSize = 0;
let overviewShowCount = 0; let overviewShowCount = 0;
let firstOverviewUsedSize; let firstOverviewUsedSize;
let haveSwapComplete = false;
function script_overviewShowStart(time) { function script_overviewShowStart(time) {
showingOverview = true; showingOverview = true;
finishedShowingOverview = false;
overviewShowStart = time; overviewShowStart = time;
overviewFrames = 0; overviewFrames = 0;
} }
function script_overviewShowDone(time) { function script_overviewShowDone(time) {
showingOverview = false; // 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
overviewShowCount++; // ourselves as done.
finishedShowingOverview = true;
if (overviewShowCount == 1) {
METRICS.overviewLatencyFirst.value = overviewLatency;
METRICS.overviewFramesFirst.value = overviewFrames;
} else {
METRICS.overviewLatencySubsequent.value = overviewLatency;
METRICS.overviewFramesSubsequent.value = overviewFrames;
}
} }
function script_afterShowHide(time) { function script_afterShowHide(time) {
@ -92,11 +91,50 @@ function malloc_usedSize(time, bytes) {
mallocUsedSize = bytes; mallocUsedSize = bytes;
} }
function clutter_stagePaintDone(time) { function _frameDone(time) {
if (showingOverview) { if (showingOverview) {
if (overviewFrames == 0) if (overviewFrames == 0)
overviewLatency = time - overviewShowStart; overviewLatency = time - overviewShowStart;
overviewFrames++; overviewFrames++;
} }
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);
} }