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

Commit ebdecd61 authored by Igor Kraskevich's avatar Igor Kraskevich Committed by Android (Google) Code Review
Browse files

Merge "Pass active functor rendering threads to HWUI ADPF session" into main

parents 1412c1ab 2cec158c
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