Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0645128b authored by Chris Craik's avatar Chris Craik
Browse files

Make setter methods on Outline call setEmpty() based on params

bug:16142564

Additionally, better define behavior around null outline providers:

A view with an empty outline, and setClipToOutline=true will not be
rendered, though one with a null outline provider
(and thus no outline) will be.

Change-Id: Ic9549841b107b2eb51b417c66058a0cd69dd89eb
parent 94ca6cd7
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -346,7 +346,9 @@ public class RenderNode {
     * Deep copies the data into native to simplify reference ownership.
     */
    public boolean setOutline(Outline outline) {
        if (outline == null || outline.isEmpty()) {
        if (outline == null) {
            return nSetOutlineNone(mNativeRenderNode);
        } else if (outline.isEmpty()) {
            return nSetOutlineEmpty(mNativeRenderNode);
        } else if (outline.mRect != null) {
            return nSetOutlineRoundRect(mNativeRenderNode, outline.mRect.left, outline.mRect.top,
@@ -878,6 +880,7 @@ public class RenderNode {
            int right, int bottom, float radius);
    private static native boolean nSetOutlineConvexPath(long renderNode, long nativePath);
    private static native boolean nSetOutlineEmpty(long 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);
+9 −0
Original line number Diff line number Diff line
@@ -152,6 +152,14 @@ static jboolean android_view_RenderNode_setOutlineEmpty(JNIEnv* env,
    return true;
}

static jboolean android_view_RenderNode_setOutlineNone(JNIEnv* env,
        jobject clazz, jlong renderNodePtr) {
    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
    renderNode->mutateStagingProperties().mutableOutline().setNone();
    renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
    return true;
}

static jboolean android_view_RenderNode_setClipToOutline(JNIEnv* env,
        jobject clazz, jlong renderNodePtr, jboolean clipToOutline) {
    RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
@@ -485,6 +493,7 @@ static JNINativeMethod gMethods[] = {
    { "nSetOutlineRoundRect",  "(JIIIIF)Z", (void*) android_view_RenderNode_setOutlineRoundRect },
    { "nSetOutlineConvexPath", "(JJ)Z",  (void*) android_view_RenderNode_setOutlineConvexPath },
    { "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 },

+16 −0
Original line number Diff line number Diff line
@@ -155,6 +155,11 @@ public final class Outline {
     * Passing a zero radius is equivalent to calling {@link #setRect(int, int, int, int)}
     */
    public void setRoundRect(int left, int top, int right, int bottom, float radius) {
        if (left >= right || top >= bottom) {
            setEmpty();
            return;
        }

        if (mRect == null) mRect = new Rect();
        mRect.set(left, top, right, bottom);
        mRadius = radius;
@@ -173,11 +178,17 @@ public final class Outline {
     * Sets the outline to the oval defined by input rect.
     */
    public void setOval(int left, int top, int right, int bottom) {
        if (left >= right || top >= bottom) {
            setEmpty();
            return;
        }

        if ((bottom - top) == (right - left)) {
            // represent circle as round rect, for efficiency, and to enable clipping
            setRoundRect(left, top, right, bottom, (bottom - top) / 2.0f);
            return;
        }

        if (mPath == null) mPath = new Path();
        mPath.reset();
        mPath.addOval(left, top, right, bottom, Path.Direction.CW);
@@ -196,6 +207,11 @@ public final class Outline {
     * Sets the Constructs an Outline from a {@link android.graphics.Path#isConvex() convex path}.
     */
    public void setConvexPath(@NonNull Path convexPath) {
        if (convexPath.isEmpty()) {
            setEmpty();
            return;
        }

        if (!convexPath.isConvex()) {
            throw new IllegalArgumentException("path must be convex");
        }
+12 −6
Original line number Diff line number Diff line
@@ -49,15 +49,20 @@ public:
        mBounds.set(outline->getBounds());
    }

    bool isEmpty() const {
        return mType == kOutlineType_None;
    void setEmpty() {
        mType = kOutlineType_Empty;
        mPath.reset();
    }

    void setEmpty() {
    void setNone() {
        mType = kOutlineType_None;
        mPath.reset();
    }

    bool isEmpty() const {
        return mType == kOutlineType_Empty;
    }

    void setShouldClip(bool clip) {
        mShouldClip = clip;
    }
@@ -81,7 +86,7 @@ public:
    }

    const SkPath* getPath() const {
        if (mType == kOutlineType_None) return NULL;
        if (mType == kOutlineType_None || mType == kOutlineType_Empty) return NULL;

        return &mPath;
    }
@@ -89,8 +94,9 @@ public:
private:
    enum OutlineType {
        kOutlineType_None = 0,
        kOutlineType_ConvexPath = 1,
        kOutlineType_RoundRect = 2
        kOutlineType_Empty = 1,
        kOutlineType_ConvexPath = 2,
        kOutlineType_RoundRect = 3
    };

    bool mShouldClip;
+13 −6
Original line number Diff line number Diff line
@@ -581,7 +581,7 @@ void RenderNode::buildZSortedChildList(Vector<ZDrawRenderNodeOpPair>& zTranslate

template <class T>
void RenderNode::issueDrawShadowOperation(const Matrix4& transformFromParent, T& handler) {
    if (properties().getAlpha() <= 0.0f || properties().getOutline().isEmpty()) return;
    if (properties().getAlpha() <= 0.0f || !properties().getOutline().getPath()) return;

    mat4 shadowMatrixXY(transformFromParent);
    applyViewPropertyTransforms(shadowMatrixXY);
@@ -776,17 +776,24 @@ void RenderNode::issueOperationsOfProjectedChildren(OpenGLRenderer& renderer, T&
 */
template <class T>
void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) {
    const int level = handler.level();
    if (mDisplayListData->isEmpty()) {
        DISPLAY_LIST_LOGD("%*sEmpty display list (%p, %s)", level * 2, "", this, getName());
        return;
    }

    const bool drawLayer = (mLayer && (&renderer != mLayer->renderer));
    // If we are updating the contents of mLayer, we don't want to apply any of
    // the RenderNode's properties to this issueOperations pass. Those will all
    // be applied when the layer is drawn, aka when this is true.
    const bool useViewProperties = (!mLayer || drawLayer);

    const int level = handler.level();
    if (mDisplayListData->isEmpty() || (useViewProperties && properties().getAlpha() <= 0)) {
        DISPLAY_LIST_LOGD("%*sEmpty display list (%p, %s)", level * 2, "", this, getName());
    if (useViewProperties) {
        const Outline& outline = properties().getOutline();
        if (properties().getAlpha() <= 0 || (outline.getShouldClip() && outline.isEmpty())) {
            DISPLAY_LIST_LOGD("%*sRejected display list (%p, %s)", level * 2, "", this, getName());
            return;
        }
    }

    handler.startMark(getName());