summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Craik <ccraik@google.com>2014-07-21 10:25:54 -0700
committerChris Craik <ccraik@google.com>2014-07-22 15:15:11 -0700
commit0645128b80621edee70f8cab4afb208fe0c26bec (patch)
tree8c12a055a0231303726cf2b6724b5b7264ca7357
parent94ca6cd7c932689b8018d1b118ddcd6b7a9eab27 (diff)
downloadframeworks_base-0645128b80621edee70f8cab4afb208fe0c26bec.zip
frameworks_base-0645128b80621edee70f8cab4afb208fe0c26bec.tar.gz
frameworks_base-0645128b80621edee70f8cab4afb208fe0c26bec.tar.bz2
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
-rw-r--r--core/java/android/view/RenderNode.java5
-rw-r--r--core/jni/android_view_RenderNode.cpp9
-rw-r--r--graphics/java/android/graphics/Outline.java16
-rw-r--r--libs/hwui/Outline.h18
-rw-r--r--libs/hwui/RenderNode.cpp19
5 files changed, 54 insertions, 13 deletions
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java
index 0a1204d..73c7321 100644
--- a/core/java/android/view/RenderNode.java
+++ b/core/java/android/view/RenderNode.java
@@ -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);
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index 28473e0..7245447 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -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 },
diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java
index 1709558..3a4c2a7 100644
--- a/graphics/java/android/graphics/Outline.java
+++ b/graphics/java/android/graphics/Outline.java
@@ -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");
}
diff --git a/libs/hwui/Outline.h b/libs/hwui/Outline.h
index 024bdfd..83426e8 100644
--- a/libs/hwui/Outline.h
+++ b/libs/hwui/Outline.h
@@ -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;
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index fe03806..3eb779f 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -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,16 +776,23 @@ 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());
- return;
+ 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());