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

Commit b49f446c authored by Chris Craik's avatar Chris Craik
Browse files

Rework Outline API, remove isolatedZVolume remnants

Change-Id: I30c2fe832dcb98fa6329b1a595b3d3aafbdcad6b
parent ac6e97a5
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -9792,6 +9792,13 @@ package android.graphics {
    method public void setPaint(android.graphics.Paint);
  }
  public class Outline {
    ctor public Outline();
    method public final boolean isValid();
    method public void set(android.graphics.Outline);
    method public void setRoundRect(int, int, int, int, float);
  }
  public class Paint {
    ctor public Paint();
    ctor public Paint(int);
@@ -10501,6 +10508,7 @@ package android.graphics.drawable {
    method public int getMinimumHeight();
    method public int getMinimumWidth();
    method public abstract int getOpacity();
    method public android.graphics.Outline getOutline();
    method public boolean getPadding(android.graphics.Rect);
    method public int[] getState();
    method public android.graphics.Region getTransparentRegion();
@@ -29097,7 +29105,6 @@ package android.view {
    method public int getNextFocusRightId();
    method public int getNextFocusUpId();
    method public android.view.View.OnFocusChangeListener getOnFocusChangeListener();
    method public final void getOutline(android.graphics.Path);
    method public int getOverScrollMode();
    method public android.view.ViewOverlay getOverlay();
    method public int getPaddingBottom();
@@ -29361,7 +29368,7 @@ package android.view {
    method public void setOnLongClickListener(android.view.View.OnLongClickListener);
    method public void setOnSystemUiVisibilityChangeListener(android.view.View.OnSystemUiVisibilityChangeListener);
    method public void setOnTouchListener(android.view.View.OnTouchListener);
    method public void setOutline(android.graphics.Path);
    method public void setOutline(android.graphics.Outline);
    method public void setOverScrollMode(int);
    method public void setPadding(int, int, int, int);
    method public void setPaddingRelative(int, int, int, int);
+18 −20
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@
package android.view;

import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.Outline;

/**
 * <p>A display list records a series of graphics related operations and can replay
@@ -310,16 +310,6 @@ public class RenderNode {
        nSetClipToBounds(mNativeDisplayList, clipToBounds);
    }

    /**
     * Set whether the display list should collect and Z order all 3d composited descendents, and
     * draw them in order with the default Z=0 content.
     *
     * @param isolatedZVolume true if the display list should collect and Z order descendents.
     */
    public void setIsolatedZVolume(boolean isolatedZVolume) {
        nSetIsolatedZVolume(mNativeDisplayList, isolatedZVolume);
    }

    /**
     * Sets whether the display list should be drawn immediately after the
     * closest ancestor display list where isolateZVolume is true. If the
@@ -346,13 +336,19 @@ public class RenderNode {
     * Sets the outline, defining the shape that casts a shadow, and the path to
     * be clipped if setClipToOutline is set.
     *
     * Deep copies the native path to simplify reference ownership.
     *
     * @param outline Convex, CW Path to store in the DisplayList. May be null.
     * Deep copies the data into native to simplify reference ownership.
     */
    public void setOutline(Path outline) {
        long nativePath = (outline == null) ? 0 : outline.mNativePath;
        nSetOutline(mNativeDisplayList, nativePath);
    public void setOutline(Outline outline) {
        if (outline == null) {
            nSetOutlineEmpty(mNativeDisplayList);
        } else if (!outline.isValid()) {
            throw new IllegalArgumentException("Outline must be valid");
        } else if (outline.mRect != null) {
            nSetOutlineRoundRect(mNativeDisplayList, outline.mRect.left, outline.mRect.top,
                    outline.mRect.right, outline.mRect.bottom, outline.mRadius);
        } else if (outline.mPath != null) {
            nSetOutlineConvexPath(mNativeDisplayList, outline.mPath.mNativePath);
        }
    }

    /**
@@ -855,8 +851,10 @@ public class RenderNode {
    private static native void nSetClipToBounds(long displayList, boolean clipToBounds);
    private static native void nSetProjectBackwards(long displayList, boolean shouldProject);
    private static native void nSetProjectionReceiver(long displayList, boolean shouldRecieve);
    private static native void nSetIsolatedZVolume(long displayList, boolean isolateZVolume);
    private static native void nSetOutline(long displayList, long nativePath);
    private static native void nSetOutlineRoundRect(long displayList, int left, int top,
            int right, int bottom, float radius);
    private static native void nSetOutlineConvexPath(long displayList, long nativePath);
    private static native void nSetOutlineEmpty(long displayList);
    private static native void nSetClipToOutline(long displayList, boolean clipToOutline);
    private static native void nSetAlpha(long displayList, float alpha);
    private static native void nSetHasOverlappingRendering(long displayList,
+44 −62
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.graphics.Insets;
import android.graphics.Interpolator;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
@@ -2376,15 +2377,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     */
    static final int PFLAG3_CLIP_TO_OUTLINE = 0x20;
    /**
     * Flag indicating that a view's outline has been specifically defined.
     */
    static final int PFLAG3_OUTLINE_DEFINED = 0x40;
    /**
     * Flag indicating that we're in the process of applying window insets.
     */
    static final int PFLAG3_APPLYING_INSETS = 0x40;
    static final int PFLAG3_APPLYING_INSETS = 0x80;
    /**
     * Flag indicating that we're in the process of fitting system windows using the old method.
     */
    static final int PFLAG3_FITTING_SYSTEM_WINDOWS = 0x80;
    static final int PFLAG3_FITTING_SYSTEM_WINDOWS = 0x100;
    /* End of masks for mPrivateFlags3 */
@@ -3335,8 +3341,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    /**
     * Stores the outline of the view, passed down to the DisplayList level for
     * defining shadow shape and clipping.
     *
     * TODO: once RenderNode is long-lived, remove this and rely on native copy.
     */
    private Path mOutline;
    private Outline mOutline;
    /**
     * When this view has focus and the next focus is {@link #FOCUS_LEFT},
@@ -10801,67 +10809,45 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        }
    }
    /**
     * Copies the Outline of the View into the Path parameter.
     * <p>
     * If the outline is not set, the parameter Path is set to empty.
     *
     * @param outline Path into which View's outline will be copied. Must be non-null.
     *
     * @see #setOutline(Path)
     * @see #getClipToOutline()
     * @see #setClipToOutline(boolean)
     */
    public final void getOutline(@NonNull Path outline) {
        if (outline == null) {
            throw new IllegalArgumentException("Path must be non-null");
        }
        if (mOutline == null) {
            outline.reset();
        } else {
            outline.set(mOutline);
        }
    }
    /**
     * Sets the outline of the view, which defines the shape of the shadow it
     * casts, and can used for clipping.
     * <p>
     * The outline path of a View must be {@link android.graphics.Path#isConvex() convex}.
     * <p>
     * If the outline is not set, or {@link Path#isEmpty()}, shadows will be
     * cast from the bounds of the View, and clipToOutline will be ignored.
     * If the outline is not set or is null, shadows will be cast from the
     * bounds of the View, and clipToOutline will be ignored.
     *
     * @param outline The new outline of the view. Must be non-null, and convex.
     * @param outline The new outline of the view.
     *         Must be {@link android.view.Outline#isValid() valid.}
     *
     * @see #getOutline(Path)
     * @see #getClipToOutline()
     * @see #setClipToOutline(boolean)
     */
    public void setOutline(@NonNull Path outline) {
        if (outline == null) {
            throw new IllegalArgumentException("Path must be non-null");
        }
        if (!outline.isConvex()) {
            throw new IllegalArgumentException("Path must be convex");
    public void setOutline(@Nullable Outline outline) {
        if (outline != null && !outline.isValid()) {
            throw new IllegalArgumentException("Outline must not be invalid");
        }
        mPrivateFlags3 |= PFLAG3_OUTLINE_DEFINED;
        if (outline == null) {
            mOutline = null;
        } else {
            // always copy the path since caller may reuse
            if (mOutline == null) {
            mOutline = new Path(outline);
        } else {
                mOutline = new Outline();
            }
            mOutline.set(outline);
        }
        if (mDisplayList != null) {
            mDisplayList.setOutline(outline);
            mDisplayList.setOutline(mOutline);
        }
    }
    /**
     * Returns whether the outline of the View will be used for clipping.
     *
     * @see #getOutline(Path)
     * @see #setOutline(Path)
     * @see #setOutline(Outline)
     */
    public final boolean getClipToOutline() {
        return ((mPrivateFlags3 & PFLAG3_CLIP_TO_OUTLINE) != 0);
@@ -10879,8 +10865,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     * If the outline of the view is not set or is empty, no clipping will be
     * performed.
     *
     * @see #getOutline(Path)
     * @see #setOutline(Path)
     * @see #setOutline(Outline)
     */
    public void setClipToOutline(boolean clipToOutline) {
        // TODO : Add a fast invalidation here.
@@ -11460,7 +11445,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            // Damage the entire IsolatedZVolume recieving this view's shadow.
            if (getTranslationZ() != 0) {
                damageIsolatedZVolume();
                damageShadowReceiver();
            }
        }
    }
@@ -11489,24 +11474,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    }
    /**
     * Damage area of the screen covered by the current isolated Z volume
     * Damage area of the screen that can be covered by this View's shadow.
     *
     * This method will guarantee that any changes to shadows cast by a View
     * are damaged on the screen for future redraw.
     */
    private void damageIsolatedZVolume() {
    private void damageShadowReceiver() {
        final AttachInfo ai = mAttachInfo;
        if (ai != null) {
            ViewParent p = getParent();
            while (p != null) {
                if (p instanceof ViewGroup) {
            if (p != null && p instanceof ViewGroup) {
                final ViewGroup vg = (ViewGroup) p;
                    if (vg.hasIsolatedZVolume()) {
                vg.damageInParent();
                        return;
                    }
                }
                p = p.getParent();
            }
        }
    }
@@ -11540,7 +11519,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            damageInParent();
        }
        if (invalidateParent && getTranslationZ() != 0) {
            damageIsolatedZVolume();
            damageShadowReceiver();
        }
    }
@@ -14571,10 +14550,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                displayList.setClipToBounds(
                        (((ViewGroup) mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0);
            }
            if (this instanceof ViewGroup) {
                displayList.setIsolatedZVolume(
                        (((ViewGroup) this).mGroupFlags & ViewGroup.FLAG_ISOLATED_Z_VOLUME) != 0);
            }
            displayList.setOutline(mOutline);
            displayList.setClipToOutline(getClipToOutline());
            float alpha = 1;
@@ -15178,6 +15153,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        if (mBackgroundSizeChanged) {
            background.setBounds(0, 0,  mRight - mLeft, mBottom - mTop);
            mBackgroundSizeChanged = false;
            if ((mPrivateFlags3 & PFLAG3_OUTLINE_DEFINED) == 0) {
                // Outline not currently define, query from background
                mOutline = background.getOutline();
                if (mDisplayList != null) {
                    mDisplayList.setOutline(mOutline);
                }
            }
        }
        // Attempt to use a display list if requested.
+2 −49
Original line number Diff line number Diff line
@@ -357,15 +357,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
     */
    private static final int FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET = 0x800000;

    /**
     * When true, indicates that all 3d composited descendents are contained within this group, and
     * will not be interleaved with other 3d composited content.
     */
    static final int FLAG_ISOLATED_Z_VOLUME = 0x1000000;

    static final int FLAG_IS_TRANSITION_GROUP = 0x2000000;
    static final int FLAG_IS_TRANSITION_GROUP = 0x1000000;

    static final int FLAG_IS_TRANSITION_GROUP_SET = 0x4000000;
    static final int FLAG_IS_TRANSITION_GROUP_SET = 0x2000000;

    /**
     * Indicates which types of drawing caches are to be kept in memory.
@@ -499,7 +493,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        mGroupFlags |= FLAG_ANIMATION_DONE;
        mGroupFlags |= FLAG_ANIMATION_CACHE;
        mGroupFlags |= FLAG_ALWAYS_DRAWN_WITH_CACHE;
        mGroupFlags |= FLAG_ISOLATED_Z_VOLUME;

        if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
            mGroupFlags |= FLAG_SPLIT_MOTION_EVENTS;
@@ -528,9 +521,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                case R.styleable.ViewGroup_clipToPadding:
                    setClipToPadding(a.getBoolean(attr, true));
                    break;
                case R.styleable.ViewGroup_isolatedZVolume:
                    setIsolatedZVolume(a.getBoolean(attr, true));
                    break;
                case R.styleable.ViewGroup_animationCache:
                    setAnimationCacheEnabled(a.getBoolean(attr, true));
                    break;
@@ -3158,43 +3148,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        return child.draw(canvas, this, drawingTime);
    }

    /**
     * Returns whether this group's descendents are drawn in their own
     * independent Z volume. Views drawn in one contained volume will not
     * interleave with views in another, even if their Z values are interleaved.
     * The default value is true.
     * @see #setIsolatedZVolume(boolean)
     *
     * @return True if the ViewGroup has an isolated Z volume.
     *
     * @hide
     */
    public boolean hasIsolatedZVolume() {
        return ((mGroupFlags & FLAG_ISOLATED_Z_VOLUME) != 0);
    }

    /**
     * By default, only direct children of a group can interleave drawing order
     * by interleaving Z values. Set to false on individual groups to enable Z
     * interleaving of views that aren't direct siblings.
     *
     * @return True if the group should be an isolated Z volume with its own Z
     *         ordering space, false if its decendents should inhabit the
     *         inherited Z ordering volume.
     * @attr ref android.R.styleable#ViewGroup_isolatedZVolume
     *
     * @hide
     */
    public void setIsolatedZVolume(boolean isolateZVolume) {
        boolean previousValue = (mGroupFlags & FLAG_ISOLATED_Z_VOLUME) != 0;
        if (isolateZVolume != previousValue) {
            setBooleanFlag(FLAG_ISOLATED_Z_VOLUME, isolateZVolume);
            if (mDisplayList != null) {
                mDisplayList.setIsolatedZVolume(isolateZVolume);
            }
        }
    }

    /**
     * Returns whether this group's children are clipped to their bounds before drawing.
     * The default value is true.
+21 −12
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ static void android_view_RenderNode_destroyDisplayList(JNIEnv* env,
}

// ----------------------------------------------------------------------------
// DisplayList view properties
// RenderProperties
// ----------------------------------------------------------------------------

static void android_view_RenderNode_setCaching(JNIEnv* env,
@@ -98,11 +98,6 @@ static void android_view_RenderNode_setClipToBounds(JNIEnv* env,
    displayList->properties().setClipToBounds(clipToBounds);
}

static void android_view_RenderNode_setIsolatedZVolume(JNIEnv* env,
        jobject clazz, jlong displayListPtr, jboolean shouldIsolate) {
    // No-op, TODO: Remove Java usage of this method
}

static void android_view_RenderNode_setProjectBackwards(JNIEnv* env,
        jobject clazz, jlong displayListPtr, jboolean shouldProject) {
    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
@@ -115,17 +110,28 @@ static void android_view_RenderNode_setProjectionReceiver(JNIEnv* env,
    displayList->properties().setProjectionReceiver(shouldRecieve);
}

static void android_view_RenderNode_setOutline(JNIEnv* env,
static void android_view_RenderNode_setOutlineRoundRect(JNIEnv* env,
        jobject clazz, jlong displayListPtr, jint left, jint top,
        jint right, jint bottom, jfloat radius) {
    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
    displayList->properties().outline().setRoundRect(left, top, right, bottom, radius);
}
static void android_view_RenderNode_setOutlineConvexPath(JNIEnv* env,
        jobject clazz, jlong displayListPtr, jlong outlinePathPtr) {
    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
    SkPath* outline = reinterpret_cast<SkPath*>(outlinePathPtr);
    displayList->properties().setOutline(outline);
    SkPath* outlinePath = reinterpret_cast<SkPath*>(outlinePathPtr);
    displayList->properties().outline().setConvexPath(outlinePath);
}
static void android_view_RenderNode_setOutlineEmpty(JNIEnv* env,
        jobject clazz, jlong displayListPtr) {
    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
    displayList->properties().outline().setEmpty();
}

static void android_view_RenderNode_setClipToOutline(JNIEnv* env,
        jobject clazz, jlong displayListPtr, jboolean clipToOutline) {
    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
    displayList->properties().setClipToOutline(clipToOutline);
    displayList->properties().outline().setShouldClip(clipToOutline);
}

static void android_view_RenderNode_setAlpha(JNIEnv* env,
@@ -381,11 +387,14 @@ static JNINativeMethod gMethods[] = {
    { "nSetStaticMatrix",      "(JJ)V",  (void*) android_view_RenderNode_setStaticMatrix },
    { "nSetAnimationMatrix",   "(JJ)V",  (void*) android_view_RenderNode_setAnimationMatrix },
    { "nSetClipToBounds",      "(JZ)V",  (void*) android_view_RenderNode_setClipToBounds },
    { "nSetIsolatedZVolume",   "(JZ)V",  (void*) android_view_RenderNode_setIsolatedZVolume },
    { "nSetProjectBackwards",  "(JZ)V",  (void*) android_view_RenderNode_setProjectBackwards },
    { "nSetProjectionReceiver","(JZ)V",  (void*) android_view_RenderNode_setProjectionReceiver },
    { "nSetOutline",           "(JJ)V",  (void*) android_view_RenderNode_setOutline },

    { "nSetOutlineRoundRect",  "(JIIIIF)V", (void*) android_view_RenderNode_setOutlineRoundRect },
    { "nSetOutlineConvexPath", "(JJ)V",  (void*) android_view_RenderNode_setOutlineConvexPath },
    { "nSetOutlineEmpty",      "(J)V",   (void*) android_view_RenderNode_setOutlineEmpty },
    { "nSetClipToOutline",     "(JZ)V",  (void*) android_view_RenderNode_setClipToOutline },

    { "nSetAlpha",             "(JF)V",  (void*) android_view_RenderNode_setAlpha },
    { "nSetHasOverlappingRendering", "(JZ)V",
            (void*) android_view_RenderNode_setHasOverlappingRendering },
Loading