Merge "SurfaceFlinger: add transactions to FrameTimeline"
diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp
index 51fd84c..ca03397 100644
--- a/libs/binder/ndk/ibinder.cpp
+++ b/libs/binder/ndk/ibinder.cpp
@@ -73,12 +73,11 @@
 AIBinder::AIBinder(const AIBinder_Class* clazz) : mClazz(clazz) {}
 AIBinder::~AIBinder() {}
 
-bool AIBinder::associateClass(const AIBinder_Class* clazz) {
-    if (clazz == nullptr) return false;
+std::optional<bool> AIBinder::associateClassInternal(const AIBinder_Class* clazz,
+                                                     const String8& newDescriptor, bool set) {
+    std::lock_guard<std::mutex> lock(mClazzMutex);
     if (mClazz == clazz) return true;
 
-    String8 newDescriptor(clazz->getInterfaceDescriptor());
-
     if (mClazz != nullptr) {
         String8 currentDescriptor(mClazz->getInterfaceDescriptor());
         if (newDescriptor == currentDescriptor) {
@@ -97,6 +96,22 @@
         return false;
     }
 
+    if (set) {
+        // if this is a local object, it's not one known to libbinder_ndk
+        mClazz = clazz;
+    }
+
+    return {};
+}
+
+bool AIBinder::associateClass(const AIBinder_Class* clazz) {
+    if (clazz == nullptr) return false;
+
+    String8 newDescriptor(clazz->getInterfaceDescriptor());
+
+    auto result = associateClassInternal(clazz, newDescriptor, false);
+    if (result.has_value()) return *result;
+
     CHECK(asABpBinder() != nullptr);  // ABBinder always has a descriptor
 
     String8 descriptor(getBinder()->getInterfaceDescriptor());
@@ -112,10 +127,7 @@
         return false;
     }
 
-    // if this is a local object, it's not one known to libbinder_ndk
-    mClazz = clazz;
-
-    return true;
+    return associateClassInternal(clazz, newDescriptor, true).value_or(true);
 }
 
 ABBinder::ABBinder(const AIBinder_Class* clazz, void* userData)
diff --git a/libs/binder/ndk/ibinder_internal.h b/libs/binder/ndk/ibinder_internal.h
index 902fe79..bf27046 100644
--- a/libs/binder/ndk/ibinder_internal.h
+++ b/libs/binder/ndk/ibinder_internal.h
@@ -22,6 +22,7 @@
 
 #include <atomic>
 #include <mutex>
+#include <optional>
 #include <vector>
 
 #include <binder/Binder.h>
@@ -52,10 +53,14 @@
     }
 
    private:
+    std::optional<bool> associateClassInternal(const AIBinder_Class* clazz,
+                                               const ::android::String8& newDescriptor, bool set);
+
     // AIBinder instance is instance of this class for a local object. In order to transact on a
     // remote object, this also must be set for simplicity (although right now, only the
     // interfaceDescriptor from it is used).
     const AIBinder_Class* mClazz;
+    std::mutex mClazzMutex;
 };
 
 // This is a local AIBinder object with a known class.
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 56591bd..ba72f9b 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -18,6 +18,7 @@
 #define LOG_TAG "BLASTBufferQueue"
 
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
+// #define LOG_NDEBUG 0
 
 #include <gui/BLASTBufferQueue.h>
 #include <gui/BufferItemConsumer.h>
@@ -29,8 +30,20 @@
 
 using namespace std::chrono_literals;
 
