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

Commit 1039cff4 authored by Ram Indani's avatar Ram Indani Committed by Android (Google) Code Review
Browse files

Merge "DM: Source supported refresh rates on mode and frame rate override change" into main

parents 1caf1f7a 5b72f90e
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -321,11 +321,13 @@ public abstract class DisplayEventReceiver {
     *                             from the target vsync, if target vsync is N then the frame
     *                             should be ready by N - presentationDeadlineNanos.
     * @param overrides The mappings from uid to frame rates
     * @param supportedRefreshRates The list of refresh rates supported on the display
     */
    public void onModeAndFrameRateOverridesChanged(long timestampNanos,
            long physicalDisplayId,  int modeId,  long renderPeriod,
            long appVsyncOffsetNanos,
            long presentationDeadlineNanos, FrameRateOverride[] overrides) {
            long presentationDeadlineNanos, FrameRateOverride[] overrides,
            float[] supportedRefreshRates) {
    }

    /**
@@ -433,9 +435,11 @@ public abstract class DisplayEventReceiver {
    @SuppressWarnings("unused")
    private void dispatchModeChangedWithFrameRateOverrides(long timestampNanos,
            long physicalDisplayId, int modeId, long renderPeriod, long appVsyncOffsetNanos,
            long presentationDeadlineNanos, FrameRateOverride[] overrides) {
            long presentationDeadlineNanos, FrameRateOverride[] overrides,
            float[] supportedRefreshRates) {
        onModeAndFrameRateOverridesChanged(timestampNanos, physicalDisplayId, modeId,
                renderPeriod, appVsyncOffsetNanos, presentationDeadlineNanos, overrides);
                renderPeriod, appVsyncOffsetNanos, presentationDeadlineNanos, overrides,
                supportedRefreshRates);
    }

    // Called from native code.
+19 −4
Original line number Diff line number Diff line
@@ -92,6 +92,18 @@ jobjectArray getFrameRateOverrides(std::vector<FrameRateOverride> overrides, JNI
    return frameRateOverrideArray;
}

jfloatArray getSupportedRefreshRates(std::vector<SupportedRefreshRate> supportedRefreshRates,
                                     JNIEnv* env) {
    jfloatArray floatArray = env->NewFloatArray(supportedRefreshRates.size());
    std::vector<jfloat> refreshRates(supportedRefreshRates.size());

    for (size_t i = 0; i < supportedRefreshRates.size(); i++) {
        refreshRates[i] = supportedRefreshRates[i].refreshRate;
    }
    env->SetFloatArrayRegion(floatArray, 0, supportedRefreshRates.size(), refreshRates.data());
    return floatArray;
}

class NativeDisplayEventReceiver : public DisplayEventDispatcher {
public:
    NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, jobject vsyncEventDataWeak,
@@ -115,7 +127,8 @@ private:
    void dispatchModeChangedWithFrameRateOverrides(
            nsecs_t timestamp, PhysicalDisplayId displayId, int32_t modeId, nsecs_t renderPeriod,
            nsecs_t appVsyncOffset, nsecs_t presentationDeadline,
            std::vector<FrameRateOverride> overrides) override;
            std::vector<FrameRateOverride> overrides,
            std::vector<SupportedRefreshRate> supportedRefreshRates) override;
    void dispatchModeChanged(nsecs_t timestamp, PhysicalDisplayId displayId, int32_t modeId,
                             nsecs_t renderPeriod, nsecs_t appVsyncOffset,
                             nsecs_t presentationDeadline) override;
@@ -302,17 +315,19 @@ void NativeDisplayEventReceiver::dispatchModeChanged(nsecs_t timestamp, Physical
void NativeDisplayEventReceiver::dispatchModeChangedWithFrameRateOverrides(
        nsecs_t timestamp, PhysicalDisplayId displayId, int32_t modeId, nsecs_t renderPeriod,
        nsecs_t appVsyncOffset, nsecs_t presentationDeadline,
        std::vector<FrameRateOverride> overrides) {
        std::vector<FrameRateOverride> overrides, std::vector<SupportedRefreshRate> refreshRates) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    ScopedLocalRef<jobject> receiverObj(env, GetReferent(env, mReceiverWeakGlobal));
    if (receiverObj.get()) {
        ALOGV("receiver %p ~ Invoking modeWithFrameRateOverride changed handler.", this);
        auto frameRateOverrideArray = getFrameRateOverrides(overrides, env);
        auto supportedRefreshRateArray = getSupportedRefreshRates(refreshRates, env);
        env->CallVoidMethod(receiverObj.get(),
                            gDisplayEventReceiverClassInfo
                                    .dispatchModeChangedWithFrameRateOverrides,
                            timestamp, displayId.value, modeId, renderPeriod, appVsyncOffset,
                            presentationDeadline, frameRateOverrideArray);
                            presentationDeadline, frameRateOverrideArray,
                            supportedRefreshRateArray);
        ALOGV("receiver %p ~ Returned from modeWithFrameRateOverride changed handler.", this);
    }

@@ -456,7 +471,7 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) {
    gDisplayEventReceiverClassInfo.dispatchModeChangedWithFrameRateOverrides =
            GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz,
                             "dispatchModeChangedWithFrameRateOverrides",
                             "(JJIJJJ[Landroid/view/DisplayEventReceiver$FrameRateOverride;)V");
                             "(JJIJJJ[Landroid/view/DisplayEventReceiver$FrameRateOverride;[F)V");
    gDisplayEventReceiverClassInfo.dispatchModeRejected =
            GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchModeRejected",
                             "(JI)V");
+61 −26
Original line number Diff line number Diff line
@@ -1242,18 +1242,26 @@ final class LocalDisplayAdapter extends DisplayAdapter {
        }

        private void onActiveDisplayModeChangedLocked(int sfModeId, float renderFrameRate,
                long appVsyncOffsetNanos, long presentationDeadlineNanos) {
                long appVsyncOffsetNanos, long presentationDeadlineNanos,
                @Nullable float[] supportedRefreshRates) {
            if (updateActiveModeAndFrameOverrideChangedLocked(sfModeId, renderFrameRate,
                    appVsyncOffsetNanos, presentationDeadlineNanos, mFrameRateOverrides)) {
                    appVsyncOffsetNanos, presentationDeadlineNanos, mFrameRateOverrides,
                    supportedRefreshRates == null
                            ? mSupportedRefreshRates
                            : supportedRefreshRates)) {
                updateDeviceInfoLocked();
            }
        }

        private void onFrameRateOverridesChangedLocked(
                DisplayEventReceiver.FrameRateOverride[] overrides) {
                DisplayEventReceiver.FrameRateOverride[] overrides,
                @Nullable float[] supportedRefreshRates) {
            if (updateActiveModeAndFrameOverrideChangedLocked(mActiveSfDisplayMode.id,
                    mActiveRenderFrameRate, mAppVsyncOffsetNanos, mPresentationDeadlineNanos,
                    overrides)) {
                    overrides,
                    supportedRefreshRates == null
                            ? mSupportedRefreshRates
                            : supportedRefreshRates)) {
                updateDeviceInfoLocked();
            }
        }
@@ -1261,10 +1269,11 @@ final class LocalDisplayAdapter extends DisplayAdapter {
        private void onModeAndFrameRateOverridesChangedLocked(
                int sfModeId, float renderFrameRate,
                long appVsyncOffsetNanos, long presentationDeadlineNanos,
                DisplayEventReceiver.FrameRateOverride[] overrides) {
                DisplayEventReceiver.FrameRateOverride[] overrides,
                float[] supportedRefreshRates) {
            if (updateActiveModeAndFrameOverrideChangedLocked(sfModeId,
                    renderFrameRate, appVsyncOffsetNanos,
                    presentationDeadlineNanos, overrides)) {
                    presentationDeadlineNanos, overrides, supportedRefreshRates)) {
                updateDeviceInfoLocked();
            }
        }
@@ -1278,13 +1287,16 @@ final class LocalDisplayAdapter extends DisplayAdapter {
        private boolean updateActiveModeAndFrameOverrideChangedLocked(int activeSfModeId,
                float renderFrameRate, long appVsyncOffsetNanos,
                long presentationDeadlineNanos,
                DisplayEventReceiver.FrameRateOverride[] overrides) {
                DisplayEventReceiver.FrameRateOverride[] overrides,
                float[] supportedRefreshRates) {
            if (mActiveSfDisplayMode.id == activeSfModeId
                    && mActiveRenderFrameRate == renderFrameRate
                    && mAppVsyncOffsetNanos == appVsyncOffsetNanos
                    && mPresentationDeadlineNanos == presentationDeadlineNanos
                    && Arrays.equals(overrides, mFrameRateOverrides)
            ) {
                    &&
                    (!com.android.graphics.surfaceflinger.flags.Flags.supportedRefreshRateUpdate()
                            || Arrays.equals(supportedRefreshRates, mSupportedRefreshRates))) {
                return false;
            }
            mActiveSfDisplayMode = getModeById(mSfDisplayModes, activeSfModeId);
@@ -1297,6 +1309,9 @@ final class LocalDisplayAdapter extends DisplayAdapter {
            mAppVsyncOffsetNanos = appVsyncOffsetNanos;
            mPresentationDeadlineNanos = presentationDeadlineNanos;
            mFrameRateOverrides = overrides;
            if (com.android.graphics.surfaceflinger.flags.Flags.supportedRefreshRateUpdate()) {
                mSupportedRefreshRates = supportedRefreshRates;
            }
            return true;
        }

@@ -1626,12 +1641,15 @@ final class LocalDisplayAdapter extends DisplayAdapter {
        void onHotplug(long timestampNanos, long physicalDisplayId, boolean connected);
        void onHotplugConnectionError(long timestampNanos, int connectionError);
        void onModeChanged(long timestampNanos, long physicalDisplayId, int modeId,
                long renderPeriod, long appVsyncOffsetNanos, long presentationDeadlineNanos);
                long renderPeriod, long appVsyncOffsetNanos, long presentationDeadlineNanos,
                @Nullable float[] supportedRefreshRates);
        void onFrameRateOverridesChanged(long timestampNanos, long physicalDisplayId,
                DisplayEventReceiver.FrameRateOverride[] overrides);
                DisplayEventReceiver.FrameRateOverride[] overrides,
                @Nullable float[] supportedRefreshRates);
        void onModeAndFrameRateOverridesChanged(long timestampNanos, long physicalDisplayId,
                int modeId,  long renderPeriod, long appVsyncOffsetNanos,
                long presentationDeadlineNanos, DisplayEventReceiver.FrameRateOverride[] overrides);
                long presentationDeadlineNanos, DisplayEventReceiver.FrameRateOverride[] overrides,
                float[] supportedRefreshRates);
        void onHdcpLevelsChanged(long physicalDisplayId, int connectedLevel, int maxLevel);

    }
@@ -1660,21 +1678,25 @@ final class LocalDisplayAdapter extends DisplayAdapter {
        public void onModeChanged(long timestampNanos, long physicalDisplayId, int modeId,
                long renderPeriod, long appVsyncOffsetNanos, long presentationDeadlineNanos) {
            mListener.onModeChanged(timestampNanos, physicalDisplayId, modeId,
                    renderPeriod, appVsyncOffsetNanos, presentationDeadlineNanos);
                    renderPeriod, appVsyncOffsetNanos, presentationDeadlineNanos,
                    /*supportedRefreshRates*/ null);
        }

        public void onModeAndFrameRateOverridesChanged(long timestampNanos, long physicalDisplayId,
                int modeId,  long renderPeriod, long appVsyncOffsetNanos,
                long presentationDeadlineNanos,
                DisplayEventReceiver.FrameRateOverride[] overrides) {
                DisplayEventReceiver.FrameRateOverride[] overrides,
                float[] supportedRefreshRates) {
            mListener.onModeAndFrameRateOverridesChanged(timestampNanos, physicalDisplayId, modeId,
                    renderPeriod, appVsyncOffsetNanos, presentationDeadlineNanos, overrides);
                    renderPeriod, appVsyncOffsetNanos, presentationDeadlineNanos, overrides,
                    supportedRefreshRates);
        }

        @Override
        public void onFrameRateOverridesChanged(long timestampNanos, long physicalDisplayId,
                DisplayEventReceiver.FrameRateOverride[] overrides) {
            mListener.onFrameRateOverridesChanged(timestampNanos, physicalDisplayId, overrides);
            mListener.onFrameRateOverridesChanged(timestampNanos, physicalDisplayId, overrides,
                    /*supportedRefreshRates*/ null);
        }

        @Override
