diff options
author | Chris Craik <ccraik@google.com> | 2014-07-29 12:50:14 -0700 |
---|---|---|
committer | Chris Craik <ccraik@google.com> | 2014-07-30 17:15:50 +0000 |
commit | af4d04cab6d48ae0d6a5e79bd30f679af87abaad (patch) | |
tree | b1fe9d83f5ccc32b1e0db8f002d2d3035368dfac | |
parent | 3d1856f4449f02a9a3bda06738c3eb83df96f88b (diff) | |
download | frameworks_base-af4d04cab6d48ae0d6a5e79bd30f679af87abaad.zip frameworks_base-af4d04cab6d48ae0d6a5e79bd30f679af87abaad.tar.gz frameworks_base-af4d04cab6d48ae0d6a5e79bd30f679af87abaad.tar.bz2 |
Use RoundRect clipping for circle reveal animation
bug:16630975
Also, remove inverse clipping feature from reveal animator.
Change-Id: I770a4eb48cd123b0ca0f39d16a0f3eefd1be3653
-rw-r--r-- | core/java/android/animation/RevealAnimator.java | 10 | ||||
-rw-r--r-- | core/java/android/view/RenderNode.java | 6 | ||||
-rw-r--r-- | core/java/android/view/RenderNodeAnimator.java | 9 | ||||
-rw-r--r-- | core/java/android/view/View.java | 11 | ||||
-rw-r--r-- | core/java/android/view/ViewAnimationUtils.java | 2 | ||||
-rw-r--r-- | core/jni/android_view_RenderNode.cpp | 6 | ||||
-rw-r--r-- | core/jni/android_view_RenderNodeAnimator.cpp | 7 | ||||
-rw-r--r-- | libs/hwui/Animator.cpp | 9 | ||||
-rw-r--r-- | libs/hwui/Animator.h | 2 | ||||
-rw-r--r-- | libs/hwui/DisplayListOp.h | 8 | ||||
-rwxr-xr-x | libs/hwui/OpenGLRenderer.cpp | 8 | ||||
-rw-r--r-- | libs/hwui/RenderNode.cpp | 32 | ||||
-rw-r--r-- | libs/hwui/RenderProperties.h | 13 | ||||
-rw-r--r-- | libs/hwui/RevealClip.h | 19 | ||||
-rw-r--r-- | libs/hwui/Snapshot.cpp | 29 | ||||
-rw-r--r-- | libs/hwui/Snapshot.h | 6 | ||||
-rw-r--r-- | libs/hwui/StatefulBaseRenderer.cpp | 19 | ||||
-rw-r--r-- | libs/hwui/StatefulBaseRenderer.h | 2 |
18 files changed, 84 insertions, 114 deletions
diff --git a/core/java/android/animation/RevealAnimator.java b/core/java/android/animation/RevealAnimator.java index 53d92e6..e363a77 100644 --- a/core/java/android/animation/RevealAnimator.java +++ b/core/java/android/animation/RevealAnimator.java @@ -30,7 +30,6 @@ public class RevealAnimator extends ValueAnimator { private View mClipView; private int mX, mY; - private boolean mInverseClip; private float mStartRadius, mEndRadius; private float mDelta; private boolean mMayRunAsync; @@ -41,14 +40,13 @@ public class RevealAnimator extends ValueAnimator { private RenderNodeAnimator mRtAnimator; public RevealAnimator(View clipView, int x, int y, - float startRadius, float endRadius, boolean inverseClip) { + float startRadius, float endRadius) { mClipView = clipView; mStartRadius = startRadius; mEndRadius = endRadius; mDelta = endRadius - startRadius; mX = x; mY = y; - mInverseClip = inverseClip; super.setValues(PropertyValuesHolder.ofFloat("radius", startRadius, endRadius)); } @@ -57,12 +55,12 @@ public class RevealAnimator extends ValueAnimator { super.animateValue(fraction); fraction = getAnimatedFraction(); float radius = mStartRadius + (mDelta * fraction); - mClipView.setRevealClip(true, mInverseClip, mX, mY, radius); + mClipView.setRevealClip(true, mX, mY, radius); } @Override protected void endAnimation(AnimationHandler handler) { - mClipView.setRevealClip(false, false, 0, 0, 0); + mClipView.setRevealClip(false, 0, 0, 0); super.endAnimation(handler); } @@ -92,7 +90,7 @@ public class RevealAnimator extends ValueAnimator { mRtAnimator = null; } if (canRunAsync()) { - mRtAnimator = new RenderNodeAnimator(mX, mY, mInverseClip, mStartRadius, mEndRadius); + mRtAnimator = new RenderNodeAnimator(mX, mY, mStartRadius, mEndRadius); mRtAnimator.setDuration(getDuration()); mRtAnimator.setInterpolator(getInterpolator()); mRtAnimator.setTarget(mClipView); diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java index 2d54acb..e9ec565 100644 --- a/core/java/android/view/RenderNode.java +++ b/core/java/android/view/RenderNode.java @@ -378,9 +378,9 @@ public class RenderNode { /** * Controls the RenderNode's circular reveal clip. */ - public boolean setRevealClip(boolean shouldClip, boolean inverseClip, + public boolean setRevealClip(boolean shouldClip, float x, float y, float radius) { - return nSetRevealClip(mNativeRenderNode, shouldClip, inverseClip, x, y, radius); + return nSetRevealClip(mNativeRenderNode, shouldClip, x, y, radius); } /** @@ -855,7 +855,7 @@ public class RenderNode { private static native boolean nSetOutlineNone(long renderNode); private static native boolean nSetClipToOutline(long renderNode, boolean clipToOutline); private static native boolean nSetRevealClip(long renderNode, - boolean shouldClip, boolean inverseClip, float x, float y, float radius); + boolean shouldClip, float x, float y, float radius); private static native boolean nSetAlpha(long renderNode, float alpha); private static native boolean nSetHasOverlappingRendering(long renderNode, boolean hasOverlappingRendering); diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java index 2a06336..c7f16e0 100644 --- a/core/java/android/view/RenderNodeAnimator.java +++ b/core/java/android/view/RenderNodeAnimator.java @@ -125,10 +125,9 @@ public class RenderNodeAnimator extends Animator { property.getNativeContainer(), paintField, finalValue)); } - public RenderNodeAnimator(int x, int y, boolean inverseClip, - float startRadius, float endRadius) { - init(nCreateRevealAnimator(new WeakReference<>(this), - x, y, inverseClip, startRadius, endRadius)); + public RenderNodeAnimator(int x, int y, float startRadius, float endRadius) { + init(nCreateRevealAnimator(new WeakReference<RenderNodeAnimator>(this), + x, y, startRadius, endRadius)); } private void init(long ptr) { @@ -333,7 +332,7 @@ public class RenderNodeAnimator extends Animator { private static native long nCreateCanvasPropertyPaintAnimator(WeakReference<RenderNodeAnimator> weakThis, long canvasProperty, int paintField, float finalValue); private static native long nCreateRevealAnimator(WeakReference<RenderNodeAnimator> weakThis, - int x, int y, boolean inverseClip, float startRadius, float endRadius); + int x, int y, float startRadius, float endRadius); private static native void nSetStartValue(long nativePtr, float startValue); private static native void nSetDuration(long nativePtr, long duration); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 16a161b..7e16c7d 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -10845,14 +10845,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, invalidateViewProperty(false, false); } - /** - * Private API to be used for reveal animation - * - * @hide - */ - public void setRevealClip(boolean shouldClip, boolean inverseClip, - float x, float y, float radius) { - mRenderNode.setRevealClip(shouldClip, inverseClip, x, y, radius); + /** @hide */ + public void setRevealClip(boolean shouldClip, float x, float y, float radius) { + mRenderNode.setRevealClip(shouldClip, x, y, radius); invalidateViewProperty(false, false); } diff --git a/core/java/android/view/ViewAnimationUtils.java b/core/java/android/view/ViewAnimationUtils.java index 0a53b91..ea3efb1 100644 --- a/core/java/android/view/ViewAnimationUtils.java +++ b/core/java/android/view/ViewAnimationUtils.java @@ -38,6 +38,6 @@ public final class ViewAnimationUtils { */ public static final Animator createCircularReveal(View view, int centerX, int centerY, float startRadius, float endRadius) { - return new RevealAnimator(view, centerX, centerY, startRadius, endRadius, false); + return new RevealAnimator(view, centerX, centerY, startRadius, endRadius); } } diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp index 3b6f0eb..ff54fb9 100644 --- a/core/jni/android_view_RenderNode.cpp +++ b/core/jni/android_view_RenderNode.cpp @@ -181,11 +181,11 @@ static jboolean android_view_RenderNode_setClipToOutline(JNIEnv* env, } static jboolean android_view_RenderNode_setRevealClip(JNIEnv* env, - jobject clazz, jlong renderNodePtr, jboolean shouldClip, jboolean inverseClip, + jobject clazz, jlong renderNodePtr, jboolean shouldClip, jfloat x, jfloat y, jfloat radius) { RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr); renderNode->mutateStagingProperties().mutableRevealClip().set( - shouldClip, inverseClip, x, y, radius); + shouldClip, x, y, radius); renderNode->setPropertyFieldsDirty(RenderNode::GENERIC); return true; } @@ -485,7 +485,7 @@ static JNINativeMethod gMethods[] = { { "nSetOutlineEmpty", "(J)Z", (void*) android_view_RenderNode_setOutlineEmpty }, { "nSetOutlineNone", "(J)Z", (void*) android_view_RenderNode_setOutlineNone }, { "nSetClipToOutline", "(JZ)Z", (void*) android_view_RenderNode_setClipToOutline }, - { "nSetRevealClip", "(JZZFFF)Z", (void*) android_view_RenderNode_setRevealClip }, + { "nSetRevealClip", "(JZFFF)Z", (void*) android_view_RenderNode_setRevealClip }, { "nSetAlpha", "(JF)Z", (void*) android_view_RenderNode_setAlpha }, { "nSetHasOverlappingRendering", "(JZ)Z", diff --git a/core/jni/android_view_RenderNodeAnimator.cpp b/core/jni/android_view_RenderNodeAnimator.cpp index 7c0c6ef..767534f 100644 --- a/core/jni/android_view_RenderNodeAnimator.cpp +++ b/core/jni/android_view_RenderNodeAnimator.cpp @@ -117,9 +117,8 @@ static jlong createCanvasPropertyPaintAnimator(JNIEnv* env, jobject clazz, } static jlong createRevealAnimator(JNIEnv* env, jobject clazz, jobject weakThis, - jint centerX, jint centerY, jboolean inverseClip, jfloat startRadius, jfloat endRadius) { - BaseRenderNodeAnimator* animator = new RevealAnimator(centerX, centerY, inverseClip, - startRadius, endRadius); + jint centerX, jint centerY, jfloat startRadius, jfloat endRadius) { + BaseRenderNodeAnimator* animator = new RevealAnimator(centerX, centerY, startRadius, endRadius); animator->setListener(new AnimationListenerBridge(env, weakThis)); return reinterpret_cast<jlong>( animator ); } @@ -180,7 +179,7 @@ static JNINativeMethod gMethods[] = { { "nCreateAnimator", "(Ljava/lang/ref/WeakReference;IF)J", (void*) createAnimator }, { "nCreateCanvasPropertyFloatAnimator", "(Ljava/lang/ref/WeakReference;JF)J", (void*) createCanvasPropertyFloatAnimator }, { "nCreateCanvasPropertyPaintAnimator", "(Ljava/lang/ref/WeakReference;JIF)J", (void*) createCanvasPropertyPaintAnimator }, - { "nCreateRevealAnimator", "(Ljava/lang/ref/WeakReference;IIZFF)J", (void*) createRevealAnimator }, + { "nCreateRevealAnimator", "(Ljava/lang/ref/WeakReference;IIFF)J", (void*) createRevealAnimator }, { "nSetStartValue", "(JF)V", (void*) setStartValue }, { "nSetDuration", "(JJ)V", (void*) setDuration }, { "nGetDuration", "(J)J", (void*) getDuration }, diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp index 24ed6cd..dd2e2fd 100644 --- a/libs/hwui/Animator.cpp +++ b/libs/hwui/Animator.cpp @@ -288,21 +288,20 @@ void CanvasPropertyPaintAnimator::setValue(RenderNode* target, float value) { LOG_ALWAYS_FATAL("Unknown field %d", (int) mField); } -RevealAnimator::RevealAnimator(int centerX, int centerY, bool inverseClip, +RevealAnimator::RevealAnimator(int centerX, int centerY, float startValue, float finalValue) : BaseRenderNodeAnimator(finalValue) , mCenterX(centerX) - , mCenterY(centerY) - , mInverseClip(inverseClip) { + , mCenterY(centerY) { setStartValue(startValue); } float RevealAnimator::getValue(RenderNode* target) const { - return target->properties().getRevealClip().radius(); + return target->properties().getRevealClip().getRadius(); } void RevealAnimator::setValue(RenderNode* target, float value) { - target->animatorProperties().mutableRevealClip().set(true, mInverseClip, + target->animatorProperties().mutableRevealClip().set(true, mCenterX, mCenterY, value); } diff --git a/libs/hwui/Animator.h b/libs/hwui/Animator.h index 9a080a7..b0dcf2d 100644 --- a/libs/hwui/Animator.h +++ b/libs/hwui/Animator.h @@ -171,7 +171,7 @@ private: class RevealAnimator : public BaseRenderNodeAnimator { public: - ANDROID_API RevealAnimator(int centerX, int centerY, bool inverseClip, + ANDROID_API RevealAnimator(int centerX, int centerY, float startValue, float finalValue); protected: virtual float getValue(RenderNode* target) const; diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index 9f66904..777a35a 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -1535,10 +1535,9 @@ private: class DrawShadowOp : public DrawOp { public: DrawShadowOp(const mat4& transformXY, const mat4& transformZ, - float casterAlpha, bool casterUnclipped, - const SkPath* casterOutline, const SkPath* revealClip) + float casterAlpha, const SkPath* casterOutline, const SkPath* revealClip) : DrawOp(NULL), mTransformXY(transformXY), mTransformZ(transformZ), - mCasterAlpha(casterAlpha), mCasterUnclipped(casterUnclipped) { + mCasterAlpha(casterAlpha) { mOutline = *casterOutline; if (revealClip) { // intersect the outline with the convex reveal clip @@ -1572,12 +1571,11 @@ public: virtual const char* name() { return "DrawShadow"; } private: - bool isCasterOpaque() { return mCasterAlpha >= 1.0f && mCasterUnclipped; } + bool isCasterOpaque() { return mCasterAlpha >= 1.0f; } const mat4 mTransformXY; const mat4 mTransformZ; const float mCasterAlpha; - const bool mCasterUnclipped; SkPath mOutline; }; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index de777f0..5e6ae3f 100755 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -1742,12 +1742,12 @@ void OpenGLRenderer::setupDrawProgram() { if (mDescription.hasRoundRectClip) { // TODO: avoid doing this repeatedly, stashing state pointer in program const RoundRectClipState* state = mSnapshot->roundRectClipState; - const Rect& innerRect = state->outlineInnerRect; + const Rect& innerRect = state->innerRect; glUniform4f(mCaches.currentProgram->getUniform("roundRectInnerRectLTRB"), - innerRect.left, innerRect.top, - innerRect.right, innerRect.bottom); + innerRect.left, innerRect.top, + innerRect.right, innerRect.bottom); glUniform1f(mCaches.currentProgram->getUniform("roundRectRadius"), - state->outlineRadius); + state->radius); glUniformMatrix4fv(mCaches.currentProgram->getUniform("roundRectInvTransform"), 1, GL_FALSE, &state->matrix.data[0]); } diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index 1df2055..0662ca2 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -384,11 +384,15 @@ void RenderNode::setViewProperties(OpenGLRenderer& renderer, T& handler) { handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds()); } - if (CC_UNLIKELY(properties().hasClippingPath())) { - ClipPathOp* op = new (handler.allocator()) ClipPathOp( - properties().getClippingPath(), properties().getClippingPathOp()); - handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds()); + // TODO: support both reveal clip and outline clip simultaneously + if (mProperties.getRevealClip().willClip()) { + Rect bounds; + mProperties.getRevealClip().getBounds(&bounds); + renderer.setClippingRoundRect(handler.allocator(), bounds, mProperties.getRevealClip().getRadius()); + } else if (mProperties.getOutline().willClip()) { + renderer.setClippingOutline(handler.allocator(), &(mProperties.getOutline())); } + } /** @@ -600,23 +604,11 @@ void RenderNode::issueDrawShadowOperation(const Matrix4& transformFromParent, T& applyViewPropertyTransforms(shadowMatrixZ, true); const SkPath* outlinePath = properties().getOutline().getPath(); - const RevealClip& revealClip = properties().getRevealClip(); - const SkPath* revealClipPath = revealClip.hasConvexClip() - ? revealClip.getPath() : NULL; // only pass the reveal clip's path if it's convex - + const SkPath* revealClipPath = properties().getRevealClip().getPath(); if (revealClipPath && revealClipPath->isEmpty()) return; - /** - * The drawing area of the caster is always the same as the its perimeter (which - * the shadow system uses) *except* in the inverse clip case. Inform the shadow - * system that the caster's drawing area (as opposed to its perimeter) has been - * clipped, so that it knows the caster can't be opaque. - */ - bool casterUnclipped = !revealClip.willClip() || revealClip.hasConvexClip(); - DisplayListOp* shadowOp = new (handler.allocator()) DrawShadowOp( - shadowMatrixXY, shadowMatrixZ, - properties().getAlpha(), casterUnclipped, + shadowMatrixXY, shadowMatrixZ, properties().getAlpha(), outlinePath, revealClipPath); handler(shadowOp, PROPERTY_SAVECOUNT, properties().getClipToBounds()); } @@ -828,10 +820,6 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) { bool quickRejected = properties().getClipToBounds() && renderer.quickRejectConservative(0, 0, properties().getWidth(), properties().getHeight()); if (!quickRejected) { - if (mProperties.getOutline().willClip()) { - renderer.setClippingOutline(alloc, &(mProperties.getOutline())); - } - if (drawLayer) { handler(new (alloc) DrawLayerOp(mLayer, 0, 0), renderer.getSaveCount() - 1, properties().getClipToBounds()); diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h index f50e514..9898bde 100644 --- a/libs/hwui/RenderProperties.h +++ b/libs/hwui/RenderProperties.h @@ -546,19 +546,6 @@ public: void updateMatrix(); - bool hasClippingPath() const { - return mPrimitiveFields.mRevealClip.willClip(); - } - - const SkPath* getClippingPath() const { - return mPrimitiveFields.mRevealClip.getPath(); - } - - SkRegion::Op getClippingPathOp() const { - return mPrimitiveFields.mRevealClip.isInverseClip() - ? SkRegion::kDifference_Op : SkRegion::kIntersect_Op; - } - Outline& mutableOutline() { return mPrimitiveFields.mOutline; } diff --git a/libs/hwui/RevealClip.h b/libs/hwui/RevealClip.h index 07404cb..a9600f1 100644 --- a/libs/hwui/RevealClip.h +++ b/libs/hwui/RevealClip.h @@ -27,14 +27,12 @@ class RevealClip { public: RevealClip() : mShouldClip(false) - , mInverseClip(false) , mX(0) , mY(0) , mRadius(0) {} - void set(bool shouldClip, bool inverseClip, float x, float y, float radius) { + void set(bool shouldClip, float x, float y, float radius) { mShouldClip = shouldClip; - mInverseClip = inverseClip; mX = x; mY = y; mRadius = radius; @@ -45,21 +43,15 @@ public: } } - bool hasConvexClip() const { - return mShouldClip && !mInverseClip; - } - - bool isInverseClip() const { - return mInverseClip; - } - bool willClip() const { return mShouldClip; } - float radius() const { - return mRadius; + void getBounds(Rect* outBounds) const { + outBounds->set(mX - mRadius, mY - mRadius, + mX + mRadius, mY + mRadius); } + float getRadius() const { return mRadius; } const SkPath* getPath() const { if (!mShouldClip) return NULL; @@ -69,7 +61,6 @@ public: private: bool mShouldClip; - bool mInverseClip; float mX; float mY; float mRadius; diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp index 80f7eca..6f19275 100644 --- a/libs/hwui/Snapshot.cpp +++ b/libs/hwui/Snapshot.cpp @@ -20,8 +20,6 @@ #include <SkCanvas.h> -#include "utils/MathUtils.h" - namespace android { namespace uirenderer { @@ -207,23 +205,22 @@ void Snapshot::resetTransform(float x, float y, float z) { } /////////////////////////////////////////////////////////////////////////////// -// Clipping outline +// Clipping round rect /////////////////////////////////////////////////////////////////////////////// -void Snapshot::setClippingOutline(LinearAllocator& allocator, const Outline* outline) { - Rect bounds; - float radius; - if (!outline->getAsRoundRect(&bounds, &radius)) return; // only RR supported - - if (!MathUtils::isPositive(radius)) return; // leave clipping up to rect clipping +void Snapshot::setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds, float radius) { + if (bounds.isEmpty()) { + clipRect->setEmpty(); + return; + } RoundRectClipState* state = new (allocator) RoundRectClipState; // store the inverse drawing matrix - Matrix4 outlineDrawingMatrix; - outlineDrawingMatrix.load(getOrthoMatrix()); - outlineDrawingMatrix.multiply(*transform); - state->matrix.loadInverse(outlineDrawingMatrix); + Matrix4 roundRectDrawingMatrix; + roundRectDrawingMatrix.load(getOrthoMatrix()); + roundRectDrawingMatrix.multiply(*transform); + state->matrix.loadInverse(roundRectDrawingMatrix); // compute area under rounded corners - only draws overlapping these rects need to be clipped for (int i = 0 ; i < 4; i++) { @@ -241,9 +238,9 @@ void Snapshot::setClippingOutline(LinearAllocator& allocator, const Outline* out } // store RR area - bounds.inset(radius); - state->outlineInnerRect = bounds; - state->outlineRadius = radius; + state->innerRect = bounds; + state->innerRect.inset(radius); + state->radius = radius; // store as immutable so, for this frame, pointer uniquely identifies this bundle of shader info roundRectClipState = state; diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h index 5426e89..98e2440 100644 --- a/libs/hwui/Snapshot.h +++ b/libs/hwui/Snapshot.h @@ -57,8 +57,8 @@ public: Matrix4 matrix; Rect dangerRects[4]; - Rect outlineInnerRect; - float outlineRadius; + Rect innerRect; + float radius; }; /** @@ -164,7 +164,7 @@ public: /** * Sets (and replaces) the current clipping outline */ - void setClippingOutline(LinearAllocator& allocator, const Outline* outline); + void setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds, float radius); /** * Indicates whether this snapshot should be ignored. A snapshot diff --git a/libs/hwui/StatefulBaseRenderer.cpp b/libs/hwui/StatefulBaseRenderer.cpp index 473005c..dc41157 100644 --- a/libs/hwui/StatefulBaseRenderer.cpp +++ b/libs/hwui/StatefulBaseRenderer.cpp @@ -20,6 +20,8 @@ #include "StatefulBaseRenderer.h" +#include "utils/MathUtils.h" + namespace android { namespace uirenderer { @@ -189,9 +191,24 @@ bool StatefulBaseRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) { } void StatefulBaseRenderer::setClippingOutline(LinearAllocator& allocator, const Outline* outline) { - mSnapshot->setClippingOutline(allocator, outline); + Rect bounds; + float radius; + if (!outline->getAsRoundRect(&bounds, &radius)) return; // only RR supported + + if (!MathUtils::isPositive(radius)) { + // TODO: consider storing this rect separately, so that this can't be replaced with clip ops + clipRect(bounds.left, bounds.top, bounds.right, bounds.bottom, SkRegion::kIntersect_Op); + return; + } + setClippingRoundRect(allocator, bounds, radius); } +void StatefulBaseRenderer::setClippingRoundRect(LinearAllocator& allocator, + const Rect& rect, float radius) { + mSnapshot->setClippingRoundRect(allocator, rect, radius); +} + + /////////////////////////////////////////////////////////////////////////////// // Quick Rejection /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/StatefulBaseRenderer.h b/libs/hwui/StatefulBaseRenderer.h index 25cc832..6d83b4c 100644 --- a/libs/hwui/StatefulBaseRenderer.h +++ b/libs/hwui/StatefulBaseRenderer.h @@ -96,6 +96,8 @@ public: * The clipping outline is independent from the regular clip. */ void setClippingOutline(LinearAllocator& allocator, const Outline* outline); + void setClippingRoundRect(LinearAllocator& allocator, + const Rect& rect, float radius); protected: const Rect& getRenderTargetClipBounds() const { return mSnapshot->getRenderTargetClip(); } |