Loading libs/gui/ISurfaceComposer.cpp +6 −6 Original line number Diff line number Diff line Loading @@ -73,11 +73,9 @@ public: return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder()); } virtual void setTransactionState( const Vector<ComposerState>& state, const Vector<DisplayState>& displays, uint32_t flags) { virtual void setTransactionState(const Vector<ComposerState>& state, const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken) { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); Loading @@ -92,6 +90,7 @@ public: } data.writeUint32(flags); data.writeStrongBinder(applyToken); remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply); } Loading Loading @@ -750,7 +749,8 @@ status_t BnSurfaceComposer::onTransact( } uint32_t stateFlags = data.readUint32(); setTransactionState(state, displays, stateFlags); sp<IBinder> applyToken = data.readStrongBinder(); setTransactionState(state, displays, stateFlags, applyToken); return NO_ERROR; } case BOOT_FINISHED: { Loading libs/gui/SurfaceComposerClient.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -264,7 +264,9 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { mAnimation = false; mEarlyWakeup = false; sf->setTransactionState(composerStates, displayStates, flags); sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance()); sf->setTransactionState(composerStates, displayStates, flags, applyToken); mStatus = NO_ERROR; return NO_ERROR; } Loading libs/gui/include/gui/ISurfaceComposer.h +2 −1 Original line number Diff line number Diff line Loading @@ -124,7 +124,8 @@ public: /* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */ virtual void setTransactionState(const Vector<ComposerState>& state, const Vector<DisplayState>& displays, uint32_t flags) = 0; const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken) = 0; /* signal that we're done booting. * Requires ACCESS_SURFACE_FLINGER permission Loading libs/gui/tests/Surface_test.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -558,8 +558,8 @@ public: void destroyDisplay(const sp<IBinder>& /*display */) override {} sp<IBinder> getBuiltInDisplay(int32_t /*id*/) override { return nullptr; } void setTransactionState(const Vector<ComposerState>& /*state*/, const Vector<DisplayState>& /*displays*/, uint32_t /*flags*/) override {} const Vector<DisplayState>& /*displays*/, uint32_t /*flags*/, const sp<IBinder>& /*applyToken*/) override {} void bootFinished() override {} bool authenticateSurfaceTexture( const sp<IGraphicBufferProducer>& /*surface*/) const override { Loading services/surfaceflinger/SurfaceFlinger.cpp +66 −9 Original line number Diff line number Diff line Loading @@ -1568,11 +1568,23 @@ void SurfaceFlinger::onMessageReceived(int32_t what) { bool SurfaceFlinger::handleMessageTransaction() { uint32_t transactionFlags = peekTransactionFlags(); // Apply any ready transactions in the queues if there are still transactions that have not been // applied, wake up during the next vsync period and check again bool transactionNeeded = false; if (!flushTransactionQueues()) { transactionNeeded = true; } if (transactionFlags) { handleTransaction(transactionFlags); return true; } return false; if (transactionNeeded) { setTransactionFlags(eTransactionNeeded); } return transactionFlags; } void SurfaceFlinger::handleMessageRefresh() { Loading Loading @@ -3314,6 +3326,26 @@ uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags, return old; } bool SurfaceFlinger::flushTransactionQueues() { Mutex::Autolock _l(mStateLock); auto it = mTransactionQueues.begin(); while (it != mTransactionQueues.end()) { auto& [applyToken, transactionQueue] = *it; while (!transactionQueue.empty()) { const auto& [states, displays, flags] = transactionQueue.front(); if (composerStateContainsUnsignaledFences(states)) { break; } applyTransactionState(states, displays, flags); transactionQueue.pop(); } it = (transactionQueue.empty()) ? mTransactionQueues.erase(it) : std::next(it, 1); } return mTransactionQueues.empty(); } bool SurfaceFlinger::containsAnyInvalidClientState(const Vector<ComposerState>& states) { for (const ComposerState& state : states) { // Here we need to check that the interface we're given is indeed Loading @@ -3336,19 +3368,44 @@ bool SurfaceFlinger::containsAnyInvalidClientState(const Vector<ComposerState>& return false; } void SurfaceFlinger::setTransactionState( const Vector<ComposerState>& states, const Vector<DisplayState>& displays, uint32_t flags) { bool SurfaceFlinger::composerStateContainsUnsignaledFences(const Vector<ComposerState>& states) { for (const ComposerState& state : states) { const layer_state_t& s = state.state; if (!(s.what & layer_state_t::eAcquireFenceChanged)) { continue; } if (s.acquireFence && s.acquireFence->getStatus() == Fence::Status::Unsignaled) { return true; } } return false; } void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& states, const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken) { ATRACE_CALL(); Mutex::Autolock _l(mStateLock); uint32_t transactionFlags = 0; if (containsAnyInvalidClientState(states)) { return; } // If its TransactionQueue already has a pending TransactionState or if it is pending if (mTransactionQueues.find(applyToken) != mTransactionQueues.end() || composerStateContainsUnsignaledFences(states)) { mTransactionQueues[applyToken].emplace(states, displays, flags); setTransactionFlags(eTransactionNeeded); return; } applyTransactionState(states, displays, flags); } void SurfaceFlinger::applyTransactionState(const Vector<ComposerState>& states, const Vector<DisplayState>& displays, uint32_t flags) { uint32_t transactionFlags = 0; if (flags & eAnimation) { // For window updates that are part of an animation we must wait for // previous animation "frames" to be handled. Loading Loading @@ -3938,7 +3995,7 @@ void SurfaceFlinger::onInitializeDisplays() { d.width = 0; d.height = 0; displays.add(d); setTransactionState(state, displays, 0); setTransactionState(state, displays, 0, nullptr); const auto display = getDisplayDevice(displayToken); if (!display) return; Loading Loading
libs/gui/ISurfaceComposer.cpp +6 −6 Original line number Diff line number Diff line Loading @@ -73,11 +73,9 @@ public: return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder()); } virtual void setTransactionState( const Vector<ComposerState>& state, const Vector<DisplayState>& displays, uint32_t flags) { virtual void setTransactionState(const Vector<ComposerState>& state, const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken) { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); Loading @@ -92,6 +90,7 @@ public: } data.writeUint32(flags); data.writeStrongBinder(applyToken); remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply); } Loading Loading @@ -750,7 +749,8 @@ status_t BnSurfaceComposer::onTransact( } uint32_t stateFlags = data.readUint32(); setTransactionState(state, displays, stateFlags); sp<IBinder> applyToken = data.readStrongBinder(); setTransactionState(state, displays, stateFlags, applyToken); return NO_ERROR; } case BOOT_FINISHED: { Loading
libs/gui/SurfaceComposerClient.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -264,7 +264,9 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { mAnimation = false; mEarlyWakeup = false; sf->setTransactionState(composerStates, displayStates, flags); sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance()); sf->setTransactionState(composerStates, displayStates, flags, applyToken); mStatus = NO_ERROR; return NO_ERROR; } Loading
libs/gui/include/gui/ISurfaceComposer.h +2 −1 Original line number Diff line number Diff line Loading @@ -124,7 +124,8 @@ public: /* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */ virtual void setTransactionState(const Vector<ComposerState>& state, const Vector<DisplayState>& displays, uint32_t flags) = 0; const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken) = 0; /* signal that we're done booting. * Requires ACCESS_SURFACE_FLINGER permission Loading
libs/gui/tests/Surface_test.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -558,8 +558,8 @@ public: void destroyDisplay(const sp<IBinder>& /*display */) override {} sp<IBinder> getBuiltInDisplay(int32_t /*id*/) override { return nullptr; } void setTransactionState(const Vector<ComposerState>& /*state*/, const Vector<DisplayState>& /*displays*/, uint32_t /*flags*/) override {} const Vector<DisplayState>& /*displays*/, uint32_t /*flags*/, const sp<IBinder>& /*applyToken*/) override {} void bootFinished() override {} bool authenticateSurfaceTexture( const sp<IGraphicBufferProducer>& /*surface*/) const override { Loading
services/surfaceflinger/SurfaceFlinger.cpp +66 −9 Original line number Diff line number Diff line Loading @@ -1568,11 +1568,23 @@ void SurfaceFlinger::onMessageReceived(int32_t what) { bool SurfaceFlinger::handleMessageTransaction() { uint32_t transactionFlags = peekTransactionFlags(); // Apply any ready transactions in the queues if there are still transactions that have not been // applied, wake up during the next vsync period and check again bool transactionNeeded = false; if (!flushTransactionQueues()) { transactionNeeded = true; } if (transactionFlags) { handleTransaction(transactionFlags); return true; } return false; if (transactionNeeded) { setTransactionFlags(eTransactionNeeded); } return transactionFlags; } void SurfaceFlinger::handleMessageRefresh() { Loading Loading @@ -3314,6 +3326,26 @@ uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags, return old; } bool SurfaceFlinger::flushTransactionQueues() { Mutex::Autolock _l(mStateLock); auto it = mTransactionQueues.begin(); while (it != mTransactionQueues.end()) { auto& [applyToken, transactionQueue] = *it; while (!transactionQueue.empty()) { const auto& [states, displays, flags] = transactionQueue.front(); if (composerStateContainsUnsignaledFences(states)) { break; } applyTransactionState(states, displays, flags); transactionQueue.pop(); } it = (transactionQueue.empty()) ? mTransactionQueues.erase(it) : std::next(it, 1); } return mTransactionQueues.empty(); } bool SurfaceFlinger::containsAnyInvalidClientState(const Vector<ComposerState>& states) { for (const ComposerState& state : states) { // Here we need to check that the interface we're given is indeed Loading @@ -3336,19 +3368,44 @@ bool SurfaceFlinger::containsAnyInvalidClientState(const Vector<ComposerState>& return false; } void SurfaceFlinger::setTransactionState( const Vector<ComposerState>& states, const Vector<DisplayState>& displays, uint32_t flags) { bool SurfaceFlinger::composerStateContainsUnsignaledFences(const Vector<ComposerState>& states) { for (const ComposerState& state : states) { const layer_state_t& s = state.state; if (!(s.what & layer_state_t::eAcquireFenceChanged)) { continue; } if (s.acquireFence && s.acquireFence->getStatus() == Fence::Status::Unsignaled) { return true; } } return false; } void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& states, const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken) { ATRACE_CALL(); Mutex::Autolock _l(mStateLock); uint32_t transactionFlags = 0; if (containsAnyInvalidClientState(states)) { return; } // If its TransactionQueue already has a pending TransactionState or if it is pending if (mTransactionQueues.find(applyToken) != mTransactionQueues.end() || composerStateContainsUnsignaledFences(states)) { mTransactionQueues[applyToken].emplace(states, displays, flags); setTransactionFlags(eTransactionNeeded); return; } applyTransactionState(states, displays, flags); } void SurfaceFlinger::applyTransactionState(const Vector<ComposerState>& states, const Vector<DisplayState>& displays, uint32_t flags) { uint32_t transactionFlags = 0; if (flags & eAnimation) { // For window updates that are part of an animation we must wait for // previous animation "frames" to be handled. Loading Loading @@ -3938,7 +3995,7 @@ void SurfaceFlinger::onInitializeDisplays() { d.width = 0; d.height = 0; displays.add(d); setTransactionState(state, displays, 0); setTransactionState(state, displays, 0, nullptr); const auto display = getDisplayDevice(displayToken); if (!display) return; Loading