Improve viewer stats collection and display

Measure the time taken for animation and flush. Exclude UI and stats logic
from the timing. Use stacked bars to visualize the breakdown of time
within a frame.

BUG=skia:

Change-Id: I7ef84442a68147f02f65b6aa4452768fd3314de2
Reviewed-on: https://skia-review.googlesource.com/8227
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
Brian Osman 2017-02-09 12:10:20 -05:00 committed by Skia Commit-Bot
parent 75435bf7c9
commit 1df161ab8a
2 changed files with 49 additions and 16 deletions

View File

@ -131,7 +131,9 @@ Viewer::Viewer(int argc, char** argv, void* platformData)
, fZoomScale(SK_Scalar1)
{
SkGraphics::Init();
memset(fMeasurements, 0, sizeof(fMeasurements));
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) {
@ -471,7 +473,15 @@ void Viewer::drawSlide(SkCanvas* canvas) {
slideCanvas->concat(fDefaultMatrix);
slideCanvas->concat(computeMatrix());
// Time the painting logic of the slide
double startTime = SkTime::GetMSecs();
fSlides[fCurrentSlide]->draw(slideCanvas);
fPaintTimes[fCurrentMeasurement] = SkTime::GetMSecs() - startTime;
// Force a flush so we can time that, too
startTime = SkTime::GetMSecs();
slideCanvas->flush();
fFlushTimes[fCurrentMeasurement] = SkTime::GetMSecs() - startTime;
// If we rendered offscreen, snap an image and push the results to the window's canvas
if (offscreenSurface) {
@ -488,20 +498,20 @@ void Viewer::drawSlide(SkCanvas* canvas) {
}
void Viewer::onPaint(SkCanvas* canvas) {
// Record measurements
double startTime = SkTime::GetMSecs();
drawSlide(canvas);
// Advance our timing bookkeeping
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);
fMeasurements[fCurrentMeasurement++] = SkTime::GetMSecs() - startTime;
fCurrentMeasurement &= (kMeasurementCount - 1); // fast mod
SkASSERT(fCurrentMeasurement < kMeasurementCount);
updateUIState(); // Update the FPS
// Update the FPS
updateUIState();
}
bool Viewer::onTouch(intptr_t owner, Window::InputState state, float x, float y) {
@ -559,10 +569,25 @@ void Viewer::drawStats(SkCanvas* canvas) {
int x = SkScalarTruncToInt(rect.fLeft) + kGraphPadding;
const int xStep = 2;
const int startY = SkScalarTruncToInt(rect.fBottom);
int i = fCurrentMeasurement;
do {
int endY = startY - (int)(fMeasurements[i] * kPixelPerMS + 0.5); // round to nearest value
// 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 = startY - flushHeight;
paint.setColor(SK_ColorRED);
canvas->drawLine(SkIntToScalar(x), SkIntToScalar(startY),
SkIntToScalar(x), SkIntToScalar(endY), paint);
startY = endY;
endY = startY - paintHeight;
paint.setColor(SK_ColorGREEN);
canvas->drawLine(SkIntToScalar(x), SkIntToScalar(startY),
SkIntToScalar(x), SkIntToScalar(endY), paint);
startY = endY;
endY = startY - animateHeight;
paint.setColor(SK_ColorMAGENTA);
canvas->drawLine(SkIntToScalar(x), SkIntToScalar(startY),
SkIntToScalar(x), SkIntToScalar(endY), paint);
i++;
@ -574,8 +599,12 @@ void Viewer::drawStats(SkCanvas* canvas) {
}
void Viewer::onIdle() {
double startTime = SkTime::GetMSecs();
fAnimTimer.updateTime();
if (fSlides[fCurrentSlide]->animate(fAnimTimer) || fDisplayStats || fRefresh) {
bool animateWantsInval = fSlides[fCurrentSlide]->animate(fAnimTimer);
fAnimateTimes[fCurrentMeasurement] = SkTime::GetMSecs() - startTime;
if (animateWantsInval || fDisplayStats || fRefresh) {
fWindow->inval();
}
}
@ -614,10 +643,12 @@ void Viewer::updateUIState() {
// FPS state
Json::Value fpsState(Json::objectValue);
fpsState[kName] = kFpsStateName;
double measurement = fMeasurements[
(fCurrentMeasurement + (kMeasurementCount-1)) % kMeasurementCount
];
fpsState[kValue] = SkStringPrintf("%8.3lf ms", measurement).c_str();
int idx = (fCurrentMeasurement + (kMeasurementCount - 1)) & (kMeasurementCount - 1);
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();
fpsState[kOptions] = Json::Value(Json::arrayValue);
Json::Value state(Json::arrayValue);

View File

@ -45,7 +45,9 @@ private:
sk_app::Window* fWindow;
static const int kMeasurementCount = 64; // should be power of 2 for fast mod
double fMeasurements[kMeasurementCount];
double fPaintTimes[kMeasurementCount];
double fFlushTimes[kMeasurementCount];
double fAnimateTimes[kMeasurementCount];
int fCurrentMeasurement;
SkAnimTimer fAnimTimer;