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

Commit 698426a8 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "SurfaceView: Clean up synchronized changes with applyTransactionOnVriDraw"

parents b60a625f 6d3b93ae
Loading
Loading
Loading
Loading
+33 −163
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import static android.view.WindowManagerPolicyConstants.APPLICATION_PANEL_SUBLAY
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.CompatibilityInfo.Translator;
import android.graphics.BLASTBufferQueue;
@@ -42,7 +41,6 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceControl.Transaction;
@@ -376,11 +374,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
    }

    private void updateSurfaceAlpha() {
        if (!mUseAlpha) {
            if (DEBUG) {
                Log.d(TAG, System.identityHashCode(this)
                        + " updateSurfaceAlpha: setUseAlpha() is not called, ignored.");
            }
        if (!mUseAlpha || !mHaveFrame || mSurfaceControl == null) {
            return;
        }
        final float viewAlpha = getAlpha();
@@ -389,88 +383,16 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
                    + " updateSurfaceAlpha:"
                    + " translucent color is not supported for a surface placed z-below.");
        }
        if (!mHaveFrame) {
            if (DEBUG) {
                Log.d(TAG, System.identityHashCode(this)
                        + " updateSurfaceAlpha: has no surface.");
            }
            return;
        }
        final ViewRootImpl viewRoot = getViewRootImpl();
        if (viewRoot == null) {
            if (DEBUG) {
                Log.d(TAG, System.identityHashCode(this)
                        + " updateSurfaceAlpha: ViewRootImpl not available.");
            }
            return;
        }
        if (mSurfaceControl == null) {
            if (DEBUG) {
                Log.d(TAG, System.identityHashCode(this)
                        + "updateSurfaceAlpha:"
                        + " surface is not yet created, or already released.");
            }
            return;
        }
        final Surface parent = viewRoot.mSurface;
        if (parent == null || !parent.isValid()) {
            if (DEBUG) {
                Log.d(TAG, System.identityHashCode(this)
                        + " updateSurfaceAlpha: ViewRootImpl has no valid surface");
            }
            return;
        }
        final float alpha = getFixedAlpha();
        if (alpha != mSurfaceAlpha) {
            if (isHardwareAccelerated()) {
                /*
                 * Schedule a callback that reflects an alpha value onto the underlying surfaces.
                 * This gets called on a RenderThread worker thread, so members accessed here must
                 * be protected by a lock.
                 */
                viewRoot.registerRtFrameCallback(frame -> {
                    try {
                        synchronized (mSurfaceControlLock) {
                            if (!parent.isValid()) {
                                if (DEBUG) {
                                    Log.d(TAG, System.identityHashCode(this)
                                            + " updateSurfaceAlpha RT:"
                                            + " ViewRootImpl has no valid surface");
                                }
                                return;
                            }
                            if (mSurfaceControl == null) {
                                if (DEBUG) {
                                    Log.d(TAG, System.identityHashCode(this)
                                            + "updateSurfaceAlpha RT:"
                                            + " mSurfaceControl has already released");
                                }
                                return;
                            }
                            if (DEBUG) {
                                Log.d(TAG, System.identityHashCode(this)
                                        + " updateSurfaceAlpha RT: set alpha=" + alpha);
                            }

                            mFrameCallbackTransaction.setAlpha(mSurfaceControl, alpha);
                            applyOrMergeTransaction(mFrameCallbackTransaction, frame);
                        }
                        // It's possible that mSurfaceControl is released in the UI thread before
                        // the transaction completes. If that happens, an exception is thrown, which
                        // must be caught immediately.
                    } catch (Exception e) {
                        Log.e(TAG, System.identityHashCode(this)
                                + "updateSurfaceAlpha RT: Exception during surface transaction", e);
                    }
                });
            final Transaction transaction = new Transaction();
            transaction.setAlpha(mSurfaceControl, alpha);
            viewRoot.applyTransactionOnDraw(transaction);
            damageInParent();
            } else {
                if (DEBUG) {
                    Log.d(TAG, System.identityHashCode(this)
                            + " updateSurfaceAlpha: set alpha=" + alpha);
                }
                mTmpTransaction.setAlpha(mSurfaceControl, alpha).apply();
            }
            mSurfaceAlpha = alpha;
        }
    }
@@ -527,12 +449,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
        mRequestedVisible = false;

        updateSurface();

        // We don't release this as part of releaseSurfaces as
        // that is also called on transient visibility changes. We can't
        // recreate this Surface, so only release it when we are fully
        // detached.
        tryReleaseSurfaces(true /* releaseSurfacePackage*/);
        releaseSurfaces(true /* releaseSurfacePackage*/);

        mHaveFrame = false;
        super.onDetachedFromWindow();
