1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker * Copyright 2023 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker *
4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker *
8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker *
10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker */
16*38e8c45fSAndroid Build Coastguard Worker
17*38e8c45fSAndroid Build Coastguard Worker #undef LOG_TAG
18*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "LayerTracing"
19*38e8c45fSAndroid Build Coastguard Worker
20*38e8c45fSAndroid Build Coastguard Worker #include "LayerDataSource.h"
21*38e8c45fSAndroid Build Coastguard Worker
22*38e8c45fSAndroid Build Coastguard Worker #include <log/log.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <perfetto/config/android/surfaceflinger_layers_config.pbzero.h>
24*38e8c45fSAndroid Build Coastguard Worker
25*38e8c45fSAndroid Build Coastguard Worker namespace android {
26*38e8c45fSAndroid Build Coastguard Worker
Initialize(LayerTracing & layerTracing)27*38e8c45fSAndroid Build Coastguard Worker void LayerDataSource::Initialize(LayerTracing& layerTracing) {
28*38e8c45fSAndroid Build Coastguard Worker mLayerTracing.store(&layerTracing);
29*38e8c45fSAndroid Build Coastguard Worker
30*38e8c45fSAndroid Build Coastguard Worker auto args = perfetto::TracingInitArgs{};
31*38e8c45fSAndroid Build Coastguard Worker args.backends = perfetto::kSystemBackend;
32*38e8c45fSAndroid Build Coastguard Worker // We are tracing ~50kb/entry and the default shmem buffer size (256kb) could be overrun.
33*38e8c45fSAndroid Build Coastguard Worker // A shmem buffer overrun typically just stalls layer tracing, however when the stall
34*38e8c45fSAndroid Build Coastguard Worker // lasts for too long perfetto assumes there is a deadlock and aborts surfaceflinger.
35*38e8c45fSAndroid Build Coastguard Worker args.shmem_size_hint_kb = 1024;
36*38e8c45fSAndroid Build Coastguard Worker perfetto::Tracing::Initialize(args);
37*38e8c45fSAndroid Build Coastguard Worker
38*38e8c45fSAndroid Build Coastguard Worker perfetto::DataSourceDescriptor descriptor;
39*38e8c45fSAndroid Build Coastguard Worker descriptor.set_name(android::LayerDataSource::kName);
40*38e8c45fSAndroid Build Coastguard Worker LayerDataSource::Register(descriptor);
41*38e8c45fSAndroid Build Coastguard Worker }
42*38e8c45fSAndroid Build Coastguard Worker
UnregisterLayerTracing()43*38e8c45fSAndroid Build Coastguard Worker void LayerDataSource::UnregisterLayerTracing() {
44*38e8c45fSAndroid Build Coastguard Worker mLayerTracing.store(nullptr);
45*38e8c45fSAndroid Build Coastguard Worker }
46*38e8c45fSAndroid Build Coastguard Worker
OnSetup(const LayerDataSource::SetupArgs & args)47*38e8c45fSAndroid Build Coastguard Worker void LayerDataSource::OnSetup(const LayerDataSource::SetupArgs& args) {
48*38e8c45fSAndroid Build Coastguard Worker const auto configRaw = args.config->surfaceflinger_layers_config_raw();
49*38e8c45fSAndroid Build Coastguard Worker const auto config = perfetto::protos::pbzero::SurfaceFlingerLayersConfig::Decoder{configRaw};
50*38e8c45fSAndroid Build Coastguard Worker
51*38e8c45fSAndroid Build Coastguard Worker if (config.has_mode() && config.mode() != LayerTracing::Mode::MODE_UNSPECIFIED) {
52*38e8c45fSAndroid Build Coastguard Worker mMode = static_cast<LayerTracing::Mode>(config.mode());
53*38e8c45fSAndroid Build Coastguard Worker } else {
54*38e8c45fSAndroid Build Coastguard Worker mMode = LayerTracing::Mode::MODE_GENERATED_BUGREPORT_ONLY;
55*38e8c45fSAndroid Build Coastguard Worker ALOGD("Received config with unspecified 'mode'."
56*38e8c45fSAndroid Build Coastguard Worker " Using 'MODE_GENERATED_BUGREPORT_ONLY' as default");
57*38e8c45fSAndroid Build Coastguard Worker }
58*38e8c45fSAndroid Build Coastguard Worker
59*38e8c45fSAndroid Build Coastguard Worker mFlags = 0;
60*38e8c45fSAndroid Build Coastguard Worker for (auto it = config.trace_flags(); it; ++it) {
61*38e8c45fSAndroid Build Coastguard Worker mFlags |= static_cast<uint32_t>(*it);
62*38e8c45fSAndroid Build Coastguard Worker }
63*38e8c45fSAndroid Build Coastguard Worker }
64*38e8c45fSAndroid Build Coastguard Worker
OnStart(const LayerDataSource::StartArgs &)65*38e8c45fSAndroid Build Coastguard Worker void LayerDataSource::OnStart(const LayerDataSource::StartArgs&) {
66*38e8c45fSAndroid Build Coastguard Worker ALOGD("Received OnStart event (mode = 0x%02x, flags = 0x%02x)", mMode, mFlags);
67*38e8c45fSAndroid Build Coastguard Worker if (auto* p = mLayerTracing.load()) {
68*38e8c45fSAndroid Build Coastguard Worker p->onStart(mMode, mFlags);
69*38e8c45fSAndroid Build Coastguard Worker }
70*38e8c45fSAndroid Build Coastguard Worker }
71*38e8c45fSAndroid Build Coastguard Worker
OnFlush(const LayerDataSource::FlushArgs & args)72*38e8c45fSAndroid Build Coastguard Worker void LayerDataSource::OnFlush(const LayerDataSource::FlushArgs& args) {
73*38e8c45fSAndroid Build Coastguard Worker ALOGD("Received OnFlush event"
74*38e8c45fSAndroid Build Coastguard Worker " (mode = 0x%02x, flags = 0x%02x, reason = 0x%" PRIx64 ", clone_target = 0x%0" PRIx64 ")",
75*38e8c45fSAndroid Build Coastguard Worker mMode, mFlags, args.flush_flags.reason(), args.flush_flags.clone_target());
76*38e8c45fSAndroid Build Coastguard Worker
77*38e8c45fSAndroid Build Coastguard Worker bool isBugreport = args.flush_flags.reason() == perfetto::FlushFlags::Reason::kTraceClone &&
78*38e8c45fSAndroid Build Coastguard Worker args.flush_flags.clone_target() == perfetto::FlushFlags::CloneTarget::kBugreport;
79*38e8c45fSAndroid Build Coastguard Worker
80*38e8c45fSAndroid Build Coastguard Worker if (auto* p = mLayerTracing.load()) {
81*38e8c45fSAndroid Build Coastguard Worker p->onFlush(mMode, mFlags, isBugreport);
82*38e8c45fSAndroid Build Coastguard Worker }
83*38e8c45fSAndroid Build Coastguard Worker }
84*38e8c45fSAndroid Build Coastguard Worker
OnStop(const LayerDataSource::StopArgs & args)85*38e8c45fSAndroid Build Coastguard Worker void LayerDataSource::OnStop(const LayerDataSource::StopArgs& args) {
86*38e8c45fSAndroid Build Coastguard Worker ALOGD("Received OnStop event (mode = 0x%02x, flags = 0x%02x)", mMode, mFlags);
87*38e8c45fSAndroid Build Coastguard Worker if (auto* p = mLayerTracing.load()) {
88*38e8c45fSAndroid Build Coastguard Worker // In dump mode we need to defer the stop (through HandleStopAsynchronously()) till
89*38e8c45fSAndroid Build Coastguard Worker // the layers snapshot has been captured and written to perfetto. We must avoid writing
90*38e8c45fSAndroid Build Coastguard Worker // to perfetto within the OnStop callback to prevent deadlocks (b/313130597).
91*38e8c45fSAndroid Build Coastguard Worker p->onStop(mMode, mFlags, args.HandleStopAsynchronously());
92*38e8c45fSAndroid Build Coastguard Worker }
93*38e8c45fSAndroid Build Coastguard Worker }
94*38e8c45fSAndroid Build Coastguard Worker
GetMode() const95*38e8c45fSAndroid Build Coastguard Worker LayerTracing::Mode LayerDataSource::GetMode() const {
96*38e8c45fSAndroid Build Coastguard Worker return mMode;
97*38e8c45fSAndroid Build Coastguard Worker }
98*38e8c45fSAndroid Build Coastguard Worker
99*38e8c45fSAndroid Build Coastguard Worker std::atomic<LayerTracing*> LayerDataSource::mLayerTracing = nullptr;
100*38e8c45fSAndroid Build Coastguard Worker
101*38e8c45fSAndroid Build Coastguard Worker } // namespace android
102*38e8c45fSAndroid Build Coastguard Worker
103*38e8c45fSAndroid Build Coastguard Worker PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(android::LayerDataSource);
104