Add the clipToOutline by just using the clipPathOp
Change-Id: I6ba23b589e579599d018600d0744be0efe2028c1
diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java
index 418aec3..a96d46c 100644
--- a/core/java/android/view/DisplayList.java
+++ b/core/java/android/view/DisplayList.java
@@ -442,7 +442,8 @@
}
/**
- * Sets the outline, defining the shape that casts a shadow.
+ * 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.
*
@@ -456,6 +457,17 @@
}
/**
+ * Enables or disables clipping to the outline.
+ *
+ * @param clipToOutline true if clipping to the outline.
+ */
+ public void setClipToOutline(boolean clipToOutline) {
+ if (hasNativeDisplayList()) {
+ nSetClipToOutline(mFinalizer.mNativeDisplayList, clipToOutline);
+ }
+ }
+
+ /**
* Set the static matrix on the display list. The specified matrix is combined with other
* transforms (such as {@link #setScaleX(float)}, {@link #setRotation(float)}, etc.)
*
@@ -1079,6 +1091,7 @@
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 nSetClipToOutline(long displayList, boolean clipToOutline);
private static native void nSetAlpha(long displayList, float alpha);
private static native void nSetHasOverlappingRendering(long displayList,
boolean hasOverlappingRendering);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 7ce2140..d017d56 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2371,6 +2371,11 @@
static final int PFLAG3_CALLED_SUPER = 0x10;
/**
+ * Flag indicating that an view will be clipped to its outline.
+ */
+ static final int PFLAG3_CLIP_TO_OUTLINE = 0x20;
+
+ /**
* Flag indicating that we're in the process of applying window insets.
*/
static final int PFLAG3_APPLYING_INSETS = 0x40;
@@ -3327,7 +3332,8 @@
private int[] mDrawableState = null;
/**
- * Stores the outline of the view, passed down to the DisplayList level for shadow shape.
+ * Stores the outline of the view, passed down to the DisplayList level for
+ * defining shadow shape and clipping.
*/
private Path mOutline;
@@ -6128,7 +6134,7 @@
* @return {@code true} if this view applied the insets and it should not
* continue propagating further down the hierarchy, {@code false} otherwise.
* @see #getFitsSystemWindows()
- * @see #setFitsSystemWindows(boolean)
+ * @see #setFitsSystemWindows(boolean)
* @see #setSystemUiVisibility(int)
*
* @deprecated As of API XX use {@link #dispatchApplyWindowInsets(WindowInsets)} to apply
@@ -10820,6 +10826,30 @@
}
/**
+ * @hide
+ */
+ public void setClipToOutline(boolean clipToOutline) {
+ // TODO : Add a fast invalidation here.
+ if (getClipToOutline() != clipToOutline) {
+ if (clipToOutline) {
+ mPrivateFlags3 |= PFLAG3_CLIP_TO_OUTLINE;
+ } else {
+ mPrivateFlags3 &= ~PFLAG3_CLIP_TO_OUTLINE;
+ }
+ if (mDisplayList != null) {
+ mDisplayList.setClipToOutline(clipToOutline);
+ }
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public final boolean getClipToOutline() {
+ return ((mPrivateFlags3 & PFLAG3_CLIP_TO_OUTLINE) != 0);
+ }
+
+ /**
* Hit rectangle in parent's coordinates
*
* @param outRect The hit rectangle of the view.
@@ -14471,6 +14501,7 @@
(((ViewGroup) this).mGroupFlags & ViewGroup.FLAG_ISOLATED_Z_VOLUME) != 0);
}
displayList.setOutline(mOutline);
+ displayList.setClipToOutline(getClipToOutline());
float alpha = 1;
if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags &
ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
diff --git a/core/jni/android_view_DisplayList.cpp b/core/jni/android_view_DisplayList.cpp
index 4bacdde..5f7912b 100644
--- a/core/jni/android_view_DisplayList.cpp
+++ b/core/jni/android_view_DisplayList.cpp
@@ -130,6 +130,12 @@
displayList->setOutline(outline);
}
+static void android_view_DisplayList_setClipToOutline(JNIEnv* env,
+ jobject clazz, jlong displayListPtr, jboolean clipToOutline) {
+ DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+ displayList->setClipToOutline(clipToOutline);
+}
+
static void android_view_DisplayList_setAlpha(JNIEnv* env,
jobject clazz, jlong displayListPtr, float alpha) {
DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
@@ -400,6 +406,7 @@
{ "nSetProjectBackwards", "(JZ)V", (void*) android_view_DisplayList_setProjectBackwards },
{ "nSetProjectionReceiver","(JZ)V", (void*) android_view_DisplayList_setProjectionReceiver },
{ "nSetOutline", "(JJ)V", (void*) android_view_DisplayList_setOutline },
+ { "nSetClipToOutline", "(JZ)V", (void*) android_view_DisplayList_setClipToOutline },
{ "nSetAlpha", "(JF)V", (void*) android_view_DisplayList_setAlpha },
{ "nSetHasOverlappingRendering", "(JZ)V",
(void*) android_view_DisplayList_setHasOverlappingRendering },
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index 4742f91..2a39bd9 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -242,6 +242,7 @@
mProjectBackwards = false;
mProjectionReceiver = false;
mOutline.rewind();
+ mClipToOutline = false;
mAlpha = 1;
mHasOverlappingRendering = true;
mTranslationX = 0;
@@ -465,6 +466,10 @@
mRight - mLeft, mBottom - mTop, SkRegion::kIntersect_Op);
handler(op, PROPERTY_SAVECOUNT, mClipToBounds);
}
+ if (CC_UNLIKELY(mClipToOutline && !mOutline.isEmpty())) {
+ ClipPathOp* op = new (handler.allocator()) ClipPathOp(&mOutline, SkRegion::kIntersect_Op);
+ handler(op, PROPERTY_SAVECOUNT, mClipToBounds);
+ }
}
/**
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index adf48d4..42a4e74 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -213,6 +213,10 @@
}
}
+ void setClipToOutline(bool clipToOutline) {
+ mClipToOutline = clipToOutline;
+ }
+
void setStaticMatrix(SkMatrix* matrix) {
delete mStaticMatrix;
mStaticMatrix = new SkMatrix(*matrix);
@@ -609,6 +613,7 @@
bool mProjectBackwards;
bool mProjectionReceiver;
SkPath mOutline;
+ bool mClipToOutline;
float mAlpha;
bool mHasOverlappingRendering;
float mTranslationX, mTranslationY, mTranslationZ;