1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
cc / metrics / lcd_text_metrics_reporter.cc [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "cc/metrics/lcd_text_metrics_reporter.h"
#include "base/functional/function_ref.h"
#include "base/lazy_instance.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/trace_event/trace_event.h"
#include "cc/base/histograms.h"
#include "cc/layers/picture_layer_impl.h"
#include "cc/paint/display_item_list.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/layer_tree_impl.h"
namespace cc {
namespace {
constexpr auto kMinimumTimeInterval = base::Minutes(1);
constexpr unsigned kMinimumFrameInterval = 500;
// This must be the same as that used in DeviceScaleEnsuresTextQuality() in
// content/renderer/render_widget.cc.
constexpr float kHighDPIDeviceScaleFactorThreshold = 1.5f;
constexpr char kMetricNameLCDTextKPixelsHighDPI[] =
"Compositing.Renderer.LCDTextDisallowedReasonKPixels2.HighDPI";
constexpr char kMetricNameLCDTextKPixelsLowDPI[] =
"Compositing.Renderer.LCDTextDisallowedReasonKPixels2.LowDPI";
void Report(const LayerTreeImpl* layer_tree,
base::FunctionRef<void(int64_t text_pixels,
LCDTextDisallowedReason)> report_layer) {
for (const PictureLayerImpl* layer : layer_tree->picture_layers()) {
if (!layer->draws_content() || !layer->GetRasterSource()) {
continue;
}
const scoped_refptr<const DisplayItemList>& display_item_list =
layer->GetRasterSource()->GetDisplayItemList();
if (!display_item_list) {
continue;
}
int64_t text_pixels = base::checked_cast<int64_t>(
display_item_list->AreaOfDrawText(layer->visible_layer_rect()));
if (!text_pixels) {
continue;
}
DCHECK_GT(text_pixels, 0);
report_layer(text_pixels, layer->lcd_text_disallowed_reason());
}
}
constexpr char const* kTraceCategory =
TRACE_DISABLED_BY_DEFAULT("cc.debug.lcd_text");
} // anonymous namespace
std::unique_ptr<LCDTextMetricsReporter> LCDTextMetricsReporter::CreateIfNeeded(
const LayerTreeHostImpl* layer_tree_host_impl) {
const char* client_name = GetClientNameForMetrics();
// The metrics are for the renderer only.
if (!client_name || strcmp(client_name, "Renderer") != 0)
return nullptr;
return base::WrapUnique(new LCDTextMetricsReporter(layer_tree_host_impl));
}
LCDTextMetricsReporter::LCDTextMetricsReporter(
const LayerTreeHostImpl* layer_tree_host_impl)
: layer_tree_host_impl_(layer_tree_host_impl) {}
LCDTextMetricsReporter::~LCDTextMetricsReporter() = default;
void LCDTextMetricsReporter::NotifySubmitFrame(
const viz::BeginFrameArgs& args) {
current_frame_time_ = args.frame_time;
frame_count_since_last_report_++;
if (last_report_frame_time_.is_null()) {
last_report_frame_time_ = current_frame_time_;
}
bool trace_enabled;
TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &trace_enabled);
if (trace_enabled) {
Report(layer_tree_host_impl_->active_tree(),
[](int64_t text_pixels, LCDTextDisallowedReason reason) {
TRACE_COUNTER2(kTraceCategory,
LCDTextDisallowedReasonToString(reason),
"text_pixels", text_pixels, "layers", 1);
});
}
}
void LCDTextMetricsReporter::NotifyPauseFrameProduction() {
if (current_frame_time_.is_null() ||
current_frame_time_ - last_report_frame_time_ < kMinimumTimeInterval ||
frame_count_since_last_report_ < kMinimumFrameInterval) {
return;
}
last_report_frame_time_ = current_frame_time_;
frame_count_since_last_report_ = 0;
float device_scale_factor =
layer_tree_host_impl_->settings().use_painted_device_scale_factor
? layer_tree_host_impl_->active_tree()->painted_device_scale_factor()
: layer_tree_host_impl_->active_tree()->device_scale_factor();
bool is_high_dpi = device_scale_factor >= kHighDPIDeviceScaleFactorThreshold;
Report(layer_tree_host_impl_->active_tree(),
[is_high_dpi](int64_t text_pixels, LCDTextDisallowedReason reason) {
if (is_high_dpi) {
UMA_HISTOGRAM_SCALED_ENUMERATION(kMetricNameLCDTextKPixelsHighDPI,
reason, text_pixels, 1000);
} else {
UMA_HISTOGRAM_SCALED_ENUMERATION(kMetricNameLCDTextKPixelsLowDPI,
reason, text_pixels, 1000);
}
});
}
} // namespace cc