SurfaceFlinger: protect state members in Layer

Add proper locking to protect state members in Layer.
These members are accessed by both the main thread and binder.

Bug: 119481871
Test: SurfaceFlinger unit tests
Test: go/wm-smoke
Change-Id: I12d47711992e09c0677b77f7e1b36c1254b63a1b
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 9b1c0db..e4fcfc8 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -396,6 +396,7 @@
     }
 
     // Capture the old state of the layer for comparisons later
+    Mutex::Autolock lock(mStateMutex);
     const State& s(getDrawingState());
     const bool oldOpacity = isOpaque(s);
     sp<GraphicBuffer> oldBuffer = mActiveBuffer;
@@ -503,7 +504,7 @@
 
     // FIXME: postedRegion should be dirty & bounds
     // transform the dirty region to window-manager space
-    return getTransform().transform(Region(getBufferSize(s)));
+    return getTransformLocked().transform(Region(getBufferSize(s)));
 }
 
 // transaction
@@ -551,7 +552,7 @@
 
 // h/w composer set-up
 bool BufferLayer::allTransactionsSignaled() {
-    auto headFrameNumber = getHeadFrameNumber();
+    auto headFrameNumber = getHeadFrameNumberLocked();
     bool matchingFramesFound = false;
     bool allTransactionsApplied = true;
     Mutex::Autolock lock(mLocalSyncPointMutex);
@@ -604,6 +605,7 @@
 
 void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const {
     ATRACE_CALL();
+    Mutex::Autolock lock(mStateMutex);
     const State& s(getDrawingState());
 
     computeGeometry(renderArea, getBE().mMesh, useIdentityTransform);
@@ -622,9 +624,9 @@
      * minimal value)? Or, we could make GL behave like HWC -- but this feel
      * like more of a hack.
      */
-    const Rect bounds{computeBounds()}; // Rounds from FloatRect
+    const Rect bounds{computeBoundsLocked()}; // Rounds from FloatRect
 
-    ui::Transform t = getTransform();
+    ui::Transform t = getTransformLocked();
     Rect win = bounds;
     const int bufferWidth = getBufferSize(s).getWidth();
     const int bufferHeight = getBufferSize(s).getHeight();
@@ -643,7 +645,7 @@
     texCoords[2] = vec2(right, 1.0f - bottom);
     texCoords[3] = vec2(right, 1.0f - top);
 
-    const auto roundedCornerState = getRoundedCornerState();
+    const auto roundedCornerState = getRoundedCornerStateLocked();
     const auto cropRect = roundedCornerState.cropRect;
     setupRoundedCornersCropCoordinates(win, cropRect);
 
@@ -665,7 +667,12 @@
 }
 
 uint64_t BufferLayer::getHeadFrameNumber() const {
-    if (hasFrameUpdate()) {
+    Mutex::Autolock lock(mStateMutex);
+    return getHeadFrameNumberLocked();
+}
+
+uint64_t BufferLayer::getHeadFrameNumberLocked() const {
+    if (hasFrameUpdateLocked()) {
         return getFrameNumber();
     } else {
         return mCurrentFrameNumber;
@@ -692,7 +699,7 @@
         std::swap(bufWidth, bufHeight);
     }
 
-    if (getTransformToDisplayInverse()) {
+    if (getTransformToDisplayInverseLocked()) {
         uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform();
         if (invTransform & ui::Transform::ROT_90) {
             std::swap(bufWidth, bufHeight);
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index 690a4e5..55d68f6 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -69,7 +69,7 @@
     bool isOpaque(const Layer::State& s) const override;
 
     // isVisible - true if this layer is visible, false otherwise
-    bool isVisible() const override;
+    bool isVisible() const override EXCLUDES(mStateMutex);
 
     // isFixedSize - true if content has a fixed size
     bool isFixedSize() const override;
@@ -87,7 +87,7 @@
     bool onPostComposition(const std::optional<DisplayId>& displayId,
                            const std::shared_ptr<FenceTime>& glDoneFence,
                            const std::shared_ptr<FenceTime>& presentFence,
-                           const CompositorTiming& compositorTiming) override;
+                           const CompositorTiming& compositorTiming) override EXCLUDES(mStateMutex);
 
     // latchBuffer - called each time the screen is redrawn and returns whether
     // the visible regions need to be recomputed (this is a fairly heavy
@@ -97,13 +97,13 @@
     // releaseFence will be populated with a native fence that fires when
     // composition has completed.
     Region latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
-                       const sp<Fence>& releaseFence) override;
+                       const sp<Fence>& releaseFence) override EXCLUDES(mStateMutex);
 
     bool isBufferLatched() const override { return mRefreshPending; }
 
     void notifyAvailableFrames() override;
 
-    bool hasReadyFrame() const override;
+    bool hasReadyFrame() const override EXCLUDES(mStateMutex);
 
     // Returns the current scaling mode, unless mOverrideScalingMode
     // is set, in which case, it returns mOverrideScalingMode
@@ -114,19 +114,24 @@
     // Functions that must be implemented by derived classes
     // -----------------------------------------------------------------------
 private:
-    virtual bool fenceHasSignaled() const = 0;
+    virtual bool fenceHasSignaled() const EXCLUDES(mStateMutex) = 0;
 
     virtual nsecs_t getDesiredPresentTime() = 0;
-    virtual std::shared_ptr<FenceTime> getCurrentFenceTime() const = 0;
+    std::shared_ptr<FenceTime> getCurrentFenceTime() const EXCLUDES(mStateMutex) {
+        Mutex::Autolock lock(mStateMutex);
+        return getCurrentFenceTimeLocked();
+    }
+
+    virtual std::shared_ptr<FenceTime> getCurrentFenceTimeLocked() const REQUIRES(mStateMutex) = 0;
 
     virtual void getDrawingTransformMatrix(float *matrix) = 0;
-    virtual uint32_t getDrawingTransform() const = 0;
-    virtual ui::Dataspace getDrawingDataSpace() const = 0;
-    virtual Rect getDrawingCrop() const = 0;
+    virtual uint32_t getDrawingTransform() const REQUIRES(mStateMutex) = 0;
+    virtual ui::Dataspace getDrawingDataSpace() const REQUIRES(mStateMutex) = 0;
+    virtual Rect getDrawingCrop() const REQUIRES(mStateMutex) = 0;
     virtual uint32_t getDrawingScalingMode() const = 0;
-    virtual Region getDrawingSurfaceDamage() const = 0;
-    virtual const HdrMetadata& getDrawingHdrMetadata() const = 0;
-    virtual int getDrawingApi() const = 0;
+    virtual Region getDrawingSurfaceDamage() const EXCLUDES(mStateMutex) = 0;
+    virtual const HdrMetadata& getDrawingHdrMetadata() const EXCLUDES(mStateMutex) = 0;
+    virtual int getDrawingApi() const EXCLUDES(mStateMutex) = 0;
     virtual PixelFormat getPixelFormat() const = 0;
 
     virtual uint64_t getFrameNumber() const = 0;
@@ -134,20 +139,21 @@
     virtual bool getAutoRefresh() const = 0;
     virtual bool getSidebandStreamChanged() const = 0;
 
-    virtual std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) = 0;
+    virtual std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions)
+            EXCLUDES(mStateMutex) = 0;
 
-    virtual bool hasFrameUpdate() const = 0;
+    virtual bool hasFrameUpdateLocked() const REQUIRES(mStateMutex) = 0;
 
     virtual void setFilteringEnabled(bool enabled) = 0;
 
-    virtual status_t bindTextureImage() = 0;
+    virtual status_t bindTextureImage() EXCLUDES(mStateMutex) = 0;
     virtual status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
-                                    const sp<Fence>& flushFence) = 0;
+                                    const sp<Fence>& flushFence) REQUIRES(mStateMutex) = 0;
 
-    virtual status_t updateActiveBuffer() = 0;
+    virtual status_t updateActiveBuffer() REQUIRES(mStateMutex) = 0;
     virtual status_t updateFrameNumber(nsecs_t latchTime) = 0;
 
-    virtual void setHwcLayerBuffer(DisplayId displayId) = 0;
+    virtual void setHwcLayerBuffer(DisplayId displayId) EXCLUDES(mStateMutex) = 0;
 
     // -----------------------------------------------------------------------
 
@@ -163,10 +169,15 @@
     // Check all of the local sync points to ensure that all transactions
     // which need to have been applied prior to the frame which is about to
     // be latched have signaled
-    bool allTransactionsSignaled();
+    bool allTransactionsSignaled() REQUIRES(mStateMutex);
 
     static bool getOpacityForFormat(uint32_t format);
 
+    bool hasFrameUpdate() const EXCLUDES(mStateMutex) {
+        Mutex::Autolock lock(mStateMutex);
+        return hasFrameUpdateLocked();
+    }
+
     // from GLES
     const uint32_t mTextureName;
 
@@ -175,9 +186,12 @@
     bool needsFiltering(const RenderArea& renderArea) const;
 
     // drawing
-    void drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const;
+    void drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const
+            EXCLUDES(mStateMutex);
 
-    uint64_t getHeadFrameNumber() const;
+    uint64_t getHeadFrameNumber() const EXCLUDES(mStateMutex);
+
+    uint64_t getHeadFrameNumberLocked() const REQUIRES(mStateMutex);
 
     uint32_t mCurrentScalingMode{NATIVE_WINDOW_SCALING_MODE_FREEZE};
 
@@ -189,7 +203,7 @@
 
     bool mRefreshPending{false};
 
-    Rect getBufferSize(const State& s) const override;
+    Rect getBufferSize(const State& s) const override REQUIRES(mStateMutex);
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index b784d11..70d52f1 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -51,7 +51,7 @@
     return history;
 }
 
-bool BufferQueueLayer::getTransformToDisplayInverse() const {
+bool BufferQueueLayer::getTransformToDisplayInverseLocked() const {
     return mConsumer->getTransformToDisplayInverse();
 }
 
@@ -131,7 +131,7 @@
     return mConsumer->getTimestamp();
 }
 
-std::shared_ptr<FenceTime> BufferQueueLayer::getCurrentFenceTime() const {
+std::shared_ptr<FenceTime> BufferQueueLayer::getCurrentFenceTimeLocked() const {
     return mConsumer->getCurrentFenceTime();
 }
 
@@ -192,6 +192,7 @@
 
 std::optional<Region> BufferQueueLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
     bool sidebandStreamChanged = true;
+    Mutex::Autolock lock(mStateMutex);
     if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, false)) {
         // mSidebandStreamChanged was changed to false
         // replicated in LayerBE until FE/BE is ready to be synchronized
@@ -200,15 +201,15 @@
             setTransactionFlags(eTransactionNeeded);
             mFlinger->setTransactionFlags(eTraversalNeeded);
         }
-        recomputeVisibleRegions = true;
 
+        recomputeVisibleRegions = true;
         const State& s(getDrawingState());
-        return getTransform().transform(Region(Rect(s.active_legacy.w, s.active_legacy.h)));
+        return getTransformLocked().transform(Region(Rect(s.active_legacy.w, s.active_legacy.h)));
     }
     return {};
 }
 
-bool BufferQueueLayer::hasFrameUpdate() const {
+bool BufferQueueLayer::hasFrameUpdateLocked() const {
     return mQueuedFrames > 0;
 }
 
@@ -228,16 +229,18 @@
     // buffer mode.
     bool queuedBuffer = false;
     const int32_t layerID = getSequence();
-    LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
+    status_t updateResult;
+    LayerRejecter r(mState.drawing, getCurrentState(), recomputeVisibleRegions,
                     getProducerStickyTransform() != 0, mName.string(), mOverrideScalingMode,
-                    getTransformToDisplayInverse(), mFreezeGeometryUpdates);
+                    getTransformToDisplayInverseLocked(), mFreezeGeometryUpdates);
 
     const nsecs_t expectedPresentTime = mFlinger->mUseScheduler
             ? mFlinger->mScheduler->mPrimaryDispSync->expectedPresentTime()
             : mFlinger->mPrimaryDispSync->expectedPresentTime();
-    status_t updateResult =
-            mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh, &queuedBuffer,
-                                      mLastFrameNumberReceived, releaseFence);
+
+    updateResult = mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh, &queuedBuffer,
+                                             mLastFrameNumberReceived, releaseFence);
+
     if (updateResult == BufferQueue::PRESENT_LATER) {
         // Producer doesn't want buffer to be displayed yet.  Signal a
         // layer update so we check again at the next opportunity.
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index ae0b705..f9da044 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -44,7 +44,7 @@
 
     std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush) override;
 
-    bool getTransformToDisplayInverse() const override;
+    bool getTransformToDisplayInverseLocked() const override REQUIRES(mStateMutex);
 
     // If a buffer was replaced this frame, release the former buffer
     void releasePendingBuffer(nsecs_t dequeueReadyTime) override;
@@ -64,12 +64,12 @@
 
 private:
     nsecs_t getDesiredPresentTime() override;
-    std::shared_ptr<FenceTime> getCurrentFenceTime() const override;
+    std::shared_ptr<FenceTime> getCurrentFenceTimeLocked() const override REQUIRES(mStateMutex);
 
     void getDrawingTransformMatrix(float *matrix) override;
-    uint32_t getDrawingTransform() const override;
-    ui::Dataspace getDrawingDataSpace() const override;
-    Rect getDrawingCrop() const override;
+    uint32_t getDrawingTransform() const override REQUIRES(mStateMutex);
+    ui::Dataspace getDrawingDataSpace() const override REQUIRES(mStateMutex);
+    Rect getDrawingCrop() const override REQUIRES(mStateMutex);
     uint32_t getDrawingScalingMode() const override;
     Region getDrawingSurfaceDamage() const override;
     const HdrMetadata& getDrawingHdrMetadata() const override;
@@ -81,17 +81,18 @@
     bool getAutoRefresh() const override;
     bool getSidebandStreamChanged() const override;
 
-    std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override;
+    std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override
+            EXCLUDES(mStateMutex);
 
