提交 418ed6f6 编写于 作者: C Chinmay Garde

Allow visualizing engine and rasterizer statistics simultaneously

上级 60176eb6
...@@ -36,6 +36,15 @@ void CompositorOptions::setEnabled(Option option, bool enabled) { ...@@ -36,6 +36,15 @@ void CompositorOptions::setEnabled(Option option, bool enabled) {
} }
} }
bool CompositorOptions::anyEnabled() const {
for (auto enabled : options_) {
if (enabled) {
return true;
}
}
return false;
}
CompositorOptions::~CompositorOptions() { CompositorOptions::~CompositorOptions() {
} }
......
...@@ -16,8 +16,10 @@ class CompositorOptions { ...@@ -16,8 +16,10 @@ class CompositorOptions {
public: public:
using OptionType = unsigned int; using OptionType = unsigned int;
enum class Option : OptionType { enum class Option : OptionType {
DisplayFrameStatistics, DisplayRasterizerStatistics,
VisualizeFrameStatistics, VisualizeRasterizerStatistics,
DisplayEngineStatistics,
VisualizeEngineStatistics,
TerminationSentinel, TerminationSentinel,
}; };
...@@ -29,6 +31,8 @@ class CompositorOptions { ...@@ -29,6 +31,8 @@ class CompositorOptions {
bool isEnabled(Option option) const; bool isEnabled(Option option) const;
bool anyEnabled() const;
void setEnabled(Option option, bool enabled); void setEnabled(Option option, bool enabled);
private: private:
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "sky/compositor/instrumentation.h" #include "sky/compositor/instrumentation.h"
#include <algorithm>
#include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkPath.h"
namespace sky { namespace sky {
...@@ -11,8 +14,7 @@ namespace instrumentation { ...@@ -11,8 +14,7 @@ namespace instrumentation {
static const size_t kMaxSamples = 120; static const size_t kMaxSamples = 120;
Stopwatch::Stopwatch() Stopwatch::Stopwatch() : _start(base::TimeTicks::Now()), _current_sample(0) {
: _start(base::TimeTicks::Now()), _lastLap(), _current_sample(0) {
const base::TimeDelta delta; const base::TimeDelta delta;
_laps.resize(kMaxSamples, delta); _laps.resize(kMaxSamples, delta);
} }
...@@ -23,8 +25,12 @@ void Stopwatch::start() { ...@@ -23,8 +25,12 @@ void Stopwatch::start() {
} }
void Stopwatch::stop() { void Stopwatch::stop() {
_lastLap = base::TimeTicks::Now() - _start; _laps[_current_sample] = base::TimeTicks::Now() - _start;
_laps[_current_sample] = _lastLap; }
void Stopwatch::setLapTime(const base::TimeDelta& delta) {
_current_sample = (_current_sample + 1) % kMaxSamples;
_laps[_current_sample] = delta;
} }
static inline constexpr double UnitFrameInterval(double frameTimeMS) { static inline constexpr double UnitFrameInterval(double frameTimeMS) {
...@@ -32,8 +38,6 @@ static inline constexpr double UnitFrameInterval(double frameTimeMS) { ...@@ -32,8 +38,6 @@ static inline constexpr double UnitFrameInterval(double frameTimeMS) {
} }
void Stopwatch::visualize(SkCanvas& canvas, const SkRect& rect) const { void Stopwatch::visualize(SkCanvas& canvas, const SkRect& rect) const {
SkAutoCanvasRestore save(&canvas, false);
SkPaint paint; SkPaint paint;
// Paint the background // Paint the background
...@@ -45,15 +49,16 @@ void Stopwatch::visualize(SkCanvas& canvas, const SkRect& rect) const { ...@@ -45,15 +49,16 @@ void Stopwatch::visualize(SkCanvas& canvas, const SkRect& rect) const {
auto width = rect.width(); auto width = rect.width();
auto height = rect.height(); auto height = rect.height();
auto unitHeight = (1.0 - UnitFrameInterval(_laps[0].InMillisecondsF())); auto unitHeight =
std::min(1.0, UnitFrameInterval(_laps[0].InMillisecondsF()));
path.moveTo(0, height); path.moveTo(0, height);
path.lineTo(0, height * unitHeight); path.lineTo(0, height * (1.0 - unitHeight));
for (size_t i = 0; i < kMaxSamples; i++) { for (size_t i = 0; i < kMaxSamples; i++) {
double unitWidth = (static_cast<double>(i + 1) / kMaxSamples); double unitWidth = (static_cast<double>(i + 1) / kMaxSamples);
unitHeight = (1.0 - UnitFrameInterval(_laps[i].InMillisecondsF())); unitHeight = std::min(1.0, UnitFrameInterval(_laps[i].InMillisecondsF()));
path.lineTo(width * unitWidth, height * unitHeight); path.lineTo(width * unitWidth, height * (1.0 - unitHeight));
} }
path.lineTo(width, height); path.lineTo(width, height);
...@@ -64,7 +69,14 @@ void Stopwatch::visualize(SkCanvas& canvas, const SkRect& rect) const { ...@@ -64,7 +69,14 @@ void Stopwatch::visualize(SkCanvas& canvas, const SkRect& rect) const {
canvas.drawPath(path, paint); canvas.drawPath(path, paint);
// Paint the marker // Paint the marker
paint.setColor(0xFF00FF00); if (UnitFrameInterval(_laps[_current_sample].InMillisecondsF()) > 1.0) {
// budget exceeded
paint.setColor(SK_ColorRED);
} else {
// within budget
paint.setColor(SK_ColorGREEN);
}
paint.setStrokeWidth(3); paint.setStrokeWidth(3);
paint.setStyle(SkPaint::Style::kStroke_Style); paint.setStyle(SkPaint::Style::kStroke_Style);
auto sampleX = width * (static_cast<double>(_current_sample) / kMaxSamples); auto sampleX = width * (static_cast<double>(_current_sample) / kMaxSamples);
......
...@@ -33,7 +33,7 @@ class Stopwatch { ...@@ -33,7 +33,7 @@ class Stopwatch {
explicit Stopwatch(); explicit Stopwatch();
~Stopwatch(); ~Stopwatch();
const base::TimeDelta& lastLap() const { return _lastLap; } const base::TimeDelta& lastLap() const { return _laps[_current_sample]; }
base::TimeDelta currentLap() const { return base::TimeTicks::Now() - _start; } base::TimeDelta currentLap() const { return base::TimeTicks::Now() - _start; }
...@@ -43,10 +43,11 @@ class Stopwatch { ...@@ -43,10 +43,11 @@ class Stopwatch {
void stop(); void stop();
void setLapTime(const base::TimeDelta& delta);
private: private:
base::TimeTicks _start; base::TimeTicks _start;
std::vector<base::TimeDelta> _laps; std::vector<base::TimeDelta> _laps;
base::TimeDelta _lastLap;
size_t _current_sample; size_t _current_sample;
DISALLOW_COPY_AND_ASSIGN(Stopwatch); DISALLOW_COPY_AND_ASSIGN(Stopwatch);
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <memory> #include <memory>
#include "base/macros.h" #include "base/macros.h"
#include "base/time/time.h"
#include "sky/compositor/layer.h" #include "sky/compositor/layer.h"
#include "third_party/skia/include/core/SkSize.h" #include "third_party/skia/include/core/SkSize.h"
...@@ -29,10 +30,20 @@ class LayerTree { ...@@ -29,10 +30,20 @@ class LayerTree {
void set_frame_size(const SkISize& frame_size) { frame_size_ = frame_size; } void set_frame_size(const SkISize& frame_size) { frame_size_ = frame_size; }
void set_construction_time(const base::TimeDelta& delta) {
construction_time_ = delta;
}
const base::TimeDelta& construction_time() const {
return construction_time_;
}
private: private:
SkISize frame_size_; // Physical pixels. SkISize frame_size_; // Physical pixels.
std::unique_ptr<Layer> root_layer_; std::unique_ptr<Layer> root_layer_;
base::TimeDelta construction_time_;
DISALLOW_COPY_AND_ASSIGN(LayerTree); DISALLOW_COPY_AND_ASSIGN(LayerTree);
}; };
......
...@@ -24,7 +24,7 @@ class PaintContext { ...@@ -24,7 +24,7 @@ class PaintContext {
public: public:
SkCanvas& canvas() { return *canvas_; } SkCanvas& canvas() { return *canvas_; }
const PaintContext& context() const { return context_; } PaintContext& context() const { return context_; }
ScopedFrame(ScopedFrame&& frame); ScopedFrame(ScopedFrame&& frame);
...@@ -59,9 +59,12 @@ class PaintContext { ...@@ -59,9 +59,12 @@ class PaintContext {
const instrumentation::Stopwatch& frame_time() const { return frame_time_; } const instrumentation::Stopwatch& frame_time() const { return frame_time_; }
instrumentation::Stopwatch& engine_time() { return engine_time_; };
private: private:
instrumentation::Counter frame_count_; instrumentation::Counter frame_count_;
instrumentation::Stopwatch frame_time_; instrumentation::Stopwatch frame_time_;
instrumentation::Stopwatch engine_time_;
void beginFrame(ScopedFrame& frame); void beginFrame(ScopedFrame& frame);
void endFrame(ScopedFrame& frame); void endFrame(ScopedFrame& frame);
......
...@@ -26,29 +26,57 @@ static void PaintContext_DrawStatisticsText(SkCanvas& canvas, ...@@ -26,29 +26,57 @@ static void PaintContext_DrawStatisticsText(SkCanvas& canvas,
canvas.drawText(string.c_str(), string.size(), x, y, paint); canvas.drawText(string.c_str(), string.size(), x, y, paint);
} }
void StatisticsLayer::Paint(PaintContext::ScopedFrame& frame) { static void VisualizeStopWatch(SkCanvas& canvas,
const instrumentation::Stopwatch& stopwatch,
SkScalar width,
bool show_graph,
bool show_labels,
std::string label_prefix) {
const int x = 8; const int x = 8;
int y = 70; const int y = 70;
static const int kLineSpacing = 18; const int height = 80;
const PaintContext& context = frame.context();
if (options_.isEnabled(CompositorOptions::Option::VisualizeFrameStatistics)) { if (show_graph) {
SkRect visualizationRect = SkRect::MakeWH(paint_bounds().width(), 80); SkRect visualizationRect = SkRect::MakeWH(width, height);
context.frame_time().visualize(frame.canvas(), visualizationRect); stopwatch.visualize(canvas, visualizationRect);
} }
if (options_.isEnabled(CompositorOptions::Option::DisplayFrameStatistics)) { if (show_labels) {
double msPerFrame = context.frame_time().lastLap().InMillisecondsF(); double msPerFrame = stopwatch.lastLap().InMillisecondsF();
double fps = 1e3 / msPerFrame; double fps = 1e3 / msPerFrame;
std::stringstream stream; std::stringstream stream;
stream.setf(std::ios::fixed | std::ios::showpoint); stream.setf(std::ios::fixed | std::ios::showpoint);
stream << std::setprecision(2); stream << std::setprecision(2);
stream << fps << " FPS | " << msPerFrame << "ms/frame"; stream << label_prefix << " " << fps << " FPS | " << msPerFrame
PaintContext_DrawStatisticsText(frame.canvas(), stream.str(), x, y); << "ms/frame";
y += kLineSpacing; PaintContext_DrawStatisticsText(canvas, stream.str(), x, y);
}
if (show_labels || show_graph) {
canvas.translate(0, height);
}
}
void StatisticsLayer::Paint(PaintContext::ScopedFrame& frame) {
if (!options_.anyEnabled()) {
return;
} }
using Opt = CompositorOptions::Option;
SkScalar width = paint_bounds().width();
SkAutoCanvasRestore save(&frame.canvas(), false);
VisualizeStopWatch(frame.canvas(), frame.context().frame_time(), width,
options_.isEnabled(Opt::VisualizeRasterizerStatistics),
options_.isEnabled(Opt::DisplayRasterizerStatistics),
"Rasterizer");
VisualizeStopWatch(frame.canvas(), frame.context().engine_time(), width,
options_.isEnabled(Opt::VisualizeEngineStatistics),
options_.isEnabled(Opt::DisplayEngineStatistics),
"Engine");
} }
} // namespace compositor } // namespace compositor
......
...@@ -52,6 +52,11 @@ void Rasterizer::Draw(scoped_ptr<compositor::LayerTree> layer_tree) { ...@@ -52,6 +52,11 @@ void Rasterizer::Draw(scoped_ptr<compositor::LayerTree> layer_tree) {
if (surface_->GetSize() != size) if (surface_->GetSize() != size)
surface_->Resize(size); surface_->Resize(size);
// There is no way for the compositor to know how long the layer tree
// construction took. Fortunately, the layer tree does. Grab that time
// for instrumentation.
paint_context_.engine_time().setLapTime(layer_tree->construction_time());
// Use the canvas from the Ganesh Surface to render the current frame into // Use the canvas from the Ganesh Surface to render the current frame into
{ {
EnsureGLContext(); EnsureGLContext();
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/threading/worker_pool.h" #include "base/threading/worker_pool.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "mojo/data_pipe_utils/data_pipe_utils.h" #include "mojo/data_pipe_utils/data_pipe_utils.h"
#include "mojo/public/cpp/application/connect.h" #include "mojo/public/cpp/application/connect.h"
...@@ -102,11 +103,13 @@ std::unique_ptr<compositor::LayerTree> Engine::BeginFrame( ...@@ -102,11 +103,13 @@ std::unique_ptr<compositor::LayerTree> Engine::BeginFrame(
if (!sky_view_) if (!sky_view_)
return nullptr; return nullptr;
auto begin_time = base::TimeTicks::Now();
std::unique_ptr<compositor::LayerTree> layer_tree = std::unique_ptr<compositor::LayerTree> layer_tree =
sky_view_->BeginFrame(frame_time); sky_view_->BeginFrame(frame_time);
if (layer_tree) { if (layer_tree) {
layer_tree->set_frame_size(SkISize::Make(physical_size_.width(), layer_tree->set_frame_size(
physical_size_.height())); SkISize::Make(physical_size_.width(), physical_size_.height()));
layer_tree->set_construction_time(base::TimeTicks::Now() - begin_time);
} }
return layer_tree; return layer_tree;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册