summaryrefslogtreecommitdiffstats
path: root/libs/hwui/RenderNode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/RenderNode.cpp')
-rw-r--r--libs/hwui/RenderNode.cpp96
1 files changed, 51 insertions, 45 deletions
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 663b67e..823ae7b 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -49,7 +49,12 @@ void RenderNode::outputLogBuffer(int fd) {
fflush(file);
}
-RenderNode::RenderNode() : mDestroyed(false), mNeedsPropertiesSync(false), mDisplayListData(0) {
+RenderNode::RenderNode()
+ : mDestroyed(false)
+ , mNeedsPropertiesSync(false)
+ , mNeedsDisplayListDataSync(false)
+ , mDisplayListData(0)
+ , mStagingDisplayListData(0) {
}
RenderNode::~RenderNode() {
@@ -57,24 +62,15 @@ RenderNode::~RenderNode() {
mDestroyed = true;
delete mDisplayListData;
+ delete mStagingDisplayListData;
}
-void RenderNode::destroyDisplayListDeferred(RenderNode* displayList) {
- if (displayList) {
- if (Caches::hasInstance()) {
- DISPLAY_LIST_LOGD("Deferring display list destruction");
- Caches::getInstance().deleteDisplayListDeferred(displayList);
- } else {
- delete displayList;
- }
- }
-}
-
-void RenderNode::setData(DisplayListData* data) {
- delete mDisplayListData;
- mDisplayListData = data;
- if (mDisplayListData) {
- Caches::getInstance().registerFunctors(mDisplayListData->functorCount);
+void RenderNode::setStagingDisplayList(DisplayListData* data) {
+ mNeedsDisplayListDataSync = true;
+ delete mStagingDisplayListData;
+ mStagingDisplayListData = data;
+ if (mStagingDisplayListData) {
+ Caches::getInstance().registerFunctors(mStagingDisplayListData->functorCount);
}
}
@@ -97,35 +93,45 @@ void RenderNode::output(uint32_t level) {
ALOGD("%*sDone (%p, %s)", (level - 1) * 2, "", this, mName.string());
}
-void RenderNode::updateProperties() {
+void RenderNode::prepareTree(TreeInfo& info) {
+ ATRACE_CALL();
+
+ prepareTreeImpl(info);
+}
+
+void RenderNode::prepareTreeImpl(TreeInfo& info) {
+ pushStagingChanges(info);
+ prepareSubTree(info, mDisplayListData);
+}
+
+void RenderNode::pushStagingChanges(TreeInfo& info) {
if (mNeedsPropertiesSync) {
mNeedsPropertiesSync = false;
mProperties = mStagingProperties;
}
-
- if (mDisplayListData) {
- for (size_t i = 0; i < mDisplayListData->children.size(); i++) {
- RenderNode* childNode = mDisplayListData->children[i]->mDisplayList;
- childNode->updateProperties();
- }
+ if (mNeedsDisplayListDataSync) {
+ mNeedsDisplayListDataSync = false;
+ // Do a push pass on the old tree to handle freeing DisplayListData
+ // that are no longer used
+ TreeInfo oldTreeInfo = {0};
+ prepareSubTree(oldTreeInfo, mDisplayListData);
+ // TODO: The damage for the old tree should be accounted for
+ delete mDisplayListData;
+ mDisplayListData = mStagingDisplayListData;
+ mStagingDisplayListData = 0;
}
}
-bool RenderNode::hasFunctors() {
- if (!mDisplayListData) return false;
-
- if (mDisplayListData->functorCount) {
- return true;
- }
-
- for (size_t i = 0; i < mDisplayListData->children.size(); i++) {
- RenderNode* childNode = mDisplayListData->children[i]->mDisplayList;
- if (childNode->hasFunctors()) {
- return true;
+void RenderNode::prepareSubTree(TreeInfo& info, DisplayListData* subtree) {
+ if (subtree) {
+ if (!info.hasFunctors) {
+ info.hasFunctors = subtree->functorCount;
+ }
+ for (size_t i = 0; i < subtree->children().size(); i++) {
+ RenderNode* childNode = subtree->children()[i]->mDisplayList;
+ childNode->prepareTreeImpl(info);
}
}
-
- return false;
}
/*
@@ -248,8 +254,8 @@ void RenderNode::computeOrdering() {
// TODO: create temporary DDLOp and call computeOrderingImpl on top DisplayList so that
// transform properties are applied correctly to top level children
if (mDisplayListData == NULL) return;
- for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) {
- DrawDisplayListOp* childOp = mDisplayListData->children[i];
+ for (unsigned int i = 0; i < mDisplayListData->children().size(); i++) {
+ DrawDisplayListOp* childOp = mDisplayListData->children()[i];
childOp->mDisplayList->computeOrderingImpl(childOp,
&mProjectedNodes, &mat4::identity());
}
@@ -277,11 +283,11 @@ void RenderNode::computeOrderingImpl(
opState->mSkipInOrderDraw = false;
}
- if (mDisplayListData->children.size() > 0) {
+ if (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];
+ for (unsigned int i = 0; i < mDisplayListData->children().size(); i++) {
+ DrawDisplayListOp* childOp = mDisplayListData->children()[i];
RenderNode* child = childOp->mDisplayList;
Vector<DrawDisplayListOp*>* projectionChildren = NULL;
@@ -375,10 +381,10 @@ void RenderNode::replayNodeInParent(ReplayStateStruct& replayStruct, const int l
}
void RenderNode::buildZSortedChildList(Vector<ZDrawDisplayListOpPair>& zTranslatedNodes) {
- if (mDisplayListData == NULL || mDisplayListData->children.size() == 0) return;
+ if (mDisplayListData == NULL || mDisplayListData->children().size() == 0) return;
- for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) {
- DrawDisplayListOp* childOp = mDisplayListData->children[i];
+ for (unsigned int i = 0; i < mDisplayListData->children().size(); i++) {
+ DrawDisplayListOp* childOp = mDisplayListData->children()[i];
RenderNode* child = childOp->mDisplayList;
float childZ = child->properties().getTranslationZ();