Loading libs/hwui/WebViewFunctorManager.cpp +21 −5 Original line number Diff line number Diff line Loading @@ -16,15 +16,16 @@ #include "WebViewFunctorManager.h" #include <log/log.h> #include <private/hwui/WebViewFunctor.h> #include <utils/Trace.h> #include <atomic> #include "Properties.h" #include "renderthread/CanvasContext.h" #include "renderthread/RenderThread.h" #include <log/log.h> #include <utils/Trace.h> #include <atomic> namespace android::uirenderer { namespace { Loading Loading @@ -265,7 +266,7 @@ void WebViewFunctor::reparentSurfaceControl(ASurfaceControl* parent) { } void WebViewFunctor::reportRenderingThreads(const int32_t* thread_ids, size_t size) { // TODO(b/329219352): Pass the threads to HWUI and update the ADPF session. mRenderingThreads = std::vector<int32_t>(thread_ids, thread_ids + size); } WebViewFunctorManager& WebViewFunctorManager::instance() { Loading Loading @@ -365,6 +366,21 @@ void WebViewFunctorManager::reportRenderingThreads(int functor, const int32_t* t } } std::vector<int32_t> WebViewFunctorManager::getRenderingThreadsForActiveFunctors() { std::vector<int32_t> renderingThreads; std::lock_guard _lock{mLock}; for (const auto& iter : mActiveFunctors) { const auto& functorThreads = iter->getRenderingThreads(); for (const auto& tid : functorThreads) { if (std::find(renderingThreads.begin(), renderingThreads.end(), tid) == renderingThreads.end()) { renderingThreads.push_back(tid); } } } return renderingThreads; } sp<WebViewFunctor::Handle> WebViewFunctorManager::handleFor(int functor) { std::lock_guard _lock{mLock}; for (auto& iter : mActiveFunctors) { Loading libs/hwui/WebViewFunctorManager.h +7 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,10 @@ public: void onRemovedFromTree() { mReference.onRemovedFromTree(); } const std::vector<int32_t>& getRenderingThreads() const { return mReference.getRenderingThreads(); } private: friend class WebViewFunctor; Loading @@ -82,6 +86,7 @@ public: void mergeTransaction(ASurfaceTransaction* transaction); void reportRenderingThreads(const int32_t* thread_ids, size_t size); const std::vector<int32_t>& getRenderingThreads() const { return mRenderingThreads; } sp<Handle> createHandle() { LOG_ALWAYS_FATAL_IF(mCreatedHandle); Loading @@ -102,6 +107,7 @@ private: bool mCreatedHandle = false; int32_t mParentSurfaceControlGenerationId = 0; ASurfaceControl* mSurfaceControl = nullptr; std::vector<int32_t> mRenderingThreads; }; class WebViewFunctorManager { Loading @@ -113,6 +119,7 @@ public: void onContextDestroyed(); void destroyFunctor(int functor); void reportRenderingThreads(int functor, const int32_t* thread_ids, size_t size); std::vector<int32_t> getRenderingThreadsForActiveFunctors(); sp<WebViewFunctor::Handle> handleFor(int functor); Loading libs/hwui/renderthread/CanvasContext.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -777,6 +777,8 @@ void CanvasContext::draw(bool solelyTextureViewUpdates) { (std::min(syncDelayDuration, mLastDequeueBufferDuration)) - dequeueBufferDuration - idleDuration; mHintSessionWrapper->reportActualWorkDuration(actualDuration); mHintSessionWrapper->setActiveFunctorThreads( WebViewFunctorManager::instance().getRenderingThreadsForActiveFunctors()); } mLastDequeueBufferDuration = dequeueBufferDuration; Loading libs/hwui/renderthread/HintSessionWrapper.cpp +27 −4 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <private/performance_hint_private.h> #include <utils/Log.h> #include <algorithm> #include <chrono> #include <vector> Loading Loading @@ -49,6 +50,7 @@ void HintSessionWrapper::HintSessionBinding::init() { BIND_APH_METHOD(updateTargetWorkDuration); BIND_APH_METHOD(reportActualWorkDuration); BIND_APH_METHOD(sendHint); BIND_APH_METHOD(setThreads); mInitialized = true; } Loading @@ -67,6 +69,10 @@ void HintSessionWrapper::destroy() { mHintSession = mHintSessionFuture->get(); mHintSessionFuture = std::nullopt; } if (mSetThreadsFuture.has_value()) { mSetThreadsFuture->wait(); mSetThreadsFuture = std::nullopt; } if (mHintSession) { mBinding->closeSession(mHintSession); mSessionValid = true; Loading Loading @@ -106,16 +112,16 @@ bool HintSessionWrapper::init() { APerformanceHintManager* manager = mBinding->getManager(); if (!manager) return false; std::vector<pid_t> tids = CommonPool::getThreadIds(); tids.push_back(mUiThreadId); tids.push_back(mRenderThreadId); mPermanentSessionTids = CommonPool::getThreadIds(); mPermanentSessionTids.push_back(mUiThreadId); mPermanentSessionTids.push_back(mRenderThreadId); // Use the cached target value if there is one, otherwise use a default. This is to ensure // the cached target and target in PowerHAL are consistent, and that it updates correctly // whenever there is a change. int64_t targetDurationNanos = mLastTargetWorkDuration == 0 ? kDefaultTargetDuration : mLastTargetWorkDuration; mHintSessionFuture = CommonPool::async([=, this, tids = std::move(tids)] { mHintSessionFuture = CommonPool::async([=, this, tids = mPermanentSessionTids] { return mBinding->createSession(manager, tids.data(), tids.size(), targetDurationNanos); }); return false; Loading Loading @@ -143,6 +149,23 @@ void HintSessionWrapper::reportActualWorkDuration(long actualDurationNanos) { mLastFrameNotification = systemTime(); } void HintSessionWrapper::setActiveFunctorThreads(std::vector<pid_t> threadIds) { if (!init()) return; if (!mBinding || !mHintSession) return; // Sort the vector to make sure they're compared as sets. std::sort(threadIds.begin(), threadIds.end()); if (threadIds == mActiveFunctorTids) return; mActiveFunctorTids = std::move(threadIds); std::vector<pid_t> combinedTids = mPermanentSessionTids; std::copy(mActiveFunctorTids.begin(), mActiveFunctorTids.end(), std::back_inserter(combinedTids)); mSetThreadsFuture = CommonPool::async([this, tids = std::move(combinedTids)] { int ret = mBinding->setThreads(mHintSession, tids.data(), tids.size()); ALOGE_IF(ret != 0, "APerformaceHint_setThreads failed: %d", ret); return ret; }); } void HintSessionWrapper::sendLoadResetHint() { static constexpr int kMaxResetsSinceLastReport = 2; if (!init()) return; Loading libs/hwui/renderthread/HintSessionWrapper.h +9 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <future> #include <optional> #include <vector> #include "utils/TimeUtils.h" Loading Loading @@ -47,11 +48,15 @@ public: nsecs_t getLastUpdate(); void delayedDestroy(renderthread::RenderThread& rt, nsecs_t delay, std::shared_ptr<HintSessionWrapper> wrapperPtr); // Must be called on Render thread. Otherwise can cause a race condition. void setActiveFunctorThreads(std::vector<pid_t> threadIds); private: APerformanceHintSession* mHintSession = nullptr; // This needs to work concurrently for testing std::optional<std::shared_future<APerformanceHintSession*>> mHintSessionFuture; // This needs to work concurrently for testing std::optional<std::shared_future<int>> mSetThreadsFuture; int mResetsSinceLastReport = 0; nsecs_t mLastFrameNotification = 0; Loading @@ -59,6 +64,8 @@ private: pid_t mUiThreadId; pid_t mRenderThreadId; std::vector<pid_t> mPermanentSessionTids; std::vector<pid_t> mActiveFunctorTids; bool mSessionValid = true; Loading @@ -82,6 +89,8 @@ private: void (*reportActualWorkDuration)(APerformanceHintSession* session, int64_t actualDuration) = nullptr; void (*sendHint)(APerformanceHintSession* session, int32_t hintId) = nullptr; int (*setThreads)(APerformanceHintSession* session, const pid_t* tids, size_t size) = nullptr; private: bool mInitialized = false; Loading Loading
libs/hwui/WebViewFunctorManager.cpp +21 −5 Original line number Diff line number Diff line Loading @@ -16,15 +16,16 @@ #include "WebViewFunctorManager.h" #include <log/log.h> #include <private/hwui/WebViewFunctor.h> #include <utils/Trace.h> #include <atomic> #include "Properties.h" #include "renderthread/CanvasContext.h" #include "renderthread/RenderThread.h" #include <log/log.h> #include <utils/Trace.h> #include <atomic> namespace android::uirenderer { namespace { Loading Loading @@ -265,7 +266,7 @@ void WebViewFunctor::reparentSurfaceControl(ASurfaceControl* parent) { } void WebViewFunctor::reportRenderingThreads(const int32_t* thread_ids, size_t size) { // TODO(b/329219352): Pass the threads to HWUI and update the ADPF session. mRenderingThreads = std::vector<int32_t>(thread_ids, thread_ids + size); } WebViewFunctorManager& WebViewFunctorManager::instance() { Loading Loading @@ -365,6 +366,21 @@ void WebViewFunctorManager::reportRenderingThreads(int functor, const int32_t* t } } std::vector<int32_t> WebViewFunctorManager::getRenderingThreadsForActiveFunctors() { std::vector<int32_t> renderingThreads; std::lock_guard _lock{mLock}; for (const auto& iter : mActiveFunctors) { const auto& functorThreads = iter->getRenderingThreads(); for (const auto& tid : functorThreads) { if (std::find(renderingThreads.begin(), renderingThreads.end(), tid) == renderingThreads.end()) { renderingThreads.push_back(tid); } } } return renderingThreads; } sp<WebViewFunctor::Handle> WebViewFunctorManager::handleFor(int functor) { std::lock_guard _lock{mLock}; for (auto& iter : mActiveFunctors) { Loading
libs/hwui/WebViewFunctorManager.h +7 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,10 @@ public: void onRemovedFromTree() { mReference.onRemovedFromTree(); } const std::vector<int32_t>& getRenderingThreads() const { return mReference.getRenderingThreads(); } private: friend class WebViewFunctor; Loading @@ -82,6 +86,7 @@ public: void mergeTransaction(ASurfaceTransaction* transaction); void reportRenderingThreads(const int32_t* thread_ids, size_t size); const std::vector<int32_t>& getRenderingThreads() const { return mRenderingThreads; } sp<Handle> createHandle() { LOG_ALWAYS_FATAL_IF(mCreatedHandle); Loading @@ -102,6 +107,7 @@ private: bool mCreatedHandle = false; int32_t mParentSurfaceControlGenerationId = 0; ASurfaceControl* mSurfaceControl = nullptr; std::vector<int32_t> mRenderingThreads; }; class WebViewFunctorManager { Loading @@ -113,6 +119,7 @@ public: void onContextDestroyed(); void destroyFunctor(int functor); void reportRenderingThreads(int functor, const int32_t* thread_ids, size_t size); std::vector<int32_t> getRenderingThreadsForActiveFunctors(); sp<WebViewFunctor::Handle> handleFor(int functor); Loading
libs/hwui/renderthread/CanvasContext.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -777,6 +777,8 @@ void CanvasContext::draw(bool solelyTextureViewUpdates) { (std::min(syncDelayDuration, mLastDequeueBufferDuration)) - dequeueBufferDuration - idleDuration; mHintSessionWrapper->reportActualWorkDuration(actualDuration); mHintSessionWrapper->setActiveFunctorThreads( WebViewFunctorManager::instance().getRenderingThreadsForActiveFunctors()); } mLastDequeueBufferDuration = dequeueBufferDuration; Loading
libs/hwui/renderthread/HintSessionWrapper.cpp +27 −4 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <private/performance_hint_private.h> #include <utils/Log.h> #include <algorithm> #include <chrono> #include <vector> Loading Loading @@ -49,6 +50,7 @@ void HintSessionWrapper::HintSessionBinding::init() { BIND_APH_METHOD(updateTargetWorkDuration); BIND_APH_METHOD(reportActualWorkDuration); BIND_APH_METHOD(sendHint); BIND_APH_METHOD(setThreads); mInitialized = true; } Loading @@ -67,6 +69,10 @@ void HintSessionWrapper::destroy() { mHintSession = mHintSessionFuture->get(); mHintSessionFuture = std::nullopt; } if (mSetThreadsFuture.has_value()) { mSetThreadsFuture->wait(); mSetThreadsFuture = std::nullopt; } if (mHintSession) { mBinding->closeSession(mHintSession); mSessionValid = true; Loading Loading @@ -106,16 +112,16 @@ bool HintSessionWrapper::init() { APerformanceHintManager* manager = mBinding->getManager(); if (!manager) return false; std::vector<pid_t> tids = CommonPool::getThreadIds(); tids.push_back(mUiThreadId); tids.push_back(mRenderThreadId); mPermanentSessionTids = CommonPool::getThreadIds(); mPermanentSessionTids.push_back(mUiThreadId); mPermanentSessionTids.push_back(mRenderThreadId); // Use the cached target value if there is one, otherwise use a default. This is to ensure // the cached target and target in PowerHAL are consistent, and that it updates correctly // whenever there is a change. int64_t targetDurationNanos = mLastTargetWorkDuration == 0 ? kDefaultTargetDuration : mLastTargetWorkDuration; mHintSessionFuture = CommonPool::async([=, this, tids = std::move(tids)] { mHintSessionFuture = CommonPool::async([=, this, tids = mPermanentSessionTids] { return mBinding->createSession(manager, tids.data(), tids.size(), targetDurationNanos); }); return false; Loading Loading @@ -143,6 +149,23 @@ void HintSessionWrapper::reportActualWorkDuration(long actualDurationNanos) { mLastFrameNotification = systemTime(); } void HintSessionWrapper::setActiveFunctorThreads(std::vector<pid_t> threadIds) { if (!init()) return; if (!mBinding || !mHintSession) return; // Sort the vector to make sure they're compared as sets. std::sort(threadIds.begin(), threadIds.end()); if (threadIds == mActiveFunctorTids) return; mActiveFunctorTids = std::move(threadIds); std::vector<pid_t> combinedTids = mPermanentSessionTids; std::copy(mActiveFunctorTids.begin(), mActiveFunctorTids.end(), std::back_inserter(combinedTids)); mSetThreadsFuture = CommonPool::async([this, tids = std::move(combinedTids)] { int ret = mBinding->setThreads(mHintSession, tids.data(), tids.size()); ALOGE_IF(ret != 0, "APerformaceHint_setThreads failed: %d", ret); return ret; }); } void HintSessionWrapper::sendLoadResetHint() { static constexpr int kMaxResetsSinceLastReport = 2; if (!init()) return; Loading
libs/hwui/renderthread/HintSessionWrapper.h +9 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <future> #include <optional> #include <vector> #include "utils/TimeUtils.h" Loading Loading @@ -47,11 +48,15 @@ public: nsecs_t getLastUpdate(); void delayedDestroy(renderthread::RenderThread& rt, nsecs_t delay, std::shared_ptr<HintSessionWrapper> wrapperPtr); // Must be called on Render thread. Otherwise can cause a race condition. void setActiveFunctorThreads(std::vector<pid_t> threadIds); private: APerformanceHintSession* mHintSession = nullptr; // This needs to work concurrently for testing std::optional<std::shared_future<APerformanceHintSession*>> mHintSessionFuture; // This needs to work concurrently for testing std::optional<std::shared_future<int>> mSetThreadsFuture; int mResetsSinceLastReport = 0; nsecs_t mLastFrameNotification = 0; Loading @@ -59,6 +64,8 @@ private: pid_t mUiThreadId; pid_t mRenderThreadId; std::vector<pid_t> mPermanentSessionTids; std::vector<pid_t> mActiveFunctorTids; bool mSessionValid = true; Loading @@ -82,6 +89,8 @@ private: void (*reportActualWorkDuration)(APerformanceHintSession* session, int64_t actualDuration) = nullptr; void (*sendHint)(APerformanceHintSession* session, int32_t hintId) = nullptr; int (*setThreads)(APerformanceHintSession* session, const pid_t* tids, size_t size) = nullptr; private: bool mInitialized = false; Loading