Merge "Support frame-synchronized clipping on SurfaceView"
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user