+namespace {
+inline const char* toString(bool b) {
+    return b ? "true" : "false";
+}
+} // namespace
+
 namespace android {
 
+// Macros to include adapter info in log messages
+#define BQA_LOGV(x, ...) \
+    ALOGV("[%s](f:%u,a:%u) " x, mName.c_str(), mNumFrameAvailable, mNumAcquired, ##__VA_ARGS__)
+#define BQA_LOGE(x, ...) \
+    ALOGE("[%s](f:%u,a:%u) " x, mName.c_str(), mNumFrameAvailable, mNumAcquired, ##__VA_ARGS__)
+
 void BLASTBufferItemConsumer::onDisconnect() {
     Mutex::Autolock lock(mFrameEventHistoryMutex);
     mPreviouslyConnected = mCurrentlyConnected;
@@ -93,9 +106,10 @@
     if (needsDisconnect != nullptr) *needsDisconnect = disconnect;
 }
 
-BLASTBufferQueue::BLASTBufferQueue(const sp<SurfaceControl>& surface, int width, int height,
-                                   bool enableTripleBuffering)
-      : mSurfaceControl(surface),
+BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface,
+                                   int width, int height, bool enableTripleBuffering)
+      : mName(name),
+        mSurfaceControl(surface),
         mWidth(width),
         mHeight(height),
         mNextTransaction(nullptr) {
@@ -110,9 +124,9 @@
     mBufferItemConsumer =
         new BLASTBufferItemConsumer(mConsumer, GraphicBuffer::USAGE_HW_COMPOSER, 1, true);
     static int32_t id = 0;
-    auto name = std::string("BLAST Consumer") + std::to_string(id);
+    auto consumerName = mName + "(BLAST Consumer)" + std::to_string(id);
     id++;
-    mBufferItemConsumer->setName(String8(name.c_str()));
+    mBufferItemConsumer->setName(String8(consumerName.c_str()));
     mBufferItemConsumer->setFrameAvailableListener(this);
     mBufferItemConsumer->setBufferFreedListener(this);
     mBufferItemConsumer->setDefaultBufferSize(mWidth, mHeight);
@@ -127,7 +141,7 @@
     mPendingReleaseItem.releaseFence = nullptr;
 }
 
-void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, int width, int height) {
+void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height) {
     std::unique_lock _lock{mMutex};
     mSurfaceControl = surface;
 
@@ -153,6 +167,8 @@
     std::unique_lock _lock{mMutex};
     ATRACE_CALL();
 
+    BQA_LOGV("transactionCallback");
+
     if (!stats.empty()) {
         mTransformHint = stats[0].transformHint;
         mBufferItemConsumer->setTransformHint(mTransformHint);
@@ -195,6 +211,8 @@
 
 void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) {
     ATRACE_CALL();
+    BQA_LOGV("processNextBufferLocked useNextTransaction=%s", toString(useNextTransaction));
+
     if (mNumFrameAvailable == 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS + 1) {
         return;
     }
@@ -246,15 +264,22 @@
                        bufferItem.mFence ? new Fence(bufferItem.mFence->dup()) : Fence::NO_FENCE);
     t->addTransactionCompletedCallback(transactionCallbackThunk, static_cast<void*>(this));
 
-    t->setFrame(mSurfaceControl, {0, 0, mWidth, mHeight});
+    t->setFrame(mSurfaceControl,
+                {0, 0, static_cast<int32_t>(mWidth), static_cast<int32_t>(mHeight)});
     t->setCrop(mSurfaceControl, computeCrop(bufferItem));
     t->setTransform(mSurfaceControl, bufferItem.mTransform);
     t->setTransformToDisplayInverse(mSurfaceControl, bufferItem.mTransformToDisplayInverse);
     t->setDesiredPresentTime(bufferItem.mTimestamp);
+    t->setFrameNumber(mSurfaceControl, bufferItem.mFrameNumber);
 
     if (applyTransaction) {
         t->apply();
     }
+
+    BQA_LOGV("processNextBufferLocked size=%dx%d mFrameNumber=%" PRIu64
+             " applyTransaction=%s mTimestamp=%" PRId64,
+             mWidth, mHeight, bufferItem.mFrameNumber, toString(applyTransaction),
+             bufferItem.mTimestamp);
 }
 
 Rect BLASTBufferQueue::computeCrop(const BufferItem& item) {
@@ -268,7 +293,10 @@
     ATRACE_CALL();
     std::unique_lock _lock{mMutex};
 
-    if (mNextTransaction != nullptr) {
+    const bool nextTransactionSet = mNextTransaction != nullptr;
+    BQA_LOGV("onFrameAvailable nextTransactionSet=%s", toString(nextTransactionSet));
+
+    if (nextTransactionSet) {
         while (mNumFrameAvailable > 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS + 1) {
             mCallbackCV.wait(_lock);
         }
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index 621cf59..a814362 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -49,13 +49,13 @@
 
     status_t createSurface(const String8& name, uint32_t width, uint32_t height, PixelFormat format,
                            uint32_t flags, const sp<IBinder>& parent, LayerMetadata metadata,
-                           sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp,
+                           sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, int32_t* outId,
                            uint32_t* outTransformHint) override {
         return callRemote<decltype(&ISurfaceComposerClient::createSurface)>(Tag::CREATE_SURFACE,
                                                                             name, width, height,
                                                                             format, flags, parent,
                                                                             std::move(metadata),
-                                                                            handle, gbp,
+                                                                            handle, gbp, outId,
                                                                             outTransformHint);
     }
 
@@ -63,14 +63,14 @@
                                      PixelFormat format, uint32_t flags,
                                      const sp<IGraphicBufferProducer>& parent,
                                      LayerMetadata metadata, sp<IBinder>* handle,
-                                     sp<IGraphicBufferProducer>* gbp,
+                                     sp<IGraphicBufferProducer>* gbp, int32_t* outId,
                                      uint32_t* outTransformHint) override {
         return callRemote<decltype(
                 &ISurfaceComposerClient::createWithSurfaceParent)>(Tag::CREATE_WITH_SURFACE_PARENT,
                                                                    name, width, height, format,
                                                                    flags, parent,
                                                                    std::move(metadata), handle, gbp,
-                                                                   outTransformHint);
+                                                                   outId, outTransformHint);
     }
 
     status_t clearLayerFrameStats(const sp<IBinder>& handle) const override {
@@ -85,10 +85,11 @@
                                                               outStats);
     }
 
-    status_t mirrorSurface(const sp<IBinder>& mirrorFromHandle, sp<IBinder>* outHandle) override {
+    status_t mirrorSurface(const sp<IBinder>& mirrorFromHandle, sp<IBinder>* outHandle,
+                           int32_t* outId) override {
         return callRemote<decltype(&ISurfaceComposerClient::mirrorSurface)>(Tag::MIRROR_SURFACE,
                                                                             mirrorFromHandle,
-                                                                            outHandle);
+                                                                            outHandle, outId);
     }
 };
 
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 6ff4a3d..4a57b1b 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -31,6 +31,7 @@
 status_t layer_state_t::write(Parcel& output) const
 {
     SAFE_PARCEL(output.writeStrongBinder, surface);
+    SAFE_PARCEL(output.writeInt32, layerId);
     SAFE_PARCEL(output.writeUint64, what);
     SAFE_PARCEL(output.writeFloat, x);
     SAFE_PARCEL(output.writeFloat, y);
@@ -45,7 +46,7 @@
     SAFE_PARCEL(output.write, crop_legacy);
     SAFE_PARCEL(output.writeStrongBinder, barrierHandle_legacy);
     SAFE_PARCEL(output.writeStrongBinder, reparentHandle);
-    SAFE_PARCEL(output.writeUint64, frameNumber_legacy);
+    SAFE_PARCEL(output.writeUint64, barrierFrameNumber);
     SAFE_PARCEL(output.writeInt32, overrideScalingMode);
     SAFE_PARCEL(output.writeStrongBinder, IInterface::asBinder(barrierGbp_legacy));
     SAFE_PARCEL(output.writeStrongBinder, relativeLayerHandle);
@@ -108,12 +109,14 @@
     SAFE_PARCEL(output.writeFloat, frameRate);
     SAFE_PARCEL(output.writeByte, frameRateCompatibility);
     SAFE_PARCEL(output.writeUint32, fixedTransformHint);
+    SAFE_PARCEL(output.writeUint64, frameNumber);
     return NO_ERROR;
 }
 
 status_t layer_state_t::read(const Parcel& input)
 {
     SAFE_PARCEL(input.readNullableStrongBinder, &surface);
+    SAFE_PARCEL(input.readInt32, &layerId);
     SAFE_PARCEL(input.readUint64, &what);
     SAFE_PARCEL(input.readFloat, &x);
     SAFE_PARCEL(input.readFloat, &y);
@@ -134,7 +137,7 @@
     SAFE_PARCEL(input.read, crop_legacy);
     SAFE_PARCEL(input.readNullableStrongBinder, &barrierHandle_legacy);
     SAFE_PARCEL(input.readNullableStrongBinder, &reparentHandle);
-    SAFE_PARCEL(input.readUint64, &frameNumber_legacy);
+    SAFE_PARCEL(input.readUint64, &barrierFrameNumber);
     SAFE_PARCEL(input.readInt32, &overrideScalingMode);
 
     sp<IBinder> tmpBinder;
@@ -213,6 +216,7 @@
     SAFE_PARCEL(input.readByte, &frameRateCompatibility);
     SAFE_PARCEL(input.readUint32, &tmpUint32);
     fixedTransformHint = static_cast<ui::Transform::RotationFlags>(tmpUint32);
+    SAFE_PARCEL(input.readUint64, &frameNumber);
     return NO_ERROR;
 }
 
@@ -340,7 +344,7 @@
         what |= eDeferTransaction_legacy;
         barrierHandle_legacy = other.barrierHandle_legacy;
         barrierGbp_legacy = other.barrierGbp_legacy;
-        frameNumber_legacy = other.frameNumber_legacy;
+        barrierFrameNumber = other.barrierFrameNumber;
     }
     if (other.what & eOverrideScalingModeChanged) {
         what |= eOverrideScalingModeChanged;
@@ -456,6 +460,10 @@
         what |= eFixedTransformHintChanged;
         fixedTransformHint = other.fixedTransformHint;
     }
+    if (other.what & eFrameNumberChanged) {
+        what |= eFrameNumberChanged;
+        frameNumber = other.frameNumber;
+    }
     if ((other.what & what) != other.what) {
         ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? "
               "other.what=0x%" PRIu64 " what=0x%" PRIu64,
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index d4a9cc1..2f6a34b 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -433,7 +433,7 @@
         }
         for (size_t j = 0; j < numSurfaces; j++) {
             sp<SurfaceControl> surface;
-            surface = SurfaceControl::readFromParcel(parcel);
+            SAFE_PARCEL(SurfaceControl::readFromParcel, *parcel, &surface);
             listenerCallbacks[listener].surfaceControls.insert(surface);
         }
     }
@@ -445,12 +445,14 @@
     std::unordered_map<sp<IBinder>, ComposerState, IBinderHash> composerStates;
     composerStates.reserve(count);
     for (size_t i = 0; i < count; i++) {
-        sp<IBinder> surfaceControlHandle = parcel->readStrongBinder();
+        sp<IBinder> surfaceControlHandle;
+        SAFE_PARCEL(parcel->readStrongBinder, &surfaceControlHandle);
 
         ComposerState composerState;
         if (composerState.read(*parcel) == BAD_VALUE) {
             return BAD_VALUE;
         }
+
         composerStates[surfaceControlHandle] = composerState;
     }
 
@@ -511,13 +513,13 @@
         }
         parcel->writeUint32(static_cast<uint32_t>(callbackInfo.surfaceControls.size()));
         for (auto surfaceControl : callbackInfo.surfaceControls) {
-            surfaceControl->writeToParcel(parcel);
+            SAFE_PARCEL(surfaceControl->writeToParcel, *parcel);
         }
     }
 
     parcel->writeUint32(static_cast<uint32_t>(mComposerStates.size()));
