diff options
Diffstat (limited to 'core/java/android/view/ViewRootImpl.java')
| -rw-r--r-- | core/java/android/view/ViewRootImpl.java | 115 |
1 files changed, 70 insertions, 45 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 30bb2bbd3385..16de906b1085 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -68,6 +68,7 @@ import android.os.Build; import android.os.Bundle; import android.os.Debug; import android.os.Handler; +import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.ParcelFileDescriptor; @@ -476,17 +477,19 @@ public final class ViewRootImpl implements ViewParent, @UnsupportedAppUsage public final Surface mSurface = new Surface(); private final SurfaceControl mSurfaceControl = new SurfaceControl(); + private IBinder mPreviousSurfaceControlHandle = null; + + private final Transaction mChangeSurfaceTransaction = new Transaction(); + private final SurfaceSession mSurfaceSession = new SurfaceSession(); /** - * Child surface of {@code mSurface} with the same bounds as its parent, and crop bounds - * are set to the parent's bounds adjusted for surface insets. This surface is created when - * {@link ViewRootImpl#createBoundsSurface(int)} is called. - * By parenting to this bounds surface, child surfaces can ensure they do not draw into the - * surface inset regions set by the parent window. + * Child container layer of {@code mSurface} with the same bounds as its parent, and cropped to + * the surface insets. This surface is created only if a client requests it via {@link + * #getBoundsLayer()}. By parenting to this bounds surface, child surfaces can ensure they do + * not draw into the surface inset regions set by the parent window. */ - public final Surface mBoundsSurface = new Surface(); - private SurfaceSession mSurfaceSession; - private SurfaceControl mBoundsSurfaceControl; + private SurfaceControl mBoundsLayer; + private final Transaction mTransaction = new Transaction(); @UnsupportedAppUsage @@ -1576,65 +1579,76 @@ public final class ViewRootImpl implements ViewParent, } } - /** - * Creates a surface as a child of {@code mSurface} with the same bounds as its parent and - * crop bounds set to the parent's bounds adjusted for surface insets. - * - * @param zOrderLayer Z order relative to the parent surface. - */ - public void createBoundsSurface(int zOrderLayer) { - if (mSurfaceSession == null) { - mSurfaceSession = new SurfaceSession(); - } - if (mBoundsSurfaceControl != null && mBoundsSurface.isValid()) { - return; // surface control for bounds surface already exists. + /** Register callback to be notified when the ViewRootImpl surface changes. */ + interface SurfaceChangedCallback { + void surfaceChangedCallback(SurfaceControl.Transaction transaction); + } + + private final ArrayList<SurfaceChangedCallback> mSurfaceChangedCallbacks = new ArrayList<>(); + void addSurfaceChangedCallback(SurfaceChangedCallback c) { + mSurfaceChangedCallbacks.add(c); + } + + void removeSurfaceChangedCallback(SurfaceChangedCallback c) { + mSurfaceChangedCallbacks.remove(c); + } + + private void notifySurfaceChanged(SurfaceControl.Transaction transaction) { + for (int i = 0; i < mSurfaceChangedCallbacks.size(); i++) { + mSurfaceChangedCallbacks.get(i).surfaceChangedCallback(transaction); } + } - mBoundsSurfaceControl = new SurfaceControl.Builder(mSurfaceSession) + /** + * Returns a child layer with the same bounds as its parent {@code mSurface} and cropped to the + * surface insets. If the layer does not exist, it is created. + * + * <p>Parenting to this layer will ensure that its children are cropped by the view's surface + * insets. + */ + public SurfaceControl getBoundsLayer() { + if (mBoundsLayer == null) { + mBoundsLayer = new SurfaceControl.Builder(mSurfaceSession) + .setContainerLayer() .setName("Bounds for - " + getTitle().toString()) .setParent(mSurfaceControl) .build(); - setBoundsSurfaceCrop(); - mTransaction.setLayer(mBoundsSurfaceControl, zOrderLayer) - .show(mBoundsSurfaceControl) - .apply(); - mBoundsSurface.copyFrom(mBoundsSurfaceControl); + setBoundsLayerCrop(mTransaction); + mTransaction.show(mBoundsLayer).apply(); + } + return mBoundsLayer; } - private void setBoundsSurfaceCrop() { + private void setBoundsLayerCrop(Transaction t) { // mWinFrame is already adjusted for surface insets. So offset it and use it as // the cropping bounds. mTempBoundsRect.set(mWinFrame); mTempBoundsRect.offsetTo(mWindowAttributes.surfaceInsets.left, mWindowAttributes.surfaceInsets.top); - mTransaction.setWindowCrop(mBoundsSurfaceControl, mTempBoundsRect); + t.setWindowCrop(mBoundsLayer, mTempBoundsRect); } /** - * Called after window layout to update the bounds surface. If the surface insets have - * changed or the surface has resized, update the bounds surface. + * Called after window layout to update the bounds surface. If the surface insets have changed + * or the surface has resized, update the bounds surface. */ - private void updateBoundsSurface() { - if (mBoundsSurfaceControl != null && mSurface.isValid()) { - setBoundsSurfaceCrop(); - mTransaction.deferTransactionUntilSurface(mBoundsSurfaceControl, + private void updateBoundsLayer() { + if (mBoundsLayer != null) { + setBoundsLayerCrop(mTransaction); + mTransaction.deferTransactionUntilSurface(mBoundsLayer, mSurface, mSurface.getNextFrameNumber()) .apply(); } } private void destroySurface() { + if (mBoundsLayer != null) { + mBoundsLayer.release(); + mBoundsLayer = null; + } mSurface.release(); mSurfaceControl.release(); - - mSurfaceSession = null; - - if (mBoundsSurfaceControl != null) { - mBoundsSurfaceControl.remove(); - mBoundsSurface.release(); - mBoundsSurfaceControl = null; - } } /** @@ -2598,7 +2612,7 @@ public final class ViewRootImpl implements ViewParent, } if (surfaceSizeChanged) { - updateBoundsSurface(); + updateBoundsLayer(); } final boolean didLayout = layoutRequested && (!mStopped || mReportNextDraw); @@ -3438,7 +3452,9 @@ public final class ViewRootImpl implements ViewParent, private void reportDrawFinished() { try { mDrawsNeededToReport = 0; - mWindowSession.finishDrawing(mWindow); + if (mSurfaceControl.isValid()) { + mWindowSession.finishDrawing(mWindow, mChangeSurfaceTransaction); + } } catch (RemoteException e) { // Have fun! } @@ -7089,6 +7105,9 @@ public final class ViewRootImpl implements ViewParent, frameNumber = mSurface.getNextFrameNumber(); } + mPreviousSurfaceControlHandle = mSurfaceControl.isValid() + ? mSurfaceControl.getHandle() : null; + int relayoutResult = mWindowSession.relayout(mWindow, mSeq, params, (int) (mView.getMeasuredWidth() * appScale + 0.5f), (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility, @@ -7102,6 +7121,11 @@ public final class ViewRootImpl implements ViewParent, destroySurface(); } + if (mPreviousSurfaceControlHandle != null && mSurfaceControl.isValid() + && mPreviousSurfaceControlHandle != mSurfaceControl.getHandle()) { + notifySurfaceChanged(mChangeSurfaceTransaction); + } + mPendingAlwaysConsumeSystemBars = (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0; @@ -7326,7 +7350,8 @@ public final class ViewRootImpl implements ViewParent, try { if ((relayoutWindow(mWindowAttributes, viewVisibility, false) & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) { - mWindowSession.finishDrawing(mWindow); + mWindowSession.finishDrawing( + mWindow, null /* postDrawTransaction */); } } catch (RemoteException e) { } |
