forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstopwatch_dl.cc
153 lines (131 loc) · 5.09 KB
/
stopwatch_dl.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Copyright 2013 The Flutter 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 "flutter/flow/stopwatch_dl.h"
#include <memory>
#include <vector>
#include "display_list/dl_blend_mode.h"
#include "display_list/dl_canvas.h"
#include "display_list/dl_color.h"
#include "display_list/dl_paint.h"
#include "display_list/dl_vertices.h"
#include "include/core/SkRect.h"
namespace flutter {
static const size_t kMaxSamples = 120;
static const size_t kMaxFrameMarkers = 8;
void DlStopwatchVisualizer::Visualize(DlCanvas* canvas,
const SkRect& rect) const {
auto painter = DlVertexPainter();
DlPaint paint;
// Establish the graph position.
auto const x = rect.x();
auto const y = rect.y();
auto const width = rect.width();
auto const height = rect.height();
auto const bottom = rect.bottom();
// Scale the graph to show time frames up to those that are 3x the frame time.
auto const one_frame_ms = GetFrameBudget().count();
auto const max_interval = one_frame_ms * 3.0;
auto const max_unit_interval = UnitFrameInterval(max_interval);
auto const sample_unit_width = (1.0 / kMaxSamples);
// Provide a semi-transparent background for the graph.
painter.DrawRect(rect, DlColor(0x99FFFFFF));
// Prepare a path for the data; we start at the height of the last point so
// it looks like we wrap around.
{
for (auto i = size_t(0); i < stopwatch_.GetLapsCount(); i++) {
auto const sample_unit_height =
(1.0 - UnitHeight(stopwatch_.GetLap(i).ToMillisecondsF(),
max_unit_interval));
auto const bar_width = width * sample_unit_width;
auto const bar_height = height * sample_unit_height;
auto const bar_left = x + width * sample_unit_width * i;
painter.DrawRect(SkRect::MakeLTRB(/*l=*/bar_left,
/*t=*/y + bar_height,
/*r=*/bar_left + bar_width,
/*b=*/bottom),
DlColor(0xAA0000FF));
}
}
// Draw horizontal frame markers.
{
if (max_interval > one_frame_ms) {
// Paint the horizontal markers.
auto count = static_cast<size_t>(max_interval / one_frame_ms);
// Limit the number of markers to a reasonable amount.
if (count > kMaxFrameMarkers) {
count = 1;
}
for (auto i = size_t(0); i < count; i++) {
auto const frame_height =
height * (1.0 - (UnitFrameInterval(i + 1) * one_frame_ms) /
max_unit_interval);
// Draw a skinny rectangle (i.e. a line).
painter.DrawRect(SkRect::MakeLTRB(/*l=*/x,
/*t=*/y + frame_height,
/*r=*/width,
/*b=*/y + frame_height + 1),
DlColor(0xCC000000));
}
}
}
// Paint the vertical marker for the current frame.
{
DlColor color = DlColor::kGreen();
if (UnitFrameInterval(stopwatch_.LastLap().ToMillisecondsF()) > 1.0) {
// budget exceeded.
color = DlColor::kRed();
}
auto const l =
x + width * (static_cast<double>(stopwatch_.GetCurrentSample()) /
kMaxSamples);
auto const t = y;
auto const r = l + width * sample_unit_width;
auto const b = rect.bottom();
painter.DrawRect(SkRect::MakeLTRB(l, t, r, b), color);
}
// Actually draw.
// Use kSrcOver blend mode so that elements under the performance overlay are
// partially visible.
paint.setBlendMode(DlBlendMode::kSrcOver);
// The second blend mode does nothing since the paint has no additional color
// sources like a tiled image or gradient.
canvas->DrawVertices(painter.IntoVertices(), DlBlendMode::kSrcOver, paint);
}
void DlVertexPainter::DrawRect(const SkRect& rect, const DlColor& color) {
// Draw 6 vertices representing 2 triangles.
auto const left = rect.x();
auto const top = rect.y();
auto const right = rect.right();
auto const bottom = rect.bottom();
auto const vertices = std::array<SkPoint, 6>{
SkPoint::Make(left, top), // tl tr
SkPoint::Make(right, top), // br
SkPoint::Make(right, bottom), //
SkPoint::Make(right, bottom), // tl
SkPoint::Make(left, bottom), // bl br
SkPoint::Make(left, top) //
};
auto const colors = std::array<DlColor, 6>{
color, // tl tr
color, // br
color, //
color, // tl
color, // bl br
color //
};
vertices_.insert(vertices_.end(), vertices.begin(), vertices.end());
colors_.insert(colors_.end(), colors.begin(), colors.end());
}
std::shared_ptr<DlVertices> DlVertexPainter::IntoVertices() {
auto const result = DlVertices::Make(
/*mode=*/DlVertexMode::kTriangles,
/*vertex_count=*/vertices_.size(),
/*vertices=*/vertices_.data(),
/*texture_coordinates=*/nullptr,
/*colors=*/colors_.data());
vertices_.clear();
colors_.clear();
return result;
}
} // namespace flutter