diff options
Diffstat (limited to 'libs/hwui/RenderNode.cpp')
-rw-r--r-- | libs/hwui/RenderNode.cpp | 121 |
1 files changed, 31 insertions, 90 deletions
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index dd20a76eb561..a03ded643521 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -51,7 +51,7 @@ RenderNode::RenderNode() RenderNode::~RenderNode() { deleteDisplayList(nullptr); delete mStagingDisplayList; - LOG_ALWAYS_FATAL_IF(mLayer, "layer missed detachment!"); + LOG_ALWAYS_FATAL_IF(hasLayer(), "layer missed detachment!"); } void RenderNode::setStagingDisplayList(DisplayList* displayList, TreeObserver* observer) { @@ -81,7 +81,7 @@ void RenderNode::output(std::ostream& output, uint32_t level) { << (properties().hasShadow() ? ", casting shadow" : "") << (isRenderable() ? "" : ", empty") << (properties().getProjectBackwards() ? ", projected" : "") - << (mLayer != nullptr ? ", on HW Layer" : "") + << (hasLayer() ? ", on HW Layer" : "") << ")" << std::endl; properties().debugOutputProperties(output, level + 1); @@ -229,19 +229,6 @@ void RenderNode::prepareLayer(TreeInfo& info, uint32_t dirtyMask) { } } -static OffscreenBuffer* createLayer(RenderState& renderState, uint32_t width, uint32_t height) { - return renderState.layerPool().get(renderState, width, height); -} - -static void destroyLayer(OffscreenBuffer* layer) { - RenderState& renderState = layer->renderState; - renderState.layerPool().putOrDelete(layer); -} - -static bool layerMatchesWidthAndHeight(OffscreenBuffer* layer, int width, int height) { - return layer->viewportWidth == (uint32_t) width && layer->viewportHeight == (uint32_t)height; -} - void RenderNode::pushLayerUpdate(TreeInfo& info) { LayerType layerType = properties().effectiveLayerType(); // If we are not a layer OR we cannot be rendered (eg, view was detached) @@ -250,36 +237,17 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { || CC_UNLIKELY(!isRenderable()) || CC_UNLIKELY(properties().getWidth() == 0) || CC_UNLIKELY(properties().getHeight() == 0)) { - if (CC_UNLIKELY(mLayer)) { - destroyLayer(mLayer); - mLayer = nullptr; + if (CC_UNLIKELY(hasLayer())) { + renderthread::CanvasContext::destroyLayer(this); } return; } - bool transformUpdateNeeded = false; - if (!mLayer) { - mLayer = createLayer(info.canvasContext.getRenderState(), getWidth(), getHeight()); + if(info.canvasContext.createOrUpdateLayer(this, *info.damageAccumulator)) { damageSelf(info); - transformUpdateNeeded = true; - } else if (!layerMatchesWidthAndHeight(mLayer, getWidth(), getHeight())) { - // TODO: remove now irrelevant, currently enqueued damage (respecting damage ordering) - // Or, ideally, maintain damage between frames on node/layer so ordering is always correct - RenderState& renderState = mLayer->renderState; - if (properties().fitsOnLayer()) { - mLayer = renderState.layerPool().resize(mLayer, getWidth(), getHeight()); - } else { - destroyLayer(mLayer); - mLayer = nullptr; - } - damageSelf(info); - transformUpdateNeeded = true; } - SkRect dirty; - info.damageAccumulator->peekAtDirty(&dirty); - - if (!mLayer) { + if (!hasLayer()) { Caches::getInstance().dumpMemoryUsage(); if (info.errorHandler) { std::ostringstream err; @@ -296,13 +264,8 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { return; } - if (transformUpdateNeeded && mLayer) { - // update the transform in window of the layer to reset its origin wrt light source position - Matrix4 windowTransform; - info.damageAccumulator->computeCurrentTransform(&windowTransform); - mLayer->setWindowTransform(windowTransform); - } - + SkRect dirty; + info.damageAccumulator->peekAtDirty(&dirty); info.layerUpdateQueue->enqueueLayerWithDamage(this, dirty); // There might be prefetched layers that need to be accounted for. @@ -332,9 +295,9 @@ void RenderNode::prepareTreeImpl(TreeInfo& info, bool functorsNeedLayer) { bool willHaveFunctor = false; if (info.mode == TreeInfo::MODE_FULL && mStagingDisplayList) { - willHaveFunctor = !mStagingDisplayList->getFunctors().empty(); + willHaveFunctor = mStagingDisplayList->hasFunctor(); } else if (mDisplayList) { - willHaveFunctor = !mDisplayList->getFunctors().empty(); + willHaveFunctor = mDisplayList->hasFunctor(); } bool childFunctorsNeedLayer = mProperties.prepareForFunctorPresence( willHaveFunctor, functorsNeedLayer); @@ -347,15 +310,15 @@ void RenderNode::prepareTreeImpl(TreeInfo& info, bool functorsNeedLayer) { if (info.mode == TreeInfo::MODE_FULL) { pushStagingDisplayListChanges(info); } - prepareSubTree(info, childFunctorsNeedLayer, mDisplayList); if (mDisplayList) { - for (auto& vectorDrawable : mDisplayList->getVectorDrawables()) { - // If any vector drawable in the display list needs update, damage the node. - if (vectorDrawable->isDirty()) { - damageSelf(info); - } - vectorDrawable->setPropertyChangeWillBeConsumed(true); + info.out.hasFunctors |= mDisplayList->hasFunctor(); + bool isDirty = mDisplayList->prepareListAndChildren(info, childFunctorsNeedLayer, + [](RenderNode* child, TreeInfo& info, bool functorsNeedLayer) { + child->prepareTreeImpl(info, functorsNeedLayer); + }); + if (isDirty) { + damageSelf(info); } } pushLayerUpdate(info); @@ -393,20 +356,15 @@ void RenderNode::syncDisplayList(TreeInfo* info) { // Make sure we inc first so that we don't fluctuate between 0 and 1, // which would thrash the layer cache if (mStagingDisplayList) { - for (auto&& child : mStagingDisplayList->getChildren()) { - child->renderNode->incParentRefCount(); - } + mStagingDisplayList->updateChildren([](RenderNode* child) { + child->incParentRefCount(); + }); } deleteDisplayList(info ? info->observer : nullptr, info); mDisplayList = mStagingDisplayList; mStagingDisplayList = nullptr; if (mDisplayList) { - for (auto& iter : mDisplayList->getFunctors()) { - (*iter.functor)(DrawGlInfo::kModeSync, nullptr); - } - for (auto& vectorDrawable : mDisplayList->getVectorDrawables()) { - vectorDrawable->syncProperties(); - } + mDisplayList->syncContents(); } } @@ -423,41 +381,24 @@ void RenderNode::pushStagingDisplayListChanges(TreeInfo& info) { void RenderNode::deleteDisplayList(TreeObserver* observer, TreeInfo* info) { if (mDisplayList) { - for (auto&& child : mDisplayList->getChildren()) { - child->renderNode->decParentRefCount(observer, info); + mDisplayList->updateChildren([observer, info](RenderNode* child) { + child->decParentRefCount(observer, info); + }); + if (!mDisplayList->reuseDisplayList(this, info ? &info->canvasContext : nullptr)) { + delete mDisplayList; } } - delete mDisplayList; mDisplayList = nullptr; } -void RenderNode::prepareSubTree(TreeInfo& info, bool functorsNeedLayer, DisplayList* subtree) { - if (subtree) { - TextureCache& cache = Caches::getInstance().textureCache; - info.out.hasFunctors |= subtree->getFunctors().size(); - for (auto&& bitmapResource : subtree->getBitmapResources()) { - void* ownerToken = &info.canvasContext; - info.prepareTextures = cache.prefetchAndMarkInUse(ownerToken, bitmapResource); - } - for (auto&& op : subtree->getChildren()) { - RenderNode* childNode = op->renderNode; - info.damageAccumulator->pushTransform(&op->localMatrix); - bool childFunctorsNeedLayer = functorsNeedLayer; // TODO! || op->mRecordedWithPotentialStencilClip; - childNode->prepareTreeImpl(info, childFunctorsNeedLayer); - info.damageAccumulator->popTransform(); - } - } -} - void RenderNode::destroyHardwareResources(TreeObserver* observer, TreeInfo* info) { - if (mLayer) { - destroyLayer(mLayer); - mLayer = nullptr; + if (hasLayer()) { + renderthread::CanvasContext::destroyLayer(this); } if (mDisplayList) { - for (auto&& child : mDisplayList->getChildren()) { - child->renderNode->destroyHardwareResources(observer, info); - } + mDisplayList->updateChildren([observer, info](RenderNode* child) { + child->destroyHardwareResources(observer, info); + }); if (mNeedsDisplayListSync) { // Next prepare tree we are going to push a new display list, so we can // drop our current one now |