Merge "Support frame-synchronized clipping on SurfaceView"

This commit is contained in:
Mark Renouf
2019-10-02 15:03:15 +00:00
committed by Android (Google) Code Review
2 changed files with 101 additions and 1 deletions

View File

@@ -29,6 +29,7 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.Insets;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.Region;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
@@ -101,6 +102,8 @@ public class ActivityView extends ViewGroup {
private Insets mForwardedInsets;
private float mCornerRadius;
public ActivityView(Context context) {
this(context, null /* attrs */);
}
@@ -203,6 +206,45 @@ public class ActivityView extends ViewGroup {
mSurfaceView.setCornerRadius(cornerRadius);
}
/**
* @hide
*/
public float getCornerRadius() {
return mSurfaceView.getCornerRadius();
}
/**
* Control whether the surface is clipped to the same bounds as the View. If true, then
* the bounds set by {@link #setSurfaceClipBounds(Rect)} are applied to the surface as
* window-crop.
*
* @param clippingEnabled whether to enable surface clipping
* @hide
*/
public void setSurfaceClippingEnabled(boolean clippingEnabled) {
mSurfaceView.setEnableSurfaceClipping(clippingEnabled);
}
/**
* Sets an area on the contained surface to which it will be clipped
* when it is drawn. Setting the value to null will remove the clip bounds
* and the surface will draw normally, using its full bounds.
*
* @param clipBounds The rectangular area, in the local coordinates of
* this view, to which future drawing operations will be clipped.
* @hide
*/
public void setSurfaceClipBounds(Rect clipBounds) {
mSurfaceView.setClipBounds(clipBounds);
}
/**
* @hide
*/
public boolean getSurfaceClipBounds(Rect outRect) {
return mSurfaceView.getClipBounds(outRect);
}
/**
* Launch a new activity into this container.
* <p>Activity resolved by the provided {@link Intent} must have

View File

@@ -167,6 +167,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
boolean mUseAlpha = false;
float mSurfaceAlpha = 1f;
boolean mClipSurfaceToBounds;
@UnsupportedAppUsage
boolean mHaveFrame = false;
@@ -555,9 +556,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
invalidate();
}
/**
* 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).
@@ -840,7 +894,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) {