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

Commit 25cfa134 authored by Robert Carr's avatar Robert Carr
Browse files

Provide non-blocking SurfaceView draw notification path.

SurfaceView needs to notify the window manager that
drawing has been completed, so that animations and such
can begin. Currently this is implemented through
having the SurfaceView user block in surfaceRedrawNeeded
(called from  UI thread) until a frame has been completed.
This blocking can be unnecessary serialization during startup, and
also clumsy to implement for some users.

Test: GLSurfaceView and takeSurface API Demos, android.server.cts.SurfaceViewTests
Bug: 31850030
Change-Id: Idda02098a635f25cf392f2d59a3abbe54a1d64d4
parent 50e0a9a3
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -28553,7 +28553,7 @@ package android.opengl {
    method public void surfaceChanged(android.view.SurfaceHolder, int, int, int);
    method public void surfaceCreated(android.view.SurfaceHolder);
    method public void surfaceDestroyed(android.view.SurfaceHolder);
    method public void surfaceRedrawNeeded(android.view.SurfaceHolder);
    method public deprecated void surfaceRedrawNeeded(android.view.SurfaceHolder);
    field public static final int DEBUG_CHECK_GL_ERROR = 1; // 0x1
    field public static final int DEBUG_LOG_GL_CALLS = 2; // 0x2
    field public static final int RENDERMODE_CONTINUOUSLY = 1; // 0x1
@@ -43035,6 +43035,7 @@ package android.view {
  public static abstract interface SurfaceHolder.Callback2 implements android.view.SurfaceHolder.Callback {
    method public abstract void surfaceRedrawNeeded(android.view.SurfaceHolder);
    method public default void surfaceRedrawNeededAsync(android.view.SurfaceHolder, java.lang.Runnable);
  }
  public class SurfaceView extends android.view.View {
+2 −1
Original line number Diff line number Diff line
@@ -31091,7 +31091,7 @@ package android.opengl {
    method public void surfaceChanged(android.view.SurfaceHolder, int, int, int);
    method public void surfaceCreated(android.view.SurfaceHolder);
    method public void surfaceDestroyed(android.view.SurfaceHolder);
    method public void surfaceRedrawNeeded(android.view.SurfaceHolder);
    method public deprecated void surfaceRedrawNeeded(android.view.SurfaceHolder);
    field public static final int DEBUG_CHECK_GL_ERROR = 1; // 0x1
    field public static final int DEBUG_LOG_GL_CALLS = 2; // 0x2
    field public static final int RENDERMODE_CONTINUOUSLY = 1; // 0x1
@@ -46227,6 +46227,7 @@ package android.view {
  public static abstract interface SurfaceHolder.Callback2 implements android.view.SurfaceHolder.Callback {
    method public abstract void surfaceRedrawNeeded(android.view.SurfaceHolder);
    method public default void surfaceRedrawNeededAsync(android.view.SurfaceHolder, java.lang.Runnable);
  }
  public class SurfaceView extends android.view.View {
+2 −1
Original line number Diff line number Diff line
@@ -28640,7 +28640,7 @@ package android.opengl {
    method public void surfaceChanged(android.view.SurfaceHolder, int, int, int);
    method public void surfaceCreated(android.view.SurfaceHolder);
    method public void surfaceDestroyed(android.view.SurfaceHolder);
    method public void surfaceRedrawNeeded(android.view.SurfaceHolder);
    method public deprecated void surfaceRedrawNeeded(android.view.SurfaceHolder);
    field public static final int DEBUG_CHECK_GL_ERROR = 1; // 0x1
    field public static final int DEBUG_LOG_GL_CALLS = 2; // 0x2
    field public static final int RENDERMODE_CONTINUOUSLY = 1; // 0x1
@@ -43324,6 +43324,7 @@ package android.view {
  public static abstract interface SurfaceHolder.Callback2 implements android.view.SurfaceHolder.Callback {
    method public abstract void surfaceRedrawNeeded(android.view.SurfaceHolder);
    method public default void surfaceRedrawNeededAsync(android.view.SurfaceHolder, java.lang.Runnable);
  }
  public class SurfaceView extends android.view.View {
+26 −1
Original line number Diff line number Diff line
@@ -116,9 +116,34 @@ public interface SurfaceHolder {
         * size before it has been correctly drawn that way).  This will
         * typically be preceeded by a call to {@link #surfaceChanged}.
         *
         * As of O, {@link #surfaceRedrawNeededAsync} may be implemented
         * to provide a non-blocking implementation. If {@link #surfaceRedrawNeededAsync}
         * is not implemented, then this will be called instead.
         *
         * @param holder The SurfaceHolder whose surface has changed.
         */
        public void surfaceRedrawNeeded(SurfaceHolder holder);
        void surfaceRedrawNeeded(SurfaceHolder holder);

        /**
         * An alternative to surfaceRedrawNeeded where it is not required to block
         * until the redraw is complete. You should initiate the redraw, and return,
         * later invoking drawingFinished when your redraw is complete.
         *
         * This can be useful to avoid blocking your main application thread on rendering.
         *
         * As of O, if this is implemented {@link #surfaceRedrawNeeded} will not be called.
         * However it is still recommended to implement {@link #surfaceRedrawNeeded} for
         * compatibility with older versions of the platform.
         *
         * @param holder The SurfaceHolder which needs redrawing.
         * @param drawingFinished A runnable to signal completion. This may be invoked
         * from any thread.
         *
         */
        default void surfaceRedrawNeededAsync(SurfaceHolder holder, Runnable drawingFinished) {
            surfaceRedrawNeeded(holder);
            drawingFinished.run();
        }
    }

    /**
+4 −12
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.util.AttributeSet;
import android.util.Log;

import com.android.internal.view.BaseIWindow;
import com.android.internal.view.SurfaceCallbackHelper;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -639,21 +640,13 @@ public class SurfaceView extends View {
                            if (callbacks == null) {
                                callbacks = getSurfaceCallbacks();
                            }
                            for (SurfaceHolder.Callback c : callbacks) {
                                if (c instanceof SurfaceHolder.Callback2) {
                                    ((SurfaceHolder.Callback2)c).surfaceRedrawNeeded(
                                            mSurfaceHolder);
                                }
                            }
                            SurfaceCallbackHelper sch =
                                    new SurfaceCallbackHelper(mSession, mWindow);
                            sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
                        }
                    }
                } finally {
                    mIsCreating = false;
                    if (redrawNeeded) {
                        if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
                                + "finishedDrawing");
                        mSession.finishDrawing(mWindow);
                    }
                    mSession.performDeferredDestroy(mWindow);
                }
            } catch (RemoteException ex) {
@@ -876,7 +869,6 @@ public class SurfaceView extends View {
    }

    private final SurfaceHolder mSurfaceHolder = new SurfaceHolder() {

        private static final String LOG_TAG = "SurfaceHolder";

        @Override
Loading