15#include "third_party/skia/include/core/SkData.h"
16#include "third_party/skia/include/core/SkImage.h"
17#include "third_party/skia/include/core/SkSerialProcs.h"
18#include "third_party/skia/include/core/SkStream.h"
19#include "third_party/skia/include/core/SkSurface.h"
20#include "third_party/skia/include/core/SkTextBlob.h"
21#include "third_party/skia/include/encode/SkPngEncoder.h"
28template <
class T, std::
size_t N>
29constexpr int size(
const T (&array)[N])
noexcept {
33constexpr int kMockedTimes[] = {17, 1, 4, 24, 4, 25, 30, 4, 13, 34,
34 14, 0, 18, 9, 32, 36, 26, 23, 5, 8,
35 32, 18, 29, 16, 29, 18, 0, 36, 33, 10};
37static std::string GetGoldenFilePath(
int refresh_rate,
bool is_new) {
42 << refresh_rate <<
"fps" << (is_new ?
"_new" :
"") <<
".png";
46static void TestPerformanceOverlayLayerGold(
int refresh_rate) {
47 std::string golden_file_path = GetGoldenFilePath(refresh_rate,
false);
48 std::string new_golden_file_path = GetGoldenFilePath(refresh_rate,
true);
50 FixedRefreshRateStopwatch mock_stopwatch(
52 for (
int i = 0;
i <
size(kMockedTimes); ++
i) {
53 mock_stopwatch.SetLapTime(
57 const SkImageInfo image_info = SkImageInfo::MakeN32Premul(1000, 1000);
58 sk_sp<SkSurface>
surface = SkSurfaces::Raster(image_info);
59 DlSkCanvasAdapter canvas(
surface->getCanvas());
61 ASSERT_TRUE(surface !=
nullptr);
63 LayerStateStack state_stack;
64 state_stack.set_delegate(&canvas);
70 .gr_context =
nullptr,
71 .view_embedder =
nullptr,
72 .raster_time = mock_stopwatch,
73 .ui_time = mock_stopwatch,
74 .texture_registry =
nullptr,
75 .raster_cache =
nullptr,
76 .impeller_enabled =
false,
89 surface->getCanvas()->clear(SK_ColorTRANSPARENT);
90 layer.Paint(paint_context);
92 sk_sp<SkImage> snapshot =
surface->makeImageSnapshot();
93 sk_sp<SkData> snapshot_data =
94 SkPngEncoder::Encode(
nullptr, snapshot.get(), {});
96 sk_sp<SkData> golden_data =
97 SkData::MakeFromFileName(golden_file_path.c_str());
98 EXPECT_TRUE(golden_data !=
nullptr)
99 <<
"Golden file not found: " << golden_file_path <<
".\n"
100 <<
"Please either set --golden-dir, or make sure that the unit test is "
101 <<
"run from the right directory (e.g., flutter/engine/src).";
105#if !defined(FML_OS_LINUX)
106 GTEST_SKIP() <<
"Skipping golden tests on non-Linux OSes";
108 const bool golden_data_matches = golden_data->equals(snapshot_data.get());
109 if (!golden_data_matches) {
110 SkFILEWStream wstream(new_golden_file_path.c_str());
111 wstream.write(snapshot_data->data(), snapshot_data->size());
115 sk_sp<SkData> b64_data = SkData::MakeUninitialized(b64_size + 1);
116 char* b64_char =
static_cast<char*
>(b64_data->writable_data());
117 Base64::Encode(snapshot_data->data(), snapshot_data->size(), b64_char);
118 b64_char[b64_size] = 0;
120 EXPECT_TRUE(golden_data_matches)
121 <<
"Golden file mismatch. Please check " <<
"the difference between "
122 << golden_file_path <<
" and " << new_golden_file_path
123 <<
", and replace the former "
124 <<
"with the latter if the difference looks good.\nS\n"
125 <<
"See also the base64 encoded " << new_golden_file_path <<
":\n"
144 bool render_with_attributes)
override {
151 sizes_.push_back(vertices->GetBounds().GetSize());
157 texts_.push_back(
text);
158 text_positions_.push_back(
DlPoint(
x,
y));
161 const std::vector<DlSize>&
sizes() {
return sizes_; }
162 const std::vector<std::shared_ptr<DlText>>
texts() {
return texts_; }
166 std::vector<DlSize> sizes_;
167 std::vector<std::shared_ptr<DlText>> texts_;
168 std::vector<DlPoint> text_positions_;
173 auto layer = std::make_shared<PerformanceOverlayLayer>(overlay_opts);
175 layer->Preroll(preroll_context());
176 EXPECT_EQ(layer->paint_bounds(),
DlRect());
177 EXPECT_FALSE(layer->needs_painting(paint_context()));
179 layer->Paint(paint_context());
184 const uint64_t overlay_opts = 0;
185 auto layer = std::make_shared<PerformanceOverlayLayer>(overlay_opts);
189 layer->set_paint_bounds(layer_bounds);
191 layer->Preroll(preroll_context());
192 EXPECT_EQ(layer->paint_bounds(), layer_bounds);
193 EXPECT_TRUE(layer->needs_painting(paint_context()));
196 layer->Paint(display_list_paint_context());
199 auto expected_dl = expected_builder.
Build();
207 auto layer = std::make_shared<PerformanceOverlayLayer>(overlay_opts);
212 layer->set_paint_bounds(layer_bounds);
214 layer->Preroll(preroll_context());
215 EXPECT_EQ(layer->paint_bounds(), layer_bounds);
216 EXPECT_TRUE(layer->needs_painting(paint_context()));
218 layer->Paint(display_list_paint_context());
220 display_list_paint_context().raster_time, font,
"Raster");
221 auto overlay_text_data = overlay_text->serialize(SkSerialProcs{});
226 display_list()->Dispatch(inspector);
228 ASSERT_EQ(inspector.
sizes().size(), 0u);
229 ASSERT_EQ(inspector.
texts().size(), 1u);
232 inspector.
texts().front()->GetTextBlob()->serialize(SkSerialProcs{});
233 EXPECT_TRUE(text_data->equals(overlay_text_data.get()));
242 auto layer = std::make_shared<PerformanceOverlayLayer>(overlay_opts);
244 layer->Preroll(preroll_context());
245 layer->Paint(display_list_paint_context());
249 display_list()->Dispatch(inspector);
250 ASSERT_EQ(inspector.
sizes().size(), 1u);
251 ASSERT_EQ(inspector.
texts().size(), 0u);
253 first_draw_size = inspector.
sizes().front();
257 layer = std::make_shared<PerformanceOverlayLayer>(overlay_opts);
259 layer->Preroll(preroll_context());
260 reset_display_list();
261 layer->Paint(display_list_paint_context());
264 display_list()->Dispatch(inspector);
265 ASSERT_EQ(inspector.
sizes().size(), 1u);
266 ASSERT_EQ(inspector.
texts().size(), 0u);
268 EXPECT_NE(first_draw_size, inspector.
sizes().front());
272TEST(PerformanceOverlayLayerDefault, Gold) {
273 TestPerformanceOverlayLayerGold(60);
276TEST(PerformanceOverlayLayer90fps, Gold) {
277 TestPerformanceOverlayLayerGold(90);
280TEST(PerformanceOverlayLayer120fps, Gold) {
281 TestPerformanceOverlayLayerGold(120);
sk_sp< DisplayList > Build()
Internal API for rendering recorded display lists to backends.
void drawImage(const sk_sp< DlImage > image, const DlPoint &point, DlImageSampling sampling, bool render_with_attributes) override
void drawVertices(const std::shared_ptr< DlVertices > &vertices, DlBlendMode mode) override
const std::vector< DlPoint > text_positions()
const std::vector< DlSize > & sizes()
void drawText(const std::shared_ptr< DlText > &text, DlScalar x, DlScalar y) override
const std::vector< std::shared_ptr< DlText > > texts()
static constexpr TimeDelta FromMilliseconds(int64_t millis)
FlutterVulkanImage * image
#define FML_UNREACHABLE()
TEST_F(DisplayListTest, Defaults)
LayerTestBase<::testing::Test > LayerTest
TEST(NativeAssetsManagerTest, NoAvailableAssets)
bool DisplayListsEQ_Verbose(const DisplayList *a, const DisplayList *b)
const int kVisualizeEngineStatistics
impeller::Scalar DlScalar
const std::string & GetFontFile()
const int kDisplayEngineStatistics
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
const int kVisualizeRasterizerStatistics
const int kDisplayRasterizerStatistics
const std::string & GetGoldenDir()
Milliseconds RefreshRateToFrameBudget(T refresh_rate)
static size_t Encode(const void *src, size_t length, void *dst)
static size_t EncodedSize(size_t srcDataLength)
LayerStateStack & state_stack
static constexpr TRect MakeWH(Type width, Type height)
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)