Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2cec158c authored by Igor Kraskevich's avatar Igor Kraskevich
Browse files

Pass active functor rendering threads to HWUI ADPF session

Test: unit tested

Bug: 329219352

Change-Id: I13e83030e5d0891584ba9d62fe6cc1eb332a7b74
parent 13b1479b
Loading
Loading
Loading
Loading
+21 −5
Original line number Diff line number Diff line
@@ -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 {
@@ -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() {
@@ -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) {
+7 −0
Original line number Diff line number Diff line
@@ -60,6 +60,10 @@ public:

        void onRemovedFromTree() { mReference.onRemovedFromTree(); }

        const std::vector<int32_t>& getRenderingThreads() const {
            return mReference.getRenderingThreads();
        }

    private:
        friend class WebViewFunctor;

@@ -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);
@@ -102,6 +107,7 @@ private:
    bool mCreatedHandle = false;
    int32_t mParentSurfaceControlGenerationId = 0;
    ASurfaceControl* mSurfaceControl = nullptr;
    std::vector<int32_t> mRenderingThreads;
};

class WebViewFunctorManager {
@@ -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);

+2 −0
Original line number Diff line number Diff line
@@ -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;
+27 −4
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <private/performance_hint_private.h>
#include <utils/Log.h>

#include <algorithm>
#include <chrono>
#include <vector>

@@ -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;
}
@@ -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;
@@ -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;
@@ -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;
+9 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@

#include <future>
#include <optional>
#include <vector>

#include "utils/TimeUtils.h"

@@ -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;
@@ -59,6 +64,8 @@ private:

    pid_t mUiThreadId;
    pid_t mRenderThreadId;
    std::vector<pid_t> mPermanentSessionTids;
    std::vector<pid_t> mActiveFunctorTids;

    bool mSessionValid = true;

@@ -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