-    bool hasFrameUpdate() const override;
+    bool hasFrameUpdateLocked() const override REQUIRES(mStateMutex);
 
     void setFilteringEnabled(bool enabled) override;
 
     status_t bindTextureImage() override;
     status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
-                            const sp<Fence>& releaseFence) override;
+                            const sp<Fence>& releaseFence) override REQUIRES(mStateMutex);
 
-    status_t updateActiveBuffer() override;
+    status_t updateActiveBuffer() override REQUIRES(mStateMutex);
     status_t updateFrameNumber(nsecs_t latchTime) override;
 
     void setHwcLayerBuffer(DisplayId displayId) override;
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index efc2c9f..8091b94 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -70,30 +70,31 @@
 }
 
 bool BufferStateLayer::willPresentCurrentTransaction() const {
+    Mutex::Autolock lock(mStateMutex);
     // Returns true if the most recent Transaction applied to CurrentState will be presented.
     return getSidebandStreamChanged() || getAutoRefresh() ||
-            (mCurrentState.modified && mCurrentState.buffer != nullptr);
+            (mState.current.modified && mState.current.buffer != nullptr);
 }
 
-bool BufferStateLayer::getTransformToDisplayInverse() const {
-    return mCurrentState.transformToDisplayInverse;
+bool BufferStateLayer::getTransformToDisplayInverseLocked() const {
+    return mState.current.transformToDisplayInverse;
 }
 
-void BufferStateLayer::pushPendingState() {
-    if (!mCurrentState.modified) {
+void BufferStateLayer::pushPendingStateLocked() {
+    if (!mState.current.modified) {
         return;
     }
-    mPendingStates.push_back(mCurrentState);
-    ATRACE_INT(mTransactionName.string(), mPendingStates.size());
+    mState.pending.push_back(mState.current);
+    ATRACE_INT(mTransactionName.string(), mState.pending.size());
 }
 
 bool BufferStateLayer::applyPendingStates(Layer::State* stateToCommit) {
-    const bool stateUpdateAvailable = !mPendingStates.empty();
-    while (!mPendingStates.empty()) {
+    const bool stateUpdateAvailable = !mState.pending.empty();
+    while (!mState.pending.empty()) {
         popPendingState(stateToCommit);
     }
-    mCurrentStateModified = stateUpdateAvailable && mCurrentState.modified;
-    mCurrentState.modified = false;
+    mCurrentStateModified = stateUpdateAvailable && mState.current.modified;
+    mState.current.modified = false;
     return stateUpdateAvailable;
 }
 
@@ -103,28 +104,31 @@
 }
 
 bool BufferStateLayer::setTransform(uint32_t transform) {
-    if (mCurrentState.transform == transform) return false;
-    mCurrentState.sequence++;
-    mCurrentState.transform = transform;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.transform == transform) return false;
+    mState.current.sequence++;
+    mState.current.transform = transform;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInverse) {
-    if (mCurrentState.transformToDisplayInverse == transformToDisplayInverse) return false;
-    mCurrentState.sequence++;
-    mCurrentState.transformToDisplayInverse = transformToDisplayInverse;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.transformToDisplayInverse == transformToDisplayInverse) return false;
+    mState.current.sequence++;
+    mState.current.transformToDisplayInverse = transformToDisplayInverse;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setCrop(const Rect& crop) {
-    if (mCurrentState.crop == crop) return false;
-    mCurrentState.sequence++;
-    mCurrentState.crop = crop;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.crop == crop) return false;
+    mState.current.sequence++;
+    mState.current.crop = crop;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
@@ -135,86 +139,94 @@
     int w = frame.getWidth();
     int h = frame.getHeight();
 
-    if (mCurrentState.active.transform.tx() == x && mCurrentState.active.transform.ty() == y &&
-        mCurrentState.active.w == w && mCurrentState.active.h == h) {
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.active.transform.tx() == x && mState.current.active.transform.ty() == y &&
+        mState.current.active.w == w && mState.current.active.h == h) {
         return false;
     }
 
     if (!frame.isValid()) {
         x = y = w = h = 0;
     }
-    mCurrentState.active.transform.set(x, y);
-    mCurrentState.active.w = w;
-    mCurrentState.active.h = h;
+    mState.current.active.transform.set(x, y);
+    mState.current.active.w = w;
+    mState.current.active.h = h;
 
-    mCurrentState.sequence++;
-    mCurrentState.modified = true;
+    mState.current.sequence++;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer) {
-    if (mCurrentState.buffer) {
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.buffer) {
         mReleasePreviousBuffer = true;
     }
 
-    mCurrentState.sequence++;
-    mCurrentState.buffer = buffer;
-    mCurrentState.modified = true;
+    mState.current.sequence++;
+    mState.current.buffer = buffer;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setAcquireFence(const sp<Fence>& fence) {
+    Mutex::Autolock lock(mStateMutex);
     // The acquire fences of BufferStateLayers have already signaled before they are set
     mCallbackHandleAcquireTime = fence->getSignalTime();
 
-    mCurrentState.acquireFence = fence;
-    mCurrentState.modified = true;
+    mState.current.acquireFence = fence;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setDataspace(ui::Dataspace dataspace) {
-    if (mCurrentState.dataspace == dataspace) return false;
-    mCurrentState.sequence++;
-    mCurrentState.dataspace = dataspace;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.dataspace == dataspace) return false;
+    mState.current.sequence++;
+    mState.current.dataspace = dataspace;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setHdrMetadata(const HdrMetadata& hdrMetadata) {
-    if (mCurrentState.hdrMetadata == hdrMetadata) return false;
-    mCurrentState.sequence++;
-    mCurrentState.hdrMetadata = hdrMetadata;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.hdrMetadata == hdrMetadata) return false;
+    mState.current.sequence++;
+    mState.current.hdrMetadata = hdrMetadata;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setSurfaceDamageRegion(const Region& surfaceDamage) {
-    mCurrentState.sequence++;
-    mCurrentState.surfaceDamageRegion = surfaceDamage;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.sequence++;
+    mState.current.surfaceDamageRegion = surfaceDamage;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setApi(int32_t api) {
-    if (mCurrentState.api == api) return false;
-    mCurrentState.sequence++;
-    mCurrentState.api = api;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.api == api) return false;
+    mState.current.sequence++;
+    mState.current.api = api;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setSidebandStream(const sp<NativeHandle>& sidebandStream) {
-    if (mCurrentState.sidebandStream == sidebandStream) return false;
-    mCurrentState.sequence++;
-    mCurrentState.sidebandStream = sidebandStream;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.sidebandStream == sidebandStream) return false;
+    mState.current.sequence++;
+    mState.current.sidebandStream = sidebandStream;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
 
     if (!mSidebandStreamChanged.exchange(true)) {
@@ -248,7 +260,10 @@
             mFlinger->getTransactionCompletedThread().registerPendingLatchedCallbackHandle(handle);
 
             // Store so latched time and release fence can be set
-            mCurrentState.callbackHandles.push_back(handle);
+            {
+                Mutex::Autolock lock(mStateMutex);
+                mState.current.callbackHandles.push_back(handle);
+            }
 
         } else { // If this layer will NOT need to be relatched and presented this frame
             // Notify the transaction completed thread this handle is done
@@ -263,8 +278,9 @@
 }
 
 bool BufferStateLayer::setTransparentRegionHint(const Region& transparent) {
-    mCurrentState.transparentRegionHint = transparent;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.transparentRegionHint = transparent;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
@@ -300,6 +316,7 @@
         return true;
     }
 
+    Mutex::Autolock lock(mStateMutex);
     return getDrawingState().acquireFence->getStatus() == Fence::Status::Signaled;
 }
 
@@ -308,7 +325,7 @@
     return 0;
 }
 
-std::shared_ptr<FenceTime> BufferStateLayer::getCurrentFenceTime() const {
+std::shared_ptr<FenceTime> BufferStateLayer::getCurrentFenceTimeLocked() const {
     return std::make_shared<FenceTime>(getDrawingState().acquireFence);
 }
 
@@ -339,14 +356,17 @@
 }
 
 Region BufferStateLayer::getDrawingSurfaceDamage() const {
+    Mutex::Autolock lock(mStateMutex);
     return getDrawingState().surfaceDamageRegion;
 }
 
 const HdrMetadata& BufferStateLayer::getDrawingHdrMetadata() const {
+    Mutex::Autolock lock(mStateMutex);
     return getDrawingState().hdrMetadata;
 }
 
 int BufferStateLayer::getDrawingApi() const {
+    Mutex::Autolock lock(mStateMutex);
     return getDrawingState().api;
 }
 
@@ -371,6 +391,7 @@
 }
 
 std::optional<Region> BufferStateLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
+    Mutex::Autolock lock(mStateMutex);
     if (mSidebandStreamChanged.exchange(false)) {
         const State& s(getDrawingState());
         // mSidebandStreamChanged was true
@@ -382,12 +403,12 @@
         }
         recomputeVisibleRegions = true;
 
-        return getTransform().transform(Region(Rect(s.active.w, s.active.h)));
+        return getTransformLocked().transform(Region(Rect(s.active.w, s.active.h)));
     }
     return {};
 }
 
-bool BufferStateLayer::hasFrameUpdate() const {
+bool BufferStateLayer::hasFrameUpdateLocked() const {
     return mCurrentStateModified && getCurrentState().buffer != nullptr;
 }
 
@@ -397,6 +418,10 @@
 }
 
 status_t BufferStateLayer::bindTextureImage() {
+    Mutex::Autolock lock(mStateMutex);
+    return bindTextureImageLocked();
+}
+status_t BufferStateLayer::bindTextureImageLocked() {
     const State& s(getDrawingState());
     auto& engine(mFlinger->getRenderEngine());
 
@@ -501,7 +526,7 @@
         auto incomingStatus = releaseFence->getStatus();
         if (incomingStatus == Fence::Status::Invalid) {
             ALOGE("New fence has invalid state");
-            mDrawingState.acquireFence = releaseFence;
+            mState.drawing.acquireFence = releaseFence;
             mFlinger->mTimeStats->onDestroy(layerID);
             return BAD_VALUE;
         }
@@ -512,16 +537,16 @@
             char fenceName[32] = {};
             snprintf(fenceName, 32, "%.28s:%d", mName.string(), mFrameNumber);
             sp<Fence> mergedFence =
-                    Fence::merge(fenceName, mDrawingState.acquireFence, releaseFence);
+                    Fence::merge(fenceName, mState.drawing.acquireFence, releaseFence);
             if (!mergedFence.get()) {
                 ALOGE("failed to merge release fences");
                 // synchronization is broken, the best we can do is hope fences
                 // signal in order so the new fence will act like a union
-                mDrawingState.acquireFence = releaseFence;
+                mState.drawing.acquireFence = releaseFence;
                 mFlinger->mTimeStats->onDestroy(layerID);
                 return BAD_VALUE;
             }
-            mDrawingState.acquireFence = mergedFence;
+            mState.drawing.acquireFence = mergedFence;
         } else if (incomingStatus == Fence::Status::Unsignaled) {
             // If one fence has signaled and the other hasn't, the unsignaled
             // fence will approximately correspond with the correct timestamp.
@@ -530,7 +555,7 @@
             // by this point, they will have both signaled and only the timestamp
             // will be slightly off; any dependencies after this point will
             // already have been met.
-            mDrawingState.acquireFence = releaseFence;
+            mState.drawing.acquireFence = releaseFence;
         }
     } else {
         // Bind the new buffer to the GL texture.
@@ -539,7 +564,7 @@
         // by glEGLImageTargetTexture2DOES, which this method calls.  Newer
         // devices will either call this in Layer::onDraw, or (if it's not
         // a GL-composited layer) not at all.
-        status_t err = bindTextureImage();
+        status_t err = bindTextureImageLocked();
         if (err != NO_ERROR) {
             mFlinger->mTimeStats->onDestroy(layerID);
             return BAD_VALUE;
@@ -548,7 +573,7 @@
 
     // TODO(marissaw): properly support mTimeStats
     mFlinger->mTimeStats->setPostTime(layerID, getFrameNumber(), getName().c_str(), latchTime);
-    mFlinger->mTimeStats->setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTime());
+    mFlinger->mTimeStats->setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTimeLocked());
     mFlinger->mTimeStats->setLatchTime(layerID, getFrameNumber(), latchTime);
 
     return NO_ERROR;
@@ -575,6 +600,7 @@
 }
 
 void BufferStateLayer::setHwcLayerBuffer(DisplayId displayId) {
+    Mutex::Autolock lock(mStateMutex);
     auto& hwcInfo = getBE().mHwcLayers[displayId];
     auto& hwcLayer = hwcInfo.layer;
 
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 3f891d3..655353c 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -41,13 +41,14 @@
 
     bool shouldPresentNow(nsecs_t expectedPresentTime) const override;
 
-    bool getTransformToDisplayInverse() const override;
+    bool getTransformToDisplayInverseLocked() const override REQUIRES(mStateMutex);
 
     uint32_t doTransactionResize(uint32_t flags, Layer::State* /*stateToCommit*/) override {
         return flags;
     }
-    void pushPendingState() override;
-    bool applyPendingStates(Layer::State* stateToCommit) override;
+
+    void pushPendingStateLocked() override REQUIRES(mStateMutex);
+    bool applyPendingStates(Layer::State* stateToCommit) override REQUIRES(mStateMutex);
 
     uint32_t getActiveWidth(const Layer::State& s) const override { return s.active.w; }
     uint32_t getActiveHeight(const Layer::State& s) const override { return s.active.h; }
@@ -59,18 +60,20 @@
     }
     Rect getCrop(const Layer::State& s) const;
 
