Loading services/surfaceflinger/Layer.cpp +15 −16 Original line number Diff line number Diff line Loading @@ -1309,16 +1309,16 @@ void Layer::pushPendingState() { mPendingStates.push_back(mCurrentState); } void Layer::popPendingState() { auto oldFlags = mCurrentState.flags; mCurrentState = mPendingStates[0]; mCurrentState.flags = (oldFlags & ~mCurrentState.mask) | (mCurrentState.flags & mCurrentState.mask); void Layer::popPendingState(State* stateToCommit) { auto oldFlags = stateToCommit->flags; *stateToCommit = mPendingStates[0]; stateToCommit->flags = (oldFlags & ~stateToCommit->mask) | (stateToCommit->flags & stateToCommit->mask); mPendingStates.removeAt(0); } bool Layer::applyPendingStates() { bool Layer::applyPendingStates(State* stateToCommit) { bool stateUpdateAvailable = false; while (!mPendingStates.empty()) { if (mPendingStates[0].handle != nullptr) { Loading @@ -1327,7 +1327,7 @@ bool Layer::applyPendingStates() { // will be visually wrong, but it should keep us from getting // into too much trouble. ALOGE("[%s] No local sync point found", mName.string()); popPendingState(); popPendingState(stateToCommit); stateUpdateAvailable = true; continue; } Loading @@ -1345,7 +1345,7 @@ bool Layer::applyPendingStates() { if (mRemoteSyncPoints.front()->frameIsAvailable()) { // Apply the state update popPendingState(); popPendingState(stateToCommit); stateUpdateAvailable = true; // Signal our end of the sync point and then dispose of it Loading @@ -1355,7 +1355,7 @@ bool Layer::applyPendingStates() { break; } } else { popPendingState(); popPendingState(stateToCommit); stateUpdateAvailable = true; } } Loading Loading @@ -1385,12 +1385,12 @@ uint32_t Layer::doTransaction(uint32_t flags) { ATRACE_CALL(); pushPendingState(); if (!applyPendingStates()) { Layer::State c = getCurrentState(); if (!applyPendingStates(&c)) { return 0; } const Layer::State& s(getDrawingState()); const Layer::State& c(getCurrentState()); const bool sizeChanged = (c.requested.w != s.requested.w) || (c.requested.h != s.requested.h); Loading Loading @@ -1454,8 +1454,7 @@ uint32_t Layer::doTransaction(uint32_t flags) { // this is used by Layer, which special cases resizes. if (flags & eDontUpdateGeometryState) { } else { Layer::State& editCurrentState(getCurrentState()); editCurrentState.active = c.requested; c.active = c.requested; } if (s.active != c.active) { Loading @@ -1475,12 +1474,12 @@ uint32_t Layer::doTransaction(uint32_t flags) { } // Commit the transaction commitTransaction(); commitTransaction(c); return flags; } void Layer::commitTransaction() { mDrawingState = mCurrentState; void Layer::commitTransaction(const State& stateToCommit) { mDrawingState = stateToCommit; } uint32_t Layer::getTransactionFlags(uint32_t flags) { Loading services/surfaceflinger/Layer.h +3 −3 Original line number Diff line number Diff line Loading @@ -431,7 +431,7 @@ private: virtual void onFrameReplaced(const BufferItem& item) override; virtual void onSidebandStreamChanged() override; void commitTransaction(); void commitTransaction(const State& stateToCommit); // needsLinearFiltering - true if this surface's state requires filtering bool needsFiltering(const sp<const DisplayDevice>& hw) const; Loading Loading @@ -500,8 +500,8 @@ private: bool addSyncPoint(const std::shared_ptr<SyncPoint>& point); void pushPendingState(); void popPendingState(); bool applyPendingStates(); void popPendingState(State* stateToCommit); bool applyPendingStates(State* stateToCommit); public: void notifyAvailableFrames(); private: Loading services/surfaceflinger/tests/Transaction_test.cpp +57 −0 Original line number Diff line number Diff line Loading @@ -459,4 +459,61 @@ TEST_F(LayerUpdateTest, LayerSetMatrixWorks) { } } TEST_F(LayerUpdateTest, DeferredTransactionTest) { sp<ScreenCapture> sc; { SCOPED_TRACE("before anything"); ScreenCapture::captureScreen(&sc); sc->checkPixel( 32, 32, 63, 63, 195); sc->checkPixel( 96, 96, 195, 63, 63); sc->checkPixel(160, 160, 63, 63, 195); } // set up two deferred transactions on different frames SurfaceComposerClient::openGlobalTransaction(); ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setAlpha(0.75)); mFGSurfaceControl->deferTransactionUntil(mSyncSurfaceControl->getHandle(), mSyncSurfaceControl->getSurface()->getNextFrameNumber()); SurfaceComposerClient::closeGlobalTransaction(true); SurfaceComposerClient::openGlobalTransaction(); ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(128,128)); mFGSurfaceControl->deferTransactionUntil(mSyncSurfaceControl->getHandle(), mSyncSurfaceControl->getSurface()->getNextFrameNumber() + 1); SurfaceComposerClient::closeGlobalTransaction(true); { SCOPED_TRACE("before any trigger"); ScreenCapture::captureScreen(&sc); sc->checkPixel( 32, 32, 63, 63, 195); sc->checkPixel( 96, 96, 195, 63, 63); sc->checkPixel(160, 160, 63, 63, 195); } // should trigger the first deferred transaction, but not the second one fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); { SCOPED_TRACE("after first trigger"); ScreenCapture::captureScreen(&sc); sc->checkPixel( 32, 32, 63, 63, 195); sc->checkPixel( 96, 96, 162, 63, 96); sc->checkPixel(160, 160, 63, 63, 195); } // should show up immediately since it's not deferred SurfaceComposerClient::openGlobalTransaction(); ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setAlpha(1.0)); SurfaceComposerClient::closeGlobalTransaction(true); // trigger the second deferred transaction fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); { SCOPED_TRACE("after second trigger"); ScreenCapture::captureScreen(&sc); sc->checkPixel( 32, 32, 63, 63, 195); sc->checkPixel( 96, 96, 63, 63, 195); sc->checkPixel(160, 160, 195, 63, 63); } } } Loading
services/surfaceflinger/Layer.cpp +15 −16 Original line number Diff line number Diff line Loading @@ -1309,16 +1309,16 @@ void Layer::pushPendingState() { mPendingStates.push_back(mCurrentState); } void Layer::popPendingState() { auto oldFlags = mCurrentState.flags; mCurrentState = mPendingStates[0]; mCurrentState.flags = (oldFlags & ~mCurrentState.mask) | (mCurrentState.flags & mCurrentState.mask); void Layer::popPendingState(State* stateToCommit) { auto oldFlags = stateToCommit->flags; *stateToCommit = mPendingStates[0]; stateToCommit->flags = (oldFlags & ~stateToCommit->mask) | (stateToCommit->flags & stateToCommit->mask); mPendingStates.removeAt(0); } bool Layer::applyPendingStates() { bool Layer::applyPendingStates(State* stateToCommit) { bool stateUpdateAvailable = false; while (!mPendingStates.empty()) { if (mPendingStates[0].handle != nullptr) { Loading @@ -1327,7 +1327,7 @@ bool Layer::applyPendingStates() { // will be visually wrong, but it should keep us from getting // into too much trouble. ALOGE("[%s] No local sync point found", mName.string()); popPendingState(); popPendingState(stateToCommit); stateUpdateAvailable = true; continue; } Loading @@ -1345,7 +1345,7 @@ bool Layer::applyPendingStates() { if (mRemoteSyncPoints.front()->frameIsAvailable()) { // Apply the state update popPendingState(); popPendingState(stateToCommit); stateUpdateAvailable = true; // Signal our end of the sync point and then dispose of it Loading @@ -1355,7 +1355,7 @@ bool Layer::applyPendingStates() { break; } } else { popPendingState(); popPendingState(stateToCommit); stateUpdateAvailable = true; } } Loading Loading @@ -1385,12 +1385,12 @@ uint32_t Layer::doTransaction(uint32_t flags) { ATRACE_CALL(); pushPendingState(); if (!applyPendingStates()) { Layer::State c = getCurrentState(); if (!applyPendingStates(&c)) { return 0; } const Layer::State& s(getDrawingState()); const Layer::State& c(getCurrentState()); const bool sizeChanged = (c.requested.w != s.requested.w) || (c.requested.h != s.requested.h); Loading Loading @@ -1454,8 +1454,7 @@ uint32_t Layer::doTransaction(uint32_t flags) { // this is used by Layer, which special cases resizes. if (flags & eDontUpdateGeometryState) { } else { Layer::State& editCurrentState(getCurrentState()); editCurrentState.active = c.requested; c.active = c.requested; } if (s.active != c.active) { Loading @@ -1475,12 +1474,12 @@ uint32_t Layer::doTransaction(uint32_t flags) { } // Commit the transaction commitTransaction(); commitTransaction(c); return flags; } void Layer::commitTransaction() { mDrawingState = mCurrentState; void Layer::commitTransaction(const State& stateToCommit) { mDrawingState = stateToCommit; } uint32_t Layer::getTransactionFlags(uint32_t flags) { Loading
services/surfaceflinger/Layer.h +3 −3 Original line number Diff line number Diff line Loading @@ -431,7 +431,7 @@ private: virtual void onFrameReplaced(const BufferItem& item) override; virtual void onSidebandStreamChanged() override; void commitTransaction(); void commitTransaction(const State& stateToCommit); // needsLinearFiltering - true if this surface's state requires filtering bool needsFiltering(const sp<const DisplayDevice>& hw) const; Loading Loading @@ -500,8 +500,8 @@ private: bool addSyncPoint(const std::shared_ptr<SyncPoint>& point); void pushPendingState(); void popPendingState(); bool applyPendingStates(); void popPendingState(State* stateToCommit); bool applyPendingStates(State* stateToCommit); public: void notifyAvailableFrames(); private: Loading
services/surfaceflinger/tests/Transaction_test.cpp +57 −0 Original line number Diff line number Diff line Loading @@ -459,4 +459,61 @@ TEST_F(LayerUpdateTest, LayerSetMatrixWorks) { } } TEST_F(LayerUpdateTest, DeferredTransactionTest) { sp<ScreenCapture> sc; { SCOPED_TRACE("before anything"); ScreenCapture::captureScreen(&sc); sc->checkPixel( 32, 32, 63, 63, 195); sc->checkPixel( 96, 96, 195, 63, 63); sc->checkPixel(160, 160, 63, 63, 195); } // set up two deferred transactions on different frames SurfaceComposerClient::openGlobalTransaction(); ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setAlpha(0.75)); mFGSurfaceControl->deferTransactionUntil(mSyncSurfaceControl->getHandle(), mSyncSurfaceControl->getSurface()->getNextFrameNumber()); SurfaceComposerClient::closeGlobalTransaction(true); SurfaceComposerClient::openGlobalTransaction(); ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(128,128)); mFGSurfaceControl->deferTransactionUntil(mSyncSurfaceControl->getHandle(), mSyncSurfaceControl->getSurface()->getNextFrameNumber() + 1); SurfaceComposerClient::closeGlobalTransaction(true); { SCOPED_TRACE("before any trigger"); ScreenCapture::captureScreen(&sc); sc->checkPixel( 32, 32, 63, 63, 195); sc->checkPixel( 96, 96, 195, 63, 63); sc->checkPixel(160, 160, 63, 63, 195); } // should trigger the first deferred transaction, but not the second one fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); { SCOPED_TRACE("after first trigger"); ScreenCapture::captureScreen(&sc); sc->checkPixel( 32, 32, 63, 63, 195); sc->checkPixel( 96, 96, 162, 63, 96); sc->checkPixel(160, 160, 63, 63, 195); } // should show up immediately since it's not deferred SurfaceComposerClient::openGlobalTransaction(); ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setAlpha(1.0)); SurfaceComposerClient::closeGlobalTransaction(true); // trigger the second deferred transaction fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); { SCOPED_TRACE("after second trigger"); ScreenCapture::captureScreen(&sc); sc->checkPixel( 32, 32, 63, 63, 195); sc->checkPixel( 96, 96, 63, 63, 195); sc->checkPixel(160, 160, 195, 63, 63); } } }