-    for (auto const& [surfaceHandle, composerState] : mComposerStates) {
-        parcel->writeStrongBinder(surfaceHandle);
+    for (auto const& [handle, composerState] : mComposerStates) {
+        SAFE_PARCEL(parcel->writeStrongBinder, handle);
         composerState.write(*parcel);
     }
 
@@ -526,11 +528,11 @@
 }
 
 SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Transaction&& other) {
-    for (auto const& [surfaceHandle, composerState] : other.mComposerStates) {
-        if (mComposerStates.count(surfaceHandle) == 0) {
-            mComposerStates[surfaceHandle] = composerState;
+    for (auto const& [handle, composerState] : other.mComposerStates) {
+        if (mComposerStates.count(handle) == 0) {
+            mComposerStates[handle] = composerState;
         } else {
-            mComposerStates[surfaceHandle].state.merge(composerState.state);
+            mComposerStates[handle].state.merge(composerState.state);
         }
     }
 
@@ -620,7 +622,7 @@
 
     size_t count = 0;
     for (auto& [handle, cs] : mComposerStates) {
-        layer_state_t* s = getLayerState(handle);
+        layer_state_t* s = &(mComposerStates[handle].state);
         if (!(s->what & layer_state_t::eBufferChanged)) {
             continue;
         } else if (s->what & layer_state_t::eCachedBufferChanged) {
@@ -793,11 +795,16 @@
     mExplicitEarlyWakeupEnd = true;
 }
 
-layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp<IBinder>& handle) {
+layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp<SurfaceControl>& sc) {
+    auto handle = sc->getHandle();
+
     if (mComposerStates.count(handle) == 0) {
         // we don't have it, add an initialized layer_state to our list
         ComposerState s;
+
         s.state.surface = handle;
+        s.state.layerId = sc->getLayerId();
+
         mComposerStates[handle] = s;
     }
 
@@ -1031,7 +1038,7 @@
     }
     s->what |= layer_state_t::eDeferTransaction_legacy;
     s->barrierHandle_legacy = handle;
-    s->frameNumber_legacy = frameNumber;
+    s->barrierFrameNumber = frameNumber;
 
     registerSurfaceControlForCallback(sc);
     return *this;
@@ -1048,7 +1055,7 @@
     }
     s->what |= layer_state_t::eDeferTransaction_legacy;
     s->barrierGbp_legacy = barrierSurface->getIGraphicBufferProducer();
-    s->frameNumber_legacy = frameNumber;
+    s->barrierFrameNumber = frameNumber;
 
     registerSurfaceControlForCallback(sc);
     return *this;
@@ -1338,6 +1345,20 @@
     return *this;
 }
 
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameNumber(
+        const sp<SurfaceControl>& sc, uint64_t frameNumber) {
+    layer_state_t* s = getLayerState(sc);
+    if (!s) {
+        mStatus = BAD_INDEX;
+        return *this;
+    }
+
+    s->what |= layer_state_t::eFrameNumberChanged;
+    s->frameNumber = frameNumber;
+
+    return *this;
+}
+
 SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::detachChildren(
         const sp<SurfaceControl>& sc) {
     layer_state_t* s = getLayerState(sc);
@@ -1675,14 +1696,16 @@
         sp<IGraphicBufferProducer> gbp;
 
         uint32_t transformHint = 0;
+        int32_t id = -1;
         err = mClient->createWithSurfaceParent(name, w, h, format, flags, parentGbp,
-                                               std::move(metadata), &handle, &gbp, &transformHint);
+                                               std::move(metadata), &handle, &gbp, &id,
+                                               &transformHint);
         if (outTransformHint) {
             *outTransformHint = transformHint;
         }
         ALOGE_IF(err, "SurfaceComposerClient::createWithSurfaceParent error %s", strerror(-err));
         if (err == NO_ERROR) {
-            return new SurfaceControl(this, handle, gbp, transformHint);
+            return new SurfaceControl(this, handle, gbp, id, transformHint);
         }
     }
     return nullptr;
@@ -1706,14 +1729,16 @@
         }
 
         uint32_t transformHint = 0;
+        int32_t id = -1;
         err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
-                                     &handle, &gbp, &transformHint);
+                                     &handle, &gbp, &id, &transformHint);
+
         if (outTransformHint) {
             *outTransformHint = transformHint;
         }
         ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
         if (err == NO_ERROR) {
-            *outSurface = new SurfaceControl(this, handle, gbp, transformHint);
+            *outSurface = new SurfaceControl(this, handle, gbp, id, transformHint);
         }
     }
     return err;
@@ -1726,9 +1751,10 @@
 
     sp<IBinder> handle;
     sp<IBinder> mirrorFromHandle = mirrorFromSurface->getHandle();
-    status_t err = mClient->mirrorSurface(mirrorFromHandle, &handle);
+    int32_t layer_id = -1;
+    status_t err = mClient->mirrorSurface(mirrorFromHandle, &handle, &layer_id);
     if (err == NO_ERROR) {
-        return new SurfaceControl(this, handle, nullptr, true /* owned */);
+        return new SurfaceControl(this, handle, nullptr, layer_id, true /* owned */);
     }
     return nullptr;
 }
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 8dcb71b..e37ff89 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -46,11 +46,12 @@
 // ============================================================================
 
 SurfaceControl::SurfaceControl(const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle,
-                               const sp<IGraphicBufferProducer>& gbp,
+                               const sp<IGraphicBufferProducer>& gbp, int32_t layerId,
                                uint32_t transform)
       : mClient(client),
         mHandle(handle),
         mGraphicBufferProducer(gbp),
+        mLayerId(layerId),
         mTransformHint(transform) {}
 
 SurfaceControl::SurfaceControl(const sp<SurfaceControl>& other) {
@@ -58,6 +59,7 @@
     mHandle = other->mHandle;
     mGraphicBufferProducer = other->mGraphicBufferProducer;
     mTransformHint = other->mTransformHint;
+    mLayerId = other->mLayerId;
 }
 
 SurfaceControl::~SurfaceControl()
@@ -148,6 +150,10 @@
     return mHandle;
 }
 
+int32_t SurfaceControl::getLayerId() const {
+    return mLayerId;
+}
+
 sp<IGraphicBufferProducer> SurfaceControl::getIGraphicBufferProducer() const
 {
     Mutex::Autolock _l(mLock);
@@ -169,42 +175,60 @@
     mTransformHint = hint;
 }
 
