diff options
| author | Mark Renouf <mrenouf@google.com> | 2019-08-12 16:22:15 -0400 |
|---|---|---|
| committer | Mark Renouf <mrenouf@google.com> | 2019-09-18 14:47:03 -0400 |
| commit | e574ad09ee145a65ec2340395c275b21a538312f (patch) | |
| tree | 4538f64be03f55de043c06a52cae14bd575e9a39 /core/java/android/view/SurfaceView.java | |
| parent | df0f3bce7ef4568c8408204b01e61e4166d07a97 (diff) | |
Support frame-synchronized clipping on SurfaceView
Bug: 123306815
Test: See ag/9384030, manual test of bubbles expand collapse animation
Change-Id: I5350501667fe729a0c668e8f6edaf30070a2e1ec
Diffstat (limited to 'core/java/android/view/SurfaceView.java')
| -rw-r--r-- | core/java/android/view/SurfaceView.java | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 90e69f3abc6c..9acebe1a26df 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -166,6 +166,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall boolean mUseAlpha = false; float mSurfaceAlpha = 1f; + boolean mClipSurfaceToBounds; @UnsupportedAppUsage boolean mHaveFrame = false; @@ -554,9 +555,52 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall super.dispatchDraw(canvas); } + /** + * Control whether the surface is clipped to the same bounds as the View. If true, then + * the bounds set by {@link #setClipBounds(Rect)} are applied to the surface as window-crop. + * + * @param enabled whether to enable surface clipping + * @hide + */ + public void setEnableSurfaceClipping(boolean enabled) { + mClipSurfaceToBounds = enabled; + invalidate(); + } + + @Override + public void setClipBounds(Rect clipBounds) { + super.setClipBounds(clipBounds); + + if (!mClipSurfaceToBounds) { + return; + } + + // When cornerRadius is non-zero, a draw() is required to update + // the viewport (rounding the corners of the clipBounds). + if (mCornerRadius > 0f && !isAboveParent()) { + 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()); + } + } + private void clearSurfaceViewPort(Canvas canvas) { if (mCornerRadius > 0f) { canvas.getClipBounds(mTmpRect); + if (mClipSurfaceToBounds && mClipBounds != null) { + mTmpRect.intersect(mClipBounds); + } canvas.drawRoundRect(mTmpRect.left, mTmpRect.top, mTmpRect.right, mTmpRect.bottom, mCornerRadius, mCornerRadius, mRoundedViewportPaint); } else { @@ -582,6 +626,16 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } /** + * Returns the corner radius for the SurfaceView. + + * @return the radius of the corners in pixels + * @hide + */ + public float getCornerRadius() { + return mCornerRadius; + } + + /** * Control whether the surface view's surface is placed on top of another * regular surface view in the window (but still behind the window itself). * This is typically used to place overlays on top of an underlying media @@ -832,7 +886,11 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall // crop the buffer to the surface size since the buffer producer may // use SCALING_MODE_SCALE and submit a larger size than the surface // size. - mSurfaceControl.setWindowCrop(mSurfaceWidth, mSurfaceHeight); + if (mClipSurfaceToBounds && mClipBounds != null) { + mSurfaceControl.setWindowCrop(mClipBounds); + } else { + mSurfaceControl.setWindowCrop(mSurfaceWidth, mSurfaceHeight); + } } mSurfaceControl.setCornerRadius(mCornerRadius); if (sizeChanged && !creating) { |
