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

Commit bdb6c422 authored by Shane's avatar Shane
Browse files

Call setFrameRate in TextureView to set frame rate properly.

Call setFrameRate in TextureView to set frame rate if one is provided.

Considering that TextureView could be invalidated with a lower
frequency comparing to the other Views. If no frame rate was set in the past 100 ms, the value of mPreferredFrameRate will be to 0 in ViewRootImpl. Otherwise, the value remains the same.

Bug: 281695725
Test: atest TextureViewTest & manual using a test app
Change-Id: Icbba5e3df8da5aa20808dd236eb93285eceddeb7
parent e475ab6a
Loading
Loading
Loading
Loading
+2 −4
Original line number Original line Diff line number Diff line
@@ -16,7 +16,6 @@


package android.view;
package android.view;


import android.annotation.FloatRange;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.compat.annotation.UnsupportedAppUsage;
@@ -197,7 +196,6 @@ public class TextureView extends View {
    private Canvas mCanvas;
    private Canvas mCanvas;
    private int mSaveCount;
    private int mSaveCount;


    @FloatRange(from = 0.0) float mFrameRate;
    @Surface.FrameRateCompatibility int mFrameRateCompatibility;
    @Surface.FrameRateCompatibility int mFrameRateCompatibility;


    private final Object[] mNativeWindowLock = new Object[0];
    private final Object[] mNativeWindowLock = new Object[0];
@@ -473,13 +471,13 @@ public class TextureView extends View {
            mLayer.setSurfaceTexture(mSurface);
            mLayer.setSurfaceTexture(mSurface);
            mSurface.setDefaultBufferSize(getWidth(), getHeight());
            mSurface.setDefaultBufferSize(getWidth(), getHeight());
            mSurface.setOnFrameAvailableListener(mUpdateListener, mAttachInfo.mHandler);
            mSurface.setOnFrameAvailableListener(mUpdateListener, mAttachInfo.mHandler);
            if (Flags.toolkitSetFrameRate()) {
            if (Flags.toolkitSetFrameRateReadOnly()) {
                mSurface.setOnSetFrameRateListener(
                mSurface.setOnSetFrameRateListener(
                        (surfaceTexture, frameRate, compatibility, strategy) -> {
                        (surfaceTexture, frameRate, compatibility, strategy) -> {
                            if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                            if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                                Trace.instant(Trace.TRACE_TAG_VIEW, "setFrameRate: " + frameRate);
                                Trace.instant(Trace.TRACE_TAG_VIEW, "setFrameRate: " + frameRate);
                            }
                            }
                            mFrameRate = frameRate;
                            setRequestedFrameRate(frameRate);
                            mFrameRateCompatibility = compatibility;
                            mFrameRateCompatibility = compatibility;
                        }, mAttachInfo.mHandler);
                        }, mAttachInfo.mHandler);
            }
            }