-void SurfaceControl::writeToParcel(Parcel* parcel)
-{
-    parcel->writeStrongBinder(ISurfaceComposerClient::asBinder(mClient->getClient()));
-    parcel->writeStrongBinder(mHandle);
-    parcel->writeStrongBinder(IGraphicBufferProducer::asBinder(mGraphicBufferProducer));
-    parcel->writeUint32(mTransformHint);
+status_t SurfaceControl::writeToParcel(Parcel& parcel) {
+    SAFE_PARCEL(parcel.writeStrongBinder, ISurfaceComposerClient::asBinder(mClient->getClient()));
+    SAFE_PARCEL(parcel.writeStrongBinder, mHandle);
+    SAFE_PARCEL(parcel.writeStrongBinder, IGraphicBufferProducer::asBinder(mGraphicBufferProducer));
+    SAFE_PARCEL(parcel.writeInt32, mLayerId);
+    SAFE_PARCEL(parcel.writeUint32, mTransformHint);
+
+    return NO_ERROR;
 }
 
-sp<SurfaceControl> SurfaceControl::readFromParcel(const Parcel* parcel) {
-    bool invalidParcel = false;
-    status_t status;
+status_t SurfaceControl::readFromParcel(const Parcel& parcel,
+                                        sp<SurfaceControl>* outSurfaceControl) {
     sp<IBinder> client;
-    if ((status = parcel->readStrongBinder(&client)) != OK) {
-        ALOGE("Failed to read client: %s", statusToString(status).c_str());
-        invalidParcel = true;
-    }
     sp<IBinder> handle;
-    if ((status = parcel->readStrongBinder(&handle)) != OK) {
-        ALOGE("Failed to read handle: %s", statusToString(status).c_str());
-        invalidParcel = true;
-    }
     sp<IBinder> gbp;
-    if ((status = parcel->readNullableStrongBinder(&gbp)) != OK) {
-        ALOGE("Failed to read gbp: %s", statusToString(status).c_str());
-        invalidParcel = true;
-    }
-    uint32_t transformHint = parcel->readUint32();
+    int32_t layerId;
+    uint32_t transformHint;
 
-    if (invalidParcel) {
-        return nullptr;
-    }
+    SAFE_PARCEL(parcel.readStrongBinder, &client);
+    SAFE_PARCEL(parcel.readStrongBinder, &handle);
+    SAFE_PARCEL(parcel.readNullableStrongBinder, &gbp);
+    SAFE_PARCEL(parcel.readInt32, &layerId);
+    SAFE_PARCEL(parcel.readUint32, &transformHint);
+
     // We aren't the original owner of the surface.
-    return new SurfaceControl(new SurfaceComposerClient(
-                                      interface_cast<ISurfaceComposerClient>(client)),
-                              handle.get(), interface_cast<IGraphicBufferProducer>(gbp),
+    *outSurfaceControl =
+            new SurfaceControl(new SurfaceComposerClient(
+                                       interface_cast<ISurfaceComposerClient>(client)),
+                               handle.get(), interface_cast<IGraphicBufferProducer>(gbp), layerId,
                                transformHint);
+
+    return NO_ERROR;
+}
+
+status_t SurfaceControl::readNullableFromParcel(const Parcel& parcel,
+                                                sp<SurfaceControl>* outSurfaceControl) {
+    bool isNotNull;
+    SAFE_PARCEL(parcel.readBool, &isNotNull);
+    if (isNotNull) {
+        SAFE_PARCEL(SurfaceControl::readFromParcel, parcel, outSurfaceControl);
+    }
+
+    return NO_ERROR;
+}
+
+status_t SurfaceControl::writeNullableToParcel(Parcel& parcel,
+                                               const sp<SurfaceControl>& surfaceControl) {
+    auto isNotNull = surfaceControl != nullptr;
+    SAFE_PARCEL(parcel.writeBool, isNotNull);
+    if (isNotNull) {
+        SAFE_PARCEL(surfaceControl->writeToParcel, parcel);
+    }
+
+    return NO_ERROR;
 }
 
 // ----------------------------------------------------------------------------
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index 2320771..35c656a 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -66,8 +66,8 @@
     : public ConsumerBase::FrameAvailableListener, public BufferItemConsumer::BufferFreedListener
 {
 public:
-    BLASTBufferQueue(const sp<SurfaceControl>& surface, int width, int height,
-                     bool enableTripleBuffering = true);
+    BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width,
+                     int height, bool enableTripleBuffering = true);
 
     sp<IGraphicBufferProducer> getIGraphicBufferProducer() const {
         return mProducer;
@@ -81,7 +81,7 @@
             const std::vector<SurfaceControlStats>& stats);
     void setNextTransaction(SurfaceComposerClient::Transaction *t);
 
-    void update(const sp<SurfaceControl>& surface, int width, int height);
+    void update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height);
 
     virtual ~BLASTBufferQueue() = default;
 
@@ -95,6 +95,7 @@
     void processNextBufferLocked(bool useNextTransaction) REQUIRES(mMutex);
     Rect computeCrop(const BufferItem& item);
 
+    std::string mName;
     sp<SurfaceControl> mSurfaceControl;
 
     std::mutex mMutex;
@@ -106,17 +107,18 @@
 
     int32_t mNumFrameAvailable GUARDED_BY(mMutex);
     int32_t mNumAcquired GUARDED_BY(mMutex);
-
     struct PendingReleaseItem {
         BufferItem item;
         sp<Fence> releaseFence;
     };
 
     std::queue<const BufferItem> mSubmitted GUARDED_BY(mMutex);
+    // Keep a reference to the currently presented buffer so we can release it when the next buffer
+    // is ready to be presented.
     PendingReleaseItem mPendingReleaseItem GUARDED_BY(mMutex);
 
-    int mWidth GUARDED_BY(mMutex);
-    int mHeight GUARDED_BY(mMutex);
+    uint32_t mWidth GUARDED_BY(mMutex);
+    uint32_t mHeight GUARDED_BY(mMutex);
 
     uint32_t mTransformHint GUARDED_BY(mMutex);
 
diff --git a/libs/gui/include/gui/ISurfaceComposerClient.h b/libs/gui/include/gui/ISurfaceComposerClient.h
index ec0a8d1..f3fcebe 100644
--- a/libs/gui/include/gui/ISurfaceComposerClient.h
+++ b/libs/gui/include/gui/ISurfaceComposerClient.h
@@ -58,7 +58,8 @@
     virtual status_t createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
                                    uint32_t flags, const sp<IBinder>& parent,
                                    LayerMetadata metadata, sp<IBinder>* handle,
-                                   sp<IGraphicBufferProducer>* gbp, uint32_t* outTransformHint) = 0;
+                                   sp<IGraphicBufferProducer>* gbp, int32_t* outId,
+                                   uint32_t* outTransformHint) = 0;
 
     /*
      * Requires ACCESS_SURFACE_FLINGER permission
@@ -67,7 +68,7 @@
                                              PixelFormat format, uint32_t flags,
                                              const sp<IGraphicBufferProducer>& parent,
                                              LayerMetadata metadata, sp<IBinder>* handle,
-                                             sp<IGraphicBufferProducer>* gbp,
+                                             sp<IGraphicBufferProducer>* gbp, int32_t* outId,
                                              uint32_t* outTransformHint) = 0;
 
     /*
@@ -80,7 +81,8 @@
      */
     virtual status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const = 0;
 
-    virtual status_t mirrorSurface(const sp<IBinder>& mirrorFromHandle, sp<IBinder>* outHandle) = 0;
+    virtual status_t mirrorSurface(const sp<IBinder>& mirrorFromHandle, sp<IBinder>* outHandle,
+                                   int32_t* outId) = 0;
 };
 
 class BnSurfaceComposerClient : public SafeBnInterface<ISurfaceComposerClient> {
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 7a9bb12..65fd9ab 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -125,6 +125,7 @@
         eBackgroundBlurRadiusChanged = 0x80'00000000,
         eProducerDisconnect = 0x100'00000000,
         eFixedTransformHintChanged = 0x200'00000000,
+        eFrameNumberChanged = 0x400'00000000,
     };
 
     layer_state_t()
@@ -142,7 +143,7 @@
             crop_legacy(Rect::INVALID_RECT),
             cornerRadius(0.0f),
             backgroundBlurRadius(0),
-            frameNumber_legacy(0),
+            barrierFrameNumber(0),
             overrideScalingMode(-1),
             transform(0),
             transformToDisplayInverse(false),
@@ -159,7 +160,8 @@
             frameRateSelectionPriority(-1),
             frameRate(0.0f),
             frameRateCompatibility(ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT),
