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

Commit f213111b authored by Winson Chung's avatar Winson Chung
Browse files

Ensure frame callback applied during scroll handling is applied.

- By the time we call computeScroll(), the current frame's callback
  has already been consumed, which makes it impossible to apply
  surface updates with the current frame (in response to the scroll).
  Instead, we should only consume the frame callback after dispatching
  draw for the current frame (but before the window callbacks which
  may reset the frame callback).

Test: Update surface transforms in response to scroll, ensure that
      it is updated with the current frame

Change-Id: I52a640604ee15cf745c47fc0120b4844b67f35be
parent c90e979d
Loading
Loading
Loading
Loading
+23 −6
Original line number Diff line number Diff line
@@ -299,6 +299,8 @@ public final class ThreadedRenderer extends HardwareRenderer {
    private boolean mEnabled;
    private boolean mRequested = true;

    private FrameDrawingCallback mNextRtFrameCallback;

    ThreadedRenderer(Context context, boolean translucent, String name) {
        super();
        setName(name);
@@ -431,6 +433,17 @@ public final class ThreadedRenderer extends HardwareRenderer {
        }
    }

    /**
     * Registers a callback to be executed when the next frame is being drawn on RenderThread. This
     * callback will be executed on a RenderThread worker thread, and only used for the next frame
     * and thus it will only fire once.
     *
     * @param callback The callback to register.
     */
    void registerRtFrameCallback(FrameDrawingCallback callback) {
        mNextRtFrameCallback = callback;
    }

    /**
     * Destroys all hardware rendering resources associated with the specified
     * view hierarchy.
@@ -562,6 +575,15 @@ public final class ThreadedRenderer extends HardwareRenderer {
        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Record View#draw()");
        updateViewTreeDisplayList(view);

        // Consume and set the frame callback after we dispatch draw to the view above, but before
        // onPostDraw below which may reset the callback for the next frame.  This ensures that
        // updates to the frame callback during scroll handling will also apply in this frame.
        final FrameDrawingCallback callback = mNextRtFrameCallback;
        mNextRtFrameCallback = null;
        if (callback != null) {
            setFrameCallback(callback);
        }

        if (mRootNodeNeedsUpdate || !mRootNode.hasDisplayList()) {
            RecordingCanvas canvas = mRootNode.startRecording(mSurfaceWidth, mSurfaceHeight);
            try {
@@ -619,10 +641,8 @@ public final class ThreadedRenderer extends HardwareRenderer {
     *
     * @param view The view to draw.
     * @param attachInfo AttachInfo tied to the specified view.
     * @param callbacks Callbacks invoked when drawing happens.
     */
    void draw(View view, AttachInfo attachInfo, DrawCallbacks callbacks,
            FrameDrawingCallback frameDrawingCallback) {
    void draw(View view, AttachInfo attachInfo, DrawCallbacks callbacks) {
        final Choreographer choreographer = attachInfo.mViewRootImpl.mChoreographer;
        choreographer.mFrameInfo.markDrawStart();

@@ -642,9 +662,6 @@ public final class ThreadedRenderer extends HardwareRenderer {
            attachInfo.mPendingAnimatingRenderNodes = null;
        }

        if (frameDrawingCallback != null) {
            setFrameCallback(frameDrawingCallback);
        }
        int syncResult = syncAndDrawFrame(choreographer.mFrameInfo);
        if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
            setEnabled(false);
+4 −7
Original line number Diff line number Diff line
@@ -200,8 +200,6 @@ public final class ViewRootImpl implements ViewParent,
    static final ArrayList<Runnable> sFirstDrawHandlers = new ArrayList();
    static boolean sFirstDrawComplete = false;

    private FrameDrawingCallback mNextRtFrameCallback;

    /**
     * Callback for notifying about global configuration changes.
     */
@@ -1052,7 +1050,9 @@ public final class ViewRootImpl implements ViewParent,
     * @param callback The callback to register.
     */
    public void registerRtFrameCallback(FrameDrawingCallback callback) {
        mNextRtFrameCallback = callback;
        if (mAttachInfo.mThreadedRenderer != null) {
            mAttachInfo.mThreadedRenderer.registerRtFrameCallback(callback);
        }
    }

    @UnsupportedAppUsage
@@ -3534,10 +3534,7 @@ public final class ViewRootImpl implements ViewParent,

                useAsyncReport = true;

                // draw(...) might invoke post-draw, which might register the next callback already.
                final FrameDrawingCallback callback = mNextRtFrameCallback;
                mNextRtFrameCallback = null;
                mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this, callback);
                mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this);
            } else {
                // If we get here with a disabled & requested hardware renderer, something went
                // wrong (an invalidate posted right before we destroyed the hardware surface