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

Commit a7872c33 authored by Steven Thomas's avatar Steven Thomas Committed by Android (Google) Code Review
Browse files

Merge "Switch from allowed display configs to refresh rate range"

parents fb3ddfc4 a74a8643
Loading
Loading
Loading
Loading
+54 −41
Original line number Diff line number Diff line
@@ -158,11 +158,10 @@ public final class SurfaceControl implements Parcelable {
            IBinder displayToken, long numFrames, long timestamp);
    private static native int nativeGetActiveConfig(IBinder displayToken);
    private static native boolean nativeSetActiveConfig(IBinder displayToken, int id);
    private static native boolean nativeSetAllowedDisplayConfigs(IBinder displayToken,
                                                                 int[] allowedConfigs);
    private static native int[] nativeGetAllowedDisplayConfigs(IBinder displayToken);
    private static native boolean nativeSetDesiredDisplayConfigSpecs(IBinder displayToken,
            SurfaceControl.DesiredDisplayConfigSpecs desiredDisplayConfigSpecs);
    private static native SurfaceControl.DesiredDisplayConfigSpecs
            nativeGetDesiredDisplayConfigSpecs(IBinder displayToken);
    private static native int[] nativeGetDisplayColorModes(IBinder displayToken);
    private static native SurfaceControl.DisplayPrimaries nativeGetDisplayNativePrimaries(
            IBinder displayToken);