-    bool setTransform(uint32_t transform) override;
-    bool setTransformToDisplayInverse(bool transformToDisplayInverse) override;
-    bool setCrop(const Rect& crop) override;
-    bool setFrame(const Rect& frame) override;
-    bool setBuffer(const sp<GraphicBuffer>& buffer) override;
-    bool setAcquireFence(const sp<Fence>& fence) override;
-    bool setDataspace(ui::Dataspace dataspace) override;
-    bool setHdrMetadata(const HdrMetadata& hdrMetadata) override;
-    bool setSurfaceDamageRegion(const Region& surfaceDamage) override;
-    bool setApi(int32_t api) override;
-    bool setSidebandStream(const sp<NativeHandle>& sidebandStream) override;
-    bool setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles) override;
+    bool setTransform(uint32_t transform) override EXCLUDES(mStateMutex);
+    bool setTransformToDisplayInverse(bool transformToDisplayInverse) override
+            EXCLUDES(mStateMutex);
+    bool setCrop(const Rect& crop) override EXCLUDES(mStateMutex);
+    bool setFrame(const Rect& frame) override EXCLUDES(mStateMutex);
+    bool setBuffer(const sp<GraphicBuffer>& buffer) override EXCLUDES(mStateMutex);
+    bool setAcquireFence(const sp<Fence>& fence) override EXCLUDES(mStateMutex);
+    bool setDataspace(ui::Dataspace dataspace) override EXCLUDES(mStateMutex);
+    bool setHdrMetadata(const HdrMetadata& hdrMetadata) override EXCLUDES(mStateMutex);
+    bool setSurfaceDamageRegion(const Region& surfaceDamage) override EXCLUDES(mStateMutex);
+    bool setApi(int32_t api) override EXCLUDES(mStateMutex);
+    bool setSidebandStream(const sp<NativeHandle>& sidebandStream) override EXCLUDES(mStateMutex);
+    bool setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles) override
+            EXCLUDES(mStateMutex);
 
     // Override to ignore legacy layer state properties that are not used by BufferStateLayer
     bool setSize(uint32_t /*w*/, uint32_t /*h*/) override { return false; }
@@ -87,26 +90,26 @@
     void deferTransactionUntil_legacy(const sp<Layer>& /*barrierLayer*/,
                                       uint64_t /*frameNumber*/) override {}
 
-    Rect getBufferSize(const State& s) const override;
+    Rect getBufferSize(const State& s) const override REQUIRES(mStateMutex);
     // -----------------------------------------------------------------------
 
     // -----------------------------------------------------------------------
     // Interface implementation for BufferLayer
     // -----------------------------------------------------------------------
-    bool fenceHasSignaled() const override;
+    bool fenceHasSignaled() const override EXCLUDES(mStateMutex);
 
 private:
     nsecs_t getDesiredPresentTime() override;
-    std::shared_ptr<FenceTime> getCurrentFenceTime() const override;
+    std::shared_ptr<FenceTime> getCurrentFenceTimeLocked() const override REQUIRES(mStateMutex);
 
     void getDrawingTransformMatrix(float *matrix) override;
-    uint32_t getDrawingTransform() const override;
-    ui::Dataspace getDrawingDataSpace() const override;
-    Rect getDrawingCrop() const override;
+    uint32_t getDrawingTransform() const override REQUIRES(mStateMutex);
+    ui::Dataspace getDrawingDataSpace() const override REQUIRES(mStateMutex);
+    Rect getDrawingCrop() const override REQUIRES(mStateMutex);
     uint32_t getDrawingScalingMode() const override;
-    Region getDrawingSurfaceDamage() const override;
-    const HdrMetadata& getDrawingHdrMetadata() const override;
-    int getDrawingApi() const override;
+    Region getDrawingSurfaceDamage() const override EXCLUDES(mStateMutex);
+    const HdrMetadata& getDrawingHdrMetadata() const override EXCLUDES(mStateMutex);
+    int getDrawingApi() const override EXCLUDES(mStateMutex);
     PixelFormat getPixelFormat() const override;
 
     uint64_t getFrameNumber() const override;
@@ -114,24 +117,26 @@
     bool getAutoRefresh() const override;
     bool getSidebandStreamChanged() const override;
 
-    std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override;
+    std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override
+            EXCLUDES(mStateMutex);
 
-    bool hasFrameUpdate() const override;
+    bool hasFrameUpdateLocked() const override REQUIRES(mStateMutex);
 
     void setFilteringEnabled(bool enabled) override;
 
-    status_t bindTextureImage() override;
+    status_t bindTextureImage() override EXCLUDES(mStateMutex);
     status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
-                            const sp<Fence>& releaseFence) override;
+                            const sp<Fence>& releaseFence) override REQUIRES(mStateMutex);
 
-    status_t updateActiveBuffer() override;
+    status_t updateActiveBuffer() override REQUIRES(mStateMutex);
     status_t updateFrameNumber(nsecs_t latchTime) override;
 
-    void setHwcLayerBuffer(DisplayId displayId) override;
+    void setHwcLayerBuffer(DisplayId displayId) override EXCLUDES(mStateMutex);
 
 private:
     void onFirstRef() override;
     bool willPresentCurrentTransaction() const;
+    status_t bindTextureImageLocked() REQUIRES(mStateMutex);
 
     static const std::array<float, 16> IDENTITY_MATRIX;
 
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index f27f6aa..cb7642e 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -40,15 +40,16 @@
 
 void ColorLayer::onDraw(const RenderArea& renderArea, const Region& /* clip */,
                         bool useIdentityTransform) {
+    Mutex::Autolock lock(mStateMutex);
     half4 color = getColor();
     if (color.a > 0) {
         renderengine::Mesh mesh(renderengine::Mesh::TRIANGLE_FAN, 4, 2);
         computeGeometry(renderArea, mesh, useIdentityTransform);
         auto& engine(mFlinger->getRenderEngine());
 
-        Rect win{computeBounds()};
+        Rect win{computeBoundsLocked()};
 
-        const auto roundedCornerState = getRoundedCornerState();
+        const auto roundedCornerState = getRoundedCornerStateLocked();
         const auto cropRect = roundedCornerState.cropRect;
         setupRoundedCornersCropCoordinates(win, cropRect);
 
@@ -91,6 +92,7 @@
     }
     getBE().compositionInfo.hwc.dataspace = mCurrentDataSpace;
 
+    Mutex::Autolock lock(mStateMutex);
     half4 color = getColor();
     error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)),
                                 static_cast<uint8_t>(std::round(255.0f * color.g)),
@@ -111,12 +113,12 @@
     }
     getBE().compositionInfo.hwc.transform = HWC2::Transform::None;
 
-    error = hwcLayer->setColorTransform(getColorTransform());
+    error = hwcLayer->setColorTransform(getColorTransformLocked());
     if (error != HWC2::Error::None) {
         ALOGE("[%s] Failed to setColorTransform: %s (%d)", mName.string(),
                 to_string(error).c_str(), static_cast<int32_t>(error));
     }
-    getBE().compositionInfo.hwc.colorTransform = getColorTransform();
+    getBE().compositionInfo.hwc.colorTransform = getColorTransformLocked();
 
     error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
     if (error != HWC2::Error::None) {
diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h
index d1b1697..5850a2e 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -29,12 +29,12 @@
     ~ColorLayer() override;
 
     virtual const char* getTypeId() const { return "ColorLayer"; }
-    virtual void onDraw(const RenderArea& renderArea, const Region& clip,
-                        bool useIdentityTransform);
-    bool isVisible() const override;
+    virtual void onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform)
+            EXCLUDES(mStateMutex);
+    bool isVisible() const override EXCLUDES(mStateMutex);
 
     void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport,
-                         int32_t supportedPerFrameMetadata) override;
+                         int32_t supportedPerFrameMetadata) override EXCLUDES(mStateMutex);
 
     bool onPreComposition(nsecs_t /*refreshStartTime*/) override { return false; }
 
diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h
index 413844b..6c4f7c8 100644
--- a/services/surfaceflinger/ContainerLayer.h
+++ b/services/surfaceflinger/ContainerLayer.h
@@ -31,7 +31,7 @@
     const char* getTypeId() const override { return "ContainerLayer"; }
     void onDraw(const RenderArea& renderArea, const Region& clip,
                 bool useIdentityTransform) override;
-    bool isVisible() const override;
+    bool isVisible() const override EXCLUDES(mStateMutex);
 
     void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport,
                          int32_t supportedPerFrameMetadata) override;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 6d0fdad..f4b3cdd 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -83,35 +83,35 @@
 
     mTransactionName = String8("TX - ") + mName;
 
-    mCurrentState.active_legacy.w = args.w;
-    mCurrentState.active_legacy.h = args.h;
-    mCurrentState.flags = layerFlags;
-    mCurrentState.active_legacy.transform.set(0, 0);
-    mCurrentState.crop_legacy.makeInvalid();
-    mCurrentState.requestedCrop_legacy = mCurrentState.crop_legacy;
-    mCurrentState.z = 0;
-    mCurrentState.color.a = 1.0f;
-    mCurrentState.layerStack = 0;
-    mCurrentState.sequence = 0;
-    mCurrentState.requested_legacy = mCurrentState.active_legacy;
-    mCurrentState.appId = 0;
-    mCurrentState.type = 0;
-    mCurrentState.active.w = UINT32_MAX;
-    mCurrentState.active.h = UINT32_MAX;
-    mCurrentState.active.transform.set(0, 0);
-    mCurrentState.transform = 0;
-    mCurrentState.transformToDisplayInverse = false;
-    mCurrentState.crop.makeInvalid();
-    mCurrentState.acquireFence = new Fence(-1);
-    mCurrentState.dataspace = ui::Dataspace::UNKNOWN;
-    mCurrentState.hdrMetadata.validTypes = 0;
-    mCurrentState.surfaceDamageRegion.clear();
-    mCurrentState.cornerRadius = 0.0f;
-    mCurrentState.api = -1;
-    mCurrentState.hasColorTransform = false;
+    mState.current.active_legacy.w = args.w;
+    mState.current.active_legacy.h = args.h;
+    mState.current.flags = layerFlags;
+    mState.current.active_legacy.transform.set(0, 0);
+    mState.current.crop_legacy.makeInvalid();
+    mState.current.requestedCrop_legacy = mState.current.crop_legacy;
+    mState.current.z = 0;
+    mState.current.color.a = 1.0f;
+    mState.current.layerStack = 0;
+    mState.current.sequence = 0;
+    mState.current.requested_legacy = mState.current.active_legacy;
+    mState.current.appId = 0;
+    mState.current.type = 0;
+    mState.current.active.w = UINT32_MAX;
+    mState.current.active.h = UINT32_MAX;
+    mState.current.active.transform.set(0, 0);
+    mState.current.transform = 0;
+    mState.current.transformToDisplayInverse = false;
+    mState.current.crop.makeInvalid();
+    mState.current.acquireFence = new Fence(-1);
+    mState.current.dataspace = ui::Dataspace::UNKNOWN;
+    mState.current.hdrMetadata.validTypes = 0;
+    mState.current.surfaceDamageRegion.clear();
+    mState.current.cornerRadius = 0.0f;
+    mState.current.api = -1;
+    mState.current.hasColorTransform = false;
 
     // drawing state & current state are identical
-    mDrawingState = mCurrentState;
+    mState.drawing = mState.current;
 
     CompositorTiming compositorTiming;
     args.flinger->getCompositorTiming(&compositorTiming);
