diff options
| -rw-r--r-- | libs/hwui/DisplayList.cpp | 45 | ||||
| -rw-r--r-- | libs/hwui/DisplayList.h | 22 | ||||
| -rw-r--r-- | libs/hwui/Layer.cpp | 1 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 2 |
4 files changed, 59 insertions, 11 deletions
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp index a1563418030b..3c8495e75959 100644 --- a/libs/hwui/DisplayList.cpp +++ b/libs/hwui/DisplayList.cpp @@ -261,6 +261,7 @@ void DisplayList::init() { mHeight = 0; mPivotExplicitlySet = false; mCaching = false; + mOrderingId = 0; } size_t DisplayList::getSize() { @@ -501,13 +502,20 @@ void DisplayList::applyViewPropertyTransforms(mat4& matrix) { */ void DisplayList::computeOrdering() { ATRACE_CALL(); - if (mDisplayListData == NULL) return; + m3dNodes.clear(); + mProjectedNodes.clear(); + mRootDisplayList = this; + mOrderingId++; + // TODO: create temporary DDLOp and call computeOrderingImpl on top DisplayList so that + // transform properties are applied correctly to top level children + if (mDisplayListData == NULL) return; for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) { DrawDisplayListOp* childOp = mDisplayListData->children[i]; childOp->mDisplayList->computeOrderingImpl(childOp, &m3dNodes, &mat4::identity(), - &mProjectedNodes, &mat4::identity()); + &mProjectedNodes, &mat4::identity(), + mRootDisplayList, mOrderingId); } } @@ -516,7 +524,14 @@ void DisplayList::computeOrderingImpl( Vector<ZDrawDisplayListOpPair>* compositedChildrenOf3dRoot, const mat4* transformFrom3dRoot, Vector<DrawDisplayListOp*>* compositedChildrenOfProjectionSurface, - const mat4* transformFromProjectionSurface) { + const mat4* transformFromProjectionSurface, + const void* rootDisplayList, const int orderingId) { + m3dNodes.clear(); + mProjectedNodes.clear(); + + // Temporary, for logging + mRootDisplayList = rootDisplayList; + mOrderingId = orderingId; // TODO: should avoid this calculation in most cases // TODO: just calculate single matrix, down to all leaf composited elements @@ -546,7 +561,6 @@ void DisplayList::computeOrderingImpl( opState->mSkipInOrderDraw = false; } - m3dNodes.clear(); if (mIsContainedVolume) { // create a new 3d space for descendents by collecting them compositedChildrenOf3dRoot = &m3dNodes; @@ -556,7 +570,6 @@ void DisplayList::computeOrderingImpl( transformFrom3dRoot = &localTransformFrom3dRoot; } - mProjectedNodes.clear(); if (mDisplayListData != NULL && mDisplayListData->projectionIndex >= 0) { // create a new projection surface for descendents by collecting them compositedChildrenOfProjectionSurface = &mProjectedNodes; @@ -571,7 +584,8 @@ void DisplayList::computeOrderingImpl( DrawDisplayListOp* childOp = mDisplayListData->children[i]; childOp->mDisplayList->computeOrderingImpl(childOp, compositedChildrenOf3dRoot, transformFrom3dRoot, - compositedChildrenOfProjectionSurface, transformFromProjectionSurface); + compositedChildrenOfProjectionSurface, transformFromProjectionSurface, + rootDisplayList, orderingId); } } } @@ -585,6 +599,7 @@ public: } inline LinearAllocator& allocator() { return *(mDeferStruct.mAllocator); } + const DisplayList* getRoot() { return mDeferStruct.mRoot; } private: DeferStateStruct& mDeferStruct; const int mLevel; @@ -607,6 +622,7 @@ public: } inline LinearAllocator& allocator() { return *(mReplayStruct.mAllocator); } + const DisplayList* getRoot() { return mReplayStruct.mRoot; } private: ReplayStateStruct& mReplayStruct; const int mLevel; @@ -643,6 +659,14 @@ void DisplayList::iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& ren const float zValue = m3dNodes[i].key; DrawDisplayListOp* childOp = m3dNodes[i].value; + if (CC_UNLIKELY(handler.getRoot()->mRootDisplayList != childOp->mDisplayList->mRootDisplayList || + handler.getRoot()->mOrderingId != childOp->mDisplayList->mOrderingId)) { + ALOGW("Error in 3d order computation: Root %p, order %d, expected %p %d", + childOp->mDisplayList->mRootDisplayList, childOp->mDisplayList->mOrderingId, + handler.getRoot()->mRootDisplayList, handler.getRoot()->mOrderingId); + CRASH(); + } + if (mode == kPositiveZChildren && zValue < 0.0f) continue; if (mode == kNegativeZChildren && zValue > 0.0f) break; @@ -704,6 +728,15 @@ void DisplayList::iterate(OpenGLRenderer& renderer, T& handler, const int level) ALOGW("Error: %s is drawing after destruction, size %d", getName(), mSize); CRASH(); } + + if (CC_UNLIKELY(handler.getRoot()->mRootDisplayList != mRootDisplayList || + handler.getRoot()->mOrderingId != mOrderingId)) { + ALOGW("Error in order computation: Root %p, order %d, expected %p %d", + mRootDisplayList, mOrderingId, + handler.getRoot()->mRootDisplayList, handler.getRoot()->mOrderingId); + CRASH(); + } + if (mSize == 0 || mAlpha <= 0) { DISPLAY_LIST_LOGD("%*sEmpty display list (%p, %s)", level * 2, "", this, mName.string()); return; diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h index 5399185e6e44..8026c4afd10b 100644 --- a/libs/hwui/DisplayList.h +++ b/libs/hwui/DisplayList.h @@ -76,7 +76,7 @@ class DrawDisplayListOp; class PlaybackStateStruct { protected: PlaybackStateStruct(OpenGLRenderer& renderer, int replayFlags, LinearAllocator* allocator) - : mRenderer(renderer), mReplayFlags(replayFlags), mAllocator(allocator){} + : mRenderer(renderer), mReplayFlags(replayFlags), mAllocator(allocator), mRoot(NULL) {} public: OpenGLRenderer& mRenderer; @@ -85,6 +85,7 @@ public: // Allocator with the lifetime of a single frame. // replay uses an Allocator owned by the struct, while defer shares the DeferredDisplayList's Allocator LinearAllocator * const mAllocator; + const DisplayList* mRoot; // TEMPORARY, for debug logging only }; class DeferStateStruct : public PlaybackStateStruct { @@ -195,6 +196,9 @@ public: } void setProjectToContainedVolume(bool shouldProject) { + if (!mProjectToContainedVolume && shouldProject) { + ALOGD("DL %s(%p) marked for projection", getName(), this); + } mProjectToContainedVolume = shouldProject; } @@ -260,6 +264,9 @@ public: void setTranslationZ(float translationZ) { if (translationZ != mTranslationZ) { + if (mTranslationZ == 0.0f) { + ALOGD("DL %s(%p) marked for 3d compositing", getName(), this); + } mTranslationZ = translationZ; onTranslationUpdate(); } @@ -527,10 +534,11 @@ private: void applyViewPropertyTransforms(mat4& matrix); void computeOrderingImpl(DrawDisplayListOp* opState, - Vector<ZDrawDisplayListOpPair>* compositedChildrenOf3dRoot, - const mat4* transformFrom3dRoot, - Vector<DrawDisplayListOp*>* compositedChildrenOfProjectionSurface, - const mat4* transformFromProjectionSurface); + Vector<ZDrawDisplayListOpPair>* compositedChildrenOf3dRoot, + const mat4* transformFrom3dRoot, + Vector<DrawDisplayListOp*>* compositedChildrenOfProjectionSurface, + const mat4* transformFromProjectionSurface, + const void* rootDisplayList, const int orderingId); template <class T> inline void setViewProperties(OpenGLRenderer& renderer, T& handler, const int level); @@ -623,6 +631,10 @@ private: // for projection surfaces, contains a list of all children items Vector<DrawDisplayListOp*> mProjectedNodes; + + // TEMPORARY, for debug logging only + const void* mRootDisplayList; + int mOrderingId; }; // class DisplayList }; // namespace uirenderer diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index 742ffd47fd8d..ed571fa5b8c1 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -199,6 +199,7 @@ void Layer::defer() { DeferStateStruct deferredState(*deferredList, *renderer, DisplayList::kReplayFlag_ClipChildren); + deferredState.mRoot = displayList; renderer->initViewport(width, height); renderer->setupFrameState(dirtyRect.left, dirtyRect.top, diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 7ee803fa1a9b..741e953e3eba 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -1877,6 +1877,7 @@ status_t OpenGLRenderer::drawDisplayList(DisplayList* displayList, Rect& dirty, if (CC_UNLIKELY(mCaches.drawDeferDisabled)) { status = startFrame(); ReplayStateStruct replayStruct(*this, dirty, replayFlags); + replayStruct.mRoot = displayList; displayList->replay(replayStruct, 0); return status | replayStruct.mDrawGlStatus; } @@ -1884,6 +1885,7 @@ status_t OpenGLRenderer::drawDisplayList(DisplayList* displayList, Rect& dirty, bool avoidOverdraw = !mCaches.debugOverdraw && !mCountOverdraw; // shh, don't tell devs! DeferredDisplayList deferredList(*currentClipRect(), avoidOverdraw); DeferStateStruct deferStruct(deferredList, *this, replayFlags); + deferStruct.mRoot = displayList; displayList->defer(deferStruct, 0); flushLayers(); |