未验证 提交 5f3f3bd9 编写于 作者: L liyuqian 提交者: GitHub

Add mock capability to PerformanceOverlayLayer (#7537)

So we can do golden test on PerformanceOverlay to avoid regression like
https://github.com/flutter/flutter/issues/26387
上级 7d97afd8
...@@ -57,6 +57,7 @@ FILE: ../../../flutter/flow/layers/opacity_layer.cc ...@@ -57,6 +57,7 @@ FILE: ../../../flutter/flow/layers/opacity_layer.cc
FILE: ../../../flutter/flow/layers/opacity_layer.h FILE: ../../../flutter/flow/layers/opacity_layer.h
FILE: ../../../flutter/flow/layers/performance_overlay_layer.cc FILE: ../../../flutter/flow/layers/performance_overlay_layer.cc
FILE: ../../../flutter/flow/layers/performance_overlay_layer.h 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.cc
FILE: ../../../flutter/flow/layers/physical_shape_layer.h FILE: ../../../flutter/flow/layers/physical_shape_layer.h
FILE: ../../../flutter/flow/layers/picture_layer.cc FILE: ../../../flutter/flow/layers/picture_layer.cc
......
...@@ -95,6 +95,7 @@ executable("flow_unittests") { ...@@ -95,6 +95,7 @@ executable("flow_unittests") {
sources = [ sources = [
"matrix_decomposition_unittests.cc", "matrix_decomposition_unittests.cc",
"raster_cache_unittests.cc", "raster_cache_unittests.cc",
"layers/performance_overlay_layer_unittests.cc",
] ]
deps = [ deps = [
......
...@@ -15,8 +15,12 @@ namespace { ...@@ -15,8 +15,12 @@ namespace {
void DrawStatisticsText(SkCanvas& canvas, void DrawStatisticsText(SkCanvas& canvas,
const std::string& string, const std::string& string,
int x, int x,
int y) { int y,
const std::string& font_path) {
SkFont font; SkFont font;
if (font_path != "") {
font = SkFont(SkTypeface::MakeFromFile(font_path.c_str()));
}
font.setSize(15); font.setSize(15);
font.setLinearMetrics(false); font.setLinearMetrics(false);
SkPaint paint; SkPaint paint;
...@@ -33,7 +37,8 @@ void VisualizeStopWatch(SkCanvas& canvas, ...@@ -33,7 +37,8 @@ void VisualizeStopWatch(SkCanvas& canvas,
SkScalar height, SkScalar height,
bool show_graph, bool show_graph,
bool show_labels, 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_x = 8; // distance from x
const int label_y = -10; // distance from y+height const int label_y = -10; // distance from y+height
...@@ -51,14 +56,20 @@ void VisualizeStopWatch(SkCanvas& canvas, ...@@ -51,14 +56,20 @@ void VisualizeStopWatch(SkCanvas& canvas,
stream << label_prefix << " " stream << label_prefix << " "
<< "max " << max_ms_per_frame << " ms/frame, " << "max " << max_ms_per_frame << " ms/frame, "
<< "avg " << average_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 } // namespace
PerformanceOverlayLayer::PerformanceOverlayLayer(uint64_t options) PerformanceOverlayLayer::PerformanceOverlayLayer(uint64_t options,
: options_(options) {} const char* font_path)
: options_(options) {
if (font_path != nullptr) {
font_path_ = font_path;
}
}
void PerformanceOverlayLayer::Paint(PaintContext& context) const { void PerformanceOverlayLayer::Paint(PaintContext& context) const {
const int padding = 8; const int padding = 8;
...@@ -73,15 +84,15 @@ void PerformanceOverlayLayer::Paint(PaintContext& context) const { ...@@ -73,15 +84,15 @@ void PerformanceOverlayLayer::Paint(PaintContext& context) const {
SkScalar height = paint_bounds().height() / 2; SkScalar height = paint_bounds().height() / 2;
SkAutoCanvasRestore save(context.leaf_nodes_canvas, true); SkAutoCanvasRestore save(context.leaf_nodes_canvas, true);
VisualizeStopWatch(*context.leaf_nodes_canvas, context.frame_time, x, y, VisualizeStopWatch(
width, height - padding, *context.leaf_nodes_canvas, context.frame_time, x, y, width,
options_ & kVisualizeRasterizerStatistics, height - padding, options_ & kVisualizeRasterizerStatistics,
options_ & kDisplayRasterizerStatistics, "GPU"); options_ & kDisplayRasterizerStatistics, "GPU", font_path_);
VisualizeStopWatch(*context.leaf_nodes_canvas, context.engine_time, x, VisualizeStopWatch(*context.leaf_nodes_canvas, context.engine_time, x,
y + height, width, height - padding, y + height, width, height - padding,
options_ & kVisualizeEngineStatistics, options_ & kVisualizeEngineStatistics,
options_ & kDisplayEngineStatistics, "UI"); options_ & kDisplayEngineStatistics, "UI", font_path_);
} }
} // namespace flow } // namespace flow
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef FLUTTER_FLOW_LAYERS_PERFORMANCE_OVERLAY_LAYER_H_ #ifndef FLUTTER_FLOW_LAYERS_PERFORMANCE_OVERLAY_LAYER_H_
#define FLUTTER_FLOW_LAYERS_PERFORMANCE_OVERLAY_LAYER_H_ #define FLUTTER_FLOW_LAYERS_PERFORMANCE_OVERLAY_LAYER_H_
#include <string>
#include "flutter/flow/layers/layer.h" #include "flutter/flow/layers/layer.h"
#include "flutter/fml/macros.h" #include "flutter/fml/macros.h"
...@@ -17,12 +19,14 @@ const int kVisualizeEngineStatistics = 1 << 3; ...@@ -17,12 +19,14 @@ const int kVisualizeEngineStatistics = 1 << 3;
class PerformanceOverlayLayer : public Layer { class PerformanceOverlayLayer : public Layer {
public: public:
explicit PerformanceOverlayLayer(uint64_t options); explicit PerformanceOverlayLayer(uint64_t options,
const char* font_path = nullptr);
void Paint(PaintContext& context) const override; void Paint(PaintContext& context) const override;
private: private:
int options_; int options_;
std::string font_path_;
FML_DISALLOW_COPY_AND_ASSIGN(PerformanceOverlayLayer); FML_DISALLOW_COPY_AND_ASSIGN(PerformanceOverlayLayer);
}; };
......
// 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 <class T, std::size_t N>
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<SkSurface> 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<SkImage> snapshot = surface->makeImageSnapshot();
sk_sp<SkData> snapshot_data = snapshot->encodeToData();
sk_sp<SkData> 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;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册