@@ -148,14 +148,17 @@
 void Layer::onRemovedFromCurrentState() {
     mRemovedFromCurrentState = true;
 
-    // the layer is removed from SF mCurrentState to mLayersPendingRemoval
-    if (mCurrentState.zOrderRelativeOf != nullptr) {
-        sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
-        if (strongRelative != nullptr) {
-            strongRelative->removeZOrderRelative(this);
-            mFlinger->setTransactionFlags(eTraversalNeeded);
+    {
+        Mutex::Autolock lock(mStateMutex);
+        // the layer is removed from SF mState.current to mLayersPendingRemoval
+        if (mState.current.zOrderRelativeOf != nullptr) {
+            sp<Layer> strongRelative = mState.current.zOrderRelativeOf.promote();
+            if (strongRelative != nullptr) {
+                strongRelative->removeZOrderRelative(this);
+                mFlinger->setTransactionFlags(eTraversalNeeded);
+            }
+            mState.current.zOrderRelativeOf = nullptr;
         }
-        mCurrentState.zOrderRelativeOf = nullptr;
     }
 
     // Since we are no longer reachable from CurrentState SurfaceFlinger
@@ -294,21 +297,32 @@
 }
 
 Rect Layer::computeScreenBounds(bool reduceTransparentRegion) const {
+    Mutex::Autolock lock(mStateMutex);
     const State& s(getDrawingState());
     Region transparentRegion = reduceTransparentRegion ? getActiveTransparentRegion(s) : Region();
-    FloatRect bounds = computeBounds(transparentRegion);
-    ui::Transform t = getTransform();
+    FloatRect bounds = computeBoundsLocked(transparentRegion);
+    ui::Transform t = getTransformLocked();
     // Transform to screen space.
     bounds = t.transform(bounds);
     return Rect{bounds};
 }
 
 FloatRect Layer::computeBounds() const {
+    Mutex::Autolock lock(mStateMutex);
+    return computeBoundsLocked();
+}
+
+FloatRect Layer::computeBoundsLocked() const {
     const State& s(getDrawingState());
-    return computeBounds(getActiveTransparentRegion(s));
+    return computeBoundsLocked(getActiveTransparentRegion(s));
 }
 
 FloatRect Layer::computeBounds(const Region& activeTransparentRegion) const {
+    Mutex::Autolock lock(mStateMutex);
+    return computeBoundsLocked(activeTransparentRegion);
+}
+
+FloatRect Layer::computeBoundsLocked(const Region& activeTransparentRegion) const {
     const State& s(getDrawingState());
     Rect bounds = getCroppedBufferSize(s);
     FloatRect floatBounds = bounds.toFloatRect();
@@ -361,6 +375,7 @@
         // child bounds as well.
         ui::Transform t = s.active_legacy.transform;
         croppedBounds = t.transform(croppedBounds);
+        Mutex::Autolock lock(p->mStateMutex);
         croppedBounds = p->cropChildBounds(croppedBounds);
         croppedBounds = t.inverse().transform(croppedBounds);
     }
@@ -388,8 +403,8 @@
     // if there are no window scaling involved, this operation will map to full
     // pixels in the buffer.
 
-    FloatRect activeCropFloat = computeBounds();
-    ui::Transform t = getTransform();
+    FloatRect activeCropFloat = computeBoundsLocked();
+    ui::Transform t = getTransformLocked();
     // Transform to screen space.
     activeCropFloat = t.transform(activeCropFloat);
     activeCropFloat = activeCropFloat.intersect(display->getViewport().toFloatRect());
@@ -439,7 +454,7 @@
     // which means using the inverse of the current transform set on the
     // SurfaceFlingerConsumer.
     uint32_t invTransform = mCurrentTransform;
-    if (getTransformToDisplayInverse()) {
+    if (getTransformToDisplayInverseLocked()) {
         /*
          * the code below applies the primary display's inverse transform to the
          * buffer
@@ -490,6 +505,7 @@
 }
 
 void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) {
+    Mutex::Autolock lock(mStateMutex);
     const auto displayId = display->getId();
     LOG_ALWAYS_FATAL_IF(!displayId);
     RETURN_IF_NO_HWC_LAYER(*displayId);
@@ -498,7 +514,7 @@
     // enable this layer
     hwcInfo.forceClientComposition = false;
 
-    if (isSecure() && !display->isSecure()) {
+    if (isSecureLocked() && !display->isSecure()) {
         hwcInfo.forceClientComposition = true;
     }
 
@@ -508,7 +524,7 @@
     const State& s(getDrawingState());
     const Rect bufferSize = getBufferSize(s);
     auto blendMode = HWC2::BlendMode::None;
-    if (!isOpaque(s) || getAlpha() != 1.0f) {
+    if (!isOpaque(s) || getAlphaLocked() != 1.0f) {
         blendMode =
                 mPremultipliedAlpha ? HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
     }
@@ -523,7 +539,7 @@
     // apply the layer's transform, followed by the display's global transform
     // here we're guaranteed that the layer's transform preserves rects
     Region activeTransparentRegion(getActiveTransparentRegion(s));
-    ui::Transform t = getTransform();
+    ui::Transform t = getTransformLocked();
     Rect activeCrop = getCrop(s);
     if (!activeCrop.isEmpty() && bufferSize.isValid()) {
         activeCrop = t.transform(activeCrop);
@@ -551,7 +567,7 @@
 
     // computeBounds returns a FloatRect to provide more accuracy during the
     // transformation. We then round upon constructing 'frame'.
-    Rect frame{t.transform(computeBounds(activeTransparentRegion))};
+    Rect frame{t.transform(computeBoundsLocked(activeTransparentRegion))};
     if (!frame.intersect(display->getViewport(), &frame)) {
         frame.clear();
     }
@@ -579,7 +595,7 @@
     }
     getBE().compositionInfo.hwc.sourceCrop = sourceCrop;
 
-    float alpha = static_cast<float>(getAlpha());
+    float alpha = static_cast<float>(getAlphaLocked());
     error = hwcLayer->setPlaneAlpha(alpha);
     ALOGE_IF(error != HWC2::Error::None,
              "[%s] Failed to set plane alpha %.3f: "
@@ -596,6 +612,7 @@
     int appId = s.appId;
     sp<Layer> parent = mDrawingParent.promote();
     if (parent.get()) {
+        Mutex::Autolock lock(parent->mStateMutex);
         auto& parentState = parent->getDrawingState();
         if (parentState.type >= 0 || parentState.appId >= 0) {
             type = parentState.type;
@@ -621,7 +638,7 @@
     const ui::Transform bufferOrientation(mCurrentTransform);
     ui::Transform transform(tr * t * bufferOrientation);
 
-    if (getTransformToDisplayInverse()) {
+    if (getTransformToDisplayInverseLocked()) {
         /*
          * the code below applies the primary display's inverse transform to the
          * buffer
@@ -671,6 +688,7 @@
 }
 
 void Layer::updateCursorPosition(const sp<const DisplayDevice>& display) {
+    Mutex::Autolock lock(mStateMutex);
     const auto displayId = display->getId();
     LOG_ALWAYS_FATAL_IF(!displayId);
     if (!hasHwcLayer(*displayId) || getCompositionType(displayId) != HWC2::Composition::Cursor) {
@@ -685,7 +703,7 @@
     Rect win = getCroppedBufferSize(s);
     // Subtract the transparent region and snap to the bounds
     Rect bounds = reduce(win, getActiveTransparentRegion(s));
-    Rect frame(getTransform().transform(bounds));
+    Rect frame(getTransformLocked().transform(bounds));
     frame.intersect(display->getViewport(), &frame);
     auto& displayTransform = display->getTransform();
     auto position = displayTransform.transform(frame);
@@ -715,6 +733,7 @@
 void Layer::clearWithOpenGL(const RenderArea& renderArea, float red, float green, float blue,
                             float alpha) const {
     auto& engine(mFlinger->getRenderEngine());
+    Mutex::Autolock lock(mStateMutex);
     computeGeometry(renderArea, getBE().mMesh, false);
     engine.setupFillWithColor(red, green, blue, alpha);
     engine.drawMesh(getBE().mMesh);
@@ -799,14 +818,14 @@
                             renderengine::Mesh& mesh,
                             bool useIdentityTransform) const {
     const ui::Transform renderAreaTransform(renderArea.getTransform());
-    FloatRect win = computeBounds();
+    FloatRect win = computeBoundsLocked();
 
     vec2 lt = vec2(win.left, win.top);
     vec2 lb = vec2(win.left, win.bottom);
     vec2 rb = vec2(win.right, win.bottom);
     vec2 rt = vec2(win.right, win.top);
 
-    ui::Transform layerTransform = getTransform();
+    ui::Transform layerTransform = getTransformLocked();
     if (!useIdentityTransform) {
         lt = layerTransform.transform(lt);
         lb = layerTransform.transform(lb);
@@ -822,7 +841,12 @@
 }
 
 bool Layer::isSecure() const {
-    const State& s(mDrawingState);
+    Mutex::Autolock lock(mStateMutex);
+    return isSecureLocked();
+}
+
+bool Layer::isSecureLocked() const {
+    const State& s(mState.drawing);
     return (s.flags & layer_state_t::eLayerSecure);
 }
 
@@ -850,9 +874,13 @@
 // ----------------------------------------------------------------------------
 // transaction
 // ----------------------------------------------------------------------------
-
 void Layer::pushPendingState() {
-    if (!mCurrentState.modified) {
+    Mutex::Autolock lock(mStateMutex);
+    pushPendingStateLocked();
+}
+
+void Layer::pushPendingStateLocked() {
+    if (!mState.current.modified) {
         return;
     }
 
@@ -860,22 +888,22 @@
     // point and send it to the remote layer.
     // We don't allow installing sync points after we are removed from the current state
     // as we won't be able to signal our end.
-    if (mCurrentState.barrierLayer_legacy != nullptr && !isRemovedFromCurrentState()) {
-        sp<Layer> barrierLayer = mCurrentState.barrierLayer_legacy.promote();
+    if (mState.current.barrierLayer_legacy != nullptr && !isRemovedFromCurrentState()) {
+        sp<Layer> barrierLayer = mState.current.barrierLayer_legacy.promote();
         if (barrierLayer == nullptr) {
             ALOGE("[%s] Unable to promote barrier Layer.", mName.string());
             // If we can't promote the layer we are intended to wait on,
             // then it is expired or otherwise invalid. Allow this transaction
             // to be applied as per normal (no synchronization).
-            mCurrentState.barrierLayer_legacy = nullptr;
+            mState.current.barrierLayer_legacy = nullptr;
         } else {
-            auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber_legacy);
+            auto syncPoint = std::make_shared<SyncPoint>(mState.current.frameNumber_legacy);
             if (barrierLayer->addSyncPoint(syncPoint)) {
                 mRemoteSyncPoints.push_back(std::move(syncPoint));
             } else {
                 // We already missed the frame we're supposed to synchronize
                 // on, so go ahead and apply the state update
-                mCurrentState.barrierLayer_legacy = nullptr;
+                mState.current.barrierLayer_legacy = nullptr;
             }
         }
 
@@ -883,21 +911,21 @@
         setTransactionFlags(eTransactionNeeded);
         mFlinger->setTransactionFlags(eTraversalNeeded);
     }
-    mPendingStates.push_back(mCurrentState);
-    ATRACE_INT(mTransactionName.string(), mPendingStates.size());
+    mState.pending.push_back(mState.current);
+    ATRACE_INT(mTransactionName.string(), mState.pending.size());
 }
 
 void Layer::popPendingState(State* stateToCommit) {
-    *stateToCommit = mPendingStates[0];
+    *stateToCommit = mState.pending[0];
 
-    mPendingStates.removeAt(0);
-    ATRACE_INT(mTransactionName.string(), mPendingStates.size());
+    mState.pending.removeAt(0);
+    ATRACE_INT(mTransactionName.string(), mState.pending.size());
 }
 
 bool Layer::applyPendingStates(State* stateToCommit) {
     bool stateUpdateAvailable = false;
-    while (!mPendingStates.empty()) {
-        if (mPendingStates[0].barrierLayer_legacy != nullptr) {
+    while (!mState.pending.empty()) {
+        if (mState.pending[0].barrierLayer_legacy != nullptr) {
             if (mRemoteSyncPoints.empty()) {
                 // If we don't have a sync point for this, apply it anyway. It
                 // will be visually wrong, but it should keep us from getting
@@ -909,7 +937,7 @@
             }
 
             if (mRemoteSyncPoints.front()->getFrameNumber() !=
-                mPendingStates[0].frameNumber_legacy) {
+                mState.pending[0].frameNumber_legacy) {
                 ALOGE("[%s] Unexpected sync point frame number found", mName.string());
 
                 // Signal our end of the sync point and then dispose of it
@@ -937,12 +965,12 @@
 
     // If we still have pending updates, wake SurfaceFlinger back up and point
     // it at this layer so we can process them
-    if (!mPendingStates.empty()) {
+    if (!mState.pending.empty()) {
         setTransactionFlags(eTransactionNeeded);
         mFlinger->setTransactionFlags(eTraversalNeeded);
     }
 
-    mCurrentState.modified = false;
+    mState.current.modified = false;
     return stateUpdateAvailable;
 }
 
@@ -1039,7 +1067,8 @@
         return 0;
     }
 
-    pushPendingState();
+    Mutex::Autolock lock(mStateMutex);
+    pushPendingStateLocked();
     State c = getCurrentState();
     if (!applyPendingStates(&c)) {
         return 0;
@@ -1071,49 +1100,60 @@
         clearSyncPoints();
     }
 
-    if (mCurrentState.inputInfoChanged) {
+    if (mState.current.inputInfoChanged) {
         flags |= eInputInfoChanged;
-        mCurrentState.inputInfoChanged = false;
+        mState.current.inputInfoChanged = false;
     }
 
     // Commit the transaction
     commitTransaction(c);
-    mCurrentState.callbackHandles = {};
+    mState.current.callbackHandles = {};
     return flags;
 }
 
 void Layer::commitTransaction(const State& stateToCommit) {
-    mDrawingState = stateToCommit;
+    mState.drawing = stateToCommit;
+}
+
+uint32_t Layer::getTransactionFlags() const {
+    Mutex::Autolock lock(mStateMutex);
+    return mState.transactionFlags;
 }
 
 uint32_t Layer::getTransactionFlags(uint32_t flags) {
-    return mTransactionFlags.fetch_and(~flags) & flags;
+    Mutex::Autolock lock(mStateMutex);
+    uint32_t and_flags = mState.transactionFlags & flags;
+    mState.transactionFlags &= ~flags;
+    return and_flags;
 }
 
 uint32_t Layer::setTransactionFlags(uint32_t flags) {
-    return mTransactionFlags.fetch_or(flags);
+    uint32_t old_flags = mState.transactionFlags;
+    mState.transactionFlags |= flags;
+    return old_flags;
 }
 
 bool Layer::setPosition(float x, float y, bool immediate) {
-    if (mCurrentState.requested_legacy.transform.tx() == x &&
-        mCurrentState.requested_legacy.transform.ty() == y)
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.requested_legacy.transform.tx() == x &&
+        mState.current.requested_legacy.transform.ty() == y)
         return false;
-    mCurrentState.sequence++;
+    mState.current.sequence++;
 
     // We update the requested and active position simultaneously because
     // we want to apply the position portion of the transform matrix immediately,
     // but still delay scaling when resizing a SCALING_MODE_FREEZE layer.
-    mCurrentState.requested_legacy.transform.set(x, y);
+    mState.current.requested_legacy.transform.set(x, y);
     if (immediate && !mFreezeGeometryUpdates) {
         // Here we directly update the active state
         // unlike other setters, because we store it within
         // the transform, but use different latching rules.
         // b/38182305
-        mCurrentState.active_legacy.transform.set(x, y);
+        mState.current.active_legacy.transform.set(x, y);
     }
     mFreezeGeometryUpdates = mFreezeGeometryUpdates || !immediate;
 
-    mCurrentState.modified = true;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
@@ -1146,38 +1186,44 @@
 }
 
 bool Layer::setLayer(int32_t z) {
-    if (mCurrentState.z == z && !usingRelativeZ(LayerVector::StateSet::Current)) return false;
-    mCurrentState.sequence++;
-    mCurrentState.z = z;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.z == z && !usingRelativeZLocked(LayerVector::StateSet::Current))
+        return false;
+
+    mState.current.sequence++;
+    mState.current.z = z;
+    mState.current.modified = true;
 
     // Discard all relative layering.
-    if (mCurrentState.zOrderRelativeOf != nullptr) {
-        sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
+    if (mState.current.zOrderRelativeOf != nullptr) {
+        sp<Layer> strongRelative = mState.current.zOrderRelativeOf.promote();
         if (strongRelative != nullptr) {
             strongRelative->removeZOrderRelative(this);
         }
-        mCurrentState.zOrderRelativeOf = nullptr;
+        mState.current.zOrderRelativeOf = nullptr;
     }
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 void Layer::removeZOrderRelative(const wp<Layer>& relative) {
-    mCurrentState.zOrderRelatives.remove(relative);
-    mCurrentState.sequence++;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.zOrderRelatives.remove(relative);
+    mState.current.sequence++;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
 }
 
 void Layer::addZOrderRelative(const wp<Layer>& relative) {
-    mCurrentState.zOrderRelatives.add(relative);
-    mCurrentState.modified = true;
-    mCurrentState.sequence++;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.zOrderRelatives.add(relative);
+    mState.current.modified = true;
+    mState.current.sequence++;
     setTransactionFlags(eTransactionNeeded);
 }
 
 bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ) {
+    Mutex::Autolock lock(mStateMutex);
     sp<Handle> handle = static_cast<Handle*>(relativeToHandle.get());
     if (handle == nullptr) {
         return false;
@@ -1187,20 +1233,20 @@
         return false;
     }
 
-    if (mCurrentState.z == relativeZ && usingRelativeZ(LayerVector::StateSet::Current) &&
-            mCurrentState.zOrderRelativeOf == relative) {
+    if (mState.current.z == relativeZ && usingRelativeZLocked(LayerVector::StateSet::Current) &&
+        mState.current.zOrderRelativeOf == relative) {
         return false;
     }
 
-    mCurrentState.sequence++;
-    mCurrentState.modified = true;
-    mCurrentState.z = relativeZ;
+    mState.current.sequence++;
+    mState.current.modified = true;
+    mState.current.z = relativeZ;
 
-    auto oldZOrderRelativeOf = mCurrentState.zOrderRelativeOf.promote();
+    auto oldZOrderRelativeOf = mState.current.zOrderRelativeOf.promote();
     if (oldZOrderRelativeOf != nullptr) {
         oldZOrderRelativeOf->removeZOrderRelative(this);
     }
-    mCurrentState.zOrderRelativeOf = relative;
+    mState.current.zOrderRelativeOf = relative;
     relative->addZOrderRelative(this);
 
     setTransactionFlags(eTransactionNeeded);
@@ -1209,48 +1255,51 @@
 }
 
 bool Layer::setSize(uint32_t w, uint32_t h) {
-    if (mCurrentState.requested_legacy.w == w && mCurrentState.requested_legacy.h == h)
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.requested_legacy.w == w && mState.current.requested_legacy.h == h)
         return false;
-    mCurrentState.requested_legacy.w = w;
-    mCurrentState.requested_legacy.h = h;
-    mCurrentState.modified = true;
+    mState.current.requested_legacy.w = w;
+    mState.current.requested_legacy.h = h;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
 
     // record the new size, from this point on, when the client request
     // a buffer, it'll get the new size.
-    setDefaultBufferSize(mCurrentState.requested_legacy.w, mCurrentState.requested_legacy.h);
+    setDefaultBufferSize(mState.current.requested_legacy.w, mState.current.requested_legacy.h);
     return true;
 }
 bool Layer::setAlpha(float alpha) {
-    if (mCurrentState.color.a == alpha) return false;
-    mCurrentState.sequence++;
-    mCurrentState.color.a = alpha;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.color.a == alpha) return false;
+    mState.current.sequence++;
+    mState.current.color.a = alpha;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setColor(const half3& color) {
-    if (color.r == mCurrentState.color.r && color.g == mCurrentState.color.g &&
-        color.b == mCurrentState.color.b)
+    Mutex::Autolock lock(mStateMutex);
+    if (color.r == mState.current.color.r && color.g == mState.current.color.g &&
+        color.b == mState.current.color.b)
         return false;
 
-    mCurrentState.sequence++;
-    mCurrentState.color.r = color.r;
-    mCurrentState.color.g = color.g;
-    mCurrentState.color.b = color.b;
-    mCurrentState.modified = true;
+    mState.current.sequence++;
+    mState.current.color.r = color.r;
+    mState.current.color.g = color.g;
+    mState.current.color.b = color.b;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setCornerRadius(float cornerRadius) {
-    if (mCurrentState.cornerRadius == cornerRadius)
-        return false;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.cornerRadius == cornerRadius) return false;
 
-    mCurrentState.sequence++;
-    mCurrentState.cornerRadius = cornerRadius;
-    mCurrentState.modified = true;
+    mState.current.sequence++;
+    mState.current.cornerRadius = cornerRadius;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
@@ -1264,45 +1313,50 @@
         ALOGW("Attempt to set rotation matrix without permission ACCESS_SURFACE_FLINGER ignored");
         return false;
     }
-    mCurrentState.sequence++;
-    mCurrentState.requested_legacy.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx,
-                                                 matrix.dsdy);
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.sequence++;
+    mState.current.requested_legacy.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx,
+                                                  matrix.dsdy);
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setTransparentRegionHint(const Region& transparent) {
-    mCurrentState.requestedTransparentRegion_legacy = transparent;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.requestedTransparentRegion_legacy = transparent;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 bool Layer::setFlags(uint8_t flags, uint8_t mask) {
-    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
-    if (mCurrentState.flags == newFlags) return false;
-    mCurrentState.sequence++;
-    mCurrentState.flags = newFlags;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    const uint32_t newFlags = (mState.current.flags & ~mask) | (flags & mask);
+    if (mState.current.flags == newFlags) return false;
+    mState.current.sequence++;
+    mState.current.flags = newFlags;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setCrop_legacy(const Rect& crop, bool immediate) {
-    if (mCurrentState.requestedCrop_legacy == crop) return false;
-    mCurrentState.sequence++;
-    mCurrentState.requestedCrop_legacy = crop;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.requestedCrop_legacy == crop) return false;
+    mState.current.sequence++;
+    mState.current.requestedCrop_legacy = crop;
     if (immediate && !mFreezeGeometryUpdates) {
-        mCurrentState.crop_legacy = crop;
+        mState.current.crop_legacy = crop;
     }
     mFreezeGeometryUpdates = mFreezeGeometryUpdates || !immediate;
 
-    mCurrentState.modified = true;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setOverrideScalingMode(int32_t scalingMode) {
+    Mutex::Autolock lock(mStateMutex);
     if (scalingMode == mOverrideScalingMode) return false;
     mOverrideScalingMode = scalingMode;
     setTransactionFlags(eTransactionNeeded);
@@ -1310,22 +1364,29 @@
 }
 
 void Layer::setInfo(int32_t type, int32_t appId) {
-    mCurrentState.appId = appId;
-    mCurrentState.type = type;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.appId = appId;
+    mState.current.type = type;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
 }
 
 bool Layer::setLayerStack(uint32_t layerStack) {
-    if (mCurrentState.layerStack == layerStack) return false;
-    mCurrentState.sequence++;
-    mCurrentState.layerStack = layerStack;
-    mCurrentState.modified = true;
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.layerStack == layerStack) return false;
+    mState.current.sequence++;
+    mState.current.layerStack = layerStack;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 uint32_t Layer::getLayerStack() const {
+    Mutex::Autolock lock(mStateMutex);
+    return getLayerStackLocked();
+}
+
+uint32_t Layer::getLayerStackLocked() const {
     auto p = mDrawingParent.promote();
     if (p == nullptr) {
         return getDrawingState().layerStack;
@@ -1334,15 +1395,16 @@
 }
 
 void Layer::deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber) {
-    mCurrentState.barrierLayer_legacy = barrierLayer;
-    mCurrentState.frameNumber_legacy = frameNumber;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.barrierLayer_legacy = barrierLayer;
+    mState.current.frameNumber_legacy = frameNumber;
     // We don't set eTransactionNeeded, because just receiving a deferral
     // request without any other state updates shouldn't actually induce a delay
-    mCurrentState.modified = true;
-    pushPendingState();
-    mCurrentState.barrierLayer_legacy = nullptr;
-    mCurrentState.frameNumber_legacy = 0;
-    mCurrentState.modified = false;
+    mState.current.modified = true;
+    pushPendingStateLocked();
+    mState.current.barrierLayer_legacy = nullptr;
+    mState.current.frameNumber_legacy = 0;
+    mState.current.modified = false;
 }
 
 void Layer::deferTransactionUntil_legacy(const sp<IBinder>& barrierHandle, uint64_t frameNumber) {
@@ -1355,7 +1417,8 @@
 // ----------------------------------------------------------------------------
 
 bool Layer::isHiddenByPolicy() const {
-    const State& s(mDrawingState);
+    Mutex::Autolock lock(mStateMutex);
+    const State& s(mState.drawing);
     const auto& parent = mDrawingParent.promote();
     if (parent != nullptr && parent->isHiddenByPolicy()) {
         return true;
@@ -1400,6 +1463,7 @@
 
 // TODO(marissaw): add new layer state info to layer debugging
 LayerDebugInfo Layer::getLayerDebugInfo() const {
+    Mutex::Autolock lock(mStateMutex);
     LayerDebugInfo info;
     const State& ds = getDrawingState();
     info.mName = getName();
@@ -1409,7 +1473,7 @@
     info.mTransparentRegion = ds.activeTransparentRegion_legacy;
     info.mVisibleRegion = visibleRegion;
     info.mSurfaceDamageRegion = surfaceDamageRegion;
-    info.mLayerStack = getLayerStack();
+    info.mLayerStack = getLayerStackLocked();
     info.mX = ds.active_legacy.transform.tx();
     info.mY = ds.active_legacy.transform.ty();
     info.mZ = ds.z;
@@ -1445,6 +1509,13 @@
     return info;
 }
 
+std::tuple<uint32_t, int32_t> Layer::getLayerStackAndZ(StateSet stateSet) {
+    Mutex::Autolock lock(mStateMutex);
+    const State& state = (stateSet == StateSet::Current) ? mState.current : mState.drawing;
+
+    return {state.layerStack, state.z};
+}
+
 void Layer::miniDumpHeader(std::string& result) {
     result.append("-------------------------------");
     result.append("-------------------------------");
@@ -1461,6 +1532,7 @@
 }
 
 void Layer::miniDump(std::string& result, DisplayId displayId) const {
+    Mutex::Autolock lock(mStateMutex);
     if (!hasHwcLayer(displayId)) {
         return;
     }
@@ -1589,6 +1661,7 @@
     }
 
     if (attachChildren()) {
+        Mutex::Autolock lock(mStateMutex);
         setTransactionFlags(eTransactionNeeded);
     }
     for (const sp<Layer>& child : mCurrentChildren) {
@@ -1639,6 +1712,7 @@
         client->updateParent(newParent);
     }
 
+    Mutex::Autolock lock(mStateMutex);
     if (mLayerDetached) {
         mLayerDetached = false;
         setTransactionFlags(eTransactionNeeded);
@@ -1682,18 +1756,24 @@
 bool Layer::setColorTransform(const mat4& matrix) {
     static const mat4 identityMatrix = mat4();
 
-    if (mCurrentState.colorTransform == matrix) {
+    Mutex::Autolock lock(mStateMutex);
+    if (mState.current.colorTransform == matrix) {
         return false;
     }
-    ++mCurrentState.sequence;
-    mCurrentState.colorTransform = matrix;
-    mCurrentState.hasColorTransform = matrix != identityMatrix;
-    mCurrentState.modified = true;
+    ++mState.current.sequence;
+    mState.current.colorTransform = matrix;
+    mState.current.hasColorTransform = matrix != identityMatrix;
+    mState.current.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 mat4 Layer::getColorTransform() const {
+    Mutex::Autolock lock(mStateMutex);
+    return getColorTransformLocked();
+}
+
+mat4 Layer::getColorTransformLocked() const {
     mat4 colorTransform = mat4(getDrawingState().colorTransform);
     if (sp<Layer> parent = mDrawingParent.promote(); parent != nullptr) {
         colorTransform = parent->getColorTransform() * colorTransform;
@@ -1702,6 +1782,7 @@
 }
 
 bool Layer::hasColorTransform() const {
+    Mutex::Autolock lock(mStateMutex);
     bool hasColorTransform = getDrawingState().hasColorTransform;
     if (sp<Layer> parent = mDrawingParent.promote(); parent != nullptr) {
         hasColorTransform = hasColorTransform || parent->hasColorTransform();
@@ -1732,12 +1813,18 @@
 }
 
 int32_t Layer::getZ() const {
-    return mDrawingState.z;
+    Mutex::Autolock lock(mStateMutex);
+    return mState.drawing.z;
 }
 
 bool Layer::usingRelativeZ(LayerVector::StateSet stateSet) {
+    Mutex::Autolock lock(mStateMutex);
+    return usingRelativeZLocked(stateSet);
+}
+
+bool Layer::usingRelativeZLocked(LayerVector::StateSet stateSet) {
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
-    const State& state = useDrawing ? mDrawingState : mCurrentState;
+    const State& state = useDrawing ? mState.drawing : mState.current;
     return state.zOrderRelativeOf != nullptr;
 }
 
@@ -1747,7 +1834,7 @@
                         "makeTraversalList received invalid stateSet");
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
-    const State& state = useDrawing ? mDrawingState : mCurrentState;
+    const State& state = useDrawing ? mState.drawing : mState.current;
 
     if (state.zOrderRelatives.size() == 0) {
         *outSkipRelativeZUsers = true;
@@ -1763,7 +1850,7 @@
     }
 
     for (const sp<Layer>& child : children) {
-        const State& childState = useDrawing ? child->mDrawingState : child->mCurrentState;
+        const State& childState = useDrawing ? child->mState.drawing : child->mState.current;
         if (childState.zOrderRelativeOf != nullptr) {
             continue;
         }
@@ -1802,7 +1889,6 @@
     visitor(this);
     for (; i < list.size(); i++) {
         const auto& relative = list[i];
-
         if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
             continue;
         }
@@ -1850,7 +1936,7 @@
                         "makeTraversalList received invalid stateSet");
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
-    const State& state = useDrawing ? mDrawingState : mCurrentState;
+    const State& state = useDrawing ? mState.drawing : mState.current;
 
     LayerVector traverse(stateSet);
     for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
@@ -1863,7 +1949,7 @@
     }
 
     for (const sp<Layer>& child : children) {
-        const State& childState = useDrawing ? child->mDrawingState : child->mCurrentState;
+        const State& childState = useDrawing ? child->mState.drawing : child->mState.current;
         // If a layer has a relativeOf layer, only ignore if the layer it's relative to is a
         // descendent of the top most parent of the tree. If it's not a descendent, then just add
         // the child here since it won't be added later as a relative.
@@ -1920,10 +2006,16 @@
 }
 
 ui::Transform Layer::getTransform() const {
+    Mutex::Autolock lock(mStateMutex);
+    return getTransformLocked();
+}
+
+ui::Transform Layer::getTransformLocked() const {
     ui::Transform t;
     const auto& p = mDrawingParent.promote();
     if (p != nullptr) {
-        t = p->getTransform();
+        Mutex::Autolock lock(p->mStateMutex);
+        t = p->getTransformLocked();
 
         // If the parent is not using NATIVE_WINDOW_SCALING_MODE_FREEZE (e.g.
         // it isFixedSize) then there may be additional scaling not accounted
@@ -1951,18 +2043,27 @@
 }
 
 half Layer::getAlpha() const {
-    const auto& p = mDrawingParent.promote();
+    Mutex::Autolock lock(mStateMutex);
+    return getAlphaLocked();
+}
 
+half Layer::getAlphaLocked() const {
+    const auto& p = mDrawingParent.promote();
     half parentAlpha = (p != nullptr) ? p->getAlpha() : 1.0_hf;
     return parentAlpha * getDrawingState().color.a;
 }
 
 half4 Layer::getColor() const {
     const half4 color(getDrawingState().color);
-    return half4(color.r, color.g, color.b, getAlpha());
+    return half4(color.r, color.g, color.b, getAlphaLocked());
 }
 
 Layer::RoundedCornerState Layer::getRoundedCornerState() const {
+    Mutex::Autolock lock(mStateMutex);
+    return getRoundedCornerStateLocked();
+}
+
+Layer::RoundedCornerState Layer::getRoundedCornerStateLocked() const {
     const auto& p = mDrawingParent.promote();
     if (p != nullptr) {
         RoundedCornerState parentState = p->getRoundedCornerState();
@@ -1979,7 +2080,7 @@
         }
     }
     const float radius = getDrawingState().cornerRadius;
-    return radius > 0 ? RoundedCornerState(computeBounds(), radius) : RoundedCornerState();
+    return radius > 0 ? RoundedCornerState(computeBoundsLocked(), radius) : RoundedCornerState();
 }
 
 void Layer::commitChildList() {
@@ -1992,19 +2093,21 @@
 }
 
 void Layer::setInputInfo(const InputWindowInfo& info) {
-    mCurrentState.inputInfo = info;
-    mCurrentState.modified = true;
-    mCurrentState.inputInfoChanged = true;
+    Mutex::Autolock lock(mStateMutex);
+    mState.current.inputInfo = info;
+    mState.current.modified = true;
+    mState.current.inputInfoChanged = true;
     setTransactionFlags(eTransactionNeeded);
 }
 
 void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) {
+    Mutex::Autolock lock(mStateMutex);
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
-    const State& state = useDrawing ? mDrawingState : mCurrentState;
+    const State& state = useDrawing ? mState.drawing : mState.current;
 
     ui::Transform requestedTransform = state.active_legacy.transform;
-    ui::Transform transform = getTransform();
+    ui::Transform transform = getTransformLocked();
 
     layerInfo->set_id(sequence);
     layerInfo->set_name(getName().c_str());
@@ -2026,7 +2129,7 @@
     LayerProtoHelper::writeToProto(visibleRegion, layerInfo->mutable_visible_region());
     LayerProtoHelper::writeToProto(surfaceDamageRegion, layerInfo->mutable_damage_region());
 
-    layerInfo->set_layer_stack(getLayerStack());
+    layerInfo->set_layer_stack(getLayerStackLocked());
     layerInfo->set_z(state.z);
 
     PositionProto* position = layerInfo->mutable_position();
@@ -2042,7 +2145,7 @@
     size->set_h(state.active_legacy.h);
 
     LayerProtoHelper::writeToProto(state.crop_legacy, layerInfo->mutable_crop());
-    layerInfo->set_corner_radius(getRoundedCornerState().radius);
+    layerInfo->set_corner_radius(getRoundedCornerStateLocked().radius);
 
     layerInfo->set_is_opaque(isOpaque(state));
     layerInfo->set_invalidate(contentDirty);
@@ -2083,7 +2186,7 @@
     layerInfo->set_curr_frame(mCurrentFrameNumber);
     layerInfo->set_effective_scaling_mode(getEffectiveScalingMode());
 
-    for (const auto& pendingState : mPendingStates) {
+    for (const auto& pendingState : mState.pending) {
         auto barrierLayer = pendingState.barrierLayer_legacy.promote();
         if (barrierLayer != nullptr) {
             BarrierLayerProto* barrierLayerProto = layerInfo->add_barrier_layer();
@@ -2127,19 +2230,25 @@
 }
 
 InputWindowInfo Layer::fillInputInfo(const Rect& screenBounds) {
-    InputWindowInfo info = mDrawingState.inputInfo;
+    InputWindowInfo info;
+    ui::Transform t;
+    Rect layerBounds;
+    {
+        Mutex::Autolock lock(mStateMutex);
+        info = mState.drawing.inputInfo;
+        t = getTransformLocked();
+        const float xScale = t.sx();
+        const float yScale = t.sy();
+        if (xScale != 1.0f || yScale != 1.0f) {
+            info.windowXScale *= 1.0f / xScale;
+            info.windowYScale *= 1.0f / yScale;
+            info.touchableRegion.scaleSelf(xScale, yScale);
+        }
 
-    ui::Transform t = getTransform();
-    const float xScale = t.sx();
-    const float yScale = t.sy();
-    if (xScale != 1.0f || yScale != 1.0f) {
-        info.windowXScale *= 1.0f / xScale;
-        info.windowYScale *= 1.0f / yScale;
-        info.touchableRegion.scaleSelf(xScale, yScale);
+        // Transform layer size to screen space and inset it by surface insets.
+        layerBounds = getCroppedBufferSize(getDrawingState());
     }
 
-    // Transform layer size to screen space and inset it by surface insets.
-    Rect layerBounds = getCroppedBufferSize(getDrawingState());
     layerBounds = t.transform(layerBounds);
     layerBounds.inset(info.surfaceInset, info.surfaceInset, info.surfaceInset, info.surfaceInset);
 
@@ -2162,7 +2271,8 @@
 }
 
 bool Layer::hasInput() const {
-    return mDrawingState.inputInfo.token != nullptr;
+    Mutex::Autolock lock(mStateMutex);
+    return mState.drawing.inputInfo.token != nullptr;
 }
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 7b6709e..57ef65a 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -55,6 +55,7 @@
 #include "RenderArea.h"
 
 using namespace android::surfaceflinger;
+using StateSet = android::LayerVector::StateSet;
 
 namespace android {
 
@@ -239,7 +240,7 @@
     // also the rendered size of the layer prior to any transformations. Parent
     // or local matrix transformations will not affect the size of the buffer,
     // but may affect it's on-screen size or clipping.
-    virtual bool setSize(uint32_t w, uint32_t h);
+    virtual bool setSize(uint32_t w, uint32_t h) EXCLUDES(mStateMutex);
     // Set a 2x2 transformation matrix on the layer. This transform
     // will be applied after parent transforms, but before any final
     // producer specified transform.
@@ -254,58 +255,76 @@
 
     // setPosition operates in parent buffer space (pre parent-transform) or display
     // space for top-level layers.
-    virtual bool setPosition(float x, float y, bool immediate);
+    virtual bool setPosition(float x, float y, bool immediate) EXCLUDES(mStateMutex);
     // Buffer space
-    virtual bool setCrop_legacy(const Rect& crop, bool immediate);
+    virtual bool setCrop_legacy(const Rect& crop, bool immediate) EXCLUDES(mStateMutex);
 
     // TODO(b/38182121): Could we eliminate the various latching modes by
     // using the layer hierarchy?
     // -----------------------------------------------------------------------
-    virtual bool setLayer(int32_t z);
-    virtual bool setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ);
+    virtual bool setLayer(int32_t z) EXCLUDES(mStateMutex);
+    virtual bool setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ)
+            EXCLUDES(mStateMutex);
 
-    virtual bool setAlpha(float alpha);
-    virtual bool setColor(const half3& color);
+    virtual bool setAlpha(float alpha) EXCLUDES(mStateMutex);
+    virtual bool setColor(const half3& color) EXCLUDES(mStateMutex);
 
     // Set rounded corner radius for this layer and its children.
     //
     // We only support 1 radius per layer in the hierarchy, where parent layers have precedence.
     // The shape of the rounded corner rectangle is specified by the crop rectangle of the layer
     // from which we inferred the rounded corner radius.
-    virtual bool setCornerRadius(float cornerRadius);
-    virtual bool setTransparentRegionHint(const Region& transparent);
-    virtual bool setFlags(uint8_t flags, uint8_t mask);
-    virtual bool setLayerStack(uint32_t layerStack);
-    virtual uint32_t getLayerStack() const;
+    virtual bool setCornerRadius(float cornerRadius) EXCLUDES(mStateMutex);
+    virtual bool setTransparentRegionHint(const Region& transparent) EXCLUDES(mStateMutex);
+    virtual bool setFlags(uint8_t flags, uint8_t mask) EXCLUDES(mStateMutex);
+    virtual bool setLayerStack(uint32_t layerStack) EXCLUDES(mStateMutex);
+    virtual uint32_t getLayerStack() const EXCLUDES(mStateMutex);
     virtual void deferTransactionUntil_legacy(const sp<IBinder>& barrierHandle,
                                               uint64_t frameNumber);
-    virtual void deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber);
-    virtual bool setOverrideScalingMode(int32_t overrideScalingMode);
-    virtual void setInfo(int32_t type, int32_t appId);
-    virtual bool reparentChildren(const sp<IBinder>& layer);
+    virtual void deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber)
+            EXCLUDES(mStateMutex);
+    virtual bool setOverrideScalingMode(int32_t overrideScalingMode) EXCLUDES(mStateMutex);
+    virtual void setInfo(int32_t type, int32_t appId) EXCLUDES(mStateMutex);
+    virtual bool reparentChildren(const sp<IBinder>& layer) EXCLUDES(mStateMutex);
     virtual void setChildrenDrawingParent(const sp<Layer>& layer);
-    virtual bool reparent(const sp<IBinder>& newParentHandle);
+    virtual bool reparent(const sp<IBinder>& newParentHandle) EXCLUDES(mStateMutex);
     virtual bool detachChildren();
     bool attachChildren();
     bool isLayerDetached() const { return mLayerDetached; }
-    virtual bool setColorTransform(const mat4& matrix);
-    virtual mat4 getColorTransform() const;
-    virtual bool hasColorTransform() const;
+    virtual bool setColorTransform(const mat4& matrix) EXCLUDES(mStateMutex);
+    mat4 getColorTransform() const EXCLUDES(mStateMutex);
+    virtual mat4 getColorTransformLocked() const REQUIRES(mStateMutex);
+    virtual bool hasColorTransform() const EXCLUDES(mStateMutex);
+    ;
 
     // Used only to set BufferStateLayer state
-    virtual bool setTransform(uint32_t /*transform*/) { return false; };
-    virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/) { return false; };
-    virtual bool setCrop(const Rect& /*crop*/) { return false; };
-    virtual bool setFrame(const Rect& /*frame*/) { return false; };
-    virtual bool setBuffer(const sp<GraphicBuffer>& /*buffer*/) { return false; };
-    virtual bool setAcquireFence(const sp<Fence>& /*fence*/) { return false; };
-    virtual bool setDataspace(ui::Dataspace /*dataspace*/) { return false; };
-    virtual bool setHdrMetadata(const HdrMetadata& /*hdrMetadata*/) { return false; };
-    virtual bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/) { return false; };
-    virtual bool setApi(int32_t /*api*/) { return false; };
-    virtual bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/) { return false; };
+    virtual bool setTransform(uint32_t /*transform*/) EXCLUDES(mStateMutex) { return false; };
+    virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/)
+            EXCLUDES(mStateMutex) {
+        return false;
+    };
+    virtual bool setCrop(const Rect& /*crop*/) EXCLUDES(mStateMutex) { return false; };
+    virtual bool setFrame(const Rect& /*frame*/) EXCLUDES(mStateMutex) { return false; };
+    virtual bool setBuffer(const sp<GraphicBuffer>& /*buffer*/) EXCLUDES(mStateMutex) {
+        return false;
+    };
+    virtual bool setAcquireFence(const sp<Fence>& /*fence*/) EXCLUDES(mStateMutex) {
+        return false;
+    };
+    virtual bool setDataspace(ui::Dataspace /*dataspace*/) EXCLUDES(mStateMutex) { return false; };
+    virtual bool setHdrMetadata(const HdrMetadata& /*hdrMetadata*/) EXCLUDES(mStateMutex) {
+        return false;
+    };
+    virtual bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/) EXCLUDES(mStateMutex) {
+        return false;
+    };
+    virtual bool setApi(int32_t /*api*/) EXCLUDES(mStateMutex) { return false; };
+    virtual bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/)
+            EXCLUDES(mStateMutex) {
+        return false;
+    };
     virtual bool setTransactionCompletedListeners(
-            const std::vector<sp<CallbackHandle>>& /*handles*/) {
+            const std::vector<sp<CallbackHandle>>& /*handles*/) EXCLUDES(mStateMutex) {
         return false;
     };
 
