diff options
author | 2014-09-03 17:52:24 -0700 | |
---|---|---|
committer | 2014-09-04 14:05:10 -0700 | |
commit | e83cbd451868a734bfac07ccd680d5617080b579 (patch) | |
tree | eb2c39e190850694b67ad3f6e810a08f63e60282 | |
parent | 01abcaa295fc4eec7442a575d160b0ce2c250127 (diff) |
Prioritize reveal clipping over Outline clipping
bug:15780987
bug:17350602
Also update docs around clipping nesting behavior,
and some Z ordering behavior.
Change-Id: Iaa204350a0adfdcbd8c4b821fb4a9c0ae22f2613
-rw-r--r-- | core/java/android/view/View.java | 23 | ||||
-rw-r--r-- | core/java/android/view/ViewAnimationUtils.java | 10 | ||||
-rw-r--r-- | core/java/android/view/ViewGroup.java | 3 | ||||
-rw-r--r-- | libs/hwui/RenderNode.cpp | 3 | ||||
-rw-r--r-- | libs/hwui/Snapshot.cpp | 10 | ||||
-rw-r--r-- | libs/hwui/Snapshot.h | 6 | ||||
-rw-r--r-- | libs/hwui/StatefulBaseRenderer.cpp | 6 | ||||
-rw-r--r-- | libs/hwui/StatefulBaseRenderer.h | 2 |
8 files changed, 45 insertions, 18 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index fce6f0b8f1ff..973483132f94 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -444,16 +444,19 @@ import java.util.concurrent.atomic.AtomicInteger; * <a name="Drawing"></a> * <h3>Drawing</h3> * <p> - * Drawing is handled by walking the tree and rendering each view that - * intersects the invalid region. Because the tree is traversed in-order, - * this means that parents will draw before (i.e., behind) their children, with - * siblings drawn in the order they appear in the tree. - * If you set a background drawable for a View, then the View will draw it for you - * before calling back to its <code>onDraw()</code> method. + * Drawing is handled by walking the tree and recording the drawing commands of + * any View that needs to update. After this, the drawing commands of the + * entire tree are issued to screen, clipped to the newly damaged area. * </p> * * <p> - * Note that the framework will not draw views that are not in the invalid region. + * The tree is largely recorded and drawn in order, with parents drawn before + * (i.e., behind) their children, with siblings drawn in the order they appear + * in the tree. If you set a background drawable for a View, then the View will + * draw it before calling back to its <code>onDraw()</code> method. The child + * drawing order can be overridden with + * {@link ViewGroup#setChildrenDrawingOrderEnabled(boolean) custom child drawing order} + * in a ViewGroup, and with {@link #setZ(float)} custom Z values} set on Views. * </p> * * <p> @@ -10852,6 +10855,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * Sets whether the View's Outline should be used to clip the contents of the View. * <p> + * Only a single non-rectangular clip can be applied on a View at any time. + * Circular clips from a {@link ViewAnimationUtils#createCircularReveal(View, int, int, float, float) + * circular reveal} animation take priority over Outline clipping, and + * child Outline clipping takes priority over Outline clipping done by a + * parent. + * <p> * Note that this flag will only be respected if the View's Outline returns true from * {@link Outline#canClip()}. * diff --git a/core/java/android/view/ViewAnimationUtils.java b/core/java/android/view/ViewAnimationUtils.java index 7ced0889cdd5..001cd01646a9 100644 --- a/core/java/android/view/ViewAnimationUtils.java +++ b/core/java/android/view/ViewAnimationUtils.java @@ -27,9 +27,13 @@ public final class ViewAnimationUtils { private ViewAnimationUtils() {} /** * Returns an Animator which can animate a clipping circle. - * + * <p> * Any shadow cast by the View will respect the circular clip from this animator. - * + * <p> + * Only a single non-rectangular clip can be applied on a View at any time. + * Views clipped by a circular reveal animation take priority over + * {@link View#setClipToOutline(boolean) View Outline clipping}. + * <p> * Note that the animation returned here is a one-shot animation. It cannot * be re-used, and once started it cannot be paused or resumed. * @@ -39,7 +43,7 @@ public final class ViewAnimationUtils { * @param startRadius The starting radius of the animating circle. * @param endRadius The ending radius of the animating circle. */ - public static final Animator createCircularReveal(View view, + public static Animator createCircularReveal(View view, int centerX, int centerY, float startRadius, float endRadius) { return new RevealAnimator(view, centerX, centerY, startRadius, endRadius); } diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index adad08242e62..974fe4e0c89f 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -5034,6 +5034,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager /** * Tells the ViewGroup whether to draw its children in the order defined by the method * {@link #getChildDrawingOrder(int, int)}. + * <p> + * Note that {@link View#getZ() Z} reordering, done by {@link #dispatchDraw(Canvas)}, + * will override custom child ordering done via this method. * * @param enabled true if the order of the children when drawing is determined by * {@link #getChildDrawingOrder(int, int)}, false otherwise diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index 72786eb0eecc..7c29f48d62f6 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -405,7 +405,7 @@ void RenderNode::setViewProperties(OpenGLRenderer& renderer, T& handler) { handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds()); } - // TODO: support both reveal clip and outline clip simultaneously + // TODO: support nesting round rect clips if (mProperties.getRevealClip().willClip()) { Rect bounds; mProperties.getRevealClip().getBounds(&bounds); @@ -413,7 +413,6 @@ void RenderNode::setViewProperties(OpenGLRenderer& renderer, T& handler) { } else if (mProperties.getOutline().willClip()) { renderer.setClippingOutline(handler.allocator(), &(mProperties.getOutline())); } - } /** diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp index ecc47d29a647..cf8229fdffb9 100644 --- a/libs/hwui/Snapshot.cpp +++ b/libs/hwui/Snapshot.cpp @@ -216,14 +216,22 @@ void Snapshot::resetTransform(float x, float y, float z) { // Clipping round rect /////////////////////////////////////////////////////////////////////////////// -void Snapshot::setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds, float radius) { +void Snapshot::setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds, + float radius, bool highPriority) { if (bounds.isEmpty()) { clipRect->setEmpty(); return; } + if (roundRectClipState && roundRectClipState->highPriority) { + // ignore, don't replace, already have a high priority clip + return; + } + RoundRectClipState* state = new (allocator) RoundRectClipState; + state->highPriority = highPriority; + // store the inverse drawing matrix Matrix4 roundRectDrawingMatrix; roundRectDrawingMatrix.load(getOrthoMatrix()); diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h index ad4ee9dee6a0..549de9baa21b 100644 --- a/libs/hwui/Snapshot.h +++ b/libs/hwui/Snapshot.h @@ -55,6 +55,7 @@ public: || rect.intersects(dangerRects[3]); } + bool highPriority; Matrix4 matrix; Rect dangerRects[4]; Rect innerRect; @@ -166,8 +167,11 @@ public: /** * Sets (and replaces) the current clipping outline + * + * If the current round rect clip is high priority, the incoming clip is ignored. */ - void setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds, float radius); + void setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds, + float radius, bool highPriority); /** * Indicates whether this snapshot should be ignored. A snapshot diff --git a/libs/hwui/StatefulBaseRenderer.cpp b/libs/hwui/StatefulBaseRenderer.cpp index 3e1aed3dfa01..12b8c8db28ea 100644 --- a/libs/hwui/StatefulBaseRenderer.cpp +++ b/libs/hwui/StatefulBaseRenderer.cpp @@ -198,13 +198,13 @@ void StatefulBaseRenderer::setClippingOutline(LinearAllocator& allocator, const clipRect(bounds.left, bounds.top, bounds.right, bounds.bottom, SkRegion::kIntersect_Op); } if (outlineIsRounded) { - setClippingRoundRect(allocator, bounds, radius); + setClippingRoundRect(allocator, bounds, radius, false); } } void StatefulBaseRenderer::setClippingRoundRect(LinearAllocator& allocator, - const Rect& rect, float radius) { - mSnapshot->setClippingRoundRect(allocator, rect, radius); + const Rect& rect, float radius, bool highPriority) { + mSnapshot->setClippingRoundRect(allocator, rect, radius, highPriority); } diff --git a/libs/hwui/StatefulBaseRenderer.h b/libs/hwui/StatefulBaseRenderer.h index c6974b4d39de..745e48a8759f 100644 --- a/libs/hwui/StatefulBaseRenderer.h +++ b/libs/hwui/StatefulBaseRenderer.h @@ -97,7 +97,7 @@ public: */ void setClippingOutline(LinearAllocator& allocator, const Outline* outline); void setClippingRoundRect(LinearAllocator& allocator, - const Rect& rect, float radius); + const Rect& rect, float radius, bool highPriority = true); inline const mat4* currentTransform() const { return mSnapshot->transform; |