@@ -1708,7 +1730,8 @@ final class LocalDisplayAdapter extends DisplayAdapter {

        @Override
        public void onModeChanged(long timestampNanos, long physicalDisplayId, int modeId,
                long renderPeriod, long appVsyncOffsetNanos, long presentationDealineNanos) {
                long renderPeriod, long appVsyncOffsetNanos, long presentationDealineNanos,
                @Nullable float[] supportedRefreshRates) {
            if (DEBUG) {
                Slog.d(TAG, "onModeChanged("
                        + "timestampNanos=" + timestampNanos
@@ -1716,7 +1739,9 @@ final class LocalDisplayAdapter extends DisplayAdapter {
                        + ", modeId=" + modeId
                        + ", renderPeriod=" + renderPeriod
                        + ", appVsyncOffsetNanos=" + appVsyncOffsetNanos
                        + ", presentationDealineNanos=" + presentationDealineNanos + ")");
                        + ", presentationDealineNanos=" + presentationDealineNanos
                        + ", supportedRefreshRates=" + Arrays.toString(supportedRefreshRates)
                        + ")");
            }
            synchronized (getSyncRoot()) {
                LocalDisplayDevice device = mDevices.get(physicalDisplayId);
@@ -1729,17 +1754,21 @@ final class LocalDisplayAdapter extends DisplayAdapter {
                }
                float renderFrameRate = 1e9f / renderPeriod;
                device.onActiveDisplayModeChangedLocked(modeId, renderFrameRate,
                        appVsyncOffsetNanos, presentationDealineNanos);
                        appVsyncOffsetNanos, presentationDealineNanos,
                        supportedRefreshRates);
            }
        }

        @Override
        public void onFrameRateOverridesChanged(long timestampNanos, long physicalDisplayId,
                DisplayEventReceiver.FrameRateOverride[] overrides) {
                DisplayEventReceiver.FrameRateOverride[] overrides,
                @Nullable float[] supportedRefreshRates) {
            if (DEBUG) {
                Slog.d(TAG, "onFrameRateOverrideChanged(timestampNanos=" + timestampNanos
                        + ", physicalDisplayId=" + physicalDisplayId + " overrides="
                        + Arrays.toString(overrides) + ")");
                        + Arrays.toString(overrides)
                        + ", supportedRefreshRates=" + Arrays.toString(supportedRefreshRates)
                        + ")");
            }
            synchronized (getSyncRoot()) {
                LocalDisplayDevice device = mDevices.get(physicalDisplayId);
@@ -1750,7 +1779,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
                    }
                    return;
                }
                device.onFrameRateOverridesChangedLocked(overrides);
                device.onFrameRateOverridesChangedLocked(overrides, supportedRefreshRates);
            }
        }