@@ -324,18 +343,21 @@
     virtual void useSurfaceDamage() {}
     virtual void useEmptyDamage() {}
 
-    uint32_t getTransactionFlags() const { return mTransactionFlags; }
-    uint32_t getTransactionFlags(uint32_t flags);
-    uint32_t setTransactionFlags(uint32_t flags);
+    uint32_t getTransactionFlags() const EXCLUDES(mStateMutex);
+    uint32_t getTransactionFlags(uint32_t flags) EXCLUDES(mStateMutex);
+    uint32_t setTransactionFlags(uint32_t flags) REQUIRES(mStateMutex);
 
-    bool belongsToDisplay(uint32_t layerStack, bool isPrimaryDisplay) const {
+    bool belongsToDisplay(uint32_t layerStack, bool isPrimaryDisplay) const EXCLUDES(mStateMutex) {
         return getLayerStack() == layerStack && (!mPrimaryDisplayOnly || isPrimaryDisplay);
     }
 
     void computeGeometry(const RenderArea& renderArea, renderengine::Mesh& mesh,
-                         bool useIdentityTransform) const;
-    FloatRect computeBounds(const Region& activeTransparentRegion) const;
-    FloatRect computeBounds() const;
+                         bool useIdentityTransform) const REQUIRES(mStateMutex);
+    FloatRect computeBounds(const Region& activeTransparentRegion) const EXCLUDES(mStateMutex);
+    FloatRect computeBoundsLocked(const Region& activeTransparentRegion) const
+            REQUIRES(mStateMutex);
+    FloatRect computeBounds() const EXCLUDES(mStateMutex);
+    FloatRect computeBoundsLocked() const REQUIRES(mStateMutex);
 
     int32_t getSequence() const { return sequence; }
 
