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);
190 layer->set_paint_bounds(layer_bounds);
192 layer->Preroll(preroll_context());
193 EXPECT_EQ(layer->paint_bounds(), layer_bounds);
194 EXPECT_TRUE(layer->needs_painting(paint_context()));
197 layer->Paint(display_list_paint_context());
200 auto expected_dl = expected_builder.
Build();
208 auto layer = std::make_shared<PerformanceOverlayLayer>(overlay_opts);
214 layer->set_paint_bounds(layer_bounds);
216 layer->Preroll(preroll_context());
217 EXPECT_EQ(layer->paint_bounds(), layer_bounds);
218 EXPECT_TRUE(layer->needs_painting(paint_context()));
220 layer->Paint(display_list_paint_context());
222 display_list_paint_context().raster_time, font,
"Raster");
223 auto overlay_text_data = overlay_text->serialize(SkSerialProcs{});
228 display_list()->Dispatch(inspector);
230 ASSERT_EQ(inspector.
sizes().size(), 0u);
231 ASSERT_EQ(inspector.
texts().size(), 1u);
234 inspector.
texts().front()->GetTextBlob()->serialize(SkSerialProcs{});
235 EXPECT_TRUE(text_data->equals(overlay_text_data.get()));
244 auto layer = std::make_shared<PerformanceOverlayLayer>(overlay_opts);
246 layer->Preroll(preroll_context());
247 layer->Paint(display_list_paint_context());
251 display_list()->Dispatch(inspector);
252 ASSERT_EQ(inspector.
sizes().size(), 1u);
253 ASSERT_EQ(inspector.
texts().size(), 0u);
255 first_draw_size = inspector.
sizes().front();
259 layer = std::make_shared<PerformanceOverlayLayer>(overlay_opts);
261 layer->Preroll(preroll_context());
262 reset_display_list();
263 layer->Paint(display_list_paint_context());
266 display_list()->Dispatch(inspector);
267 ASSERT_EQ(inspector.
sizes().size(), 1u);
268 ASSERT_EQ(inspector.
texts().size(), 0u);
270 EXPECT_NE(first_draw_size, inspector.
sizes().front());
274TEST(PerformanceOverlayLayerDefault, Gold) {
275 TestPerformanceOverlayLayerGold(60);
278TEST(PerformanceOverlayLayer90fps, Gold) {
279 TestPerformanceOverlayLayerGold(90);
282TEST(PerformanceOverlayLayer120fps, Gold) {
283 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)