Loading core/java/android/view/RenderNode.java +10 −0 Original line number Diff line number Diff line Loading @@ -360,6 +360,14 @@ public class RenderNode { nSetClipToOutline(mNativeDisplayList, clipToOutline); } /** * Controls the RenderNode's circular reveal clip. */ public void setRevealClip(boolean shouldClip, boolean inverseClip, float x, float y, float radius) { nSetRevealClip(mNativeDisplayList, shouldClip, inverseClip, x, y, radius); } /** * 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.) Loading Loading @@ -856,6 +864,8 @@ public class RenderNode { 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 nSetRevealClip(long displayList, boolean shouldClip, boolean inverseClip, float x, float y, float radius); private static native void nSetAlpha(long displayList, float alpha); private static native void nSetHasOverlappingRendering(long displayList, boolean hasOverlappingRendering); Loading core/java/android/view/View.java +12 −1 Original line number Diff line number Diff line Loading @@ -33,7 +33,6 @@ import android.graphics.LinearGradient; import android.graphics.Matrix; import android.graphics.Outline; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.PorterDuff; Loading Loading @@ -10883,6 +10882,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } /** * Private API to be used for reveal animation * * @hide */ public void setRevealClip(boolean shouldClip, boolean inverseClip, float x, float y, float radius) { if (mDisplayList != null) { mDisplayList.setRevealClip(shouldClip, inverseClip, x, y, radius); } } /** * Hit rectangle in parent's coordinates * Loading core/jni/android_view_RenderNode.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -115,23 +115,38 @@ static void android_view_RenderNode_setOutlineRoundRect(JNIEnv* env, jint right, jint bottom, jfloat radius) { RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); displayList->mutateStagingProperties().mutableOutline().setRoundRect(left, top, right, bottom, radius); displayList->mutateStagingProperties().updateClipPath(); } static void android_view_RenderNode_setOutlineConvexPath(JNIEnv* env, jobject clazz, jlong displayListPtr, jlong outlinePathPtr) { RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); SkPath* outlinePath = reinterpret_cast<SkPath*>(outlinePathPtr); displayList->mutateStagingProperties().mutableOutline().setConvexPath(outlinePath); displayList->mutateStagingProperties().updateClipPath(); } static void android_view_RenderNode_setOutlineEmpty(JNIEnv* env, jobject clazz, jlong displayListPtr) { RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); displayList->mutateStagingProperties().mutableOutline().setEmpty(); displayList->mutateStagingProperties().updateClipPath(); } static void android_view_RenderNode_setClipToOutline(JNIEnv* env, jobject clazz, jlong displayListPtr, jboolean clipToOutline) { RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); displayList->mutateStagingProperties().mutableOutline().setShouldClip(clipToOutline); displayList->mutateStagingProperties().updateClipPath(); } static void android_view_RenderNode_setRevealClip(JNIEnv* env, jobject clazz, jlong displayListPtr, jboolean shouldClip, jboolean inverseClip, jfloat x, jfloat y, jfloat radius) { RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); displayList->mutateStagingProperties().mutableRevealClip().set( shouldClip, inverseClip, x, y, radius); displayList->mutateStagingProperties().updateClipPath(); } static void android_view_RenderNode_setAlpha(JNIEnv* env, Loading Loading @@ -396,6 +411,7 @@ static JNINativeMethod gMethods[] = { { "nSetOutlineConvexPath", "(JJ)V", (void*) android_view_RenderNode_setOutlineConvexPath }, { "nSetOutlineEmpty", "(J)V", (void*) android_view_RenderNode_setOutlineEmpty }, { "nSetClipToOutline", "(JZ)V", (void*) android_view_RenderNode_setClipToOutline }, { "nSetRevealClip", "(JZZFFF)V", (void*) android_view_RenderNode_setRevealClip }, { "nSetAlpha", "(JF)V", (void*) android_view_RenderNode_setAlpha }, { "nSetHasOverlappingRendering", "(JZ)V", Loading libs/hwui/DisplayListOp.h +23 −11 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ #define LOG_TAG "OpenGLRenderer" #endif #include <SkPath.h> #include <SkPathOps.h> #include <SkXfermode.h> #include <private/hwui/DrawGlInfo.h> Loading Loading @@ -1550,20 +1552,27 @@ private: */ class DrawShadowOp : public DrawOp { public: DrawShadowOp(const mat4& transformXY, const mat4& transformZ, float alpha, const SkPath* outline, float fallbackWidth, float fallbackHeight) : DrawOp(NULL), mTransformXY(transformXY), mTransformZ(transformZ), mAlpha(alpha), mOutline(outline), mFallbackWidth(fallbackWidth), mFallbackHeight(fallbackHeight) {} DrawShadowOp(const mat4& transformXY, const mat4& transformZ, float alpha, float fallbackWidth, float fallbackHeight, const SkPath* outline, const SkPath* revealClip) : DrawOp(NULL), mTransformXY(transformXY), mTransformZ(transformZ), mAlpha(alpha), mFallbackWidth(fallbackWidth), mFallbackHeight(fallbackHeight), mOutline(outline), mRevealClip(revealClip) {} virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { if (mOutline->isEmpty()) { SkPath fakeOutline; fakeOutline.addRect(0, 0, mFallbackWidth, mFallbackHeight); return renderer.drawShadow(mTransformXY, mTransformZ, mAlpha, &fakeOutline); SkPath casterPerimeter; if (!mOutline || mOutline->isEmpty()) { casterPerimeter.addRect(0, 0, mFallbackWidth, mFallbackHeight); } else { casterPerimeter = *mOutline; } if (mRevealClip) { // intersect the outline with the convex reveal clip Op(casterPerimeter, *mRevealClip, kIntersect_PathOp, &casterPerimeter); } return renderer.drawShadow(mTransformXY, mTransformZ, mAlpha, mOutline); return renderer.drawShadow(mTransformXY, mTransformZ, mAlpha, &casterPerimeter); } virtual void output(int level, uint32_t logFlags) const { Loading @@ -1576,9 +1585,12 @@ private: const mat4 mTransformXY; const mat4 mTransformZ; const float mAlpha; const SkPath* mOutline; const float mFallbackWidth; const float mFallbackHeight; // these point at convex SkPaths owned by RenderProperties, or null const SkPath* mOutline; const SkPath* mRevealClip; }; class DrawLayerOp : public DrawOp { Loading libs/hwui/OpenGLRenderer.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -1919,6 +1919,7 @@ status_t OpenGLRenderer::drawDisplayList(RenderNode* displayList, Rect& dirty, // will be performed by the display list itself if (displayList && displayList->isRenderable()) { // compute 3d ordering displayList->updateProperties(); displayList->computeOrdering(); if (CC_UNLIKELY(mCaches.drawDeferDisabled)) { status = startFrame(); Loading Loading @@ -3202,7 +3203,7 @@ static void mapPointFakeZ(Vector3& point, const mat4& transformXY, const mat4& t } status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& casterTransformZ, float casterAlpha, const SkPath* casterOutline) { float casterAlpha, const SkPath* casterPerimeter) { if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone; // TODO: use quickRejectWithScissor. For now, always force enable scissor. Loading @@ -3214,7 +3215,7 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c // tessellate caster outline into a 2d polygon Vector<Vertex> casterVertices2d; const float casterRefinementThresholdSquared = 20.0f; // TODO: experiment with this value PathTessellator::approximatePathOutlineVertices(*casterOutline, PathTessellator::approximatePathOutlineVertices(*casterPerimeter, casterRefinementThresholdSquared, casterVertices2d); if (casterVertices2d.size() == 0) { Loading Loading @@ -3256,7 +3257,7 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c // We only have ortho projection, so we can just ignore the Z in caster for // simple rejection calculation. Rect localClip = mSnapshot->getLocalClip(); Rect casterBounds(casterOutline->getBounds()); Rect casterBounds(casterPerimeter->getBounds()); casterTransformXY.mapRect(casterBounds); bool isCasterOpaque = (casterAlpha == 1.0f); Loading Loading
core/java/android/view/RenderNode.java +10 −0 Original line number Diff line number Diff line Loading @@ -360,6 +360,14 @@ public class RenderNode { nSetClipToOutline(mNativeDisplayList, clipToOutline); } /** * Controls the RenderNode's circular reveal clip. */ public void setRevealClip(boolean shouldClip, boolean inverseClip, float x, float y, float radius) { nSetRevealClip(mNativeDisplayList, shouldClip, inverseClip, x, y, radius); } /** * 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.) Loading Loading @@ -856,6 +864,8 @@ public class RenderNode { 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 nSetRevealClip(long displayList, boolean shouldClip, boolean inverseClip, float x, float y, float radius); private static native void nSetAlpha(long displayList, float alpha); private static native void nSetHasOverlappingRendering(long displayList, boolean hasOverlappingRendering); Loading
core/java/android/view/View.java +12 −1 Original line number Diff line number Diff line Loading @@ -33,7 +33,6 @@ import android.graphics.LinearGradient; import android.graphics.Matrix; import android.graphics.Outline; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.PorterDuff; Loading Loading @@ -10883,6 +10882,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } /** * Private API to be used for reveal animation * * @hide */ public void setRevealClip(boolean shouldClip, boolean inverseClip, float x, float y, float radius) { if (mDisplayList != null) { mDisplayList.setRevealClip(shouldClip, inverseClip, x, y, radius); } } /** * Hit rectangle in parent's coordinates * Loading
core/jni/android_view_RenderNode.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -115,23 +115,38 @@ static void android_view_RenderNode_setOutlineRoundRect(JNIEnv* env, jint right, jint bottom, jfloat radius) { RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); displayList->mutateStagingProperties().mutableOutline().setRoundRect(left, top, right, bottom, radius); displayList->mutateStagingProperties().updateClipPath(); } static void android_view_RenderNode_setOutlineConvexPath(JNIEnv* env, jobject clazz, jlong displayListPtr, jlong outlinePathPtr) { RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); SkPath* outlinePath = reinterpret_cast<SkPath*>(outlinePathPtr); displayList->mutateStagingProperties().mutableOutline().setConvexPath(outlinePath); displayList->mutateStagingProperties().updateClipPath(); } static void android_view_RenderNode_setOutlineEmpty(JNIEnv* env, jobject clazz, jlong displayListPtr) { RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); displayList->mutateStagingProperties().mutableOutline().setEmpty(); displayList->mutateStagingProperties().updateClipPath(); } static void android_view_RenderNode_setClipToOutline(JNIEnv* env, jobject clazz, jlong displayListPtr, jboolean clipToOutline) { RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); displayList->mutateStagingProperties().mutableOutline().setShouldClip(clipToOutline); displayList->mutateStagingProperties().updateClipPath(); } static void android_view_RenderNode_setRevealClip(JNIEnv* env, jobject clazz, jlong displayListPtr, jboolean shouldClip, jboolean inverseClip, jfloat x, jfloat y, jfloat radius) { RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr); displayList->mutateStagingProperties().mutableRevealClip().set( shouldClip, inverseClip, x, y, radius); displayList->mutateStagingProperties().updateClipPath(); } static void android_view_RenderNode_setAlpha(JNIEnv* env, Loading Loading @@ -396,6 +411,7 @@ static JNINativeMethod gMethods[] = { { "nSetOutlineConvexPath", "(JJ)V", (void*) android_view_RenderNode_setOutlineConvexPath }, { "nSetOutlineEmpty", "(J)V", (void*) android_view_RenderNode_setOutlineEmpty }, { "nSetClipToOutline", "(JZ)V", (void*) android_view_RenderNode_setClipToOutline }, { "nSetRevealClip", "(JZZFFF)V", (void*) android_view_RenderNode_setRevealClip }, { "nSetAlpha", "(JF)V", (void*) android_view_RenderNode_setAlpha }, { "nSetHasOverlappingRendering", "(JZ)V", Loading
libs/hwui/DisplayListOp.h +23 −11 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ #define LOG_TAG "OpenGLRenderer" #endif #include <SkPath.h> #include <SkPathOps.h> #include <SkXfermode.h> #include <private/hwui/DrawGlInfo.h> Loading Loading @@ -1550,20 +1552,27 @@ private: */ class DrawShadowOp : public DrawOp { public: DrawShadowOp(const mat4& transformXY, const mat4& transformZ, float alpha, const SkPath* outline, float fallbackWidth, float fallbackHeight) : DrawOp(NULL), mTransformXY(transformXY), mTransformZ(transformZ), mAlpha(alpha), mOutline(outline), mFallbackWidth(fallbackWidth), mFallbackHeight(fallbackHeight) {} DrawShadowOp(const mat4& transformXY, const mat4& transformZ, float alpha, float fallbackWidth, float fallbackHeight, const SkPath* outline, const SkPath* revealClip) : DrawOp(NULL), mTransformXY(transformXY), mTransformZ(transformZ), mAlpha(alpha), mFallbackWidth(fallbackWidth), mFallbackHeight(fallbackHeight), mOutline(outline), mRevealClip(revealClip) {} virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { if (mOutline->isEmpty()) { SkPath fakeOutline; fakeOutline.addRect(0, 0, mFallbackWidth, mFallbackHeight); return renderer.drawShadow(mTransformXY, mTransformZ, mAlpha, &fakeOutline); SkPath casterPerimeter; if (!mOutline || mOutline->isEmpty()) { casterPerimeter.addRect(0, 0, mFallbackWidth, mFallbackHeight); } else { casterPerimeter = *mOutline; } if (mRevealClip) { // intersect the outline with the convex reveal clip Op(casterPerimeter, *mRevealClip, kIntersect_PathOp, &casterPerimeter); } return renderer.drawShadow(mTransformXY, mTransformZ, mAlpha, mOutline); return renderer.drawShadow(mTransformXY, mTransformZ, mAlpha, &casterPerimeter); } virtual void output(int level, uint32_t logFlags) const { Loading @@ -1576,9 +1585,12 @@ private: const mat4 mTransformXY; const mat4 mTransformZ; const float mAlpha; const SkPath* mOutline; const float mFallbackWidth; const float mFallbackHeight; // these point at convex SkPaths owned by RenderProperties, or null const SkPath* mOutline; const SkPath* mRevealClip; }; class DrawLayerOp : public DrawOp { Loading
libs/hwui/OpenGLRenderer.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -1919,6 +1919,7 @@ status_t OpenGLRenderer::drawDisplayList(RenderNode* displayList, Rect& dirty, // will be performed by the display list itself if (displayList && displayList->isRenderable()) { // compute 3d ordering displayList->updateProperties(); displayList->computeOrdering(); if (CC_UNLIKELY(mCaches.drawDeferDisabled)) { status = startFrame(); Loading Loading @@ -3202,7 +3203,7 @@ static void mapPointFakeZ(Vector3& point, const mat4& transformXY, const mat4& t } status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& casterTransformZ, float casterAlpha, const SkPath* casterOutline) { float casterAlpha, const SkPath* casterPerimeter) { if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone; // TODO: use quickRejectWithScissor. For now, always force enable scissor. Loading @@ -3214,7 +3215,7 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c // tessellate caster outline into a 2d polygon Vector<Vertex> casterVertices2d; const float casterRefinementThresholdSquared = 20.0f; // TODO: experiment with this value PathTessellator::approximatePathOutlineVertices(*casterOutline, PathTessellator::approximatePathOutlineVertices(*casterPerimeter, casterRefinementThresholdSquared, casterVertices2d); if (casterVertices2d.size() == 0) { Loading Loading @@ -3256,7 +3257,7 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c // We only have ortho projection, so we can just ignore the Z in caster for // simple rejection calculation. Rect localClip = mSnapshot->getLocalClip(); Rect casterBounds(casterOutline->getBounds()); Rect casterBounds(casterPerimeter->getBounds()); casterTransformXY.mapRect(casterBounds); bool isCasterOpaque = (casterAlpha == 1.0f); Loading