@@ -1474,71 +1473,85 @@ public final class SurfaceControl implements Parcelable {
    }

    /**
     * Contains information about desired display configuration.
     *
     * @hide
     */
    public static boolean setAllowedDisplayConfigs(IBinder displayToken, int[] allowedConfigs) {
        if (displayToken == null) {
            throw new IllegalArgumentException("displayToken must not be null");
    public static final class DesiredDisplayConfigSpecs {
        public int defaultConfig;
        public float minRefreshRate;
        public float maxRefreshRate;

        public DesiredDisplayConfigSpecs() {}

        public DesiredDisplayConfigSpecs(DesiredDisplayConfigSpecs other) {
            copyFrom(other);
        }
        if (allowedConfigs == null) {
            throw new IllegalArgumentException("allowedConfigs must not be null");

        public DesiredDisplayConfigSpecs(
                int defaultConfig, float minRefreshRate, float maxRefreshRate) {
            this.defaultConfig = defaultConfig;
            this.minRefreshRate = minRefreshRate;
            this.maxRefreshRate = maxRefreshRate;
        }

        return nativeSetAllowedDisplayConfigs(displayToken, allowedConfigs);
        @Override
        public boolean equals(Object o) {
            return o instanceof DesiredDisplayConfigSpecs && equals((DesiredDisplayConfigSpecs) o);
        }

        /**
     * @hide
         * Tests for equality.
         */
    public static int[] getAllowedDisplayConfigs(IBinder displayToken) {
        if (displayToken == null) {
            throw new IllegalArgumentException("displayToken must not be null");
        }
        return nativeGetAllowedDisplayConfigs(displayToken);
        public boolean equals(DesiredDisplayConfigSpecs other) {
            return other != null && defaultConfig == other.defaultConfig
                    && minRefreshRate == other.minRefreshRate
                    && maxRefreshRate == other.maxRefreshRate;
        }

    /**
     * Contains information about desired display configuration.
     *
     * @hide
     */
    public static final class DesiredDisplayConfigSpecs {
        /**
         * @hide
         */
        public int mDefaultModeId;
        @Override
        public int hashCode() {
            return 0; // don't care
        }

        /**
         * @hide
         * Copies the supplied object's values to this object.
         */
        public float mMinRefreshRate;
        public void copyFrom(DesiredDisplayConfigSpecs other) {
            defaultConfig = other.defaultConfig;
            minRefreshRate = other.minRefreshRate;
            maxRefreshRate = other.maxRefreshRate;
        }

        /**
         * @hide
         */
        public float mMaxRefreshRate;
        @Override
        public String toString() {
            return String.format("defaultConfig=%d min=%.0f max=%.0f", defaultConfig,
                    minRefreshRate, maxRefreshRate);
        }
    }

    /**
     * @hide
     */
        public DesiredDisplayConfigSpecs(
                int defaultModeId, float minRefreshRate, float maxRefreshRate) {
            mDefaultModeId = defaultModeId;
            mMinRefreshRate = minRefreshRate;
            mMaxRefreshRate = maxRefreshRate;
    public static boolean setDesiredDisplayConfigSpecs(IBinder displayToken,
            SurfaceControl.DesiredDisplayConfigSpecs desiredDisplayConfigSpecs) {
        if (displayToken == null) {
            throw new IllegalArgumentException("displayToken must not be null");
        }

        return nativeSetDesiredDisplayConfigSpecs(displayToken, desiredDisplayConfigSpecs);
    }

    /**
     * @hide
     */
    public static boolean setDesiredDisplayConfigSpecs(IBinder displayToken,
            SurfaceControl.DesiredDisplayConfigSpecs desiredDisplayConfigSpecs) {
    public static SurfaceControl.DesiredDisplayConfigSpecs getDesiredDisplayConfigSpecs(
            IBinder displayToken) {
        if (displayToken == null) {
            throw new IllegalArgumentException("displayToken must not be null");
        }

        return nativeSetDesiredDisplayConfigSpecs(displayToken, desiredDisplayConfigSpecs);
        return nativeGetDesiredDisplayConfigSpecs(displayToken);
    }

    /**
+28 −54
Original line number Diff line number Diff line
@@ -141,7 +141,7 @@ static struct {
static struct {
    jclass clazz;
    jmethodID ctor;
    jfieldID defaultModeId;
    jfieldID defaultConfig;
    jfieldID minRefreshRate;
    jfieldID maxRefreshRate;
} gDesiredDisplayConfigSpecsClassInfo;
@@ -776,65 +776,40 @@ static jobjectArray nativeGetDisplayConfigs(JNIEnv* env, jclass clazz,
    return configArray;
}

static jboolean nativeSetAllowedDisplayConfigs(JNIEnv* env, jclass clazz,
        jobject tokenObj, jintArray configArray) {
    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
    if (token == nullptr) return JNI_FALSE;

    std::vector<int32_t> allowedConfigs;
    jsize configArraySize = env->GetArrayLength(configArray);
    allowedConfigs.reserve(configArraySize);

    jint* configArrayElements = env->GetIntArrayElements(configArray, 0);
    for (int i = 0; i < configArraySize; i++) {
        allowedConfigs.push_back(configArrayElements[i]);
    }
    env->ReleaseIntArrayElements(configArray, configArrayElements, 0);

    size_t result = SurfaceComposerClient::setAllowedDisplayConfigs(token, allowedConfigs);
    return result == NO_ERROR ? JNI_TRUE : JNI_FALSE;
}

static jintArray nativeGetAllowedDisplayConfigs(JNIEnv* env, jclass clazz, jobject tokenObj) {
    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
    if (token == nullptr) return JNI_FALSE;

    std::vector<int32_t> allowedConfigs;
    size_t result = SurfaceComposerClient::getAllowedDisplayConfigs(token, &allowedConfigs);
    if (result != NO_ERROR) {
        return nullptr;
    }

    jintArray allowedConfigsArray = env->NewIntArray(allowedConfigs.size());
    if (allowedConfigsArray == nullptr) {
        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
        return nullptr;
    }
    jint* allowedConfigsArrayValues = env->GetIntArrayElements(allowedConfigsArray, 0);
    for (size_t i = 0; i < allowedConfigs.size(); i++) {
        allowedConfigsArrayValues[i] = static_cast<jint>(allowedConfigs[i]);
    }
    env->ReleaseIntArrayElements(allowedConfigsArray, allowedConfigsArrayValues, 0);
    return allowedConfigsArray;
}

static jboolean nativeSetDesiredDisplayConfigSpecs(JNIEnv* env, jclass clazz, jobject tokenObj,
                                                   jobject desiredDisplayConfigSpecs) {
    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
    if (token == nullptr) return JNI_FALSE;

    jint defaultModeId = env->GetIntField(desiredDisplayConfigSpecs,
                                          gDesiredDisplayConfigSpecsClassInfo.defaultModeId);
    jint defaultConfig = env->GetIntField(desiredDisplayConfigSpecs,
                                          gDesiredDisplayConfigSpecsClassInfo.defaultConfig);
    jfloat minRefreshRate = env->GetFloatField(desiredDisplayConfigSpecs,
                                               gDesiredDisplayConfigSpecsClassInfo.minRefreshRate);
    jfloat maxRefreshRate = env->GetFloatField(desiredDisplayConfigSpecs,
                                               gDesiredDisplayConfigSpecsClassInfo.maxRefreshRate);

    size_t result = SurfaceComposerClient::setDesiredDisplayConfigSpecs(
            token, defaultModeId, minRefreshRate, maxRefreshRate);
            token, defaultConfig, minRefreshRate, maxRefreshRate);
    return result == NO_ERROR ? JNI_TRUE : JNI_FALSE;
}

static jobject nativeGetDesiredDisplayConfigSpecs(JNIEnv* env, jclass clazz, jobject tokenObj) {
    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
    if (token == nullptr) return nullptr;

    int32_t defaultConfig;
    float minRefreshRate;
    float maxRefreshRate;
    if (SurfaceComposerClient::getDesiredDisplayConfigSpecs(token, &defaultConfig, &minRefreshRate,
                                                            &maxRefreshRate) != NO_ERROR) {
        return nullptr;
    }

    return env->NewObject(gDesiredDisplayConfigSpecsClassInfo.clazz,
                          gDesiredDisplayConfigSpecsClassInfo.ctor, defaultConfig, minRefreshRate,
                          maxRefreshRate);
}

static jint nativeGetActiveConfig(JNIEnv* env, jclass clazz, jobject tokenObj) {
    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
    if (token == NULL) return -1;
@@ -1387,13 +1362,12 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
            (void*)nativeGetActiveConfig },
    {"nativeSetActiveConfig", "(Landroid/os/IBinder;I)Z",
            (void*)nativeSetActiveConfig },
    {"nativeSetAllowedDisplayConfigs", "(Landroid/os/IBinder;[I)Z",
            (void*)nativeSetAllowedDisplayConfigs },
    {"nativeGetAllowedDisplayConfigs", "(Landroid/os/IBinder;)[I",
            (void*)nativeGetAllowedDisplayConfigs },
    {"nativeSetDesiredDisplayConfigSpecs",
            "(Landroid/os/IBinder;Landroid/view/SurfaceControl$DesiredDisplayConfigSpecs;)Z",
            (void*)nativeSetDesiredDisplayConfigSpecs },
    {"nativeGetDesiredDisplayConfigSpecs",
            "(Landroid/os/IBinder;)Landroid/view/SurfaceControl$DesiredDisplayConfigSpecs;",
            (void*)nativeGetDesiredDisplayConfigSpecs },
    {"nativeGetDisplayColorModes", "(Landroid/os/IBinder;)[I",
            (void*)nativeGetDisplayColorModes},
    {"nativeGetDisplayNativePrimaries", "(Landroid/os/IBinder;)Landroid/view/SurfaceControl$DisplayPrimaries;",
@@ -1569,12 +1543,12 @@ int register_android_view_SurfaceControl(JNIEnv* env)
            MakeGlobalRefOrDie(env, desiredDisplayConfigSpecsClazz);
    gDesiredDisplayConfigSpecsClassInfo.ctor =
            GetMethodIDOrDie(env, gDesiredDisplayConfigSpecsClassInfo.clazz, "<init>", "(IFF)V");
    gDesiredDisplayConfigSpecsClassInfo.defaultModeId =
            GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "mDefaultModeId", "I");
    gDesiredDisplayConfigSpecsClassInfo.defaultConfig =
            GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "defaultConfig", "I");
    gDesiredDisplayConfigSpecsClassInfo.minRefreshRate =
            GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "mMinRefreshRate", "F");
            GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "minRefreshRate", "F");
    gDesiredDisplayConfigSpecsClassInfo.maxRefreshRate =
            GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "mMaxRefreshRate", "F");
            GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "maxRefreshRate", "F");

    return err;
}
+4 −9
Original line number Diff line number Diff line
@@ -138,18 +138,13 @@ abstract class DisplayDevice {
    }

    /**
     * Sets the refresh ranges, and display modes that the system is allowed to switch between.
     * Display modes are roughly ordered by preference.
     * Sets the display mode specs.
     *
     * Not all display devices will automatically switch between modes, so it's important that the
     * most-desired modes are at the beginning of the allowed array.
     *
     * @param defaultModeId is used, if the device does not support multiple refresh
     * rates, and to navigate other parameters.
     * default modeId is set correctly.
     */
    public void setDesiredDisplayConfigSpecs(int defaultModeId, float minRefreshRate,
            float maxRefreshRate, int[] modes) {
    }
    public void setDesiredDisplayModeSpecsLocked(
            DisplayModeDirector.DesiredDisplayModeSpecs displayModeSpecs) {}

    /**
     * Sets the requested color mode.
+18 −11
Original line number Diff line number Diff line
@@ -431,7 +431,8 @@ public final class DisplayManagerService extends SystemService {
            recordTopInsetLocked(mLogicalDisplays.get(Display.DEFAULT_DISPLAY));
        }

        mDisplayModeDirector.setDisplayModeListener(new AllowedDisplayModeObserver());
        mDisplayModeDirector.setDesiredDisplayModeSpecsListener(
                new DesiredDisplayModeSpecsObserver());
        mDisplayModeDirector.start(mSensorManager);

        mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
@@ -1327,19 +1328,24 @@ public final class DisplayManagerService extends SystemService {
        return SurfaceControl.getDisplayedContentSample(token, maxFrames, timestamp);
    }

    private void onAllowedDisplayModesChangedInternal() {
    private void onDesiredDisplayModeSpecsChangedInternal() {
        boolean changed = false;
        synchronized (mSyncRoot) {
            final int count = mLogicalDisplays.size();
            for (int i = 0; i < count; i++) {
                LogicalDisplay display = mLogicalDisplays.valueAt(i);
                int displayId = mLogicalDisplays.keyAt(i);
                int[] allowedModes = mDisplayModeDirector.getAllowedModes(displayId);
                // Note that order is important here since not all display devices are capable of
                // automatically switching, so we do actually want to check for equality and not
                // just equivalent contents (regardless of order).
                if (!Arrays.equals(allowedModes, display.getAllowedDisplayModesLocked())) {
                    display.setAllowedDisplayModesLocked(allowedModes);
                DisplayModeDirector.DesiredDisplayModeSpecs desiredDisplayModeSpecs =
                        mDisplayModeDirector.getDesiredDisplayModeSpecs(displayId);
                DisplayModeDirector.DesiredDisplayModeSpecs existingDesiredDisplayModeSpecs =
                        display.getDesiredDisplayModeSpecsLocked();
                if (DEBUG) {
                    Slog.i(TAG,
                            "Comparing display specs: " + desiredDisplayModeSpecs
                                    + ", existing: " + existingDesiredDisplayModeSpecs);
                }
                if (!desiredDisplayModeSpecs.equals(existingDesiredDisplayModeSpecs)) {
                    display.setDesiredDisplayModeSpecsLocked(desiredDisplayModeSpecs);
                    changed = true;
                }
            }
@@ -2488,9 +2494,10 @@ public final class DisplayManagerService extends SystemService {

    }

    class AllowedDisplayModeObserver implements DisplayModeDirector.DisplayModeListener {
        public void onAllowedDisplayModesChanged() {
            onAllowedDisplayModesChangedInternal();
    class DesiredDisplayModeSpecsObserver
            implements DisplayModeDirector.DesiredDisplayModeSpecsListener {
        public void onDesiredDisplayModeSpecsChanged() {
            onDesiredDisplayModeSpecsChangedInternal();
        }
    }
}
+69 −67

File changed.

Preview size limit exceeded, changes collapsed.

Loading