Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64734744 authored by Matt Buckley's avatar Matt Buckley Committed by Android (Google) Code Review
Browse files

Merge "Add plumbing for ADPF Power Efficiency hint" into main

parents eb40b6f0 423c1b36
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -33668,6 +33668,7 @@ package android.os {
  public static class PerformanceHintManager.Session implements java.io.Closeable {
    method public void close();
    method public void reportActualWorkDuration(long);
    method public void setPreferPowerEfficiency(boolean);
    method public void setThreads(@NonNull int[]);
    method public void updateTargetWorkDuration(long);
  }
+1 −0
Original line number Diff line number Diff line
@@ -23,4 +23,5 @@ oneway interface IHintSession {
    void reportActualWorkDuration(in long[] actualDurationNanos, in long[] timeStampNanos);
    void close();
    void sendHint(int hint);
    void setMode(int mode, boolean enabled);
}
+35 −27
Original line number Diff line number Diff line
@@ -50,6 +50,15 @@ public final class PerformanceHintManager {
        mNativeManagerPtr = nativeManagerPtr;
    }

    /**
     * Get preferred update rate information for this device.
     *
     * @return the preferred update rate supported by device software
     */
    public long getPreferredUpdateRateNanos() {
        return nativeGetPreferredUpdateRateNanos(mNativeManagerPtr);
    }

    /**
     * Creates a {@link Session} for the given set of threads and sets their initial target work
     * duration.
@@ -77,36 +86,23 @@ public final class PerformanceHintManager {
        return new Session(nativeSessionPtr);
    }

    /**
     * Get preferred update rate information for this device.
     *
     * @return the preferred update rate supported by device software
     */
    public long getPreferredUpdateRateNanos() {
        return nativeGetPreferredUpdateRateNanos(mNativeManagerPtr);
    }

    /**
     * A Session represents a group of threads with an inter-related workload such that hints for
     * their performance should be considered as a unit. The threads in a given session should be
     * long-life and not created or destroyed dynamically.
     *
     * <p>Each session is expected to have a periodic workload with a target duration for each
     * cycle. The cycle duration is likely greater than the target work duration to allow other
     * parts of the pipeline to run within the available budget. For example, a renderer thread may
     * work at 60hz in order to produce frames at the display's frame but have a target work
     * duration of only 6ms.</p>
     * long-lived and not created or destroyed dynamically.
     *
     * <p>Any call in this class will change its internal data, so you must do your own thread
     * safety to protect from racing.</p>
     * The work duration API can be used with periodic workloads to dynamically adjust thread
     * performance and keep the work on schedule while optimizing the available power budget.
     * When using the work duration API, the starting target duration should be specified
     * while creating the session, but can later be adjusted with
     * {@link #updateTargetWorkDuration(long)}. While using the work duration API, the client is be
     * expected to call {@link #reportActualWorkDuration(long)} each cycle to report the actual
     * time taken to complete to the system.
     *
     * <p>Note that the target work duration can be {@link #updateTargetWorkDuration(long) updated}
     * if workloads change.</p>
     * Any call in this class will change its internal data, so you must do your own thread
     * safety to protect from racing.
     *
     * <p>After each cycle of work, the client is expected to
     * {@link #reportActualWorkDuration(long) report} the actual time taken to complete.</p>
     *
     * <p>All timings should be in {@link SystemClock#elapsedRealtimeNanos()}.</p>
     * All timings should be in {@link SystemClock#elapsedRealtimeNanos()}.
     */
    public static class Session implements Closeable {
        private long mNativeSessionPtr;
@@ -186,9 +182,9 @@ public final class PerformanceHintManager {
        /**
         * Reports the actual duration for the last cycle of work.
         *
         * <p>The system will attempt to adjust the core placement of the threads within the thread
         * The system will attempt to adjust the core placement of the threads within the thread
         * group and/or the frequency of the core on which they are run to bring the actual duration
         * close to the target duration.</p>
         * close to the target duration.
         *
         * @param actualDurationNanos how long the thread group took to complete its last task in
         *     nanoseconds
@@ -202,7 +198,7 @@ public final class PerformanceHintManager {
        /**
         * Ends the current hint session.
         *
         * <p>Once called, you should not call anything else on this object.</p>
         * Once called, you should not call anything else on this object.
         */
        public void close() {
            if (mNativeSessionPtr != 0) {
@@ -229,6 +225,16 @@ public final class PerformanceHintManager {
            }
        }

        /**
         * This tells the session that these threads can be
         * safely scheduled to prefer power efficiency over performance.
         *
         * @param enabled The flag that sets whether this session uses power-efficient scheduling.
         */
        public void setPreferPowerEfficiency(boolean enabled) {
            nativeSetPreferPowerEfficiency(mNativeSessionPtr, enabled);
        }

        /**
         * Set a list of threads to the performance hint session. This operation will replace
         * the current list of threads with the given list of threads.
@@ -275,4 +281,6 @@ public final class PerformanceHintManager {
    private static native void nativeCloseSession(long nativeSessionPtr);
    private static native void nativeSendHint(long nativeSessionPtr, int hint);
    private static native void nativeSetThreads(long nativeSessionPtr, int[] tids);
    private static native void nativeSetPreferPowerEfficiency(long nativeSessionPtr,
            boolean enabled);
}
+24 −8
Original line number Diff line number Diff line
@@ -34,26 +34,28 @@ struct APerformanceHintManager;
struct APerformanceHintSession;

typedef APerformanceHintManager* (*APH_getManager)();
typedef int64_t (*APH_getPreferredUpdateRateNanos)(APerformanceHintManager* manager);
typedef APerformanceHintSession* (*APH_createSession)(APerformanceHintManager*, const int32_t*,
                                                      size_t, int64_t);
typedef int64_t (*APH_getPreferredUpdateRateNanos)(APerformanceHintManager* manager);
typedef void (*APH_updateTargetWorkDuration)(APerformanceHintSession*, int64_t);
typedef void (*APH_reportActualWorkDuration)(APerformanceHintSession*, int64_t);
typedef void (*APH_closeSession)(APerformanceHintSession* session);
typedef void (*APH_sendHint)(APerformanceHintSession*, int32_t);
typedef int (*APH_setThreads)(APerformanceHintSession*, const pid_t*, size_t);
typedef void (*APH_getThreadIds)(APerformanceHintSession*, int32_t* const, size_t* const);
typedef void (*APH_setPreferPowerEfficiency)(APerformanceHintSession*, bool);

bool gAPerformanceHintBindingInitialized = false;
APH_getManager gAPH_getManagerFn = nullptr;
APH_createSession gAPH_createSessionFn = nullptr;
APH_getPreferredUpdateRateNanos gAPH_getPreferredUpdateRateNanosFn = nullptr;
APH_createSession gAPH_createSessionFn = nullptr;
APH_updateTargetWorkDuration gAPH_updateTargetWorkDurationFn = nullptr;
APH_reportActualWorkDuration gAPH_reportActualWorkDurationFn = nullptr;
APH_closeSession gAPH_closeSessionFn = nullptr;
APH_sendHint gAPH_sendHintFn = nullptr;
APH_setThreads gAPH_setThreadsFn = nullptr;
APH_getThreadIds gAPH_getThreadIdsFn = nullptr;
APH_setPreferPowerEfficiency gAPH_setPreferPowerEfficiencyFn = nullptr;

void ensureAPerformanceHintBindingInitialized() {
    if (gAPerformanceHintBindingInitialized) return;
@@ -65,10 +67,6 @@ void ensureAPerformanceHintBindingInitialized() {
    LOG_ALWAYS_FATAL_IF(gAPH_getManagerFn == nullptr,
                        "Failed to find required symbol APerformanceHint_getManager!");

    gAPH_createSessionFn = (APH_createSession)dlsym(handle_, "APerformanceHint_createSession");
    LOG_ALWAYS_FATAL_IF(gAPH_createSessionFn == nullptr,
                        "Failed to find required symbol APerformanceHint_createSession!");

    gAPH_getPreferredUpdateRateNanosFn =
            (APH_getPreferredUpdateRateNanos)dlsym(handle_,
                                                   "APerformanceHint_getPreferredUpdateRateNanos");
@@ -76,6 +74,10 @@ void ensureAPerformanceHintBindingInitialized() {
                        "Failed to find required symbol "
                        "APerformanceHint_getPreferredUpdateRateNanos!");

    gAPH_createSessionFn = (APH_createSession)dlsym(handle_, "APerformanceHint_createSession");
    LOG_ALWAYS_FATAL_IF(gAPH_createSessionFn == nullptr,
                        "Failed to find required symbol APerformanceHint_createSession!");

    gAPH_updateTargetWorkDurationFn =
            (APH_updateTargetWorkDuration)dlsym(handle_,
                                                "APerformanceHint_updateTargetWorkDuration");
@@ -96,8 +98,7 @@ void ensureAPerformanceHintBindingInitialized() {

    gAPH_sendHintFn = (APH_sendHint)dlsym(handle_, "APerformanceHint_sendHint");
    LOG_ALWAYS_FATAL_IF(gAPH_sendHintFn == nullptr,
                        "Failed to find required symbol "
                        "APerformanceHint_sendHint!");
                        "Failed to find required symbol APerformanceHint_sendHint!");

    gAPH_setThreadsFn = (APH_setThreads)dlsym(handle_, "APerformanceHint_setThreads");
    LOG_ALWAYS_FATAL_IF(gAPH_setThreadsFn == nullptr,
@@ -107,6 +108,13 @@ void ensureAPerformanceHintBindingInitialized() {
    LOG_ALWAYS_FATAL_IF(gAPH_getThreadIdsFn == nullptr,
                        "Failed to find required symbol APerformanceHint_getThreadIds!");

    gAPH_setPreferPowerEfficiencyFn =
            (APH_setPreferPowerEfficiency)dlsym(handle_,
                                                "APerformanceHint_setPreferPowerEfficiency");
    LOG_ALWAYS_FATAL_IF(gAPH_setPreferPowerEfficiencyFn == nullptr,
                        "Failed to find required symbol"
                        "APerformanceHint_setPreferPowerEfficiency!");

    gAPerformanceHintBindingInitialized = true;
}

@@ -223,6 +231,13 @@ static jintArray nativeGetThreadIds(JNIEnv* env, jclass clazz, jlong nativeSessi
    return jintArr;
}

static void nativeSetPreferPowerEfficiency(JNIEnv* env, jclass clazz, jlong nativeSessionPtr,
                                           jboolean enabled) {
    ensureAPerformanceHintBindingInitialized();
    gAPH_setPreferPowerEfficiencyFn(reinterpret_cast<APerformanceHintSession*>(nativeSessionPtr),
                                    enabled);
}

static const JNINativeMethod gPerformanceHintMethods[] = {
        {"nativeAcquireManager", "()J", (void*)nativeAcquireManager},
        {"nativeGetPreferredUpdateRateNanos", "(J)J", (void*)nativeGetPreferredUpdateRateNanos},
@@ -233,6 +248,7 @@ static const JNINativeMethod gPerformanceHintMethods[] = {
        {"nativeSendHint", "(JI)V", (void*)nativeSendHint},
        {"nativeSetThreads", "(J[I)V", (void*)nativeSetThreads},
        {"nativeGetThreadIds", "(J)[I", (void*)nativeGetThreadIds},
        {"nativeSetPreferPowerEfficiency", "(JZ)V", (void*)nativeSetPreferPowerEfficiency},
};

int register_android_os_PerformanceHintManager(JNIEnv* env) {
+9 −0
Original line number Diff line number Diff line
@@ -173,4 +173,13 @@ public class PerformanceHintManagerTest {
            session.setThreads(new int[]{-1});
        });
    }

    @Test
    public void testSetPreferPowerEfficiency() {
        Session s = createSession();
        assumeNotNull(s);
        s.setPreferPowerEfficiency(false);
        s.setPreferPowerEfficiency(true);
        s.setPreferPowerEfficiency(true);
    }
}
Loading