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

Commit 27da1340 authored by Matt Buckley's avatar Matt Buckley
Browse files

Add HWUI session tagging

Adds a hidden method for the creation of special "internal" hint
sessions with extra metadata, and plumbs hwui to use it

Bug: 330553312
Test: atest PerformanceHintNativeTestCases
Test: hwui unit tests
Change-Id: I35e7f81623b8f81a9a12e485f221952a13035b02
parent e073c73f
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ void HintSessionWrapper::HintSessionBinding::init() {
    LOG_ALWAYS_FATAL_IF(handle_ == nullptr, "Failed to dlopen libandroid.so!");

    BIND_APH_METHOD(getManager);
    BIND_APH_METHOD(createSession);
    BIND_APH_METHOD(createSessionInternal);
    BIND_APH_METHOD(closeSession);
    BIND_APH_METHOD(updateTargetWorkDuration);
    BIND_APH_METHOD(reportActualWorkDuration);
@@ -122,7 +122,8 @@ bool HintSessionWrapper::init() {
    int64_t targetDurationNanos =
            mLastTargetWorkDuration == 0 ? kDefaultTargetDuration : mLastTargetWorkDuration;
    mHintSessionFuture = CommonPool::async([=, this, tids = mPermanentSessionTids] {
        return mBinding->createSession(manager, tids.data(), tids.size(), targetDurationNanos);
        return mBinding->createSessionInternal(manager, tids.data(), tids.size(),
                                               targetDurationNanos, SessionTag::HWUI);
    });
    return false;
}
+5 −3
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#pragma once

#include <android/performance_hint.h>
#include <private/performance_hint_private.h>

#include <future>
#include <optional>
@@ -80,9 +81,10 @@ private:
        virtual ~HintSessionBinding() = default;
        virtual void init();
        APerformanceHintManager* (*getManager)();
        APerformanceHintSession* (*createSession)(APerformanceHintManager* manager,
        APerformanceHintSession* (*createSessionInternal)(APerformanceHintManager* manager,
                                                          const int32_t* tids, size_t tidCount,
                                                  int64_t defaultTarget) = nullptr;
                                                          int64_t defaultTarget,
                                                          SessionTag tag) = nullptr;
        void (*closeSession)(APerformanceHintSession* session) = nullptr;
        void (*updateTargetWorkDuration)(APerformanceHintSession* session,
                                         int64_t targetDuration) = nullptr;
+28 −22
Original line number Diff line number Diff line
@@ -52,8 +52,8 @@ protected:
        void init() override;

        MOCK_METHOD(APerformanceHintManager*, fakeGetManager, ());
        MOCK_METHOD(APerformanceHintSession*, fakeCreateSession,
                    (APerformanceHintManager*, const int32_t*, size_t, int64_t));
        MOCK_METHOD(APerformanceHintSession*, fakeCreateSessionInternal,
                    (APerformanceHintManager*, const int32_t*, size_t, int64_t, SessionTag));
        MOCK_METHOD(void, fakeCloseSession, (APerformanceHintSession*));
        MOCK_METHOD(void, fakeUpdateTargetWorkDuration, (APerformanceHintSession*, int64_t));
        MOCK_METHOD(void, fakeReportActualWorkDuration, (APerformanceHintSession*, int64_t));
@@ -72,22 +72,28 @@ protected:

    // Must be static so we can point to them as normal fn pointers with HintSessionBinding
    static APerformanceHintManager* stubGetManager() { return sMockBinding->fakeGetManager(); };
    static APerformanceHintSession* stubCreateSession(APerformanceHintManager* manager,
    static APerformanceHintSession* stubCreateSessionInternal(APerformanceHintManager* manager,
                                                              const int32_t* ids, size_t idsSize,
                                                      int64_t initialTarget) {
        return sMockBinding->fakeCreateSession(manager, ids, idsSize, initialTarget);
                                                              int64_t initialTarget,
                                                              SessionTag tag) {
        return sMockBinding->fakeCreateSessionInternal(manager, ids, idsSize, initialTarget,
                                                       SessionTag::HWUI);
    }
    static APerformanceHintSession* stubManagedCreateSession(APerformanceHintManager* manager,
                                                             const int32_t* ids, size_t idsSize,
                                                             int64_t initialTarget) {
    static APerformanceHintSession* stubManagedCreateSessionInternal(
            APerformanceHintManager* manager, const int32_t* ids, size_t idsSize,
            int64_t initialTarget, SessionTag tag) {
        sMockBinding->allowCreationToFinish.get_future().wait();
        return sMockBinding->fakeCreateSession(manager, ids, idsSize, initialTarget);
        return sMockBinding->fakeCreateSessionInternal(manager, ids, idsSize, initialTarget,
                                                       SessionTag::HWUI);
    }
    static APerformanceHintSession* stubSlowCreateSession(APerformanceHintManager* manager,
                                                          const int32_t* ids, size_t idsSize,
                                                          int64_t initialTarget) {
    static APerformanceHintSession* stubSlowCreateSessionInternal(APerformanceHintManager* manager,
                                                                  const int32_t* ids,
                                                                  size_t idsSize,
                                                                  int64_t initialTarget,
                                                                  SessionTag tag) {
        std::this_thread::sleep_for(50ms);
        return sMockBinding->fakeCreateSession(manager, ids, idsSize, initialTarget);
        return sMockBinding->fakeCreateSessionInternal(manager, ids, idsSize, initialTarget,
                                                       SessionTag::HWUI);
    }
    static void stubCloseSession(APerformanceHintSession* session) {
        sMockBinding->fakeCloseSession(session);
@@ -139,14 +145,14 @@ void HintSessionWrapperTests::SetUp() {
    mWrapper = std::make_shared<HintSessionWrapper>(uiThreadId, renderThreadId);
    mWrapper->mBinding = sMockBinding;
    EXPECT_CALL(*sMockBinding, fakeGetManager).WillOnce(Return(managerPtr));
    ON_CALL(*sMockBinding, fakeCreateSession).WillByDefault(Return(sessionPtr));
    ON_CALL(*sMockBinding, fakeCreateSessionInternal).WillByDefault(Return(sessionPtr));
    ON_CALL(*sMockBinding, fakeSetThreads).WillByDefault(Return(0));
}

void HintSessionWrapperTests::MockHintSessionBinding::init() {
    sMockBinding->getManager = &stubGetManager;
    if (sMockBinding->createSession == nullptr) {
        sMockBinding->createSession = &stubCreateSession;
    if (sMockBinding->createSessionInternal == nullptr) {
        sMockBinding->createSessionInternal = &stubCreateSessionInternal;
    }
    sMockBinding->closeSession = &stubCloseSession;
    sMockBinding->updateTargetWorkDuration = &stubUpdateTargetWorkDuration;
@@ -163,14 +169,14 @@ void HintSessionWrapperTests::TearDown() {

TEST_F(HintSessionWrapperTests, destructorClosesBackgroundSession) {
    EXPECT_CALL(*sMockBinding, fakeCloseSession(sessionPtr)).Times(1);
    sMockBinding->createSession = stubSlowCreateSession;
    sMockBinding->createSessionInternal = stubSlowCreateSessionInternal;
    mWrapper->init();
    mWrapper = nullptr;
    Mock::VerifyAndClearExpectations(sMockBinding.get());
}

TEST_F(HintSessionWrapperTests, sessionInitializesCorrectly) {
    EXPECT_CALL(*sMockBinding, fakeCreateSession(managerPtr, _, Gt(1), _)).Times(1);
    EXPECT_CALL(*sMockBinding, fakeCreateSessionInternal(managerPtr, _, Gt(1), _, _)).Times(1);
    mWrapper->init();
    waitForWrapperReady();
}
@@ -219,7 +225,7 @@ TEST_F(HintSessionWrapperTests, delayedDeletionResolvesBeforeAsyncCreationFinish
    // Here we test whether queueing delayedDestroy works while creation is still happening, if
    // creation happens after
    EXPECT_CALL(*sMockBinding, fakeCloseSession(sessionPtr)).Times(1);
    sMockBinding->createSession = &stubManagedCreateSession;
    sMockBinding->createSessionInternal = &stubManagedCreateSessionInternal;

    // Start creating the session and destroying it at the same time
    mWrapper->init();
@@ -246,7 +252,7 @@ TEST_F(HintSessionWrapperTests, delayedDeletionResolvesAfterAsyncCreationFinishe
    // Here we test whether queueing delayedDestroy works while creation is still happening, if
    // creation happens before
    EXPECT_CALL(*sMockBinding, fakeCloseSession(sessionPtr)).Times(1);
    sMockBinding->createSession = &stubManagedCreateSession;
    sMockBinding->createSessionInternal = &stubManagedCreateSessionInternal;

    // Start creating the session and destroying it at the same time
    mWrapper->init();
@@ -352,7 +358,7 @@ TEST_F(HintSessionWrapperTests, manualSessionDestroyPlaysNiceWithDelayedDestruct
}

TEST_F(HintSessionWrapperTests, setThreadsUpdatesSessionThreads) {
    EXPECT_CALL(*sMockBinding, fakeCreateSession(managerPtr, _, Gt(1), _)).Times(1);
    EXPECT_CALL(*sMockBinding, fakeCreateSessionInternal(managerPtr, _, Gt(1), _, _)).Times(1);
    EXPECT_CALL(*sMockBinding, fakeSetThreads(sessionPtr, testing::IsSupersetOf({11, 22})))
            .Times(1);
    mWrapper->init();
+1 −0
Original line number Diff line number Diff line
@@ -366,6 +366,7 @@ LIBANDROID_PLATFORM {
    APerformanceHint_setIHintManagerForTesting;
    APerformanceHint_sendHint;
    APerformanceHint_getThreadIds;
    APerformanceHint_createSessionInternal;
    extern "C++" {
        ASurfaceControl_registerSurfaceStatsListener*;
        ASurfaceControl_unregisterSurfaceStatsListener*;
+14 −6
Original line number Diff line number Diff line
@@ -463,6 +463,15 @@ APerformanceHintSession* APerformanceHint_createSession(APerformanceHintManager*
    return manager->createSession(threadIds, size, initialTargetWorkDurationNanos);
}

APerformanceHintSession* APerformanceHint_createSessionInternal(
        APerformanceHintManager* manager, const int32_t* threadIds, size_t size,
        int64_t initialTargetWorkDurationNanos, SessionTag tag) {
    VALIDATE_PTR(manager)
    VALIDATE_PTR(threadIds)
    return manager->createSession(threadIds, size, initialTargetWorkDurationNanos,
                                  static_cast<hal::SessionTag>(tag));
}

int64_t APerformanceHint_getPreferredUpdateRateNanos(APerformanceHintManager* manager) {
    VALIDATE_PTR(manager)
    return manager->getPreferredRateNanos();
@@ -486,9 +495,9 @@ void APerformanceHint_closeSession(APerformanceHintSession* session) {
    delete session;
}

int APerformanceHint_sendHint(void* session, SessionHint hint) {
int APerformanceHint_sendHint(APerformanceHintSession* session, SessionHint hint) {
    VALIDATE_PTR(session)
    return reinterpret_cast<APerformanceHintSession*>(session)->sendHint(hint);
    return session->sendHint(hint);
}

int APerformanceHint_setThreads(APerformanceHintSession* session, const pid_t* threadIds,
@@ -498,11 +507,10 @@ int APerformanceHint_setThreads(APerformanceHintSession* session, const pid_t* t
    return session->setThreads(threadIds, size);
}

int APerformanceHint_getThreadIds(void* aPerformanceHintSession, int32_t* const threadIds,
int APerformanceHint_getThreadIds(APerformanceHintSession* session, int32_t* const threadIds,
                                  size_t* const size) {
    VALIDATE_PTR(aPerformanceHintSession)
    return static_cast<APerformanceHintSession*>(aPerformanceHintSession)
            ->getThreadIds(threadIds, size);
    VALIDATE_PTR(session)
    return session->getThreadIds(threadIds, size);
}

int APerformanceHint_setPreferPowerEfficiency(APerformanceHintSession* session, bool enabled) {
Loading