diff options
author | Chris Craik <ccraik@google.com> | 2014-08-21 17:41:57 -0700 |
---|---|---|
committer | Chris Craik <ccraik@google.com> | 2014-08-25 15:35:40 -0700 |
commit | 8afd0f245cc0c4a0366f39f41b5f78e47ee83be3 (patch) | |
tree | 220f6cac192fe822650d4676ef3996da5fb02ad9 | |
parent | cc3e5d5cd197ad45e051e31fd85af28588af4cf7 (diff) | |
download | frameworks_base-8afd0f245cc0c4a0366f39f41b5f78e47ee83be3.zip frameworks_base-8afd0f245cc0c4a0366f39f41b5f78e47ee83be3.tar.gz frameworks_base-8afd0f245cc0c4a0366f39f41b5f78e47ee83be3.tar.bz2 |
Create z reordering boundaries around dispatchDraw
bug:16012254
This means rendernodes with a Z will no longer be drawn at the end of
their parent's DisplayList, but at the end of the associated reorder
region (DisplayListData::Chunk).
Change-Id: Ia033fee9d9a4db567b2a8d5e90fc57a4d0a64544
-rw-r--r-- | core/java/android/view/GLES20Canvas.java | 12 | ||||
-rw-r--r-- | core/java/android/view/ViewGroup.java | 3 | ||||
-rw-r--r-- | core/jni/android_view_GLES20Canvas.cpp | 7 | ||||
-rw-r--r-- | graphics/java/android/graphics/Canvas.java | 6 | ||||
-rw-r--r-- | libs/hwui/DisplayList.cpp | 6 | ||||
-rw-r--r-- | libs/hwui/DisplayList.h | 37 | ||||
-rw-r--r-- | libs/hwui/DisplayListOp.h | 8 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 96 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.h | 31 | ||||
-rw-r--r-- | libs/hwui/RenderNode.cpp | 55 | ||||
-rw-r--r-- | libs/hwui/RenderNode.h | 5 |
11 files changed, 187 insertions, 79 deletions
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index a410aa9..ceea9f8 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -179,6 +179,18 @@ class GLES20Canvas extends HardwareCanvas { private static native void nSetHighContrastText(long renderer, boolean highContrastText); @Override + public void insertReorderBarrier() { + nInsertReorderBarrier(mRenderer, true); + } + + @Override + public void insertInorderBarrier() { + nInsertReorderBarrier(mRenderer, false); + } + + private static native void nInsertReorderBarrier(long renderer, boolean enableReorder); + + @Override public int onPreDraw(Rect dirty) { if (dirty != null) { return nPrepareDirty(mRenderer, dirty.left, dirty.top, dirty.right, dirty.bottom, diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 19dd583..854e6be 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -3072,7 +3072,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager boolean more = false; final long drawingTime = getDrawingTime(); - + if (usingRenderNodeProperties) canvas.insertReorderBarrier(); // Only use the preordered list if not HW accelerated, since the HW pipeline will do the // draw reordering internally final ArrayList<View> preorderedList = usingRenderNodeProperties @@ -3099,6 +3099,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager more |= drawChild(canvas, child, drawingTime); } } + if (usingRenderNodeProperties) canvas.insertInorderBarrier(); if (debugDraw()) { onDebugDraw(canvas); diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index afcfaf6..6080f2a 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -104,6 +104,12 @@ static void android_view_GLES20Canvas_setHighContrastText(JNIEnv* env, jobject c renderer->setHighContrastText(highContrastText); } +static void android_view_GLES20Canvas_insertReorderBarrier(JNIEnv* env, jobject clazz, + jlong rendererPtr, jboolean reorderEnable) { + DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); + renderer->insertReorderBarrier(reorderEnable); +} + static int android_view_GLES20Canvas_prepare(JNIEnv* env, jobject clazz, jlong rendererPtr, jboolean opaque) { DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr); @@ -859,6 +865,7 @@ static JNINativeMethod gMethods[] = { { "nDestroyRenderer", "(J)V", (void*) android_view_GLES20Canvas_destroyRenderer }, { "nSetViewport", "(JII)V", (void*) android_view_GLES20Canvas_setViewport }, { "nSetHighContrastText","(JZ)V", (void*) android_view_GLES20Canvas_setHighContrastText }, + { "nInsertReorderBarrier","(JZ)V", (void*) android_view_GLES20Canvas_insertReorderBarrier }, { "nPrepare", "(JZ)I", (void*) android_view_GLES20Canvas_prepare }, { "nPrepareDirty", "(JIIIIZ)I", (void*) android_view_GLES20Canvas_prepareDirty }, { "nFinish", "(J)V", (void*) android_view_GLES20Canvas_finish }, diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index f3af8f6..f18694b 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -243,6 +243,12 @@ public class Canvas { /** @hide */ public void setHighContrastText(boolean highContrastText) {} + /** @hide */ + public void insertReorderBarrier() {} + + /** @hide */ + public void insertInorderBarrier() {} + /** * @hide */ diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp index 6461ee7..d8932ce 100644 --- a/libs/hwui/DisplayList.cpp +++ b/libs/hwui/DisplayList.cpp @@ -89,11 +89,9 @@ void DisplayListData::cleanupResources() { layers.clear(); } -void DisplayListData::addChild(DrawRenderNodeOp* op) { - LOG_ALWAYS_FATAL_IF(!op->renderNode(), "DrawRenderNodeOp with no render node!"); - - mChildren.push(op); +size_t DisplayListData::addChild(DrawRenderNodeOp* op) { mReferenceHolders.push(op->renderNode()); + return mChildren.add(op); } }; // namespace uirenderer diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h index acfa98e..dea109c 100644 --- a/libs/hwui/DisplayList.h +++ b/libs/hwui/DisplayList.h @@ -115,13 +115,24 @@ public: * Data structure that holds the list of commands used in display list stream */ class DisplayListData { + friend class DisplayListRenderer; public: + struct Chunk { + // range of included ops in DLD::displayListOps + size_t beginOpIndex; + size_t endOpIndex; + + // range of included children in DLD::mChildren + size_t beginChildIndex; + size_t endChildIndex; + + // whether children with non-zero Z in the chunk should be reordered + bool reorderChildren; + }; + DisplayListData(); ~DisplayListData(); - // allocator into which all ops were allocated - LinearAllocator allocator; - // pointers to all ops within display list, pointing into allocator data Vector<DisplayListOp*> displayListOps; @@ -138,13 +149,12 @@ public: Vector<const SkRegion*> regions; Vector<Layer*> layers; Vector<Functor*> functors; - bool hasDrawOps; - bool isEmpty() { - return !displayListOps.size(); + const Vector<Chunk>& getChunks() const { + return chunks; } - void addChild(DrawRenderNodeOp* childOp); + size_t addChild(DrawRenderNodeOp* childOp); const Vector<DrawRenderNodeOp*>& children() { return mChildren; } void refProperty(CanvasPropertyPrimitive* prop) { @@ -155,12 +165,25 @@ public: mReferenceHolders.push(prop); } + size_t getUsedSize() { + return allocator.usedSize(); + } + bool isEmpty() { + return !hasDrawOps; + } + private: Vector< sp<VirtualLightRefBase> > mReferenceHolders; // list of children display lists for quick, non-drawing traversal Vector<DrawRenderNodeOp*> mChildren; + Vector<Chunk> chunks; + + // allocator into which all ops were allocated + LinearAllocator allocator; + bool hasDrawOps; + void cleanupResources(); }; diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index 5f533a7..8818510 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -1445,6 +1445,7 @@ private: class DrawRenderNodeOp : public DrawBoundedOp { friend class RenderNode; // grant RenderNode access to info of child + friend class DisplayListData; // grant DisplayListData access to info of child public: DrawRenderNodeOp(RenderNode* renderNode, int flags, const mat4& transformFromParent) : DrawBoundedOp(0, 0, renderNode->getWidth(), renderNode->getHeight(), 0), @@ -1452,13 +1453,14 @@ public: virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, bool useQuickReject) { - if (mRenderNode && mRenderNode->isRenderable() && !mSkipInOrderDraw) { + if (mRenderNode->isRenderable() && !mSkipInOrderDraw) { mRenderNode->defer(deferStruct, level + 1); } } + virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level, bool useQuickReject) { - if (mRenderNode && mRenderNode->isRenderable() && !mSkipInOrderDraw) { + if (mRenderNode->isRenderable() && !mSkipInOrderDraw) { mRenderNode->replay(replayStruct, level + 1); } } @@ -1469,7 +1471,7 @@ public: } virtual void output(int level, uint32_t logFlags) const { - OP_LOG("Draw Display List %p, flags %#x", mRenderNode, mFlags); + OP_LOG("Draw RenderNode %p %s, flags %#x", mRenderNode, mRenderNode->getName(), mFlags); if (mRenderNode && (logFlags & kOpLogFlag_Recurse)) { mRenderNode->output(level + 1); } diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index 9a9c544..5892978 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -33,10 +33,10 @@ namespace uirenderer { DisplayListRenderer::DisplayListRenderer() : mCaches(Caches::getInstance()) - , mDisplayListData(0) + , mDisplayListData(NULL) , mTranslateX(0.0f) , mTranslateY(0.0f) - , mHasTranslate(false) + , mDeferredBarrierType(kBarrier_None) , mHighContrastText(false) , mRestoreSaveCount(-1) { } @@ -68,6 +68,7 @@ status_t DisplayListRenderer::prepareDirty(float left, float top, initializeSaveStack(0, 0, getWidth(), getHeight(), Vector3()); + mDeferredBarrierType = kBarrier_InOrder; mDirtyClip = opaque; mRestoreSaveCount = -1; @@ -75,8 +76,8 @@ status_t DisplayListRenderer::prepareDirty(float left, float top, } void DisplayListRenderer::finish() { - insertRestoreToCount(); - insertTranslate(); + flushRestoreToCount(); + flushTranslate(); } void DisplayListRenderer::interrupt() { @@ -104,13 +105,13 @@ void DisplayListRenderer::restore() { } mRestoreSaveCount--; - insertTranslate(); + flushTranslate(); StatefulBaseRenderer::restore(); } void DisplayListRenderer::restoreToCount(int saveCount) { mRestoreSaveCount = saveCount; - insertTranslate(); + flushTranslate(); StatefulBaseRenderer::restoreToCount(saveCount); } @@ -123,10 +124,10 @@ int DisplayListRenderer::saveLayer(float left, float top, float right, float bot void DisplayListRenderer::translate(float dx, float dy, float dz) { // ignore dz, not used at defer time - mHasTranslate = true; + mHasDeferredTranslate = true; mTranslateX += dx; mTranslateY += dy; - insertRestoreToCount(); + flushRestoreToCount(); StatefulBaseRenderer::translate(dx, dy, dz); } @@ -174,16 +175,12 @@ bool DisplayListRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) { } status_t DisplayListRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t flags) { + LOG_ALWAYS_FATAL_IF(!renderNode, "missing rendernode"); + // dirty is an out parameter and should not be recorded, // it matters only when replaying the display list DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(renderNode, flags, *currentTransform()); - int opIndex = addDrawOp(op); - mDisplayListData->addChild(op); - - if (renderNode->stagingProperties().isProjectionReceiver()) { - // use staging property, since recording on UI thread - mDisplayListData->projectionReceiveIndex = opIndex; - } + addRenderNodeOp(op); return DrawGlInfo::kStatusDone; } @@ -428,30 +425,60 @@ void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) { addStateOp(new (alloc()) SetupPaintFilterOp(clearBits, setBits)); } -void DisplayListRenderer::insertRestoreToCount() { +void DisplayListRenderer::insertReorderBarrier(bool enableReorder) { + flushRestoreToCount(); + flushTranslate(); + mDeferredBarrierType = enableReorder ? kBarrier_OutOfOrder : kBarrier_InOrder; +} + +void DisplayListRenderer::flushRestoreToCount() { if (mRestoreSaveCount >= 0) { - DisplayListOp* op = new (alloc()) RestoreToCountOp(mRestoreSaveCount); - mDisplayListData->displayListOps.add(op); + addOpAndUpdateChunk(new (alloc()) RestoreToCountOp(mRestoreSaveCount)); mRestoreSaveCount = -1; } } -void DisplayListRenderer::insertTranslate() { - if (mHasTranslate) { +void DisplayListRenderer::flushTranslate() { + if (mHasDeferredTranslate) { if (mTranslateX != 0.0f || mTranslateY != 0.0f) { - DisplayListOp* op = new (alloc()) TranslateOp(mTranslateX, mTranslateY); - mDisplayListData->displayListOps.add(op); + addOpAndUpdateChunk(new (alloc()) TranslateOp(mTranslateX, mTranslateY)); mTranslateX = mTranslateY = 0.0f; } - mHasTranslate = false; + mHasDeferredTranslate = false; } } -int DisplayListRenderer::addStateOp(StateOp* op) { - return addOpInternal(op); +size_t DisplayListRenderer::addOpAndUpdateChunk(DisplayListOp* op) { + int insertIndex = mDisplayListData->displayListOps.add(op); + if (mDeferredBarrierType != kBarrier_None) { + // op is first in new chunk + mDisplayListData->chunks.push(); + DisplayListData::Chunk& newChunk = mDisplayListData->chunks.editTop(); + newChunk.beginOpIndex = insertIndex; + newChunk.endOpIndex = insertIndex + 1; + newChunk.reorderChildren = (mDeferredBarrierType == kBarrier_OutOfOrder); + + int nextChildIndex = mDisplayListData->children().size(); + newChunk.beginChildIndex = newChunk.endChildIndex = nextChildIndex; + mDeferredBarrierType = kBarrier_None; + } else { + // standard case - append to existing chunk + mDisplayListData->chunks.editTop().endOpIndex = insertIndex + 1; + } + return insertIndex; } -int DisplayListRenderer::addDrawOp(DrawOp* op) { +size_t DisplayListRenderer::flushAndAddOp(DisplayListOp* op) { + flushRestoreToCount(); + flushTranslate(); + return addOpAndUpdateChunk(op); +} + +size_t DisplayListRenderer::addStateOp(StateOp* op) { + return flushAndAddOp(op); +} + +size_t DisplayListRenderer::addDrawOp(DrawOp* op) { Rect localBounds; if (op->getLocalBounds(localBounds)) { bool rejected = quickRejectConservative(localBounds.left, localBounds.top, @@ -460,7 +487,22 @@ int DisplayListRenderer::addDrawOp(DrawOp* op) { } mDisplayListData->hasDrawOps = true; - return addOpInternal(op); + return flushAndAddOp(op); +} + +size_t DisplayListRenderer::addRenderNodeOp(DrawRenderNodeOp* op) { + int opIndex = addDrawOp(op); + int childIndex = mDisplayListData->addChild(op); + + // update the chunk's child indices + DisplayListData::Chunk& chunk = mDisplayListData->chunks.editTop(); + chunk.endChildIndex = childIndex + 1; + + if (op->renderNode()->stagingProperties().isProjectionReceiver()) { + // use staging property, since recording on UI thread + mDisplayListData->projectionReceiveIndex = opIndex; + } + return opIndex; } }; // namespace uirenderer diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index b5c0159..7350082 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -57,6 +57,8 @@ public: DisplayListRenderer(); virtual ~DisplayListRenderer(); + void insertReorderBarrier(bool enableReorder); + DisplayListData* finishRecording(); // ---------------------------------------------------------------------------- @@ -154,19 +156,27 @@ public: mHighContrastText = highContrastText; } private: - void insertRestoreToCount(); - void insertTranslate(); + enum DeferredBarrierType { + kBarrier_None, + kBarrier_InOrder, + kBarrier_OutOfOrder, + }; + + void flushRestoreToCount(); + void flushTranslate(); + void flushReorderBarrier(); LinearAllocator& alloc() { return mDisplayListData->allocator; } // Each method returns final index of op - int addStateOp(StateOp* op); - int addDrawOp(DrawOp* op); - int addOpInternal(DisplayListOp* op) { - insertRestoreToCount(); - insertTranslate(); - return mDisplayListData->displayListOps.add(op); - } + size_t addOpAndUpdateChunk(DisplayListOp* op); + // flushes any deferred operations, and appends the op + size_t flushAndAddOp(DisplayListOp* op); + + size_t addStateOp(StateOp* op); + size_t addDrawOp(DrawOp* op); + size_t addRenderNodeOp(DrawRenderNodeOp* op); + template<class T> inline const T* refBuffer(const T* srcBuffer, int32_t count) { @@ -277,7 +287,8 @@ private: float mTranslateX; float mTranslateY; - bool mHasTranslate; + bool mHasDeferredTranslate; + DeferredBarrierType mDeferredBarrierType; bool mHighContrastText; int mRestoreSaveCount; diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index 977744f..658265d 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -95,6 +95,7 @@ void RenderNode::output(uint32_t level) { properties().debugOutputProperties(level); int flags = DisplayListOp::kOpLogFlag_Recurse; if (mDisplayListData) { + // TODO: consider printing the chunk boundaries here for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) { mDisplayListData->displayListOps[i]->output(level, flags); } @@ -106,10 +107,10 @@ void RenderNode::output(uint32_t level) { int RenderNode::getDebugSize() { int size = sizeof(RenderNode); if (mStagingDisplayListData) { - size += mStagingDisplayListData->allocator.usedSize(); + size += mStagingDisplayListData->getUsedSize(); } if (mDisplayListData && mDisplayListData != mStagingDisplayListData) { - size += mDisplayListData->allocator.usedSize(); + size += mDisplayListData->getUsedSize(); } return size; } @@ -593,15 +594,16 @@ void RenderNode::replay(ReplayStateStruct& replayStruct, const int level) { issueOperations<ReplayOperationHandler>(replayStruct.mRenderer, handler); } -void RenderNode::buildZSortedChildList(Vector<ZDrawRenderNodeOpPair>& zTranslatedNodes) { - if (mDisplayListData == NULL || mDisplayListData->children().size() == 0) return; +void RenderNode::buildZSortedChildList(const DisplayListData::Chunk& chunk, + Vector<ZDrawRenderNodeOpPair>& zTranslatedNodes) { + if (chunk.beginChildIndex == chunk.endChildIndex) return; - for (unsigned int i = 0; i < mDisplayListData->children().size(); i++) { + for (unsigned int i = chunk.beginChildIndex; i < chunk.endChildIndex; i++) { DrawRenderNodeOp* childOp = mDisplayListData->children()[i]; RenderNode* child = childOp->mRenderNode; float childZ = child->properties().getZ(); - if (!MathUtils::isZero(childZ)) { + if (!MathUtils::isZero(childZ) && chunk.reorderChildren) { zTranslatedNodes.add(ZDrawRenderNodeOpPair(childZ, childOp)); childOp->mSkipInOrderDraw = true; } else if (!child->properties().getProjectBackwards()) { @@ -610,7 +612,7 @@ void RenderNode::buildZSortedChildList(Vector<ZDrawRenderNodeOpPair>& zTranslate } } - // Z sort 3d children (stable-ness makes z compare fall back to standard drawing order) + // Z sort any 3d children (stable-ness makes z compare fall back to standard drawing order) std::stable_sort(zTranslatedNodes.begin(), zTranslatedNodes.end()); } @@ -871,32 +873,35 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) { handler(new (alloc) DrawLayerOp(mLayer, 0, 0), renderer.getSaveCount() - 1, properties().getClipToBounds()); } else { - Vector<ZDrawRenderNodeOpPair> zTranslatedNodes; - buildZSortedChildList(zTranslatedNodes); + DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance(); + for (size_t chunkIndex = 0; chunkIndex < mDisplayListData->getChunks().size(); chunkIndex++) { + const DisplayListData::Chunk& chunk = mDisplayListData->getChunks()[chunkIndex]; - // for 3d root, draw children with negative z values - int shadowRestoreTo = issueOperationsOfNegZChildren(zTranslatedNodes, renderer, handler); + Vector<ZDrawRenderNodeOpPair> zTranslatedNodes; + buildZSortedChildList(chunk, zTranslatedNodes); - DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance(); - const int saveCountOffset = renderer.getSaveCount() - 1; - const int projectionReceiveIndex = mDisplayListData->projectionReceiveIndex; - const int size = static_cast<int>(mDisplayListData->displayListOps.size()); - for (int i = 0; i < size; i++) { - DisplayListOp *op = mDisplayListData->displayListOps[i]; + // for 3d root, draw children with negative z values + int shadowRestoreTo = issueOperationsOfNegZChildren(zTranslatedNodes, + renderer, handler); + const int saveCountOffset = renderer.getSaveCount() - 1; + const int projectionReceiveIndex = mDisplayListData->projectionReceiveIndex; + for (int opIndex = chunk.beginOpIndex; opIndex < chunk.endOpIndex; opIndex++) { + DisplayListOp *op = mDisplayListData->displayListOps[opIndex]; #if DEBUG_DISPLAY_LIST - op->output(level + 1); + op->output(level + 1); #endif - logBuffer.writeCommand(level, op->name()); - handler(op, saveCountOffset, properties().getClipToBounds()); + logBuffer.writeCommand(level, op->name()); + handler(op, saveCountOffset, properties().getClipToBounds()); - if (CC_UNLIKELY(i == projectionReceiveIndex && mProjectedNodes.size() > 0)) { - issueOperationsOfProjectedChildren(renderer, handler); + if (CC_UNLIKELY(!mProjectedNodes.isEmpty() && opIndex == projectionReceiveIndex)) { + issueOperationsOfProjectedChildren(renderer, handler); + } } - } - // for 3d root, draw children with positive z values - issueOperationsOfPosZChildren(shadowRestoreTo, zTranslatedNodes, renderer, handler); + // for 3d root, draw children with positive z values + issueOperationsOfPosZChildren(shadowRestoreTo, zTranslatedNodes, renderer, handler); + } } } diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h index afa17d5..18402b2 100644 --- a/libs/hwui/RenderNode.h +++ b/libs/hwui/RenderNode.h @@ -114,7 +114,7 @@ public: ANDROID_API int getDebugSize(); bool isRenderable() const { - return mDisplayListData && mDisplayListData->hasDrawOps; + return mDisplayListData && !mDisplayListData->isEmpty(); } bool hasProjectionReceiver() const { @@ -199,7 +199,8 @@ private: template <class T> inline void setViewProperties(OpenGLRenderer& renderer, T& handler); - void buildZSortedChildList(Vector<ZDrawRenderNodeOpPair>& zTranslatedNodes); + void buildZSortedChildList(const DisplayListData::Chunk& chunk, + Vector<ZDrawRenderNodeOpPair>& zTranslatedNodes); template<class T> inline void issueDrawShadowOperation(const Matrix4& transformFromParent, T& handler); |