Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 24d4f27

Browse files
author
Jonah Williams
authored
[engine] changes to DlVertices::Builder and Stopwatch visualizer. (#57031)
Collection of changes to DlVertices::Builder and the stopwatch visualizer. At a high level: * improve performance of the stopwatch visualizer by pre-allocating storage (and sharing it across both visualizers), lookup up font once, and cache the debug frame rate used. Updates to use Dl types instead of SkTypes. * Change DlVerticesBuilder to allow storing the bounds and use that in the visualizer, since we already know them. Make FML_CHECKS into dchecks, as the dart:ui vertices will already bounds check correctly - so these should only be necessary for debugging engine changes.
1 parent ba7ad87 commit 24d4f27

13 files changed

+182
-122
lines changed

display_list/dl_vertices.cc

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ std::shared_ptr<DlVertices> DlVertices::Make(
4343
const SkPoint texture_coordinates[],
4444
const DlColor colors[],
4545
int index_count,
46-
const uint16_t indices[]) {
46+
const uint16_t indices[],
47+
const DlRect* bounds) {
4748
if (!vertices || vertex_count <= 0) {
4849
vertex_count = 0;
4950
texture_coordinates = nullptr;
@@ -75,6 +76,9 @@ std::shared_ptr<DlVertices> DlVertices::Make(
7576
if (indices) {
7677
builder.store_indices(indices);
7778
}
79+
if (bounds != nullptr) {
80+
builder.store_bounds(*bounds);
81+
}
7882

7983
return builder.build();
8084
}
@@ -223,53 +227,53 @@ static void store_points(char* dst, int offset, const float* src, int count) {
223227
}
224228

225229
void DlVertices::Builder::store_vertices(const SkPoint vertices[]) {
226-
FML_CHECK(is_valid());
227-
FML_CHECK(needs_vertices_);
230+
FML_DCHECK(is_valid());
231+
FML_DCHECK(needs_vertices_);
228232
char* pod = reinterpret_cast<char*>(vertices_.get());
229233
size_t bytes = vertices_->vertex_count_ * sizeof(vertices[0]);
230234
memcpy(pod + vertices_->vertices_offset_, vertices, bytes);
231235
needs_vertices_ = false;
232236
}
233237

234238
void DlVertices::Builder::store_vertices(const float vertices[]) {
235-
FML_CHECK(is_valid());
236-
FML_CHECK(needs_vertices_);
239+
FML_DCHECK(is_valid());
240+
FML_DCHECK(needs_vertices_);
237241
char* pod = reinterpret_cast<char*>(vertices_.get());
238242
store_points(pod, vertices_->vertices_offset_, vertices,
239243
vertices_->vertex_count_);
240244
needs_vertices_ = false;
241245
}
242246

243247
void DlVertices::Builder::store_texture_coordinates(const SkPoint coords[]) {
244-
FML_CHECK(is_valid());
245-
FML_CHECK(needs_texture_coords_);
248+
FML_DCHECK(is_valid());
249+
FML_DCHECK(needs_texture_coords_);
246250
char* pod = reinterpret_cast<char*>(vertices_.get());
247251
size_t bytes = vertices_->vertex_count_ * sizeof(coords[0]);
248252
memcpy(pod + vertices_->texture_coordinates_offset_, coords, bytes);
249253
needs_texture_coords_ = false;
250254
}
251255

252256
void DlVertices::Builder::store_texture_coordinates(const float coords[]) {
253-
FML_CHECK(is_valid());
254-
FML_CHECK(needs_texture_coords_);
257+
FML_DCHECK(is_valid());
258+
FML_DCHECK(needs_texture_coords_);
255259
char* pod = reinterpret_cast<char*>(vertices_.get());
256260
store_points(pod, vertices_->texture_coordinates_offset_, coords,
257261
vertices_->vertex_count_);
258262
needs_texture_coords_ = false;
259263
}
260264

261265
void DlVertices::Builder::store_colors(const DlColor colors[]) {
262-
FML_CHECK(is_valid());
263-
FML_CHECK(needs_colors_);
266+
FML_DCHECK(is_valid());
267+
FML_DCHECK(needs_colors_);
264268
char* pod = reinterpret_cast<char*>(vertices_.get());
265269
size_t bytes = vertices_->vertex_count_ * sizeof(colors[0]);
266270
memcpy(pod + vertices_->colors_offset_, colors, bytes);
267271
needs_colors_ = false;
268272
}
269273

270274
void DlVertices::Builder::store_colors(const uint32_t colors[]) {
271-
FML_CHECK(is_valid());
272-
FML_CHECK(needs_colors_);
275+
FML_DCHECK(is_valid());
276+
FML_DCHECK(needs_colors_);
273277
char* pod = reinterpret_cast<char*>(vertices_.get());
274278
DlColor* dlcolors_ptr =
275279
reinterpret_cast<DlColor*>(pod + vertices_->colors_offset_);
@@ -280,29 +284,37 @@ void DlVertices::Builder::store_colors(const uint32_t colors[]) {
280284
}
281285

282286
void DlVertices::Builder::store_indices(const uint16_t indices[]) {
283-
FML_CHECK(is_valid());
284-
FML_CHECK(needs_indices_);
287+
FML_DCHECK(is_valid());
288+
FML_DCHECK(needs_indices_);
285289
char* pod = reinterpret_cast<char*>(vertices_.get());
286290
size_t bytes = vertices_->index_count_ * sizeof(indices[0]);
287291
memcpy(pod + vertices_->indices_offset_, indices, bytes);
288292
needs_indices_ = false;
289293
}
290294

295+
void DlVertices::Builder::store_bounds(DlRect bounds) {
296+
vertices_->bounds_ = SkRect::MakeLTRB(bounds.GetLeft(), bounds.GetTop(),
297+
bounds.GetRight(), bounds.GetBottom());
298+
needs_bounds_ = false;
299+
}
300+
291301
std::shared_ptr<DlVertices> DlVertices::Builder::build() {
292-
FML_CHECK(is_valid());
302+
FML_DCHECK(is_valid());
293303
if (vertices_->vertex_count() <= 0) {
294304
// We set this to true in the constructor to make sure that they
295305
// call store_vertices() only once, but if there are no vertices
296306
// then we will not object to them never having stored any vertices
297307
needs_vertices_ = false;
298308
}
299-
FML_CHECK(!needs_vertices_);
300-
FML_CHECK(!needs_texture_coords_);
301-
FML_CHECK(!needs_colors_);
302-
FML_CHECK(!needs_indices_);
303-
304-
vertices_->bounds_ =
305-
compute_bounds(vertices_->vertices(), vertices_->vertex_count_);
309+
FML_DCHECK(!needs_vertices_);
310+
FML_DCHECK(!needs_texture_coords_);
311+
FML_DCHECK(!needs_colors_);
312+
FML_DCHECK(!needs_indices_);
313+
314+
if (needs_bounds_) {
315+
vertices_->bounds_ =
316+
compute_bounds(vertices_->vertices(), vertices_->vertex_count_);
317+
}
306318

307319
return std::move(vertices_);
308320
}

display_list/dl_vertices.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ class DlVertices {
155155
/// promised by (index_count > 0).
156156
void store_indices(const uint16_t indices[]);
157157

158+
/// @brief Overwrite the internal bounds with a precomputed bounding rect.
159+
void store_bounds(DlRect bounds);
160+
158161
/// @brief Finalizes and the constructed DlVertices object.
159162
///
160163
/// fails if any of the optional data promised in the constructor is
@@ -167,6 +170,7 @@ class DlVertices {
167170
bool needs_texture_coords_;
168171
bool needs_colors_;
169172
bool needs_indices_;
173+
bool needs_bounds_ = true;
170174
};
171175

172176
//--------------------------------------------------------------------------
@@ -183,7 +187,8 @@ class DlVertices {
183187
const SkPoint texture_coordinates[],
184188
const DlColor colors[],
185189
int index_count = 0,
186-
const uint16_t indices[] = nullptr);
190+
const uint16_t indices[] = nullptr,
191+
const DlRect* bounds = nullptr);
187192

188193
/// Returns the size of the object including all of the inlined data.
189194
size_t size() const;

flow/layers/performance_overlay_layer.cc

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,26 +34,25 @@ void VisualizeStopWatch(DlCanvas* canvas,
3434
bool show_graph,
3535
bool show_labels,
3636
const std::string& label_prefix,
37-
const std::string& font_path) {
37+
std::vector<DlPoint>& point_storage,
38+
std::vector<DlColor>& color_storage,
39+
const SkFont& font) {
3840
const int label_x = 8; // distance from x
3941
const int label_y = -10; // distance from y+height
4042

4143
if (show_graph) {
42-
SkRect visualization_rect = SkRect::MakeXYWH(x, y, width, height);
43-
std::unique_ptr<StopwatchVisualizer> visualizer;
44-
44+
DlRect visualization_rect = DlRect::MakeXYWH(x, y, width, height);
4545
if (impeller_enabled) {
46-
visualizer = std::make_unique<DlStopwatchVisualizer>(stopwatch);
46+
DlStopwatchVisualizer(stopwatch, point_storage, color_storage)
47+
.Visualize(canvas, visualization_rect);
4748
} else {
48-
visualizer = std::make_unique<SkStopwatchVisualizer>(stopwatch);
49+
SkStopwatchVisualizer(stopwatch).Visualize(canvas, visualization_rect);
4950
}
50-
51-
visualizer->Visualize(canvas, visualization_rect);
5251
}
5352

5453
if (show_labels) {
55-
auto text = PerformanceOverlayLayer::MakeStatisticsText(
56-
stopwatch, label_prefix, font_path);
54+
auto text = PerformanceOverlayLayer::MakeStatisticsText(stopwatch, font,
55+
label_prefix);
5756
// Historically SK_ColorGRAY (== 0xFF888888) was used here
5857
DlPaint paint(DlColor(0xFF888888));
5958
#ifdef IMPELLER_SUPPORTS_RENDERING
@@ -69,24 +68,28 @@ void VisualizeStopWatch(DlCanvas* canvas,
6968

7069
} // namespace
7170

72-
sk_sp<SkTextBlob> PerformanceOverlayLayer::MakeStatisticsText(
73-
const Stopwatch& stopwatch,
74-
const std::string& label_prefix,
75-
const std::string& font_path) {
76-
SkFont font;
71+
// static
72+
SkFont PerformanceOverlayLayer::MakeStatisticsFont(std::string_view font_path) {
7773
sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
7874
if (font_path == "") {
7975
if (sk_sp<SkTypeface> face = font_mgr->matchFamilyStyle(nullptr, {})) {
80-
font = SkFont(face, 15);
76+
return SkFont(face, 15);
8177
} else {
8278
// In Skia's Android fontmgr, matchFamilyStyle can return null instead
8379
// of falling back to a default typeface. If that's the case, we can use
8480
// legacyMakeTypeface, which *does* use that default typeface.
85-
font = SkFont(font_mgr->legacyMakeTypeface(nullptr, {}), 15);
81+
return SkFont(font_mgr->legacyMakeTypeface(nullptr, {}), 15);
8682
}
8783
} else {
88-
font = SkFont(font_mgr->makeFromFile(font_path.c_str()), 15);
84+
return SkFont(font_mgr->makeFromFile(font_path.data()), 15);
8985
}
86+
}
87+
88+
// static
89+
sk_sp<SkTextBlob> PerformanceOverlayLayer::MakeStatisticsText(
90+
const Stopwatch& stopwatch,
91+
const SkFont& font,
92+
std::string_view label_prefix) {
9093
// Make sure there's not an empty typeface returned, or we won't see any text.
9194
FML_DCHECK(font.getTypeface()->countGlyphs() > 0);
9295

@@ -134,16 +137,22 @@ void PerformanceOverlayLayer::Paint(PaintContext& context) const {
134137
SkScalar width = paint_bounds().width() - (padding * 2);
135138
SkScalar height = paint_bounds().height() / 2;
136139
auto mutator = context.state_stack.save();
140+
// Cached storage for vertex output.
141+
std::vector<DlPoint> vertices_storage;
142+
std::vector<DlColor> color_storage;
143+
SkFont font = MakeStatisticsFont(font_path_);
137144

138-
VisualizeStopWatch(
139-
context.canvas, context.impeller_enabled, context.raster_time, x, y,
140-
width, height - padding, options_ & kVisualizeRasterizerStatistics,
141-
options_ & kDisplayRasterizerStatistics, "Raster", font_path_);
145+
VisualizeStopWatch(context.canvas, context.impeller_enabled,
146+
context.raster_time, x, y, width, height - padding,
147+
options_ & kVisualizeRasterizerStatistics,
148+
options_ & kDisplayRasterizerStatistics, "Raster",
149+
vertices_storage, color_storage, font);
142150

143151
VisualizeStopWatch(context.canvas, context.impeller_enabled, context.ui_time,
144152
x, y + height, width, height - padding,
145153
options_ & kVisualizeEngineStatistics,
146-
options_ & kDisplayEngineStatistics, "UI", font_path_);
154+
options_ & kDisplayEngineStatistics, "UI",
155+
vertices_storage, color_storage, font);
147156
}
148157

149158
} // namespace flutter

flow/layers/performance_overlay_layer.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ const int kVisualizeEngineStatistics = 1 << 3;
2222

2323
class PerformanceOverlayLayer : public Layer {
2424
public:
25+
static SkFont MakeStatisticsFont(std::string_view font_path);
26+
2527
static sk_sp<SkTextBlob> MakeStatisticsText(const Stopwatch& stopwatch,
26-
const std::string& label_prefix,
27-
const std::string& font_path);
28+
const SkFont& font,
29+
std::string_view label_prefix);
2830

2931
bool IsReplacing(DiffContext* context, const Layer* layer) const override {
3032
return layer->as_performance_overlay_layer() != nullptr;

flow/layers/performance_overlay_layer_unittests.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ TEST_F(PerformanceOverlayLayerTest, SimpleRasterizerStatistics) {
199199
const SkRect layer_bounds = SkRect::MakeLTRB(0.0f, 0.0f, 64.0f, 64.0f);
200200
const uint64_t overlay_opts = kDisplayRasterizerStatistics;
201201
auto layer = std::make_shared<PerformanceOverlayLayer>(overlay_opts);
202+
auto font = PerformanceOverlayLayer::MakeStatisticsFont("");
202203

203204
// TODO(): Note calling code has to call set_paint_bounds right now. Make
204205
// this a constructor parameter and move the set_paint_bounds into Preroll
@@ -210,7 +211,7 @@ TEST_F(PerformanceOverlayLayerTest, SimpleRasterizerStatistics) {
210211

211212
layer->Paint(display_list_paint_context());
212213
auto overlay_text = PerformanceOverlayLayer::MakeStatisticsText(
213-
display_list_paint_context().raster_time, "Raster", "");
214+
display_list_paint_context().raster_time, font, "Raster");
214215
auto overlay_text_data = overlay_text->serialize(SkSerialProcs{});
215216
// Historically SK_ColorGRAY (== 0xFF888888) was used here
216217
DlPaint text_paint(DlColor(0xFF888888));

flow/stopwatch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ class StopwatchVisualizer {
106106
///
107107
/// @param canvas The canvas to draw on.
108108
/// @param[in] rect The rectangle to draw in.
109-
virtual void Visualize(DlCanvas* canvas, const SkRect& rect) const = 0;
109+
virtual void Visualize(DlCanvas* canvas, const DlRect& rect) const = 0;
110110

111111
FML_DISALLOW_COPY_AND_ASSIGN(StopwatchVisualizer);
112112

0 commit comments

Comments
 (0)