Flutter Engine
 
Loading...
Searching...
No Matches
stopwatch_dl.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <memory>
8#include <vector>
9
15
16namespace flutter {
17
18static const size_t kMaxSamples = 120;
19static const size_t kMaxFrameMarkers = 8;
20
22 const DlRect& rect) const {
23 DlVertexPainter painter(vertices_storage_, color_storage_);
24 DlPaint paint;
25
26 // Establish the graph position.
27 const DlScalar x = rect.GetX();
28 const DlScalar y = rect.GetY();
29 const DlScalar width = rect.GetWidth();
30 const DlScalar height = rect.GetHeight();
31 const DlScalar bottom = rect.GetBottom();
32
33 // Scale the graph to show time frames up to those that are 3x the frame time.
34 const DlScalar one_frame_ms = GetFrameBudget().count();
35 const DlScalar max_interval = one_frame_ms * 3.0;
36 const DlScalar max_unit_interval = UnitFrameInterval(max_interval);
37 const DlScalar sample_unit_width = width / kMaxSamples;
38
39 // resize backing storage to match expected lap count.
40 size_t required_storage =
42 if (vertices_storage_.size() < required_storage) {
43 vertices_storage_.resize(required_storage);
44 color_storage_.resize(required_storage);
45 }
46
47 // Provide a semi-transparent background for the graph.
48 painter.DrawRect(rect, DlColor(0x99FFFFFF));
49
50 // Prepare a path for the data; we start at the height of the last point so
51 // it looks like we wrap around.
52 {
53 DlScalar bar_left = x;
54 for (size_t i = 0u; i < stopwatch_.GetLapsCount(); i++) {
55 const double time_ms = stopwatch_.GetLap(i).ToMillisecondsF();
56 const DlScalar sample_unit_height = static_cast<DlScalar>(
57 height * UnitHeight(time_ms, max_unit_interval));
58
59 const DlScalar bar_top = bottom - sample_unit_height;
60 const DlScalar bar_right = x + (i + 1) * sample_unit_width;
61
62 painter.DrawRect(DlRect::MakeLTRB(/*left=*/bar_left,
63 /*top=*/bar_top,
64 /*right=*/bar_right,
65 /*bottom=*/bottom),
66 DlColor(0xAA0000FF));
67 bar_left = bar_right;
68 }
69 }
70
71 // Draw horizontal frame markers.
72 {
73 if (max_interval > one_frame_ms) {
74 // Paint the horizontal markers.
75 size_t count = static_cast<size_t>(max_interval / one_frame_ms);
76
77 // Limit the number of markers to a reasonable amount.
78 if (count > kMaxFrameMarkers) {
79 count = 1;
80 }
81
82 for (uint32_t i = 0u; i < count; i++) {
83 const DlScalar frame_height =
84 height * (1.0 - (UnitFrameInterval(i + 1) * one_frame_ms) /
85 max_unit_interval);
86
87 // Draw a skinny rectangle (i.e. a line).
88 painter.DrawRect(DlRect::MakeLTRB(/*left=*/x,
89 /*top=*/y + frame_height,
90 /*right=*/x + width,
91 /*bottom=*/y + frame_height + 1),
92 DlColor(0xCC000000));
93 }
94 }
95 }
96
97 // Paint the vertical marker for the current frame.
98 {
99 DlColor color = DlColor::kGreen();
101 // budget exceeded.
102 color = DlColor::kRed();
103 }
104 size_t sample =
106 const DlScalar l = x + sample * sample_unit_width;
107 const DlScalar t = y;
108 const DlScalar r = l + sample_unit_width;
109 const DlScalar b = rect.GetBottom();
110 painter.DrawRect(DlRect::MakeLTRB(l, t, r, b), color);
111 }
112
113 // Actually draw.
114 // Use kSrcOver blend mode so that elements under the performance overlay are
115 // partially visible.
116 paint.setBlendMode(DlBlendMode::kSrcOver);
117 // The second blend mode does nothing since the paint has no additional color
118 // sources like a tiled image or gradient.
119 canvas->DrawVertices(painter.IntoVertices(rect), DlBlendMode::kSrcOver,
120 paint);
121}
122
123DlVertexPainter::DlVertexPainter(std::vector<DlPoint>& vertices_storage,
124 std::vector<DlColor>& color_storage)
125 : vertices_(vertices_storage), colors_(color_storage) {}
126
127void DlVertexPainter::DrawRect(const DlRect& rect, const DlColor& color) {
128 const DlScalar left = rect.GetLeft();
129 const DlScalar top = rect.GetTop();
130 const DlScalar right = rect.GetRight();
131 const DlScalar bottom = rect.GetBottom();
132
133 FML_DCHECK(6 + colors_offset_ <= vertices_.size());
134 FML_DCHECK(6 + colors_offset_ <= colors_.size());
135
136 // Draw 6 vertices representing 2 triangles.
137 vertices_[vertices_offset_++] = DlPoint(left, top); // tl tr
138 vertices_[vertices_offset_++] = DlPoint(right, top); // br
139 vertices_[vertices_offset_++] = DlPoint(right, bottom); //
140 vertices_[vertices_offset_++] = DlPoint(right, bottom); // tl
141 vertices_[vertices_offset_++] = DlPoint(left, bottom); // bl br
142 vertices_[vertices_offset_++] = DlPoint(left, top); //
143 for (size_t i = 0u; i < 6u; i++) {
144 colors_[colors_offset_++] = color;
145 }
146}
147
148std::shared_ptr<DlVertices> DlVertexPainter::IntoVertices(
149 const DlRect& bounds_rect) {
150 return DlVertices::Make(
152 /*vertex_count=*/vertices_.size(),
153 /*vertices=*/vertices_.data(),
154 /*texture_coordinates=*/nullptr,
155 /*colors=*/colors_.data(),
156 /*index_count=*/0,
157 /*indices=*/nullptr,
158 /*bounds=*/&bounds_rect);
159}
160
161} // namespace flutter
Developer-facing API for rendering anything within the engine.
Definition dl_canvas.h:32
virtual void DrawVertices(const std::shared_ptr< DlVertices > &vertices, DlBlendMode mode, const DlPaint &paint)=0
DlPaint & setBlendMode(DlBlendMode mode)
Definition dl_paint.h:85
void Visualize(DlCanvas *canvas, const DlRect &rect) const override
Renders the stopwatch as a graph.
Provides canvas-like painting methods that actually build vertices.
std::shared_ptr< DlVertices > IntoVertices(const DlRect &bounds_rect)
void DrawRect(const DlRect &rect, const DlColor &color)
Draws a rectangle with the given color to a buffer.
DlVertexPainter(std::vector< DlPoint > &vertices_storage, std::vector< DlColor > &color_storage)
static std::shared_ptr< DlVertices > Make(DlVertexMode mode, int vertex_count, const DlPoint vertices[], const DlPoint texture_coordinates[], const DlColor colors[], int index_count=0, const uint16_t indices[]=nullptr, const DlRect *bounds=nullptr)
Constructs a DlVector with compact inline storage for all of its required and optional lists of data.
const fml::TimeDelta & GetLap(size_t index) const
Definition stopwatch.cc:42
const fml::TimeDelta & LastLap() const
Definition stopwatch.cc:38
size_t GetLapsCount() const
Return a reference to all the laps.
Definition stopwatch.cc:46
size_t GetCurrentSample() const
Definition stopwatch.cc:50
double UnitHeight(double time_ms, double max_height) const
Converts a raster time to a unit height.
Definition stopwatch.cc:58
const Stopwatch & stopwatch_
Definition stopwatch.h:125
fml::Milliseconds GetFrameBudget() const
Definition stopwatch.h:123
double UnitFrameInterval(double time_ms) const
Converts a raster time to a unit interval.
Definition stopwatch.cc:54
constexpr double ToMillisecondsF() const
Definition time_delta.h:68
int32_t x
#define FML_DCHECK(condition)
Definition logging.h:122
double y
impeller::Scalar DlScalar
@ kTriangles
The vertices are taken 3 at a time to form a triangle.
static const size_t kMaxSamples
impeller::Point DlPoint
static const size_t kMaxFrameMarkers
int32_t height
int32_t width
static constexpr DlColor kRed()
Definition dl_color.h:71
static constexpr DlColor kGreen()
Definition dl_color.h:72
constexpr auto GetBottom() const
Definition rect.h:357
constexpr Type GetY() const
Returns the Y coordinate of the upper left corner, equivalent to |GetOrigin().y|.
Definition rect.h:337
constexpr auto GetTop() const
Definition rect.h:353
constexpr Type GetHeight() const
Returns the height of the rectangle, equivalent to |GetSize().height|.
Definition rect.h:347
constexpr auto GetLeft() const
Definition rect.h:351
constexpr Type GetX() const
Returns the X coordinate of the upper left corner, equivalent to |GetOrigin().x|.
Definition rect.h:333
constexpr auto GetRight() const
Definition rect.h:355
constexpr Type GetWidth() const
Returns the width of the rectangle, equivalent to |GetSize().width|.
Definition rect.h:341
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition rect.h:129