diff options
author | Chris Craik <ccraik@google.com> | 2014-02-07 18:47:57 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-02-07 18:47:57 +0000 |
commit | 27bfb24518934f0344c79a1d655ea8d1208d2446 (patch) | |
tree | 538f3f695b9e2ca35332db94c180361f92fbb00c /libs | |
parent | 1a88d834e8f7d21e714121c011fec82369a2e9f1 (diff) | |
parent | 1df26446b7eac7050767c38ca977fde03a41a033 (diff) | |
download | frameworks_base-27bfb24518934f0344c79a1d655ea8d1208d2446.zip frameworks_base-27bfb24518934f0344c79a1d655ea8d1208d2446.tar.gz frameworks_base-27bfb24518934f0344c79a1d655ea8d1208d2446.tar.bz2 |
Merge "Rework and clean up DisplayList projection"
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/DisplayList.cpp | 68 | ||||
-rw-r--r-- | libs/hwui/DisplayList.h | 14 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 11 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.h | 2 | ||||
-rw-r--r-- | libs/hwui/Snapshot.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/Snapshot.h | 8 |
6 files changed, 59 insertions, 48 deletions
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp index f67814f..e50ef6f 100644 --- a/libs/hwui/DisplayList.cpp +++ b/libs/hwui/DisplayList.cpp @@ -240,6 +240,7 @@ void DisplayList::init() { mClipToBounds = true; mIsolatedZVolume = true; mProjectBackwards = false; + mProjectionReceiver = false; mOutline.rewind(); mAlpha = 1; mHasOverlappingRendering = true; @@ -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 @@ -552,32 +554,46 @@ void DisplayList::computeOrderingImpl( opState->mSkipInOrderDraw = false; } - if (mIsolatedZVolume) { - // create a new 3d space for descendents by collecting them - compositedChildrenOf3dRoot = &m3dNodes; - transformFrom3dRoot = &mat4::identity(); - } else { - applyViewPropertyTransforms(localTransformFrom3dRoot); - transformFrom3dRoot = &localTransformFrom3dRoot; - } - - if (mDisplayListData != NULL && mDisplayListData->projectionIndex >= 0) { - // create a new projection surface for descendents by collecting them - compositedChildrenOfProjectionSurface = &mProjectedNodes; - transformFromProjectionSurface = &mat4::identity(); - } else { - applyViewPropertyTransforms(localTransformFromProjectionSurface); - transformFromProjectionSurface = &localTransformFromProjectionSurface; - } + if (mDisplayListData->children.size() > 0) { + if (mIsolatedZVolume) { + // create a new 3d space for descendents by collecting them + compositedChildrenOf3dRoot = &m3dNodes; + transformFrom3dRoot = &mat4::identity(); + } else { + applyViewPropertyTransforms(localTransformFrom3dRoot); + transformFrom3dRoot = &localTransformFrom3dRoot; + } - if (mDisplayListData != NULL && mDisplayListData->children.size() > 0) { + const bool isProjectionReceiver = mDisplayListData->projectionReceiveIndex >= 0; + bool haveAppliedPropertiesToProjection = false; for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) { DrawDisplayListOp* childOp = mDisplayListData->children[i]; - childOp->mDisplayList->computeOrderingImpl(childOp, + 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); + haveAppliedPropertiesToProjection = true; + } + projectionChildren = compositedChildrenOfProjectionSurface; + projectionTransform = &localTransformFromProjectionSurface; + } + child->computeOrderingImpl(childOp, compositedChildrenOf3dRoot, transformFrom3dRoot, - compositedChildrenOfProjectionSurface, transformFromProjectionSurface); + projectionChildren, projectionTransform); } } + } class DeferOperationHandler { @@ -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; @@ -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); } @@ -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]; @@ -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); } } diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h index a62ff56..adf48d4 100644 --- a/libs/hwui/DisplayList.h +++ b/libs/hwui/DisplayList.h @@ -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; @@ -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; }; /** @@ -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(); @@ -600,6 +607,7 @@ private: bool mClipToBounds; bool mIsolatedZVolume; bool mProjectBackwards; + bool mProjectionReceiver; SkPath mOutline; float mAlpha; bool mHasOverlappingRendering; diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index c8a6c2d..f7d7b3d 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -173,14 +173,6 @@ void DisplayListRenderer::restoreToCount(int saveCount) { StatefulBaseRenderer::restoreToCount(saveCount); } -void DisplayListRenderer::onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) { - bool restoreProjection = removed.flags & Snapshot::kFlagProjectionTarget; - if (restoreProjection) { - mDisplayListData->projectionIndex = mDisplayListData->displayListOps.size() - 1; - mDisplayListData->projectionTransform.load(*currentTransform()); - } -} - int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom, int alpha, SkXfermode::Mode mode, int flags) { addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, alpha, mode, flags)); @@ -254,6 +246,9 @@ status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList, flags, *currentTransform()); addDrawOp(op); mDisplayListData->children.push(op); + if (displayList->isProjectionReceiver()) { + mDisplayListData->projectionReceiveIndex = mDisplayListData->displayListOps.size() - 1; + } return DrawGlInfo::kStatusDone; } diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 1360808..f129c10 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -221,8 +221,6 @@ public: uint32_t getFunctorCount() const { return mFunctorCount; } -protected: - virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored); private: void insertRestoreToCount(); diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp index a6ec183..d26ee38 100644 --- a/libs/hwui/Snapshot.cpp +++ b/libs/hwui/Snapshot.cpp @@ -70,10 +70,6 @@ Snapshot::Snapshot(const sp<Snapshot>& s, int saveFlags): } else { region = NULL; } - - if (saveFlags & Snapshot::kFlagProjectionTarget) { - flags |= Snapshot::kFlagProjectionTarget; - } } /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h index d61d972..cc6d0cd 100644 --- a/libs/hwui/Snapshot.h +++ b/libs/hwui/Snapshot.h @@ -75,13 +75,7 @@ public: * Indicates that this snapshot or an ancestor snapshot is * an FBO layer. */ - kFlagFboTarget = 0x10, - /** - * Indicates that the save/restore pair encapsulates a - * projection target, and that after the restore any projected - * descendents should be drawn. - */ - kFlagProjectionTarget = 0x20 + kFlagFboTarget = 0x10 }; /** |