Merge changes I0ccbdb5a,I0f5d57e5 into sc-dev

* changes:
  Use surface size instead of frame size when adjusting layer bounds
  Fix SurfaceView background layer leaks
This commit is contained in:
Vishnu Nair
2021-02-11 16:35:34 +00:00
committed by Android (Google) Code Review
2 changed files with 65 additions and 35 deletions

View File

@@ -1083,7 +1083,12 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
if (creating) {
updateOpaqueFlag();
mDeferredDestroySurfaceControl = createSurfaceControls(viewRoot);
final String name = "SurfaceView[" + viewRoot.getTitle().toString() + "]";
if (mUseBlastAdapter) {
createBlastSurfaceControls(viewRoot, name);
} else {
mDeferredDestroySurfaceControl = createSurfaceControls(viewRoot, name);
}
} else if (mSurfaceControl == null) {
return;
}
@@ -1220,53 +1225,77 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
* out, the old surface can be persevered until the new one has drawn by keeping the reference
* of the old SurfaceControl alive.
*/
private SurfaceControl createSurfaceControls(ViewRootImpl viewRoot) {
final String name = "SurfaceView[" + viewRoot.getTitle().toString() + "]";
SurfaceControl.Builder builder = new SurfaceControl.Builder(mSurfaceSession)
private SurfaceControl createSurfaceControls(ViewRootImpl viewRoot, String name) {
final SurfaceControl previousSurfaceControl = mSurfaceControl;
mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
.setName(name)
.setLocalOwnerView(this)
.setParent(viewRoot.getBoundsLayer())
.setCallsite("SurfaceView.updateSurface");
.setCallsite("SurfaceView.updateSurface")
.setBufferSize(mSurfaceWidth, mSurfaceHeight)
.setFlags(mSurfaceFlags)
.setFormat(mFormat)
.build();
mBackgroundControl = createBackgroundControl(name);
return previousSurfaceControl;
}
final SurfaceControl previousSurfaceControl;
if (mUseBlastAdapter) {
mSurfaceControl = builder
private SurfaceControl createBackgroundControl(String name) {
return new SurfaceControl.Builder(mSurfaceSession)
.setName("Background for " + name)
.setLocalOwnerView(this)
.setOpaque(true)
.setColorLayer()
.setParent(mSurfaceControl)
.setCallsite("SurfaceView.updateSurface")
.build();
}
// We don't recreate the surface controls but only recreate the adapter. Since the blast layer
// is still alive, the old buffers will continue to be presented until replaced by buffers from
// the new adapter. This means we do not need to track the old surface control and destroy it
// after the client has drawn to avoid any flickers.
private void createBlastSurfaceControls(ViewRootImpl viewRoot, String name) {
if (mSurfaceControl == null) {
mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
.setName(name)
.setLocalOwnerView(this)
.setParent(viewRoot.getBoundsLayer())
.setCallsite("SurfaceView.updateSurface")
.setContainerLayer()
.build();
previousSurfaceControl = mBlastSurfaceControl;
}
if (mBlastSurfaceControl == null) {
mBlastSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
.setName(name + "(BLAST)")
.setLocalOwnerView(this)
.setBufferSize(mSurfaceWidth, mSurfaceHeight)
.setParent(mSurfaceControl)
.setFlags(mSurfaceFlags)
.setHidden(false)
.setBLASTLayer()
.setCallsite("SurfaceView.updateSurface")
.build();
mBlastBufferQueue = new BLASTBufferQueue(name, mBlastSurfaceControl, mSurfaceWidth,
mSurfaceHeight, mFormat, true /* TODO */);
} else {
previousSurfaceControl = mSurfaceControl;
mSurfaceControl = builder
.setBufferSize(mSurfaceWidth, mSurfaceHeight)
.setFlags(mSurfaceFlags)
.setFormat(mFormat)
.build();
mBlastSurfaceControl = null;
mBlastBufferQueue = null;
// update blast layer
mTmpTransaction
.setOpaque(mBlastSurfaceControl, (mSurfaceFlags & SurfaceControl.OPAQUE) != 0)
.setSecure(mBlastSurfaceControl, (mSurfaceFlags & SurfaceControl.SECURE) != 0)
.show(mBlastSurfaceControl)
.apply();
}
mBackgroundControl = new SurfaceControl.Builder(mSurfaceSession)
.setName("Background for " + name)
.setLocalOwnerView(this)
.setOpaque(true)
.setColorLayer()
.setParent(mSurfaceControl)
.setCallsite("SurfaceView.updateSurface")
.build();
return previousSurfaceControl;
if (mBackgroundControl == null) {
mBackgroundControl = createBackgroundControl(name);
}
// Always recreate the IGBP for compatibility. This can be optimized in the future but
// the behavior change will need to be gated by SDK version.
if (mBlastBufferQueue != null) {
mBlastBufferQueue.destroy();
}
mBlastBufferQueue = new BLASTBufferQueue(name, mBlastSurfaceControl, mSurfaceWidth,
mSurfaceHeight, mFormat, true /* TODO */);
}
private void onDrawFinished() {

View File

@@ -1898,11 +1898,12 @@ public final class ViewRootImpl implements ViewParent,
}
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);
// Adjust of insets and update the bounds layer so child surfaces do not draw into
// the surface inset region.
mTempBoundsRect.set(0, 0, mSurfaceSize.x, mSurfaceSize.y);
mTempBoundsRect.inset(mWindowAttributes.surfaceInsets.left,
mWindowAttributes.surfaceInsets.top,
mWindowAttributes.surfaceInsets.right, mWindowAttributes.surfaceInsets.bottom);
t.setWindowCrop(mBoundsLayer, mTempBoundsRect);
}