@@ -352,16 +374,21 @@
      */
     virtual bool isOpaque(const Layer::State&) const { return false; }
 
+    virtual bool isDrawingOpaque() const EXCLUDES(mStateMutex) {
+        Mutex::Autolock lock(mStateMutex);
+        return isOpaque(mState.drawing);
+    }
+
     /*
      * isSecure - true if this surface is secure, that is if it prevents
      * screenshots or VNC servers.
      */
-    bool isSecure() const;
+    bool isSecure() const EXCLUDES(mStateMutex);
 
     /*
      * isVisible - true if this layer is visible, false otherwise
      */
-    virtual bool isVisible() const = 0;
+    virtual bool isVisible() const EXCLUDES(mStateMutex) = 0;
 
     /*
      * isHiddenByPolicy - true if this layer has been forced invisible.
@@ -369,7 +396,7 @@
      * For example if this layer has no active buffer, it may not be hidden by
      * policy, but it still can not be visible.
      */
-    bool isHiddenByPolicy() const;
+    bool isHiddenByPolicy() const EXCLUDES(mStateMutex);
 
     /*
      * isFixedSize - true if content has a fixed size
@@ -384,7 +411,8 @@
     bool isRemovedFromCurrentState() const;
 
     void writeToProto(LayerProto* layerInfo,
-                      LayerVector::StateSet stateSet = LayerVector::StateSet::Drawing);
+                      LayerVector::StateSet stateSet = LayerVector::StateSet::Drawing)
+            EXCLUDES(mStateMutex);
 
     void writeToProto(LayerProto* layerInfo, DisplayId displayId);
 
@@ -397,25 +425,32 @@
     virtual Region getActiveTransparentRegion(const Layer::State& s) const {
         return s.activeTransparentRegion_legacy;
     }
+
+    virtual Region getDrawingActiveTransparentRegion() const EXCLUDES(mStateMutex) {
+        Mutex::Autolock lock(mStateMutex);
+        return getActiveTransparentRegion(mState.drawing);
+    }
+
     virtual Rect getCrop(const Layer::State& s) const { return s.crop_legacy; }
 
 protected:
     /*
      * onDraw - draws the surface.
      */
