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

Commit eb994d9a authored by Ady Abraham's avatar Ady Abraham
Browse files

Handle the render frame rate from SF

SurfaceFlinger render rate might be a divisor of the display
physical refresh rate. Plumb this throught DisplayManager and return
that value when apps call Display#getRefreshRate

Test: atest FrameRateOverrideHostTest
Test: atest LocalDisplayAdapterTest
Test: atest DisplayManagerServiceTest
Bug: 259740021
Change-Id: I1a6925f112bc982371aafe31deb56f2430801fac
parent e3b11bea
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -227,8 +227,10 @@ public abstract class DisplayEventReceiver {
     * timebase.
     * @param physicalDisplayId Stable display ID that uniquely describes a (display, port) pair.
     * @param modeId The new mode Id
     * @param renderPeriod The render frame period, which is a multiple of the mode's vsync period
     */
    public void onModeChanged(long timestampNanos, long physicalDisplayId, int modeId) {
    public void onModeChanged(long timestampNanos, long physicalDisplayId, int modeId,
            long renderPeriod) {
    }

    /**
@@ -303,8 +305,9 @@ public abstract class DisplayEventReceiver {

    // Called from native code.
    @SuppressWarnings("unused")
    private void dispatchModeChanged(long timestampNanos, long physicalDisplayId, int modeId) {
        onModeChanged(timestampNanos, physicalDisplayId, modeId);
    private void dispatchModeChanged(long timestampNanos, long physicalDisplayId, int modeId,
            long renderPeriod) {
        onModeChanged(timestampNanos, physicalDisplayId, modeId, renderPeriod);
    }

    // Called from native code.
+15 −0
Original line number Diff line number Diff line
@@ -179,6 +179,16 @@ public final class DisplayInfo implements Parcelable {
     */
    public int modeId;

    /**
     * The render frame rate this display is scheduled at, which is a divisor of the active mode
     * refresh rate. This is the rate SurfaceFlinger would consume frames and would be observable
     * by applications via the cadence of {@link android.view.Choreographer} callbacks and
     * by backpressure when submitting buffers as fast as possible.
     * Apps can call {@link android.view.Display#getRefreshRate} to query this value.
     *
     */
    public float renderFrameRate;

    /**
     * The default display mode.
     */
@@ -376,6 +386,7 @@ public final class DisplayInfo implements Parcelable {
                && Objects.equals(displayCutout, other.displayCutout)
                && rotation == other.rotation
                && modeId == other.modeId
                && renderFrameRate == other.renderFrameRate
                && defaultModeId == other.defaultModeId
                && Arrays.equals(supportedModes, other.supportedModes)
                && colorMode == other.colorMode
@@ -428,6 +439,7 @@ public final class DisplayInfo implements Parcelable {
        displayCutout = other.displayCutout;
        rotation = other.rotation;
        modeId = other.modeId;
        renderFrameRate = other.renderFrameRate;
        defaultModeId = other.defaultModeId;
        supportedModes = Arrays.copyOf(other.supportedModes, other.supportedModes.length);
        colorMode = other.colorMode;
@@ -475,6 +487,7 @@ public final class DisplayInfo implements Parcelable {
        displayCutout = DisplayCutout.ParcelableWrapper.readCutoutFromParcel(source);
        rotation = source.readInt();
        modeId = source.readInt();
        renderFrameRate = source.readFloat();
        defaultModeId = source.readInt();
        int nModes = source.readInt();
        supportedModes = new Display.Mode[nModes];
@@ -535,6 +548,7 @@ public final class DisplayInfo implements Parcelable {
        DisplayCutout.ParcelableWrapper.writeCutoutToParcel(displayCutout, dest, flags);
        dest.writeInt(rotation);
        dest.writeInt(modeId);
        dest.writeFloat(renderFrameRate);
        dest.writeInt(defaultModeId);
        dest.writeInt(supportedModes.length);
        for (int i = 0; i < supportedModes.length; i++) {
@@ -764,6 +778,7 @@ public final class DisplayInfo implements Parcelable {
        sb.append(presentationDeadlineNanos);
        sb.append(", mode ");
        sb.append(modeId);
        sb.append(renderFrameRate);
        sb.append(", defaultMode ");
        sb.append(defaultModeId);
        sb.append(", modes ");
+4 −1
Original line number Diff line number Diff line
@@ -1504,6 +1504,7 @@ public final class SurfaceControl implements Parcelable {
    public static final class DynamicDisplayInfo {
        public DisplayMode[] supportedDisplayModes;
        public int activeDisplayModeId;
        public float renderFrameRate;

        public int[] supportedColorModes;
        public int activeColorMode;
@@ -1520,6 +1521,7 @@ public final class SurfaceControl implements Parcelable {
            return "DynamicDisplayInfo{"
                    + "supportedDisplayModes=" + Arrays.toString(supportedDisplayModes)
                    + ", activeDisplayModeId=" + activeDisplayModeId
                    + ", renderFrameRate=" + renderFrameRate
                    + ", supportedColorModes=" + Arrays.toString(supportedColorModes)
                    + ", activeColorMode=" + activeColorMode
                    + ", hdrCapabilities=" + hdrCapabilities
@@ -1535,6 +1537,7 @@ public final class SurfaceControl implements Parcelable {
            DynamicDisplayInfo that = (DynamicDisplayInfo) o;
            return Arrays.equals(supportedDisplayModes, that.supportedDisplayModes)
                && activeDisplayModeId == that.activeDisplayModeId
                && renderFrameRate == that.renderFrameRate
                && Arrays.equals(supportedColorModes, that.supportedColorModes)
                && activeColorMode == that.activeColorMode
                && Objects.equals(hdrCapabilities, that.hdrCapabilities)
@@ -1544,7 +1547,7 @@ public final class SurfaceControl implements Parcelable {
        @Override
        public int hashCode() {
            return Objects.hash(Arrays.hashCode(supportedDisplayModes), activeDisplayModeId,
                    activeColorMode, hdrCapabilities);
                    renderFrameRate, activeColorMode, hdrCapabilities);
        }
    }

+4 −4
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ private:
                       VsyncEventData vsyncEventData) override;
    void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) override;
    void dispatchModeChanged(nsecs_t timestamp, PhysicalDisplayId displayId, int32_t modeId,
                             nsecs_t vsyncPeriod) override;
                             nsecs_t renderPeriod) override;
    void dispatchFrameRateOverrides(nsecs_t timestamp, PhysicalDisplayId displayId,
                                    std::vector<FrameRateOverride> overrides) override;
    void dispatchNullEvent(nsecs_t timestamp, PhysicalDisplayId displayId) override {}
@@ -168,14 +168,14 @@ void NativeDisplayEventReceiver::dispatchHotplug(nsecs_t timestamp, PhysicalDisp
}

void NativeDisplayEventReceiver::dispatchModeChanged(nsecs_t timestamp, PhysicalDisplayId displayId,
                                                     int32_t modeId, nsecs_t) {
                                                     int32_t modeId, nsecs_t renderPeriod) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();

    ScopedLocalRef<jobject> receiverObj(env, GetReferent(env, mReceiverWeakGlobal));
    if (receiverObj.get()) {
        ALOGV("receiver %p ~ Invoking mode changed handler.", this);
        env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchModeChanged,
                            timestamp, displayId.value, modeId);
                            timestamp, displayId.value, modeId, renderPeriod);
        ALOGV("receiver %p ~ Returned from mode changed handler.", this);
    }

@@ -290,7 +290,7 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) {
            gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JJZ)V");
    gDisplayEventReceiverClassInfo.dispatchModeChanged =
            GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchModeChanged",
                             "(JJI)V");
                             "(JJIJ)V");
    gDisplayEventReceiverClassInfo.dispatchFrameRateOverrides =
            GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz,
                             "dispatchFrameRateOverrides",
+4 −0
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ static struct {
    jmethodID ctor;
    jfieldID supportedDisplayModes;
    jfieldID activeDisplayModeId;
    jfieldID renderFrameRate;
    jfieldID supportedColorModes;
    jfieldID activeColorMode;
    jfieldID hdrCapabilities;
@@ -1184,6 +1185,7 @@ static jobject nativeGetDynamicDisplayInfo(JNIEnv* env, jclass clazz, jobject to
    env->SetObjectField(object, gDynamicDisplayInfoClassInfo.supportedDisplayModes, modesArray);
    env->SetIntField(object, gDynamicDisplayInfoClassInfo.activeDisplayModeId,
                     info.activeDisplayModeId);
    env->SetFloatField(object, gDynamicDisplayInfoClassInfo.renderFrameRate, info.renderFrameRate);

    jintArray colorModesArray = env->NewIntArray(info.supportedColorModes.size());
    if (colorModesArray == NULL) {
@@ -2174,6 +2176,8 @@ int register_android_view_SurfaceControl(JNIEnv* env)
                            "[Landroid/view/SurfaceControl$DisplayMode;");
    gDynamicDisplayInfoClassInfo.activeDisplayModeId =
            GetFieldIDOrDie(env, dynamicInfoClazz, "activeDisplayModeId", "I");
    gDynamicDisplayInfoClassInfo.renderFrameRate =
            GetFieldIDOrDie(env, dynamicInfoClazz, "renderFrameRate", "F");
    gDynamicDisplayInfoClassInfo.supportedColorModes =
            GetFieldIDOrDie(env, dynamicInfoClazz, "supportedColorModes", "[I");
    gDynamicDisplayInfoClassInfo.activeColorMode =
Loading