summaryrefslogtreecommitdiff
path: root/core/java/android/view/SurfaceView.java
diff options
context:
space:
mode:
authorMark Renouf <mrenouf@google.com>2019-08-12 16:22:15 -0400
committerMark Renouf <mrenouf@google.com>2019-09-18 14:47:03 -0400
commite574ad09ee145a65ec2340395c275b21a538312f (patch)
tree4538f64be03f55de043c06a52cae14bd575e9a39 /core/java/android/view/SurfaceView.java
parentdf0f3bce7ef4568c8408204b01e61e4166d07a97 (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.java60
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) {