mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Now that the compositor doesn't have any tricky deps, we can make it a top-level project, which saves a bunch of typing.
141 lines
3.7 KiB
C++
141 lines
3.7 KiB
C++
// Copyright 2015 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "flow/instrumentation.h"
|
|
|
|
#include <algorithm>
|
|
|
|
#include "third_party/skia/include/core/SkPath.h"
|
|
|
|
namespace flow {
|
|
namespace instrumentation {
|
|
|
|
static const size_t kMaxSamples = 120;
|
|
static const size_t kMaxFrameMarkers = 8;
|
|
static const double kOneFrameMS = 1e3 / 60.0;
|
|
|
|
Stopwatch::Stopwatch() : _start(base::TimeTicks::Now()), _current_sample(0) {
|
|
const base::TimeDelta delta;
|
|
_laps.resize(kMaxSamples, delta);
|
|
}
|
|
|
|
void Stopwatch::start() {
|
|
_start = base::TimeTicks::Now();
|
|
_current_sample = (_current_sample + 1) % kMaxSamples;
|
|
}
|
|
|
|
void Stopwatch::stop() {
|
|
_laps[_current_sample] = base::TimeTicks::Now() - _start;
|
|
}
|
|
|
|
void Stopwatch::setLapTime(const base::TimeDelta& delta) {
|
|
_current_sample = (_current_sample + 1) % kMaxSamples;
|
|
_laps[_current_sample] = delta;
|
|
}
|
|
|
|
const base::TimeDelta& Stopwatch::lastLap() const {
|
|
return _laps[(_current_sample - 1) % kMaxSamples];
|
|
}
|
|
|
|
static inline constexpr double UnitFrameInterval(double frameTimeMS) {
|
|
return frameTimeMS * 60.0 * 1e-3;
|
|
}
|
|
|
|
base::TimeDelta Stopwatch::maxDelta() const {
|
|
base::TimeDelta maxDelta;
|
|
for (size_t i = 0; i < kMaxSamples; i++) {
|
|
if (_laps[i] > maxDelta) {
|
|
maxDelta = _laps[i];
|
|
}
|
|
}
|
|
return maxDelta;
|
|
}
|
|
|
|
void Stopwatch::visualize(SkCanvas& canvas, const SkRect& rect) const {
|
|
SkPaint paint;
|
|
|
|
// Paint the background
|
|
paint.setColor(0xAAFFFFFF);
|
|
canvas.drawRect(rect, paint);
|
|
|
|
// Paint the graph
|
|
SkPath path;
|
|
const SkScalar width = rect.width();
|
|
const SkScalar height = rect.height();
|
|
|
|
// Find the max delta. We use this to scale the graph
|
|
|
|
double maxInterval = maxDelta().InMillisecondsF();
|
|
|
|
if (maxInterval < kOneFrameMS) {
|
|
maxInterval = kOneFrameMS;
|
|
} else {
|
|
maxInterval =
|
|
kOneFrameMS * (static_cast<size_t>(maxInterval / kOneFrameMS) + 1);
|
|
}
|
|
|
|
const double maxUnitInterval = UnitFrameInterval(maxInterval);
|
|
|
|
// Draw the path
|
|
double unitHeight =
|
|
UnitFrameInterval(_laps[0].InMillisecondsF()) / maxUnitInterval;
|
|
|
|
path.moveTo(0, height);
|
|
path.lineTo(0, height * (1.0 - unitHeight));
|
|
|
|
for (size_t i = 0; i < kMaxSamples; i++) {
|
|
double unitWidth = (static_cast<double>(i + 1) / kMaxSamples);
|
|
unitHeight =
|
|
UnitFrameInterval(_laps[i].InMillisecondsF()) / maxUnitInterval;
|
|
path.lineTo(width * unitWidth, height * (1.0 - unitHeight));
|
|
}
|
|
|
|
path.lineTo(width, height);
|
|
|
|
path.close();
|
|
|
|
paint.setColor(0xAA0000FF);
|
|
canvas.drawPath(path, paint);
|
|
|
|
paint.setStrokeWidth(1);
|
|
paint.setStyle(SkPaint::Style::kStroke_Style);
|
|
paint.setColor(0xAAFFFFFF);
|
|
|
|
if (maxInterval > kOneFrameMS) {
|
|
// Paint the horizontal markers
|
|
size_t frameMarkerCount = static_cast<size_t>(maxInterval / kOneFrameMS);
|
|
|
|
// Limit the number of markers displayed. After a certain point, the graph
|
|
// becomes crowded
|
|
if (frameMarkerCount > kMaxFrameMarkers) {
|
|
frameMarkerCount = 1;
|
|
}
|
|
|
|
for (size_t frameIndex = 0; frameIndex < frameMarkerCount; frameIndex++) {
|
|
const double frameHeight =
|
|
height * (1.0 - (UnitFrameInterval((frameIndex + 1) * kOneFrameMS) /
|
|
maxUnitInterval));
|
|
canvas.drawLine(0, frameHeight, width, frameHeight, paint);
|
|
}
|
|
}
|
|
|
|
// Paint the vertical marker
|
|
if (UnitFrameInterval(lastLap().InMillisecondsF()) > 1.0) {
|
|
// budget exceeded
|
|
paint.setColor(SK_ColorRED);
|
|
} else {
|
|
// within budget
|
|
paint.setColor(SK_ColorGREEN);
|
|
}
|
|
|
|
double sampleX = width * (static_cast<double>(_current_sample) / kMaxSamples);
|
|
paint.setStrokeWidth(3);
|
|
canvas.drawLine(sampleX, 0, sampleX, height, paint);
|
|
}
|
|
|
|
Stopwatch::~Stopwatch() = default;
|
|
|
|
} // namespace instrumentation
|
|
} // namespace flow
|