Flutter Engine
 
Loading...
Searching...
No Matches
performance_overlay_layer.cc
Go to the documentation of this file.
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
6
7#include <iomanip>
8#include <iostream>
9#include <memory>
10#include <string>
11
13#include "flow/stopwatch.h"
14#include "flow/stopwatch_dl.h"
15#include "third_party/skia/include/core/SkFont.h"
16#include "third_party/skia/include/core/SkFontMgr.h"
17#include "third_party/skia/include/core/SkTextBlob.h"
18#include "third_party/skia/include/core/SkTypeface.h"
19#include "txt/platform.h"
20#ifdef IMPELLER_SUPPORTS_RENDERING
21#include "impeller/display_list/dl_text_impeller.h" // nogncheck
23#endif // IMPELLER_SUPPORTS_RENDERING
24
25namespace flutter {
26namespace {
27
28void VisualizeStopWatch(DlCanvas* canvas,
29 const bool impeller_enabled,
30 const Stopwatch& stopwatch,
31 SkScalar x,
32 SkScalar y,
33 SkScalar width,
34 SkScalar height,
35 bool show_graph,
36 bool show_labels,
37 const std::string& label_prefix,
38 std::vector<DlPoint>& point_storage,
39 std::vector<DlColor>& color_storage,
40 const SkFont& font) {
41 const int label_x = 8; // distance from x
42 const int label_y = -10; // distance from y+height
43
44 if (show_graph) {
45 DlRect visualization_rect = DlRect::MakeXYWH(x, y, width, height);
46 DlStopwatchVisualizer(stopwatch, point_storage, color_storage)
47 .Visualize(canvas, visualization_rect);
48 }
49
50 if (show_labels) {
52 label_prefix);
53 // Historically SK_ColorGRAY (== 0xFF888888) was used here
54 DlPaint paint(DlColor(0xFF888888));
55#ifdef IMPELLER_SUPPORTS_RENDERING
56 if (impeller_enabled) {
57 canvas->DrawText(
59 x + label_x, y + height + label_y, paint);
60 return;
61 }
62#endif // IMPELLER_SUPPORTS_RENDERING
63 canvas->DrawText(DlTextSkia::Make(text), x + label_x, y + height + label_y,
64 paint);
65 }
66}
67
68} // namespace
69
70// static
71SkFont PerformanceOverlayLayer::MakeStatisticsFont(std::string_view font_path) {
72 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
73 if (font_path == "") {
74 if (sk_sp<SkTypeface> face = font_mgr->matchFamilyStyle(nullptr, {})) {
75 return SkFont(face, 15);
76 } else {
77 // In Skia's Android fontmgr, matchFamilyStyle can return null instead
78 // of falling back to a default typeface. If that's the case, we can use
79 // legacyMakeTypeface, which *does* use that default typeface.
80 return SkFont(font_mgr->legacyMakeTypeface(nullptr, {}), 15);
81 }
82 } else {
83 return SkFont(font_mgr->makeFromFile(font_path.data()), 15);
84 }
85}
86
87// static
89 const Stopwatch& stopwatch,
90 const SkFont& font,
91 std::string_view label_prefix) {
92 // Make sure there's not an empty typeface returned, or we won't see any text.
93 FML_DCHECK(font.getTypeface()->countGlyphs() > 0);
94
95 double max_ms_per_frame = stopwatch.MaxDelta().ToMillisecondsF();
96 double average_ms_per_frame = stopwatch.AverageDelta().ToMillisecondsF();
97 std::stringstream stream;
98 stream.setf(std::ios::fixed | std::ios::showpoint);
99 stream << std::setprecision(1);
100 stream << label_prefix << " " << "max " << max_ms_per_frame << " ms/frame, "
101 << "avg " << average_ms_per_frame << " ms/frame";
102 auto text = stream.str();
103 return SkTextBlob::MakeFromText(text.c_str(), text.size(), font,
104 SkTextEncoding::kUTF8);
105}
106
108 const char* font_path)
109 : options_(options) {
110 if (font_path != nullptr) {
111 font_path_ = font_path;
112 }
113}
114
116 const Layer* old_layer) {
117 DiffContext::AutoSubtreeRestore subtree(context);
118 if (!context->IsSubtreeDirty()) {
119 FML_DCHECK(old_layer);
120 auto prev = old_layer->as_performance_overlay_layer();
121 context->MarkSubtreeDirty(context->GetOldLayerPaintRegion(prev));
122 }
123 context->AddLayerBounds(paint_bounds());
124 context->SetLayerPaintRegion(this, context->CurrentSubtreeRegion());
125}
126
128 const int padding = 8;
129
130 if (!options_) {
131 return;
132 }
133
138 auto mutator = context.state_stack.save();
139 // Cached storage for vertex output.
140 std::vector<DlPoint> vertices_storage;
141 std::vector<DlColor> color_storage;
142 SkFont font = MakeStatisticsFont(font_path_);
143
144 VisualizeStopWatch(context.canvas, context.impeller_enabled,
145 context.raster_time, x, y, width, height - padding,
147 options_ & kDisplayRasterizerStatistics, "Raster",
148 vertices_storage, color_storage, font);
149
150 VisualizeStopWatch(context.canvas, context.impeller_enabled, context.ui_time,
151 x, y + height, width, height - padding,
153 options_ & kDisplayEngineStatistics, "UI",
154 vertices_storage, color_storage, font);
155}
156
157} // namespace flutter
void SetLayerPaintRegion(const Layer *layer, const PaintRegion &region)
void MarkSubtreeDirty(const PaintRegion &previous_paint_region=PaintRegion())
PaintRegion CurrentSubtreeRegion() const
PaintRegion GetOldLayerPaintRegion(const Layer *layer) const
bool IsSubtreeDirty() const
void AddLayerBounds(const DlRect &rect)
static std::shared_ptr< DlTextImpeller > Make(const std::shared_ptr< impeller::TextFrame > &frame)
static std::shared_ptr< DlTextSkia > Make(const sk_sp< SkTextBlob > &blob)
virtual const PerformanceOverlayLayer * as_performance_overlay_layer() const
Definition layer.h:249
const DlRect & paint_bounds() const
Definition layer.h:196
void Paint(PaintContext &context) const override
void Diff(DiffContext *context, const Layer *old_layer) override
PerformanceOverlayLayer(uint64_t options, const char *font_path=nullptr)
static sk_sp< SkTextBlob > MakeStatisticsText(const Stopwatch &stopwatch, const SkFont &font, std::string_view label_prefix)
static SkFont MakeStatisticsFont(std::string_view font_path)
fml::TimeDelta MaxDelta() const
Definition stopwatch.cc:67
fml::TimeDelta AverageDelta() const
Definition stopwatch.cc:77
constexpr double ToMillisecondsF() const
Definition time_delta.h:68
int32_t x
#define FML_DCHECK(condition)
Definition logging.h:122
Vector2 padding
The halo padding in source space.
std::u16string text
double y
const int kVisualizeEngineStatistics
impeller::Scalar DlScalar
const int kDisplayEngineStatistics
impeller::Rect DlRect
const int kVisualizeRasterizerStatistics
const int kDisplayRasterizerStatistics
std::shared_ptr< TextFrame > MakeTextFrameFromTextBlobSkia(const sk_sp< SkTextBlob > &blob)
flutter::DlColor DlColor
flutter::DlPaint DlPaint
sk_sp< SkFontMgr > GetDefaultFontManager(uint32_t font_initialization_data)
Definition platform.cc:17
int32_t height
int32_t width
const Stopwatch & raster_time
Definition layer.h:102
const Stopwatch & ui_time
Definition layer.h:103
DlCanvas * canvas
Definition layer.h:92
LayerStateStack & state_stack
Definition layer.h:91
constexpr Type GetY() const
Returns the Y coordinate of the upper left corner, equivalent to |GetOrigin().y|.
Definition rect.h:337
constexpr Type GetHeight() const
Returns the height of the rectangle, equivalent to |GetSize().height|.
Definition rect.h:347
constexpr Type GetX() const
Returns the X coordinate of the upper left corner, equivalent to |GetOrigin().x|.
Definition rect.h:333
static constexpr TRect MakeXYWH(Type x, Type y, Type width, Type height)
Definition rect.h:136
constexpr Type GetWidth() const
Returns the width of the rectangle, equivalent to |GetSize().width|.
Definition rect.h:341