Revert "Integrate layer tracing with perfetto"

This reverts commit 22cbec5335e84a18ed913d3272609828e7c9c649.

Reason for revert: 298512106

Change-Id: Ief74f64ace55cd3a2a802be5f8890654aa8c757d
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index a13dc65..eda52bf 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -198,11 +198,9 @@
         "StartPropertySetThread.cpp",
         "SurfaceFlinger.cpp",
         "SurfaceFlingerDefaultFactory.cpp",
-        "Tracing/LayerDataSource.cpp",
         "Tracing/LayerTracing.cpp",
         "Tracing/TransactionTracing.cpp",
         "Tracing/TransactionProtoParser.cpp",
-        "Tracing/tools/LayerTraceGenerator.cpp",
         "TransactionCallbackInvoker.cpp",
         "TunnelModeEnabledReporter.cpp",
     ],
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b30469d..e24c0db 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -320,6 +320,8 @@
 
 const char* KERNEL_IDLE_TIMER_PROP = "graphics.display.kernel_idle_timer.enabled";
 
+static const int MAX_TRACING_MEMORY = 1024 * 1024 * 1024; // 1GB
+
 // ---------------------------------------------------------------------------
 int64_t SurfaceFlinger::dispSyncPresentTimeOffset;
 bool SurfaceFlinger::useHwcForRgbToYuv;
@@ -481,7 +483,6 @@
 
     if (!mIsUserBuild && base::GetBoolProperty("debug.sf.enable_transaction_tracing"s, true)) {
         mTransactionTracing.emplace();
-        mLayerTracing.setTransactionTracing(*mTransactionTracing);
     }
 
     mIgnoreHdrCameraLayers = ignore_hdr_camera_layers(false);
@@ -826,17 +827,6 @@
     initScheduler(display);
     dispatchDisplayHotplugEvent(display->getPhysicalId(), true);
 
-    mLayerTracing.setTakeLayersSnapshotProtoFunction([&](uint32_t traceFlags) {
-        auto snapshot = perfetto::protos::LayersSnapshotProto{};
-        mScheduler
-                ->schedule([&]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD(kMainThreadContext) {
-                    snapshot = takeLayersSnapshotProto(traceFlags, TimePoint::now(),
-                                                       mLastCommittedVsyncId, true);
-                })
-                .wait();
-        return snapshot;
-    });
-
     // Commit secondary display(s).
     processDisplayChangesLocked();
 
@@ -2388,6 +2378,11 @@
         mTimeStats->incrementMissedFrames();
     }
 
