Loading services/surfaceflinger/BufferLayer.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -545,6 +545,12 @@ void BufferLayer::notifyAvailableFrames() { if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled && presentTimeIsCurrent) { point->setFrameAvailable(); sp<Layer> requestedSyncLayer = point->getRequestedSyncLayer(); if (requestedSyncLayer) { // Need to update the transaction flag to ensure the layer's pending transaction // gets applied. requestedSyncLayer->setTransactionFlags(eTransactionNeeded); } } } } Loading services/surfaceflinger/Layer.cpp +17 −5 Original line number Diff line number Diff line Loading @@ -144,6 +144,20 @@ Layer::~Layer() { */ void Layer::onLayerDisplayed(const sp<Fence>& /*releaseFence*/) {} void Layer::removeRemoteSyncPoints() { for (auto& point : mRemoteSyncPoints) { point->setTransactionApplied(); } mRemoteSyncPoints.clear(); { Mutex::Autolock pendingStateLock(mPendingStateMutex); for (State pendingState : mPendingStates) { pendingState.barrierLayer_legacy = nullptr; } } } void Layer::onRemovedFromCurrentState() { mRemovedFromCurrentState = true; Loading @@ -162,10 +176,7 @@ void Layer::onRemovedFromCurrentState() { // never finish applying transactions. We signal the sync point // now so that another layer will not become indefinitely // blocked. for (auto& point: mRemoteSyncPoints) { point->setTransactionApplied(); } mRemoteSyncPoints.clear(); removeRemoteSyncPoints(); { Mutex::Autolock syncLock(mLocalSyncPointMutex); Loading Loading @@ -667,7 +678,7 @@ void Layer::pushPendingState() { // to be applied as per normal (no synchronization). mCurrentState.barrierLayer_legacy = nullptr; } else { auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber_legacy); auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber_legacy, this); if (barrierLayer->addSyncPoint(syncPoint)) { mRemoteSyncPoints.push_back(std::move(syncPoint)); } else { Loading Loading @@ -1510,6 +1521,7 @@ bool Layer::detachChildren() { if (client != nullptr && parentClient != client) { child->mLayerDetached = true; child->detachChildren(); child->removeRemoteSyncPoints(); } } Loading services/surfaceflinger/Layer.h +10 −2 Original line number Diff line number Diff line Loading @@ -733,8 +733,11 @@ protected: class SyncPoint { public: explicit SyncPoint(uint64_t frameNumber) : mFrameNumber(frameNumber), mFrameIsAvailable(false), mTransactionIsApplied(false) {} explicit SyncPoint(uint64_t frameNumber, wp<Layer> requestedSyncLayer) : mFrameNumber(frameNumber), mFrameIsAvailable(false), mTransactionIsApplied(false), mRequestedSyncLayer(requestedSyncLayer) {} uint64_t getFrameNumber() const { return mFrameNumber; } Loading @@ -746,10 +749,13 @@ protected: void setTransactionApplied() { mTransactionIsApplied = true; } sp<Layer> getRequestedSyncLayer() { return mRequestedSyncLayer.promote(); } private: const uint64_t mFrameNumber; std::atomic<bool> mFrameIsAvailable; std::atomic<bool> mTransactionIsApplied; wp<Layer> mRequestedSyncLayer; }; // SyncPoints which will be signaled when the correct frame is at the head Loading Loading @@ -928,6 +934,8 @@ private: void setZOrderRelativeOf(const wp<Layer>& relativeOf); bool mGetHandleCalled = false; void removeRemoteSyncPoints(); }; } // namespace android Loading services/surfaceflinger/tests/Transaction_test.cpp +42 −0 Original line number Diff line number Diff line Loading @@ -4725,6 +4725,48 @@ TEST_F(ChildLayerTest, DetachChildrenThenAttach) { mCapture->expectColor(Rect(20, 20, 52, 52), Color::RED); } } TEST_F(ChildLayerTest, DetachChildrenWithDeferredTransaction) { sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient; sp<SurfaceControl> childNewClient = newComposerClient->createSurface(String8("New Child Test Surface"), 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get()); ASSERT_TRUE(childNewClient != nullptr); ASSERT_TRUE(childNewClient->isValid()); fillSurfaceRGBA8(childNewClient, 200, 200, 200); Transaction() .hide(mChild) .show(childNewClient) .setPosition(childNewClient, 10, 10) .setPosition(mFGSurfaceControl, 64, 64) .apply(); { mCapture = screenshot(); Rect rect = Rect(74, 74, 84, 84); mCapture->expectBorder(rect, Color{195, 63, 63, 255}); mCapture->expectColor(rect, Color{200, 200, 200, 255}); } Transaction() .deferTransactionUntil_legacy(childNewClient, mFGSurfaceControl->getHandle(), mFGSurfaceControl->getSurface()->getNextFrameNumber()) .apply(); Transaction().detachChildren(mFGSurfaceControl).apply(); ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(mFGSurfaceControl, Color::RED, 32, 32)); // BufferLayer can still dequeue buffers even though there's a detached layer with a // deferred transaction. { SCOPED_TRACE("new buffer"); mCapture = screenshot(); Rect rect = Rect(74, 74, 84, 84); mCapture->expectBorder(rect, Color::RED); mCapture->expectColor(rect, Color{200, 200, 200, 255}); } } TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) { asTransaction([&](Transaction& t) { Loading Loading
services/surfaceflinger/BufferLayer.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -545,6 +545,12 @@ void BufferLayer::notifyAvailableFrames() { if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled && presentTimeIsCurrent) { point->setFrameAvailable(); sp<Layer> requestedSyncLayer = point->getRequestedSyncLayer(); if (requestedSyncLayer) { // Need to update the transaction flag to ensure the layer's pending transaction // gets applied. requestedSyncLayer->setTransactionFlags(eTransactionNeeded); } } } } Loading
services/surfaceflinger/Layer.cpp +17 −5 Original line number Diff line number Diff line Loading @@ -144,6 +144,20 @@ Layer::~Layer() { */ void Layer::onLayerDisplayed(const sp<Fence>& /*releaseFence*/) {} void Layer::removeRemoteSyncPoints() { for (auto& point : mRemoteSyncPoints) { point->setTransactionApplied(); } mRemoteSyncPoints.clear(); { Mutex::Autolock pendingStateLock(mPendingStateMutex); for (State pendingState : mPendingStates) { pendingState.barrierLayer_legacy = nullptr; } } } void Layer::onRemovedFromCurrentState() { mRemovedFromCurrentState = true; Loading @@ -162,10 +176,7 @@ void Layer::onRemovedFromCurrentState() { // never finish applying transactions. We signal the sync point // now so that another layer will not become indefinitely // blocked. for (auto& point: mRemoteSyncPoints) { point->setTransactionApplied(); } mRemoteSyncPoints.clear(); removeRemoteSyncPoints(); { Mutex::Autolock syncLock(mLocalSyncPointMutex); Loading Loading @@ -667,7 +678,7 @@ void Layer::pushPendingState() { // to be applied as per normal (no synchronization). mCurrentState.barrierLayer_legacy = nullptr; } else { auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber_legacy); auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber_legacy, this); if (barrierLayer->addSyncPoint(syncPoint)) { mRemoteSyncPoints.push_back(std::move(syncPoint)); } else { Loading Loading @@ -1510,6 +1521,7 @@ bool Layer::detachChildren() { if (client != nullptr && parentClient != client) { child->mLayerDetached = true; child->detachChildren(); child->removeRemoteSyncPoints(); } } Loading
services/surfaceflinger/Layer.h +10 −2 Original line number Diff line number Diff line Loading @@ -733,8 +733,11 @@ protected: class SyncPoint { public: explicit SyncPoint(uint64_t frameNumber) : mFrameNumber(frameNumber), mFrameIsAvailable(false), mTransactionIsApplied(false) {} explicit SyncPoint(uint64_t frameNumber, wp<Layer> requestedSyncLayer) : mFrameNumber(frameNumber), mFrameIsAvailable(false), mTransactionIsApplied(false), mRequestedSyncLayer(requestedSyncLayer) {} uint64_t getFrameNumber() const { return mFrameNumber; } Loading @@ -746,10 +749,13 @@ protected: void setTransactionApplied() { mTransactionIsApplied = true; } sp<Layer> getRequestedSyncLayer() { return mRequestedSyncLayer.promote(); } private: const uint64_t mFrameNumber; std::atomic<bool> mFrameIsAvailable; std::atomic<bool> mTransactionIsApplied; wp<Layer> mRequestedSyncLayer; }; // SyncPoints which will be signaled when the correct frame is at the head Loading Loading @@ -928,6 +934,8 @@ private: void setZOrderRelativeOf(const wp<Layer>& relativeOf); bool mGetHandleCalled = false; void removeRemoteSyncPoints(); }; } // namespace android Loading
services/surfaceflinger/tests/Transaction_test.cpp +42 −0 Original line number Diff line number Diff line Loading @@ -4725,6 +4725,48 @@ TEST_F(ChildLayerTest, DetachChildrenThenAttach) { mCapture->expectColor(Rect(20, 20, 52, 52), Color::RED); } } TEST_F(ChildLayerTest, DetachChildrenWithDeferredTransaction) { sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient; sp<SurfaceControl> childNewClient = newComposerClient->createSurface(String8("New Child Test Surface"), 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get()); ASSERT_TRUE(childNewClient != nullptr); ASSERT_TRUE(childNewClient->isValid()); fillSurfaceRGBA8(childNewClient, 200, 200, 200); Transaction() .hide(mChild) .show(childNewClient) .setPosition(childNewClient, 10, 10) .setPosition(mFGSurfaceControl, 64, 64) .apply(); { mCapture = screenshot(); Rect rect = Rect(74, 74, 84, 84); mCapture->expectBorder(rect, Color{195, 63, 63, 255}); mCapture->expectColor(rect, Color{200, 200, 200, 255}); } Transaction() .deferTransactionUntil_legacy(childNewClient, mFGSurfaceControl->getHandle(), mFGSurfaceControl->getSurface()->getNextFrameNumber()) .apply(); Transaction().detachChildren(mFGSurfaceControl).apply(); ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(mFGSurfaceControl, Color::RED, 32, 32)); // BufferLayer can still dequeue buffers even though there's a detached layer with a // deferred transaction. { SCOPED_TRACE("new buffer"); mCapture = screenshot(); Rect rect = Rect(74, 74, 84, 84); mCapture->expectBorder(rect, Color::RED); mCapture->expectColor(rect, Color{200, 200, 200, 255}); } } TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) { asTransaction([&](Transaction& t) { Loading