diff options
Diffstat (limited to 'native')
| -rw-r--r-- | native/android/input.cpp | 21 | ||||
| -rw-r--r-- | native/android/libandroid.map.txt | 2 | ||||
| -rw-r--r-- | native/android/performance_hint.cpp | 174 | ||||
| -rw-r--r-- | native/android/surface_control.cpp | 18 |
4 files changed, 159 insertions, 56 deletions
diff --git a/native/android/input.cpp b/native/android/input.cpp index 64e8efeaa4e8..53699bc706ea 100644 --- a/native/android/input.cpp +++ b/native/android/input.cpp @@ -87,7 +87,7 @@ int64_t AKeyEvent_getDownTime(const AInputEvent* key_event) { const AInputEvent* AKeyEvent_fromJava(JNIEnv* env, jobject keyEvent) { std::unique_ptr<KeyEvent> event = std::make_unique<KeyEvent>(); - *event = android::android_view_KeyEvent_toNative(env, keyEvent); + *event = android::android_view_KeyEvent_obtainAsCopy(env, keyEvent); return event.release(); } @@ -314,6 +314,25 @@ const AInputEvent* AMotionEvent_fromJava(JNIEnv* env, jobject motionEvent) { return event; } +jobject AInputEvent_toJava(JNIEnv* env, const AInputEvent* aInputEvent) { + LOG_ALWAYS_FATAL_IF(aInputEvent == nullptr, "Expected aInputEvent to be non-null"); + const int32_t eventType = AInputEvent_getType(aInputEvent); + switch (eventType) { + case AINPUT_EVENT_TYPE_MOTION: + return android::android_view_MotionEvent_obtainAsCopy(env, + static_cast<const MotionEvent&>( + *aInputEvent)) + .release(); + case AINPUT_EVENT_TYPE_KEY: + return android::android_view_KeyEvent_obtainAsCopy(env, + static_cast<const KeyEvent&>( + *aInputEvent)) + .release(); + default: + LOG_ALWAYS_FATAL("Unexpected event type %d in AInputEvent_toJava.", eventType); + } +} + void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper, int ident, ALooper_callbackFunc callback, void* data) { InputQueue* iq = static_cast<InputQueue*>(queue); diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index 960510879a4c..35e37b2a6893 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -90,6 +90,7 @@ LIBANDROID { AInputEvent_getSource; AInputEvent_getType; AInputEvent_release; # introduced=31 + AInputEvent_toJava; # introduced=35 AInputQueue_attachLooper; AInputQueue_detachLooper; AInputQueue_finishEvent; @@ -276,6 +277,7 @@ LIBANDROID { ASurfaceTransaction_setHdrMetadata_cta861_3; # introduced=29 ASurfaceTransaction_setHdrMetadata_smpte2086; # introduced=29 ASurfaceTransaction_setExtendedRangeBrightness; # introduced=UpsideDownCake + ASurfaceTransaction_setDesiredHdrHeadroom; # introduced=VanillaIceCream ASurfaceTransaction_setOnComplete; # introduced=29 ASurfaceTransaction_setOnCommit; # introduced=31 ASurfaceTransaction_setPosition; # introduced=31 diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp index c4c81284780e..279f9d682b9f 100644 --- a/native/android/performance_hint.cpp +++ b/native/android/performance_hint.cpp @@ -18,10 +18,12 @@ #include <aidl/android/hardware/power/SessionHint.h> #include <aidl/android/hardware/power/SessionMode.h> +#include <android-base/stringprintf.h> #include <android/WorkDuration.h> #include <android/os/IHintManager.h> #include <android/os/IHintSession.h> #include <android/performance_hint.h> +#include <android/trace.h> #include <binder/Binder.h> #include <binder/IBinder.h> #include <binder/IServiceManager.h> @@ -30,6 +32,7 @@ #include <utils/SystemClock.h> #include <chrono> +#include <set> #include <utility> #include <vector> @@ -40,6 +43,7 @@ using namespace std::chrono_literals; using AidlSessionHint = aidl::android::hardware::power::SessionHint; using AidlSessionMode = aidl::android::hardware::power::SessionMode; +using android::base::StringPrintf; struct APerformanceHintSession; @@ -98,10 +102,21 @@ private: std::vector<int64_t> mLastHintSentTimestamp; // Cached samples std::vector<WorkDuration> mActualWorkDurations; + std::string mSessionName; + static int32_t sIDCounter; + // The most recent set of thread IDs + std::vector<int32_t> mLastThreadIDs; + // Tracing helpers + void traceThreads(std::vector<int32_t>& tids); + void tracePowerEfficient(bool powerEfficient); + void traceActualDuration(int64_t actualDuration); + void traceBatchSize(size_t batchSize); + void traceTargetDuration(int64_t targetDuration); }; static IHintManager* gIHintManagerForTesting = nullptr; static APerformanceHintManager* gHintManagerForTesting = nullptr; +int32_t APerformanceHintSession::sIDCounter = 0; // ===================================== APerformanceHintManager implementation APerformanceHintManager::APerformanceHintManager(sp<IHintManager> manager, @@ -150,8 +165,12 @@ APerformanceHintSession* APerformanceHintManager::createSession( if (!ret.isOk() || !session) { return nullptr; } - return new APerformanceHintSession(mHintManager, std::move(session), mPreferredRateNanos, - initialTargetWorkDurationNanos); + auto out = new APerformanceHintSession(mHintManager, std::move(session), mPreferredRateNanos, + initialTargetWorkDurationNanos); + out->traceThreads(tids); + out->traceTargetDuration(initialTargetWorkDurationNanos); + out->tracePowerEfficient(false); + return out; } int64_t APerformanceHintManager::getPreferredRateNanos() const { @@ -174,6 +193,7 @@ APerformanceHintSession::APerformanceHintSession(sp<IHintManager> hintManager, ndk::enum_range<AidlSessionHint>().end()}; mLastHintSentTimestamp = std::vector<int64_t>(sessionHintRange.size(), 0); + mSessionName = android::base::StringPrintf("ADPF Session %" PRId32, ++sIDCounter); } APerformanceHintSession::~APerformanceHintSession() { @@ -200,17 +220,14 @@ int APerformanceHintSession::updateTargetWorkDuration(int64_t targetDurationNano * as they are most likely obsolete. */ mActualWorkDurations.clear(); + traceBatchSize(0); + traceTargetDuration(targetDurationNanos); mFirstTargetMetTimestamp = 0; mLastTargetMetTimestamp = 0; return 0; } int APerformanceHintSession::reportActualWorkDuration(int64_t actualDurationNanos) { - if (actualDurationNanos <= 0) { - ALOGE("%s: actualDurationNanos must be positive", __FUNCTION__); - return EINVAL; - } - WorkDuration workDuration(0, actualDurationNanos, actualDurationNanos, 0); return reportActualWorkDurationInternal(&workDuration); @@ -254,6 +271,9 @@ int APerformanceHintSession::setThreads(const int32_t* threadIds, size_t size) { } return EPIPE; } + + traceThreads(tids); + return 0; } @@ -289,28 +309,12 @@ int APerformanceHintSession::setPreferPowerEfficiency(bool enabled) { ret.exceptionMessage().c_str()); return EPIPE; } + tracePowerEfficient(enabled); return OK; } int APerformanceHintSession::reportActualWorkDuration(AWorkDuration* aWorkDuration) { WorkDuration* workDuration = static_cast<WorkDuration*>(aWorkDuration); - if (workDuration->workPeriodStartTimestampNanos <= 0) { - ALOGE("%s: workPeriodStartTimestampNanos must be positive", __FUNCTION__); - return EINVAL; - } - if (workDuration->actualTotalDurationNanos <= 0) { - ALOGE("%s: actualDurationNanos must be positive", __FUNCTION__); - return EINVAL; - } - if (workDuration->actualCpuDurationNanos <= 0) { - ALOGE("%s: cpuDurationNanos must be positive", __FUNCTION__); - return EINVAL; - } - if (workDuration->actualGpuDurationNanos < 0) { - ALOGE("%s: gpuDurationNanos must be non negative", __FUNCTION__); - return EINVAL; - } - return reportActualWorkDurationInternal(workDuration); } @@ -318,6 +322,7 @@ int APerformanceHintSession::reportActualWorkDurationInternal(WorkDuration* work int64_t actualTotalDurationNanos = workDuration->actualTotalDurationNanos; int64_t now = uptimeNanos(); workDuration->timestampNanos = now; + traceActualDuration(workDuration->actualTotalDurationNanos); mActualWorkDurations.push_back(std::move(*workDuration)); if (actualTotalDurationNanos >= mTargetDurationNanos) { @@ -335,6 +340,7 @@ int APerformanceHintSession::reportActualWorkDurationInternal(WorkDuration* work */ if (now - mFirstTargetMetTimestamp > mPreferredRateNanos && now - mLastTargetMetTimestamp <= mPreferredRateNanos) { + traceBatchSize(mActualWorkDurations.size()); return 0; } mLastTargetMetTimestamp = now; @@ -346,74 +352,142 @@ int APerformanceHintSession::reportActualWorkDurationInternal(WorkDuration* work ret.exceptionMessage().c_str()); mFirstTargetMetTimestamp = 0; mLastTargetMetTimestamp = 0; + traceBatchSize(mActualWorkDurations.size()); return ret.exceptionCode() == binder::Status::EX_ILLEGAL_ARGUMENT ? EINVAL : EPIPE; } mActualWorkDurations.clear(); + traceBatchSize(0); return 0; } +// ===================================== Tracing helpers + +void APerformanceHintSession::traceThreads(std::vector<int32_t>& tids) { + std::set<int32_t> tidSet{tids.begin(), tids.end()}; + + // Disable old TID tracing + for (int32_t tid : mLastThreadIDs) { + if (!tidSet.count(tid)) { + std::string traceName = + android::base::StringPrintf("%s TID: %" PRId32, mSessionName.c_str(), tid); + ATrace_setCounter(traceName.c_str(), 0); + } + } + + // Add new TID tracing + for (int32_t tid : tids) { + std::string traceName = + android::base::StringPrintf("%s TID: %" PRId32, mSessionName.c_str(), tid); + ATrace_setCounter(traceName.c_str(), 1); + } + + mLastThreadIDs = std::move(tids); +} + +void APerformanceHintSession::tracePowerEfficient(bool powerEfficient) { + ATrace_setCounter((mSessionName + " power efficiency mode").c_str(), powerEfficient); +} + +void APerformanceHintSession::traceActualDuration(int64_t actualDuration) { + ATrace_setCounter((mSessionName + " actual duration").c_str(), actualDuration); +} + +void APerformanceHintSession::traceBatchSize(size_t batchSize) { + std::string traceName = StringPrintf("%s batch size", mSessionName.c_str()); + ATrace_setCounter((mSessionName + " batch size").c_str(), batchSize); +} + +void APerformanceHintSession::traceTargetDuration(int64_t targetDuration) { + ATrace_setCounter((mSessionName + " target duration").c_str(), targetDuration); +} // ===================================== C API APerformanceHintManager* APerformanceHint_getManager() { return APerformanceHintManager::getInstance(); } +#define VALIDATE_PTR(ptr) \ + LOG_ALWAYS_FATAL_IF(ptr == nullptr, "%s: " #ptr " is nullptr", __FUNCTION__); + +#define VALIDATE_INT(value, cmp) \ + if (!(value cmp)) { \ + ALOGE("%s: Invalid value. Check failed: (" #value " " #cmp ") with value: %" PRIi64, \ + __FUNCTION__, value); \ + return EINVAL; \ + } + +#define WARN_INT(value, cmp) \ + if (!(value cmp)) { \ + ALOGE("%s: Invalid value. Check failed: (" #value " " #cmp ") with value: %" PRIi64, \ + __FUNCTION__, value); \ + } + APerformanceHintSession* APerformanceHint_createSession(APerformanceHintManager* manager, const int32_t* threadIds, size_t size, int64_t initialTargetWorkDurationNanos) { + VALIDATE_PTR(manager) + VALIDATE_PTR(threadIds) return manager->createSession(threadIds, size, initialTargetWorkDurationNanos); } int64_t APerformanceHint_getPreferredUpdateRateNanos(APerformanceHintManager* manager) { + VALIDATE_PTR(manager) return manager->getPreferredRateNanos(); } int APerformanceHint_updateTargetWorkDuration(APerformanceHintSession* session, int64_t targetDurationNanos) { + VALIDATE_PTR(session) return session->updateTargetWorkDuration(targetDurationNanos); } int APerformanceHint_reportActualWorkDuration(APerformanceHintSession* session, int64_t actualDurationNanos) { + VALIDATE_PTR(session) + VALIDATE_INT(actualDurationNanos, > 0) return session->reportActualWorkDuration(actualDurationNanos); } void APerformanceHint_closeSession(APerformanceHintSession* session) { + VALIDATE_PTR(session) delete session; } int APerformanceHint_sendHint(void* session, SessionHint hint) { + VALIDATE_PTR(session) return reinterpret_cast<APerformanceHintSession*>(session)->sendHint(hint); } int APerformanceHint_setThreads(APerformanceHintSession* session, const pid_t* threadIds, size_t size) { - if (session == nullptr) { - return EINVAL; - } + VALIDATE_PTR(session) + VALIDATE_PTR(threadIds) return session->setThreads(threadIds, size); } int APerformanceHint_getThreadIds(void* aPerformanceHintSession, int32_t* const threadIds, size_t* const size) { - if (aPerformanceHintSession == nullptr) { - return EINVAL; - } + VALIDATE_PTR(aPerformanceHintSession) return static_cast<APerformanceHintSession*>(aPerformanceHintSession) ->getThreadIds(threadIds, size); } int APerformanceHint_setPreferPowerEfficiency(APerformanceHintSession* session, bool enabled) { + VALIDATE_PTR(session) return session->setPreferPowerEfficiency(enabled); } int APerformanceHint_reportActualWorkDuration2(APerformanceHintSession* session, - AWorkDuration* workDuration) { - if (session == nullptr || workDuration == nullptr) { - ALOGE("Invalid value: (session %p, workDuration %p)", session, workDuration); - return EINVAL; - } - return session->reportActualWorkDuration(workDuration); + AWorkDuration* workDurationPtr) { + VALIDATE_PTR(session) + VALIDATE_PTR(workDurationPtr) + WorkDuration& workDuration = *static_cast<WorkDuration*>(workDurationPtr); + VALIDATE_INT(workDuration.workPeriodStartTimestampNanos, > 0) + VALIDATE_INT(workDuration.actualTotalDurationNanos, > 0) + VALIDATE_INT(workDuration.actualCpuDurationNanos, >= 0) + VALIDATE_INT(workDuration.actualGpuDurationNanos, >= 0) + VALIDATE_INT(workDuration.actualGpuDurationNanos + workDuration.actualCpuDurationNanos, > 0) + return session->reportActualWorkDuration(workDurationPtr); } AWorkDuration* AWorkDuration_create() { @@ -422,46 +496,36 @@ AWorkDuration* AWorkDuration_create() { } void AWorkDuration_release(AWorkDuration* aWorkDuration) { - if (aWorkDuration == nullptr) { - ALOGE("%s: aWorkDuration is nullptr", __FUNCTION__); - } + VALIDATE_PTR(aWorkDuration) delete aWorkDuration; } void AWorkDuration_setWorkPeriodStartTimestampNanos(AWorkDuration* aWorkDuration, int64_t workPeriodStartTimestampNanos) { - if (aWorkDuration == nullptr || workPeriodStartTimestampNanos <= 0) { - ALOGE("%s: Invalid value. (AWorkDuration: %p, workPeriodStartTimestampNanos: %" PRIi64 ")", - __FUNCTION__, aWorkDuration, workPeriodStartTimestampNanos); - } + VALIDATE_PTR(aWorkDuration) + WARN_INT(workPeriodStartTimestampNanos, > 0) static_cast<WorkDuration*>(aWorkDuration)->workPeriodStartTimestampNanos = workPeriodStartTimestampNanos; } void AWorkDuration_setActualTotalDurationNanos(AWorkDuration* aWorkDuration, int64_t actualTotalDurationNanos) { - if (aWorkDuration == nullptr || actualTotalDurationNanos <= 0) { - ALOGE("%s: Invalid value. (AWorkDuration: %p, actualTotalDurationNanos: %" PRIi64 ")", - __FUNCTION__, aWorkDuration, actualTotalDurationNanos); - } + VALIDATE_PTR(aWorkDuration) + WARN_INT(actualTotalDurationNanos, > 0) static_cast<WorkDuration*>(aWorkDuration)->actualTotalDurationNanos = actualTotalDurationNanos; } void AWorkDuration_setActualCpuDurationNanos(AWorkDuration* aWorkDuration, int64_t actualCpuDurationNanos) { - if (aWorkDuration == nullptr || actualCpuDurationNanos <= 0) { - ALOGE("%s: Invalid value. (AWorkDuration: %p, actualCpuDurationNanos: %" PRIi64 ")", - __FUNCTION__, aWorkDuration, actualCpuDurationNanos); - } + VALIDATE_PTR(aWorkDuration) + WARN_INT(actualCpuDurationNanos, >= 0) static_cast<WorkDuration*>(aWorkDuration)->actualCpuDurationNanos = actualCpuDurationNanos; } void AWorkDuration_setActualGpuDurationNanos(AWorkDuration* aWorkDuration, int64_t actualGpuDurationNanos) { - if (aWorkDuration == nullptr || actualGpuDurationNanos < 0) { - ALOGE("%s: Invalid value. (AWorkDuration: %p, actualGpuDurationNanos: %" PRIi64 ")", - __FUNCTION__, aWorkDuration, actualGpuDurationNanos); - } + VALIDATE_PTR(aWorkDuration) + WARN_INT(actualGpuDurationNanos, >= 0) static_cast<WorkDuration*>(aWorkDuration)->actualGpuDurationNanos = actualGpuDurationNanos; } diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp index 4b63fbf14d4c..9b1330fc048a 100644 --- a/native/android/surface_control.cpp +++ b/native/android/surface_control.cpp @@ -646,6 +646,24 @@ void ASurfaceTransaction_setExtendedRangeBrightness(ASurfaceTransaction* aSurfac transaction->setExtendedRangeBrightness(surfaceControl, currentBufferRatio, desiredRatio); } +void ASurfaceTransaction_setDesiredHdrHeadroom(ASurfaceTransaction* aSurfaceTransaction, + ASurfaceControl* aSurfaceControl, + float desiredRatio) { + CHECK_NOT_NULL(aSurfaceTransaction); + CHECK_NOT_NULL(aSurfaceControl); + + if (!isfinite(desiredRatio) || (desiredRatio < 1.0f && desiredRatio > 0.0f)) { + LOG_ALWAYS_FATAL("setDesiredHdrHeadroom, desiredRatio isn't finite && >= 1.0f or 0, got %f", + desiredRatio); + return; + } + + sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl); + Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction); + + transaction->setDesiredHdrHeadroom(surfaceControl, desiredRatio); +} + void ASurfaceTransaction_setColor(ASurfaceTransaction* aSurfaceTransaction, ASurfaceControl* aSurfaceControl, float r, float g, float b, float alpha, |