summaryrefslogtreecommitdiff
path: root/native
diff options
context:
space:
mode:
Diffstat (limited to 'native')
-rw-r--r--native/android/input.cpp21
-rw-r--r--native/android/libandroid.map.txt2
-rw-r--r--native/android/performance_hint.cpp174
-rw-r--r--native/android/surface_control.cpp18
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,