@@ -625,7 +542,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
    public void setClipBounds(Rect clipBounds) {
        super.setClipBounds(clipBounds);

        if (!mClipSurfaceToBounds) {
        if (!mClipSurfaceToBounds || mSurfaceControl == null) {
            return;
        }

@@ -635,18 +552,15 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
            invalidate();
        }

        if (mSurfaceControl != null) {
        if (mClipBounds != null) {
            mTmpRect.set(mClipBounds);
        } else {
            mTmpRect.set(0, 0, mSurfaceWidth, mSurfaceHeight);
        }
            SyncRtSurfaceTransactionApplier applier = new SyncRtSurfaceTransactionApplier(this);
            applier.scheduleApply(
                    new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(mSurfaceControl)
                            .withWindowCrop(mTmpRect)
                            .build());
        }
        final Transaction transaction = new Transaction();
        transaction.setWindowCrop(mSurfaceControl, mTmpRect);
        applyTransactionOnVriDraw(transaction);
        invalidate();
    }

    private void clearSurfaceViewPort(Canvas canvas) {
@@ -782,37 +696,10 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
        if (viewRoot == null) {
            return true;
        }
        final Surface parent = viewRoot.mSurface;
        if (parent == null || !parent.isValid()) {
            return true;
        }

        /*
         * Schedule a callback that reflects an alpha value onto the underlying surfaces.
         * This gets called on a RenderThread worker thread, so members accessed here must
         * be protected by a lock.
         */
        viewRoot.registerRtFrameCallback(frame -> {
            try {
                synchronized (mSurfaceControlLock) {
                    if (!parent.isValid() || mSurfaceControl == null) {
                        return;
                    }

                    updateRelativeZ(mFrameCallbackTransaction);
                    applyOrMergeTransaction(mFrameCallbackTransaction, frame);
                }
                // It's possible that mSurfaceControl is released in the UI thread before
                // the transaction completes. If that happens, an exception is thrown, which
                // must be caught immediately.
             } catch (Exception e) {
                Log.e(TAG, System.identityHashCode(this)
                        + "setZOrderOnTop RT: Exception during surface transaction", e);
            }
        });

        final Transaction transaction = new SurfaceControl.Transaction();
        updateRelativeZ(transaction);
        viewRoot.applyTransactionOnDraw(transaction);
        invalidate();

        return true;
    }

@@ -863,7 +750,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
        return t;
    }

    private void tryReleaseSurfaces(boolean releaseSurfacePackage) {
    private void releaseSurfaces(boolean releaseSurfacePackage) {
        mSurfaceAlpha = 1f;

        synchronized (mSurfaceControlLock) {
@@ -892,12 +779,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
                mSurfacePackage = null;
            }

            ViewRootImpl viewRoot = getViewRootImpl();
            if (viewRoot != null) {
                viewRoot.applyTransactionOnDraw(transaction);
            } else {
                transaction.apply();
            }
            applyTransactionOnVriDraw(transaction);
        }
    }

@@ -1041,7 +923,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall

        if (viewRoot.mSurface == null || !viewRoot.mSurface.isValid()) {
            notifySurfaceDestroyed();
            tryReleaseSurfaces(false /* releaseSurfacePackage*/);
            releaseSurfaces(false /* releaseSurfacePackage*/);
            return;
        }

@@ -1182,7 +1064,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
                } finally {
                    mIsCreating = false;
                    if (mSurfaceControl != null && !mSurfaceCreated) {
                        tryReleaseSurfaces(false /* releaseSurfacePackage*/);
                        releaseSurfaces(false /* releaseSurfacePackage*/);
                    }
                }
            } catch (Exception ex) {
@@ -1316,17 +1198,6 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
        runOnUiThread(() -> performDrawFinished(t));
    }

    /**
     * A place to over-ride for applying child-surface transactions.
     * These can be synchronized with the viewroot surface using deferTransaction.
     *
     * Called from RenderWorker while UI thread is paused.
     * @hide
     */
    protected void applyChildSurfaceTransaction_renderWorker(SurfaceControl.Transaction t,
            Surface viewRootSurface, long nextViewRootFrameNumber) {
    }

    /**
     * Sets the surface position and scale. Can be called on
     * the UI thread as well as on the renderer thread.
@@ -1435,11 +1306,6 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
                    if (mViewVisibility) {
                        mPositionChangedTransaction.show(mSurfaceControl);
                    }
                    final ViewRootImpl viewRoot = getViewRootImpl();
                    if (viewRoot != null) {
                        applyChildSurfaceTransaction_renderWorker(mPositionChangedTransaction,
                                viewRoot.mSurface, frameNumber);
                    }
                    applyOrMergeTransaction(mPositionChangedTransaction, frameNumber);
                    mPendingTransaction = false;
                } catch (Exception ex) {
@@ -1837,12 +1703,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
                mSurfacePackage.release();
            }
            reparentSurfacePackage(transaction, p);
            final ViewRootImpl viewRoot = getViewRootImpl();
            if (viewRoot != null) {
                viewRoot.applyTransactionOnDraw(transaction);
            } else {
                transaction.apply();
            }
            applyTransactionOnVriDraw(transaction);
        }
        mSurfacePackage = p;
        invalidate();
@@ -1948,4 +1809,13 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
        }
    }

    private void applyTransactionOnVriDraw(Transaction t) {
        final ViewRootImpl viewRoot = getViewRootImpl();
        if (viewRoot != null) {
            // If we are using BLAST, merge the transaction with the viewroot buffer transaction.
            viewRoot.applyTransactionOnDraw(t);
        } else {
            t.apply();
        }
    }
}