diff options
-rw-r--r-- | libs/hwui/DisplayListOp.h | 8 | ||||
-rw-r--r-- | libs/hwui/Layer.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/RenderNode.cpp | 64 | ||||
-rw-r--r-- | libs/hwui/RenderNode.h | 15 |
5 files changed, 55 insertions, 38 deletions
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index 233f3f0..4dbebc5 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -1475,19 +1475,19 @@ public: virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, bool useQuickReject) { if (mDisplayList && mDisplayList->isRenderable() && !mSkipInOrderDraw) { - mDisplayList->deferNodeInParent(deferStruct, level + 1); + mDisplayList->defer(deferStruct, level + 1); } } virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level, bool useQuickReject) { if (mDisplayList && mDisplayList->isRenderable() && !mSkipInOrderDraw) { - mDisplayList->replayNodeInParent(replayStruct, level + 1); + mDisplayList->replay(replayStruct, level + 1); } } - // NOT USED since replay() is overridden virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - return DrawGlInfo::kStatusDone; + LOG_ALWAYS_FATAL("should not be called, because replay() is overridden"); + return 0; } virtual void output(int level, uint32_t logFlags) const { diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index 6a2ef2a..e59e714 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -219,7 +219,7 @@ void Layer::defer() { dirtyRect.right, dirtyRect.bottom, !isBlend()); displayList->computeOrdering(); - displayList->deferNodeTree(deferredState); + displayList->defer(deferredState, 0); deferredUpdateScheduled = false; } diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 8f3872a..48cc3e4 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -1942,14 +1942,14 @@ status_t OpenGLRenderer::drawDisplayList(RenderNode* displayList, Rect& dirty, if (CC_UNLIKELY(mCaches.drawDeferDisabled)) { status = startFrame(); ReplayStateStruct replayStruct(*this, dirty, replayFlags); - displayList->replayNodeTree(replayStruct); + displayList->replay(replayStruct, 0); return status | replayStruct.mDrawGlStatus; } bool avoidOverdraw = !mCaches.debugOverdraw && !mCountOverdraw; // shh, don't tell devs! DeferredDisplayList deferredList(*currentClipRect(), avoidOverdraw); DeferStateStruct deferStruct(deferredList, *this, replayFlags); - displayList->deferNodeTree(deferStruct); + displayList->defer(deferStruct, 0); flushLayers(); status = startFrame(); diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index 378183a..f0eca3c 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -15,7 +15,7 @@ */ #define ATRACE_TAG ATRACE_TAG_VIEW -#define LOG_TAG "RenderNode" +#define LOG_TAG "OpenGLRenderer" #include "RenderNode.h" @@ -523,15 +523,7 @@ private: const int mLevel; }; -void RenderNode::deferNodeTree(DeferStateStruct& deferStruct) { - DeferOperationHandler handler(deferStruct, 0); - if (MathUtils::isPositive(properties().getZ())) { - issueDrawShadowOperation(Matrix4::identity(), handler); - } - issueOperations<DeferOperationHandler>(deferStruct.mRenderer, handler); -} - -void RenderNode::deferNodeInParent(DeferStateStruct& deferStruct, const int level) { +void RenderNode::defer(DeferStateStruct& deferStruct, const int level) { DeferOperationHandler handler(deferStruct, level); issueOperations<DeferOperationHandler>(deferStruct.mRenderer, handler); } @@ -561,15 +553,7 @@ private: const int mLevel; }; -void RenderNode::replayNodeTree(ReplayStateStruct& replayStruct) { - ReplayOperationHandler handler(replayStruct, 0); - if (MathUtils::isPositive(properties().getZ())) { - issueDrawShadowOperation(Matrix4::identity(), handler); - } - issueOperations<ReplayOperationHandler>(replayStruct.mRenderer, handler); -} - -void RenderNode::replayNodeInParent(ReplayStateStruct& replayStruct, const int level) { +void RenderNode::replay(ReplayStateStruct& replayStruct, const int level) { ReplayOperationHandler handler(replayStruct, level); issueOperations<ReplayOperationHandler>(replayStruct.mRenderer, handler); } @@ -628,6 +612,36 @@ void RenderNode::issueDrawShadowOperation(const Matrix4& transformFromParent, T& handler(shadowOp, PROPERTY_SAVECOUNT, properties().getClipToBounds()); } +template <class T> +int RenderNode::issueOperationsOfNegZChildren( + const Vector<ZDrawDisplayListOpPair>& zTranslatedNodes, + OpenGLRenderer& renderer, T& handler) { + if (zTranslatedNodes.isEmpty()) return -1; + + // create a save around the body of the ViewGroup's draw method, so that + // matrix/clip methods don't affect composited children + int shadowSaveCount = renderer.getSaveCount(); + handler(new (handler.allocator()) SaveOp(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag), + PROPERTY_SAVECOUNT, properties().getClipToBounds()); + + issueOperationsOf3dChildren(zTranslatedNodes, kNegativeZChildren, renderer, handler); + return shadowSaveCount; +} + +template <class T> +void RenderNode::issueOperationsOfPosZChildren(int shadowRestoreTo, + const Vector<ZDrawDisplayListOpPair>& zTranslatedNodes, + OpenGLRenderer& renderer, T& handler) { + if (zTranslatedNodes.isEmpty()) return; + + LOG_ALWAYS_FATAL_IF(shadowRestoreTo < 0, "invalid save to restore to"); + handler(new (handler.allocator()) RestoreToCountOp(shadowRestoreTo), + PROPERTY_SAVECOUNT, properties().getClipToBounds()); + renderer.setOverrideLayerAlpha(1.0f); + + issueOperationsOf3dChildren(zTranslatedNodes, kPositiveZChildren, renderer, handler); +} + #define SHADOW_DELTA 0.1f template <class T> @@ -701,8 +715,6 @@ template <class T> void RenderNode::issueOperationsOfProjectedChildren(OpenGLRenderer& renderer, T& handler) { DISPLAY_LIST_LOGD("%*s%d projected children:", (handler.level() + 1) * 2, "", mProjectedNodes.size()); const SkPath* projectionReceiverOutline = properties().getOutline().getPath(); - bool maskProjecteesWithPath = projectionReceiverOutline != NULL - && !projectionReceiverOutline->isRect(NULL); int restoreTo = renderer.getSaveCount(); // If the projection reciever has an outline, we mask each of the projected rendernodes to it @@ -723,7 +735,7 @@ void RenderNode::issueOperationsOfProjectedChildren(OpenGLRenderer& renderer, T& SaveLayerOp* op = new (alloc) SaveLayerOp( outlineBounds.left(), outlineBounds.top(), outlineBounds.right(), outlineBounds.bottom(), - 255, SkCanvas::kARGB_ClipLayer_SaveFlag); + 255, SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag | SkCanvas::kARGB_ClipLayer_SaveFlag); op->setMask(projectionReceiverOutline); handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds()); @@ -812,7 +824,7 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) { buildZSortedChildList(zTranslatedNodes); // for 3d root, draw children with negative z values - issueOperationsOf3dChildren(zTranslatedNodes, kNegativeZChildren, renderer, handler); + int shadowRestoreTo = issueOperationsOfNegZChildren(zTranslatedNodes, renderer, handler); DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance(); const int saveCountOffset = renderer.getSaveCount() - 1; @@ -820,9 +832,9 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) { for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) { DisplayListOp *op = mDisplayListData->displayListOps[i]; - #if DEBUG_DISPLAY_LIST +#if DEBUG_DISPLAY_LIST op->output(level + 1); - #endif +#endif logBuffer.writeCommand(level, op->name()); handler(op, saveCountOffset, properties().getClipToBounds()); @@ -832,7 +844,7 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) { } // for 3d root, draw children with positive z values - issueOperationsOf3dChildren(zTranslatedNodes, kPositiveZChildren, renderer, handler); + issueOperationsOfPosZChildren(shadowRestoreTo, zTranslatedNodes, renderer, handler); } } diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h index b2fe849..ec12b9f 100644 --- a/libs/hwui/RenderNode.h +++ b/libs/hwui/RenderNode.h @@ -113,11 +113,8 @@ public: void computeOrdering(); - void deferNodeTree(DeferStateStruct& deferStruct); - void deferNodeInParent(DeferStateStruct& deferStruct, const int level); - - void replayNodeTree(ReplayStateStruct& replayStruct); - void replayNodeInParent(ReplayStateStruct& replayStruct, const int level); + void defer(DeferStateStruct& deferStruct, const int level); + void replay(ReplayStateStruct& replayStruct, const int level); ANDROID_API void output(uint32_t level = 1); ANDROID_API int getDebugSize(); @@ -226,6 +223,14 @@ private: inline void issueDrawShadowOperation(const Matrix4& transformFromParent, T& handler); template <class T> + inline int issueOperationsOfNegZChildren( + const Vector<ZDrawDisplayListOpPair>& zTranslatedNodes, + OpenGLRenderer& renderer, T& handler); + template <class T> + inline void issueOperationsOfPosZChildren(int shadowRestoreTo, + const Vector<ZDrawDisplayListOpPair>& zTranslatedNodes, + OpenGLRenderer& renderer, T& handler); + template <class T> inline void issueOperationsOf3dChildren(const Vector<ZDrawDisplayListOpPair>& zTranslatedNodes, ChildrenSelectMode mode, OpenGLRenderer& renderer, T& handler); |