@@ -1758,7 +1787,8 @@ final class LocalDisplayAdapter extends DisplayAdapter {
        public void onModeAndFrameRateOverridesChanged(long timestampNanos, long physicalDisplayId,
                int modeId, long renderPeriod, long appVsyncOffsetNanos,
                long presentationDeadlineNanos,
                DisplayEventReceiver.FrameRateOverride[] overrides) {
                DisplayEventReceiver.FrameRateOverride[] overrides,
                float[] supportedRefreshRates) {
            if (getFeatureFlags().isSingleAppEventForModeAndFrameRateOverrideEnabled()) {
                if (DEBUG) {
                    Slog.d(TAG, "onModeAndFrameRateOverridesChanged("
@@ -1768,7 +1798,9 @@ final class LocalDisplayAdapter extends DisplayAdapter {
                            + ", renderPeriod=" + renderPeriod
                            + ", appVsyncOffsetNanos=" + appVsyncOffsetNanos
                            + ", presentationDeadlineNanos=" + presentationDeadlineNanos
                            + ", overrides=" + Arrays.toString(overrides) + ")");
                            + ", overrides=" + Arrays.toString(overrides)
                            + ", supportedRefreshRates=" + Arrays.toString(supportedRefreshRates)
                            + ")");
                }
                synchronized (getSyncRoot()) {
                    LocalDisplayDevice device = mDevices.get(physicalDisplayId);
@@ -1782,15 +1814,18 @@ final class LocalDisplayAdapter extends DisplayAdapter {
                    }
                    float renderFrameRate = 1e9f / renderPeriod;
                    device.onModeAndFrameRateOverridesChangedLocked(modeId, renderFrameRate,
                            appVsyncOffsetNanos, presentationDeadlineNanos, overrides);
                            appVsyncOffsetNanos, presentationDeadlineNanos, overrides,
                            supportedRefreshRates);
                }
            } else {
                if (DEBUG) {
                    Slog.d(TAG, "onModeAndFrameRateOverridesChanged");
                }
                onModeChanged(timestampNanos, physicalDisplayId, modeId, renderPeriod,
                        appVsyncOffsetNanos, presentationDeadlineNanos);
                onFrameRateOverridesChanged(timestampNanos, physicalDisplayId, overrides);
                        appVsyncOffsetNanos, presentationDeadlineNanos,
                        supportedRefreshRates);
                onFrameRateOverridesChanged(timestampNanos, physicalDisplayId, overrides,
                        supportedRefreshRates);
            }
        }