+12 −2
Original line number Original line Diff line number Diff line
@@ -1024,6 +1024,9 @@ public final class ViewRootImpl implements ViewParent,
    private static final int FRAME_RATE_IDLENESS_CHECK_TIME_MILLIS = 500;
    private static final int FRAME_RATE_IDLENESS_CHECK_TIME_MILLIS = 500;
    // time for revaluating the idle status before lowering the frame rate.
    // time for revaluating the idle status before lowering the frame rate.
    private static final int FRAME_RATE_IDLENESS_REEVALUATE_TIME = 500;
    private static final int FRAME_RATE_IDLENESS_REEVALUATE_TIME = 500;
    // time for evaluating the interval between current time and
    // the time when frame rate was set previously.
    private static final int FRAME_RATE_SETTING_REEVALUATE_TIME = 100;
    /*
    /*
     * the variables below are used to determine whther a dVRR feature should be enabled
     * the variables below are used to determine whther a dVRR feature should be enabled
@@ -4080,7 +4083,6 @@ public final class ViewRootImpl implements ViewParent,
        setPreferredFrameRate(mPreferredFrameRate);
        setPreferredFrameRate(mPreferredFrameRate);
        setPreferredFrameRateCategory(mPreferredFrameRateCategory);
        setPreferredFrameRateCategory(mPreferredFrameRateCategory);
        mPreferredFrameRateCategory = FRAME_RATE_CATEGORY_NO_PREFERENCE;
        mPreferredFrameRateCategory = FRAME_RATE_CATEGORY_NO_PREFERENCE;
        mPreferredFrameRate = 0;
    }
    }
    private void createSyncIfNeeded() {
    private void createSyncIfNeeded() {
@@ -6134,6 +6136,7 @@ public final class ViewRootImpl implements ViewParent,
    private static final int MSG_TOUCH_BOOST_TIMEOUT = 39;
    private static final int MSG_TOUCH_BOOST_TIMEOUT = 39;
    private static final int MSG_CHECK_INVALIDATION_IDLE = 40;
    private static final int MSG_CHECK_INVALIDATION_IDLE = 40;
    private static final int MSG_REFRESH_POINTER_ICON = 41;
    private static final int MSG_REFRESH_POINTER_ICON = 41;
    private static final int MSG_FRAME_RATE_SETTING = 42;
    final class ViewRootHandler extends Handler {
    final class ViewRootHandler extends Handler {
        @Override
        @Override
@@ -6472,6 +6475,10 @@ public final class ViewRootImpl implements ViewParent,
                    }
                    }
                    updatePointerIcon(mPointerIconEvent);
                    updatePointerIcon(mPointerIconEvent);
                    break;
                    break;
                case MSG_FRAME_RATE_SETTING:
                    mPreferredFrameRate = 0;
                    setPreferredFrameRate(mPreferredFrameRate);
                    break;
            }
            }
        }
        }
    }
    }
@@ -12285,7 +12292,7 @@ public final class ViewRootImpl implements ViewParent,
    private boolean shouldSetFrameRate() {
    private boolean shouldSetFrameRate() {
        // use toolkitSetFrameRate flag to gate the change
        // use toolkitSetFrameRate flag to gate the change
        return mPreferredFrameRate > 0 && sToolkitSetFrameRateReadOnlyFlagValue;
        return sToolkitSetFrameRateReadOnlyFlagValue;
    }
    }
    private boolean shouldTouchBoost(int motionEventAction, int windowType) {
    private boolean shouldTouchBoost(int motionEventAction, int windowType) {
@@ -12336,6 +12343,9 @@ public final class ViewRootImpl implements ViewParent,
        }
        }
        mHasInvalidation = true;
        mHasInvalidation = true;
        mHandler.removeMessages(MSG_FRAME_RATE_SETTING);
        mHandler.sendEmptyMessageDelayed(MSG_FRAME_RATE_SETTING,
                FRAME_RATE_SETTING_REEVALUATE_TIME);
    }
    }
    /**
    /**
+27 −0
Original line number Original line Diff line number Diff line
@@ -795,6 +795,33 @@ public class ViewRootImplTest {
        });
        });
    }
    }


    /**
     * Test votePreferredFrameRate_voteFrameRateTimeOut
     * If no frame rate is voted in 100 milliseconds, the value of
     * mPreferredFrameRate should be set to 0.
     */
    @Test
    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
    public void votePreferredFrameRate_voteFrameRateTimeOut() throws InterruptedException {
        final long delay = 200L;

        View view = new View(sContext);
        attachViewToWindow(view);
        sInstrumentation.waitForIdleSync();
        ViewRootImpl viewRootImpl = view.getViewRootImpl();

        sInstrumentation.runOnMainSync(() -> {
            assertEquals(viewRootImpl.getPreferredFrameRate(), 0, 0.1);
            viewRootImpl.votePreferredFrameRate(24);
            assertEquals(viewRootImpl.getPreferredFrameRate(), 24, 0.1);
            view.invalidate();
            assertEquals(viewRootImpl.getPreferredFrameRate(), 24, 0.1);
        });

        Thread.sleep(delay);
        assertEquals(viewRootImpl.getPreferredFrameRate(), 0, 0.1);
    }

    /**
    /**
     * Test the logic of infrequent layer:
     * Test the logic of infrequent layer:
     * - NORMAL for infrequent update: FT2-FT1 > 100 && FT3-FT2 > 100.
     * - NORMAL for infrequent update: FT2-FT1 > 100 && FT3-FT2 > 100.
+1 −1
Original line number Original line Diff line number Diff line
@@ -489,7 +489,7 @@ public class SurfaceTexture {
            @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy) {
            @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy) {
        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "postOnSetFrameRateEventFromNative");
        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "postOnSetFrameRateEventFromNative");
        try {
        try {
            if (Flags.toolkitSetFrameRate()) {
            if (Flags.toolkitSetFrameRateReadOnly()) {
                SurfaceTexture st = weakSelf.get();
                SurfaceTexture st = weakSelf.get();
                if (st != null) {
                if (st != null) {
                    Handler handler = st.mOnSetFrameRateHandler;
                    Handler handler = st.mOnSetFrameRateHandler;