summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorChris Craik <ccraik@google.com>2014-02-07 18:47:57 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-02-07 18:47:57 +0000
commit27bfb24518934f0344c79a1d655ea8d1208d2446 (patch)
tree538f3f695b9e2ca35332db94c180361f92fbb00c /libs
parent1a88d834e8f7d21e714121c011fec82369a2e9f1 (diff)
parent1df26446b7eac7050767c38ca977fde03a41a033 (diff)
downloadframeworks_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.cpp68
-rw-r--r--libs/hwui/DisplayList.h14
-rw-r--r--libs/hwui/DisplayListRenderer.cpp11
-rw-r--r--libs/hwui/DisplayListRenderer.h2
-rw-r--r--libs/hwui/Snapshot.cpp4
-rw-r--r--libs/hwui/Snapshot.h8
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
};
/**