Loading core/java/android/view/DisplayList.java +12 −0 Original line number Diff line number Diff line Loading @@ -430,6 +430,17 @@ public class DisplayList { } } /** * Sets whether the display list is a projection receiver - that its parent * DisplayList should draw any descendent DisplayLists with * ProjectBackwards=true directly on top of it. Default value is false. */ public void setProjectionReceiver(boolean shouldRecieve) { if (hasNativeDisplayList()) { nSetProjectionReceiver(mFinalizer.mNativeDisplayList, shouldRecieve); } } /** * Sets the outline, defining the shape that casts a shadow. * Loading Loading @@ -1065,6 +1076,7 @@ public class DisplayList { private static native void nSetCaching(long displayList, boolean caching); 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 nSetAlpha(long displayList, float alpha); Loading core/java/android/view/View.java +1 −7 Original line number Diff line number Diff line Loading @@ -2335,7 +2335,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * 1 PFLAG3_IS_LAID_OUT * 1 PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT * 1 PFLAG3_CALLED_SUPER * 1 PFLAG3_PROJECT_BACKGROUND * |-------|-------|-------|-------| */ Loading Loading @@ -2371,12 +2370,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ static final int PFLAG3_CALLED_SUPER = 0x10; /** * Flag indicating that the background of this view will be drawn into a * display list and projected onto the closest parent projection surface. */ static final int PFLAG3_PROJECT_BACKGROUND = 0x20; /** * Flag indicating that we're in the process of applying window insets. */ Loading Loading @@ -15148,6 +15141,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // Set up drawable properties that are view-independent. displayList.setLeftTopRightBottom(bounds.left, bounds.top, bounds.right, bounds.bottom); displayList.setProjectBackwards(drawable.isProjected()); displayList.setProjectionReceiver(true); displayList.setClipToBounds(false); return displayList; } core/jni/android_view_DisplayList.cpp +8 −1 Original line number Diff line number Diff line Loading @@ -117,6 +117,12 @@ static void android_view_DisplayList_setProjectBackwards(JNIEnv* env, displayList->setProjectBackwards(shouldProject); } static void android_view_DisplayList_setProjectionReceiver(JNIEnv* env, jobject clazz, jlong displayListPtr, jboolean shouldRecieve) { DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr); displayList->setProjectionReceiver(shouldRecieve); } static void android_view_DisplayList_setOutline(JNIEnv* env, jobject clazz, jlong displayListPtr, jlong outlinePathPtr) { DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr); Loading Loading @@ -392,6 +398,7 @@ static JNINativeMethod gMethods[] = { { "nSetClipToBounds", "(JZ)V", (void*) android_view_DisplayList_setClipToBounds }, { "nSetIsolatedZVolume", "(JZ)V", (void*) android_view_DisplayList_setIsolatedZVolume }, { "nSetProjectBackwards", "(JZ)V", (void*) android_view_DisplayList_setProjectBackwards }, { "nSetProjectionReceiver","(JZ)V", (void*) android_view_DisplayList_setProjectionReceiver }, { "nSetOutline", "(JJ)V", (void*) android_view_DisplayList_setOutline }, { "nSetAlpha", "(JF)V", (void*) android_view_DisplayList_setAlpha }, { "nSetHasOverlappingRendering", "(JZ)V", Loading libs/hwui/DisplayList.cpp +44 −24 Original line number Diff line number Diff line Loading @@ -240,6 +240,7 @@ void DisplayList::init() { mClipToBounds = true; mIsolatedZVolume = true; mProjectBackwards = false; mProjectionReceiver = false; mOutline.rewind(); mAlpha = 1; mHasOverlappingRendering = true; Loading Loading @@ -523,6 +524,7 @@ void DisplayList::computeOrderingImpl( const mat4* transformFromProjectionSurface) { m3dNodes.clear(); mProjectedNodes.clear(); if (mDisplayListData == NULL || mSize == 0) return; // TODO: should avoid this calculation in most cases // TODO: just calculate single matrix, down to all leaf composited elements Loading Loading @@ -552,6 +554,7 @@ void DisplayList::computeOrderingImpl( opState->mSkipInOrderDraw = false; } if (mDisplayListData->children.size() > 0) { if (mIsolatedZVolume) { // create a new 3d space for descendents by collecting them compositedChildrenOf3dRoot = &m3dNodes; Loading @@ -561,23 +564,36 @@ void DisplayList::computeOrderingImpl( transformFrom3dRoot = &localTransformFrom3dRoot; } if (mDisplayListData != NULL && mDisplayListData->projectionIndex >= 0) { // create a new projection surface for descendents by collecting them compositedChildrenOfProjectionSurface = &mProjectedNodes; transformFromProjectionSurface = &mat4::identity(); const bool isProjectionReceiver = mDisplayListData->projectionReceiveIndex >= 0; bool haveAppliedPropertiesToProjection = false; for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) { DrawDisplayListOp* childOp = mDisplayListData->children[i]; DisplayList* child = childOp->mDisplayList; Vector<DrawDisplayListOp*>* projectionChildren = NULL; const mat4* projectionTransform = NULL; if (isProjectionReceiver && !child->mProjectBackwards) { // if receiving projections, collect projecting descendent // Note that if a direct descendent is projecting backwards, we pass it's // grandparent projection collection, since it shouldn't project onto it's // parent, where it will already be drawing. projectionChildren = &mProjectedNodes; projectionTransform = &mat4::identity(); } else { if (!haveAppliedPropertiesToProjection) { applyViewPropertyTransforms(localTransformFromProjectionSurface); transformFromProjectionSurface = &localTransformFromProjectionSurface; haveAppliedPropertiesToProjection = true; } if (mDisplayListData != NULL && mDisplayListData->children.size() > 0) { for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) { DrawDisplayListOp* childOp = mDisplayListData->children[i]; childOp->mDisplayList->computeOrderingImpl(childOp, projectionChildren = compositedChildrenOfProjectionSurface; projectionTransform = &localTransformFromProjectionSurface; } child->computeOrderingImpl(childOp, compositedChildrenOf3dRoot, transformFrom3dRoot, compositedChildrenOfProjectionSurface, transformFromProjectionSurface); projectionChildren, projectionTransform); } } } class DeferOperationHandler { Loading Loading @@ -637,11 +653,11 @@ void DisplayList::iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& ren return; } int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); LinearAllocator& alloc = handler.allocator(); ClipRectOp* clipOp = new (alloc) ClipRectOp(0, 0, mWidth, mHeight, SkRegion::kIntersect_Op); // clip to 3d root bounds for now handler(clipOp, PROPERTY_SAVECOUNT, mClipToBounds); int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); for (size_t i = 0; i < m3dNodes.size(); i++) { const float zValue = m3dNodes[i].key; Loading Loading @@ -676,18 +692,22 @@ void DisplayList::iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& ren template <class T> void DisplayList::iterateProjectedChildren(OpenGLRenderer& renderer, T& handler, const int level) { int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); LinearAllocator& alloc = handler.allocator(); ClipRectOp* clipOp = new (alloc) ClipRectOp(0, 0, mWidth, mHeight, SkRegion::kReplace_Op); // clip to projection surface root bounds handler(clipOp, PROPERTY_SAVECOUNT, mClipToBounds); int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); for (size_t i = 0; i < mProjectedNodes.size(); i++) { DrawDisplayListOp* childOp = mProjectedNodes[i]; // matrix save, concat, and restore can be done safely without allocating operations int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag); renderer.concatMatrix(childOp->mTransformFromCompositingAncestor); childOp->mSkipInOrderDraw = false; // this is horrible, I'm so sorry everyone handler(childOp, renderer.getSaveCount() - 1, mClipToBounds); childOp->mSkipInOrderDraw = true; renderer.restoreToCount(restoreTo); } handler(new (alloc) RestoreToCountOp(rootRestoreTo), PROPERTY_SAVECOUNT, mClipToBounds); } Loading Loading @@ -739,7 +759,7 @@ void DisplayList::iterate(OpenGLRenderer& renderer, T& handler, const int level) DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance(); const int saveCountOffset = renderer.getSaveCount() - 1; const int projectionIndex = mDisplayListData->projectionIndex; const int projectionReceiveIndex = mDisplayListData->projectionReceiveIndex; for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) { DisplayListOp *op = mDisplayListData->displayListOps[i]; Loading @@ -750,7 +770,7 @@ void DisplayList::iterate(OpenGLRenderer& renderer, T& handler, const int level) logBuffer.writeCommand(level, op->name()); handler(op, saveCountOffset, mClipToBounds); if (CC_UNLIKELY(i == projectionIndex && mProjectedNodes.size() > 0)) { if (CC_UNLIKELY(i == projectionReceiveIndex && mProjectedNodes.size() > 0)) { iterateProjectedChildren(renderer, handler, level); } } Loading libs/hwui/DisplayList.h +11 −3 Original line number Diff line number Diff line Loading @@ -112,7 +112,7 @@ public: */ class DisplayListData : public LightRefBase<DisplayListData> { public: DisplayListData() : projectionIndex(-1) {} DisplayListData() : projectionReceiveIndex(-1) {} // allocator into which all ops were allocated LinearAllocator allocator; Loading @@ -123,8 +123,7 @@ public: Vector<DrawDisplayListOp*> children; // index of DisplayListOp restore, after which projected descendents should be drawn int projectionIndex; Matrix4 projectionTransform; int projectionReceiveIndex; }; /** Loading Loading @@ -198,6 +197,14 @@ public: mProjectBackwards = shouldProject; } void setProjectionReceiver(bool shouldRecieve) { mProjectionReceiver = shouldRecieve; } bool isProjectionReceiver() { return mProjectionReceiver; } void setOutline(const SkPath* outline) { if (!outline) { mOutline.reset(); Loading Loading @@ -600,6 +607,7 @@ private: bool mClipToBounds; bool mIsolatedZVolume; bool mProjectBackwards; bool mProjectionReceiver; SkPath mOutline; float mAlpha; bool mHasOverlappingRendering; Loading Loading
core/java/android/view/DisplayList.java +12 −0 Original line number Diff line number Diff line Loading @@ -430,6 +430,17 @@ public class DisplayList { } } /** * Sets whether the display list is a projection receiver - that its parent * DisplayList should draw any descendent DisplayLists with * ProjectBackwards=true directly on top of it. Default value is false. */ public void setProjectionReceiver(boolean shouldRecieve) { if (hasNativeDisplayList()) { nSetProjectionReceiver(mFinalizer.mNativeDisplayList, shouldRecieve); } } /** * Sets the outline, defining the shape that casts a shadow. * Loading Loading @@ -1065,6 +1076,7 @@ public class DisplayList { private static native void nSetCaching(long displayList, boolean caching); 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 nSetAlpha(long displayList, float alpha); Loading
core/java/android/view/View.java +1 −7 Original line number Diff line number Diff line Loading @@ -2335,7 +2335,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * 1 PFLAG3_IS_LAID_OUT * 1 PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT * 1 PFLAG3_CALLED_SUPER * 1 PFLAG3_PROJECT_BACKGROUND * |-------|-------|-------|-------| */ Loading Loading @@ -2371,12 +2370,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ static final int PFLAG3_CALLED_SUPER = 0x10; /** * Flag indicating that the background of this view will be drawn into a * display list and projected onto the closest parent projection surface. */ static final int PFLAG3_PROJECT_BACKGROUND = 0x20; /** * Flag indicating that we're in the process of applying window insets. */ Loading Loading @@ -15148,6 +15141,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // Set up drawable properties that are view-independent. displayList.setLeftTopRightBottom(bounds.left, bounds.top, bounds.right, bounds.bottom); displayList.setProjectBackwards(drawable.isProjected()); displayList.setProjectionReceiver(true); displayList.setClipToBounds(false); return displayList; }
core/jni/android_view_DisplayList.cpp +8 −1 Original line number Diff line number Diff line Loading @@ -117,6 +117,12 @@ static void android_view_DisplayList_setProjectBackwards(JNIEnv* env, displayList->setProjectBackwards(shouldProject); } static void android_view_DisplayList_setProjectionReceiver(JNIEnv* env, jobject clazz, jlong displayListPtr, jboolean shouldRecieve) { DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr); displayList->setProjectionReceiver(shouldRecieve); } static void android_view_DisplayList_setOutline(JNIEnv* env, jobject clazz, jlong displayListPtr, jlong outlinePathPtr) { DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr); Loading Loading @@ -392,6 +398,7 @@ static JNINativeMethod gMethods[] = { { "nSetClipToBounds", "(JZ)V", (void*) android_view_DisplayList_setClipToBounds }, { "nSetIsolatedZVolume", "(JZ)V", (void*) android_view_DisplayList_setIsolatedZVolume }, { "nSetProjectBackwards", "(JZ)V", (void*) android_view_DisplayList_setProjectBackwards }, { "nSetProjectionReceiver","(JZ)V", (void*) android_view_DisplayList_setProjectionReceiver }, { "nSetOutline", "(JJ)V", (void*) android_view_DisplayList_setOutline }, { "nSetAlpha", "(JF)V", (void*) android_view_DisplayList_setAlpha }, { "nSetHasOverlappingRendering", "(JZ)V", Loading
libs/hwui/DisplayList.cpp +44 −24 Original line number Diff line number Diff line Loading @@ -240,6 +240,7 @@ void DisplayList::init() { mClipToBounds = true; mIsolatedZVolume = true; mProjectBackwards = false; mProjectionReceiver = false; mOutline.rewind(); mAlpha = 1; mHasOverlappingRendering = true; Loading Loading @@ -523,6 +524,7 @@ void DisplayList::computeOrderingImpl( const mat4* transformFromProjectionSurface) { m3dNodes.clear(); mProjectedNodes.clear(); if (mDisplayListData == NULL || mSize == 0) return; // TODO: should avoid this calculation in most cases // TODO: just calculate single matrix, down to all leaf composited elements Loading Loading @@ -552,6 +554,7 @@ void DisplayList::computeOrderingImpl( opState->mSkipInOrderDraw = false; } if (mDisplayListData->children.size() > 0) { if (mIsolatedZVolume) { // create a new 3d space for descendents by collecting them compositedChildrenOf3dRoot = &m3dNodes; Loading @@ -561,23 +564,36 @@ void DisplayList::computeOrderingImpl( transformFrom3dRoot = &localTransformFrom3dRoot; } if (mDisplayListData != NULL && mDisplayListData->projectionIndex >= 0) { // create a new projection surface for descendents by collecting them compositedChildrenOfProjectionSurface = &mProjectedNodes; transformFromProjectionSurface = &mat4::identity(); const bool isProjectionReceiver = mDisplayListData->projectionReceiveIndex >= 0; bool haveAppliedPropertiesToProjection = false; for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) { DrawDisplayListOp* childOp = mDisplayListData->children[i]; DisplayList* child = childOp->mDisplayList; Vector<DrawDisplayListOp*>* projectionChildren = NULL; const mat4* projectionTransform = NULL; if (isProjectionReceiver && !child->mProjectBackwards) { // if receiving projections, collect projecting descendent // Note that if a direct descendent is projecting backwards, we pass it's // grandparent projection collection, since it shouldn't project onto it's // parent, where it will already be drawing. projectionChildren = &mProjectedNodes; projectionTransform = &mat4::identity(); } else { if (!haveAppliedPropertiesToProjection) { applyViewPropertyTransforms(localTransformFromProjectionSurface); transformFromProjectionSurface = &localTransformFromProjectionSurface; haveAppliedPropertiesToProjection = true; } if (mDisplayListData != NULL && mDisplayListData->children.size() > 0) { for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) { DrawDisplayListOp* childOp = mDisplayListData->children[i]; childOp->mDisplayList->computeOrderingImpl(childOp, projectionChildren = compositedChildrenOfProjectionSurface; projectionTransform = &localTransformFromProjectionSurface; } child->computeOrderingImpl(childOp, compositedChildrenOf3dRoot, transformFrom3dRoot, compositedChildrenOfProjectionSurface, transformFromProjectionSurface); projectionChildren, projectionTransform); } } } class DeferOperationHandler { Loading Loading @@ -637,11 +653,11 @@ void DisplayList::iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& ren return; } int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); LinearAllocator& alloc = handler.allocator(); ClipRectOp* clipOp = new (alloc) ClipRectOp(0, 0, mWidth, mHeight, SkRegion::kIntersect_Op); // clip to 3d root bounds for now handler(clipOp, PROPERTY_SAVECOUNT, mClipToBounds); int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); for (size_t i = 0; i < m3dNodes.size(); i++) { const float zValue = m3dNodes[i].key; Loading Loading @@ -676,18 +692,22 @@ void DisplayList::iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& ren template <class T> void DisplayList::iterateProjectedChildren(OpenGLRenderer& renderer, T& handler, const int level) { int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); LinearAllocator& alloc = handler.allocator(); ClipRectOp* clipOp = new (alloc) ClipRectOp(0, 0, mWidth, mHeight, SkRegion::kReplace_Op); // clip to projection surface root bounds handler(clipOp, PROPERTY_SAVECOUNT, mClipToBounds); int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); for (size_t i = 0; i < mProjectedNodes.size(); i++) { DrawDisplayListOp* childOp = mProjectedNodes[i]; // matrix save, concat, and restore can be done safely without allocating operations int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag); renderer.concatMatrix(childOp->mTransformFromCompositingAncestor); childOp->mSkipInOrderDraw = false; // this is horrible, I'm so sorry everyone handler(childOp, renderer.getSaveCount() - 1, mClipToBounds); childOp->mSkipInOrderDraw = true; renderer.restoreToCount(restoreTo); } handler(new (alloc) RestoreToCountOp(rootRestoreTo), PROPERTY_SAVECOUNT, mClipToBounds); } Loading Loading @@ -739,7 +759,7 @@ void DisplayList::iterate(OpenGLRenderer& renderer, T& handler, const int level) DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance(); const int saveCountOffset = renderer.getSaveCount() - 1; const int projectionIndex = mDisplayListData->projectionIndex; const int projectionReceiveIndex = mDisplayListData->projectionReceiveIndex; for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) { DisplayListOp *op = mDisplayListData->displayListOps[i]; Loading @@ -750,7 +770,7 @@ void DisplayList::iterate(OpenGLRenderer& renderer, T& handler, const int level) logBuffer.writeCommand(level, op->name()); handler(op, saveCountOffset, mClipToBounds); if (CC_UNLIKELY(i == projectionIndex && mProjectedNodes.size() > 0)) { if (CC_UNLIKELY(i == projectionReceiveIndex && mProjectedNodes.size() > 0)) { iterateProjectedChildren(renderer, handler, level); } } Loading
libs/hwui/DisplayList.h +11 −3 Original line number Diff line number Diff line Loading @@ -112,7 +112,7 @@ public: */ class DisplayListData : public LightRefBase<DisplayListData> { public: DisplayListData() : projectionIndex(-1) {} DisplayListData() : projectionReceiveIndex(-1) {} // allocator into which all ops were allocated LinearAllocator allocator; Loading @@ -123,8 +123,7 @@ public: Vector<DrawDisplayListOp*> children; // index of DisplayListOp restore, after which projected descendents should be drawn int projectionIndex; Matrix4 projectionTransform; int projectionReceiveIndex; }; /** Loading Loading @@ -198,6 +197,14 @@ public: mProjectBackwards = shouldProject; } void setProjectionReceiver(bool shouldRecieve) { mProjectionReceiver = shouldRecieve; } bool isProjectionReceiver() { return mProjectionReceiver; } void setOutline(const SkPath* outline) { if (!outline) { mOutline.reset(); Loading Loading @@ -600,6 +607,7 @@ private: bool mClipToBounds; bool mIsolatedZVolume; bool mProjectBackwards; bool mProjectionReceiver; SkPath mOutline; float mAlpha; bool mHasOverlappingRendering; Loading