Revert^2 Integrate layer tracing with perfetto

Define the perfetto custom data source LayerDataSource.
LayerDataSource is registered with perfetto. The data source
is used to listen to perfetto events (setup, start, stop, flush)
and to write trace packets to perfetto.

The user can configure/start/stop tracing via /system/bin/perfetto.

Tracing can operate in the following modes.

ACTIVE mode:
A layers snapshot is taken and written to perfetto for each vsyncid commit.

GENERATED mode:
Listens to the perfetto 'flush' event (e.g. when a bugreport is taken).
When a 'flush' event is received, the ring buffer of transactions (hold by TransactionTracing)
is processed by LayerTraceGenerator, a sequence of layers snapshots is generated
and written to perfetto.

DUMP mode:
When the 'start' event is received a single layers snapshot is taken
and written to perfetto.

Bug: b/284424784
Test: atest libsurfaceflinger_unittest && atest transactiontrace_testsuite
Change-Id: Ic1b10a040ec4533f0b56a4c8087c5a2898e3e34d
diff --git a/services/surfaceflinger/Tracing/LayerDataSource.cpp b/services/surfaceflinger/Tracing/LayerDataSource.cpp
new file mode 100644
index 0000000..474fef8
--- /dev/null
+++ b/services/surfaceflinger/Tracing/LayerDataSource.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#undef LOG_TAG
+#define LOG_TAG "LayerTracing"
+
+#include "LayerDataSource.h"
+
+#include <log/log.h>
+#include <perfetto/config/android/surfaceflinger_layers_config.pbzero.h>
+
+namespace android {
+
+void LayerDataSource::Initialize(LayerTracing& layerTracing) {
+    mLayerTracing.store(&layerTracing);
+
+    auto args = perfetto::TracingInitArgs{};
+    args.backends = perfetto::kSystemBackend;
+    // We are tracing ~50kb/entry and the default shmem buffer size (256kb) could be overrun.
+    // A shmem buffer overrun typically just stalls layer tracing, however when the stall
+    // lasts for too long perfetto assumes there is a deadlock and aborts surfaceflinger.
+    args.shmem_size_hint_kb = 1024;
+    perfetto::Tracing::Initialize(args);
+
+    perfetto::DataSourceDescriptor descriptor;
+    descriptor.set_name(android::LayerDataSource::kName);
+    LayerDataSource::Register(descriptor);
+}
+
+void LayerDataSource::UnregisterLayerTracing() {
+    mLayerTracing.store(nullptr);
+}
+
+void LayerDataSource::OnSetup(const LayerDataSource::SetupArgs& args) {
+    const auto configRaw = args.config->surfaceflinger_layers_config_raw();
+    const auto config = perfetto::protos::pbzero::SurfaceFlingerLayersConfig::Decoder{configRaw};
+
+    if (config.has_mode() && config.mode() != LayerTracing::Mode::MODE_UNSPECIFIED) {
+        mMode = static_cast<LayerTracing::Mode>(config.mode());
+    } else {
+        mMode = LayerTracing::Mode::MODE_GENERATED;
+        ALOGV("Received config with unspecified 'mode'. Using 'GENERATED' as default");
+    }
+
+    mFlags = 0;
+    for (auto it = config.trace_flags(); it; ++it) {
+        mFlags |= static_cast<uint32_t>(*it);
+    }
+}
+
+void LayerDataSource::OnStart(const LayerDataSource::StartArgs&) {
+    ALOGV("Received OnStart event (mode = 0x%02x, flags = 0x%02x)", mMode, mFlags);
+    if (auto* p = mLayerTracing.load()) {
+        p->onStart(mMode, mFlags);
+    }
+}
+
+void LayerDataSource::OnFlush(const LayerDataSource::FlushArgs&) {
+    ALOGV("Received OnFlush event (mode = 0x%02x, flags = 0x%02x)", mMode, mFlags);
+    if (auto* p = mLayerTracing.load()) {
+        p->onFlush(mMode, mFlags);
+    }
+}
+
+void LayerDataSource::OnStop(const LayerDataSource::StopArgs&) {
+    ALOGV("Received OnStop event (mode = 0x%02x, flags = 0x%02x)", mMode, mFlags);
+    if (auto* p = mLayerTracing.load()) {
+        p->onStop(mMode);
+    }
+}
+
+LayerTracing::Mode LayerDataSource::GetMode() const {
+    return mMode;
+}
+
+std::atomic<LayerTracing*> LayerDataSource::mLayerTracing = nullptr;
+
+} // namespace android
+
+PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(android::LayerDataSource);