summaryrefslogtreecommitdiff
path: root/libs/hwui/RenderNode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/RenderNode.cpp')
-rw-r--r--libs/hwui/RenderNode.cpp443
1 files changed, 299 insertions, 144 deletions
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 642ec25dfe83..3f24f44e52da 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -14,20 +14,14 @@
* limitations under the License.
*/
-#define ATRACE_TAG ATRACE_TAG_VIEW
-#define LOG_TAG "OpenGLRenderer"
-
#include "RenderNode.h"
-#include <algorithm>
-#include <string>
-
-#include <SkCanvas.h>
-#include <algorithm>
-
-
#include "DamageAccumulator.h"
#include "Debug.h"
+#if HWUI_NEW_OPS
+#include "RecordedOp.h"
+#include "BakedOpRenderer.h"
+#endif
#include "DisplayListOp.h"
#include "LayerRenderer.h"
#include "OpenGLRenderer.h"
@@ -36,46 +30,67 @@
#include "utils/TraceUtils.h"
#include "renderthread/CanvasContext.h"
+#include "protos/hwui.pb.h"
+#include "protos/ProtoHelpers.h"
+
+#include <SkCanvas.h>
+
+#include <algorithm>
+#include <sstream>
+#include <string>
+
namespace android {
namespace uirenderer {
void RenderNode::debugDumpLayers(const char* prefix) {
+#if HWUI_NEW_OPS
+ LOG_ALWAYS_FATAL("TODO: dump layer");
+#else
if (mLayer) {
ALOGD("%sNode %p (%s) has layer %p (fbo = %u, wasBuildLayered = %s)",
prefix, this, getName(), mLayer, mLayer->getFbo(),
mLayer->wasBuildLayered ? "true" : "false");
}
- if (mDisplayListData) {
- for (size_t i = 0; i < mDisplayListData->children().size(); i++) {
- mDisplayListData->children()[i]->mRenderNode->debugDumpLayers(prefix);
+#endif
+ if (mDisplayList) {
+ for (auto&& child : mDisplayList->getChildren()) {
+ child->renderNode->debugDumpLayers(prefix);
}
}
}
RenderNode::RenderNode()
: mDirtyPropertyFields(0)
- , mNeedsDisplayListDataSync(false)
- , mDisplayListData(nullptr)
- , mStagingDisplayListData(nullptr)
+ , mNeedsDisplayListSync(false)
+ , mDisplayList(nullptr)
+ , mStagingDisplayList(nullptr)
, mAnimatorManager(*this)
- , mLayer(nullptr)
, mParentCount(0) {
}
RenderNode::~RenderNode() {
- deleteDisplayListData();
- delete mStagingDisplayListData;
+ deleteDisplayList();
+ delete mStagingDisplayList;
+#if HWUI_NEW_OPS
+ LOG_ALWAYS_FATAL_IF(mLayer, "layer missed detachment!");
+#else
if (mLayer) {
ALOGW("Memory Warning: Layer %p missed its detachment, held on to for far too long!", mLayer);
mLayer->postDecStrong();
mLayer = nullptr;
}
+#endif
}
-void RenderNode::setStagingDisplayList(DisplayListData* data) {
- mNeedsDisplayListDataSync = true;
- delete mStagingDisplayListData;
- mStagingDisplayListData = data;
+void RenderNode::setStagingDisplayList(DisplayList* displayList) {
+ mNeedsDisplayListSync = true;
+ delete mStagingDisplayList;
+ mStagingDisplayList = displayList;
+ // If mParentCount == 0 we are the sole reference to this RenderNode,
+ // so immediately free the old display list
+ if (!mParentCount && !mStagingDisplayList) {
+ deleteDisplayList();
+ }
}
/**
@@ -94,24 +109,100 @@ void RenderNode::output(uint32_t level) {
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
properties().debugOutputProperties(level);
- int flags = DisplayListOp::kOpLogFlag_Recurse;
- if (mDisplayListData) {
+
+ if (mDisplayList) {
+#if HWUI_NEW_OPS
+ LOG_ALWAYS_FATAL("op dumping unsupported");
+#else
// TODO: consider printing the chunk boundaries here
- for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
- mDisplayListData->displayListOps[i]->output(level, flags);
+ for (auto&& op : mDisplayList->getOps()) {
+ op->output(level, DisplayListOp::kOpLogFlag_Recurse);
}
+#endif
}
ALOGD("%*sDone (%p, %s)", (level - 1) * 2, "", this, getName());
}
+void RenderNode::copyTo(proto::RenderNode *pnode) {
+ pnode->set_id(static_cast<uint64_t>(
+ reinterpret_cast<uintptr_t>(this)));
+ pnode->set_name(mName.string(), mName.length());
+
+ proto::RenderProperties* pprops = pnode->mutable_properties();
+ pprops->set_left(properties().getLeft());
+ pprops->set_top(properties().getTop());
+ pprops->set_right(properties().getRight());
+ pprops->set_bottom(properties().getBottom());
+ pprops->set_clip_flags(properties().getClippingFlags());
+ pprops->set_alpha(properties().getAlpha());
+ pprops->set_translation_x(properties().getTranslationX());
+ pprops->set_translation_y(properties().getTranslationY());
+ pprops->set_translation_z(properties().getTranslationZ());
+ pprops->set_elevation(properties().getElevation());
+ pprops->set_rotation(properties().getRotation());
+ pprops->set_rotation_x(properties().getRotationX());
+ pprops->set_rotation_y(properties().getRotationY());
+ pprops->set_scale_x(properties().getScaleX());
+ pprops->set_scale_y(properties().getScaleY());
+ pprops->set_pivot_x(properties().getPivotX());
+ pprops->set_pivot_y(properties().getPivotY());
+ pprops->set_has_overlapping_rendering(properties().getHasOverlappingRendering());
+ pprops->set_pivot_explicitly_set(properties().isPivotExplicitlySet());
+ pprops->set_project_backwards(properties().getProjectBackwards());
+ pprops->set_projection_receiver(properties().isProjectionReceiver());
+ set(pprops->mutable_clip_bounds(), properties().getClipBounds());
+
+ const Outline& outline = properties().getOutline();
+ if (outline.getType() != Outline::Type::None) {
+ proto::Outline* poutline = pprops->mutable_outline();
+ poutline->clear_path();
+ if (outline.getType() == Outline::Type::Empty) {
+ poutline->set_type(proto::Outline_Type_Empty);
+ } else if (outline.getType() == Outline::Type::ConvexPath) {
+ poutline->set_type(proto::Outline_Type_ConvexPath);
+ if (const SkPath* path = outline.getPath()) {
+ set(poutline->mutable_path(), *path);
+ }
+ } else if (outline.getType() == Outline::Type::RoundRect) {
+ poutline->set_type(proto::Outline_Type_RoundRect);
+ } else {
+ ALOGW("Uknown outline type! %d", static_cast<int>(outline.getType()));
+ poutline->set_type(proto::Outline_Type_None);
+ }
+ poutline->set_should_clip(outline.getShouldClip());
+ poutline->set_alpha(outline.getAlpha());
+ poutline->set_radius(outline.getRadius());
+ set(poutline->mutable_bounds(), outline.getBounds());
+ } else {
+ pprops->clear_outline();
+ }
+
+ const RevealClip& revealClip = properties().getRevealClip();
+ if (revealClip.willClip()) {
+ proto::RevealClip* prevealClip = pprops->mutable_reveal_clip();
+ prevealClip->set_x(revealClip.getX());
+ prevealClip->set_y(revealClip.getY());
+ prevealClip->set_radius(revealClip.getRadius());
+ } else {
+ pprops->clear_reveal_clip();
+ }
+
+ pnode->clear_children();
+ if (mDisplayList) {
+ for (auto&& child : mDisplayList->getChildren()) {
+ child->renderNode->copyTo(pnode->add_children());
+ }
+ }
+}
+
int RenderNode::getDebugSize() {
int size = sizeof(RenderNode);
- if (mStagingDisplayListData) {
- size += mStagingDisplayListData->getUsedSize();
+ if (mStagingDisplayList) {
+ size += mStagingDisplayList->getUsedSize();
}
- if (mDisplayListData && mDisplayListData != mStagingDisplayListData) {
- size += mDisplayListData->getUsedSize();
+ if (mDisplayList && mDisplayList != mStagingDisplayList) {
+ size += mDisplayList->getUsedSize();
}
return size;
}
@@ -137,7 +228,7 @@ void RenderNode::damageSelf(TreeInfo& info) {
} else {
// Hope this is big enough?
// TODO: Get this from the display list ops or something
- info.damageAccumulator->dirty(INT_MIN, INT_MIN, INT_MAX, INT_MAX);
+ info.damageAccumulator->dirty(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX);
}
}
}
@@ -157,13 +248,38 @@ void RenderNode::prepareLayer(TreeInfo& info, uint32_t dirtyMask) {
}
}
+static layer_t* createLayer(RenderState& renderState, uint32_t width, uint32_t height) {
+#if HWUI_NEW_OPS
+ return renderState.layerPool().get(renderState, width, height);
+#else
+ return LayerRenderer::createRenderLayer(renderState, width, height);
+#endif
+}
+
+static void destroyLayer(layer_t* layer) {
+#if HWUI_NEW_OPS
+ RenderState& renderState = layer->renderState;
+ renderState.layerPool().putOrDelete(layer);
+#else
+ LayerRenderer::destroyLayer(layer);
+#endif
+}
+
+static bool layerMatchesWidthAndHeight(layer_t* layer, int width, int height) {
+#if HWUI_NEW_OPS
+ return layer->viewportWidth == (uint32_t) width && layer->viewportHeight == (uint32_t)height;
+#else
+ return layer->layer.getWidth() == width && layer->layer.getHeight() == height;
+#endif
+}
+
void RenderNode::pushLayerUpdate(TreeInfo& info) {
LayerType layerType = properties().effectiveLayerType();
// If we are not a layer OR we cannot be rendered (eg, view was detached)
// we need to destroy any Layers we may have had previously
if (CC_LIKELY(layerType != LayerType::RenderLayer) || CC_UNLIKELY(!isRenderable())) {
if (CC_UNLIKELY(mLayer)) {
- LayerRenderer::destroyLayer(mLayer);
+ destroyLayer(mLayer);
mLayer = nullptr;
}
return;
@@ -171,13 +287,22 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) {
bool transformUpdateNeeded = false;
if (!mLayer) {
- mLayer = LayerRenderer::createRenderLayer(info.renderState, getWidth(), getHeight());
+ mLayer = createLayer(info.canvasContext.getRenderState(), getWidth(), getHeight());
+#if !HWUI_NEW_OPS
applyLayerPropertiesToLayer(info);
+#endif
damageSelf(info);
transformUpdateNeeded = true;
- } else if (mLayer->layer.getWidth() != getWidth() || mLayer->layer.getHeight() != getHeight()) {
+ } else if (!layerMatchesWidthAndHeight(mLayer, getWidth(), getHeight())) {
+#if HWUI_NEW_OPS
+ RenderState& renderState = mLayer->renderState;
+ if (properties().fitsOnLayer()) {
+ mLayer = renderState.layerPool().resize(mLayer, getWidth(), getHeight());
+ } else {
+#else
if (!LayerRenderer::resizeLayer(mLayer, getWidth(), getHeight())) {
- LayerRenderer::destroyLayer(mLayer);
+#endif
+ destroyLayer(mLayer);
mLayer = nullptr;
}
damageSelf(info);
@@ -190,20 +315,30 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) {
if (!mLayer) {
Caches::getInstance().dumpMemoryUsage();
if (info.errorHandler) {
- std::string msg = "Unable to create layer for ";
- msg += getName();
- info.errorHandler->onError(msg);
+ std::ostringstream err;
+ err << "Unable to create layer for " << getName();
+ const int maxTextureSize = Caches::getInstance().maxTextureSize;
+ if (getWidth() > maxTextureSize || getHeight() > maxTextureSize) {
+ err << ", size " << getWidth() << "x" << getHeight()
+ << " exceeds max size " << maxTextureSize;
+ } else {
+ err << ", see logcat for more info";
+ }
+ info.errorHandler->onError(err.str());
}
return;
}
- if (transformUpdateNeeded) {
+ 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);
}
+#if HWUI_NEW_OPS
+ info.layerUpdateQueue->enqueueLayerWithDamage(this, dirty);
+#else
if (dirty.intersect(0, 0, getWidth(), getHeight())) {
dirty.roundOut(&dirty);
mLayer->updateDeferred(this, dirty.fLeft, dirty.fTop, dirty.fRight, dirty.fBottom);
@@ -213,13 +348,12 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) {
if (info.renderer && mLayer->deferredUpdateScheduled) {
info.renderer->pushLayerUpdate(mLayer);
}
+#endif
- if (info.canvasContext) {
- // There might be prefetched layers that need to be accounted for.
- // That might be us, so tell CanvasContext that this layer is in the
- // tree and should not be destroyed.
- info.canvasContext->markLayerInUse(this);
- }
+ // There might be prefetched layers that need to be accounted for.
+ // That might be us, so tell CanvasContext that this layer is in the
+ // tree and should not be destroyed.
+ info.canvasContext.markLayerInUse(this);
}
/**
@@ -242,10 +376,10 @@ void RenderNode::prepareTreeImpl(TreeInfo& info, bool functorsNeedLayer) {
}
bool willHaveFunctor = false;
- if (info.mode == TreeInfo::MODE_FULL && mStagingDisplayListData) {
- willHaveFunctor = !mStagingDisplayListData->functors.isEmpty();
- } else if (mDisplayListData) {
- willHaveFunctor = !mDisplayListData->functors.isEmpty();
+ if (info.mode == TreeInfo::MODE_FULL && mStagingDisplayList) {
+ willHaveFunctor = !mStagingDisplayList->getFunctors().empty();
+ } else if (mDisplayList) {
+ willHaveFunctor = !mDisplayList->getFunctors().empty();
}
bool childFunctorsNeedLayer = mProperties.prepareForFunctorPresence(
willHaveFunctor, functorsNeedLayer);
@@ -254,12 +388,16 @@ void RenderNode::prepareTreeImpl(TreeInfo& info, bool functorsNeedLayer) {
if (info.mode == TreeInfo::MODE_FULL) {
pushStagingDisplayListChanges(info);
}
- prepareSubTree(info, childFunctorsNeedLayer, mDisplayListData);
+ prepareSubTree(info, childFunctorsNeedLayer, mDisplayList);
pushLayerUpdate(info);
info.damageAccumulator->popTransform();
}
+void RenderNode::syncProperties() {
+ mProperties = mStagingProperties;
+}
+
void RenderNode::pushStagingPropertiesChanges(TreeInfo& info) {
// Push the animators first so that setupStartValueIfNecessary() is called
// before properties() is trampled by stagingProperties(), as they are
@@ -271,8 +409,10 @@ void RenderNode::pushStagingPropertiesChanges(TreeInfo& info) {
mDirtyPropertyFields = 0;
damageSelf(info);
info.damageAccumulator->popTransform();
- mProperties = mStagingProperties;
+ syncProperties();
+#if !HWUI_NEW_OPS
applyLayerPropertiesToLayer(info);
+#endif
// We could try to be clever and only re-damage if the matrix changed.
// However, we don't need to worry about that. The cost of over-damaging
// here is only going to be a single additional map rect of this node
@@ -283,6 +423,7 @@ void RenderNode::pushStagingPropertiesChanges(TreeInfo& info) {
}
}
+#if !HWUI_NEW_OPS
void RenderNode::applyLayerPropertiesToLayer(TreeInfo& info) {
if (CC_LIKELY(!mLayer)) return;
@@ -291,64 +432,66 @@ void RenderNode::applyLayerPropertiesToLayer(TreeInfo& info) {
mLayer->setColorFilter(props.colorFilter());
mLayer->setBlend(props.needsBlending());
}
+#endif
-void RenderNode::pushStagingDisplayListChanges(TreeInfo& info) {
- if (mNeedsDisplayListDataSync) {
- mNeedsDisplayListDataSync = false;
- // Make sure we inc first so that we don't fluctuate between 0 and 1,
- // which would thrash the layer cache
- if (mStagingDisplayListData) {
- for (size_t i = 0; i < mStagingDisplayListData->children().size(); i++) {
- mStagingDisplayListData->children()[i]->mRenderNode->incParentRefCount();
- }
+void RenderNode::syncDisplayList() {
+ // 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();
}
+ }
+ deleteDisplayList();
+ mDisplayList = mStagingDisplayList;
+ mStagingDisplayList = nullptr;
+ if (mDisplayList) {
+ for (size_t i = 0; i < mDisplayList->getFunctors().size(); i++) {
+ (*mDisplayList->getFunctors()[i])(DrawGlInfo::kModeSync, nullptr);
+ }
+ }
+}
+
+void RenderNode::pushStagingDisplayListChanges(TreeInfo& info) {
+ if (mNeedsDisplayListSync) {
+ mNeedsDisplayListSync = false;
// Damage with the old display list first then the new one to catch any
// changes in isRenderable or, in the future, bounds
damageSelf(info);
- deleteDisplayListData();
- // TODO: Remove this caches stuff
- if (mStagingDisplayListData && mStagingDisplayListData->functors.size()) {
- Caches::getInstance().registerFunctors(mStagingDisplayListData->functors.size());
- }
- mDisplayListData = mStagingDisplayListData;
- mStagingDisplayListData = nullptr;
- if (mDisplayListData) {
- for (size_t i = 0; i < mDisplayListData->functors.size(); i++) {
- (*mDisplayListData->functors[i])(DrawGlInfo::kModeSync, nullptr);
- }
- }
+ syncDisplayList();
damageSelf(info);
}
}
-void RenderNode::deleteDisplayListData() {
- if (mDisplayListData) {
- for (size_t i = 0; i < mDisplayListData->children().size(); i++) {
- mDisplayListData->children()[i]->mRenderNode->decParentRefCount();
- }
- if (mDisplayListData->functors.size()) {
- Caches::getInstance().unregisterFunctors(mDisplayListData->functors.size());
+void RenderNode::deleteDisplayList() {
+ if (mDisplayList) {
+ for (auto&& child : mDisplayList->getChildren()) {
+ child->renderNode->decParentRefCount();
}
}
- delete mDisplayListData;
- mDisplayListData = nullptr;
+ delete mDisplayList;
+ mDisplayList = nullptr;
}
-void RenderNode::prepareSubTree(TreeInfo& info, bool functorsNeedLayer, DisplayListData* subtree) {
+void RenderNode::prepareSubTree(TreeInfo& info, bool functorsNeedLayer, DisplayList* subtree) {
if (subtree) {
TextureCache& cache = Caches::getInstance().textureCache;
- info.out.hasFunctors |= subtree->functors.size();
- for (size_t i = 0; info.prepareTextures && i < subtree->bitmapResources.size(); i++) {
- info.prepareTextures = cache.prefetchAndMarkInUse(
- info.canvasContext, subtree->bitmapResources[i]);
+ info.out.hasFunctors |= subtree->getFunctors().size();
+ for (auto&& bitmapResource : subtree->getBitmapResources()) {
+ void* ownerToken = &info.canvasContext;
+ info.prepareTextures = cache.prefetchAndMarkInUse(ownerToken, bitmapResource);
}
- for (size_t i = 0; i < subtree->children().size(); i++) {
- DrawRenderNodeOp* op = subtree->children()[i];
- RenderNode* childNode = op->mRenderNode;
+ for (auto&& op : subtree->getChildren()) {
+ RenderNode* childNode = op->renderNode;
+#if HWUI_NEW_OPS
+ info.damageAccumulator->pushTransform(&op->localMatrix);
+ bool childFunctorsNeedLayer = functorsNeedLayer; // TODO! || op->mRecordedWithPotentialStencilClip;
+#else
info.damageAccumulator->pushTransform(&op->mTransformFromParent);
bool childFunctorsNeedLayer = functorsNeedLayer
// Recorded with non-rect clip, or canvas-rotated by parent
|| op->mRecordedWithPotentialStencilClip;
+#endif
childNode->prepareTreeImpl(info, childFunctorsNeedLayer);
info.damageAccumulator->popTransform();
}
@@ -357,17 +500,17 @@ void RenderNode::prepareSubTree(TreeInfo& info, bool functorsNeedLayer, DisplayL
void RenderNode::destroyHardwareResources() {
if (mLayer) {
- LayerRenderer::destroyLayer(mLayer);
+ destroyLayer(mLayer);
mLayer = nullptr;
}
- if (mDisplayListData) {
- for (size_t i = 0; i < mDisplayListData->children().size(); i++) {
- mDisplayListData->children()[i]->mRenderNode->destroyHardwareResources();
+ if (mDisplayList) {
+ for (auto&& child : mDisplayList->getChildren()) {
+ child->renderNode->destroyHardwareResources();
}
- if (mNeedsDisplayListDataSync) {
+ if (mNeedsDisplayListSync) {
// Next prepare tree we are going to push a new display list, so we can
// drop our current one now
- deleteDisplayListData();
+ deleteDisplayList();
}
}
}
@@ -515,26 +658,27 @@ void RenderNode::applyViewPropertyTransforms(mat4& matrix, bool true3dTransform)
* which are flagged to not draw in the standard draw loop.
*/
void RenderNode::computeOrdering() {
+#if !HWUI_NEW_OPS
ATRACE_CALL();
mProjectedNodes.clear();
// TODO: create temporary DDLOp and call computeOrderingImpl on top DisplayList so that
// transform properties are applied correctly to top level children
- if (mDisplayListData == nullptr) return;
- for (unsigned int i = 0; i < mDisplayListData->children().size(); i++) {
- DrawRenderNodeOp* childOp = mDisplayListData->children()[i];
- childOp->mRenderNode->computeOrderingImpl(childOp,
- properties().getOutline().getPath(), &mProjectedNodes, &mat4::identity());
+ if (mDisplayList == nullptr) return;
+ for (unsigned int i = 0; i < mDisplayList->getChildren().size(); i++) {
+ DrawRenderNodeOp* childOp = mDisplayList->getChildren()[i];
+ childOp->renderNode->computeOrderingImpl(childOp, &mProjectedNodes, &mat4::identity());
}
+#endif
}
void RenderNode::computeOrderingImpl(
DrawRenderNodeOp* opState,
- const SkPath* outlineOfProjectionSurface,
- Vector<DrawRenderNodeOp*>* compositedChildrenOfProjectionSurface,
+ std::vector<DrawRenderNodeOp*>* compositedChildrenOfProjectionSurface,
const mat4* transformFromProjectionSurface) {
+#if !HWUI_NEW_OPS
mProjectedNodes.clear();
- if (mDisplayListData == nullptr || mDisplayListData->isEmpty()) return;
+ if (mDisplayList == nullptr || mDisplayList->isEmpty()) return;
// TODO: should avoid this calculation in most cases
// TODO: just calculate single matrix, down to all leaf composited elements
@@ -544,22 +688,21 @@ void RenderNode::computeOrderingImpl(
if (properties().getProjectBackwards()) {
// composited projectee, flag for out of order draw, save matrix, and store in proj surface
opState->mSkipInOrderDraw = true;
- opState->mTransformFromCompositingAncestor.load(localTransformFromProjectionSurface);
- compositedChildrenOfProjectionSurface->add(opState);
+ opState->mTransformFromCompositingAncestor = localTransformFromProjectionSurface;
+ compositedChildrenOfProjectionSurface->push_back(opState);
} else {
// standard in order draw
opState->mSkipInOrderDraw = false;
}
- if (mDisplayListData->children().size() > 0) {
- const bool isProjectionReceiver = mDisplayListData->projectionReceiveIndex >= 0;
+ if (mDisplayList->getChildren().size() > 0) {
+ const bool isProjectionReceiver = mDisplayList->projectionReceiveIndex >= 0;
bool haveAppliedPropertiesToProjection = false;
- for (unsigned int i = 0; i < mDisplayListData->children().size(); i++) {
- DrawRenderNodeOp* childOp = mDisplayListData->children()[i];
- RenderNode* child = childOp->mRenderNode;
+ for (unsigned int i = 0; i < mDisplayList->getChildren().size(); i++) {
+ DrawRenderNodeOp* childOp = mDisplayList->getChildren()[i];
+ RenderNode* child = childOp->renderNode;
- const SkPath* projectionOutline = nullptr;
- Vector<DrawRenderNodeOp*>* projectionChildren = nullptr;
+ std::vector<DrawRenderNodeOp*>* projectionChildren = nullptr;
const mat4* projectionTransform = nullptr;
if (isProjectionReceiver && !child->properties().getProjectBackwards()) {
// if receiving projections, collect projecting descendant
@@ -567,7 +710,6 @@ void RenderNode::computeOrderingImpl(
// Note that if a direct descendant is projecting backwards, we pass its
// grandparent projection collection, since it shouldn't project onto its
// parent, where it will already be drawing.
- projectionOutline = properties().getOutline().getPath();
projectionChildren = &mProjectedNodes;
projectionTransform = &mat4::identity();
} else {
@@ -575,14 +717,13 @@ void RenderNode::computeOrderingImpl(
applyViewPropertyTransforms(localTransformFromProjectionSurface);
haveAppliedPropertiesToProjection = true;
}
- projectionOutline = outlineOfProjectionSurface;
projectionChildren = compositedChildrenOfProjectionSurface;
projectionTransform = &localTransformFromProjectionSurface;
}
- child->computeOrderingImpl(childOp,
- projectionOutline, projectionChildren, projectionTransform);
+ child->computeOrderingImpl(childOp, projectionChildren, projectionTransform);
}
}
+#endif
}
class DeferOperationHandler {
@@ -640,17 +781,18 @@ void RenderNode::replay(ReplayStateStruct& replayStruct, const int level) {
issueOperations<ReplayOperationHandler>(replayStruct.mRenderer, handler);
}
-void RenderNode::buildZSortedChildList(const DisplayListData::Chunk& chunk,
- Vector<ZDrawRenderNodeOpPair>& zTranslatedNodes) {
+void RenderNode::buildZSortedChildList(const DisplayList::Chunk& chunk,
+ std::vector<ZDrawRenderNodeOpPair>& zTranslatedNodes) {
+#if !HWUI_NEW_OPS
if (chunk.beginChildIndex == chunk.endChildIndex) return;
for (unsigned int i = chunk.beginChildIndex; i < chunk.endChildIndex; i++) {
- DrawRenderNodeOp* childOp = mDisplayListData->children()[i];
- RenderNode* child = childOp->mRenderNode;
+ DrawRenderNodeOp* childOp = mDisplayList->getChildren()[i];
+ RenderNode* child = childOp->renderNode;
float childZ = child->properties().getZ();
if (!MathUtils::isZero(childZ) && chunk.reorderChildren) {
- zTranslatedNodes.add(ZDrawRenderNodeOpPair(childZ, childOp));
+ zTranslatedNodes.push_back(ZDrawRenderNodeOpPair(childZ, childOp));
childOp->mSkipInOrderDraw = true;
} else if (!child->properties().getProjectBackwards()) {
// regular, in order drawing DisplayList
@@ -660,6 +802,7 @@ void RenderNode::buildZSortedChildList(const DisplayListData::Chunk& chunk,
// Z sort any 3d children (stable-ness makes z compare fall back to standard drawing order)
std::stable_sort(zTranslatedNodes.begin(), zTranslatedNodes.end());
+#endif
}
template <class T>
@@ -695,7 +838,7 @@ void RenderNode::issueDrawShadowOperation(const Matrix4& transformFromParent, T&
if (revealClipPath) {
frameAllocatedPath = handler.allocPathForFrame();
- Op(*outlinePath, *revealClipPath, kIntersect_PathOp, frameAllocatedPath);
+ Op(*outlinePath, *revealClipPath, kIntersect_SkPathOp, frameAllocatedPath);
outlinePath = frameAllocatedPath;
}
@@ -711,7 +854,7 @@ void RenderNode::issueDrawShadowOperation(const Matrix4& transformFromParent, T&
clipBoundsPath.addRect(clipBounds.left, clipBounds.top,
clipBounds.right, clipBounds.bottom);
- Op(*outlinePath, clipBoundsPath, kIntersect_PathOp, frameAllocatedPath);
+ Op(*outlinePath, clipBoundsPath, kIntersect_SkPathOp, frameAllocatedPath);
outlinePath = frameAllocatedPath;
}
@@ -724,12 +867,12 @@ void RenderNode::issueDrawShadowOperation(const Matrix4& transformFromParent, T&
template <class T>
void RenderNode::issueOperationsOf3dChildren(ChildrenSelectMode mode,
- const Matrix4& initialTransform, const Vector<ZDrawRenderNodeOpPair>& zTranslatedNodes,
+ const Matrix4& initialTransform, const std::vector<ZDrawRenderNodeOpPair>& zTranslatedNodes,
OpenGLRenderer& renderer, T& handler) {
const int size = zTranslatedNodes.size();
if (size == 0
- || (mode == kNegativeZChildren && zTranslatedNodes[0].key > 0.0f)
- || (mode == kPositiveZChildren && zTranslatedNodes[size - 1].key < 0.0f)) {
+ || (mode == ChildrenSelectMode::NegativeZChildren && zTranslatedNodes[0].key > 0.0f)
+ || (mode == ChildrenSelectMode::PositiveZChildren && zTranslatedNodes[size - 1].key < 0.0f)) {
// no 3d children to draw
return;
}
@@ -737,7 +880,7 @@ void RenderNode::issueOperationsOf3dChildren(ChildrenSelectMode mode,
// Apply the base transform of the parent of the 3d children. This isolates
// 3d children of the current chunk from transformations made in previous chunks.
int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag);
- renderer.setMatrix(initialTransform);
+ renderer.setGlobalMatrix(initialTransform);
/**
* Draw shadows and (potential) casters mostly in order, but allow the shadows of casters
@@ -748,7 +891,7 @@ void RenderNode::issueOperationsOf3dChildren(ChildrenSelectMode mode,
*/
const size_t nonNegativeIndex = findNonNegativeIndex(zTranslatedNodes);
size_t drawIndex, shadowIndex, endIndex;
- if (mode == kNegativeZChildren) {
+ if (mode == ChildrenSelectMode::NegativeZChildren) {
drawIndex = 0;
endIndex = nonNegativeIndex;
shadowIndex = endIndex; // draw no shadows
@@ -765,7 +908,7 @@ void RenderNode::issueOperationsOf3dChildren(ChildrenSelectMode mode,
while (shadowIndex < endIndex || drawIndex < endIndex) {
if (shadowIndex < endIndex) {
DrawRenderNodeOp* casterOp = zTranslatedNodes[shadowIndex].value;
- RenderNode* caster = casterOp->mRenderNode;
+ RenderNode* caster = casterOp->renderNode;
const float casterZ = zTranslatedNodes[shadowIndex].key;
// attempt to render the shadow if the caster about to be drawn is its caster,
// OR if its caster's Z value is similar to the previous potential caster
@@ -808,12 +951,17 @@ void RenderNode::issueOperationsOfProjectedChildren(OpenGLRenderer& renderer, T&
// Transform renderer to match background we're projecting onto
// (by offsetting canvas by translationX/Y of background rendernode, since only those are set)
const DisplayListOp* op =
- (mDisplayListData->displayListOps[mDisplayListData->projectionReceiveIndex]);
+#if HWUI_NEW_OPS
+ nullptr;
+ LOG_ALWAYS_FATAL("unsupported");
+#else
+ (mDisplayList->getOps()[mDisplayList->projectionReceiveIndex]);
+#endif
const DrawRenderNodeOp* backgroundOp = reinterpret_cast<const DrawRenderNodeOp*>(op);
- const RenderProperties& backgroundProps = backgroundOp->mRenderNode->properties();
+ const RenderProperties& backgroundProps = backgroundOp->renderNode->properties();
renderer.translate(backgroundProps.getTranslationX(), backgroundProps.getTranslationY());
- // If the projection reciever has an outline, we mask projected content to it
+ // If the projection receiver has an outline, we mask projected content to it
// (which we know, apriori, are all tessellated paths)
renderer.setProjectionPathMask(alloc, projectionReceiverOutline);
@@ -845,13 +993,17 @@ void RenderNode::issueOperationsOfProjectedChildren(OpenGLRenderer& renderer, T&
*/
template <class T>
void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) {
- if (mDisplayListData->isEmpty()) {
+ if (mDisplayList->isEmpty()) {
DISPLAY_LIST_LOGD("%*sEmpty display list (%p, %s)", handler.level() * 2, "",
this, getName());
return;
}
+#if HWUI_NEW_OPS
+ const bool drawLayer = false;
+#else
const bool drawLayer = (mLayer && (&renderer != mLayer->renderer.get()));
+#endif
// If we are updating the contents of mLayer, we don't want to apply any of
// the RenderNode's properties to this issueOperations pass. Those will all
// be applied when the layer is drawn, aka when this is true.
@@ -889,6 +1041,9 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) {
setViewProperties<T>(renderer, handler);
}
+#if HWUI_NEW_OPS
+ LOG_ALWAYS_FATAL("legacy op traversal not supported");
+#else
bool quickRejected = properties().getClipToBounds()
&& renderer.quickRejectConservative(0, 0, properties().getWidth(), properties().getHeight());
if (!quickRejected) {
@@ -896,39 +1051,39 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) {
renderer.setBaseTransform(initialTransform);
if (drawLayer) {
- handler(new (alloc) DrawLayerOp(mLayer, 0, 0),
+ handler(new (alloc) DrawLayerOp(mLayer),
renderer.getSaveCount() - 1, properties().getClipToBounds());
} else {
const int saveCountOffset = renderer.getSaveCount() - 1;
- const int projectionReceiveIndex = mDisplayListData->projectionReceiveIndex;
- for (size_t chunkIndex = 0; chunkIndex < mDisplayListData->getChunks().size(); chunkIndex++) {
- const DisplayListData::Chunk& chunk = mDisplayListData->getChunks()[chunkIndex];
+ const int projectionReceiveIndex = mDisplayList->projectionReceiveIndex;
+ for (size_t chunkIndex = 0; chunkIndex < mDisplayList->getChunks().size(); chunkIndex++) {
+ const DisplayList::Chunk& chunk = mDisplayList->getChunks()[chunkIndex];
- Vector<ZDrawRenderNodeOpPair> zTranslatedNodes;
+ std::vector<ZDrawRenderNodeOpPair> zTranslatedNodes;
buildZSortedChildList(chunk, zTranslatedNodes);
- issueOperationsOf3dChildren(kNegativeZChildren,
+ issueOperationsOf3dChildren(ChildrenSelectMode::NegativeZChildren,
initialTransform, zTranslatedNodes, renderer, handler);
-
for (size_t opIndex = chunk.beginOpIndex; opIndex < chunk.endOpIndex; opIndex++) {
- DisplayListOp *op = mDisplayListData->displayListOps[opIndex];
+ DisplayListOp *op = mDisplayList->getOps()[opIndex];
#if DEBUG_DISPLAY_LIST
op->output(handler.level() + 1);
#endif
handler(op, saveCountOffset, properties().getClipToBounds());
- if (CC_UNLIKELY(!mProjectedNodes.isEmpty() && projectionReceiveIndex >= 0 &&
+ if (CC_UNLIKELY(!mProjectedNodes.empty() && projectionReceiveIndex >= 0 &&
opIndex == static_cast<size_t>(projectionReceiveIndex))) {
issueOperationsOfProjectedChildren(renderer, handler);
}
}
- issueOperationsOf3dChildren(kPositiveZChildren,
+ issueOperationsOf3dChildren(ChildrenSelectMode::PositiveZChildren,
initialTransform, zTranslatedNodes, renderer, handler);
}
}
}
+#endif
DISPLAY_LIST_LOGD("%*sRestoreToCount %d", (handler.level() + 1) * 2, "", restoreTo);
handler(new (alloc) RestoreToCountOp(restoreTo),