+14 −4
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.util.Spline;
import android.view.Display;
import android.view.DisplayAddress;
@@ -78,6 +80,7 @@ import com.google.common.truth.Truth;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -155,6 +158,9 @@ public class LocalDisplayAdapterTest {
    private static final List<Integer> mDisplayOffloadSupportedStates
            = new ArrayList<>(List.of(Display.STATE_DOZE_SUSPEND));

    @Rule
    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();

    @Before
    public void setUp() throws Exception {
        mMockitoSession = mockitoSession()
@@ -941,6 +947,7 @@ public class LocalDisplayAdapterTest {
    }

    @Test
    @EnableFlags(com.android.graphics.surfaceflinger.flags.Flags.FLAG_SUPPORTED_REFRESH_RATE_UPDATE)
    public void testOnModeAndFrameRateOverridesChanged() throws Exception {
        doReturn(true).when(mFlags).isDispatchDisplayModeWithVsyncOffsetsEnabled();
        doReturn(true).when(mFlags).isSingleAppEventForModeAndFrameRateOverrideEnabled();
@@ -974,9 +981,10 @@ public class LocalDisplayAdapterTest {
        long newPresentationDeadlineNanos = 500;

        FrameRateOverride[] frameRateOverrides = new FrameRateOverride[1];
        float[] supportedRefreshRates = {120.f, 60.f, 40.f, 30.f, 24.f, 20.f};
        mInjector.getTransmitter().sendOnModeAndFrameRateOverridesChanged(display,
                /*modeId*/ 1, (long) displayMode2.peakRefreshRate, newAppVsyncOffsetNanos,
                newPresentationDeadlineNanos, frameRateOverrides);
                newPresentationDeadlineNanos, frameRateOverrides, supportedRefreshRates);
        waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
        assertTrue(mListener.traversalRequested);

@@ -989,6 +997,7 @@ public class LocalDisplayAdapterTest {
        assertThat(mListener.changedDisplays.size()).isEqualTo(1);
        activeMode = getModeById(displayDeviceInfo, displayDeviceInfo.modeId);
        assertThat(activeMode.matches(1920, 1080, 120f)).isTrue();
        assertEquals(supportedRefreshRates.length, displayDeviceInfo.supportedRefreshRates.length);
    }

    @Test
@@ -1977,18 +1986,19 @@ public class LocalDisplayAdapterTest {
                throws InterruptedException {
            mHandler.post(() -> mListener.onModeChanged(/* timestampNanos = */ 0,
                    display.address.getPhysicalDisplayId(), modeId, renderPeriod,
                    appVsyncOffsetNanos, presentationDeadlineNanos));
                    appVsyncOffsetNanos, presentationDeadlineNanos, /*supportedRefreshRate*/ null));
            waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
        }

        public void sendOnModeAndFrameRateOverridesChanged(FakeDisplay display, int modeId,
                long renderPeriod, long appVsyncOffsetNanos, long presentationDeadlineNanos,
                FrameRateOverride[] frameRateOverrides) throws InterruptedException {
                FrameRateOverride[] frameRateOverrides, float[] supportedRefreshRates)
                throws InterruptedException {

            mHandler.post(() -> mListener.onModeAndFrameRateOverridesChanged(
                    /* timestampNanos = */ 0, display.address.getPhysicalDisplayId(), modeId,
                    renderPeriod, appVsyncOffsetNanos, presentationDeadlineNanos,
                    frameRateOverrides));
                    frameRateOverrides, supportedRefreshRates));
            waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
        }
    }