-            fixedTransformHint(ui::Transform::ROT_INVALID) {
+            fixedTransformHint(ui::Transform::ROT_INVALID),
+            frameNumber(0) {
         matrix.dsdx = matrix.dtdy = 1.0f;
         matrix.dsdy = matrix.dtdx = 0.0f;
         hdrMetadata.validTypes = 0;
@@ -178,6 +180,7 @@
         status_t read(const Parcel& input);
     };
     sp<IBinder> surface;
+    int32_t layerId;
     uint64_t what;
     float x;
     float y;
@@ -195,7 +198,7 @@
     uint32_t backgroundBlurRadius;
     sp<IBinder> barrierHandle_legacy;
     sp<IBinder> reparentHandle;
-    uint64_t frameNumber_legacy;
+    uint64_t barrierFrameNumber;
     int32_t overrideScalingMode;
 
     sp<IGraphicBufferProducer> barrierGbp_legacy;
@@ -259,6 +262,10 @@
     // a buffer of a different size. -1 means the transform hint is not set,
     // otherwise the value will be a valid ui::Rotation.
     ui::Transform::RotationFlags fixedTransformHint;
+
+    // Used by BlastBufferQueue to forward the framenumber generated by the
+    // graphics producer.
+    uint64_t frameNumber;
 };
 
 struct ComposerState {
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 519b26e..cc82502 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -345,7 +345,7 @@
 
     protected:
         std::unordered_map<sp<IBinder>, ComposerState, IBinderHash> mComposerStates;
-        SortedVector<DisplayState > mDisplayStates;
+        SortedVector<DisplayState> mDisplayStates;
         std::unordered_map<sp<ITransactionCompletedListener>, CallbackInfo, TCLHash>
                 mListenerCallbacks;
 
@@ -379,10 +379,7 @@
         InputWindowCommands mInputWindowCommands;
         int mStatus = NO_ERROR;
 
-        layer_state_t* getLayerState(const sp<IBinder>& surfaceHandle);
-        layer_state_t* getLayerState(const sp<SurfaceControl>& sc) {
-            return getLayerState(sc->getHandle());
-        }
+        layer_state_t* getLayerState(const sp<SurfaceControl>& sc);
         DisplayState& getDisplayState(const sp<IBinder>& token);
 
         void cacheBuffers();
@@ -496,6 +493,8 @@
 
         // ONLY FOR BLAST ADAPTER
         Transaction& notifyProducerDisconnect(const sp<SurfaceControl>& sc);
+        // Set the framenumber generated by the graphics producer to mimic BufferQueue behaviour.
+        Transaction& setFrameNumber(const sp<SurfaceControl>& sc, uint64_t frameNumber);
 
         // Detaches all child surfaces (and their children recursively)
         // from their SurfaceControl.
diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h
index ac2bbcc..c0dfcdb 100644
--- a/libs/gui/include/gui/SurfaceControl.h
+++ b/libs/gui/include/gui/SurfaceControl.h
@@ -44,8 +44,12 @@
 class SurfaceControl : public RefBase
 {
 public:
-    static sp<SurfaceControl> readFromParcel(const Parcel* parcel);
-    void writeToParcel(Parcel* parcel);
+    static status_t readFromParcel(const Parcel& parcel, sp<SurfaceControl>* outSurfaceControl);
+    status_t writeToParcel(Parcel& parcel);
+
+    static status_t readNullableFromParcel(const Parcel& parcel,
+                                           sp<SurfaceControl>* outSurfaceControl);
+    static status_t writeNullableToParcel(Parcel& parcel, const sp<SurfaceControl>& surfaceControl);
 
     static bool isValid(const sp<SurfaceControl>& surface) {
         return (surface != nullptr) && surface->isValid();
@@ -70,6 +74,7 @@
     sp<Surface> getSurface() const;
     sp<Surface> createSurface() const;
     sp<IBinder> getHandle() const;
+    int32_t getLayerId() const;
 
     sp<IGraphicBufferProducer> getIGraphicBufferProducer() const;
 
@@ -85,7 +90,8 @@
     explicit SurfaceControl(const sp<SurfaceControl>& other);
 
     SurfaceControl(const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle,
-                   const sp<IGraphicBufferProducer>& gbp, uint32_t transformHint = 0);
+                   const sp<IGraphicBufferProducer>& gbp, int32_t layerId,
+                   uint32_t transformHint = 0);
 
 private:
     // can't be copied
@@ -105,6 +111,7 @@
     sp<IGraphicBufferProducer>  mGraphicBufferProducer;
     mutable Mutex               mLock;
     mutable sp<Surface>         mSurfaceData;
+    int32_t mLayerId;
     uint32_t mTransformHint;
 };
 
diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp
index da0d5f8..35fff0a 100644
--- a/libs/gui/tests/BLASTBufferQueue_test.cpp
+++ b/libs/gui/tests/BLASTBufferQueue_test.cpp
@@ -44,7 +44,7 @@
 class BLASTBufferQueueHelper {
 public:
     BLASTBufferQueueHelper(const sp<SurfaceControl>& sc, int width, int height) {
-        mBlastBufferQueueAdapter = new BLASTBufferQueue(sc, width, height);
+        mBlastBufferQueueAdapter = new BLASTBufferQueue("TestBLASTBufferQueue", sc, width, height);
     }
 
     void update(const sp<SurfaceControl>& sc, int width, int height) {
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 0fed08b..afedd48 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -19,26 +19,27 @@
 #define LOG_TAG "RenderEngine"
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
-#include <cmath>
+#include "SkiaGLRenderEngine.h"
 
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 #include <GLES2/gl2.h>
-#include <sync/sync.h>
-#include <ui/GraphicBuffer.h>
-#include <utils/Trace.h>
-#include "../gl/GLExtensions.h"
-#include "SkiaGLRenderEngine.h"
-#include "filters/BlurFilter.h"
-
 #include <GrContextOptions.h>
-#include <gl/GrGLInterface.h>
-
 #include <SkCanvas.h>
+#include <SkColorSpace.h>
 #include <SkImage.h>
 #include <SkImageFilters.h>
 #include <SkShadowUtils.h>
 #include <SkSurface.h>
+#include <gl/GrGLInterface.h>
+#include <sync/sync.h>
+#include <ui/GraphicBuffer.h>
+#include <utils/Trace.h>
+
+#include <cmath>
+
+#include "../gl/GLExtensions.h"
+#include "filters/BlurFilter.h"
 
 extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
 
@@ -130,6 +131,47 @@
     return err;
 }
 
+// Converts an android dataspace to a supported SkColorSpace
+// Supported dataspaces are
+// 1. sRGB
+// 2. Display P3
+// 3. BT2020 PQ
+// 4. BT2020 HLG
+// Unknown primaries are mapped to BT709, and unknown transfer functions
+// are mapped to sRGB.
+static sk_sp<SkColorSpace> toColorSpace(ui::Dataspace dataspace) {
+    skcms_Matrix3x3 gamut;
+    switch (dataspace & HAL_DATASPACE_STANDARD_MASK) {
+        case HAL_DATASPACE_STANDARD_BT709:
+            gamut = SkNamedGamut::kSRGB;
+            break;
+        case HAL_DATASPACE_STANDARD_BT2020:
+            gamut = SkNamedGamut::kRec2020;
+            break;
+        case HAL_DATASPACE_STANDARD_DCI_P3:
+            gamut = SkNamedGamut::kDisplayP3;
+            break;
+        default:
+            ALOGV("Unsupported Gamut: %d, defaulting to sRGB", dataspace);
+            gamut = SkNamedGamut::kSRGB;
+            break;
+    }
+
+    switch (dataspace & HAL_DATASPACE_TRANSFER_MASK) {
+        case HAL_DATASPACE_TRANSFER_LINEAR:
+            return SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, gamut);
+        case HAL_DATASPACE_TRANSFER_SRGB:
+            return SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, gamut);
+        case HAL_DATASPACE_TRANSFER_ST2084:
+            return SkColorSpace::MakeRGB(SkNamedTransferFn::kPQ, gamut);
+        case HAL_DATASPACE_TRANSFER_HLG:
+            return SkColorSpace::MakeRGB(SkNamedTransferFn::kHLG, gamut);
+        default:
+            ALOGV("Unsupported Gamma: %d, defaulting to sRGB transfer", dataspace);
+            return SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, gamut);
+    }
+}
+
 std::unique_ptr<SkiaGLRenderEngine> SkiaGLRenderEngine::create(
         const RenderEngineCreationArgs& args) {
     // initialize EGL for the default display
@@ -257,7 +299,8 @@
         mEGLContext(ctxt),
         mPlaceholderSurface(placeholder),
         mProtectedEGLContext(protectedContext),
-        mProtectedPlaceholderSurface(protectedPlaceholder) {
+        mProtectedPlaceholderSurface(protectedPlaceholder),
+        mUseColorManagement(args.useColorManagement) {
     // Suppress unused field warnings for things we definitely will need/use
     // These EGL fields will all be needed for toggling between protected & unprotected contexts
     // Or we need different RE instances for that
@@ -385,7 +428,10 @@
     if (!surface) {
         surface = SkSurface::MakeFromAHardwareBuffer(mGrContext.get(), buffer->toAHardwareBuffer(),
                                                      GrSurfaceOrigin::kTopLeft_GrSurfaceOrigin,
-                                                     SkColorSpace::MakeSRGB(), nullptr);
+                                                     mUseColorManagement
+                                                             ? toColorSpace(display.outputDataspace)
+                                                             : SkColorSpace::MakeSRGB(),
+                                                     nullptr);
         if (useFramebufferCache && surface) {
             ALOGD("Adding to cache");
             mSurfaceCache.insert({buffer->getId(), surface});
@@ -430,7 +476,11 @@
                 image = SkImage::MakeFromAHardwareBuffer(item.buffer->toAHardwareBuffer(),
                                                          item.usePremultipliedAlpha
                                                                  ? kPremul_SkAlphaType
-                                                                 : kUnpremul_SkAlphaType);
+                                                                 : kUnpremul_SkAlphaType,
+                                                         mUseColorManagement
+                                                                 ? toColorSpace(
+                                                                           layer->sourceDataspace)
+                                                                 : SkColorSpace::MakeSRGB());
                 mImageCache.insert({item.buffer->getId(), image});
             }
 
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h
index 898dc54..ed4ba11 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.h
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.h
@@ -17,16 +17,19 @@
 #ifndef SF_SKIAGLRENDERENGINE_H_
 #define SF_SKIAGLRENDERENGINE_H_
 
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GrDirectContext.h>
+#include <SkSurface.h>
+#include <android-base/thread_annotations.h>
+#include <renderengine/RenderEngine.h>
 #include <sys/types.h>
+
 #include <mutex>
 #include <unordered_map>
 
-#include <android-base/thread_annotations.h>
-#include <renderengine/RenderEngine.h>
-
-#include <GrDirectContext.h>
-#include <SkSurface.h>
-
+#include "EGL/egl.h"
 #include "SkiaRenderEngine.h"
 #include "filters/BlurFilter.h"
 
@@ -81,6 +84,8 @@
     EGLSurface mProtectedPlaceholderSurface;
     BlurFilter* mBlurFilter = nullptr;
 
+    const bool mUseColorManagement;
+
     // Cache of GL images that we'll store per GraphicBuffer ID
     std::unordered_map<uint64_t, sk_sp<SkImage>> mImageCache GUARDED_BY(mRenderingMutex);
     // Mutex guarding rendering operations, so that:
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index 4cbfdff..1cd753b 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -167,7 +167,7 @@
     void updateCloneBufferInfo() override;
     uint64_t mPreviousFrameNumber = 0;
 
-    virtual uint64_t getHeadFrameNumber(nsecs_t expectedPresentTime) const;
+    uint64_t getHeadFrameNumber(nsecs_t expectedPresentTime) const override;
 
     void setTransformHint(ui::Transform::RotationFlags displayTransformHint) override;
 
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index f6c3cef..2033f8e 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -262,12 +262,12 @@
 
 bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& acquireFence,
                                  nsecs_t postTime, nsecs_t desiredPresentTime,
-                                 const client_cache_t& clientCacheId) {
+                                 const client_cache_t& clientCacheId, uint64_t frameNumber) {
     if (mCurrentState.buffer) {
         mReleasePreviousBuffer = true;
     }
 
-    mCurrentState.frameNumber++;
+    mCurrentState.frameNumber = frameNumber;
 
     mCurrentState.buffer = buffer;
     mCurrentState.clientCacheId = clientCacheId;
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 81959ae..c13f5e8 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -70,7 +70,8 @@
     bool setCrop(const Rect& crop) override;
     bool setFrame(const Rect& frame) override;
     bool setBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& acquireFence, nsecs_t postTime,
-                   nsecs_t desiredPresentTime, const client_cache_t& clientCacheId) override;
+                   nsecs_t desiredPresentTime, const client_cache_t& clientCacheId,
+                   uint64_t frameNumber) override;
     bool setAcquireFence(const sp<Fence>& fence) override;
     bool setDataspace(ui::Dataspace dataspace) override;
     bool setHdrMetadata(const HdrMetadata& hdrMetadata) override;
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 78bbcba..07817b5 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -79,17 +79,18 @@
 status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
                                uint32_t flags, const sp<IBinder>& parentHandle,
                                LayerMetadata metadata, sp<IBinder>* handle,
