Create VisualStreamTimingModule
BUG=skia:
Review URL: https://codereview.chromium.org/1385073002
diff --git a/tools/VisualBench/TimingStateMachine.h b/tools/VisualBench/TimingStateMachine.h
index 7f7a5af..2215059 100644
--- a/tools/VisualBench/TimingStateMachine.h
+++ b/tools/VisualBench/TimingStateMachine.h
@@ -3,7 +3,6 @@
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
- *
*/
#ifndef TimingStateMachine_DEFINED
diff --git a/tools/VisualBench/VisualInteractiveModule.cpp b/tools/VisualBench/VisualInteractiveModule.cpp
index d2e5b20..b597b05 100755
--- a/tools/VisualBench/VisualInteractiveModule.cpp
+++ b/tools/VisualBench/VisualInteractiveModule.cpp
@@ -3,42 +3,28 @@
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
- *
*/
#include "VisualInteractiveModule.h"
-#include "ProcStats.h"
-#include "SkApplication.h"
#include "SkCanvas.h"
#include "SkCommandLineFlags.h"
#include "SkForceLinking.h"
-#include "SkGraphics.h"
-#include "SkGr.h"
#include "SkImageDecoder.h"
-#include "SkOSFile.h"
-#include "SkStream.h"
-#include "Stats.h"
-#include "gl/GrGLInterface.h"
__SK_FORCE_IMAGE_DECODER_LINKING;
VisualInteractiveModule::VisualInteractiveModule(VisualBench* owner)
- : fCurrentMeasurement(0)
- , fBenchmark(nullptr)
- , fAdvance(false)
- , fHasBeenReset(false)
- , fOwner(SkRef(owner)) {
- fBenchmarkStream.reset(new VisualBenchmarkStream);
-
+ : INHERITED(owner, false)
+ , fCurrentMeasurement(0)
+ , fAdvance(false) {
memset(fMeasurements, 0, sizeof(fMeasurements));
}
-inline void VisualInteractiveModule::renderFrame(SkCanvas* canvas) {
- fBenchmark->draw(fTSM.loops(), canvas);
+void VisualInteractiveModule::renderFrame(SkCanvas* canvas, Benchmark* benchmark, int loops) {
+ benchmark->draw(loops, canvas);
this->drawStats(canvas);
canvas->flush();
- fOwner->present();
}
void VisualInteractiveModule::drawStats(SkCanvas* canvas) {
@@ -80,63 +66,16 @@
}
-bool VisualInteractiveModule::advanceRecordIfNecessary(SkCanvas* canvas) {
- if (fBenchmark) {
+bool VisualInteractiveModule::timingFinished(Benchmark* benchmark, int loops, double measurement) {
+ // Record measurements
+ fMeasurements[fCurrentMeasurement++] = measurement;
+ fCurrentMeasurement &= (kMeasurementCount-1); // fast mod
+ SkASSERT(fCurrentMeasurement < kMeasurementCount);
+ if (fAdvance) {
+ fAdvance = false;
return true;
}
-
- fBenchmark.reset(fBenchmarkStream->next());
- if (!fBenchmark) {
- return false;
- }
-
- // clear both buffers
- fOwner->clear(canvas, SK_ColorWHITE, 2);
-
- fBenchmark->delayedSetup();
- fBenchmark->preTimingHooks(canvas);
- return true;
-}
-#include "GrGpu.h"
-#include "GrResourceCache.h"
-void VisualInteractiveModule::draw(SkCanvas* canvas) {
- if (!this->advanceRecordIfNecessary(canvas)) {
- SkDebugf("Exiting VisualBench successfully\n");
- fOwner->closeWindow();
- return;
- }
-
- if (fHasBeenReset) {
- fHasBeenReset = false;
- fBenchmark->preTimingHooks(canvas);
- }
-
- this->renderFrame(canvas);
- TimingStateMachine::ParentEvents event = fTSM.nextFrame(false);
- switch (event) {
- case TimingStateMachine::kReset_ParentEvents:
- fBenchmark->postTimingHooks(canvas);
- fHasBeenReset = true;
- fOwner->reset();
- break;
- case TimingStateMachine::kTiming_ParentEvents:
- break;
- case TimingStateMachine::kTimingFinished_ParentEvents:
- // Record measurements
- fMeasurements[fCurrentMeasurement++] = fTSM.lastMeasurement();
- fCurrentMeasurement &= (kMeasurementCount-1); // fast mod
- SkASSERT(fCurrentMeasurement < kMeasurementCount);
- this->drawStats(canvas);
- if (fAdvance) {
- fAdvance = false;
- fTSM.nextBenchmark(canvas, fBenchmark);
- fBenchmark->postTimingHooks(canvas);
- fBenchmark.reset(nullptr);
- fOwner->reset();
- fHasBeenReset = true;
- }
- break;
- }
+ return false;
}
bool VisualInteractiveModule::onHandleChar(SkUnichar c) {
diff --git a/tools/VisualBench/VisualInteractiveModule.h b/tools/VisualBench/VisualInteractiveModule.h
index 5b9ff0a..d4f8f69 100755
--- a/tools/VisualBench/VisualInteractiveModule.h
+++ b/tools/VisualBench/VisualInteractiveModule.h
@@ -3,56 +3,36 @@
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
- *
*/
#ifndef VisualInteractiveModule_DEFINED
#define VisualInteractiveModule_DEFINED
-#include "VisualModule.h"
-
-#include "ResultsWriter.h"
-#include "SkPicture.h"
-#include "Timer.h"
-#include "TimingStateMachine.h"
-#include "VisualBench.h"
-#include "VisualBenchmarkStream.h"
+#include "VisualStreamTimingModule.h"
class SkCanvas;
/*
* This module for VisualBench is designed to display stats data dynamically
*/
-class VisualInteractiveModule : public VisualModule {
+class VisualInteractiveModule : public VisualStreamTimingModule {
public:
// TODO get rid of backpointer
VisualInteractiveModule(VisualBench* owner);
- void draw(SkCanvas* canvas) override;
- bool onHandleChar(SkUnichar unichar) override;
+ bool onHandleChar(SkUnichar c) override;
private:
- void setTitle();
- bool setupBackend();
- void setupRenderTarget();
void drawStats(SkCanvas*);
- bool advanceRecordIfNecessary(SkCanvas*);
- inline void renderFrame(SkCanvas*);
+ void renderFrame(SkCanvas*, Benchmark*, int loops) override;
+ bool timingFinished(Benchmark*, int loops, double measurement) override;
static const int kMeasurementCount = 64; // should be power of 2 for fast mod
double fMeasurements[kMeasurementCount];
int fCurrentMeasurement;
-
- SkAutoTDelete<VisualBenchmarkStream> fBenchmarkStream;
- SkAutoTUnref<Benchmark> fBenchmark;
- TimingStateMachine fTSM;
bool fAdvance;
- bool fHasBeenReset;
- // support framework
- SkAutoTUnref<VisualBench> fOwner;
-
- typedef VisualModule INHERITED;
+ typedef VisualStreamTimingModule INHERITED;
};
#endif
diff --git a/tools/VisualBench/VisualLightweightBenchModule.cpp b/tools/VisualBench/VisualLightweightBenchModule.cpp
index e2942d1..af939ff 100644
--- a/tools/VisualBench/VisualLightweightBenchModule.cpp
+++ b/tools/VisualBench/VisualLightweightBenchModule.cpp
@@ -3,7 +3,6 @@
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
- *
*/
#include "VisualLightweightBenchModule.h"
@@ -43,12 +42,9 @@
#define HUMANIZE(time) humanize(time).c_str()
VisualLightweightBenchModule::VisualLightweightBenchModule(VisualBench* owner)
- : fCurrentSample(0)
- , fHasBeenReset(false)
- , fOwner(SkRef(owner))
+ : INHERITED(owner, true)
+ , fCurrentSample(0)
, fResults(new ResultsWriter) {
- fBenchmarkStream.reset(new VisualBenchmarkStream);
-
// Print header
SkDebugf("curr/maxrss\tloops\tmin\tmedian\tmean\tmax\tstddev\t%-*s\tbench\n", FLAGS_samples,
"samples");
@@ -73,17 +69,19 @@
fResults->property(FLAGS_properties[i - 1], FLAGS_properties[i]);
}
}
+
+ // seed an initial record
+ fRecords.push_back();
}
-inline void VisualLightweightBenchModule::renderFrame(SkCanvas* canvas) {
- fBenchmark->draw(fTSM.loops(), canvas);
+void VisualLightweightBenchModule::renderFrame(SkCanvas* canvas, Benchmark* benchmark, int loops) {
+ benchmark->draw(loops, canvas);
canvas->flush();
- fOwner->present();
}
-void VisualLightweightBenchModule::printStats() {
+void VisualLightweightBenchModule::printStats(Benchmark* benchmark, int loops) {
const SkTArray<double>& measurements = fRecords.back().fMeasurements;
- const char* shortName = fBenchmark->getUniqueName();
+ const char* shortName = benchmark->getUniqueName();
// update log
// Note: We currently log only the minimum. It would be interesting to log more information
@@ -93,6 +91,9 @@
} else {
configName.appendf("gpu");
}
+ // Log bench name
+ fResults->bench(shortName, benchmark->getSize().fX, benchmark->getSize().fY);
+
fResults->config(configName.c_str());
fResults->configOption("name", shortName);
SkASSERT(measurements.count());
@@ -110,7 +111,7 @@
SkDebugf("%4d/%-4dMB\t%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\t%s\n",
sk_tools::getCurrResidentSetSizeMB(),
sk_tools::getMaxResidentSetSizeMB(),
- fTSM.loops(),
+ loops,
HUMANIZE(stats.min),
HUMANIZE(stats.median),
HUMANIZE(stats.mean),
@@ -121,65 +122,16 @@
}
}
-bool VisualLightweightBenchModule::advanceRecordIfNecessary(SkCanvas* canvas) {
- if (fBenchmark) {
+bool VisualLightweightBenchModule::timingFinished(Benchmark* benchmark, int loops,
+ double measurement) {
+ fRecords.back().fMeasurements.push_back(measurement);
+ if (++fCurrentSample > FLAGS_samples) {
+ this->printStats(benchmark, loops);
+ fRecords.push_back();
+ fCurrentSample = 0;
return true;
}
-
- fBenchmark.reset(fBenchmarkStream->next());
- if (!fBenchmark) {
- return false;
- }
-
- fOwner->clear(canvas, SK_ColorWHITE, 2);
-
- fRecords.push_back();
-
- // Log bench name
- fResults->bench(fBenchmark->getUniqueName(), fBenchmark->getSize().fX,
- fBenchmark->getSize().fY);
-
- fBenchmark->delayedSetup();
- fBenchmark->preTimingHooks(canvas);
- return true;
-}
-
-void VisualLightweightBenchModule::draw(SkCanvas* canvas) {
- if (!this->advanceRecordIfNecessary(canvas)) {
- SkDebugf("Exiting VisualBench successfully\n");
- fOwner->closeWindow();
- return;
- }
-
- if (fHasBeenReset) {
- fHasBeenReset = false;
- fBenchmark->preTimingHooks(canvas);
- }
-
- this->renderFrame(canvas);
- TimingStateMachine::ParentEvents event = fTSM.nextFrame(true);
- switch (event) {
- case TimingStateMachine::kReset_ParentEvents:
- fBenchmark->postTimingHooks(canvas);
- fOwner->reset();
- fHasBeenReset = true;
- break;
- case TimingStateMachine::kTiming_ParentEvents:
- break;
- case TimingStateMachine::kTimingFinished_ParentEvents:
- fBenchmark->postTimingHooks(canvas);
- fOwner->reset();
- fRecords.back().fMeasurements.push_back(fTSM.lastMeasurement());
- if (++fCurrentSample > FLAGS_samples) {
- this->printStats();
- fTSM.nextBenchmark(canvas, fBenchmark);
- fCurrentSample = 0;
- fBenchmark.reset(nullptr);
- } else {
- fHasBeenReset = true;
- }
- break;
- }
+ return false;
}
bool VisualLightweightBenchModule::onHandleChar(SkUnichar c) {
diff --git a/tools/VisualBench/VisualLightweightBenchModule.h b/tools/VisualBench/VisualLightweightBenchModule.h
index 3538a48..7618ff2 100644
--- a/tools/VisualBench/VisualLightweightBenchModule.h
+++ b/tools/VisualBench/VisualLightweightBenchModule.h
@@ -3,57 +3,44 @@
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
- *
*/
#ifndef VisualLightweightBenchModule_DEFINED
#define VisualLightweightBenchModule_DEFINED
-#include "VisualModule.h"
+#include "VisualStreamTimingModule.h"
#include "ResultsWriter.h"
#include "SkPicture.h"
-#include "TimingStateMachine.h"
#include "VisualBench.h"
-#include "VisualBenchmarkStream.h"
class SkCanvas;
/*
* This module is designed to be a minimal overhead timing module for VisualBench
*/
-class VisualLightweightBenchModule : public VisualModule {
+class VisualLightweightBenchModule : public VisualStreamTimingModule {
public:
// TODO get rid of backpointer
VisualLightweightBenchModule(VisualBench* owner);
- void draw(SkCanvas* canvas) override;
-
bool onHandleChar(SkUnichar c) override;
private:
- void setTitle();
- bool setupBackend();
- void setupRenderTarget();
- void printStats();
- bool advanceRecordIfNecessary(SkCanvas*);
- inline void renderFrame(SkCanvas*);
+ void renderFrame(SkCanvas*, Benchmark*, int loops) override;
+ bool timingFinished(Benchmark*, int loops, double measurement) override;
+ void printStats(Benchmark*, int loops);
struct Record {
SkTArray<double> fMeasurements;
};
int fCurrentSample;
SkTArray<Record> fRecords;
- SkAutoTDelete<VisualBenchmarkStream> fBenchmarkStream;
- SkAutoTUnref<Benchmark> fBenchmark;
- TimingStateMachine fTSM;
- bool fHasBeenReset;
// support framework
- SkAutoTUnref<VisualBench> fOwner;
SkAutoTDelete<ResultsWriter> fResults;
- typedef VisualModule INHERITED;
+ typedef VisualStreamTimingModule INHERITED;
};
#endif
diff --git a/tools/VisualBench/VisualStreamTimingModule.cpp b/tools/VisualBench/VisualStreamTimingModule.cpp
new file mode 100644
index 0000000..db75890
--- /dev/null
+++ b/tools/VisualBench/VisualStreamTimingModule.cpp
@@ -0,0 +1,70 @@
+/*
+ * 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 "VisualStreamTimingModule.h"
+
+#include "SkCanvas.h"
+
+VisualStreamTimingModule::VisualStreamTimingModule(VisualBench* owner, bool preWarmBeforeSample)
+ : fReinitializeBenchmark(false)
+ , fPreWarmBeforeSample(preWarmBeforeSample)
+ , fOwner(owner) {
+ fBenchmarkStream.reset(new VisualBenchmarkStream);
+}
+
+bool VisualStreamTimingModule::nextBenchmarkIfNecessary(SkCanvas* canvas) {
+ if (fBenchmark) {
+ return true;
+ }
+
+ fBenchmark.reset(fBenchmarkStream->next());
+ if (!fBenchmark) {
+ return false;
+ }
+
+ fOwner->clear(canvas, SK_ColorWHITE, 2);
+
+ fBenchmark->delayedSetup();
+ fBenchmark->preTimingHooks(canvas);
+ return true;
+}
+
+void VisualStreamTimingModule::draw(SkCanvas* canvas) {
+ if (!this->nextBenchmarkIfNecessary(canvas)) {
+ SkDebugf("Exiting VisualBench successfully\n");
+ fOwner->closeWindow();
+ return;
+ }
+
+ if (fReinitializeBenchmark) {
+ fReinitializeBenchmark = false;
+ fBenchmark->preTimingHooks(canvas);
+ }
+
+ this->renderFrame(canvas, fBenchmark, fTSM.loops());
+ fOwner->present();
+ TimingStateMachine::ParentEvents event = fTSM.nextFrame(fPreWarmBeforeSample);
+ switch (event) {
+ case TimingStateMachine::kReset_ParentEvents:
+ fBenchmark->postTimingHooks(canvas);
+ fOwner->reset();
+ fReinitializeBenchmark = true;
+ break;
+ case TimingStateMachine::kTiming_ParentEvents:
+ break;
+ case TimingStateMachine::kTimingFinished_ParentEvents:
+ fBenchmark->postTimingHooks(canvas);
+ fOwner->reset();
+ if (this->timingFinished(fBenchmark, fTSM.loops(), fTSM.lastMeasurement())) {
+ fTSM.nextBenchmark(canvas, fBenchmark);
+ fBenchmark.reset(nullptr);
+ } else {
+ fReinitializeBenchmark = true;
+ }
+ break;
+ }
+}
diff --git a/tools/VisualBench/VisualStreamTimingModule.h b/tools/VisualBench/VisualStreamTimingModule.h
new file mode 100644
index 0000000..ac06ed4
--- /dev/null
+++ b/tools/VisualBench/VisualStreamTimingModule.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef VisualStreamTimingModule_DEFINED
+#define VisualStreamTimingModule_DEFINED
+
+#include "VisualModule.h"
+
+#include "TimingStateMachine.h"
+#include "VisualBench.h"
+#include "VisualBenchmarkStream.h"
+
+/*
+ * VisualStreamTimingModule is the base class for modules which want to time a stream of Benchmarks.
+ *
+ * Subclasses should implement renderFrame, which is called for each frame, and timingFinished,
+ * which is called when a sample has finished timing.
+ */
+class VisualStreamTimingModule : public VisualModule {
+public:
+ VisualStreamTimingModule(VisualBench* owner, bool preWarmBeforeSample);
+ void draw(SkCanvas* canvas) override;
+
+private:
+ virtual void renderFrame(SkCanvas*, Benchmark*, int loops)=0;
+
+ // subclasses should return true to advance the stream
+ virtual bool timingFinished(Benchmark*, int loops, double measurement)=0;
+
+ bool nextBenchmarkIfNecessary(SkCanvas*);
+
+ TimingStateMachine fTSM;
+ SkAutoTDelete<VisualBenchmarkStream> fBenchmarkStream;
+ SkAutoTUnref<Benchmark> fBenchmark;
+ bool fReinitializeBenchmark;
+ bool fPreWarmBeforeSample;
+
+ // support framework
+ VisualBench* fOwner;
+
+ typedef VisualModule INHERITED;
+};
+
+#endif