Skip to content
Snippets Groups Projects
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
No related branches found
No related tags found
No related merge requests found
......@@ -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;
}
......
......@@ -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,
const int32_t* tids, size_t tidCount,
int64_t defaultTarget) = nullptr;
APerformanceHintSession* (*createSessionInternal)(APerformanceHintManager* manager,
const int32_t* tids, size_t tidCount,
int64_t defaultTarget,
SessionTag tag) = nullptr;
void (*closeSession)(APerformanceHintSession* session) = nullptr;
void (*updateTargetWorkDuration)(APerformanceHintSession* session,
int64_t targetDuration) = nullptr;
......
......@@ -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,
const int32_t* ids, size_t idsSize,
int64_t initialTarget) {
return sMockBinding->fakeCreateSession(manager, ids, idsSize, initialTarget);
static APerformanceHintSession* stubCreateSessionInternal(APerformanceHintManager* manager,
const int32_t* ids, size_t idsSize,
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();
......
......@@ -366,6 +366,7 @@ LIBANDROID_PLATFORM {
APerformanceHint_setIHintManagerForTesting;
APerformanceHint_sendHint;
APerformanceHint_getThreadIds;
APerformanceHint_createSessionInternal;
extern "C++" {
ASurfaceControl_registerSurfaceStatsListener*;
ASurfaceControl_unregisterSurfaceStatsListener*;
......
......@@ -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) {
......
......@@ -30,9 +30,7 @@
#include <memory>
#include <vector>
using aidl::android::hardware::power::SessionConfig;
using aidl::android::hardware::power::SessionTag;
using aidl::android::hardware::power::WorkDuration;
namespace hal = aidl::android::hardware::power;
using aidl::android::os::IHintManager;
using aidl::android::os::IHintSession;
using ndk::ScopedAStatus;
......@@ -45,7 +43,7 @@ class MockIHintManager : public IHintManager {
public:
MOCK_METHOD(ScopedAStatus, createHintSessionWithConfig,
(const SpAIBinder& token, const ::std::vector<int32_t>& tids, int64_t durationNanos,
SessionTag tag, std::optional<SessionConfig>* config,
hal::SessionTag tag, std::optional<hal::SessionConfig>* config,
std::shared_ptr<IHintSession>* _aidl_return),
(override));
MOCK_METHOD(ScopedAStatus, getHintSessionPreferredRate, (int64_t * _aidl_return), (override));
......@@ -71,7 +69,7 @@ public:
MOCK_METHOD(ScopedAStatus, setMode, (int32_t mode, bool enabled), (override));
MOCK_METHOD(ScopedAStatus, close, (), (override));
MOCK_METHOD(ScopedAStatus, reportActualWorkDuration2,
(const ::std::vector<WorkDuration>& workDurations), (override));
(const ::std::vector<hal::WorkDuration>& workDurations), (override));
MOCK_METHOD(SpAIBinder, asBinder, (), (override));
MOCK_METHOD(bool, isRemote, (), (override));
};
......@@ -95,7 +93,7 @@ public:
return APerformanceHint_getManager();
}
APerformanceHintSession* createSession(APerformanceHintManager* manager,
int64_t targetDuration = 56789L) {
int64_t targetDuration = 56789L, bool isHwui = false) {
mMockSession = ndk::SharedRefBase::make<NiceMock<MockIHintSession>>();
int64_t sessionId = 123;
std::vector<int32_t> tids;
......@@ -104,8 +102,8 @@ public:
ON_CALL(*mMockIHintManager,
createHintSessionWithConfig(_, Eq(tids), Eq(targetDuration), _, _, _))
.WillByDefault(DoAll(SetArgPointee<4>(
std::make_optional<SessionConfig>({.id = sessionId})),
.WillByDefault(DoAll(SetArgPointee<4>(std::make_optional<hal::SessionConfig>(
{.id = sessionId})),
SetArgPointee<5>(std::shared_ptr<IHintSession>(mMockSession)),
[] { return ScopedAStatus::ok(); }));
......@@ -124,6 +122,10 @@ public:
ON_CALL(*mMockSession, reportActualWorkDuration2(_)).WillByDefault([] {
return ScopedAStatus::ok();
});
if (isHwui) {
return APerformanceHint_createSessionInternal(manager, tids.data(), tids.size(),
targetDuration, SessionTag::HWUI);
}
return APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
}
......@@ -131,7 +133,7 @@ public:
std::shared_ptr<NiceMock<MockIHintSession>> mMockSession = nullptr;
};
bool equalsWithoutTimestamp(WorkDuration lhs, WorkDuration rhs) {
bool equalsWithoutTimestamp(hal::WorkDuration lhs, hal::WorkDuration rhs) {
return lhs.workPeriodStartTimestampNanos == rhs.workPeriodStartTimestampNanos &&
lhs.cpuDurationNanos == rhs.cpuDurationNanos &&
lhs.gpuDurationNanos == rhs.gpuDurationNanos && lhs.durationNanos == rhs.durationNanos;
......@@ -194,6 +196,16 @@ TEST_F(PerformanceHintTest, TestUpdatedSessionCreation) {
APerformanceHint_closeSession(session);
}
TEST_F(PerformanceHintTest, TestHwuiSessionCreation) {
EXPECT_CALL(*mMockIHintManager,
createHintSessionWithConfig(_, _, _, hal::SessionTag::HWUI, _, _))
.Times(1);
APerformanceHintManager* manager = createManager();
APerformanceHintSession* session = createSession(manager, 56789L, true);
ASSERT_TRUE(session);
APerformanceHint_closeSession(session);
}
TEST_F(PerformanceHintTest, SetThreads) {
APerformanceHintManager* manager = createManager();
......@@ -249,8 +261,8 @@ MATCHER_P(WorkDurationEq, expected, "") {
return false;
}
for (int i = 0; i < expected.size(); ++i) {
WorkDuration expectedWorkDuration = expected[i];
WorkDuration actualWorkDuration = arg[i];
hal::WorkDuration expectedWorkDuration = expected[i];
hal::WorkDuration actualWorkDuration = arg[i];
if (!equalsWithoutTimestamp(expectedWorkDuration, actualWorkDuration)) {
*result_listener << "WorkDuration at [" << i << "] is different: "
<< "Expected: " << expectedWorkDuration.toString()
......@@ -273,7 +285,7 @@ TEST_F(PerformanceHintTest, TestAPerformanceHint_reportActualWorkDuration2) {
usleep(2); // Sleep for longer than preferredUpdateRateNanos.
struct TestPair {
WorkDuration duration;
hal::WorkDuration duration;
int expectedResult;
};
std::vector<TestPair> testPairs{
......@@ -282,7 +294,7 @@ TEST_F(PerformanceHintTest, TestAPerformanceHint_reportActualWorkDuration2) {
{{1, -20, 1, 13, -8}, EINVAL},
};
for (auto&& pair : testPairs) {
std::vector<WorkDuration> actualWorkDurations;
std::vector<hal::WorkDuration> actualWorkDurations;
actualWorkDurations.push_back(pair.duration);
EXPECT_CALL(*mMockSession, reportActualWorkDuration2(WorkDurationEq(actualWorkDurations)))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment