summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Peiyong Lin <lpy@google.com> 2023-10-08 21:11:26 +0000
committer Peiyong Lin <lpy@google.com> 2023-11-10 21:12:56 +0000
commit31fab3e1ef4554cf3f9a708b514c3d5f2bc2d502 (patch)
tree694b7da670ccf0952c67ef403de6baa1d714eac5
parent6129c87ef1fa6b4bdf077b64f9ded30fcce95f74 (diff)
Add API support for GPU work duration report in ADPF.
Previously we introduced the reportActualWorkDuration API without specifying the work duration for each components, this patch introduces a separate API that allows clients to send work duration with each component to allow fine grained scheduling strategy. Bug: b/284324521 Test: atest PerformanceHintNativeTest Test: atest PerformanceHintManagerTest Change-Id: Ia2e66ae173255acee3f05fa99177659604976aa1
-rw-r--r--include/android/performance_hint.h126
-rw-r--r--services/powermanager/Android.bp1
-rw-r--r--services/powermanager/WorkDuration.cpp51
-rw-r--r--services/powermanager/include/android/WorkDuration.h71
-rw-r--r--services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp5
5 files changed, 242 insertions, 12 deletions
diff --git a/include/android/performance_hint.h b/include/android/performance_hint.h
index ba8b02d597..9d2c79139f 100644
--- a/include/android/performance_hint.h
+++ b/include/android/performance_hint.h
@@ -60,6 +60,27 @@ __BEGIN_DECLS
struct APerformanceHintManager;
struct APerformanceHintSession;
+struct AWorkDuration;
+
+/**
+ * {@link AWorkDuration} is an opaque type that represents the breakdown of the
+ * actual workload duration in each component internally.
+ *
+ * A new {@link AWorkDuration} can be obtained using
+ * {@link AWorkDuration_create()}, when the client finishes using
+ * {@link AWorkDuration}, {@link AWorkDuration_release()} must be
+ * called to destroy and free up the resources associated with
+ * {@link AWorkDuration}.
+ *
+ * This file provides a set of functions to allow clients to set the measured
+ * work duration of each component on {@link AWorkDuration}.
+ *
+ * - AWorkDuration_setWorkPeriodStartTimestampNanos()
+ * - AWorkDuration_setActualTotalDurationNanos()
+ * - AWorkDuration_setActualCpuDurationNanos()
+ * - AWorkDuration_setActualGpuDurationNanos()
+ */
+typedef struct AWorkDuration AWorkDuration;
/**
* An opaque type representing a handle to a performance hint manager.
@@ -102,7 +123,7 @@ typedef struct APerformanceHintSession APerformanceHintSession;
*
* @return APerformanceHintManager instance on success, nullptr on failure.
*/
-APerformanceHintManager* APerformanceHint_getManager() __INTRODUCED_IN(__ANDROID_API_T__);
+APerformanceHintManager* _Nullable APerformanceHint_getManager() __INTRODUCED_IN(__ANDROID_API_T__);
/**
* Creates a session for the given set of threads and sets their initial target work
@@ -116,9 +137,9 @@ APerformanceHintManager* APerformanceHint_getManager() __INTRODUCED_IN(__ANDROID
* This must be positive if using the work duration API, or 0 otherwise.
* @return APerformanceHintManager instance on success, nullptr on failure.
*/
-APerformanceHintSession* APerformanceHint_createSession(
- APerformanceHintManager* manager,
- const int32_t* threadIds, size_t size,
+APerformanceHintSession* _Nullable APerformanceHint_createSession(
+ APerformanceHintManager* _Nonnull manager,
+ const int32_t* _Nonnull threadIds, size_t size,
int64_t initialTargetWorkDurationNanos) __INTRODUCED_IN(__ANDROID_API_T__);
/**
@@ -128,7 +149,7 @@ APerformanceHintSession* APerformanceHint_createSession(
* @return the preferred update rate supported by device software.
*/
int64_t APerformanceHint_getPreferredUpdateRateNanos(
- APerformanceHintManager* manager) __INTRODUCED_IN(__ANDROID_API_T__);
+ APerformanceHintManager* _Nonnull manager) __INTRODUCED_IN(__ANDROID_API_T__);
/**
* Updates this session's target duration for each cycle of work.
@@ -140,7 +161,7 @@ int64_t APerformanceHint_getPreferredUpdateRateNanos(
* EPIPE if communication with the system service has failed.
*/
int APerformanceHint_updateTargetWorkDuration(
- APerformanceHintSession* session,
+ APerformanceHintSession* _Nonnull session,
int64_t targetDurationNanos) __INTRODUCED_IN(__ANDROID_API_T__);
/**
@@ -157,7 +178,7 @@ int APerformanceHint_updateTargetWorkDuration(
* EPIPE if communication with the system service has failed.
*/
int APerformanceHint_reportActualWorkDuration(
- APerformanceHintSession* session,
+ APerformanceHintSession* _Nonnull session,
int64_t actualDurationNanos) __INTRODUCED_IN(__ANDROID_API_T__);
/**
@@ -167,7 +188,7 @@ int APerformanceHint_reportActualWorkDuration(
* @param session The performance hint session instance to release.
*/
void APerformanceHint_closeSession(
- APerformanceHintSession* session) __INTRODUCED_IN(__ANDROID_API_T__);
+ APerformanceHintSession* _Nonnull session) __INTRODUCED_IN(__ANDROID_API_T__);
/**
* Set a list of threads to the performance hint session. This operation will replace
@@ -184,8 +205,8 @@ void APerformanceHint_closeSession(
* EPERM if any thread id doesn't belong to the application.
*/
int APerformanceHint_setThreads(
- APerformanceHintSession* session,
- const pid_t* threadIds,
+ APerformanceHintSession* _Nonnull session,
+ const pid_t* _Nonnull threadIds,
size_t size) __INTRODUCED_IN(__ANDROID_API_U__);
/**
@@ -198,11 +219,92 @@ int APerformanceHint_setThreads(
* EPIPE if communication with the system service has failed.
*/
int APerformanceHint_setPreferPowerEfficiency(
- APerformanceHintSession* session,
+ APerformanceHintSession* _Nonnull session,
bool enabled) __INTRODUCED_IN(__ANDROID_API_V__);
+/**
+ * Reports the durations for the last cycle of work.
+ *
+ * The system will attempt to adjust the scheduling and performance of the
+ * threads within the thread group to bring the actual duration close to the target duration.
+ *
+ * @param session The {@link APerformanceHintSession} instance to update.
+ * @param workDuration The {@link AWorkDuration} structure of times the thread group took to
+ * complete its last task in nanoseconds breaking down into different components.
+ *
+ * The work period start timestamp, actual total duration and actual CPU duration must be
+ * positive.
+ *
+ * The actual GPU duration must be non-negative. If the actual GPU duration is 0, it means
+ * the actual GPU duration is not measured.
+ *
+ * @return 0 on success.
+ * EINVAL if session is nullptr or any duration is an invalid number.
+ * EPIPE if communication with the system service has failed.
+ */
+int APerformanceHint_reportActualWorkDuration2(
+ APerformanceHintSession* _Nonnull session,
+ AWorkDuration* _Nonnull workDuration) __INTRODUCED_IN(__ANDROID_API_V__);
+
+/**
+ * Creates a new AWorkDuration. When the client finishes using {@link AWorkDuration}, it should
+ * call {@link AWorkDuration_release()} to destroy {@link AWorkDuration} and release all resources
+ * associated with it.
+ *
+ * @return AWorkDuration on success and nullptr otherwise.
+ */
+AWorkDuration* _Nonnull AWorkDuration_create() __INTRODUCED_IN(__ANDROID_API_V__);
+
+/**
+ * Destroys {@link AWorkDuration} and free all resources associated to it.
+ *
+ * @param aWorkDuration The {@link AWorkDuration} created by calling {@link AWorkDuration_create()}
+ */
+void AWorkDuration_release(AWorkDuration* _Nonnull WorkDuration) __INTRODUCED_IN(__ANDROID_API_V__);
+
+/**
+ * Sets the work period start timestamp in nanoseconds.
+ *
+ * @param aWorkDuration The {@link AWorkDuration} created by calling {@link AWorkDuration_create()}
+ * @param workPeriodStartTimestampNanos The work period start timestamp in nanoseconds based on
+ * CLOCK_MONOTONIC about when the work starts, the timestamp must be positive.
+ */
+void AWorkDuration_setWorkPeriodStartTimestampNanos(AWorkDuration* _Nonnull aWorkDuration,
+ int64_t workPeriodStartTimestampNanos) __INTRODUCED_IN(__ANDROID_API_V__);
+
+/**
+ * Sets the actual total work duration in nanoseconds.
+ *
+ * @param aWorkDuration The {@link AWorkDuration} created by calling {@link AWorkDuration_create()}
+ * @param actualTotalDurationNanos The actual total work duration in nanoseconds, the number must be
+ * positive.
+ */
+void AWorkDuration_setActualTotalDurationNanos(AWorkDuration* _Nonnull aWorkDuration,
+ int64_t actualTotalDurationNanos) __INTRODUCED_IN(__ANDROID_API_V__);
+
+/**
+ * Sets the actual CPU work duration in nanoseconds.
+ *
+ * @param aWorkDuration The {@link AWorkDuration} created by calling {@link AWorkDuration_create()}
+ * @param actualCpuDurationNanos The actual CPU work duration in nanoseconds, the number must be
+ * positive.
+ */
+void AWorkDuration_setActualCpuDurationNanos(AWorkDuration* _Nonnull aWorkDuration,
+ int64_t actualCpuDurationNanos) __INTRODUCED_IN(__ANDROID_API_V__);
+
+/**
+ * Sets the actual GPU work duration in nanoseconds.
+ *
+ * @param aWorkDuration The {@link AWorkDuration} created by calling {@link AWorkDuration_create()}.
+ * @param actualGpuDurationNanos The actual GPU work duration in nanoseconds, the number must be
+ * non-negative. If the actual GPU duration is 0, it means the actual GPU duration is
+ * measured.
+ */
+void AWorkDuration_setActualGpuDurationNanos(AWorkDuration* _Nonnull aWorkDuration,
+ int64_t actualGpuDurationNanos) __INTRODUCED_IN(__ANDROID_API_V__);
+
__END_DECLS
#endif // ANDROID_NATIVE_PERFORMANCE_HINT_H
-/** @} */ \ No newline at end of file
+/** @} */
diff --git a/services/powermanager/Android.bp b/services/powermanager/Android.bp
index 8b16890a45..1f72e8ba2c 100644
--- a/services/powermanager/Android.bp
+++ b/services/powermanager/Android.bp
@@ -19,6 +19,7 @@ cc_library_shared {
"PowerHalWrapper.cpp",
"PowerSaveState.cpp",
"Temperature.cpp",
+ "WorkDuration.cpp",
"WorkSource.cpp",
":libpowermanager_aidl",
],
diff --git a/services/powermanager/WorkDuration.cpp b/services/powermanager/WorkDuration.cpp
new file mode 100644
index 0000000000..ef723c229c
--- /dev/null
+++ b/services/powermanager/WorkDuration.cpp
@@ -0,0 +1,51 @@
+/**
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "WorkDuration"
+
+#include <android/WorkDuration.h>
+#include <android/performance_hint.h>
+#include <binder/Parcel.h>
+#include <utils/Log.h>
+
+namespace android::os {
+
+WorkDuration::WorkDuration(int64_t startTimestampNanos, int64_t totalDurationNanos,
+ int64_t cpuDurationNanos, int64_t gpuDurationNanos)
+ : workPeriodStartTimestampNanos(startTimestampNanos),
+ actualTotalDurationNanos(totalDurationNanos),
+ actualCpuDurationNanos(cpuDurationNanos),
+ actualGpuDurationNanos(gpuDurationNanos) {}
+
+status_t WorkDuration::writeToParcel(Parcel* parcel) const {
+ if (parcel == nullptr) {
+ ALOGE("%s: Null parcel", __func__);
+ return BAD_VALUE;
+ }
+
+ parcel->writeInt64(workPeriodStartTimestampNanos);
+ parcel->writeInt64(actualTotalDurationNanos);
+ parcel->writeInt64(actualCpuDurationNanos);
+ parcel->writeInt64(actualGpuDurationNanos);
+ parcel->writeInt64(timestampNanos);
+ return OK;
+}
+
+status_t WorkDuration::readFromParcel(const Parcel*) {
+ return INVALID_OPERATION;
+}
+
+} // namespace android::os
diff --git a/services/powermanager/include/android/WorkDuration.h b/services/powermanager/include/android/WorkDuration.h
new file mode 100644
index 0000000000..99b5b8b1b4
--- /dev/null
+++ b/services/powermanager/include/android/WorkDuration.h
@@ -0,0 +1,71 @@
+/**
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <binder/Parcelable.h>
+#include <math.h>
+
+struct AWorkDuration {};
+
+namespace android::os {
+
+/**
+ * C++ Parcelable version of {@link PerformanceHintManager.WorkDuration} that can be used in
+ * binder calls.
+ * This file needs to be kept in sync with the WorkDuration in
+ * frameworks/base/core/java/android/os/WorkDuration.java
+ */
+struct WorkDuration : AWorkDuration, android::Parcelable {
+ WorkDuration() = default;
+ ~WorkDuration() = default;
+
+ WorkDuration(int64_t workPeriodStartTimestampNanos, int64_t actualTotalDurationNanos,
+ int64_t actualCpuDurationNanos, int64_t actualGpuDurationNanos);
+ status_t writeToParcel(Parcel* parcel) const override;
+ status_t readFromParcel(const Parcel* parcel) override;
+
+ inline bool equalsWithoutTimestamp(const WorkDuration& other) const {
+ return workPeriodStartTimestampNanos == other.workPeriodStartTimestampNanos &&
+ actualTotalDurationNanos == other.actualTotalDurationNanos &&
+ actualCpuDurationNanos == other.actualCpuDurationNanos &&
+ actualGpuDurationNanos == other.actualGpuDurationNanos;
+ }
+
+ bool operator==(const WorkDuration& other) const {
+ return timestampNanos == other.timestampNanos && equalsWithoutTimestamp(other);
+ }
+
+ bool operator!=(const WorkDuration& other) const { return !(*this == other); }
+
+ friend std::ostream& operator<<(std::ostream& os, const WorkDuration& workDuration) {
+ os << "{"
+ << "workPeriodStartTimestampNanos: " << workDuration.workPeriodStartTimestampNanos
+ << ", actualTotalDurationNanos: " << workDuration.actualTotalDurationNanos
+ << ", actualCpuDurationNanos: " << workDuration.actualCpuDurationNanos
+ << ", actualGpuDurationNanos: " << workDuration.actualGpuDurationNanos
+ << ", timestampNanos: " << workDuration.timestampNanos << "}";
+ return os;
+ }
+
+ int64_t workPeriodStartTimestampNanos;
+ int64_t actualTotalDurationNanos;
+ int64_t actualCpuDurationNanos;
+ int64_t actualGpuDurationNanos;
+ int64_t timestampNanos;
+};
+
+} // namespace android::os
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
index f00ef671ad..e005ad3e03 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
@@ -251,7 +251,12 @@ void PowerAdvisor::reportActualWorkDuration() {
actualDuration = std::make_optional(*actualDuration + sTargetSafetyMargin);
mActualDuration = actualDuration;
WorkDuration duration;
+ duration.workPeriodStartTimestampNanos = mCommitStartTimes[0].ns();
+ // TODO(b/284324521): Correctly calculate total duration.
duration.durationNanos = actualDuration->ns();
+ duration.cpuDurationNanos = actualDuration->ns();
+ // TODO(b/284324521): Calculate RenderEngine GPU time.
+ duration.gpuDurationNanos = 0;
duration.timeStampNanos = TimePoint::now().ns();
mHintSessionQueue.push_back(duration);