-                               sp<IGraphicBufferProducer>* gbp, uint32_t* outTransformHint) {
+                               sp<IGraphicBufferProducer>* gbp, int32_t* outId,
+                               uint32_t* outTransformHint) {
     // We rely on createLayer to check permissions.
     return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
-                                 parentHandle, nullptr, outTransformHint);
+                                 parentHandle, nullptr, outId, outTransformHint);
 }
 
 status_t Client::createWithSurfaceParent(const String8& name, uint32_t w, uint32_t h,
                                          PixelFormat format, uint32_t flags,
                                          const sp<IGraphicBufferProducer>& parent,
                                          LayerMetadata metadata, sp<IBinder>* handle,
-                                         sp<IGraphicBufferProducer>* gbp,
+                                         sp<IGraphicBufferProducer>* gbp, int32_t* outId,
                                          uint32_t* outTransformHint) {
     if (mFlinger->authenticateSurfaceTexture(parent) == false) {
         ALOGE("failed to authenticate surface texture");
@@ -103,11 +104,12 @@
     }
 
     return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
-                                 nullptr, layer, outTransformHint);
+                                 nullptr, layer, outId, outTransformHint);
 }
 
-status_t Client::mirrorSurface(const sp<IBinder>& mirrorFromHandle, sp<IBinder>* outHandle) {
-    return mFlinger->mirrorLayer(this, mirrorFromHandle, outHandle);
+status_t Client::mirrorSurface(const sp<IBinder>& mirrorFromHandle, sp<IBinder>* outHandle,
+                               int32_t* outId) {
+    return mFlinger->mirrorLayer(this, mirrorFromHandle, outHandle, outId);
 }
 
 status_t Client::clearLayerFrameStats(const sp<IBinder>& handle) const {
diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h
index f64be3a..9462f1a 100644
--- a/services/surfaceflinger/Client.h
+++ b/services/surfaceflinger/Client.h
@@ -50,17 +50,18 @@
     virtual status_t createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
                                    uint32_t flags, const sp<IBinder>& parent,
                                    LayerMetadata metadata, sp<IBinder>* handle,
-                                   sp<IGraphicBufferProducer>* gbp,
+                                   sp<IGraphicBufferProducer>* gbp, int32_t* outId,
                                    uint32_t* outTransformHint = nullptr);
 
     virtual status_t createWithSurfaceParent(const String8& name, uint32_t w, uint32_t h,
                                              PixelFormat format, uint32_t flags,
                                              const sp<IGraphicBufferProducer>& parent,
                                              LayerMetadata metadata, sp<IBinder>* handle,
-                                             sp<IGraphicBufferProducer>* gbp,
+                                             sp<IGraphicBufferProducer>* gbp, int32_t* outId,
                                              uint32_t* outTransformHint = nullptr);
 
-    status_t mirrorSurface(const sp<IBinder>& mirrorFromHandle, sp<IBinder>* handle);
+    status_t mirrorSurface(const sp<IBinder>& mirrorFromHandle, sp<IBinder>* handle,
+                           int32_t* outId);
 
     virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const;
 
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 44edb6e..04dceae 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -148,7 +148,7 @@
     LOG_FATAL_IF(outputState.framebufferSpace.bounds == Rect::INVALID_RECT,
                  "The framebuffer bounds are unknown.");
     const auto scale =
-            getScale(outputState.framebufferSpace.bounds, outputState.displaySpace.bounds);
+            getScale(outputState.displaySpace.bounds, outputState.framebufferSpace.bounds);
     outputState.framebufferSpace.content = outputState.displaySpace.content.scale(scale.x, scale.y);
 
     // Compute layerStackSpace
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 57b399a..1e10365 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -235,16 +235,75 @@
  * Output::setProjection()
  */
 
-TEST_F(OutputTest, setProjectionTriviallyWorks) {
+TEST_F(OutputTest, setProjectionWorks) {
+    const Rect displayRect{0, 0, 1000, 2000};
+    mOutput->editState().displaySpace.bounds = displayRect;
+    mOutput->editState().framebufferSpace.bounds = displayRect;
+
     const ui::Rotation orientation = ui::ROTATION_90;
-    const Rect frame{1, 2, 3, 4};
-    const Rect viewport{5, 6, 7, 8};
+    const Rect frame{50, 60, 100, 100};
+    const Rect viewport{10, 20, 30, 40};
 
     mOutput->setProjection(orientation, viewport, frame);
 
     EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
     EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
     EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
+
+    const auto state = mOutput->getState();
+    EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
+    EXPECT_EQ(viewport, state.layerStackSpace.content);
+    EXPECT_EQ(viewport, state.layerStackSpace.bounds);
+
+    EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
+    EXPECT_EQ(frame, state.orientedDisplaySpace.content);
+    EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.bounds);
+
+    EXPECT_EQ(displayRect, state.displaySpace.bounds);
+    EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.content);
+    EXPECT_EQ(orientation, state.displaySpace.orientation);
+
+    EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
+    EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.content);
+    EXPECT_EQ(orientation, state.framebufferSpace.orientation);
+
+    EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
+}
+
+TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
+    const Rect displayRect{0, 0, 1000, 2000};
+    const Rect framebufferRect{0, 0, 500, 1000};
+    mOutput->editState().displaySpace.bounds = displayRect;
+    mOutput->editState().framebufferSpace.bounds = framebufferRect;
+
+    const ui::Rotation orientation = ui::ROTATION_90;
+    const Rect frame{50, 60, 100, 100};
+    const Rect viewport{10, 20, 30, 40};
+
+    mOutput->setProjection(orientation, viewport, frame);
+
+    EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
+    EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
+    EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
+
+    const auto state = mOutput->getState();
+    EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
+    EXPECT_EQ(viewport, state.layerStackSpace.content);
+    EXPECT_EQ(viewport, state.layerStackSpace.bounds);
+
+    EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
+    EXPECT_EQ(frame, state.orientedDisplaySpace.content);
+    EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.bounds);
+
+    EXPECT_EQ(displayRect, state.displaySpace.bounds);
+    EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.content);
+    EXPECT_EQ(orientation, state.displaySpace.orientation);
+
+    EXPECT_EQ(framebufferRect, state.framebufferSpace.bounds);
+    EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.content);
+    EXPECT_EQ(orientation, state.framebufferSpace.orientation);
+
+    EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
 }
 
 /*
@@ -275,12 +334,15 @@
     EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
     EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.content);
     EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.bounds);
+
     EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
     EXPECT_EQ(Rect(0, 0, 900, 450), state.orientedDisplaySpace.content);
     EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.bounds);
+
     EXPECT_EQ(displayRect, state.displaySpace.bounds);
     EXPECT_EQ(Rect(0, 0, 450, 900), state.displaySpace.content);
     EXPECT_EQ(ui::ROTATION_90, state.displaySpace.orientation);
+
     EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
     EXPECT_EQ(Rect(0, 0, 450, 900), state.framebufferSpace.content);
     EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.orientation);
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 193804c..df2ef80 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -804,10 +804,10 @@
             // to be applied as per normal (no synchronization).
             mCurrentState.barrierLayer_legacy = nullptr;
         } else {
-            auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber_legacy, this);
+            auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.barrierFrameNumber, this);
             if (barrierLayer->addSyncPoint(syncPoint)) {
                 std::stringstream ss;
-                ss << "Adding sync point " << mCurrentState.frameNumber_legacy;
+                ss << "Adding sync point " << mCurrentState.barrierFrameNumber;
                 ATRACE_NAME(ss.str().c_str());
                 mRemoteSyncPoints.push_back(std::move(syncPoint));
             } else {
@@ -848,7 +848,7 @@
             }
 
             if (mRemoteSyncPoints.front()->getFrameNumber() !=
-                mPendingStates[0].frameNumber_legacy) {
+                mPendingStates[0].barrierFrameNumber) {
                 ALOGE("[%s] Unexpected sync point frame number found", getDebugName());
 
                 // Signal our end of the sync point and then dispose of it
@@ -1486,13 +1486,13 @@
     }
 
     mCurrentState.barrierLayer_legacy = barrierLayer;
-    mCurrentState.frameNumber_legacy = frameNumber;
+    mCurrentState.barrierFrameNumber = 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.barrierFrameNumber = 0;
     mCurrentState.modified = false;
 }
 
@@ -2257,7 +2257,7 @@
 
 void Layer::writeToProtoDrawingState(LayerProto* layerInfo, uint32_t traceFlags,
                                      const DisplayDevice* display) {
-    ui::Transform transform = getTransform();
+    const ui::Transform transform = getTransform();
 
     if (traceFlags & SurfaceTracing::TRACE_CRITICAL) {
         for (const auto& pendingState : mPendingStatesSnapshot) {
@@ -2265,7 +2265,7 @@
             if (barrierLayer != nullptr) {
                 BarrierLayerProto* barrierLayerProto = layerInfo->add_barrier_layer();
                 barrierLayerProto->set_id(barrierLayer->sequence);
-                barrierLayerProto->set_frame_number(pendingState.frameNumber_legacy);
+                barrierLayerProto->set_frame_number(pendingState.barrierFrameNumber);
             }
         }
 
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index f903758..02593d5 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -191,7 +191,7 @@
         // If set, defers this state update until the identified Layer
         // receives a frame with the given frameNumber
         wp<Layer> barrierLayer_legacy;
-        uint64_t frameNumber_legacy;
+        uint64_t barrierFrameNumber;
 
         // the transparentRegion hint is a bit special, it's latched only
         // when we receive a buffer -- this is because it's "content"
@@ -416,7 +416,7 @@
     virtual bool setFrame(const Rect& /*frame*/) { return false; };
     virtual bool setBuffer(const sp<GraphicBuffer>& /*buffer*/, const sp<Fence>& /*acquireFence*/,
                            nsecs_t /*postTime*/, nsecs_t /*desiredPresentTime*/,
-                           const client_cache_t& /*clientCacheId*/) {
+                           const client_cache_t& /*clientCacheId*/, uint64_t /* frameNumber */) {
         return false;
     };
     virtual bool setAcquireFence(const sp<Fence>& /*fence*/) { return false; };
