diff options
author | Chris Craik <ccraik@google.com> | 2014-02-05 16:50:41 -0800 |
---|---|---|
committer | Chris Craik <ccraik@google.com> | 2014-02-06 16:07:37 -0800 |
commit | 1df26446b7eac7050767c38ca977fde03a41a033 (patch) | |
tree | 7a21fd8c7d067b80c704c72e2cf02342b7511c78 /libs | |
parent | d5154ec2bc7e7c0bdfd14fc784912d390afe43cc (diff) | |
download | frameworks_base-1df26446b7eac7050767c38ca977fde03a41a033.zip frameworks_base-1df26446b7eac7050767c38ca977fde03a41a033.tar.gz frameworks_base-1df26446b7eac7050767c38ca977fde03a41a033.tar.bz2 |
Rework and clean up DisplayList projection
Move the projection surface to be a property of a DisplayList,
set to true for every background drawable.
Additionally, handle a projecting view background such that it doesn't
try to project onto itself (which is undesirable).
Change-Id: Ic70b17474bd87340e80767f8518f73b233419c7a
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 fd3dae7..ae8c189 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; @@ -524,6 +525,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 @@ -553,32 +555,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 { @@ -638,11 +654,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; @@ -677,18 +693,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); } @@ -740,7 +760,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]; @@ -751,7 +771,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 8622d61..935282e 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 }; /** |