-    virtual void onDraw(const RenderArea& renderArea, const Region& clip,
-                        bool useIdentityTransform) = 0;
+    virtual void onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform)
+            EXCLUDES(mStateMutex) = 0;
 
 public:
     virtual void setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) {}
 
     virtual bool isHdrY410() const { return false; }
 
-    void setGeometry(const sp<const DisplayDevice>& display, uint32_t z);
+    void setGeometry(const sp<const DisplayDevice>& display, uint32_t z) EXCLUDES(mStateMutex);
     void forceClientComposition(DisplayId displayId);
     bool getForceClientComposition(DisplayId displayId);
     virtual void setPerFrameData(DisplayId displayId, const ui::Transform& transform,
-                                 const Rect& viewport, int32_t supportedPerFrameMetadata) = 0;
+                                 const Rect& viewport, int32_t supportedPerFrameMetadata)
+            EXCLUDES(mStateMutex) = 0;
 
     // callIntoHwc exists so we can update our local state and call
     // acceptDisplayChanges without unnecessarily updating the device's state
@@ -423,7 +458,7 @@
     HWC2::Composition getCompositionType(const std::optional<DisplayId>& displayId) const;
     void setClearClientTarget(DisplayId displayId, bool clear);
     bool getClearClientTarget(DisplayId displayId) const;
-    void updateCursorPosition(const sp<const DisplayDevice>& display);
+    void updateCursorPosition(const sp<const DisplayDevice>& display) EXCLUDES(mStateMutex);
 
     /*
      * called after page-flip
@@ -446,7 +481,8 @@
     virtual bool onPostComposition(const std::optional<DisplayId>& /*displayId*/,
                                    const std::shared_ptr<FenceTime>& /*glDoneFence*/,
                                    const std::shared_ptr<FenceTime>& /*presentFence*/,
-                                   const CompositorTiming& /*compositorTiming*/) {
+                                   const CompositorTiming& /*compositorTiming*/)
+            EXCLUDES(mStateMutex) {
         return false;
     }
 
@@ -458,14 +494,14 @@
      * draw - performs some global clipping optimizations
      * and calls onDraw().
      */
-    void draw(const RenderArea& renderArea, const Region& clip);
-    void draw(const RenderArea& renderArea, bool useIdentityTransform);
+    void draw(const RenderArea& renderArea, const Region& clip) EXCLUDES(mStateMutex);
+    void draw(const RenderArea& renderArea, bool useIdentityTransform) EXCLUDES(mStateMutex);
 
     /*
      * doTransaction - process the transaction. This is a good place to figure
      * out which attributes of the surface have changed.
      */
-    uint32_t doTransaction(uint32_t transactionFlags);
+    uint32_t doTransaction(uint32_t transactionFlags) EXCLUDES(mStateMutex);
 
     /*
      * setVisibleRegion - called to set the new visible region. This gives
@@ -498,17 +534,17 @@
      * to figure out if the content or size of a surface has changed.
      */
     virtual Region latchBuffer(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/,
-                               const sp<Fence>& /*releaseFence*/) {
+                               const sp<Fence>& /*releaseFence*/) EXCLUDES(mStateMutex) {
         return {};
     }
 
     virtual bool isBufferLatched() const { return false; }
 
     /*
-     * called with the state lock from a binder thread when the layer is
+     * called with SurfaceFlinger mStateLock a binder thread when the layer is
      * removed from the current list to the pending removal list
      */
-    void onRemovedFromCurrentState();
+    void onRemovedFromCurrentState() EXCLUDES(mStateMutex);
 
     /*
      * Called when the layer is added back to the current state list.
@@ -528,7 +564,7 @@
     /*
      * Returns if a frame is ready
      */
-    virtual bool hasReadyFrame() const { return false; }
+    virtual bool hasReadyFrame() const EXCLUDES(mStateMutex) { return false; }
 
     virtual int32_t getQueuedFrameCount() const { return 0; }
 
@@ -557,17 +593,32 @@
     }
 
     // -----------------------------------------------------------------------
-    void clearWithOpenGL(const RenderArea& renderArea) const;
+    void clearWithOpenGL(const RenderArea& renderArea) const EXCLUDES(mStateMutex);
 
-    inline const State& getDrawingState() const { return mDrawingState; }
-    inline const State& getCurrentState() const { return mCurrentState; }
-    inline State& getCurrentState() { return mCurrentState; }
+    inline const State& getDrawingState() const REQUIRES(mStateMutex) { return mState.drawing; }
 
-    LayerDebugInfo getLayerDebugInfo() const;
+    inline const State& getCurrentState() const REQUIRES(mStateMutex) { return mState.current; }
+
+    inline State& getCurrentState() REQUIRES(mStateMutex) { return mState.current; }
+
+    std::tuple<uint32_t, int32_t> getLayerStackAndZ(StateSet stateSet) EXCLUDES(mStateMutex);
+    wp<Layer> getZOrderRelativeOf(StateSet stateSet) EXCLUDES(mStateMutex) {
+        Mutex::Autolock lock(mStateMutex);
+        const State& state = (stateSet == StateSet::Current) ? mState.current : mState.drawing;
+
+        return state.zOrderRelativeOf;
+    }
+
+    uint8_t getCurrentFlags() EXCLUDES(mStateMutex) {
+        Mutex::Autolock lock(mStateMutex);
+        return mState.current.flags;
+    }
+
+    LayerDebugInfo getLayerDebugInfo() const EXCLUDES(mStateMutex);
 
     /* always call base class first */
     static void miniDumpHeader(std::string& result);
-    void miniDump(std::string& result, DisplayId displayId) const;
+    void miniDump(std::string& result, DisplayId displayId) const EXCLUDES(mStateMutex);
     void dumpFrameStats(std::string& result) const;
     void dumpFrameEvents(std::string& result);
     void clearFrameStats();
@@ -582,22 +633,29 @@
     void addAndGetFrameTimestamps(const NewFrameEventsEntry* newEntry,
                                   FrameEventHistoryDelta* outDelta);
 
-    virtual bool getTransformToDisplayInverse() const { return false; }
+    bool getTransformToDisplayInverse() const EXCLUDES(mStateMutex) {
+        Mutex::Autolock lock(mStateMutex);
+        return getTransformToDisplayInverseLocked();
+    }
 
-    ui::Transform getTransform() const;
+    virtual bool getTransformToDisplayInverseLocked() const REQUIRES(mStateMutex) { return false; }
+
+    ui::Transform getTransform() const EXCLUDES(mStateMutex);
+    ui::Transform getTransformLocked() const REQUIRES(mStateMutex);
 
     // Returns the Alpha of the Surface, accounting for the Alpha
     // of parent Surfaces in the hierarchy (alpha's will be multiplied
     // down the hierarchy).
-    half getAlpha() const;
-    half4 getColor() const;
+    half getAlpha() const EXCLUDES(mStateMutex);
+    half4 getColor() const REQUIRES(mStateMutex);
 
     // Returns how rounded corners should be drawn for this layer.
     // This will traverse the hierarchy until it reaches its root, finding topmost rounded
     // corner definition and converting it into current layer's coordinates.
     // As of now, only 1 corner radius per display list is supported. Subsequent ones will be
     // ignored.
-    RoundedCornerState getRoundedCornerState() const;
+    RoundedCornerState getRoundedCornerState() const EXCLUDES(mStateMutex);
+    RoundedCornerState getRoundedCornerStateLocked() const REQUIRES(mStateMutex);
 
     void traverseInReverseZOrder(LayerVector::StateSet stateSet,
                                  const LayerVector::Visitor& visitor);
@@ -617,7 +675,7 @@
     ssize_t removeChild(const sp<Layer>& layer);
     sp<Layer> getParent() const { return mCurrentParent.promote(); }
     bool hasParent() const { return getParent() != nullptr; }
-    Rect computeScreenBounds(bool reduceTransparentRegion = true) const;
+    Rect computeScreenBounds(bool reduceTransparentRegion = true) const EXCLUDES(mStateMutex);
     bool setChildLayer(const sp<Layer>& childLayer, int32_t z);
     bool setChildRelativeLayer(const sp<Layer>& childLayer,
             const sp<IBinder>& relativeToHandle, int32_t relativeZ);
@@ -625,14 +683,23 @@
     // Copy the current list of children to the drawing state. Called by
     // SurfaceFlinger to complete a transaction.
     void commitChildList();
-    int32_t getZ() const;
-    virtual void pushPendingState();
+    int32_t getZ() const EXCLUDES(mStateMutex);
+    void pushPendingState() EXCLUDES(mStateMutex);
+    virtual void pushPendingStateLocked() REQUIRES(mStateMutex);
 
     /**
      * Returns active buffer size in the correct orientation. Buffer size is determined by undoing
      * any buffer transformations. If the layer has no buffer then return INVALID_RECT.
      */
-    virtual Rect getBufferSize(const Layer::State&) const { return Rect::INVALID_RECT; }
+    virtual Rect getBufferSize(const Layer::State&) const REQUIRES(mStateMutex) {
+        return Rect::INVALID_RECT;
+    }
+
+    virtual Rect getBufferSize(StateSet stateSet) const EXCLUDES(mStateMutex) {
+        Mutex::Autolock lock(mStateMutex);
+        const State& state = (stateSet == StateSet::Current) ? mState.current : mState.drawing;
+        return getBufferSize(state);
+    }
 
 protected:
     // constant
@@ -661,16 +728,17 @@
     // For unit tests
     friend class TestableSurfaceFlinger;
 
-    void commitTransaction(const State& stateToCommit);
+    void commitTransaction(const State& stateToCommit) REQUIRES(mStateMutex);
 
     uint32_t getEffectiveUsage(uint32_t usage) const;
 
-    virtual FloatRect computeCrop(const sp<const DisplayDevice>& display) const;
+    virtual FloatRect computeCrop(const sp<const DisplayDevice>& display) const
+            REQUIRES(mStateMutex);
     // Compute the initial crop as specified by parent layers and the
     // SurfaceControl for this layer. Does not include buffer crop from the
     // IGraphicBufferProducer client, as that should not affect child clipping.
     // Returns in screen space.