+    if (mTracingEnabledChanged) {
+        mLayerTracingEnabled = mLayerTracing.isEnabled();
+        mTracingEnabledChanged = false;
+    }
+
     // If a mode set is pending and the fence hasn't fired yet, wait for the next commit.
     if (std::any_of(frameTargets.begin(), frameTargets.end(),
                     [this](const auto& pair) FTL_FAKE_GUARD(mStateLock)
@@ -2514,9 +2509,11 @@
     if (!mustComposite) {
         updateInputFlinger(vsyncId, pacesetterFrameTarget.frameBeginTime());
     }
-    doActiveLayersTracingIfNeeded(false, mVisibleRegionsDirty,
-                                  pacesetterFrameTarget.frameBeginTime(), vsyncId);
 
+    if (mLayerTracingEnabled && !mLayerTracing.flagIsSet(LayerTracing::TRACE_COMPOSITION)) {
+        // This will block and tracing should only be enabled for debugging.
+        addToLayerTracing(mVisibleRegionsDirty, pacesetterFrameTarget.frameBeginTime(), vsyncId);
+    }
     mLastCommittedVsyncId = vsyncId;
 
     persistDisplayBrightness(mustComposite);
@@ -2738,8 +2735,10 @@
 
     mLayersWithQueuedFrames.clear();
     mLayersIdsWithQueuedFrames.clear();
-    doActiveLayersTracingIfNeeded(true, mVisibleRegionsDirty, pacesetterTarget.frameBeginTime(),
-                                  vsyncId);
+    if (mLayerTracingEnabled && mLayerTracing.flagIsSet(LayerTracing::TRACE_COMPOSITION)) {
+        // This will block and should only be used for debugging.
+        addToLayerTracing(mVisibleRegionsDirty, pacesetterTarget.frameBeginTime(), vsyncId);
+    }
 
     updateInputFlinger(vsyncId, pacesetterTarget.frameBeginTime());
 
@@ -6367,6 +6366,11 @@
 
     StringAppendF(&result, "  transaction time: %f us\n", inTransactionDuration / 1000.0);
 
+    /*
+     * Tracing state
+     */
+    mLayerTracing.dump(result);
+
     result.append("\nTransaction tracing: ");
     if (mTransactionTracing) {
         result.append("enabled\n");
@@ -6718,13 +6722,42 @@
             case 1024: {
                 return NAME_NOT_FOUND;
             }
-            // Deprecated, use perfetto to start/stop the layer tracing
-            case 1025: {
-                return NAME_NOT_FOUND;
+            case 1025: { // Set layer tracing
+                n = data.readInt32();
+                bool tracingEnabledChanged;
+                if (n == 1) {
+                    int64_t fixedStartingTime = data.readInt64();
+                    ALOGD("LayerTracing enabled");
+                    tracingEnabledChanged = mLayerTracing.enable();
+                    if (tracingEnabledChanged) {
+                        const TimePoint startingTime = fixedStartingTime
+                                ? TimePoint::fromNs(fixedStartingTime)
+                                : TimePoint::now();
+
+                        mScheduler
+                                ->schedule([this, startingTime]() FTL_FAKE_GUARD(
+                                                   mStateLock) FTL_FAKE_GUARD(kMainThreadContext) {
+                                    constexpr bool kVisibleRegionDirty = true;
+                                    addToLayerTracing(kVisibleRegionDirty, startingTime,
+                                                      mLastCommittedVsyncId);
+                                })
+                                .wait();
+                    }
+                } else if (n == 2) {
+                    std::string filename = std::string(data.readCString());
+                    ALOGD("LayerTracing disabled. Trace wrote to %s", filename.c_str());
+                    tracingEnabledChanged = mLayerTracing.disable(filename.c_str());
+                } else {
+                    ALOGD("LayerTracing disabled");
+                    tracingEnabledChanged = mLayerTracing.disable();
+                }
+                mTracingEnabledChanged = tracingEnabledChanged;
+                reply->writeInt32(NO_ERROR);
+                return NO_ERROR;
             }
-            // Deprecated, execute "adb shell perfetto --query" to see the ongoing tracing sessions
-            case 1026: {
-                return NAME_NOT_FOUND;
+            case 1026: { // Get layer tracing status
+                reply->writeBool(mLayerTracing.isEnabled());
+                return NO_ERROR;
             }
             // Is a DisplayColorSetting supported?
             case 1027: {
@@ -6752,9 +6785,19 @@
             case 1028: { // Unused.
                 return NAME_NOT_FOUND;
             }
-            // Deprecated, use perfetto to set the active layer tracing buffer size
+            // Set buffer size for SF tracing (value in KB)
             case 1029: {
-                return NAME_NOT_FOUND;
+                n = data.readInt32();
+                if (n <= 0 || n > MAX_TRACING_MEMORY) {
+                    ALOGW("Invalid buffer size: %d KB", n);
+                    reply->writeInt32(BAD_VALUE);
+                    return BAD_VALUE;
+                }
+
+                ALOGD("Updating trace buffer to %d KB", n);
+                mLayerTracing.setBufferSize(n * 1024);
+                reply->writeInt32(NO_ERROR);
+                return NO_ERROR;
             }
             // Is device color managed?
             case 1030: {
@@ -6794,9 +6837,13 @@
                 }
                 return NO_ERROR;
             }
-            // Deprecated, use perfetto to set layer trace flags
+            // Set trace flags
             case 1033: {
-                return NAME_NOT_FOUND;
+                n = data.readUint32();
+                ALOGD("Updating trace flags to 0x%x", n);
+                mLayerTracing.setTraceFlags(n);
+                reply->writeInt32(NO_ERROR);
+                return NO_ERROR;
             }
             case 1034: {
                 n = data.readInt32();
@@ -6955,6 +7002,9 @@
                 if (mTransactionTracing) {
                     mTransactionTracing->writeToFile();
                 }
+                if (mLayerTracingEnabled) {
+                    mLayerTracing.writeToFile();
+                }
                 reply->writeInt32(NO_ERROR);
                 return NO_ERROR;
             }
@@ -8741,50 +8791,19 @@
     return update;
 }
 
-void SurfaceFlinger::doActiveLayersTracingIfNeeded(bool isCompositionComputed,
-                                                   bool visibleRegionDirty, TimePoint time,
-                                                   VsyncId vsyncId) {
-    if (!mLayerTracing.isActiveTracingStarted()) {
-        return;
-    }
-    if (isCompositionComputed !=
-        mLayerTracing.isActiveTracingFlagSet(LayerTracing::Flag::TRACE_COMPOSITION)) {
-        return;
-    }
-    if (!visibleRegionDirty &&
-        !mLayerTracing.isActiveTracingFlagSet(LayerTracing::Flag::TRACE_BUFFERS)) {
-        return;
-    }
-    auto snapshot = takeLayersSnapshotProto(mLayerTracing.getActiveTracingFlags(), time, vsyncId,
-                                            visibleRegionDirty);
-    mLayerTracing.addProtoSnapshotToOstream(std::move(snapshot), LayerTracing::Mode::MODE_ACTIVE);
-}
-
-perfetto::protos::LayersSnapshotProto SurfaceFlinger::takeLayersSnapshotProto(
-        uint32_t traceFlags, TimePoint time, VsyncId vsyncId, bool visibleRegionDirty) {
-    ATRACE_CALL();
-    perfetto::protos::LayersSnapshotProto snapshot;
-    snapshot.set_elapsed_realtime_nanos(time.ns());
-    snapshot.set_vsync_id(ftl::to_underlying(vsyncId));
-    snapshot.set_where(visibleRegionDirty ? "visibleRegionsDirty" : "bufferLatched");
-    snapshot.set_excludes_composition_state((traceFlags & LayerTracing::Flag::TRACE_COMPOSITION) ==
-                                            0);
-
-    auto layers = dumpDrawingStateProto(traceFlags);
-    if (traceFlags & LayerTracing::Flag::TRACE_EXTRA) {
+void SurfaceFlinger::addToLayerTracing(bool visibleRegionDirty, TimePoint time, VsyncId vsyncId) {
+    const uint32_t tracingFlags = mLayerTracing.getFlags();
+    perfetto::protos::LayersProto layers(dumpDrawingStateProto(tracingFlags));
+    if (tracingFlags & LayerTracing::TRACE_EXTRA) {
         dumpOffscreenLayersProto(layers);
     }
-    *snapshot.mutable_layers() = std::move(layers);
-
-    if (traceFlags & LayerTracing::Flag::TRACE_HWC) {
-        std::string hwcDump;
+    std::string hwcDump;
+    if (tracingFlags & LayerTracing::TRACE_HWC) {
         dumpHwc(hwcDump);
-        snapshot.set_hwc_blob(std::move(hwcDump));
     }
-
-    *snapshot.mutable_displays() = dumpDisplayProto();
-
-    return snapshot;
+    auto displays = dumpDisplayProto();
+    mLayerTracing.notify(visibleRegionDirty, time.ns(), ftl::to_underlying(vsyncId), &layers,
+                         std::move(hwcDump), &displays);
 }
 
 // sfdo functions
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index dc4e7cf..693bf3b 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -368,6 +368,7 @@
     friend class RefreshRateOverlay;
     friend class RegionSamplingThread;
     friend class LayerRenderArea;
+    friend class LayerTracing;
     friend class SurfaceComposerAIDL;
     friend class DisplayRenderArea;
 
@@ -1095,10 +1096,7 @@
     void dumpOffscreenLayersProto(perfetto::protos::LayersProto& layersProto,
                                   uint32_t traceFlags = LayerTracing::TRACE_ALL) const;
     google::protobuf::RepeatedPtrField<perfetto::protos::DisplayProto> dumpDisplayProto() const;
-    void doActiveLayersTracingIfNeeded(bool isCompositionComputed, bool visibleRegionDirty,
-                                       TimePoint, VsyncId) REQUIRES(kMainThreadContext);
-    perfetto::protos::LayersSnapshotProto takeLayersSnapshotProto(uint32_t flags, TimePoint,
-                                                                  VsyncId, bool visibleRegionDirty)
+    void addToLayerTracing(bool visibleRegionDirty, TimePoint, VsyncId)
             REQUIRES(kMainThreadContext);
 
     // Dumps state from HW Composer
@@ -1263,7 +1261,10 @@
     bool mBackpressureGpuComposition = false;
 
     LayerTracing mLayerTracing;
+    bool mLayerTracingEnabled = false;
+
     std::optional<TransactionTracing> mTransactionTracing;
+    std::atomic<bool> mTracingEnabledChanged = false;
 
     const std::shared_ptr<TimeStats> mTimeStats;
     const std::unique_ptr<FrameTracer> mFrameTracer;
diff --git a/services/surfaceflinger/Tracing/LayerDataSource.cpp b/services/surfaceflinger/Tracing/LayerDataSource.cpp
deleted file mode 100644
index 474fef8..0000000
--- a/services/surfaceflinger/Tracing/LayerDataSource.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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);
diff --git a/services/surfaceflinger/Tracing/LayerDataSource.h b/services/surfaceflinger/Tracing/LayerDataSource.h
deleted file mode 100644
index 7944092..0000000
--- a/services/surfaceflinger/Tracing/LayerDataSource.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "LayerTracing.h"
-
-#include <perfetto/tracing.h>
-
-#include <atomic>
-
-namespace android {
-
-/*
- * Thread local storage used for fast (lock free) read of data source's properties.
- *
- */
-struct LayerDataSourceTlsState {
-    template <typename TraceContext>
-    explicit LayerDataSourceTlsState(const TraceContext& trace_context) {
-        auto dataSource = trace_context.GetDataSourceLocked();
-        mMode = dataSource.valid()
-                ? dataSource->GetMode()
-                : perfetto::protos::pbzero::SurfaceFlingerLayersConfig::Mode::MODE_GENERATED;
-    }
-
-    LayerTracing::Mode mMode;
-};
-
-struct LayerDataSourceTraits : public perfetto::DefaultDataSourceTraits {
-    using TlsStateType = LayerDataSourceTlsState;
-};
-
-/*
- * Defines the Perfetto custom data source 'android.surfaceflinger.layers'.
- *
- * Registers the data source with Perfetto, listens to Perfetto events (setup/start/flush/stop)
- * and writes trace packets to Perfetto.
- *
- */
-class LayerDataSource : public perfetto::DataSource<LayerDataSource, LayerDataSourceTraits> {
-public:
-    static void Initialize(LayerTracing&);
-    static void UnregisterLayerTracing();
-    void OnSetup(const SetupArgs&) override;
-    void OnStart(const StartArgs&) override;
-    void OnFlush(const FlushArgs&) override;
-    void OnStop(const StopArgs&) override;
-    LayerTracing::Mode GetMode() const;
-
-    static constexpr auto* kName = "android.surfaceflinger.layers";
-    static constexpr perfetto::BufferExhaustedPolicy kBufferExhaustedPolicy =
-            perfetto::BufferExhaustedPolicy::kStall;
-    static constexpr bool kRequiresCallbacksUnderLock = false;
-
-private:
-    static std::atomic<LayerTracing*> mLayerTracing;
-    LayerTracing::Mode mMode;
-    std::uint32_t mFlags;
-};
-
-} // namespace android
-
-PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(android::LayerDataSource);
diff --git a/services/surfaceflinger/Tracing/LayerTracing.cpp b/services/surfaceflinger/Tracing/LayerTracing.cpp
index e55b4c2..b92d50b 100644
--- a/services/surfaceflinger/Tracing/LayerTracing.cpp
+++ b/services/surfaceflinger/Tracing/LayerTracing.cpp
@@ -18,177 +18,131 @@
 #define LOG_TAG "LayerTracing"
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
-#include "LayerTracing.h"
+#include <filesystem>
 
-#include "LayerDataSource.h"
-#include "Tracing/tools/LayerTraceGenerator.h"
-#include "TransactionTracing.h"
-
+#include <SurfaceFlinger.h>
+#include <android-base/stringprintf.h>
 #include <log/log.h>
-#include <perfetto/tracing.h>
-#include <utils/Timers.h>
+#include <utils/SystemClock.h>
 #include <utils/Trace.h>
 
+#include "LayerTracing.h"
+#include "TransactionRingBuffer.h"
+
 namespace android {
 
-LayerTracing::LayerTracing() {
-    mTakeLayersSnapshotProto = [](uint32_t) { return perfetto::protos::LayersSnapshotProto{}; };
-    LayerDataSource::Initialize(*this);
+LayerTracing::LayerTracing()
+      : mBuffer(std::make_unique<TransactionRingBuffer<LayersTraceFileProto, LayersTraceProto>>()) {
 }
 
-LayerTracing::~LayerTracing() {
-    LayerDataSource::UnregisterLayerTracing();
-}
+LayerTracing::~LayerTracing() = default;
 
-void LayerTracing::setTakeLayersSnapshotProtoFunction(
-        const std::function<perfetto::protos::LayersSnapshotProto(uint32_t)>& callback) {
-    mTakeLayersSnapshotProto = callback;
-}
-
-void LayerTracing::setTransactionTracing(TransactionTracing& transactionTracing) {
-    mTransactionTracing = &transactionTracing;
-}
-
-void LayerTracing::setOutputStream(std::ostream& outStream) {
-    mOutStream = std::ref(outStream);
-}
-
-void LayerTracing::onStart(Mode mode, uint32_t flags) {
-    switch (mode) {
-        case Mode::MODE_ACTIVE: {
-            mActiveTracingFlags.store(flags);
-            mIsActiveTracingStarted.store(true);
-            ALOGV("Starting active tracing (waiting for initial snapshot)");
-            // It might take a while before a layers change occurs and a "spontaneous" snapshot is
-            // taken. Let's manually take a snapshot, so that the trace's first entry will contain
-            // the current layers state.
-            addProtoSnapshotToOstream(mTakeLayersSnapshotProto(flags), Mode::MODE_ACTIVE);
-            ALOGV("Started active tracing (traced initial snapshot)");
-            break;
-        }
-        case Mode::MODE_GENERATED: {
-            ALOGV("Started generated tracing (waiting for OnFlush event to generated layers)");
-            break;
-        }
-        case Mode::MODE_DUMP: {
-            ALOGV("Starting dump tracing (dumping single snapshot)");
-            auto snapshot = mTakeLayersSnapshotProto(flags);
-            addProtoSnapshotToOstream(std::move(snapshot), Mode::MODE_DUMP);
-            ALOGV("Started dump tracing (dumped single snapshot)");
-            break;
-        }
-        default: {
-            ALOGE("Started unknown tracing mode (0x%02x)", mode);
-        }
+bool LayerTracing::enable() {
+    std::scoped_lock lock(mTraceLock);
+    if (mEnabled) {
+        return false;
     }
+    mBuffer->setSize(mBufferSizeInBytes);
+    mEnabled = true;
+    return true;
 }
 
-void LayerTracing::onFlush(Mode mode, uint32_t flags) {
-    // In "generated" mode process the buffer of transactions (owned by TransactionTracing),
-    // generate a sequence of layers snapshots and write them to perfetto.
-    if (mode != Mode::MODE_GENERATED) {
-        return;
+bool LayerTracing::disable(std::string filename, bool writeToFile) {
+    std::scoped_lock lock(mTraceLock);
+    if (!mEnabled) {
+        return false;
     }
-
-    if (!mTransactionTracing) {
-        ALOGV("Skipping layers trace generation (transactions tracing disabled)");
-        return;
+    mEnabled = false;
+    if (writeToFile) {
+        LayersTraceFileProto fileProto = createTraceFileProto();
+        mBuffer->writeToFile(fileProto, filename);
     }
-
-    auto transactionTrace = mTransactionTracing->writeToProto();
-    LayerTraceGenerator{}.generate(transactionTrace, flags);
-    ALOGV("Flushed generated tracing");
+    mBuffer->reset();
+    return true;
 }
 
-void LayerTracing::onStop(Mode mode) {
-    if (mode == Mode::MODE_ACTIVE) {
-        mIsActiveTracingStarted.store(false);
-        ALOGV("Stopped active tracing");
+void LayerTracing::appendToStream(std::ofstream& out) {
+    std::scoped_lock lock(mTraceLock);
+    LayersTraceFileProto fileProto = createTraceFileProto();
+    mBuffer->appendToStream(fileProto, out);
+    mBuffer->reset();
+}
+
+bool LayerTracing::isEnabled() const {
+    std::scoped_lock lock(mTraceLock);
+    return mEnabled;
+}
+
+status_t LayerTracing::writeToFile(std::string filename) {
+    std::scoped_lock lock(mTraceLock);
+    if (!mEnabled) {
+        return STATUS_OK;
     }
+    LayersTraceFileProto fileProto = createTraceFileProto();
+    return mBuffer->writeToFile(fileProto, filename);
 }
 
-void LayerTracing::addProtoSnapshotToOstream(perfetto::protos::LayersSnapshotProto&& snapshot,
-                                             Mode mode) {
-    ATRACE_CALL();
-    if (mOutStream) {
-        writeSnapshotToStream(std::move(snapshot));
-    } else {
-        writeSnapshotToPerfetto(snapshot, mode);
-    }
+void LayerTracing::setTraceFlags(uint32_t flags) {
+    std::scoped_lock lock(mTraceLock);
+    mFlags = flags;
 }
 
-bool LayerTracing::isActiveTracingStarted() const {
-    return mIsActiveTracingStarted.load();
+void LayerTracing::setBufferSize(size_t bufferSizeInBytes) {
+    std::scoped_lock lock(mTraceLock);
+    mBufferSizeInBytes = bufferSizeInBytes;
 }
 
-uint32_t LayerTracing::getActiveTracingFlags() const {
-    return mActiveTracingFlags.load();
+bool LayerTracing::flagIsSet(uint32_t flags) const {
+    return (mFlags & flags) == flags;
+}
+uint32_t LayerTracing::getFlags() const {
+    return mFlags;
 }
 
-bool LayerTracing::isActiveTracingFlagSet(Flag flag) const {
-    return (mActiveTracingFlags.load() & flag) != 0;
-}
-
-perfetto::protos::LayersTraceFileProto LayerTracing::createTraceFileProto() {
-    perfetto::protos::LayersTraceFileProto fileProto;
-    fileProto.set_magic_number(
-            static_cast<uint64_t>(perfetto::protos::LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H)
-                    << 32 |
-            perfetto::protos::LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
-    auto timeOffsetNs = static_cast<uint64_t>(systemTime(SYSTEM_TIME_REALTIME) -
-                                              systemTime(SYSTEM_TIME_MONOTONIC));
+LayersTraceFileProto LayerTracing::createTraceFileProto() {
+    LayersTraceFileProto fileProto;
+    fileProto.set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
+                               LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
+    auto timeOffsetNs = static_cast<std::uint64_t>(systemTime(SYSTEM_TIME_REALTIME) -
+                                                   systemTime(SYSTEM_TIME_MONOTONIC));
     fileProto.set_real_to_elapsed_time_offset_nanos(timeOffsetNs);
     return fileProto;
 }
 
-void LayerTracing::writeSnapshotToStream(perfetto::protos::LayersSnapshotProto&& snapshot) const {
-    auto fileProto = createTraceFileProto();
-    *fileProto.add_entry() = std::move(snapshot);
-    mOutStream->get() << fileProto.SerializeAsString();
+void LayerTracing::dump(std::string& result) const {
+    std::scoped_lock lock(mTraceLock);
+    base::StringAppendF(&result, "Tracing state: %s\n", mEnabled ? "enabled" : "disabled");
+    mBuffer->dump(result);
 }
 
-void LayerTracing::writeSnapshotToPerfetto(const perfetto::protos::LayersSnapshotProto& snapshot,
-                                           Mode mode) {
-    const auto snapshotBytes = snapshot.SerializeAsString();
-
-    LayerDataSource::Trace([&](LayerDataSource::TraceContext context) {
-        if (mode != context.GetCustomTlsState()->mMode) {
-            return;
-        }
-        if (!checkAndUpdateLastVsyncIdWrittenToPerfetto(mode, snapshot.vsync_id())) {
-            return;
-        }
-        {
-            auto packet = context.NewTracePacket();
-            packet->set_timestamp(static_cast<uint64_t>(snapshot.elapsed_realtime_nanos()));
-            packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
-            auto* snapshotProto = packet->set_surfaceflinger_layers_snapshot();
-            snapshotProto->AppendRawProtoBytes(snapshotBytes.data(), snapshotBytes.size());
-        }
-        {
-            // TODO (b/162206162): remove empty packet when perfetto bug is fixed.
-            //  It is currently needed in order not to lose the last trace entry.
-            context.NewTracePacket();
-        }
-    });
-}
-
-bool LayerTracing::checkAndUpdateLastVsyncIdWrittenToPerfetto(Mode mode, std::int64_t vsyncId) {
-    // In some situations (e.g. two bugreports taken shortly one after the other) the generated
-    // sequence of layers snapshots might overlap. Here we check the snapshot's vsyncid to make
-    // sure that in generated tracing mode a given snapshot is written only once to perfetto.
-    if (mode != Mode::MODE_GENERATED) {
-        return true;
+void LayerTracing::notify(bool visibleRegionDirty, int64_t time, int64_t vsyncId,
+                          LayersProto* layers, std::string hwcDump,
+                          google::protobuf::RepeatedPtrField<DisplayProto>* displays) {
+    std::scoped_lock lock(mTraceLock);
+    if (!mEnabled) {
+        return;
     }
 
-    auto lastVsyncId = mLastVsyncIdWrittenToPerfetto.load();
-    while (lastVsyncId < vsyncId) {
-        if (mLastVsyncIdWrittenToPerfetto.compare_exchange_strong(lastVsyncId, vsyncId)) {
-            return true;
-        }
+    if (!visibleRegionDirty && !flagIsSet(LayerTracing::TRACE_BUFFERS)) {
+        return;
     }
 
-    return false;
+    ATRACE_CALL();
+    LayersTraceProto entry;
+    entry.set_elapsed_realtime_nanos(time);
+    const char* where = visibleRegionDirty ? "visibleRegionsDirty" : "bufferLatched";
+    entry.set_where(where);
+    entry.mutable_layers()->Swap(layers);
+
+    if (flagIsSet(LayerTracing::TRACE_HWC)) {
+        entry.set_hwc_blob(hwcDump);
+    }
+    if (!flagIsSet(LayerTracing::TRACE_COMPOSITION)) {
+        entry.set_excludes_composition_state(true);
+    }
+    entry.mutable_displays()->Swap(displays);
+    entry.set_vsync_id(vsyncId);
+    mBuffer->emplace(std::move(entry));
 }
 
 } // namespace android
diff --git a/services/surfaceflinger/Tracing/LayerTracing.h b/services/surfaceflinger/Tracing/LayerTracing.h
index 349cc40..7c0d23d 100644
--- a/services/surfaceflinger/Tracing/LayerTracing.h
+++ b/services/surfaceflinger/Tracing/LayerTracing.h
@@ -16,77 +16,42 @@
 
 #pragma once
 
+#include <android-base/thread_annotations.h>
 #include <layerproto/LayerProtoHeader.h>
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+#include <utils/Timers.h>
 
-#include <atomic>
-#include <functional>
-#include <optional>
-#include <ostream>
+#include <memory>
+#include <mutex>
+
+using namespace android::surfaceflinger;
 
 namespace android {
 
-class TransactionTracing;
+template <typename FileProto, typename EntryProto>
+class TransactionRingBuffer;
+
+class SurfaceFlinger;
 
 /*
  * LayerTracing records layer states during surface flinging. Manages tracing state and
  * configuration.
- *
- * The traced data can then be collected with Perfetto.
- *
- * The Perfetto custom data source 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.
- *
- *
- * E.g. start active mode tracing:
- *
-   adb shell -t perfetto \
-     -c - --txt \
-     -o /data/misc/perfetto-traces/trace \
-   <<EOF
-   unique_session_name: "surfaceflinger_layers_active"
-   buffers: {
-       size_kb: 63488
-       fill_policy: RING_BUFFER
-   }
-   data_sources: {
-       config {
-           name: "android.surfaceflinger.layers"
-           surfaceflinger_layers_config: {
-               mode: MODE_ACTIVE
-               trace_flags: TRACE_FLAG_INPUT
-               trace_flags: TRACE_FLAG_COMPOSITION
-               trace_flags: TRACE_FLAG_HWC
-               trace_flags: TRACE_FLAG_BUFFERS
-               trace_flags: TRACE_FLAG_VIRTUAL_DISPLAYS
-           }
-       }
-   }
-   EOF
- *
  */
 class LayerTracing {
 public:
-    using Mode = perfetto::protos::pbzero::SurfaceFlingerLayersConfig::Mode;
+    LayerTracing();
+    ~LayerTracing();
+    bool enable();
+    bool disable(std::string filename = FILE_NAME, bool writeToFile = true);
+    void appendToStream(std::ofstream& out);
+    bool isEnabled() const;
+    status_t writeToFile(std::string filename = FILE_NAME);
+    static LayersTraceFileProto createTraceFileProto();
+    void notify(bool visibleRegionDirty, int64_t time, int64_t vsyncId, LayersProto* layers,
+                std::string hwcDump, google::protobuf::RepeatedPtrField<DisplayProto>* displays);
 
-    enum Flag : uint32_t {
+    enum : uint32_t {
         TRACE_INPUT = 1 << 1,
         TRACE_COMPOSITION = 1 << 2,
         TRACE_EXTRA = 1 << 3,
@@ -95,39 +60,20 @@
         TRACE_VIRTUAL_DISPLAYS = 1 << 6,
         TRACE_ALL = TRACE_INPUT | TRACE_COMPOSITION | TRACE_EXTRA,
     };
-
-    LayerTracing();
-    ~LayerTracing();
-    void setTakeLayersSnapshotProtoFunction(
-            const std::function<perfetto::protos::LayersSnapshotProto(uint32_t)>&);
-    void setTransactionTracing(TransactionTracing&);
-    void setOutputStream(std::ostream&);
-
-    // Start event from perfetto data source
-    void onStart(Mode mode, uint32_t flags);
-    // Flush event from perfetto data source
-    void onFlush(Mode mode, uint32_t flags);
-    // Stop event from perfetto data source
-    void onStop(Mode mode);
-
-    void addProtoSnapshotToOstream(perfetto::protos::LayersSnapshotProto&& snapshot, Mode mode);
-    bool isActiveTracingStarted() const;
-    uint32_t getActiveTracingFlags() const;
-    bool isActiveTracingFlagSet(Flag flag) const;
-    static perfetto::protos::LayersTraceFileProto createTraceFileProto();
+    void setTraceFlags(uint32_t flags);
+    bool flagIsSet(uint32_t flags) const;
+    uint32_t getFlags() const;
+    void setBufferSize(size_t bufferSizeInBytes);
+    void dump(std::string&) const;
 
 private:
-    void writeSnapshotToStream(perfetto::protos::LayersSnapshotProto&& snapshot) const;
-    void writeSnapshotToPerfetto(const perfetto::protos::LayersSnapshotProto& snapshot, Mode mode);
-    bool checkAndUpdateLastVsyncIdWrittenToPerfetto(Mode mode, std::int64_t vsyncId);
-
-    std::function<perfetto::protos::LayersSnapshotProto(uint32_t)> mTakeLayersSnapshotProto;
-    TransactionTracing* mTransactionTracing;
-
-    std::atomic<bool> mIsActiveTracingStarted{false};
-    std::atomic<uint32_t> mActiveTracingFlags{0};
-    std::atomic<std::int64_t> mLastVsyncIdWrittenToPerfetto{-1};
-    std::optional<std::reference_wrapper<std::ostream>> mOutStream;
+    static constexpr auto FILE_NAME = "/data/misc/wmtrace/layers_trace.winscope";
+    uint32_t mFlags = TRACE_INPUT;
+    mutable std::mutex mTraceLock;
+    bool mEnabled GUARDED_BY(mTraceLock) = false;
+    std::unique_ptr<TransactionRingBuffer<LayersTraceFileProto, LayersTraceProto>> mBuffer
+            GUARDED_BY(mTraceLock);
+    size_t mBufferSizeInBytes GUARDED_BY(mTraceLock) = 20 * 1024 * 1024;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/Tracing/tools/Android.bp b/services/surfaceflinger/Tracing/tools/Android.bp
index 2ff09c3..b6435a8 100644
--- a/services/surfaceflinger/Tracing/tools/Android.bp
+++ b/services/surfaceflinger/Tracing/tools/Android.bp
@@ -31,6 +31,7 @@
     srcs: [
         ":libsurfaceflinger_sources",
         ":libsurfaceflinger_mock_sources",
+        ":layertracegenerator_sources",
         "main.cpp",
     ],
     static_libs: [
@@ -40,3 +41,15 @@
         "libsurfaceflinger_mocks_headers",
     ],
 }
+
+filegroup {
+    name: "layertracegenerator_sources",
+    srcs: [
+        "LayerTraceGenerator.cpp",
+    ],
+}
+
+cc_library_headers {
+    name: "layertracegenerator_headers",
+    export_include_dirs: ["."],
+}
diff --git a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
index 62c362e..9471e95 100644
--- a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
+++ b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
@@ -41,9 +41,7 @@
 using namespace ftl::flag_operators;
 
 bool LayerTraceGenerator::generate(const perfetto::protos::TransactionTraceFile& traceFile,
-                                   std::uint32_t traceFlags,
-                                   std::optional<std::reference_wrapper<std::ostream>> outStream,
-                                   bool onlyLastEntry) {
+                                   const char*, bool onlyLastEntry) {
     if (traceFile.entry_size() == 0) {
         ALOGD("Trace file is empty");
         return false;
@@ -51,11 +49,6 @@
 
     TransactionProtoParser parser(std::make_unique<TransactionProtoParser::FlingerDataMapper>());
 
-    LayerTracing layerTracing;
-    if (outStream) {
-        layerTracing.setOutputStream(outStream->get());
-    }
-
     // frontend
     frontend::LayerLifecycleManager lifecycleManager;
     frontend::LayerHierarchyBuilder hierarchyBuilder{{}};
@@ -67,10 +60,18 @@
     property_get("ro.surface_flinger.supports_background_blur", value, "0");
     bool supportsBlur = atoi(value);
 
+    LayerTracing layerTracing;
+    layerTracing.setTraceFlags(LayerTracing::TRACE_INPUT | LayerTracing::TRACE_BUFFERS);
+    // 10MB buffer size (large enough to hold a single entry)
+    layerTracing.setBufferSize(10 * 1024 * 1024);
+    layerTracing.enable();
+    layerTracing.writeToFile(outputLayersTracePath);
+    std::ofstream out(outputLayersTracePath, std::ios::binary | std::ios::app);
+
     ALOGD("Generating %d transactions...", traceFile.entry_size());
     for (int i = 0; i < traceFile.entry_size(); i++) {
         // parse proto
-        perfetto::protos::TransactionTraceEntry entry = traceFile.entry(i);
+        proto::TransactionTraceEntry entry = traceFile.entry(i);
         ALOGV("    Entry %04d/%04d for time=%" PRId64 " vsyncid=%" PRId64
               " layers +%d -%d handles -%d transactions=%d",
               i, traceFile.entry_size(), entry.elapsed_realtime_nanos(), entry.vsync_id(),
@@ -153,26 +154,19 @@
 
         lifecycleManager.commitChanges();
 
-        auto layersProto =
-                LayerProtoFromSnapshotGenerator(snapshotBuilder, displayInfos, {}, traceFlags)
-                        .generate(hierarchyBuilder.getHierarchy());
+        LayersProto layersProto = LayerProtoFromSnapshotGenerator(snapshotBuilder, displayInfos, {},
+                                                                  layerTracing.getFlags())
+                                          .generate(hierarchyBuilder.getHierarchy());
         auto displayProtos = LayerProtoHelper::writeDisplayInfoToProto(displayInfos);
         if (!onlyLastEntry || (i == traceFile.entry_size() - 1)) {
-            perfetto::protos::LayersSnapshotProto snapshotProto{};
-            snapshotProto.set_vsync_id(entry.vsync_id());
-            snapshotProto.set_elapsed_realtime_nanos(entry.elapsed_realtime_nanos());
-            snapshotProto.set_where(visibleRegionsDirty ? "visibleRegionsDirty" : "bufferLatched");
-            *snapshotProto.mutable_layers() = std::move(layersProto);
-            if ((traceFlags & LayerTracing::TRACE_COMPOSITION) == 0) {
-                snapshotProto.set_excludes_composition_state(true);
-            }
-            *snapshotProto.mutable_displays() = std::move(displayProtos);
-
-            layerTracing.addProtoSnapshotToOstream(std::move(snapshotProto),
-                                                   LayerTracing::Mode::MODE_GENERATED);
+            layerTracing.notify(visibleRegionsDirty, entry.elapsed_realtime_nanos(),
+                                entry.vsync_id(), &layersProto, {}, &displayProtos);
+            layerTracing.appendToStream(out);
         }
     }
-    ALOGD("End of generating trace file");
+    layerTracing.disable("", /*writeToFile=*/false);
+    out.close();
+    ALOGD("End of generating trace file. File written to %s", outputLayersTracePath);
     return true;
 }
 
diff --git a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.h b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.h
index 2bb6f51..a1e5fc8 100644
--- a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.h
+++ b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.h
@@ -18,19 +18,10 @@
 
 #include <Tracing/TransactionTracing.h>
 
-#include <functional>
-#include <optional>
-#include <ostream>
-#include <string>
-
 namespace android {
-
-class LayerTracing;
-
 class LayerTraceGenerator {
 public:
-    bool generate(const perfetto::protos::TransactionTraceFile&, std::uint32_t traceFlags,
-                  std::optional<std::reference_wrapper<std::ostream>> outStream = std::nullopt,
-                  bool onlyLastEntry = false);
+    bool generate(const perfetto::protos::TransactionTraceFile&, const char* outputLayersTracePath,
+                  bool onlyLastEntry);
 };
 } // namespace android
diff --git a/services/surfaceflinger/Tracing/tools/main.cpp b/services/surfaceflinger/Tracing/tools/main.cpp
index a8ac36a..0ff8f98 100644
--- a/services/surfaceflinger/Tracing/tools/main.cpp
+++ b/services/surfaceflinger/Tracing/tools/main.cpp
@@ -21,7 +21,6 @@
 #include <iostream>
 #include <string>
 
-#include <Tracing/LayerTracing.h>
 #include "LayerTraceGenerator.h"
 
 using namespace android;
@@ -48,22 +47,19 @@
         return -1;
     }
 
-    const auto* outputLayersTracePath =
-            (argc == 3) ? argv[2] : "/data/misc/wmtrace/layers_trace.winscope";
-    auto outStream = std::ofstream{outputLayersTracePath, std::ios::binary | std::ios::app};
+    const char* outputLayersTracePath =
+            (argc >= 3) ? argv[2] : "/data/misc/wmtrace/layers_trace.winscope";
 
     const bool generateLastEntryOnly =
             argc >= 4 && std::string_view(argv[3]) == "--last-entry-only";
 
-    auto traceFlags = LayerTracing::Flag::TRACE_INPUT | LayerTracing::Flag::TRACE_BUFFERS;
-
     ALOGD("Generating %s...", outputLayersTracePath);
     std::cout << "Generating " << outputLayersTracePath << "\n";
 
-    if (!LayerTraceGenerator().generate(transactionTraceFile, traceFlags, outStream,
+    if (!LayerTraceGenerator().generate(transactionTraceFile, outputLayersTracePath,
                                         generateLastEntryOnly)) {
         std::cout << "Error: Failed to generate layers trace " << outputLayersTracePath;
         return -1;
     }
     return 0;
-}
+}
\ No newline at end of file
diff --git a/services/surfaceflinger/tests/tracing/Android.bp b/services/surfaceflinger/tests/tracing/Android.bp
index b6cd7b8..21ebaea 100644
--- a/services/surfaceflinger/tests/tracing/Android.bp
+++ b/services/surfaceflinger/tests/tracing/Android.bp
@@ -35,6 +35,7 @@
     srcs: [
         ":libsurfaceflinger_sources",
         ":libsurfaceflinger_mock_sources",
+        ":layertracegenerator_sources",
         "TransactionTraceTestSuite.cpp",
     ],
     static_libs: [
@@ -42,6 +43,7 @@
     ],
     header_libs: [
         "libsurfaceflinger_mocks_headers",
+        "layertracegenerator_headers",
     ],
     data: ["testdata/*"],
 }
diff --git a/services/surfaceflinger/tests/tracing/TransactionTraceTestSuite.cpp b/services/surfaceflinger/tests/tracing/TransactionTraceTestSuite.cpp
index 7a07634..333768a 100644
--- a/services/surfaceflinger/tests/tracing/TransactionTraceTestSuite.cpp
+++ b/services/surfaceflinger/tests/tracing/TransactionTraceTestSuite.cpp
@@ -23,8 +23,8 @@
 #include <unordered_map>
 
 #include <LayerProtoHelper.h>
+#include <LayerTraceGenerator.h>
 #include <Tracing/TransactionProtoParser.h>
-#include <Tracing/tools/LayerTraceGenerator.h>
 #include <layerproto/LayerProtoHeader.h>
 #include <log/log.h>
 
@@ -40,9 +40,9 @@
     static constexpr std::string_view sLayersTracePrefix = "layers_trace_";
     static constexpr std::string_view sTracePostfix = ".winscope";
 
-    perfetto::protos::TransactionTraceFile mTransactionTrace;
-    perfetto::protos::LayersTraceFileProto mExpectedLayersTraceProto;
-    perfetto::protos::LayersTraceFileProto mActualLayersTraceProto;
+    proto::TransactionTraceFile mTransactionTrace;
+    LayersTraceFileProto mExpectedLayersTraceProto;
+    LayersTraceFileProto mActualLayersTraceProto;
 
 protected:
     void SetUp() override {
@@ -56,23 +56,18 @@
         EXPECT_TRUE(std::filesystem::exists(std::filesystem::path(expectedLayersTracePath)));
         parseLayersTraceFromFile(expectedLayersTracePath.c_str(), mExpectedLayersTraceProto);
         TemporaryDir temp_dir;
-
         std::string actualLayersTracePath =
                 std::string(temp_dir.path) + "/" + expectedLayersFilename + "_actual";
-        {
-            auto traceFlags = LayerTracing::TRACE_INPUT | LayerTracing::TRACE_BUFFERS;
-            std::ofstream outStream{actualLayersTracePath, std::ios::binary | std::ios::app};
-            EXPECT_TRUE(LayerTraceGenerator().generate(mTransactionTrace, traceFlags, outStream,
-                                                       /*onlyLastEntry=*/true))
-                    << "Failed to generate layers trace from " << transactionTracePath;
-        }
 
+        EXPECT_TRUE(LayerTraceGenerator().generate(mTransactionTrace, actualLayersTracePath.c_str(),
+                                                   /*onlyLastEntry=*/true))
+                << "Failed to generate layers trace from " << transactionTracePath;
         EXPECT_TRUE(std::filesystem::exists(std::filesystem::path(actualLayersTracePath)));
         parseLayersTraceFromFile(actualLayersTracePath.c_str(), mActualLayersTraceProto);
     }
 
     void parseTransactionTraceFromFile(const char* transactionTracePath,
-                                       perfetto::protos::TransactionTraceFile& outProto) {
+                                       proto::TransactionTraceFile& outProto) {
         ALOGD("Parsing file %s...", transactionTracePath);
         std::fstream input(transactionTracePath, std::ios::in | std::ios::binary);
         EXPECT_TRUE(input) << "Error could not open " << transactionTracePath;
@@ -80,8 +75,7 @@
                 << "Failed to parse " << transactionTracePath;
     }
 
-    void parseLayersTraceFromFile(const char* layersTracePath,
-                                  perfetto::protos::LayersTraceFileProto& outProto) {
+    void parseLayersTraceFromFile(const char* layersTracePath, LayersTraceFileProto& outProto) {
         ALOGD("Parsing file %s...", layersTracePath);
         std::fstream input(layersTracePath, std::ios::in | std::ios::binary);
         EXPECT_TRUE(input) << "Error could not open " << layersTracePath;
@@ -130,7 +124,7 @@
     bool operator()(LayerInfo const& m) const { return m.id == id; }
 };
 
-static LayerInfo getLayerInfoFromProto(perfetto::protos::LayerProto& proto) {
+static LayerInfo getLayerInfoFromProto(::android::surfaceflinger::LayerProto& proto) {
     Rect touchableRegionBounds = Rect::INVALID_RECT;
     // ignore touchable region for layers without buffers, the new fe aggressively avoids
     // calculating state for layers that are not visible which could lead to mismatches
@@ -154,7 +148,8 @@
             touchableRegionBounds};
 }
 
-static std::vector<LayerInfo> getLayerInfosFromProto(perfetto::protos::LayersSnapshotProto& entry) {
+static std::vector<LayerInfo> getLayerInfosFromProto(
+        perfetto::protos::pbzero::LayersSnapshotProto& entry) {
     std::unordered_map<uint64_t /* snapshotId*/, uint64_t /*layerId*/> snapshotIdToLayerId;
     std::vector<LayerInfo> layers;
     layers.reserve(static_cast<size_t>(entry.layers().layers_size()));