2015-10-05 14:23:30 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2015 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "TimingStateMachine.h"
|
|
|
|
|
|
|
|
#include "SkCanvas.h"
|
|
|
|
#include "SkCommandLineFlags.h"
|
|
|
|
|
|
|
|
DEFINE_int32(gpuFrameLag, 5, "Overestimate of maximum number of frames GPU is allowed to lag.");
|
|
|
|
DEFINE_int32(frames, 5, "Number of frames of each skp to render per sample.");
|
|
|
|
DEFINE_double(loopMs, 5, "Each benchmark will be tuned until it takes loopsMs millseconds.");
|
|
|
|
|
2015-11-03 14:54:24 +00:00
|
|
|
static double now_ms() { return SkTime::GetNSecs() * 1e-6; }
|
|
|
|
|
2015-10-05 14:23:30 +00:00
|
|
|
TimingStateMachine::TimingStateMachine()
|
|
|
|
: fCurrentFrame(0)
|
|
|
|
, fLoops(1)
|
|
|
|
, fLastMeasurement(0.)
|
2015-10-05 20:58:26 +00:00
|
|
|
, fState(kPreWarm_State)
|
|
|
|
, fInnerState(kTuning_InnerState) {
|
2015-10-05 14:23:30 +00:00
|
|
|
}
|
|
|
|
|
2015-10-05 20:58:26 +00:00
|
|
|
TimingStateMachine::ParentEvents TimingStateMachine::nextFrame(bool preWarmBetweenSamples) {
|
|
|
|
ParentEvents parentEvent = kTiming_ParentEvents;
|
2015-10-05 14:23:30 +00:00
|
|
|
switch (fState) {
|
2015-10-05 20:58:26 +00:00
|
|
|
case kPreWarm_State: {
|
|
|
|
if (fCurrentFrame >= FLAGS_gpuFrameLag) {
|
|
|
|
fCurrentFrame = 0;
|
2015-11-03 14:54:24 +00:00
|
|
|
fStartTime = now_ms();
|
2015-10-05 20:58:26 +00:00
|
|
|
fState = kTiming_State;
|
|
|
|
} else {
|
|
|
|
fCurrentFrame++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case kTiming_State: {
|
|
|
|
switch (fInnerState) {
|
|
|
|
case kTuning_InnerState: {
|
|
|
|
if (1 << 30 == fLoops) {
|
|
|
|
// We're about to wrap. Something's wrong with the bench.
|
|
|
|
SkDebugf("InnerLoops wrapped\n");
|
|
|
|
fLoops = 1;
|
|
|
|
} else {
|
2015-11-13 16:42:06 +00:00
|
|
|
double elapsedMs = now_ms() - fStartTime;
|
2015-10-05 20:58:26 +00:00
|
|
|
if (elapsedMs < FLAGS_loopMs) {
|
|
|
|
fLoops *= 2;
|
|
|
|
} else {
|
|
|
|
fInnerState = kTiming_InnerState;
|
|
|
|
}
|
2015-10-06 15:25:15 +00:00
|
|
|
fState = kPreWarm_State;
|
2015-11-13 16:42:06 +00:00
|
|
|
fCurrentFrame = 0;
|
2015-10-05 20:58:26 +00:00
|
|
|
parentEvent = kReset_ParentEvents;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case kTiming_InnerState: {
|
|
|
|
if (fCurrentFrame >= FLAGS_frames) {
|
2015-11-13 16:42:06 +00:00
|
|
|
double now = now_ms();
|
|
|
|
fLastMeasurement = (now - fStartTime) / (FLAGS_frames * fLoops);
|
|
|
|
fCurrentFrame = 0;
|
2015-10-05 20:58:26 +00:00
|
|
|
parentEvent = kTimingFinished_ParentEvents;
|
|
|
|
if (preWarmBetweenSamples) {
|
|
|
|
fState = kPreWarm_State;
|
|
|
|
} else {
|
2015-11-13 16:42:06 +00:00
|
|
|
fStartTime = now;
|
2015-10-05 20:58:26 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
fCurrentFrame++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2015-10-05 14:23:30 +00:00
|
|
|
}
|
2015-10-05 20:58:26 +00:00
|
|
|
return parentEvent;
|
2015-10-05 14:23:30 +00:00
|
|
|
}
|
|
|
|
|
2015-10-15 14:18:29 +00:00
|
|
|
void TimingStateMachine::nextBenchmark() {
|
2015-10-05 20:24:55 +00:00
|
|
|
fLoops = 1;
|
2015-10-05 20:58:26 +00:00
|
|
|
fInnerState = kTuning_InnerState;
|
|
|
|
fState = kPreWarm_State;
|
2015-10-05 20:24:55 +00:00
|
|
|
}
|