@@ -520,6 +520,8 @@
 
     virtual bool shouldPresentNow(nsecs_t /*expectedPresentTime*/) const { return false; }
 
+    virtual uint64_t getHeadFrameNumber(nsecs_t /* expectedPresentTime */) const { return 0; }
+
     /*
      * called after composition.
      * returns true if the layer latched a new buffer this frame.
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index d8477e7..99d061d 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -241,7 +241,8 @@
 void RefreshRateOverlay::changeRefreshRate(const RefreshRate& refreshRate) {
     mCurrentFps = refreshRate.getFps();
     auto buffer = mBufferCache[*mCurrentFps][mFrame];
-    mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, {});
+    mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, {},
+                      mLayer->getHeadFrameNumber(-1 /* expectedPresentTime */));
 
     mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
 }
@@ -252,7 +253,8 @@
     const auto& buffers = mBufferCache[*mCurrentFps];
     mFrame = (mFrame + 1) % buffers.size();
     auto buffer = buffers[mFrame];
-    mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, {});
+    mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, {},
+                      mLayer->getHeadFrameNumber(-1 /* expectedPresentTime */));
 
     mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
 }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b4605aa..152d872 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3686,13 +3686,13 @@
     }
     if (what & layer_state_t::eDeferTransaction_legacy) {
         if (s.barrierHandle_legacy != nullptr) {
-            layer->deferTransactionUntil_legacy(s.barrierHandle_legacy, s.frameNumber_legacy);
+            layer->deferTransactionUntil_legacy(s.barrierHandle_legacy, s.barrierFrameNumber);
         } else if (s.barrierGbp_legacy != nullptr) {
             const sp<IGraphicBufferProducer>& gbp = s.barrierGbp_legacy;
             if (authenticateSurfaceTextureLocked(gbp)) {
                 const auto& otherLayer =
                     (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
-                layer->deferTransactionUntil_legacy(otherLayer, s.frameNumber_legacy);
+                layer->deferTransactionUntil_legacy(otherLayer, s.barrierFrameNumber);
             } else {
                 ALOGE("Attempt to defer transaction to to an"
                         " unrecognized GraphicBufferProducer");
@@ -3823,8 +3823,13 @@
         buffer = s.buffer;
     }
     if (buffer) {
-        if (layer->setBuffer(buffer, s.acquireFence, postTime, desiredPresentTime,
-                             s.cachedBuffer)) {
+        const bool frameNumberChanged = what & layer_state_t::eFrameNumberChanged;
+        const uint64_t frameNumber = frameNumberChanged
+                ? s.frameNumber
+                : layer->getHeadFrameNumber(-1 /* expectedPresentTime */) + 1;
+
+        if (layer->setBuffer(buffer, s.acquireFence, postTime, desiredPresentTime, s.cachedBuffer,
+                             frameNumber)) {
             flags |= eTraversalNeeded;
         }
     }
@@ -3843,7 +3848,7 @@
 }
 
 status_t SurfaceFlinger::mirrorLayer(const sp<Client>& client, const sp<IBinder>& mirrorFromHandle,
-                                     sp<IBinder>* outHandle) {
+                                     sp<IBinder>* outHandle, int32_t* outId) {
     if (!mirrorFromHandle) {
         return NAME_NOT_FOUND;
     }
@@ -3868,6 +3873,7 @@
         mirrorLayer->mClonedChild = mirrorFrom->createClone();
     }
 
+    *outId = mirrorLayer->sequence;
     return addClientLayer(client, *outHandle, nullptr, mirrorLayer, nullptr, nullptr, false,
                           nullptr /* outTransformHint */);
 }
@@ -3877,7 +3883,7 @@
                                      LayerMetadata metadata, sp<IBinder>* handle,
                                      sp<IGraphicBufferProducer>* gbp,
                                      const sp<IBinder>& parentHandle, const sp<Layer>& parentLayer,
-                                     uint32_t* outTransformHint) {
+                                     int32_t* outId, uint32_t* outTransformHint) {
     if (int32_t(w|h) < 0) {
         ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
                 int(w), int(h));
@@ -3943,6 +3949,7 @@
     mInterceptor->saveSurfaceCreation(layer);
 
     setTransactionFlags(eTransactionNeeded);
+    *outId = layer->sequence;
     return result;
 }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 06ea473..9a552d8 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -750,7 +750,7 @@
                          PixelFormat format, uint32_t flags, LayerMetadata metadata,
                          sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp,
                          const sp<IBinder>& parentHandle, const sp<Layer>& parentLayer = nullptr,
-                         uint32_t* outTransformHint = nullptr);
+                         int32_t* outId = nullptr, uint32_t* outTransformHint = nullptr);
 
     status_t createBufferQueueLayer(const sp<Client>& client, std::string name, uint32_t w,
                                     uint32_t h, uint32_t flags, LayerMetadata metadata,
@@ -770,7 +770,7 @@
                                   sp<IBinder>* outHandle, sp<Layer>* outLayer);
 
     status_t mirrorLayer(const sp<Client>& client, const sp<IBinder>& mirrorFromHandle,
-                         sp<IBinder>* outHandle);
+                         sp<IBinder>* outHandle, int32_t* outId);
 
     std::string getUniqueLayerName(const char* name);
 
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 016951a..4407f4c 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -148,7 +148,7 @@
     if (layer->mCurrentState.barrierLayer_legacy != nullptr) {
         addDeferTransactionLocked(transaction, layerId,
                                   layer->mCurrentState.barrierLayer_legacy.promote(),
-                                  layer->mCurrentState.frameNumber_legacy);
+                                  layer->mCurrentState.barrierFrameNumber);
     }
     addOverrideScalingModeLocked(transaction, layerId, layer->getEffectiveScalingMode());
     addFlagsLocked(transaction, layerId, layer->mCurrentState.flags,
@@ -483,7 +483,7 @@
                 ALOGE("Attempt to defer transaction to to an unrecognized GraphicBufferProducer");
             }
         }
