summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libs/hwui/DisplayListOp.h8
-rw-r--r--libs/hwui/Layer.cpp2
-rw-r--r--libs/hwui/OpenGLRenderer.cpp4
-rw-r--r--libs/hwui/RenderNode.cpp64
-rw-r--r--libs/hwui/RenderNode.h15
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);