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