SF: Simplify layer tracing

As preparation to support transaction tracing, do the
following:
1. refactor the ring buffer code so it can be reused
2. remove layer async tracing since we will use
transaction tracing for always on tracing

Test: presubmit
Test: capture sf trace via bugreport
Bug: 200284593

Change-Id: I28388c6db27a420c078e1cc33b0b378c55c6c5d6
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 56b8374..4e29172 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -200,7 +200,7 @@
         "SurfaceFlinger.cpp",
         "SurfaceFlingerDefaultFactory.cpp",
         "SurfaceInterceptor.cpp",
-        "SurfaceTracing.cpp",
+        "Tracing/LayerTracing.cpp",
         "Tracing/TransactionProtoParser.cpp",
         "TransactionCallbackInvoker.cpp",
         "TunnelModeEnabledReporter.cpp",
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 3d189d6..f5c5b4a 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2005,7 +2005,7 @@
     writeToProtoDrawingState(layerProto, traceFlags, display);
     writeToProtoCommonState(layerProto, LayerVector::StateSet::Drawing, traceFlags);
 
-    if (traceFlags & SurfaceTracing::TRACE_COMPOSITION) {
+    if (traceFlags & LayerTracing::TRACE_COMPOSITION) {
         // Only populate for the primary display.
         if (display) {
             const Hwc2::IComposerClient::Composition compositionType = getCompositionType(*display);
@@ -2023,43 +2023,38 @@
 void Layer::writeToProtoDrawingState(LayerProto* layerInfo, uint32_t traceFlags,
                                      const DisplayDevice* display) {
     const ui::Transform transform = getTransform();
+    auto buffer = getBuffer();
+    if (buffer != nullptr) {
+        LayerProtoHelper::writeToProto(buffer,
+                                       [&]() { return layerInfo->mutable_active_buffer(); });
+        LayerProtoHelper::writeToProtoDeprecated(ui::Transform(getBufferTransform()),
+                                                 layerInfo->mutable_buffer_transform());
+    }
+    layerInfo->set_invalidate(contentDirty);
+    layerInfo->set_is_protected(isProtected());
+    layerInfo->set_dataspace(dataspaceDetails(static_cast<android_dataspace>(getDataSpace())));
+    layerInfo->set_queued_frames(getQueuedFrameCount());
+    layerInfo->set_refresh_pending(isBufferLatched());
+    layerInfo->set_curr_frame(mCurrentFrameNumber);
+    layerInfo->set_effective_scaling_mode(getEffectiveScalingMode());
 
-    if (traceFlags & SurfaceTracing::TRACE_CRITICAL) {
+    layerInfo->set_requested_corner_radius(getDrawingState().cornerRadius);
+    layerInfo->set_corner_radius(getRoundedCornerState().radius);
+    layerInfo->set_background_blur_radius(getBackgroundBlurRadius());
+    layerInfo->set_is_trusted_overlay(isTrustedOverlay());
+    LayerProtoHelper::writeToProtoDeprecated(transform, layerInfo->mutable_transform());
+    LayerProtoHelper::writePositionToProto(transform.tx(), transform.ty(),
+                                           [&]() { return layerInfo->mutable_position(); });
+    LayerProtoHelper::writeToProto(mBounds, [&]() { return layerInfo->mutable_bounds(); });
+    if (traceFlags & LayerTracing::TRACE_COMPOSITION) {
+        LayerProtoHelper::writeToProto(getVisibleRegion(display),
+                                       [&]() { return layerInfo->mutable_visible_region(); });
+    }
+    LayerProtoHelper::writeToProto(surfaceDamageRegion,
+                                   [&]() { return layerInfo->mutable_damage_region(); });
 
-        auto buffer = getBuffer();
-        if (buffer != nullptr) {
-            LayerProtoHelper::writeToProto(buffer,
-                                           [&]() { return layerInfo->mutable_active_buffer(); });
-            LayerProtoHelper::writeToProtoDeprecated(ui::Transform(getBufferTransform()),
-                                                     layerInfo->mutable_buffer_transform());
-        }
-        layerInfo->set_invalidate(contentDirty);
-        layerInfo->set_is_protected(isProtected());
-        layerInfo->set_dataspace(dataspaceDetails(static_cast<android_dataspace>(getDataSpace())));
-        layerInfo->set_queued_frames(getQueuedFrameCount());
-        layerInfo->set_refresh_pending(isBufferLatched());
-        layerInfo->set_curr_frame(mCurrentFrameNumber);
-        layerInfo->set_effective_scaling_mode(getEffectiveScalingMode());
-
-        layerInfo->set_requested_corner_radius(getDrawingState().cornerRadius);
-        layerInfo->set_corner_radius(getRoundedCornerState().radius);
-        layerInfo->set_background_blur_radius(getBackgroundBlurRadius());
-        layerInfo->set_is_trusted_overlay(isTrustedOverlay());
-        LayerProtoHelper::writeToProtoDeprecated(transform, layerInfo->mutable_transform());
-        LayerProtoHelper::writePositionToProto(transform.tx(), transform.ty(),
-                                               [&]() { return layerInfo->mutable_position(); });
-        LayerProtoHelper::writeToProto(mBounds, [&]() { return layerInfo->mutable_bounds(); });
-        if (traceFlags & SurfaceTracing::TRACE_COMPOSITION) {
-            LayerProtoHelper::writeToProto(getVisibleRegion(display),
-                                           [&]() { return layerInfo->mutable_visible_region(); });
-        }
-        LayerProtoHelper::writeToProto(surfaceDamageRegion,
-                                       [&]() { return layerInfo->mutable_damage_region(); });
-
-        if (hasColorTransform()) {
-            LayerProtoHelper::writeToProto(getColorTransform(),
-                                           layerInfo->mutable_color_transform());
-        }
+    if (hasColorTransform()) {
+        LayerProtoHelper::writeToProto(getColorTransform(), layerInfo->mutable_color_transform());
     }
 
     LayerProtoHelper::writeToProto(mSourceBounds,
@@ -2079,70 +2074,66 @@
 
     ui::Transform requestedTransform = state.transform;
 
-    if (traceFlags & SurfaceTracing::TRACE_CRITICAL) {
-        layerInfo->set_id(sequence);
-        layerInfo->set_name(getName().c_str());
-        layerInfo->set_type(getType());
+    layerInfo->set_id(sequence);
+    layerInfo->set_name(getName().c_str());
+    layerInfo->set_type(getType());
 
-        for (const auto& child : children) {
-            layerInfo->add_children(child->sequence);
-        }
-
-        for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
-            sp<Layer> strongRelative = weakRelative.promote();
-            if (strongRelative != nullptr) {
-                layerInfo->add_relatives(strongRelative->sequence);
-            }
-        }
-
-        LayerProtoHelper::writeToProto(state.activeTransparentRegion_legacy,
-                                       [&]() { return layerInfo->mutable_transparent_region(); });
-
-        layerInfo->set_layer_stack(getLayerStack().id);
-        layerInfo->set_z(state.z);
-
-        LayerProtoHelper::writePositionToProto(requestedTransform.tx(), requestedTransform.ty(),
-                                               [&]() {
-                                                   return layerInfo->mutable_requested_position();
-                                               });
-
-        LayerProtoHelper::writeSizeToProto(state.width, state.height,
-                                           [&]() { return layerInfo->mutable_size(); });
-
-        LayerProtoHelper::writeToProto(state.crop, [&]() { return layerInfo->mutable_crop(); });
-
-        layerInfo->set_is_opaque(isOpaque(state));
-
-
-        layerInfo->set_pixel_format(decodePixelFormat(getPixelFormat()));
-        LayerProtoHelper::writeToProto(getColor(), [&]() { return layerInfo->mutable_color(); });
-        LayerProtoHelper::writeToProto(state.color,
-                                       [&]() { return layerInfo->mutable_requested_color(); });
-        layerInfo->set_flags(state.flags);
-
-        LayerProtoHelper::writeToProtoDeprecated(requestedTransform,
-                                                 layerInfo->mutable_requested_transform());
-
-        auto parent = useDrawing ? mDrawingParent.promote() : mCurrentParent.promote();
-        if (parent != nullptr) {
-            layerInfo->set_parent(parent->sequence);
-        } else {
-            layerInfo->set_parent(-1);
-        }
-
-        auto zOrderRelativeOf = state.zOrderRelativeOf.promote();
-        if (zOrderRelativeOf != nullptr) {
-            layerInfo->set_z_order_relative_of(zOrderRelativeOf->sequence);
-        } else {
-            layerInfo->set_z_order_relative_of(-1);
-        }
-
-        layerInfo->set_is_relative_of(state.isRelativeOf);
-
-        layerInfo->set_owner_uid(mOwnerUid);
+    for (const auto& child : children) {
+        layerInfo->add_children(child->sequence);
     }
 
-    if (traceFlags & SurfaceTracing::TRACE_INPUT) {
+    for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
+        sp<Layer> strongRelative = weakRelative.promote();
+        if (strongRelative != nullptr) {
+            layerInfo->add_relatives(strongRelative->sequence);
+        }
+    }
+
+    LayerProtoHelper::writeToProto(state.activeTransparentRegion_legacy,
+                                   [&]() { return layerInfo->mutable_transparent_region(); });
+
+    layerInfo->set_layer_stack(getLayerStack().id);
+    layerInfo->set_z(state.z);
+
+    LayerProtoHelper::writePositionToProto(requestedTransform.tx(), requestedTransform.ty(), [&]() {
+        return layerInfo->mutable_requested_position();
+    });
+
+    LayerProtoHelper::writeSizeToProto(state.width, state.height,
+                                       [&]() { return layerInfo->mutable_size(); });
+
+    LayerProtoHelper::writeToProto(state.crop, [&]() { return layerInfo->mutable_crop(); });
+
+    layerInfo->set_is_opaque(isOpaque(state));
+
+    layerInfo->set_pixel_format(decodePixelFormat(getPixelFormat()));
+    LayerProtoHelper::writeToProto(getColor(), [&]() { return layerInfo->mutable_color(); });
+    LayerProtoHelper::writeToProto(state.color,
+                                   [&]() { return layerInfo->mutable_requested_color(); });
+    layerInfo->set_flags(state.flags);
+
+    LayerProtoHelper::writeToProtoDeprecated(requestedTransform,
+                                             layerInfo->mutable_requested_transform());
+
+    auto parent = useDrawing ? mDrawingParent.promote() : mCurrentParent.promote();
+    if (parent != nullptr) {
+        layerInfo->set_parent(parent->sequence);
+    } else {
+        layerInfo->set_parent(-1);
+    }
+
+    auto zOrderRelativeOf = state.zOrderRelativeOf.promote();
+    if (zOrderRelativeOf != nullptr) {
+        layerInfo->set_z_order_relative_of(zOrderRelativeOf->sequence);
+    } else {
+        layerInfo->set_z_order_relative_of(-1);
+    }
+
+    layerInfo->set_is_relative_of(state.isRelativeOf);
+
+    layerInfo->set_owner_uid(mOwnerUid);
+
+    if (traceFlags & LayerTracing::TRACE_INPUT) {
         WindowInfo info;
         if (useDrawing) {
             info = fillInputInfo(ui::Transform(), /* displayIsSecure */ true);
@@ -2154,7 +2145,7 @@
                                        [&]() { return layerInfo->mutable_input_window_info(); });
     }
 
-    if (traceFlags & SurfaceTracing::TRACE_EXTRA) {
+    if (traceFlags & LayerTracing::TRACE_EXTRA) {
         auto protoMap = layerInfo->mutable_metadata();
         for (const auto& entry : state.metadata.mMap) {
             (*protoMap)[entry.first] = std::string(entry.second.cbegin(), entry.second.cend());
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 3da07e8..5af8dda 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -57,7 +57,7 @@
 #include "Scheduler/LayerInfo.h"
 #include "Scheduler/Seamlessness.h"
 #include "SurfaceFlinger.h"
-#include "SurfaceTracing.h"
+#include "Tracing/LayerTracing.h"
 #include "TransactionCallbackInvoker.h"
 
 using namespace android::surfaceflinger;
@@ -691,7 +691,7 @@
     // external mStateLock. If writing drawing state, this function should be called on the
     // main or tracing thread.
     void writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet,
-                                 uint32_t traceFlags = SurfaceTracing::TRACE_ALL);
+                                 uint32_t traceFlags = LayerTracing::TRACE_ALL);
 
     gui::WindowInfo::Type getWindowType() const { return mWindowType; }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 5a6a8ce..a990e6b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1948,7 +1948,7 @@
     }
 
     if (mTracingEnabledChanged) {
-        mTracingEnabled = mTracing.isEnabled();
+        mTracingEnabled = mLayerTracing.isEnabled();
         mTracingEnabledChanged = false;
     }
 
@@ -1962,24 +1962,12 @@
     // Composite if transactions were committed, or if requested by HWC.
     bool mustComposite = mMustComposite.exchange(false);
     {
-        mTracePostComposition = mTracing.flagIsSet(SurfaceTracing::TRACE_COMPOSITION) ||
-                mTracing.flagIsSet(SurfaceTracing::TRACE_SYNC) ||
-                mTracing.flagIsSet(SurfaceTracing::TRACE_BUFFERS);
-        const bool tracePreComposition = mTracingEnabled && !mTracePostComposition;
-        ConditionalLockGuard<std::mutex> lock(mTracingLock, tracePreComposition);
-
         mFrameTimeline->setSfWakeUp(vsyncId, frameTime, Fps::fromPeriodNsecs(stats.vsyncPeriod));
 
         mustComposite |= flushAndCommitTransactions();
         mustComposite |= latchBuffers();
 
         updateLayerGeometry();
-
-        if (tracePreComposition) {
-            if (mVisibleRegionsDirty) {
-                mTracing.notifyLocked("visibleRegionsDirty");
-            }
-        }
     }
 
     // Layers need to get updated (in the previous line) before we can use them for
@@ -2112,12 +2100,12 @@
     modulateVsync(&VsyncModulator::onDisplayRefresh, usedGpuComposition);
 
     mLayersWithQueuedFrames.clear();
-    if (mTracingEnabled && mTracePostComposition) {
-        // This may block if SurfaceTracing is running in sync mode.
+    if (mTracingEnabled) {
+        // This will block and should only be used for debugging.
         if (mVisibleRegionsDirty) {
-            mTracing.notify("visibleRegionsDirty");
-        } else if (mTracing.flagIsSet(SurfaceTracing::TRACE_BUFFERS)) {
-            mTracing.notify("bufferLatched");
+            mLayerTracing.notify("visibleRegionsDirty");
+        } else if (mLayerTracing.flagIsSet(LayerTracing::TRACE_BUFFERS)) {
+            mLayerTracing.notify("bufferLatched");
         }
     }
 
@@ -4647,7 +4635,7 @@
         }
 
         if (dumpLayers) {
-            LayersTraceFileProto traceFileProto = SurfaceTracing::createLayersTraceFileProto();
+            LayersTraceFileProto traceFileProto = mLayerTracing.createTraceFileProto();
             LayersTraceProto* layersTrace = traceFileProto.add_entry();
             LayersProto layersProto = dumpProtoFromMainThread();
             layersTrace->mutable_layers()->Swap(&layersProto);
@@ -4669,8 +4657,8 @@
 }
 
 status_t SurfaceFlinger::dumpCritical(int fd, const DumpArgs&, bool asProto) {
-    if (asProto && mTracing.isEnabled()) {
-        mTracing.writeToFile();
+    if (asProto && mLayerTracing.isEnabled()) {
+        mLayerTracing.writeToFile();
     }
 
     return doDump(fd, DumpArgs(), asProto);
@@ -5066,7 +5054,7 @@
     /*
      * Tracing state
      */
-    mTracing.dump(result);
+    mLayerTracing.dump(result);
     result.append("\n");
 
     /*
@@ -5493,20 +5481,20 @@
                 bool tracingEnabledChanged;
                 if (n) {
                     ALOGD("LayerTracing enabled");
-                    tracingEnabledChanged = mTracing.enable();
+                    tracingEnabledChanged = mLayerTracing.enable();
                     if (tracingEnabledChanged) {
-                        schedule([&]() MAIN_THREAD { mTracing.notify("start"); }).wait();
+                        schedule([&]() MAIN_THREAD { mLayerTracing.notify("start"); }).wait();
                     }
                 } else {
                     ALOGD("LayerTracing disabled");
-                    tracingEnabledChanged = mTracing.disable();
+                    tracingEnabledChanged = mLayerTracing.disable();
                 }
                 mTracingEnabledChanged = tracingEnabledChanged;
                 reply->writeInt32(NO_ERROR);
                 return NO_ERROR;
             }
             case 1026: { // Get layer tracing status
-                reply->writeBool(mTracing.isEnabled());
+                reply->writeBool(mLayerTracing.isEnabled());
                 return NO_ERROR;
             }
             // Is a DisplayColorSetting supported?
@@ -5547,7 +5535,7 @@
                 }
 
                 ALOGD("Updating trace buffer to %d KB", n);
-                mTracing.setBufferSize(n * 1024);
+                mLayerTracing.setBufferSize(n * 1024);
                 reply->writeInt32(NO_ERROR);
                 return NO_ERROR;
             }
@@ -5592,7 +5580,7 @@
             case 1033: {
                 n = data.readUint32();
                 ALOGD("Updating trace flags to 0x%x", n);
-                mTracing.setTraceFlags(n);
+                mLayerTracing.setTraceFlags(n);
                 reply->writeInt32(NO_ERROR);
                 return NO_ERROR;
             }
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b432f24..e3bcde2 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -62,8 +62,8 @@
 #include "Scheduler/Scheduler.h"
 #include "Scheduler/VsyncModulator.h"
 #include "SurfaceFlingerFactory.h"
-#include "SurfaceTracing.h"
 #include "TracedOrdinal.h"
+#include "Tracing/LayerTracing.h"
 #include "TransactionCallbackInvoker.h"
 #include "TransactionState.h"
 
@@ -353,7 +353,7 @@
     friend class MonitoredProducer;
     friend class RefreshRateOverlay;
     friend class RegionSamplingThread;
-    friend class SurfaceTracing;
+    friend class LayerTracing;
 
     // For unit tests
     friend class TestableSurfaceFlinger;
@@ -1042,12 +1042,12 @@
     void dumpWideColorInfo(std::string& result) const REQUIRES(mStateLock);
     LayersProto dumpDrawingStateProto(uint32_t traceFlags) const;
     void dumpOffscreenLayersProto(LayersProto& layersProto,
-                                  uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const;
+                                  uint32_t traceFlags = LayerTracing::TRACE_ALL) const;
     void dumpDisplayProto(LayersTraceProto& layersTraceProto) const;
 
     // Dumps state from HW Composer
     void dumpHwc(std::string& result) const;
-    LayersProto dumpProtoFromMainThread(uint32_t traceFlags = SurfaceTracing::TRACE_ALL)
+    LayersProto dumpProtoFromMainThread(uint32_t traceFlags = LayerTracing::TRACE_ALL)
             EXCLUDES(mStateLock);
     void dumpOffscreenLayers(std::string& result) EXCLUDES(mStateLock);
     void dumpPlannerInfo(const DumpArgs& args, std::string& result) const REQUIRES(mStateLock);
@@ -1190,10 +1190,9 @@
     bool mPropagateBackpressureClientComposition = false;
     sp<SurfaceInterceptor> mInterceptor;
 
-    SurfaceTracing mTracing{*this};
+    LayerTracing mLayerTracing{*this};
     std::mutex mTracingLock;
     bool mTracingEnabled = false;
-    bool mTracePostComposition = false;
     std::atomic<bool> mTracingEnabledChanged = false;
 
     const std::shared_ptr<TimeStats> mTimeStats;
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
deleted file mode 100644
index 5963737..0000000
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright 2017 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 "SurfaceTracing"
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-
-#include "SurfaceTracing.h"
-#include <SurfaceFlinger.h>
-
-#include <android-base/file.h>
-#include <android-base/stringprintf.h>
-#include <log/log.h>
-#include <utils/SystemClock.h>
-#include <utils/Trace.h>
-
-namespace android {
-
-SurfaceTracing::SurfaceTracing(SurfaceFlinger& flinger) : mFlinger(flinger) {}
-
-bool SurfaceTracing::enable() {
-    std::scoped_lock lock(mTraceLock);
-    if (mEnabled) {
-        return false;
-    }
-
-    if (flagIsSet(TRACE_SYNC)) {
-        runner = std::make_unique<SurfaceTracing::Runner>(mFlinger, mConfig);
-    } else {
-        runner = std::make_unique<SurfaceTracing::AsyncRunner>(mFlinger, mConfig,
-                                                               mFlinger.mTracingLock);
-    }
-    mEnabled = true;
-    return true;
-}
-
-bool SurfaceTracing::disable() {
-    std::scoped_lock lock(mTraceLock);
-    if (!mEnabled) {
-        return false;
-    }
-    mEnabled = false;
-    runner->stop();
-    return true;
-}
-
-bool SurfaceTracing::isEnabled() const {
-    std::scoped_lock lock(mTraceLock);
-    return mEnabled;
-}
-
-status_t SurfaceTracing::writeToFile() {
-    std::scoped_lock lock(mTraceLock);
-    if (!mEnabled) {
-        return STATUS_OK;
-    }
-    return runner->writeToFile();
-}
-
-void SurfaceTracing::notify(const char* where) {
-    std::scoped_lock lock(mTraceLock);
-    if (mEnabled) {
-        runner->notify(where);
-    }
-}
-
-void SurfaceTracing::notifyLocked(const char* where) {
-    std::scoped_lock lock(mTraceLock);
-    if (mEnabled) {
-        runner->notifyLocked(where);
-    }
-}
-
-void SurfaceTracing::dump(std::string& result) const {
-    std::scoped_lock lock(mTraceLock);
-    base::StringAppendF(&result, "Tracing state: %s\n", mEnabled ? "enabled" : "disabled");
-    if (mEnabled) {
-        runner->dump(result);
-    }
-}
-
-void SurfaceTracing::LayersTraceBuffer::reset(size_t newSize) {
-    // use the swap trick to make sure memory is released
-    std::queue<LayersTraceProto>().swap(mStorage);
-    mSizeInBytes = newSize;
-    mUsedInBytes = 0U;
-}
-
-void SurfaceTracing::LayersTraceBuffer::emplace(LayersTraceProto&& proto) {
-    size_t protoSize = static_cast<size_t>(proto.ByteSize());
-    while (mUsedInBytes + protoSize > mSizeInBytes) {
-        if (mStorage.empty()) {
-            return;
-        }
-        mUsedInBytes -= static_cast<size_t>(mStorage.front().ByteSize());
-        mStorage.pop();
-    }
-    mUsedInBytes += protoSize;
-    mStorage.emplace();
-    mStorage.back().Swap(&proto);
-}
-
-void SurfaceTracing::LayersTraceBuffer::flush(LayersTraceFileProto* fileProto) {
-    fileProto->mutable_entry()->Reserve(static_cast<int>(mStorage.size()));
-
-    while (!mStorage.empty()) {
-        auto entry = fileProto->add_entry();
-        entry->Swap(&mStorage.front());
-        mStorage.pop();
-    }
-}
-
-SurfaceTracing::Runner::Runner(SurfaceFlinger& flinger, SurfaceTracing::Config& config)
-      : mFlinger(flinger), mConfig(config) {
-    mBuffer.setSize(mConfig.bufferSize);
-}
-
-void SurfaceTracing::Runner::notify(const char* where) {
-    LayersTraceProto entry = traceLayers(where);
-    mBuffer.emplace(std::move(entry));
-}
-
-status_t SurfaceTracing::Runner::stop() {
-    return writeToFile();
-}
-
-LayersTraceFileProto SurfaceTracing::createLayersTraceFileProto() {
-    LayersTraceFileProto fileProto;
-    fileProto.set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
-                               LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
-    return fileProto;
-}
-
-status_t SurfaceTracing::Runner::writeToFile() {
-    ATRACE_CALL();
-
-    LayersTraceFileProto fileProto = createLayersTraceFileProto();
-    std::string output;
-
-    mBuffer.flush(&fileProto);
-    mBuffer.reset(mConfig.bufferSize);
-
-    if (!fileProto.SerializeToString(&output)) {
-        ALOGE("Could not save the proto file! Permission denied");
-        return PERMISSION_DENIED;
-    }
-
-    // -rw-r--r--
-    const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
-    if (!android::base::WriteStringToFile(output, DEFAULT_FILE_NAME, mode, getuid(), getgid(),
-                                          true)) {
-        ALOGE("Could not save the proto file! There are missing fields");
-        return PERMISSION_DENIED;
-    }
-
-    return NO_ERROR;
-}
-
-LayersTraceProto SurfaceTracing::Runner::traceLayers(const char* where) {
-    ATRACE_CALL();
-
-    LayersTraceProto entry;
-    entry.set_elapsed_realtime_nanos(elapsedRealtimeNano());
-    entry.set_where(where);
-    LayersProto layers(mFlinger.dumpDrawingStateProto(mConfig.flags));
-
-    if (flagIsSet(SurfaceTracing::TRACE_EXTRA)) {
-        mFlinger.dumpOffscreenLayersProto(layers);
-    }
-    entry.mutable_layers()->Swap(&layers);
-
-    if (flagIsSet(SurfaceTracing::TRACE_HWC)) {
-        std::string hwcDump;
-        mFlinger.dumpHwc(hwcDump);
-        entry.set_hwc_blob(hwcDump);
-    }
-    if (!flagIsSet(SurfaceTracing::TRACE_COMPOSITION)) {
-        entry.set_excludes_composition_state(true);
-    }
-    entry.set_missed_entries(mMissedTraceEntries);
-    mFlinger.dumpDisplayProto(entry);
-    return entry;
-}
-
-void SurfaceTracing::Runner::dump(std::string& result) const {
-    base::StringAppendF(&result, "  number of entries: %zu (%.2fMB / %.2fMB)\n",
-                        mBuffer.frameCount(), float(mBuffer.used()) / float(1_MB),
-                        float(mBuffer.size()) / float(1_MB));
-}
-
-SurfaceTracing::AsyncRunner::AsyncRunner(SurfaceFlinger& flinger, SurfaceTracing::Config& config,
-                                         std::mutex& sfLock)
-      : SurfaceTracing::Runner(flinger, config), mSfLock(sfLock) {
-    mEnabled = true;
-    mThread = std::thread(&AsyncRunner::loop, this);
-}
-
-void SurfaceTracing::AsyncRunner::loop() {
-    while (mEnabled) {
-        LayersTraceProto entry;
-        bool entryAdded = traceWhenNotified(&entry);
-        if (entryAdded) {
-            mBuffer.emplace(std::move(entry));
-        }
-        if (mWriteToFile) {
-            Runner::writeToFile();
-            mWriteToFile = false;
-        }
-    }
-}
-
-bool SurfaceTracing::AsyncRunner::traceWhenNotified(LayersTraceProto* outProto) {
-    std::unique_lock<std::mutex> lock(mSfLock);
-    mCanStartTrace.wait(lock);
-    if (!mAddEntry) {
-        return false;
-    }
-    *outProto = traceLayers(mWhere);
-    mAddEntry = false;
-    mMissedTraceEntries = 0;
-    return true;
-}
-
-void SurfaceTracing::AsyncRunner::notify(const char* where) {
-    std::scoped_lock lock(mSfLock);
-    notifyLocked(where);
-}
-
-void SurfaceTracing::AsyncRunner::notifyLocked(const char* where) {
-    mWhere = where;
-    if (mAddEntry) {
-        mMissedTraceEntries++;
-    }
-    mAddEntry = true;
-    mCanStartTrace.notify_one();
-}
-
-status_t SurfaceTracing::AsyncRunner::writeToFile() {
-    mWriteToFile = true;
-    mCanStartTrace.notify_one();
-    return STATUS_OK;
-}
-
-status_t SurfaceTracing::AsyncRunner::stop() {
-    mEnabled = false;
-    mCanStartTrace.notify_one();
-    mThread.join();
-    return Runner::writeToFile();
-}
-
-} // namespace android
diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h
deleted file mode 100644
index 97adb20..0000000
--- a/services/surfaceflinger/SurfaceTracing.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright 2017 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 <android-base/thread_annotations.h>
-#include <layerproto/LayerProtoHeader.h>
-#include <utils/Errors.h>
-#include <utils/StrongPointer.h>
-
-#include <condition_variable>
-#include <memory>
-#include <mutex>
-#include <queue>
-#include <thread>
-
-using namespace android::surfaceflinger;
-
-namespace android {
-
-class SurfaceFlinger;
-constexpr auto operator""_MB(unsigned long long const num) {
-    return num * 1024 * 1024;
-}
-/*
- * SurfaceTracing records layer states during surface flinging. Manages tracing state and
- * configuration.
- */
-class SurfaceTracing {
-public:
-    SurfaceTracing(SurfaceFlinger& flinger);
-    bool enable();
-    bool disable();
-    status_t writeToFile();
-    bool isEnabled() const;
-    /*
-     * Adds a trace entry, must be called from the drawing thread or while holding the
-     * SurfaceFlinger tracing lock.
-     */
-    void notify(const char* where);
-    /*
-     * Adds a trace entry, called while holding the SurfaceFlinger tracing lock.
-     */
-    void notifyLocked(const char* where) /* REQUIRES(mSfLock) */;
-
-    void setBufferSize(size_t bufferSizeInBytes) { mConfig.bufferSize = bufferSizeInBytes; }
-    void dump(std::string& result) const;
-
-    enum : uint32_t {
-        TRACE_CRITICAL = 1 << 0,
-        TRACE_INPUT = 1 << 1,
-        TRACE_COMPOSITION = 1 << 2,
-        TRACE_EXTRA = 1 << 3,
-        TRACE_HWC = 1 << 4,
-        // Add non-geometry composition changes to the trace.
-        TRACE_BUFFERS = 1 << 5,
-        // Add entries from the drawing thread post composition.
-        TRACE_SYNC = 1 << 6,
-        TRACE_ALL = TRACE_CRITICAL | TRACE_INPUT | TRACE_COMPOSITION | TRACE_EXTRA,
-    };
-    void setTraceFlags(uint32_t flags) { mConfig.flags = flags; }
-    bool flagIsSet(uint32_t flags) { return (mConfig.flags & flags) == flags; }
-    static LayersTraceFileProto createLayersTraceFileProto();
-
-private:
-    class Runner;
-    static constexpr auto DEFAULT_BUFFER_SIZE = 20_MB;
-    static constexpr auto DEFAULT_FILE_NAME = "/data/misc/wmtrace/layers_trace.winscope";
-
-    SurfaceFlinger& mFlinger;
-    mutable std::mutex mTraceLock;
-    bool mEnabled GUARDED_BY(mTraceLock) = false;
-    std::unique_ptr<Runner> runner GUARDED_BY(mTraceLock);
-
-    struct Config {
-        uint32_t flags = TRACE_CRITICAL | TRACE_INPUT | TRACE_SYNC;
-        size_t bufferSize = DEFAULT_BUFFER_SIZE;
-    } mConfig;
-
-    /*
-     * ring buffer.
-     */
-    class LayersTraceBuffer {
-    public:
-        size_t size() const { return mSizeInBytes; }
-        size_t used() const { return mUsedInBytes; }
-        size_t frameCount() const { return mStorage.size(); }
-
-        void setSize(size_t newSize) { mSizeInBytes = newSize; }
-        void reset(size_t newSize);
-        void emplace(LayersTraceProto&& proto);
-        void flush(LayersTraceFileProto* fileProto);
-
-    private:
-        size_t mUsedInBytes = 0U;
-        size_t mSizeInBytes = DEFAULT_BUFFER_SIZE;
-        std::queue<LayersTraceProto> mStorage;
-    };
-
-    /*
-     * Implements a synchronous way of adding trace entries. This must be called
-     * from the drawing thread.
-     */
-    class Runner {
-    public:
-        Runner(SurfaceFlinger& flinger, SurfaceTracing::Config& config);
-        virtual ~Runner() = default;
-        virtual status_t stop();
-        virtual status_t writeToFile();
-        virtual void notify(const char* where);
-        /* Cannot be called with a synchronous runner. */
-        virtual void notifyLocked(const char* /* where */) {}
-        void dump(std::string& result) const;
-
-    protected:
-        bool flagIsSet(uint32_t flags) { return (mConfig.flags & flags) == flags; }
-        SurfaceFlinger& mFlinger;
-        SurfaceTracing::Config mConfig;
-        SurfaceTracing::LayersTraceBuffer mBuffer;
-        uint32_t mMissedTraceEntries = 0;
-        LayersTraceProto traceLayers(const char* where);
-    };
-
-    /*
-     * Implements asynchronous way to add trace entries called from a separate thread while holding
-     * the SurfaceFlinger tracing lock. Trace entries may be missed if the tracing thread is not
-     * scheduled in time.
-     */
-    class AsyncRunner : public Runner {
-    public:
-        AsyncRunner(SurfaceFlinger& flinger, SurfaceTracing::Config& config, std::mutex& sfLock);
-        virtual ~AsyncRunner() = default;
-        status_t stop() override;
-        status_t writeToFile() override;
-        void notify(const char* where) override;
-        void notifyLocked(const char* where);
-
-    private:
-        std::mutex& mSfLock;
-        std::condition_variable mCanStartTrace;
-        std::thread mThread;
-        const char* mWhere = "";
-        bool mWriteToFile = false;
-        bool mEnabled = false;
-        bool mAddEntry = false;
-        void loop();
-        bool traceWhenNotified(LayersTraceProto* outProto);
-    };
-};
-
-} // namespace android
diff --git a/services/surfaceflinger/Tracing/LayerTracing.cpp b/services/surfaceflinger/Tracing/LayerTracing.cpp
new file mode 100644
index 0000000..84890ee
--- /dev/null
+++ b/services/surfaceflinger/Tracing/LayerTracing.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2021 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"
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
+#include <SurfaceFlinger.h>
+#include <android-base/stringprintf.h>
+#include <log/log.h>
+#include <utils/SystemClock.h>
+#include <utils/Trace.h>
+
+#include "LayerTracing.h"
+#include "RingBuffer.h"
+
+namespace android {
+
+LayerTracing::LayerTracing(SurfaceFlinger& flinger) : mFlinger(flinger) {
+    mBuffer = std::make_unique<RingBuffer<LayersTraceFileProto, LayersTraceProto>>();
+}
+
+LayerTracing::~LayerTracing() = default;
+
+bool LayerTracing::enable() {
+    std::scoped_lock lock(mTraceLock);
+    if (mEnabled) {
+        return false;
+    }
+    mBuffer->setSize(mBufferSizeInBytes);
+    mEnabled = true;
+    return true;
+}
+
+bool LayerTracing::disable() {
+    std::scoped_lock lock(mTraceLock);
+    if (!mEnabled) {
+        return false;
+    }
+    mEnabled = false;
+    LayersTraceFileProto fileProto = createTraceFileProto();
+    mBuffer->writeToFile(fileProto, FILE_NAME);
+    return true;
+}
+
+bool LayerTracing::isEnabled() const {
+    std::scoped_lock lock(mTraceLock);
+    return mEnabled;
+}
+
+status_t LayerTracing::writeToFile() {
+    std::scoped_lock lock(mTraceLock);
+    if (!mEnabled) {
+        return STATUS_OK;
+    }
+    LayersTraceFileProto fileProto = createTraceFileProto();
+    return mBuffer->writeToFile(fileProto, FILE_NAME);
+}
+
+void LayerTracing::setTraceFlags(uint32_t flags) {
+    std::scoped_lock lock(mTraceLock);
+    mFlags = flags;
+}
+
+void LayerTracing::setBufferSize(size_t bufferSizeInBytes) {
+    std::scoped_lock lock(mTraceLock);
+    mBufferSizeInBytes = bufferSizeInBytes;
+}
+
+bool LayerTracing::flagIsSet(uint32_t flags) const {
+    return (mFlags & flags) == flags;
+}
+
+LayersTraceFileProto LayerTracing::createTraceFileProto() const {
+    LayersTraceFileProto fileProto;
+    fileProto.set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
+                               LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
+    return fileProto;
+}
+
+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::notify(const char* where) {
+    ATRACE_CALL();
+    std::scoped_lock lock(mTraceLock);
+    if (!mEnabled) {
+        return;
+    }
+
+    ATRACE_CALL();
+    LayersTraceProto entry;
+    entry.set_elapsed_realtime_nanos(elapsedRealtimeNano());
+    entry.set_where(where);
+    LayersProto layers(mFlinger.dumpDrawingStateProto(mFlags));
+
+    if (flagIsSet(LayerTracing::TRACE_EXTRA)) {
+        mFlinger.dumpOffscreenLayersProto(layers);
+    }
+    entry.mutable_layers()->Swap(&layers);
+
+    if (flagIsSet(LayerTracing::TRACE_HWC)) {
+        std::string hwcDump;
+        mFlinger.dumpHwc(hwcDump);
+        entry.set_hwc_blob(hwcDump);
+    }
+    if (!flagIsSet(LayerTracing::TRACE_COMPOSITION)) {
+        entry.set_excludes_composition_state(true);
+    }
+    mFlinger.dumpDisplayProto(entry);
+    mBuffer->emplace(std::move(entry));
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/Tracing/LayerTracing.h b/services/surfaceflinger/Tracing/LayerTracing.h
new file mode 100644
index 0000000..8ca3587
--- /dev/null
+++ b/services/surfaceflinger/Tracing/LayerTracing.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2021 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 <android-base/thread_annotations.h>
+#include <layerproto/LayerProtoHeader.h>
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+#include <utils/Timers.h>
+
+#include <memory>
+#include <mutex>
+
+using namespace android::surfaceflinger;
+
+namespace android {
+
+template <typename FileProto, typename EntryProto>
+class RingBuffer;
+
+class SurfaceFlinger;
+
+/*
+ * LayerTracing records layer states during surface flinging. Manages tracing state and
+ * configuration.
+ */
+class LayerTracing {
+public:
+    LayerTracing(SurfaceFlinger& flinger);
+    ~LayerTracing();
+    bool enable();
+    bool disable();
+    bool isEnabled() const;
+    status_t writeToFile();
+    LayersTraceFileProto createTraceFileProto() const;
+    void notify(const char* where);
+
+    enum : uint32_t {
+        TRACE_INPUT = 1 << 1,
+        TRACE_COMPOSITION = 1 << 2,
+        TRACE_EXTRA = 1 << 3,
+        TRACE_HWC = 1 << 4,
+        TRACE_BUFFERS = 1 << 5,
+        TRACE_ALL = TRACE_INPUT | TRACE_COMPOSITION | TRACE_EXTRA,
+    };
+    void setTraceFlags(uint32_t flags);
+    bool flagIsSet(uint32_t flags) const;
+    void setBufferSize(size_t bufferSizeInBytes);
+    void dump(std::string&) const;
+
+private:
+    static constexpr auto FILE_NAME = "/data/misc/wmtrace/layers_trace.winscope";
+
+    SurfaceFlinger& mFlinger;
+    uint32_t mFlags = TRACE_INPUT;
+    mutable std::mutex mTraceLock;
+    bool mEnabled GUARDED_BY(mTraceLock) = false;
+    std::unique_ptr<RingBuffer<LayersTraceFileProto, LayersTraceProto>> mBuffer
+            GUARDED_BY(mTraceLock);
+    size_t mBufferSizeInBytes GUARDED_BY(mTraceLock) = 20 * 1024 * 1024;
+};
+
+} // namespace android
diff --git a/services/surfaceflinger/Tracing/RingBuffer.h b/services/surfaceflinger/Tracing/RingBuffer.h
new file mode 100644
index 0000000..d0fb3f2
--- /dev/null
+++ b/services/surfaceflinger/Tracing/RingBuffer.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2021 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 <android-base/file.h>
+#include <android-base/stringprintf.h>
+
+#include <log/log.h>
+#include <utils/Errors.h>
+#include <utils/SystemClock.h>
+#include <utils/Trace.h>
+#include <queue>
+
+namespace android {
+
+class SurfaceFlinger;
+
+template <typename FileProto, typename EntryProto>
+class RingBuffer {
+public:
+    size_t size() const { return mSizeInBytes; }
+    size_t used() const { return mUsedInBytes; }
+    size_t frameCount() const { return mStorage.size(); }
+    void setSize(size_t newSize) { mSizeInBytes = newSize; }
+    EntryProto& front() { return mStorage.front(); }
+    const EntryProto& front() const { return mStorage.front(); }
+
+    void reset(size_t newSize) {
+        // use the swap trick to make sure memory is released
+        std::queue<EntryProto>().swap(mStorage);
+        mSizeInBytes = newSize;
+        mUsedInBytes = 0U;
+    }
+    void flush(FileProto& fileProto) {
+        fileProto.mutable_entry()->Reserve(static_cast<int>(mStorage.size()));
+        while (!mStorage.empty()) {
+            auto entry = fileProto.add_entry();
+            entry->Swap(&mStorage.front());
+            mStorage.pop();
+        }
+    }
+
+    status_t writeToFile(FileProto& fileProto, std::string filename) {
+        ATRACE_CALL();
+        std::string output;
+        flush(fileProto);
+        reset(mSizeInBytes);
+        if (!fileProto.SerializeToString(&output)) {
+            ALOGE("Could not serialize proto.");
+            return UNKNOWN_ERROR;
+        }
+
+        // -rw-r--r--
+        const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+        if (!android::base::WriteStringToFile(output, filename, mode, getuid(), getgid(), true)) {
+            ALOGE("Could not save the proto file.");
+            return PERMISSION_DENIED;
+        }
+        return NO_ERROR;
+    }
+
+    std::vector<EntryProto> emplace(EntryProto&& proto) {
+        std::vector<EntryProto> replacedEntries;
+        size_t protoSize = static_cast<size_t>(proto.ByteSize());
+        while (mUsedInBytes + protoSize > mSizeInBytes) {
+            if (mStorage.empty()) {
+                return {};
+            }
+            mUsedInBytes -= static_cast<size_t>(mStorage.front().ByteSize());
+            replacedEntries.emplace_back(mStorage.front());
+            mStorage.pop();
+        }
+        mUsedInBytes += protoSize;
+        mStorage.emplace();
+        mStorage.back().Swap(&proto);
+        return replacedEntries;
+    }
+
+    void dump(std::string& result) const {
+        std::chrono::milliseconds duration(0);
+        if (frameCount() > 0) {
+            duration = std::chrono::duration_cast<std::chrono::milliseconds>(
+                    std::chrono::nanoseconds(systemTime() - front().elapsed_realtime_nanos()));
+        }
+        const int64_t durationCount = duration.count();
+        base::StringAppendF(&result,
+                            "  number of entries: %zu (%.2fMB / %.2fMB) duration: %" PRIi64 "ms\n",
+                            frameCount(), float(used()) / 1024.f * 1024.f,
+                            float(size()) / 1024.f * 1024.f, durationCount);
+    }
+
+private:
+    size_t mUsedInBytes = 0U;
+    size_t mSizeInBytes = 0U;
+    std::queue<EntryProto> mStorage;
+};
+
+} // namespace android