diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 7d5e643fdcb6d009a1b0a8a856460c4d91dfafe2..35ea7cad1e859567ec9f7c8877e840aa9a6effc4 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -57,6 +57,7 @@ FILE: ../../../flutter/flow/layers/opacity_layer.cc FILE: ../../../flutter/flow/layers/opacity_layer.h FILE: ../../../flutter/flow/layers/performance_overlay_layer.cc FILE: ../../../flutter/flow/layers/performance_overlay_layer.h +FILE: ../../../flutter/flow/layers/performance_overlay_layer_unittests.cc FILE: ../../../flutter/flow/layers/physical_shape_layer.cc FILE: ../../../flutter/flow/layers/physical_shape_layer.h FILE: ../../../flutter/flow/layers/picture_layer.cc diff --git a/flow/BUILD.gn b/flow/BUILD.gn index 6b345aa87a35a9f2f382486a6b127e5fbdb624fb..003fb326becb112027317fff149bf7f77d5a88cf 100644 --- a/flow/BUILD.gn +++ b/flow/BUILD.gn @@ -95,6 +95,7 @@ executable("flow_unittests") { sources = [ "matrix_decomposition_unittests.cc", "raster_cache_unittests.cc", + "layers/performance_overlay_layer_unittests.cc", ] deps = [ diff --git a/flow/layers/performance_overlay_layer.cc b/flow/layers/performance_overlay_layer.cc index c80786e866e1be45afac4bfc597f2052cddbba62..e7f40058c3bfb4070f511c8324f522e92421fa8e 100644 --- a/flow/layers/performance_overlay_layer.cc +++ b/flow/layers/performance_overlay_layer.cc @@ -15,8 +15,12 @@ namespace { void DrawStatisticsText(SkCanvas& canvas, const std::string& string, int x, - int y) { + int y, + const std::string& font_path) { SkFont font; + if (font_path != "") { + font = SkFont(SkTypeface::MakeFromFile(font_path.c_str())); + } font.setSize(15); font.setLinearMetrics(false); SkPaint paint; @@ -33,7 +37,8 @@ void VisualizeStopWatch(SkCanvas& canvas, SkScalar height, bool show_graph, bool show_labels, - const std::string& label_prefix) { + const std::string& label_prefix, + const std::string& font_path) { const int label_x = 8; // distance from x const int label_y = -10; // distance from y+height @@ -51,14 +56,20 @@ void VisualizeStopWatch(SkCanvas& canvas, stream << label_prefix << " " << "max " << max_ms_per_frame << " ms/frame, " << "avg " << average_ms_per_frame << " ms/frame"; - DrawStatisticsText(canvas, stream.str(), x + label_x, y + height + label_y); + DrawStatisticsText(canvas, stream.str(), x + label_x, y + height + label_y, + font_path); } } } // namespace -PerformanceOverlayLayer::PerformanceOverlayLayer(uint64_t options) - : options_(options) {} +PerformanceOverlayLayer::PerformanceOverlayLayer(uint64_t options, + const char* font_path) + : options_(options) { + if (font_path != nullptr) { + font_path_ = font_path; + } +} void PerformanceOverlayLayer::Paint(PaintContext& context) const { const int padding = 8; @@ -73,15 +84,15 @@ void PerformanceOverlayLayer::Paint(PaintContext& context) const { SkScalar height = paint_bounds().height() / 2; SkAutoCanvasRestore save(context.leaf_nodes_canvas, true); - VisualizeStopWatch(*context.leaf_nodes_canvas, context.frame_time, x, y, - width, height - padding, - options_ & kVisualizeRasterizerStatistics, - options_ & kDisplayRasterizerStatistics, "GPU"); + VisualizeStopWatch( + *context.leaf_nodes_canvas, context.frame_time, x, y, width, + height - padding, options_ & kVisualizeRasterizerStatistics, + options_ & kDisplayRasterizerStatistics, "GPU", font_path_); VisualizeStopWatch(*context.leaf_nodes_canvas, context.engine_time, x, y + height, width, height - padding, options_ & kVisualizeEngineStatistics, - options_ & kDisplayEngineStatistics, "UI"); + options_ & kDisplayEngineStatistics, "UI", font_path_); } } // namespace flow diff --git a/flow/layers/performance_overlay_layer.h b/flow/layers/performance_overlay_layer.h index b5f20ecbd7a6bc19be727e06e44f3658cc08d9f5..a47b836c49f3a73cedcb05b296136eeca240ce0a 100644 --- a/flow/layers/performance_overlay_layer.h +++ b/flow/layers/performance_overlay_layer.h @@ -5,6 +5,8 @@ #ifndef FLUTTER_FLOW_LAYERS_PERFORMANCE_OVERLAY_LAYER_H_ #define FLUTTER_FLOW_LAYERS_PERFORMANCE_OVERLAY_LAYER_H_ +#include + #include "flutter/flow/layers/layer.h" #include "flutter/fml/macros.h" @@ -17,12 +19,14 @@ const int kVisualizeEngineStatistics = 1 << 3; class PerformanceOverlayLayer : public Layer { public: - explicit PerformanceOverlayLayer(uint64_t options); + explicit PerformanceOverlayLayer(uint64_t options, + const char* font_path = nullptr); void Paint(PaintContext& context) const override; private: int options_; + std::string font_path_; FML_DISALLOW_COPY_AND_ASSIGN(PerformanceOverlayLayer); }; diff --git a/flow/layers/performance_overlay_layer_unittests.cc b/flow/layers/performance_overlay_layer_unittests.cc new file mode 100644 index 0000000000000000000000000000000000000000..21eb30653c50f7638d7efb378b25f954a554928b --- /dev/null +++ b/flow/layers/performance_overlay_layer_unittests.cc @@ -0,0 +1,90 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/flow/layers/performance_overlay_layer.h" +#include "flutter/flow/raster_cache.h" + +#include "third_party/skia/include/core/SkSurface.h" +#include "third_party/skia/include/utils/SkBase64.h" + +#include "gtest/gtest.h" + +// To get the size of kMockedTimes in compile time. +template +constexpr int size(const T (&array)[N]) noexcept { + return N; +} + +constexpr int kMockedTimes[] = {17, 1, 4, 24, 4, 25, 30, 4, 13, 34, + 14, 0, 18, 9, 32, 36, 26, 23, 5, 8, + 32, 18, 29, 16, 29, 18, 0, 36, 33, 10}; + +const char* kGoldenFileName = + "flutter/testing/resources/performance_overlay_gold.png"; + +const char* kNewGoldenFileName = + "flutter/testing/resources/performance_overlay_gold_new.png"; + +// Ensure the same font across different operation systems. +const char* kFontFilePath = + "flutter/third_party/txt/third_party/fonts/Roboto-Regular.ttf"; + +TEST(PerformanceOverlayLayer, Gold) { + flow::Stopwatch mock_stopwatch; + for (int i = 0; i < size(kMockedTimes); ++i) { + mock_stopwatch.SetLapTime( + fml::TimeDelta::FromMilliseconds(kMockedTimes[i])); + } + + const SkImageInfo image_info = SkImageInfo::MakeN32Premul(1000, 1000); + sk_sp surface = SkSurface::MakeRaster(image_info); + + ASSERT_TRUE(surface != nullptr); + + flow::TextureRegistry unused_texture_registry; + + flow::Layer::PaintContext paintContext = { + nullptr, surface->getCanvas(), nullptr, mock_stopwatch, + mock_stopwatch, unused_texture_registry, nullptr, false}; + + flow::PerformanceOverlayLayer layer(flow::kDisplayRasterizerStatistics | + flow::kVisualizeRasterizerStatistics | + flow::kDisplayEngineStatistics | + flow::kVisualizeEngineStatistics, + kFontFilePath); + layer.set_paint_bounds(SkRect::MakeWH(1000, 400)); + surface->getCanvas()->clear(SK_ColorTRANSPARENT); + layer.Paint(paintContext); + + sk_sp snapshot = surface->makeImageSnapshot(); + sk_sp snapshot_data = snapshot->encodeToData(); + + sk_sp golden_data = SkData::MakeFromFileName(kGoldenFileName); + EXPECT_TRUE(golden_data != nullptr) + << "Golden file not found: " << kGoldenFileName << ".\n" + << "Please make sure that the unit test is run from the right directory " + << "(e.g., flutter/engine/src)"; + + const bool golden_data_matches = golden_data->equals(snapshot_data.get()); + if (!golden_data_matches) { + SkFILEWStream wstream(kNewGoldenFileName); + wstream.write(snapshot_data->data(), snapshot_data->size()); + wstream.flush(); + + size_t b64_size = + SkBase64::Encode(snapshot_data->data(), snapshot_data->size(), nullptr); + char* b64_data = new char[b64_size]; + SkBase64::Encode(snapshot_data->data(), snapshot_data->size(), b64_data); + + EXPECT_TRUE(golden_data_matches) + << "Golden file mismatch. Please check " + << "the difference between " << kGoldenFileName << " and " + << kNewGoldenFileName << ", and replace the former " + << "with the latter if the difference looks good.\n\n" + << "See also the base64 encoded " << kNewGoldenFileName << ":\n" + << b64_data; + + delete[] b64_data; + } +} diff --git a/testing/resources/performance_overlay_gold.png b/testing/resources/performance_overlay_gold.png new file mode 100644 index 0000000000000000000000000000000000000000..119551f705793600890950be96b6b0d60688cc54 Binary files /dev/null and b/testing/resources/performance_overlay_gold.png differ