[engine] changes to DlVertices::Builder and Stopwatch visualizer. (flutter/engine#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.
diff --git a/engine/src/flutter/display_list/dl_vertices.cc b/engine/src/flutter/display_list/dl_vertices.cc
index f0cf5ae..5d32577 100644
--- a/engine/src/flutter/display_list/dl_vertices.cc
+++ b/engine/src/flutter/display_list/dl_vertices.cc
@@ -43,7 +43,8 @@
const SkPoint texture_coordinates[],
const DlColor colors[],
int index_count,
- const uint16_t indices[]) {
+ const uint16_t indices[],
+ const DlRect* bounds) {
if (!vertices || vertex_count <= 0) {
vertex_count = 0;
texture_coordinates = nullptr;
@@ -75,6 +76,9 @@
if (indices) {
builder.store_indices(indices);
}
+ if (bounds != nullptr) {
+ builder.store_bounds(*bounds);
+ }
return builder.build();
}
@@ -223,8 +227,8 @@
}
void DlVertices::Builder::store_vertices(const SkPoint vertices[]) {
- FML_CHECK(is_valid());
- FML_CHECK(needs_vertices_);
+ FML_DCHECK(is_valid());
+ FML_DCHECK(needs_vertices_);
char* pod = reinterpret_cast<char*>(vertices_.get());
size_t bytes = vertices_->vertex_count_ * sizeof(vertices[0]);
memcpy(pod + vertices_->vertices_offset_, vertices, bytes);
@@ -232,8 +236,8 @@
}
void DlVertices::Builder::store_vertices(const float vertices[]) {
- FML_CHECK(is_valid());
- FML_CHECK(needs_vertices_);
+ FML_DCHECK(is_valid());
+ FML_DCHECK(needs_vertices_);
char* pod = reinterpret_cast<char*>(vertices_.get());
store_points(pod, vertices_->vertices_offset_, vertices,
vertices_->vertex_count_);
@@ -241,8 +245,8 @@
}
void DlVertices::Builder::store_texture_coordinates(const SkPoint coords[]) {
- FML_CHECK(is_valid());
- FML_CHECK(needs_texture_coords_);
+ FML_DCHECK(is_valid());
+ FML_DCHECK(needs_texture_coords_);
char* pod = reinterpret_cast<char*>(vertices_.get());
size_t bytes = vertices_->vertex_count_ * sizeof(coords[0]);
memcpy(pod + vertices_->texture_coordinates_offset_, coords, bytes);
@@ -250,8 +254,8 @@
}
void DlVertices::Builder::store_texture_coordinates(const float coords[]) {
- FML_CHECK(is_valid());
- FML_CHECK(needs_texture_coords_);
+ FML_DCHECK(is_valid());
+ FML_DCHECK(needs_texture_coords_);
char* pod = reinterpret_cast<char*>(vertices_.get());
store_points(pod, vertices_->texture_coordinates_offset_, coords,
vertices_->vertex_count_);
@@ -259,8 +263,8 @@
}
void DlVertices::Builder::store_colors(const DlColor colors[]) {
- FML_CHECK(is_valid());
- FML_CHECK(needs_colors_);
+ FML_DCHECK(is_valid());
+ FML_DCHECK(needs_colors_);
char* pod = reinterpret_cast<char*>(vertices_.get());
size_t bytes = vertices_->vertex_count_ * sizeof(colors[0]);
memcpy(pod + vertices_->colors_offset_, colors, bytes);
@@ -268,8 +272,8 @@
}
void DlVertices::Builder::store_colors(const uint32_t colors[]) {
- FML_CHECK(is_valid());
- FML_CHECK(needs_colors_);
+ FML_DCHECK(is_valid());
+ FML_DCHECK(needs_colors_);
char* pod = reinterpret_cast<char*>(vertices_.get());
DlColor* dlcolors_ptr =
reinterpret_cast<DlColor*>(pod + vertices_->colors_offset_);
@@ -280,29 +284,37 @@
}
void DlVertices::Builder::store_indices(const uint16_t indices[]) {
- FML_CHECK(is_valid());
- FML_CHECK(needs_indices_);
+ FML_DCHECK(is_valid());
+ FML_DCHECK(needs_indices_);
char* pod = reinterpret_cast<char*>(vertices_.get());
size_t bytes = vertices_->index_count_ * sizeof(indices[0]);
memcpy(pod + vertices_->indices_offset_, indices, bytes);
needs_indices_ = false;
}
+void DlVertices::Builder::store_bounds(DlRect bounds) {
+ vertices_->bounds_ = SkRect::MakeLTRB(bounds.GetLeft(), bounds.GetTop(),
+ bounds.GetRight(), bounds.GetBottom());
+ needs_bounds_ = false;
+}
+
std::shared_ptr<DlVertices> DlVertices::Builder::build() {
- FML_CHECK(is_valid());
+ FML_DCHECK(is_valid());
if (vertices_->vertex_count() <= 0) {
// We set this to true in the constructor to make sure that they
// call store_vertices() only once, but if there are no vertices
// then we will not object to them never having stored any vertices
needs_vertices_ = false;
}
- FML_CHECK(!needs_vertices_);
- FML_CHECK(!needs_texture_coords_);
- FML_CHECK(!needs_colors_);
- FML_CHECK(!needs_indices_);
+ FML_DCHECK(!needs_vertices_);
+ FML_DCHECK(!needs_texture_coords_);
+ FML_DCHECK(!needs_colors_);
+ FML_DCHECK(!needs_indices_);
- vertices_->bounds_ =
- compute_bounds(vertices_->vertices(), vertices_->vertex_count_);
+ if (needs_bounds_) {
+ vertices_->bounds_ =
+ compute_bounds(vertices_->vertices(), vertices_->vertex_count_);
+ }
return std::move(vertices_);
}
diff --git a/engine/src/flutter/display_list/dl_vertices.h b/engine/src/flutter/display_list/dl_vertices.h
index ddbaa3f..8a3bed3 100644
--- a/engine/src/flutter/display_list/dl_vertices.h
+++ b/engine/src/flutter/display_list/dl_vertices.h
@@ -155,6 +155,9 @@
/// promised by (index_count > 0).
void store_indices(const uint16_t indices[]);
+ /// @brief Overwrite the internal bounds with a precomputed bounding rect.
+ void store_bounds(DlRect bounds);
+
/// @brief Finalizes and the constructed DlVertices object.
///
/// fails if any of the optional data promised in the constructor is
@@ -167,6 +170,7 @@
bool needs_texture_coords_;
bool needs_colors_;
bool needs_indices_;
+ bool needs_bounds_ = true;
};
//--------------------------------------------------------------------------
@@ -183,7 +187,8 @@
const SkPoint texture_coordinates[],
const DlColor colors[],
int index_count = 0,
- const uint16_t indices[] = nullptr);
+ const uint16_t indices[] = nullptr,
+ const DlRect* bounds = nullptr);
/// Returns the size of the object including all of the inlined data.
size_t size() const;
diff --git a/engine/src/flutter/flow/layers/performance_overlay_layer.cc b/engine/src/flutter/flow/layers/performance_overlay_layer.cc
index 63e41dd..7761faf 100644
--- a/engine/src/flutter/flow/layers/performance_overlay_layer.cc
+++ b/engine/src/flutter/flow/layers/performance_overlay_layer.cc
@@ -34,26 +34,25 @@
bool show_graph,
bool show_labels,
const std::string& label_prefix,
- const std::string& font_path) {
+ std::vector<DlPoint>& point_storage,
+ std::vector<DlColor>& color_storage,
+ const SkFont& font) {
const int label_x = 8; // distance from x
const int label_y = -10; // distance from y+height
if (show_graph) {
- SkRect visualization_rect = SkRect::MakeXYWH(x, y, width, height);
- std::unique_ptr<StopwatchVisualizer> visualizer;
-
+ DlRect visualization_rect = DlRect::MakeXYWH(x, y, width, height);
if (impeller_enabled) {
- visualizer = std::make_unique<DlStopwatchVisualizer>(stopwatch);
+ DlStopwatchVisualizer(stopwatch, point_storage, color_storage)
+ .Visualize(canvas, visualization_rect);
} else {
- visualizer = std::make_unique<SkStopwatchVisualizer>(stopwatch);
+ SkStopwatchVisualizer(stopwatch).Visualize(canvas, visualization_rect);
}
-
- visualizer->Visualize(canvas, visualization_rect);
}
if (show_labels) {
- auto text = PerformanceOverlayLayer::MakeStatisticsText(
- stopwatch, label_prefix, font_path);
+ auto text = PerformanceOverlayLayer::MakeStatisticsText(stopwatch, font,
+ label_prefix);
// Historically SK_ColorGRAY (== 0xFF888888) was used here
DlPaint paint(DlColor(0xFF888888));
#ifdef IMPELLER_SUPPORTS_RENDERING
@@ -69,24 +68,28 @@
} // namespace
-sk_sp<SkTextBlob> PerformanceOverlayLayer::MakeStatisticsText(
- const Stopwatch& stopwatch,
- const std::string& label_prefix,
- const std::string& font_path) {
- SkFont font;
+// static
+SkFont PerformanceOverlayLayer::MakeStatisticsFont(std::string_view font_path) {
sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
if (font_path == "") {
if (sk_sp<SkTypeface> face = font_mgr->matchFamilyStyle(nullptr, {})) {
- font = SkFont(face, 15);
+ return SkFont(face, 15);
} else {
// In Skia's Android fontmgr, matchFamilyStyle can return null instead
// of falling back to a default typeface. If that's the case, we can use
// legacyMakeTypeface, which *does* use that default typeface.
- font = SkFont(font_mgr->legacyMakeTypeface(nullptr, {}), 15);
+ return SkFont(font_mgr->legacyMakeTypeface(nullptr, {}), 15);
}
} else {
- font = SkFont(font_mgr->makeFromFile(font_path.c_str()), 15);
+ return SkFont(font_mgr->makeFromFile(font_path.data()), 15);
}
+}
+
+// static
+sk_sp<SkTextBlob> PerformanceOverlayLayer::MakeStatisticsText(
+ const Stopwatch& stopwatch,
+ const SkFont& font,
+ std::string_view label_prefix) {
// Make sure there's not an empty typeface returned, or we won't see any text.
FML_DCHECK(font.getTypeface()->countGlyphs() > 0);
@@ -134,16 +137,22 @@
SkScalar width = paint_bounds().width() - (padding * 2);
SkScalar height = paint_bounds().height() / 2;
auto mutator = context.state_stack.save();
+ // Cached storage for vertex output.
+ std::vector<DlPoint> vertices_storage;
+ std::vector<DlColor> color_storage;
+ SkFont font = MakeStatisticsFont(font_path_);
- VisualizeStopWatch(
- context.canvas, context.impeller_enabled, context.raster_time, x, y,
- width, height - padding, options_ & kVisualizeRasterizerStatistics,
- options_ & kDisplayRasterizerStatistics, "Raster", font_path_);
+ VisualizeStopWatch(context.canvas, context.impeller_enabled,
+ context.raster_time, x, y, width, height - padding,
+ options_ & kVisualizeRasterizerStatistics,
+ options_ & kDisplayRasterizerStatistics, "Raster",
+ vertices_storage, color_storage, font);
VisualizeStopWatch(context.canvas, context.impeller_enabled, context.ui_time,
x, y + height, width, height - padding,
options_ & kVisualizeEngineStatistics,
- options_ & kDisplayEngineStatistics, "UI", font_path_);
+ options_ & kDisplayEngineStatistics, "UI",
+ vertices_storage, color_storage, font);
}
} // namespace flutter
diff --git a/engine/src/flutter/flow/layers/performance_overlay_layer.h b/engine/src/flutter/flow/layers/performance_overlay_layer.h
index 5fd1c71..fa99a99 100644
--- a/engine/src/flutter/flow/layers/performance_overlay_layer.h
+++ b/engine/src/flutter/flow/layers/performance_overlay_layer.h
@@ -22,9 +22,11 @@
class PerformanceOverlayLayer : public Layer {
public:
+ static SkFont MakeStatisticsFont(std::string_view font_path);
+
static sk_sp<SkTextBlob> MakeStatisticsText(const Stopwatch& stopwatch,
- const std::string& label_prefix,
- const std::string& font_path);
+ const SkFont& font,
+ std::string_view label_prefix);
bool IsReplacing(DiffContext* context, const Layer* layer) const override {
return layer->as_performance_overlay_layer() != nullptr;
diff --git a/engine/src/flutter/flow/layers/performance_overlay_layer_unittests.cc b/engine/src/flutter/flow/layers/performance_overlay_layer_unittests.cc
index fa59d17..dafe53c 100644
--- a/engine/src/flutter/flow/layers/performance_overlay_layer_unittests.cc
+++ b/engine/src/flutter/flow/layers/performance_overlay_layer_unittests.cc
@@ -199,6 +199,7 @@
const SkRect layer_bounds = SkRect::MakeLTRB(0.0f, 0.0f, 64.0f, 64.0f);
const uint64_t overlay_opts = kDisplayRasterizerStatistics;
auto layer = std::make_shared<PerformanceOverlayLayer>(overlay_opts);
+ auto font = PerformanceOverlayLayer::MakeStatisticsFont("");
// TODO(): Note calling code has to call set_paint_bounds right now. Make
// this a constructor parameter and move the set_paint_bounds into Preroll
@@ -210,7 +211,7 @@
layer->Paint(display_list_paint_context());
auto overlay_text = PerformanceOverlayLayer::MakeStatisticsText(
- display_list_paint_context().raster_time, "Raster", "");
+ display_list_paint_context().raster_time, font, "Raster");
auto overlay_text_data = overlay_text->serialize(SkSerialProcs{});
// Historically SK_ColorGRAY (== 0xFF888888) was used here
DlPaint text_paint(DlColor(0xFF888888));
diff --git a/engine/src/flutter/flow/stopwatch.h b/engine/src/flutter/flow/stopwatch.h
index 50d731a..71869aa 100644
--- a/engine/src/flutter/flow/stopwatch.h
+++ b/engine/src/flutter/flow/stopwatch.h
@@ -106,7 +106,7 @@
///
/// @param canvas The canvas to draw on.
/// @param[in] rect The rectangle to draw in.
- virtual void Visualize(DlCanvas* canvas, const SkRect& rect) const = 0;
+ virtual void Visualize(DlCanvas* canvas, const DlRect& rect) const = 0;
FML_DISALLOW_COPY_AND_ASSIGN(StopwatchVisualizer);
diff --git a/engine/src/flutter/flow/stopwatch_dl.cc b/engine/src/flutter/flow/stopwatch_dl.cc
index 9f7fa3f..3e1a054 100644
--- a/engine/src/flutter/flow/stopwatch_dl.cc
+++ b/engine/src/flutter/flow/stopwatch_dl.cc
@@ -3,14 +3,15 @@
// 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 {
@@ -18,16 +19,16 @@
static const size_t kMaxFrameMarkers = 8;
void DlStopwatchVisualizer::Visualize(DlCanvas* canvas,
- const SkRect& rect) const {
- auto painter = DlVertexPainter();
+ const DlRect& rect) const {
+ auto painter = DlVertexPainter(vertices_storage_, color_storage_);
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();
+ auto const x = rect.GetX();
+ auto const y = rect.GetY();
+ auto const width = rect.GetWidth();
+ auto const height = rect.GetHeight();
+ auto const bottom = rect.GetBottom();
// Scale the graph to show time frames up to those that are 3x the frame time.
auto const one_frame_ms = GetFrameBudget().count();
@@ -35,13 +36,21 @@
auto const max_unit_interval = UnitFrameInterval(max_interval);
auto const sample_unit_width = (1.0 / kMaxSamples);
+ // resize backing storage to match expected lap count.
+ size_t required_storage =
+ (stopwatch_.GetLapsCount() + 2 + kMaxFrameMarkers) * 6;
+ if (vertices_storage_.size() < required_storage) {
+ vertices_storage_.resize(required_storage);
+ color_storage_.resize(required_storage);
+ }
+
// 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++) {
+ for (auto i = 0u; i < stopwatch_.GetLapsCount(); i++) {
auto const sample_unit_height =
(1.0 - UnitHeight(stopwatch_.GetLap(i).ToMillisecondsF(),
max_unit_interval));
@@ -50,10 +59,10 @@
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),
+ painter.DrawRect(DlRect::MakeLTRB(/*left=*/bar_left,
+ /*top=*/y + bar_height,
+ /*right=*/bar_left + bar_width,
+ /*bottom=*/bottom),
DlColor(0xAA0000FF));
}
}
@@ -69,16 +78,16 @@
count = 1;
}
- for (auto i = size_t(0); i < count; i++) {
+ for (auto i = 0u; 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),
+ painter.DrawRect(DlRect::MakeLTRB(/*left=*/x,
+ /*top=*/y + frame_height,
+ /*right=*/width,
+ /*bottom=*/y + frame_height + 1),
DlColor(0xCC000000));
}
}
@@ -96,8 +105,8 @@
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);
+ auto const b = rect.GetBottom();
+ painter.DrawRect(DlRect::MakeLTRB(l, t, r, b), color);
}
// Actually draw.
@@ -106,48 +115,46 @@
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);
+ canvas->DrawVertices(painter.IntoVertices(rect), DlBlendMode::kSrcOver,
+ paint);
}
-void DlVertexPainter::DrawRect(const SkRect& rect, const DlColor& color) {
+DlVertexPainter::DlVertexPainter(std::vector<DlPoint>& vertices_storage,
+ std::vector<DlColor>& color_storage)
+ : vertices_(vertices_storage), colors_(color_storage) {}
+
+void DlVertexPainter::DrawRect(const DlRect& rect, const DlColor& color) {
+ auto const left = rect.GetLeft();
+ auto const top = rect.GetTop();
+ auto const right = rect.GetRight();
+ auto const bottom = rect.GetBottom();
+
+ FML_DCHECK(6 + colors_offset_ <= vertices_.size());
+ FML_DCHECK(6 + colors_offset_ <= colors_.size());
+
// 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());
+ vertices_[vertices_offset_++] = DlPoint(left, top); // tl tr
+ vertices_[vertices_offset_++] = DlPoint(right, top); // br
+ vertices_[vertices_offset_++] = DlPoint(right, bottom); //
+ vertices_[vertices_offset_++] = DlPoint(right, bottom); // tl
+ vertices_[vertices_offset_++] = DlPoint(left, bottom); // bl br
+ vertices_[vertices_offset_++] = DlPoint(left, top); //
+ for (auto i = 0u; i < 6u; i++) {
+ colors_[colors_offset_++] = color;
+ }
}
-std::shared_ptr<DlVertices> DlVertexPainter::IntoVertices() {
- auto const result = DlVertices::Make(
+std::shared_ptr<DlVertices> DlVertexPainter::IntoVertices(
+ const DlRect& bounds_rect) {
+ return DlVertices::Make(
/*mode=*/DlVertexMode::kTriangles,
/*vertex_count=*/vertices_.size(),
- /*vertices=*/vertices_.data(),
+ /*vertices=*/reinterpret_cast<SkPoint*>(vertices_.data()),
/*texture_coordinates=*/nullptr,
- /*colors=*/colors_.data());
- vertices_.clear();
- colors_.clear();
- return result;
+ /*colors=*/colors_.data(),
+ /*index_count=*/0,
+ /*indices=*/nullptr,
+ /*bounds=*/&bounds_rect);
}
} // namespace flutter
diff --git a/engine/src/flutter/flow/stopwatch_dl.h b/engine/src/flutter/flow/stopwatch_dl.h
index d15dc40..be3aba7 100644
--- a/engine/src/flutter/flow/stopwatch_dl.h
+++ b/engine/src/flutter/flow/stopwatch_dl.h
@@ -18,10 +18,18 @@
/// optimizations.
class DlStopwatchVisualizer : public StopwatchVisualizer {
public:
- explicit DlStopwatchVisualizer(const Stopwatch& stopwatch)
- : StopwatchVisualizer(stopwatch) {}
+ explicit DlStopwatchVisualizer(const Stopwatch& stopwatch,
+ std::vector<DlPoint>& vertices_storage,
+ std::vector<DlColor>& color_storage)
+ : StopwatchVisualizer(stopwatch),
+ vertices_storage_(vertices_storage),
+ color_storage_(color_storage) {}
- void Visualize(DlCanvas* canvas, const SkRect& rect) const override;
+ void Visualize(DlCanvas* canvas, const DlRect& rect) const override;
+
+ private:
+ std::vector<DlPoint>& vertices_storage_;
+ std::vector<DlColor>& color_storage_;
};
/// @brief Provides canvas-like painting methods that actually build vertices.
@@ -38,17 +46,22 @@
/// possible (i.e. not having to do triangle-math).
class DlVertexPainter final {
public:
+ DlVertexPainter(std::vector<DlPoint>& vertices_storage,
+ std::vector<DlColor>& color_storage);
+
/// Draws a rectangle with the given color to a buffer.
- void DrawRect(const SkRect& rect, const DlColor& color);
+ void DrawRect(const DlRect& rect, const DlColor& color);
/// Converts the buffered vertices into a |DlVertices| object.
///
/// @note This method clears the buffer.
- std::shared_ptr<DlVertices> IntoVertices();
+ std::shared_ptr<DlVertices> IntoVertices(const DlRect& bounds_rect);
private:
- std::vector<SkPoint> vertices_;
- std::vector<DlColor> colors_;
+ std::vector<DlPoint>& vertices_;
+ std::vector<DlColor>& colors_;
+ size_t vertices_offset_ = 0u;
+ size_t colors_offset_ = 0u;
};
} // namespace flutter
diff --git a/engine/src/flutter/flow/stopwatch_dl_unittests.cc b/engine/src/flutter/flow/stopwatch_dl_unittests.cc
index f8d2900..dfb1910 100644
--- a/engine/src/flutter/flow/stopwatch_dl_unittests.cc
+++ b/engine/src/flutter/flow/stopwatch_dl_unittests.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "display_list/dl_color.h"
#include "flutter/flow/stopwatch_dl.h"
#include "gtest/gtest.h"
@@ -19,16 +20,18 @@
}
TEST(DlVertexPainter, DrawRectIntoVertices) {
- auto painter = DlVertexPainter();
+ std::vector<DlPoint> point_storage(12);
+ std::vector<DlColor> color_storage(12);
+ auto painter = DlVertexPainter(point_storage, color_storage);
// Paint a red rectangle.
- painter.DrawRect(SkRect::MakeLTRB(0, 0, 10, 10), DlColor::kRed());
+ painter.DrawRect(DlRect::MakeLTRB(0, 0, 10, 10), DlColor::kRed());
// Paint a blue rectangle.
- painter.DrawRect(SkRect::MakeLTRB(10, 10, 20, 20), DlColor::kBlue());
+ painter.DrawRect(DlRect::MakeLTRB(10, 10, 20, 20), DlColor::kBlue());
// Convert the buffered vertices into a |DlVertices| object.
- auto vertices = painter.IntoVertices();
+ auto vertices = painter.IntoVertices(DlRect::MakeLTRB(0, 0, 20, 20));
// Verify the vertices.
EXPECT_EQ(vertices->mode(), DlVertexMode::kTriangles);
diff --git a/engine/src/flutter/flow/stopwatch_sk.cc b/engine/src/flutter/flow/stopwatch_sk.cc
index b347f01..4d30371 100644
--- a/engine/src/flutter/flow/stopwatch_sk.cc
+++ b/engine/src/flutter/flow/stopwatch_sk.cc
@@ -86,9 +86,9 @@
}
void SkStopwatchVisualizer::Visualize(DlCanvas* canvas,
- const SkRect& rect) const {
+ const DlRect& rect) const {
// Initialize visualize cache if it has not yet been initialized.
- InitVisualizeSurface(SkISize::Make(rect.width(), rect.height()));
+ InitVisualizeSurface(SkISize::Make(rect.GetWidth(), rect.GetHeight()));
SkCanvas* cache_canvas = visualize_cache_surface_->getCanvas();
SkPaint paint;
@@ -180,7 +180,7 @@
// Draw the cached surface onto the output canvas.
auto image = DlImage::Make(visualize_cache_surface_->makeImageSnapshot());
- canvas->DrawImage(image, SkPoint{rect.x(), rect.y()},
+ canvas->DrawImage(image, SkPoint{rect.GetX(), rect.GetY()},
DlImageSampling::kNearestNeighbor);
}
diff --git a/engine/src/flutter/flow/stopwatch_sk.h b/engine/src/flutter/flow/stopwatch_sk.h
index c1dfb24..9a73b0d 100644
--- a/engine/src/flutter/flow/stopwatch_sk.h
+++ b/engine/src/flutter/flow/stopwatch_sk.h
@@ -19,7 +19,7 @@
explicit SkStopwatchVisualizer(const Stopwatch& stopwatch)
: StopwatchVisualizer(stopwatch) {}
- void Visualize(DlCanvas* canvas, const SkRect& rect) const override;
+ void Visualize(DlCanvas* canvas, const DlRect& rect) const override;
private:
/// Initializes the |SkSurface| used for drawing the stopwatch.
diff --git a/engine/src/flutter/shell/common/shell.cc b/engine/src/flutter/shell/common/shell.cc
index 9cc5c13..8bd6403 100644
--- a/engine/src/flutter/shell/common/shell.cc
+++ b/engine/src/flutter/shell/common/shell.cc
@@ -1633,12 +1633,17 @@
}
fml::Milliseconds Shell::GetFrameBudget() {
+ if (cached_display_refresh_rate_.has_value()) {
+ return cached_display_refresh_rate_.value();
+ }
double display_refresh_rate = display_manager_->GetMainDisplayRefreshRate();
if (display_refresh_rate > 0) {
- return fml::RefreshRateToFrameBudget(display_refresh_rate);
+ cached_display_refresh_rate_ =
+ fml::RefreshRateToFrameBudget(display_refresh_rate);
} else {
- return fml::kDefaultFrameBudget;
+ cached_display_refresh_rate_ = fml::kDefaultFrameBudget;
}
+ return cached_display_refresh_rate_.value_or(fml::kDefaultFrameBudget);
}
fml::TimePoint Shell::GetLatestFrameTargetTime() const {
diff --git a/engine/src/flutter/shell/common/shell.h b/engine/src/flutter/shell/common/shell.h
index 0685bb7..0ff7984 100644
--- a/engine/src/flutter/shell/common/shell.h
+++ b/engine/src/flutter/shell/common/shell.h
@@ -512,6 +512,9 @@
// Used to communicate the right frame bounds via service protocol.
double device_pixel_ratio_ = 0.0;
+ // Cached refresh rate used by the performance overlay.
+ std::optional<fml::Milliseconds> cached_display_refresh_rate_;
+
// How many frames have been timed since last report.
size_t UnreportedFramesCount() const;