1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "flutter/flow/flow_test_utils.h"
6 #include "flutter/flow/layers/performance_overlay_layer.h"
7 #include "flutter/flow/raster_cache.h"
8 #include "flutter/fml/build_config.h"
9
10 #include "third_party/skia/include/core/SkSurface.h"
11 #include "third_party/skia/include/utils/SkBase64.h"
12
13 #include "gtest/gtest.h"
14
15 // To get the size of kMockedTimes in compile time.
16 template <class T, std::size_t N>
size(const T (& array)[N])17 constexpr int size(const T (&array)[N]) noexcept {
18 return N;
19 }
20
21 constexpr int kMockedTimes[] = {17, 1, 4, 24, 4, 25, 30, 4, 13, 34,
22 14, 0, 18, 9, 32, 36, 26, 23, 5, 8,
23 32, 18, 29, 16, 29, 18, 0, 36, 33, 10};
24
25 // Relative to the flutter/src/engine/flutter directory
26 const char* kGoldenFileName = "performance_overlay_gold.png";
27
28 // Relative to the flutter/src/engine/flutter directory
29 const char* kNewGoldenFileName = "performance_overlay_gold_new.png";
30
TEST(PerformanceOverlayLayer,Gold)31 TEST(PerformanceOverlayLayer, Gold) {
32 const std::string& golden_dir = flutter::GetGoldenDir();
33 // This unit test should only be run on Linux (not even on Mac since it's a
34 // golden test). Hence we don't have to worry about the "/" vs. "\".
35 std::string golden_file_path = golden_dir + "/" + kGoldenFileName;
36 std::string new_golden_file_path = golden_dir + "/" + kNewGoldenFileName;
37
38 flutter::Stopwatch mock_stopwatch;
39 for (int i = 0; i < size(kMockedTimes); ++i) {
40 mock_stopwatch.SetLapTime(
41 fml::TimeDelta::FromMilliseconds(kMockedTimes[i]));
42 }
43
44 const SkImageInfo image_info = SkImageInfo::MakeN32Premul(1000, 1000);
45 sk_sp<SkSurface> surface = SkSurface::MakeRaster(image_info);
46
47 ASSERT_TRUE(surface != nullptr);
48
49 flutter::TextureRegistry unused_texture_registry;
50 flutter::Layer::PaintContext paintContext = {
51 nullptr, surface->getCanvas(), nullptr, nullptr, mock_stopwatch,
52 mock_stopwatch, unused_texture_registry, nullptr, false};
53
54 // Specify font file to ensure the same font across different operation
55 // systems.
56 flutter::PerformanceOverlayLayer layer(
57 flutter::kDisplayRasterizerStatistics |
58 flutter::kVisualizeRasterizerStatistics |
59 flutter::kDisplayEngineStatistics |
60 flutter::kVisualizeEngineStatistics,
61 flutter::GetFontFile().c_str());
62 layer.set_paint_bounds(SkRect::MakeWH(1000, 400));
63 surface->getCanvas()->clear(SK_ColorTRANSPARENT);
64 layer.Paint(paintContext);
65
66 sk_sp<SkImage> snapshot = surface->makeImageSnapshot();
67 sk_sp<SkData> snapshot_data = snapshot->encodeToData();
68
69 sk_sp<SkData> golden_data =
70 SkData::MakeFromFileName(golden_file_path.c_str());
71 EXPECT_TRUE(golden_data != nullptr)
72 << "Golden file not found: " << golden_file_path << ".\n"
73 << "Please either set --golden-dir, or make sure that the unit test is "
74 << "run from the right directory (e.g., flutter/engine/src).";
75
76 #if !OS_LINUX
77 GTEST_SKIP() << "Skipping golden tests on non-Linux OSes";
78 #endif // OS_LINUX
79 const bool golden_data_matches = golden_data->equals(snapshot_data.get());
80 if (!golden_data_matches) {
81 SkFILEWStream wstream(new_golden_file_path.c_str());
82 wstream.write(snapshot_data->data(), snapshot_data->size());
83 wstream.flush();
84
85 size_t b64_size =
86 SkBase64::Encode(snapshot_data->data(), snapshot_data->size(), nullptr);
87 sk_sp<SkData> b64_data = SkData::MakeUninitialized(b64_size + 1);
88 char* b64_char = static_cast<char*>(b64_data->writable_data());
89 SkBase64::Encode(snapshot_data->data(), snapshot_data->size(), b64_char);
90 b64_char[b64_size] = 0; // make it null terminated for printing
91
92 EXPECT_TRUE(golden_data_matches)
93 << "Golden file mismatch. Please check "
94 << "the difference between " << kGoldenFileName << " and "
95 << kNewGoldenFileName << ", and replace the former "
96 << "with the latter if the difference looks good.\n\n"
97 << "See also the base64 encoded " << kNewGoldenFileName << ":\n"
98 << b64_char;
99 }
100 }
101