Move stats code to new layer (with configurable list of timers)
Bug: skia:
Change-Id: I3ca5c8c7047309983018339ec7b71b9aea5ee786
Reviewed-on: https://skia-review.googlesource.com/86921
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 96c7623..3f1ce7f 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1846,6 +1846,7 @@
"tools/viewer/ImageSlide.cpp",
"tools/viewer/SKPSlide.cpp",
"tools/viewer/SampleSlide.cpp",
+ "tools/viewer/StatsLayer.cpp",
"tools/viewer/Viewer.cpp",
]
libs = []
diff --git a/tools/sk_app/Window.cpp b/tools/sk_app/Window.cpp
index 6713c4c..29e4864 100644
--- a/tools/sk_app/Window.cpp
+++ b/tools/sk_app/Window.cpp
@@ -20,61 +20,49 @@
fWindowContext = nullptr;
}
-void Window::onBackendCreated() {
+void Window::visitLayers(std::function<void(Layer*)> visitor) {
for (int i = 0; i < fLayers.count(); ++i) {
- fLayers[i]->onBackendCreated();
+ if (fLayers[i]->fActive) {
+ visitor(fLayers[i]);
+ }
}
}
+bool Window::signalLayers(std::function<bool(Layer*)> visitor) {
+ for (int i = fLayers.count() - 1; i >= 0; --i) {
+ if (fLayers[i]->fActive && visitor(fLayers[i])) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void Window::onBackendCreated() {
+ this->visitLayers([](Layer* layer) { layer->onBackendCreated(); });
+}
+
bool Window::onChar(SkUnichar c, uint32_t modifiers) {
- for (int i = fLayers.count() - 1; i >= 0; --i) {
- if (fLayers[i]->onChar(c, modifiers)) {
- return true;
- }
- }
- return false;
+ return this->signalLayers([=](Layer* layer) { return layer->onChar(c, modifiers); });
}
bool Window::onKey(Key key, InputState state, uint32_t modifiers) {
- for (int i = fLayers.count() - 1; i >= 0; --i) {
- if (fLayers[i]->onKey(key, state, modifiers)) {
- return true;
- }
- }
- return false;
+ return this->signalLayers([=](Layer* layer) { return layer->onKey(key, state, modifiers); });
}
bool Window::onMouse(int x, int y, InputState state, uint32_t modifiers) {
- for (int i = fLayers.count() - 1; i >= 0; --i) {
- if (fLayers[i]->onMouse(x, y, state, modifiers)) {
- return true;
- }
- }
- return false;
+ return this->signalLayers([=](Layer* layer) { return layer->onMouse(x, y, state, modifiers); });
}
bool Window::onMouseWheel(float delta, uint32_t modifiers) {
- for (int i = fLayers.count() - 1; i >= 0; --i) {
- if (fLayers[i]->onMouseWheel(delta, modifiers)) {
- return true;
- }
- }
- return false;
+ return this->signalLayers([=](Layer* layer) { return layer->onMouseWheel(delta, modifiers); });
}
bool Window::onTouch(intptr_t owner, InputState state, float x, float y) {
- for (int i = fLayers.count() - 1; i >= 0; --i) {
- if (fLayers[i]->onTouch(owner, state, x, y)) {
- return true;
- }
- }
- return false;
+ return this->signalLayers([=](Layer* layer) { return layer->onTouch(owner, state, x, y); });
}
void Window::onUIStateChanged(const SkString& stateName, const SkString& stateValue) {
- for (int i = 0; i < fLayers.count(); ++i) {
- fLayers[i]->onUIStateChanged(stateName, stateValue);
- }
+ this->visitLayers([=](Layer* layer) { layer->onUIStateChanged(stateName, stateValue); });
}
void Window::onPaint() {
@@ -87,12 +75,8 @@
// draw into the canvas of this surface
SkCanvas* canvas = backbuffer->getCanvas();
- for (int i = 0; i < fLayers.count(); ++i) {
- fLayers[i]->onPrePaint();
- }
- for (int i = 0; i < fLayers.count(); ++i) {
- fLayers[i]->onPaint(canvas);
- }
+ this->visitLayers([](Layer* layer) { layer->onPrePaint(); });
+ this->visitLayers([=](Layer* layer) { layer->onPaint(canvas); });
canvas->flush();
diff --git a/tools/sk_app/Window.h b/tools/sk_app/Window.h
index b541e24..927d8a9 100644
--- a/tools/sk_app/Window.h
+++ b/tools/sk_app/Window.h
@@ -132,8 +132,12 @@
class Layer {
public:
+ Layer() : fActive(true) {}
virtual ~Layer() = default;
+ bool getActive() { return fActive; }
+ void setActive(bool active) { fActive = active; }
+
// return value of 'true' means 'I have handled this event'
virtual void onBackendCreated() {}
virtual void onAttach(Window* window) {}
@@ -145,6 +149,10 @@
virtual void onUIStateChanged(const SkString& stateName, const SkString& stateValue) {}
virtual void onPrePaint() {}
virtual void onPaint(SkCanvas*) {}
+
+ private:
+ friend class Window;
+ bool fActive;
};
void pushLayer(Layer* layer) {
@@ -189,6 +197,9 @@
void markInvalProcessed();
bool fIsContentInvalidated = false; // use this to avoid duplicate invalidate events
+
+ void visitLayers(std::function<void(Layer*)> visitor);
+ bool signalLayers(std::function<bool(Layer*)> visitor);
};
} // namespace sk_app
diff --git a/tools/viewer/StatsLayer.cpp b/tools/viewer/StatsLayer.cpp
new file mode 100644
index 0000000..75226fd
--- /dev/null
+++ b/tools/viewer/StatsLayer.cpp
@@ -0,0 +1,139 @@
+/*
+* Copyright 2017 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#include "StatsLayer.h"
+
+#include "SkCanvas.h"
+#include "SkString.h"
+#include "SkTime.h"
+
+StatsLayer::StatsLayer()
+ : fCurrentMeasurement(0)
+ , fCumulativeMeasurementTime(0)
+ , fCumulativeMeasurementCount(0) {}
+
+void StatsLayer::resetMeasurements() {
+ for (int i = 0; i < fTimers.count(); ++i) {
+ memset(fTimers[i].fTimes, 0, sizeof(fTimers[i].fTimes));
+ }
+ fCurrentMeasurement = 0;
+ fCumulativeMeasurementTime = 0;
+ fCumulativeMeasurementCount = 0;
+}
+
+StatsLayer::Timer StatsLayer::addTimer(const char* label, SkColor color, SkColor labelColor) {
+ Timer newTimer = fTimers.count();
+ TimerData& newData = fTimers.push_back();
+ memset(newData.fTimes, 0, sizeof(newData.fTimes));
+ newData.fLabel = label;
+ newData.fColor = color;
+ newData.fLabelColor = labelColor ? labelColor : color;
+ return newTimer;
+}
+
+void StatsLayer::beginTiming(Timer timer) {
+ fTimers[timer].fTimes[fCurrentMeasurement] -= SkTime::GetMSecs();
+}
+
+void StatsLayer::endTiming(Timer timer) {
+ fTimers[timer].fTimes[fCurrentMeasurement] += SkTime::GetMSecs();
+}
+
+double StatsLayer::getLastTime(Timer timer) {
+ int idx = (fCurrentMeasurement + (kMeasurementCount - 1)) & (kMeasurementCount - 1);
+ return fTimers[timer].fTimes[idx];
+}
+
+void StatsLayer::onPaint(SkCanvas* canvas) {
+ // Advance our timing bookkeeping
+ for (int i = 0; i < fTimers.count(); ++i) {
+ fCumulativeMeasurementTime += fTimers[i].fTimes[fCurrentMeasurement];
+ }
+ fCumulativeMeasurementCount++;
+ fCurrentMeasurement = (fCurrentMeasurement + 1) & (kMeasurementCount - 1);
+ SkASSERT(fCurrentMeasurement < kMeasurementCount);
+ for (int i = 0; i < fTimers.count(); ++i) {
+ fTimers[i].fTimes[fCurrentMeasurement] = 0;
+ }
+
+ // Now draw everything
+ static const float kPixelPerMS = 2.0f;
+ static const int kDisplayWidth = 192;
+ static const int kGraphHeight = 100;
+ static const int kTextHeight = 60;
+ static const int kDisplayHeight = kGraphHeight + kTextHeight;
+ static const int kDisplayPadding = 10;
+ static const int kGraphPadding = 3;
+ static const SkScalar kBaseMS = 1000.f / 60.f; // ms/frame to hit 60 fps
+
+ SkISize canvasSize = canvas->getBaseLayerSize();
+ SkRect rect = SkRect::MakeXYWH(SkIntToScalar(canvasSize.fWidth-kDisplayWidth-kDisplayPadding),
+ SkIntToScalar(kDisplayPadding),
+ SkIntToScalar(kDisplayWidth), SkIntToScalar(kDisplayHeight));
+ SkPaint paint;
+ canvas->save();
+
+ paint.setColor(SK_ColorBLACK);
+ canvas->drawRect(rect, paint);
+ // draw the 16ms line
+ paint.setColor(SK_ColorLTGRAY);
+ canvas->drawLine(rect.fLeft, rect.fBottom - kBaseMS*kPixelPerMS,
+ rect.fRight, rect.fBottom - kBaseMS*kPixelPerMS, paint);
+ paint.setColor(SK_ColorRED);
+ paint.setStyle(SkPaint::kStroke_Style);
+ canvas->drawRect(rect, paint);
+ paint.setStyle(SkPaint::kFill_Style);
+
+ int x = SkScalarTruncToInt(rect.fLeft) + kGraphPadding;
+ const int xStep = 3;
+ int i = fCurrentMeasurement;
+ double ms = 0;
+ SkTDArray<double> sumTimes;
+ sumTimes.setCount(fTimers.count());
+ memset(sumTimes.begin(), 0, sumTimes.count() * sizeof(double));
+ int count = 0;
+ do {
+ int startY = SkScalarTruncToInt(rect.fBottom);
+ double inc = 0;
+ for (int timer = 0; timer < fTimers.count(); ++timer) {
+ int height = (int)(fTimers[timer].fTimes[i] * kPixelPerMS + 0.5);
+ int endY = SkTMax(startY - height, kDisplayPadding + kTextHeight);
+ paint.setColor(fTimers[timer].fColor);
+ canvas->drawLine(SkIntToScalar(x), SkIntToScalar(startY),
+ SkIntToScalar(x), SkIntToScalar(endY), paint);
+ startY = endY;
+ inc += fTimers[timer].fTimes[i];
+ sumTimes[timer] += fTimers[timer].fTimes[i];
+ }
+
+ if (inc > 0) {
+ ms += inc;
+ ++count;
+ }
+
+ i++;
+ i &= (kMeasurementCount - 1); // fast mod
+ x += xStep;
+ } while (i != fCurrentMeasurement);
+
+ paint.setTextSize(16);
+ SkString mainString;
+ mainString.appendf("%4.3f ms -> %4.3f ms", ms / SkTMax(1, count),
+ fCumulativeMeasurementTime / SkTMax(1, fCumulativeMeasurementCount));
+ paint.setColor(SK_ColorWHITE);
+ canvas->drawString(mainString.c_str(), rect.fLeft + 3, rect.fTop + 14, paint);
+
+ for (int timer = 0; timer < fTimers.count(); ++timer) {
+ SkString str;
+ str.appendf("%s: %4.3f ms", fTimers[timer].fLabel.c_str(),
+ sumTimes[timer] / SkTMax(1, count));
+ paint.setColor(fTimers[timer].fLabelColor);
+ canvas->drawString(str, rect.fLeft + 3, rect.fTop + 28 + (14 * timer), paint);
+ }
+
+ canvas->restore();
+}
diff --git a/tools/viewer/StatsLayer.h b/tools/viewer/StatsLayer.h
new file mode 100644
index 0000000..a99bd43
--- /dev/null
+++ b/tools/viewer/StatsLayer.h
@@ -0,0 +1,43 @@
+/*
+* Copyright 2017 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#ifndef StatsLayer_DEFINED
+#define StatsLayer_DEFINED
+
+#include "SkColor.h"
+#include "SkString.h"
+#include "sk_app/Window.h"
+
+class StatsLayer : public sk_app::Window::Layer {
+public:
+ StatsLayer();
+ void resetMeasurements();
+
+ typedef int Timer;
+
+ Timer addTimer(const char* label, SkColor color, SkColor labelColor = 0);
+ void beginTiming(Timer);
+ void endTiming(Timer);
+ double getLastTime(Timer);
+
+ void onPaint(SkCanvas* canvas) override;
+
+private:
+ static const int kMeasurementCount = 1 << 6; // should be power of 2 for fast mod
+ struct TimerData {
+ double fTimes[kMeasurementCount];
+ SkString fLabel;
+ SkColor fColor;
+ SkColor fLabelColor;
+ };
+ SkTArray<TimerData> fTimers;
+ int fCurrentMeasurement;
+ double fCumulativeMeasurementTime;
+ int fCumulativeMeasurementCount;
+};
+
+#endif
diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp
index edf37cd..0baa409 100644
--- a/tools/viewer/Viewer.cpp
+++ b/tools/viewer/Viewer.cpp
@@ -30,7 +30,6 @@
#include "SkSurface.h"
#include "SkTaskGroup.h"
#include "SkThreadedBMPDevice.h"
-#include "SkTime.h"
#include "imgui.h"
@@ -171,11 +170,7 @@
const char* kRefreshStateName = "Refresh";
Viewer::Viewer(int argc, char** argv, void* platformData)
- : fCurrentMeasurement(0)
- , fCumulativeMeasurementTime(0)
- , fCumulativeMeasurementCount(0)
- , fDisplayStats(false)
- , fRefresh(false)
+ : fRefresh(false)
, fSaveToSKP(false)
, fShowImGuiDebugWindow(false)
, fShowSlidePicker(false)
@@ -204,10 +199,6 @@
gPathRendererNames[GpuPathRenderers::kTessellating] = "Tessellating";
gPathRendererNames[GpuPathRenderers::kNone] = "Software masks";
- memset(fPaintTimes, 0, sizeof(fPaintTimes));
- memset(fFlushTimes, 0, sizeof(fFlushTimes));
- memset(fAnimateTimes, 0, sizeof(fAnimateTimes));
-
SkDebugf("Command line arguments: ");
for (int i = 1; i < argc; ++i) {
SkDebugf("%s ", argv[i]);
@@ -230,9 +221,16 @@
SetCtxOptionsFromCommonFlags(&displayParams.fGrContextOptions);
fWindow->setRequestedDisplayParams(displayParams);
+ // Configure timers
+ fStatsLayer.setActive(false);
+ fAnimateTimer = fStatsLayer.addTimer("Animate", SK_ColorMAGENTA, 0xffff66ff);
+ fPaintTimer = fStatsLayer.addTimer("Paint", SK_ColorGREEN);
+ fFlushTimer = fStatsLayer.addTimer("Flush", SK_ColorRED, 0xffff6666);
+
// register callbacks
fCommands.attach(fWindow);
fWindow->pushLayer(this);
+ fWindow->pushLayer(&fStatsLayer);
fWindow->pushLayer(&fImGuiLayer);
// add key-bindings
@@ -261,11 +259,11 @@
fWindow->inval();
});
fCommands.addCommand('s', "Overlays", "Toggle stats display", [this]() {
- this->fDisplayStats = !this->fDisplayStats;
+ fStatsLayer.setActive(!fStatsLayer.getActive());
fWindow->inval();
});
fCommands.addCommand('0', "Overlays", "Reset stats", [this]() {
- this->resetMeasurements();
+ fStatsLayer.resetMeasurements();
this->updateTitle();
fWindow->inval();
});
@@ -593,15 +591,6 @@
}
}
-void Viewer::resetMeasurements() {
- memset(fPaintTimes, 0, sizeof(fPaintTimes));
- memset(fFlushTimes, 0, sizeof(fFlushTimes));
- memset(fAnimateTimes, 0, sizeof(fAnimateTimes));
- fCurrentMeasurement = 0;
- fCumulativeMeasurementTime = 0;
- fCumulativeMeasurementCount = 0;
-}
-
void Viewer::setupCurrentSlide(int previousSlide) {
if (fCurrentSlide == previousSlide) {
return; // no change; do nothing
@@ -632,7 +621,7 @@
fSlides[previousSlide]->unload();
}
- this->resetMeasurements();
+ fStatsLayer.resetMeasurements();
fWindow->inval();
}
@@ -673,6 +662,7 @@
// re-register callbacks
fCommands.attach(fWindow);
fWindow->pushLayer(this);
+ fWindow->pushLayer(&fStatsLayer);
fWindow->pushLayer(&fImGuiLayer);
// Don't allow the window to re-attach. If we're in MSAA mode, the params we grabbed above
@@ -788,15 +778,15 @@
slideCanvas->clear(SK_ColorWHITE);
slideCanvas->concat(computeMatrix());
// Time the painting logic of the slide
- double startTime = SkTime::GetMSecs();
+ fStatsLayer.beginTiming(fPaintTimer);
fSlides[fCurrentSlide]->draw(slideCanvas);
- fPaintTimes[fCurrentMeasurement] = SkTime::GetMSecs() - startTime;
+ fStatsLayer.endTiming(fPaintTimer);
slideCanvas->restoreToCount(count);
// Force a flush so we can time that, too
- startTime = SkTime::GetMSecs();
+ fStatsLayer.beginTiming(fFlushTimer);
slideCanvas->flush();
- fFlushTimes[fCurrentMeasurement] = SkTime::GetMSecs() - startTime;
+ fStatsLayer.endTiming(fFlushTimer);
// If we rendered offscreen, snap an image and push the results to the window's canvas
if (offscreenSurface) {
@@ -816,7 +806,7 @@
this->updateTitle();
this->updateUIState();
this->setupCurrentSlide(-1);
- this->resetMeasurements();
+ fStatsLayer.resetMeasurements();
fWindow->show();
fWindow->inval();
}
@@ -824,18 +814,6 @@
void Viewer::onPaint(SkCanvas* canvas) {
this->drawSlide(canvas);
- // Advance our timing bookkeeping
- fCumulativeMeasurementTime += fAnimateTimes[fCurrentMeasurement] +
- fPaintTimes[fCurrentMeasurement] +
- fFlushTimes[fCurrentMeasurement];
- fCumulativeMeasurementCount++;
- fCurrentMeasurement = (fCurrentMeasurement + 1) & (kMeasurementCount - 1);
- SkASSERT(fCurrentMeasurement < kMeasurementCount);
-
- // Draw any overlays or UI that we don't want timed
- if (fDisplayStats) {
- drawStats(canvas);
- }
fCommands.drawHelp(canvas);
this->drawImGui();
@@ -893,102 +871,6 @@
return true;
}
-void Viewer::drawStats(SkCanvas* canvas) {
- static const float kPixelPerMS = 2.0f;
- static const int kDisplayWidth = 192;
- static const int kGraphHeight = 100;
- static const int kTextHeight = 60;
- static const int kDisplayHeight = kGraphHeight + kTextHeight;
- static const int kDisplayPadding = 10;
- static const int kGraphPadding = 3;
- static const SkScalar kBaseMS = 1000.f / 60.f; // ms/frame to hit 60 fps
-
- SkISize canvasSize = canvas->getBaseLayerSize();
- SkRect rect = SkRect::MakeXYWH(SkIntToScalar(canvasSize.fWidth-kDisplayWidth-kDisplayPadding),
- SkIntToScalar(kDisplayPadding),
- SkIntToScalar(kDisplayWidth), SkIntToScalar(kDisplayHeight));
- SkPaint paint;
- canvas->save();
-
- paint.setColor(SK_ColorBLACK);
- canvas->drawRect(rect, paint);
- // draw the 16ms line
- paint.setColor(SK_ColorLTGRAY);
- canvas->drawLine(rect.fLeft, rect.fBottom - kBaseMS*kPixelPerMS,
- rect.fRight, rect.fBottom - kBaseMS*kPixelPerMS, paint);
- paint.setColor(SK_ColorRED);
- paint.setStyle(SkPaint::kStroke_Style);
- canvas->drawRect(rect, paint);
- paint.setStyle(SkPaint::kFill_Style);
-
- int x = SkScalarTruncToInt(rect.fLeft) + kGraphPadding;
- const int xStep = 3;
- int i = fCurrentMeasurement;
- double ms = 0;
- double animateMS = 0;
- double paintMS = 0;
- double flushMS = 0;
- int count = 0;
- do {
- // Round to nearest values
- int animateHeight = (int)(fAnimateTimes[i] * kPixelPerMS + 0.5);
- int paintHeight = (int)(fPaintTimes[i] * kPixelPerMS + 0.5);
- int flushHeight = (int)(fFlushTimes[i] * kPixelPerMS + 0.5);
- int startY = SkScalarTruncToInt(rect.fBottom);
- int endY = SkTMax(startY - flushHeight, kDisplayPadding + kTextHeight);
- paint.setColor(SK_ColorRED);
- canvas->drawLine(SkIntToScalar(x), SkIntToScalar(startY),
- SkIntToScalar(x), SkIntToScalar(endY), paint);
- startY = endY;
- endY = SkTMax(startY - paintHeight, kDisplayPadding + kTextHeight);
- paint.setColor(SK_ColorGREEN);
- canvas->drawLine(SkIntToScalar(x), SkIntToScalar(startY),
- SkIntToScalar(x), SkIntToScalar(endY), paint);
- startY = endY;
- endY = SkTMax(startY - animateHeight, kDisplayPadding + kTextHeight);
- paint.setColor(SK_ColorMAGENTA);
- canvas->drawLine(SkIntToScalar(x), SkIntToScalar(startY),
- SkIntToScalar(x), SkIntToScalar(endY), paint);
-
- double inc = fAnimateTimes[i] + fPaintTimes[i] + fFlushTimes[i];
- if (inc > 0) {
- ms += inc;
- animateMS += fAnimateTimes[i];
- paintMS += fPaintTimes[i];
- flushMS += fFlushTimes[i];
- ++count;
- }
-
- i++;
- i &= (kMeasurementCount - 1); // fast mod
- x += xStep;
- } while (i != fCurrentMeasurement);
-
- paint.setTextSize(16);
- SkString mainString;
- mainString.appendf("%4.3f ms -> %4.3f ms", ms / SkTMax(1, count),
- fCumulativeMeasurementTime / SkTMax(1, fCumulativeMeasurementCount));
- paint.setColor(SK_ColorWHITE);
- canvas->drawString(mainString.c_str(), rect.fLeft+3, rect.fTop + 14, paint);
-
- SkString animateString;
- animateString.appendf("Animate: %4.3f ms", animateMS / SkTMax(1, count));
- paint.setColor(0xffff66ff); // pure magenta is hard to read
- canvas->drawString(animateString.c_str(), rect.fLeft+3, rect.fTop + 28, paint);
-
- SkString paintString;
- paintString.appendf("Paint: %4.3f ms", paintMS / SkTMax(1, count));
- paint.setColor(SK_ColorGREEN);
- canvas->drawString(paintString.c_str(), rect.fLeft+3, rect.fTop + 42, paint);
-
- SkString flushString;
- flushString.appendf("Flush: %4.3f ms", flushMS / SkTMax(1, count));
- paint.setColor(0xffff6666); // pure red is hard to read
- canvas->drawString(flushString.c_str(), rect.fLeft+3, rect.fTop + 56, paint);
-
- canvas->restore();
-}
-
static ImVec2 ImGui_DragPrimary(const char* label, float* x, float* y,
const ImVec2& pos, const ImVec2& size) {
// Transform primaries ([0, 0] - [0.8, 0.9]) to screen coords (including Y-flip)
@@ -1282,13 +1164,13 @@
}
fDeferredActions.reset();
- double startTime = SkTime::GetMSecs();
+ fStatsLayer.beginTiming(fAnimateTimer);
fAnimTimer.updateTime();
bool animateWantsInval = fSlides[fCurrentSlide]->animate(fAnimTimer);
- fAnimateTimes[fCurrentMeasurement] = SkTime::GetMSecs() - startTime;
+ fStatsLayer.endTiming(fAnimateTimer);
ImGuiIO& io = ImGui::GetIO();
- if (animateWantsInval || fDisplayStats || fRefresh || io.MetricsActiveWindows) {
+ if (animateWantsInval || fStatsLayer.getActive() || fRefresh || io.MetricsActiveWindows) {
fWindow->inval();
}
}
@@ -1378,12 +1260,12 @@
// FPS state
Json::Value fpsState(Json::objectValue);
fpsState[kName] = kFpsStateName;
- int idx = (fCurrentMeasurement + (kMeasurementCount - 1)) & (kMeasurementCount - 1);
+ double animTime = fStatsLayer.getLastTime(fAnimateTimer);
+ double paintTime = fStatsLayer.getLastTime(fPaintTimer);
+ double flushTime = fStatsLayer.getLastTime(fFlushTimer);
fpsState[kValue] = SkStringPrintf("%8.3lf ms\n\nA %8.3lf\nP %8.3lf\nF%8.3lf",
- fAnimateTimes[idx] + fPaintTimes[idx] + fFlushTimes[idx],
- fAnimateTimes[idx],
- fPaintTimes[idx],
- fFlushTimes[idx]).c_str();
+ animTime + paintTime + flushTime,
+ animTime, paintTime, flushTime).c_str();
fpsState[kOptions] = Json::Value(Json::arrayValue);
Json::Value state(Json::arrayValue);
diff --git a/tools/viewer/Viewer.h b/tools/viewer/Viewer.h
index 2ab3de5..7d4980c 100644
--- a/tools/viewer/Viewer.h
+++ b/tools/viewer/Viewer.h
@@ -18,6 +18,7 @@
#include "SkJSONCPP.h"
#include "SkTouchGesture.h"
#include "Slide.h"
+#include "StatsLayer.h"
class SkCanvas;
@@ -51,12 +52,10 @@
void setStartupSlide();
void setupCurrentSlide(int previousSlide);
void listNames();
- void resetMeasurements();
void updateUIState();
void drawSlide(SkCanvas* canvs);
- void drawStats(SkCanvas* canvas);
void drawImGui();
void changeZoomLevel(float delta);
@@ -68,19 +67,15 @@
sk_app::Window* fWindow;
- static const int kMeasurementCount = 1 << 6; // should be power of 2 for fast mod
- double fPaintTimes[kMeasurementCount];
- double fFlushTimes[kMeasurementCount];
- double fAnimateTimes[kMeasurementCount];
- int fCurrentMeasurement;
- double fCumulativeMeasurementTime;
- int fCumulativeMeasurementCount;
+ StatsLayer fStatsLayer;
+ StatsLayer::Timer fPaintTimer;
+ StatsLayer::Timer fFlushTimer;
+ StatsLayer::Timer fAnimateTimer;
SkAnimTimer fAnimTimer;
SkTArray<sk_sp<Slide>> fSlides;
int fCurrentSlide;
- bool fDisplayStats;
bool fRefresh; // whether to continuously refresh for measuring render time
bool fSaveToSKP;