-    Rect computeInitialCrop(const sp<const DisplayDevice>& display) const;
+    Rect computeInitialCrop(const sp<const DisplayDevice>& display) const REQUIRES(mStateMutex);
     /**
      * Setup rounded corners coordinates of this layer, taking into account the layer bounds and
      * crop coordinates, transforming them into layer space.
@@ -678,13 +746,13 @@
     void setupRoundedCornersCropCoordinates(Rect win, const FloatRect& roundedCornersCrop) const;
 
     // drawing
-    void clearWithOpenGL(const RenderArea& renderArea, float r, float g, float b,
-                         float alpha) const;
+    void clearWithOpenGL(const RenderArea& renderArea, float r, float g, float b, float alpha) const
+            EXCLUDES(mStateMutex);
     void setParent(const sp<Layer>& layer);
 
     LayerVector makeTraversalList(LayerVector::StateSet stateSet, bool* outSkipRelativeZUsers);
-    void addZOrderRelative(const wp<Layer>& relative);
-    void removeZOrderRelative(const wp<Layer>& relative);
+    void addZOrderRelative(const wp<Layer>& relative) EXCLUDES(mStateMutex);
+    void removeZOrderRelative(const wp<Layer>& relative) EXCLUDES(mStateMutex);
 
     class SyncPoint {
     public:
@@ -720,9 +788,10 @@
     // Returns false if the relevant frame has already been latched
     bool addSyncPoint(const std::shared_ptr<SyncPoint>& point);
 
-    void popPendingState(State* stateToCommit);
-    virtual bool applyPendingStates(State* stateToCommit);
-    virtual uint32_t doTransactionResize(uint32_t flags, Layer::State* stateToCommit);
+    void popPendingState(State* stateToCommit) REQUIRES(mStateMutex);
+    virtual bool applyPendingStates(State* stateToCommit) REQUIRES(mStateMutex);
+    virtual uint32_t doTransactionResize(uint32_t flags, Layer::State* stateToCommit)
+            REQUIRES(mStateMutex);
 
     void clearSyncPoints();
 
@@ -755,14 +824,15 @@
     bool getPremultipledAlpha() const;
 
     bool mPendingHWCDestroy{false};
-    void setInputInfo(const InputWindowInfo& info);
+    void setInputInfo(const InputWindowInfo& info) EXCLUDES(mStateMutex);
 
-    InputWindowInfo fillInputInfo(const Rect& screenBounds);
-    bool hasInput() const;
+    InputWindowInfo fillInputInfo(const Rect& screenBounds) EXCLUDES(mStateMutex);
+    bool hasInput() const EXCLUDES(mStateMutex);
 
 protected:
     // -----------------------------------------------------------------------
-    bool usingRelativeZ(LayerVector::StateSet stateSet);
+    bool usingRelativeZ(LayerVector::StateSet stateSet) EXCLUDES(mStateMutex);
+    bool usingRelativeZLocked(LayerVector::StateSet stateSet) REQUIRES(mStateMutex);
 
     bool mPremultipliedAlpha{true};
     String8 mName;
@@ -770,14 +840,14 @@
 
     bool mPrimaryDisplayOnly = false;
 
-    // these are protected by an external lock
-    State mCurrentState;
-    State mDrawingState;
-    std::atomic<uint32_t> mTransactionFlags{0};
-
     // Accessed from main thread and binder threads
-    Mutex mPendingStateMutex;
-    Vector<State> mPendingStates;
+    mutable Mutex mStateMutex;
+    struct {
+        State current;
+        State drawing;
+        uint32_t transactionFlags{0};
+        Vector<State> pending;
+    } mState GUARDED_BY(mStateMutex);
 
     // Timestamp history for UIAutomation. Thread safe.
     FrameTracker mFrameTracker;
@@ -850,7 +920,7 @@
      * The cropped bounds must be transformed back from parent layer space to child layer space by
      * applying the inverse of the child's transformation.
      */
-    FloatRect cropChildBounds(const FloatRect& childBounds) const;
+    FloatRect cropChildBounds(const FloatRect& childBounds) const REQUIRES(mStateMutex);
 
     /**
      * Returns the cropped buffer size or the layer crop if the layer has no buffer. Return
@@ -858,7 +928,12 @@
      * A layer with an invalid buffer size and no crop is considered to be boundless. The layer
      * bounds are constrained by its parent bounds.
      */
-    Rect getCroppedBufferSize(const Layer::State& s) const;
+    Rect getCroppedBufferSize(const Layer::State& s) const REQUIRES(mStateMutex);
+
+    // locked version of public methods
+    bool isSecureLocked() const REQUIRES(mStateMutex);
+    virtual uint32_t getLayerStackLocked() const REQUIRES(mStateMutex);
+    half getAlphaLocked() const REQUIRES(mStateMutex);
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/LayerVector.cpp b/services/surfaceflinger/LayerVector.cpp
index 8494524..a7db23e 100644
--- a/services/surfaceflinger/LayerVector.cpp
+++ b/services/surfaceflinger/LayerVector.cpp
@@ -38,18 +38,12 @@
     const auto& l = *reinterpret_cast<const sp<Layer>*>(lhs);
     const auto& r = *reinterpret_cast<const sp<Layer>*>(rhs);
 
-    const auto& lState =
-            (mStateSet == StateSet::Current) ? l->getCurrentState() : l->getDrawingState();
-    const auto& rState =
-            (mStateSet == StateSet::Current) ? r->getCurrentState() : r->getDrawingState();
+    const auto& [ls, lz] = l->getLayerStackAndZ(mStateSet);
+    const auto& [rs, rz] = r->getLayerStackAndZ(mStateSet);
 
-    uint32_t ls = lState.layerStack;
-    uint32_t rs = rState.layerStack;
     if (ls != rs)
         return (ls > rs) ? 1 : -1;
 
-    int32_t lz = lState.z;
-    int32_t rz = rState.z;
     if (lz != rz)
         return (lz > rz) ? 1 : -1;
 
@@ -62,9 +56,8 @@
 void LayerVector::traverseInZOrder(StateSet stateSet, const Visitor& visitor) const {
     for (size_t i = 0; i < size(); i++) {
         const auto& layer = (*this)[i];
-        auto& state = (stateSet == StateSet::Current) ? layer->getCurrentState()
-                                                      : layer->getDrawingState();
-        if (state.zOrderRelativeOf != nullptr) {
+        auto zOrderRelativeOf = layer->getZOrderRelativeOf(stateSet);
+        if (zOrderRelativeOf != nullptr) {
             continue;
         }
         layer->traverseInZOrder(stateSet, visitor);
@@ -74,9 +67,8 @@
 void LayerVector::traverseInReverseZOrder(StateSet stateSet, const Visitor& visitor) const {
     for (auto i = static_cast<int64_t>(size()) - 1; i >= 0; i--) {
         const auto& layer = (*this)[i];
-        auto& state = (stateSet == StateSet::Current) ? layer->getCurrentState()
-                                                      : layer->getDrawingState();
-        if (state.zOrderRelativeOf != nullptr) {
+        auto zOrderRelativeOf = layer->getZOrderRelativeOf(stateSet);
+        if (zOrderRelativeOf != nullptr) {
             continue;
         }
         layer->traverseInReverseZOrder(stateSet, visitor);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a142928..93e03d6 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2850,9 +2850,6 @@
     outDirtyRegion.clear();
 
     mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
-        // start with the whole surface at its current location
-        const Layer::State& s(layer->getDrawingState());
-
         // only consider the layers on the given layer stack
         if (!layer->belongsToDisplay(display->getLayerStack(), display->isPrimary())) {
             return;
@@ -2890,7 +2887,7 @@
 
         // handle hidden surfaces by setting the visible region to empty
         if (CC_LIKELY(layer->isVisible())) {
-            const bool translucent = !layer->isOpaque(s);
+            const bool translucent = !layer->isDrawingOpaque();
             Rect bounds(layer->computeScreenBounds());
 
             visibleRegion.set(bounds);
@@ -2900,7 +2897,8 @@
                 if (translucent) {
                     if (tr.preserveRects()) {
                         // transform the transparent region
-                        transparentRegion = tr.transform(layer->getActiveTransparentRegion(s));
+                        transparentRegion =
+                                tr.transform(layer->getDrawingActiveTransparentRegion());
                     } else {
                         // transformation too complex, can't do the
                         // transparent region optimization.
@@ -3199,9 +3197,8 @@
                 case HWC2::Composition::Sideband:
                 case HWC2::Composition::SolidColor: {
                     LOG_ALWAYS_FATAL_IF(!displayId);
-                    const Layer::State& state(layer->getDrawingState());
                     if (layer->getClearClientTarget(*displayId) && !firstLayer &&
-                        layer->isOpaque(state) && (layer->getAlpha() == 1.0f) &&
+                        layer->isDrawingOpaque() && (layer->getAlpha() == 1.0f) &&
                         layer->getRoundedCornerState().radius == 0.0f && hasClientComposition) {
                         // never clear the very first layer since we're
                         // guaranteed the FB is already cleared
@@ -5235,15 +5232,12 @@
                 mFlinger(flinger),
                 mChildrenOnly(childrenOnly) {}
         const ui::Transform& getTransform() const override { return mTransform; }
-        Rect getBounds() const override {
-            const Layer::State& layerState(mLayer->getDrawingState());
-            return mLayer->getBufferSize(layerState);
-        }
+        Rect getBounds() const override { return mLayer->getBufferSize(StateSet::Drawing); }
         int getHeight() const override {
-            return mLayer->getBufferSize(mLayer->getDrawingState()).getHeight();
+            return mLayer->getBufferSize(StateSet::Drawing).getHeight();
         }
         int getWidth() const override {
-            return mLayer->getBufferSize(mLayer->getDrawingState()).getWidth();
+            return mLayer->getBufferSize(StateSet::Drawing).getWidth();
         }
         bool isSecure() const override { return false; }
         bool needsFiltering() const override { return mNeedsFiltering; }
@@ -5310,7 +5304,7 @@
 
     const int uid = IPCThreadState::self()->getCallingUid();
     const bool forSystem = uid == AID_GRAPHICS || uid == AID_SYSTEM;
-    if (!forSystem && parent->getCurrentState().flags & layer_state_t::eLayerSecure) {
+    if (!forSystem && parent->getCurrentFlags() & layer_state_t::eLayerSecure) {
         ALOGW("Attempting to capture secure layer: PERMISSION_DENIED");
         return PERMISSION_DENIED;
     }
@@ -5318,12 +5312,12 @@
     Rect crop(sourceCrop);
     if (sourceCrop.width() <= 0) {
         crop.left = 0;
-        crop.right = parent->getBufferSize(parent->getCurrentState()).getWidth();
+        crop.right = parent->getBufferSize(StateSet::Current).getWidth();
     }
 
     if (sourceCrop.height() <= 0) {
         crop.top = 0;
-        crop.bottom = parent->getBufferSize(parent->getCurrentState()).getHeight();
+        crop.bottom = parent->getBufferSize(StateSet::Current).getHeight();
     }
 
     int32_t reqWidth = crop.width() * frameScale;
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 7bfe033..a6dcb7e 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -101,22 +101,23 @@
     transaction->set_animation(layerFlags & BnSurfaceComposer::eAnimation);
 
     const int32_t layerId(getLayerId(layer));
-    addPositionLocked(transaction, layerId, layer->mCurrentState.active_legacy.transform.tx(),
-                      layer->mCurrentState.active_legacy.transform.ty());
-    addDepthLocked(transaction, layerId, layer->mCurrentState.z);
-    addAlphaLocked(transaction, layerId, layer->mCurrentState.color.a);
+    Mutex::Autolock lock(layer->mStateMutex);
+    addPositionLocked(transaction, layerId, layer->mState.current.active_legacy.transform.tx(),
+                      layer->mState.current.active_legacy.transform.ty());
+    addDepthLocked(transaction, layerId, layer->mState.current.z);
+    addAlphaLocked(transaction, layerId, layer->mState.current.color.a);
     addTransparentRegionLocked(transaction, layerId,
-                               layer->mCurrentState.activeTransparentRegion_legacy);
-    addLayerStackLocked(transaction, layerId, layer->mCurrentState.layerStack);
-    addCropLocked(transaction, layerId, layer->mCurrentState.crop_legacy);
-    addCornerRadiusLocked(transaction, layerId, layer->mCurrentState.cornerRadius);
-    if (layer->mCurrentState.barrierLayer_legacy != nullptr) {
+                               layer->mState.current.activeTransparentRegion_legacy);
+    addLayerStackLocked(transaction, layerId, layer->mState.current.layerStack);
+    addCropLocked(transaction, layerId, layer->mState.current.crop_legacy);
+    addCornerRadiusLocked(transaction, layerId, layer->mState.current.cornerRadius);
+    if (layer->mState.current.barrierLayer_legacy != nullptr) {
         addDeferTransactionLocked(transaction, layerId,
-                                  layer->mCurrentState.barrierLayer_legacy.promote(),
-                                  layer->mCurrentState.frameNumber_legacy);
+                                  layer->mState.current.barrierLayer_legacy.promote(),
+                                  layer->mState.current.frameNumber_legacy);
     }
     addOverrideScalingModeLocked(transaction, layerId, layer->getEffectiveScalingMode());
-    addFlagsLocked(transaction, layerId, layer->mCurrentState.flags);
+    addFlagsLocked(transaction, layerId, layer->mState.current.flags);
 }
 
 void SurfaceInterceptor::addInitialDisplayStateLocked(Increment* increment,
@@ -426,8 +427,9 @@
     SurfaceCreation* creation(increment->mutable_surface_creation());
     creation->set_id(getLayerId(layer));
     creation->set_name(getLayerName(layer));
-    creation->set_w(layer->mCurrentState.active_legacy.w);
-    creation->set_h(layer->mCurrentState.active_legacy.h);
+    Mutex::Autolock lock(layer->mStateMutex);
+    creation->set_w(layer->mState.current.active_legacy.w);
+    creation->set_h(layer->mState.current.active_legacy.h);
 }
 
 void SurfaceInterceptor::addSurfaceDeletionLocked(Increment* increment,
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 6d4f7ef..63216a9 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -178,11 +178,12 @@
 
     using HotplugEvent = SurfaceFlinger::HotplugEvent;
 
-    auto& mutableLayerCurrentState(sp<Layer> layer) { return layer->mCurrentState; }
-    auto& mutableLayerDrawingState(sp<Layer> layer) { return layer->mDrawingState; }
+    auto& mutableLayerCurrentState(sp<Layer> layer) { return layer->mState.current; }
+    auto& mutableLayerDrawingState(sp<Layer> layer) { return layer->mState.drawing; }
 
     void setLayerSidebandStream(sp<Layer> layer, sp<NativeHandle> sidebandStream) {
-        layer->mDrawingState.sidebandStream = sidebandStream;
+        Mutex::Autolock lock(layer->mStateMutex);
+        layer->mState.drawing.sidebandStream = sidebandStream;
         layer->getBE().compositionInfo.hwc.sidebandStream = sidebandStream;
     }