-        addDeferTransactionLocked(transaction, layerId, otherLayer, state.frameNumber_legacy);
+        addDeferTransactionLocked(transaction, layerId, otherLayer, state.barrierFrameNumber);
     }
     if (state.what & layer_state_t::eOverrideScalingModeChanged) {
         addOverrideScalingModeLocked(transaction, layerId, state.overrideScalingMode);
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index b750d6b..5864d02 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -1448,7 +1448,7 @@
         });
     }
 
-    ui::Size SwapWH(const ui::Size size) const { return ui::Size(size.height, size.width); }
+    ui::Size swapWH(const ui::Size size) const { return ui::Size(size.height, size.width); }
 
     void setProjectionForRotation0() {
         // A logical rotation of 0 uses the SurfaceFlinger display size
@@ -1459,8 +1459,8 @@
     void setProjectionForRotation90() {
         // A logical rotation of 90 uses the SurfaceFlinger display size with
         // the width/height swapped.
-        mDisplayDevice->setProjection(ui::ROTATION_90, Rect(SwapWH(mFlingerDisplaySize)),
-                                      Rect(SwapWH(mFlingerDisplaySize)));
+        mDisplayDevice->setProjection(ui::ROTATION_90, Rect(swapWH(mFlingerDisplaySize)),
+                                      Rect(swapWH(mFlingerDisplaySize)));
     }
 
     void setProjectionForRotation180() {
@@ -1472,8 +1472,8 @@
     void setProjectionForRotation270() {
         // A logical rotation of 270 uses the SurfaceFlinger display size with
         // the width/height swapped.
-        mDisplayDevice->setProjection(ui::ROTATION_270, Rect(SwapWH(mFlingerDisplaySize)),
-                                      Rect(SwapWH(mFlingerDisplaySize)));
+        mDisplayDevice->setProjection(ui::ROTATION_270, Rect(swapWH(mFlingerDisplaySize)),
+                                      Rect(swapWH(mFlingerDisplaySize)));
     }
 
     void expectStateForHardwareTransform0() {
@@ -1497,9 +1497,9 @@
         EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.displaySpace.content);
         // For 90, the orientedDisplaySpaceRect and layerStackSpaceRect have the hardware display
         // size width and height swapped
-        EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)),
+        EXPECT_EQ(Rect(swapWH(mHardwareDisplaySize)),
                   compositionState.orientedDisplaySpace.content);
-        EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.layerStackSpace.content);
+        EXPECT_EQ(Rect(swapWH(mHardwareDisplaySize)), compositionState.layerStackSpace.content);
         EXPECT_EQ(false, compositionState.needsFiltering);
     }
 
@@ -1523,9 +1523,9 @@
         EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.displaySpace.content);
         // For 270, the orientedDisplaySpaceRect and layerStackSpaceRect have the hardware display
         // size width and height swapped
-        EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)),
+        EXPECT_EQ(Rect(swapWH(mHardwareDisplaySize)),
                   compositionState.orientedDisplaySpace.content);
-        EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.layerStackSpace.content);
+        EXPECT_EQ(Rect(swapWH(mHardwareDisplaySize)), compositionState.layerStackSpace.content);
         EXPECT_EQ(false, compositionState.needsFiltering);
     }