Loading libs/gui/LayerState.cpp +21 −6 Original line number Diff line number Diff line Loading @@ -664,29 +664,44 @@ bool InputWindowCommands::merge(const InputWindowCommands& other) { changes |= !other.focusRequests.empty(); focusRequests.insert(focusRequests.end(), std::make_move_iterator(other.focusRequests.begin()), std::make_move_iterator(other.focusRequests.end())); changes |= other.syncInputWindows && !syncInputWindows; syncInputWindows |= other.syncInputWindows; changes |= !other.windowInfosReportedListeners.empty(); windowInfosReportedListeners.insert(other.windowInfosReportedListeners.begin(), other.windowInfosReportedListeners.end()); return changes; } bool InputWindowCommands::empty() const { return focusRequests.empty() && !syncInputWindows; return focusRequests.empty() && windowInfosReportedListeners.empty(); } void InputWindowCommands::clear() { focusRequests.clear(); syncInputWindows = false; windowInfosReportedListeners.clear(); } status_t InputWindowCommands::write(Parcel& output) const { SAFE_PARCEL(output.writeParcelableVector, focusRequests); SAFE_PARCEL(output.writeBool, syncInputWindows); SAFE_PARCEL(output.writeInt32, windowInfosReportedListeners.size()); for (const auto& listener : windowInfosReportedListeners) { SAFE_PARCEL(output.writeStrongBinder, listener); } return NO_ERROR; } status_t InputWindowCommands::read(const Parcel& input) { SAFE_PARCEL(input.readParcelableVector, &focusRequests); SAFE_PARCEL(input.readBool, &syncInputWindows); int listenerSize = 0; SAFE_PARCEL_READ_SIZE(input.readInt32, &listenerSize, input.dataSize()); windowInfosReportedListeners.reserve(listenerSize); for (int i = 0; i < listenerSize; i++) { sp<gui::IWindowInfosReportedListener> listener; SAFE_PARCEL(input.readStrongBinder, &listener); windowInfosReportedListeners.insert(listener); } return NO_ERROR; } Loading libs/gui/SurfaceComposerClient.cpp +42 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <stdint.h> #include <sys/types.h> #include <android/gui/BnWindowInfosReportedListener.h> #include <android/gui/DisplayState.h> #include <android/gui/ISurfaceComposerClient.h> #include <android/gui/IWindowInfosListener.h> Loading Loading @@ -635,7 +636,8 @@ SurfaceComposerClient::Transaction::Transaction(const Transaction& other) mDesiredPresentTime(other.mDesiredPresentTime), mIsAutoTimestamp(other.mIsAutoTimestamp), mFrameTimelineInfo(other.mFrameTimelineInfo), mApplyToken(other.mApplyToken) { mApplyToken(other.mApplyToken), mWindowInfosReportedEvent(other.mWindowInfosReportedEvent) { mDisplayStates = other.mDisplayStates; mComposerStates = other.mComposerStates; mInputWindowCommands = other.mInputWindowCommands; Loading Loading @@ -879,6 +881,9 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Tr mEarlyWakeupStart = mEarlyWakeupStart || other.mEarlyWakeupStart; mEarlyWakeupEnd = mEarlyWakeupEnd || other.mEarlyWakeupEnd; mApplyToken = other.mApplyToken; if (other.mWindowInfosReportedEvent) { mWindowInfosReportedEvent = std::move(other.mWindowInfosReportedEvent); } mergeFrameTimelineInfo(mFrameTimelineInfo, other.mFrameTimelineInfo); Loading @@ -901,6 +906,7 @@ void SurfaceComposerClient::Transaction::clear() { mIsAutoTimestamp = true; clearFrameTimelineInfo(mFrameTimelineInfo); mApplyToken = nullptr; mWindowInfosReportedEvent = nullptr; } uint64_t SurfaceComposerClient::Transaction::getId() { Loading Loading @@ -1047,6 +1053,10 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay hasListenerCallbacks, listenerCallbacks, mId); mId = generateId(); if (mWindowInfosReportedEvent && !mWindowInfosReportedEvent->wait()) { ALOGE("Timed out waiting for window infos to be reported."); } // Clear the current states and flags clear(); Loading Loading @@ -1733,8 +1743,25 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFocus return *this; } class NotifyWindowInfosReported : public gui::BnWindowInfosReportedListener { public: NotifyWindowInfosReported( std::shared_ptr<SurfaceComposerClient::Event> windowInfosReportedEvent) : mWindowInfosReportedEvent(windowInfosReportedEvent) {} binder::Status onWindowInfosReported() { mWindowInfosReportedEvent->set(); return binder::Status::ok(); } private: std::shared_ptr<SurfaceComposerClient::Event> mWindowInfosReportedEvent; }; SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::syncInputWindows() { mInputWindowCommands.syncInputWindows = true; mWindowInfosReportedEvent = std::make_shared<Event>(); mInputWindowCommands.windowInfosReportedListeners.insert( sp<NotifyWindowInfosReported>::make(mWindowInfosReportedEvent)); return *this; } Loading Loading @@ -2809,4 +2836,17 @@ void ReleaseCallbackThread::threadMain() { } } // --------------------------------------------------------------------------------- void SurfaceComposerClient::Event::set() { std::lock_guard<std::mutex> lock(mMutex); mComplete = true; mConditionVariable.notify_all(); } bool SurfaceComposerClient::Event::wait() { std::unique_lock<std::mutex> lock(mMutex); return mConditionVariable.wait_for(lock, sTimeout, [this] { return mComplete; }); } } // namespace android libs/gui/include/gui/LayerState.h +4 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <stdint.h> #include <sys/types.h> #include <android/gui/IWindowInfosReportedListener.h> #include <android/native_window.h> #include <gui/IGraphicBufferProducer.h> #include <gui/ITransactionCompletedListener.h> Loading Loading @@ -359,7 +360,9 @@ struct DisplayState { struct InputWindowCommands { std::vector<gui::FocusRequest> focusRequests; bool syncInputWindows{false}; std::unordered_set<sp<gui::IWindowInfosReportedListener>, SpHash<gui::IWindowInfosReportedListener>> windowInfosReportedListeners; // Merges the passed in commands and returns true if there were any changes. bool merge(const InputWindowCommands& other); Loading libs/gui/include/gui/SurfaceComposerClient.h +18 −0 Original line number Diff line number Diff line Loading @@ -387,6 +387,22 @@ public: std::unordered_set<sp<SurfaceControl>, SCHash> surfaceControls; }; // TODO(b/222421815) this class should be removed when // SurfaceComposerClient::Transaction::syncInputWindows is removed and replaced with a method // for adding callbacks to InputWindowCommands. class Event { private: static constexpr std::chrono::seconds sTimeout{5}; bool mComplete = false; std::condition_variable mConditionVariable; std::mutex mMutex; public: void set(); bool wait(); }; class Transaction : public Parcelable { private: void releaseBufferIfOverwriting(const layer_state_t& state); Loading Loading @@ -436,6 +452,8 @@ public: InputWindowCommands mInputWindowCommands; int mStatus = NO_ERROR; std::shared_ptr<Event> mWindowInfosReportedEvent = nullptr; layer_state_t* getLayerState(const sp<SurfaceControl>& sc); DisplayState& getDisplayState(const sp<IBinder>& token); Loading services/surfaceflinger/SurfaceFlinger.cpp +15 −17 Original line number Diff line number Diff line Loading @@ -341,7 +341,7 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag) mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)), mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)), mPowerAdvisor(std::make_unique<Hwc2::impl::PowerAdvisor>(*this)), mWindowInfosListenerInvoker(sp<WindowInfosListenerInvoker>::make(*this)) { mWindowInfosListenerInvoker(sp<WindowInfosListenerInvoker>::make()) { ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str()); } Loading Loading @@ -3273,12 +3273,17 @@ void SurfaceFlinger::updateInputFlinger() { inputFlinger = mInputFlinger, this]() { ATRACE_NAME("BackgroundExecutor::updateInputFlinger"); if (updateWindowInfo) { mWindowInfosListenerInvoker->windowInfosChanged(windowInfos, displayInfos, inputWindowCommands.syncInputWindows); } else if (inputWindowCommands.syncInputWindows) { // If the caller requested to sync input windows, but there are no // changes to input windows, notify immediately. windowInfosReported(); mWindowInfosListenerInvoker ->windowInfosChanged(windowInfos, displayInfos, inputWindowCommands.windowInfosReportedListeners); } else { // If there are listeners but no changes to input windows, call the listeners // immediately. for (const auto& listener : inputWindowCommands.windowInfosReportedListeners) { if (IInterface::asBinder(listener)->isBinderAlive()) { listener->onWindowInfosReported(); } } } for (const auto& focusRequest : inputWindowCommands.focusRequests) { inputFlinger->setFocusedWindow(focusRequest); Loading Loading @@ -4101,11 +4106,9 @@ void SurfaceFlinger::queueTransaction(TransactionState& state) { Mutex::Autolock lock(mQueueLock); // Generate a CountDownLatch pending state if this is a synchronous transaction. if ((state.flags & eSynchronous) || state.inputWindowCommands.syncInputWindows) { state.transactionCommittedSignal = std::make_shared<CountDownLatch>( (state.inputWindowCommands.syncInputWindows ? (CountDownLatch::eSyncInputWindows | CountDownLatch::eSyncTransaction) : CountDownLatch::eSyncTransaction)); if (state.flags & eSynchronous) { state.transactionCommittedSignal = std::make_shared<CountDownLatch>(CountDownLatch::eSyncTransaction); } mTransactionQueue.emplace_back(state); Loading Loading @@ -6806,11 +6809,6 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( return future; } void SurfaceFlinger::windowInfosReported() { Mutex::Autolock _l(mStateLock); signalSynchronousTransactions(CountDownLatch::eSyncInputWindows); } // --------------------------------------------------------------------------- void SurfaceFlinger::State::traverse(const LayerVector::Visitor& visitor) const { Loading Loading
libs/gui/LayerState.cpp +21 −6 Original line number Diff line number Diff line Loading @@ -664,29 +664,44 @@ bool InputWindowCommands::merge(const InputWindowCommands& other) { changes |= !other.focusRequests.empty(); focusRequests.insert(focusRequests.end(), std::make_move_iterator(other.focusRequests.begin()), std::make_move_iterator(other.focusRequests.end())); changes |= other.syncInputWindows && !syncInputWindows; syncInputWindows |= other.syncInputWindows; changes |= !other.windowInfosReportedListeners.empty(); windowInfosReportedListeners.insert(other.windowInfosReportedListeners.begin(), other.windowInfosReportedListeners.end()); return changes; } bool InputWindowCommands::empty() const { return focusRequests.empty() && !syncInputWindows; return focusRequests.empty() && windowInfosReportedListeners.empty(); } void InputWindowCommands::clear() { focusRequests.clear(); syncInputWindows = false; windowInfosReportedListeners.clear(); } status_t InputWindowCommands::write(Parcel& output) const { SAFE_PARCEL(output.writeParcelableVector, focusRequests); SAFE_PARCEL(output.writeBool, syncInputWindows); SAFE_PARCEL(output.writeInt32, windowInfosReportedListeners.size()); for (const auto& listener : windowInfosReportedListeners) { SAFE_PARCEL(output.writeStrongBinder, listener); } return NO_ERROR; } status_t InputWindowCommands::read(const Parcel& input) { SAFE_PARCEL(input.readParcelableVector, &focusRequests); SAFE_PARCEL(input.readBool, &syncInputWindows); int listenerSize = 0; SAFE_PARCEL_READ_SIZE(input.readInt32, &listenerSize, input.dataSize()); windowInfosReportedListeners.reserve(listenerSize); for (int i = 0; i < listenerSize; i++) { sp<gui::IWindowInfosReportedListener> listener; SAFE_PARCEL(input.readStrongBinder, &listener); windowInfosReportedListeners.insert(listener); } return NO_ERROR; } Loading
libs/gui/SurfaceComposerClient.cpp +42 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <stdint.h> #include <sys/types.h> #include <android/gui/BnWindowInfosReportedListener.h> #include <android/gui/DisplayState.h> #include <android/gui/ISurfaceComposerClient.h> #include <android/gui/IWindowInfosListener.h> Loading Loading @@ -635,7 +636,8 @@ SurfaceComposerClient::Transaction::Transaction(const Transaction& other) mDesiredPresentTime(other.mDesiredPresentTime), mIsAutoTimestamp(other.mIsAutoTimestamp), mFrameTimelineInfo(other.mFrameTimelineInfo), mApplyToken(other.mApplyToken) { mApplyToken(other.mApplyToken), mWindowInfosReportedEvent(other.mWindowInfosReportedEvent) { mDisplayStates = other.mDisplayStates; mComposerStates = other.mComposerStates; mInputWindowCommands = other.mInputWindowCommands; Loading Loading @@ -879,6 +881,9 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Tr mEarlyWakeupStart = mEarlyWakeupStart || other.mEarlyWakeupStart; mEarlyWakeupEnd = mEarlyWakeupEnd || other.mEarlyWakeupEnd; mApplyToken = other.mApplyToken; if (other.mWindowInfosReportedEvent) { mWindowInfosReportedEvent = std::move(other.mWindowInfosReportedEvent); } mergeFrameTimelineInfo(mFrameTimelineInfo, other.mFrameTimelineInfo); Loading @@ -901,6 +906,7 @@ void SurfaceComposerClient::Transaction::clear() { mIsAutoTimestamp = true; clearFrameTimelineInfo(mFrameTimelineInfo); mApplyToken = nullptr; mWindowInfosReportedEvent = nullptr; } uint64_t SurfaceComposerClient::Transaction::getId() { Loading Loading @@ -1047,6 +1053,10 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay hasListenerCallbacks, listenerCallbacks, mId); mId = generateId(); if (mWindowInfosReportedEvent && !mWindowInfosReportedEvent->wait()) { ALOGE("Timed out waiting for window infos to be reported."); } // Clear the current states and flags clear(); Loading Loading @@ -1733,8 +1743,25 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFocus return *this; } class NotifyWindowInfosReported : public gui::BnWindowInfosReportedListener { public: NotifyWindowInfosReported( std::shared_ptr<SurfaceComposerClient::Event> windowInfosReportedEvent) : mWindowInfosReportedEvent(windowInfosReportedEvent) {} binder::Status onWindowInfosReported() { mWindowInfosReportedEvent->set(); return binder::Status::ok(); } private: std::shared_ptr<SurfaceComposerClient::Event> mWindowInfosReportedEvent; }; SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::syncInputWindows() { mInputWindowCommands.syncInputWindows = true; mWindowInfosReportedEvent = std::make_shared<Event>(); mInputWindowCommands.windowInfosReportedListeners.insert( sp<NotifyWindowInfosReported>::make(mWindowInfosReportedEvent)); return *this; } Loading Loading @@ -2809,4 +2836,17 @@ void ReleaseCallbackThread::threadMain() { } } // --------------------------------------------------------------------------------- void SurfaceComposerClient::Event::set() { std::lock_guard<std::mutex> lock(mMutex); mComplete = true; mConditionVariable.notify_all(); } bool SurfaceComposerClient::Event::wait() { std::unique_lock<std::mutex> lock(mMutex); return mConditionVariable.wait_for(lock, sTimeout, [this] { return mComplete; }); } } // namespace android
libs/gui/include/gui/LayerState.h +4 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <stdint.h> #include <sys/types.h> #include <android/gui/IWindowInfosReportedListener.h> #include <android/native_window.h> #include <gui/IGraphicBufferProducer.h> #include <gui/ITransactionCompletedListener.h> Loading Loading @@ -359,7 +360,9 @@ struct DisplayState { struct InputWindowCommands { std::vector<gui::FocusRequest> focusRequests; bool syncInputWindows{false}; std::unordered_set<sp<gui::IWindowInfosReportedListener>, SpHash<gui::IWindowInfosReportedListener>> windowInfosReportedListeners; // Merges the passed in commands and returns true if there were any changes. bool merge(const InputWindowCommands& other); Loading
libs/gui/include/gui/SurfaceComposerClient.h +18 −0 Original line number Diff line number Diff line Loading @@ -387,6 +387,22 @@ public: std::unordered_set<sp<SurfaceControl>, SCHash> surfaceControls; }; // TODO(b/222421815) this class should be removed when // SurfaceComposerClient::Transaction::syncInputWindows is removed and replaced with a method // for adding callbacks to InputWindowCommands. class Event { private: static constexpr std::chrono::seconds sTimeout{5}; bool mComplete = false; std::condition_variable mConditionVariable; std::mutex mMutex; public: void set(); bool wait(); }; class Transaction : public Parcelable { private: void releaseBufferIfOverwriting(const layer_state_t& state); Loading Loading @@ -436,6 +452,8 @@ public: InputWindowCommands mInputWindowCommands; int mStatus = NO_ERROR; std::shared_ptr<Event> mWindowInfosReportedEvent = nullptr; layer_state_t* getLayerState(const sp<SurfaceControl>& sc); DisplayState& getDisplayState(const sp<IBinder>& token); Loading
services/surfaceflinger/SurfaceFlinger.cpp +15 −17 Original line number Diff line number Diff line Loading @@ -341,7 +341,7 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag) mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)), mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)), mPowerAdvisor(std::make_unique<Hwc2::impl::PowerAdvisor>(*this)), mWindowInfosListenerInvoker(sp<WindowInfosListenerInvoker>::make(*this)) { mWindowInfosListenerInvoker(sp<WindowInfosListenerInvoker>::make()) { ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str()); } Loading Loading @@ -3273,12 +3273,17 @@ void SurfaceFlinger::updateInputFlinger() { inputFlinger = mInputFlinger, this]() { ATRACE_NAME("BackgroundExecutor::updateInputFlinger"); if (updateWindowInfo) { mWindowInfosListenerInvoker->windowInfosChanged(windowInfos, displayInfos, inputWindowCommands.syncInputWindows); } else if (inputWindowCommands.syncInputWindows) { // If the caller requested to sync input windows, but there are no // changes to input windows, notify immediately. windowInfosReported(); mWindowInfosListenerInvoker ->windowInfosChanged(windowInfos, displayInfos, inputWindowCommands.windowInfosReportedListeners); } else { // If there are listeners but no changes to input windows, call the listeners // immediately. for (const auto& listener : inputWindowCommands.windowInfosReportedListeners) { if (IInterface::asBinder(listener)->isBinderAlive()) { listener->onWindowInfosReported(); } } } for (const auto& focusRequest : inputWindowCommands.focusRequests) { inputFlinger->setFocusedWindow(focusRequest); Loading Loading @@ -4101,11 +4106,9 @@ void SurfaceFlinger::queueTransaction(TransactionState& state) { Mutex::Autolock lock(mQueueLock); // Generate a CountDownLatch pending state if this is a synchronous transaction. if ((state.flags & eSynchronous) || state.inputWindowCommands.syncInputWindows) { state.transactionCommittedSignal = std::make_shared<CountDownLatch>( (state.inputWindowCommands.syncInputWindows ? (CountDownLatch::eSyncInputWindows | CountDownLatch::eSyncTransaction) : CountDownLatch::eSyncTransaction)); if (state.flags & eSynchronous) { state.transactionCommittedSignal = std::make_shared<CountDownLatch>(CountDownLatch::eSyncTransaction); } mTransactionQueue.emplace_back(state); Loading Loading @@ -6806,11 +6809,6 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( return future; } void SurfaceFlinger::windowInfosReported() { Mutex::Autolock _l(mStateLock); signalSynchronousTransactions(CountDownLatch::eSyncInputWindows); } // --------------------------------------------------------------------------- void SurfaceFlinger::State::traverse(const LayerVector::Visitor& visitor) const { Loading