diff options
author | 2023-10-08 21:11:26 +0000 | |
---|---|---|
committer | 2023-11-10 21:12:56 +0000 | |
commit | 31fab3e1ef4554cf3f9a708b514c3d5f2bc2d502 (patch) | |
tree | 694b7da670ccf0952c67ef403de6baa1d714eac5 | |
parent | 6129c87ef1fa6b4bdf077b64f9ded30fcce95f74 (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.h | 126 | ||||
-rw-r--r-- | services/powermanager/Android.bp | 1 | ||||
-rw-r--r-- | services/powermanager/WorkDuration.cpp | 51 | ||||
-rw-r--r-- | services/powermanager/include/android/WorkDuration.h | 71 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp | 5 |
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); |