blob: d2e5b20fa3b253a8cc419796aec4e2fee55cfc20 [file] [log] [blame]
jvanverthf5d1b2d2015-09-15 07:40:56 -07001/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 *
7 */
8
9#include "VisualInteractiveModule.h"
10
11#include "ProcStats.h"
12#include "SkApplication.h"
13#include "SkCanvas.h"
14#include "SkCommandLineFlags.h"
15#include "SkForceLinking.h"
16#include "SkGraphics.h"
17#include "SkGr.h"
18#include "SkImageDecoder.h"
19#include "SkOSFile.h"
20#include "SkStream.h"
21#include "Stats.h"
22#include "gl/GrGLInterface.h"
23
24__SK_FORCE_IMAGE_DECODER_LINKING;
25
jvanverthf5d1b2d2015-09-15 07:40:56 -070026VisualInteractiveModule::VisualInteractiveModule(VisualBench* owner)
27 : fCurrentMeasurement(0)
jvanverthf5d1b2d2015-09-15 07:40:56 -070028 , fBenchmark(nullptr)
joshualittdc5db592015-10-05 13:24:55 -070029 , fAdvance(false)
joshualittcb54e8e2015-10-05 13:58:26 -070030 , fHasBeenReset(false)
jvanverthf5d1b2d2015-09-15 07:40:56 -070031 , fOwner(SkRef(owner)) {
32 fBenchmarkStream.reset(new VisualBenchmarkStream);
33
34 memset(fMeasurements, 0, sizeof(fMeasurements));
35}
36
37inline void VisualInteractiveModule::renderFrame(SkCanvas* canvas) {
joshualittdc5db592015-10-05 13:24:55 -070038 fBenchmark->draw(fTSM.loops(), canvas);
jvanverthf5d1b2d2015-09-15 07:40:56 -070039 this->drawStats(canvas);
40 canvas->flush();
41 fOwner->present();
42}
43
44void VisualInteractiveModule::drawStats(SkCanvas* canvas) {
45 static const float kPixelPerMS = 2.0f;
46 static const int kDisplayWidth = 130;
47 static const int kDisplayHeight = 100;
48 static const int kDisplayPadding = 10;
49 static const int kGraphPadding = 3;
50 static const float kBaseMS = 1000.f / 60.f; // ms/frame to hit 60 fps
51
52 SkISize canvasSize = canvas->getDeviceSize();
53 SkRect rect = SkRect::MakeXYWH(SkIntToScalar(canvasSize.fWidth-kDisplayWidth-kDisplayPadding),
54 SkIntToScalar(kDisplayPadding),
55 SkIntToScalar(kDisplayWidth), SkIntToScalar(kDisplayHeight));
56 SkPaint paint;
57 canvas->clipRect(rect);
58 paint.setColor(SK_ColorBLACK);
59 canvas->drawRect(rect, paint);
60 // draw the 16ms line
61 paint.setColor(SK_ColorLTGRAY);
62 canvas->drawLine(rect.fLeft, rect.fBottom - kBaseMS*kPixelPerMS,
63 rect.fRight, rect.fBottom - kBaseMS*kPixelPerMS, paint);
64 paint.setColor(SK_ColorRED);
65 paint.setStyle(SkPaint::kStroke_Style);
66 canvas->drawRect(rect, paint);
67
68 int x = SkScalarTruncToInt(rect.fLeft) + kGraphPadding;
69 const int xStep = 2;
70 const int startY = SkScalarTruncToInt(rect.fBottom);
71 int i = fCurrentMeasurement;
72 do {
73 int endY = startY - (int)(fMeasurements[i] * kPixelPerMS + 0.5); // round to nearest value
74 canvas->drawLine(SkIntToScalar(x), SkIntToScalar(startY),
75 SkIntToScalar(x), SkIntToScalar(endY), paint);
76 i++;
77 i &= (kMeasurementCount - 1); // fast mod
78 x += xStep;
79 } while (i != fCurrentMeasurement);
80
81}
82
83bool VisualInteractiveModule::advanceRecordIfNecessary(SkCanvas* canvas) {
84 if (fBenchmark) {
85 return true;
86 }
87
88 fBenchmark.reset(fBenchmarkStream->next());
89 if (!fBenchmark) {
90 return false;
91 }
92
93 // clear both buffers
94 fOwner->clear(canvas, SK_ColorWHITE, 2);
95
joshualitt8a6697a2015-09-30 12:11:07 -070096 fBenchmark->delayedSetup();
joshualittcb54e8e2015-10-05 13:58:26 -070097 fBenchmark->preTimingHooks(canvas);
jvanverthf5d1b2d2015-09-15 07:40:56 -070098 return true;
99}
joshualittdc5db592015-10-05 13:24:55 -0700100#include "GrGpu.h"
101#include "GrResourceCache.h"
jvanverthf5d1b2d2015-09-15 07:40:56 -0700102void VisualInteractiveModule::draw(SkCanvas* canvas) {
103 if (!this->advanceRecordIfNecessary(canvas)) {
104 SkDebugf("Exiting VisualBench successfully\n");
105 fOwner->closeWindow();
106 return;
107 }
joshualittcb54e8e2015-10-05 13:58:26 -0700108
109 if (fHasBeenReset) {
110 fHasBeenReset = false;
111 fBenchmark->preTimingHooks(canvas);
112 }
113
jvanverthf5d1b2d2015-09-15 07:40:56 -0700114 this->renderFrame(canvas);
joshualittcb54e8e2015-10-05 13:58:26 -0700115 TimingStateMachine::ParentEvents event = fTSM.nextFrame(false);
joshualittdc5db592015-10-05 13:24:55 -0700116 switch (event) {
117 case TimingStateMachine::kReset_ParentEvents:
joshualittcb54e8e2015-10-05 13:58:26 -0700118 fBenchmark->postTimingHooks(canvas);
119 fHasBeenReset = true;
joshualittdc5db592015-10-05 13:24:55 -0700120 fOwner->reset();
jvanverthf5d1b2d2015-09-15 07:40:56 -0700121 break;
joshualittdc5db592015-10-05 13:24:55 -0700122 case TimingStateMachine::kTiming_ParentEvents:
jvanverthf5d1b2d2015-09-15 07:40:56 -0700123 break;
joshualittdc5db592015-10-05 13:24:55 -0700124 case TimingStateMachine::kTimingFinished_ParentEvents:
125 // Record measurements
126 fMeasurements[fCurrentMeasurement++] = fTSM.lastMeasurement();
127 fCurrentMeasurement &= (kMeasurementCount-1); // fast mod
128 SkASSERT(fCurrentMeasurement < kMeasurementCount);
129 this->drawStats(canvas);
130 if (fAdvance) {
131 fAdvance = false;
132 fTSM.nextBenchmark(canvas, fBenchmark);
joshualittcb54e8e2015-10-05 13:58:26 -0700133 fBenchmark->postTimingHooks(canvas);
joshualittdc5db592015-10-05 13:24:55 -0700134 fBenchmark.reset(nullptr);
135 fOwner->reset();
joshualittcb54e8e2015-10-05 13:58:26 -0700136 fHasBeenReset = true;
joshualittdc5db592015-10-05 13:24:55 -0700137 }
jvanverthf5d1b2d2015-09-15 07:40:56 -0700138 break;
jvanverthf5d1b2d2015-09-15 07:40:56 -0700139 }
140}
141
142bool VisualInteractiveModule::onHandleChar(SkUnichar c) {
143 if (' ' == c) {
joshualittdc5db592015-10-05 13:24:55 -0700144 fAdvance = true;
jvanverthf5d1b2d2015-09-15 07:40:56 -0700145 }
146
147 return true;
148}