Recalculated layer's reusability flags after transform update 97/266497/2
authorDavid Steele <david.steele@samsung.com>
Fri, 12 Nov 2021 16:20:09 +0000 (16:20 +0000)
committerRichard <r.huang@samsung.com>
Thu, 18 Nov 2021 16:11:41 +0000 (16:11 +0000)
Layer's reusability flags were being left as true causing
some examples to fail to render properly, as render items
were being reused without being updated after a transform.

Reworked UpdateNodes to move layer reusability calculation
until after TransformManager::Update.

Change-Id: Id0e30489074ae3690984e4f95f0b3cd730d80440

dali/internal/update/manager/update-algorithms.cpp
dali/internal/update/manager/update-algorithms.h
dali/internal/update/manager/update-manager.cpp
dali/internal/update/manager/update-manager.h
dali/internal/update/nodes/node-declarations.h
dali/internal/update/nodes/node.h

index 99df7d3..3ff66c4 100644 (file)
@@ -101,8 +101,6 @@ inline NodePropertyFlags UpdateNodes(Node&             node,
                                      NodePropertyFlags parentFlags,
                                      BufferIndex       updateBufferIndex,
                                      RenderQueue&      renderQueue,
-                                     Layer&            currentLayer,
-                                     uint32_t          inheritedDrawMode,
                                      bool              updated)
 {
   // Apply constraints to the node
@@ -113,35 +111,11 @@ inline NodePropertyFlags UpdateNodes(Node&             node,
 
   NodePropertyFlags cumulativeDirtyFlags = nodeDirtyFlags;
 
-  Layer* layer = &currentLayer;
-  Layer* nodeIsLayer(node.GetLayer());
-  if(nodeIsLayer)
-  {
-    // all childs go to this layer
-    layer = nodeIsLayer;
-
-    // assume layer is clean to begin with
-    layer->SetReuseRenderers(updateBufferIndex, true);
-
-    // Layers do not inherit the DrawMode from their parents
-    inheritedDrawMode = DrawMode::NORMAL;
-  }
-  DALI_ASSERT_DEBUG(NULL != layer);
-
   UpdateNodeOpacity(node, nodeDirtyFlags, updateBufferIndex);
 
-  // Draw mode inheritance is treated as or-ing the modes together (as they are a bit-mask).
-  inheritedDrawMode |= node.GetDrawMode();
-
+  // Collect uniform maps
   node.PrepareRender(updateBufferIndex);
 
-  // if any child node has moved or had its sort modifier changed, layer is not clean and old frame cannot be reused
-  // also if node has been deleted, dont reuse old render items
-  if(nodeDirtyFlags & RenderableUpdateFlags)
-  {
-    layer->SetReuseRenderers(updateBufferIndex, false);
-  }
-
   // For partial update, mark all children of an animating node as updated.
   if(updated) // Only set to updated if parent was updated.
   {
@@ -162,8 +136,6 @@ inline NodePropertyFlags UpdateNodes(Node&             node,
                                         nodeDirtyFlags,
                                         updateBufferIndex,
                                         renderQueue,
-                                        *layer,
-                                        inheritedDrawMode,
                                         updated);
   }
 
@@ -199,8 +171,6 @@ NodePropertyFlags UpdateNodeTree(Layer&       rootNode,
 
   UpdateRootNodeOpacity(rootNode, nodeDirtyFlags, updateBufferIndex);
 
-  DrawMode::Type drawMode(rootNode.GetDrawMode());
-
   bool updated = rootNode.Updated();
 
   // recurse children
@@ -213,14 +183,62 @@ NodePropertyFlags UpdateNodeTree(Layer&       rootNode,
                                         nodeDirtyFlags,
                                         updateBufferIndex,
                                         renderQueue,
-                                        rootNode,
-                                        drawMode,
                                         updated);
   }
 
   return cumulativeDirtyFlags;
 }
 
+inline void UpdateLayers(Node&             node,
+                         NodePropertyFlags parentFlags,
+                         BufferIndex       updateBufferIndex,
+                         Layer&            currentLayer)
+{
+  // Some dirty flags are inherited from parent
+  NodePropertyFlags nodeDirtyFlags = node.GetDirtyFlags() | node.GetInheritedDirtyFlags(parentFlags);
+  nodeDirtyFlags |= (node.IsLocalMatrixDirty() ? NodePropertyFlags::TRANSFORM : NodePropertyFlags::NOTHING);
+
+  Layer* nodeIsLayer(node.GetLayer());
+  Layer* layer = nodeIsLayer ? nodeIsLayer : &currentLayer;
+  if(nodeIsLayer)
+  {
+    layer->SetReuseRenderers(updateBufferIndex, true);
+  }
+  DALI_ASSERT_DEBUG(nullptr != layer);
+
+  // if any child node has moved or had its sort modifier changed, layer is not clean and old frame cannot be reused
+  // also if node has been deleted, dont reuse old render items
+  if(nodeDirtyFlags != NodePropertyFlags::NOTHING)
+  {
+    layer->SetReuseRenderers(updateBufferIndex, false);
+  }
+
+  // recurse children
+  NodeContainer& children = node.GetChildren();
+  const NodeIter endIter  = children.End();
+  for(NodeIter iter = children.Begin(); iter != endIter; ++iter)
+  {
+    Node& child = **iter;
+    UpdateLayers(child, nodeDirtyFlags, updateBufferIndex, *layer);
+  }
+}
+
+void UpdateLayerTree(Layer&      layer,
+                     BufferIndex updateBufferIndex)
+{
+  NodePropertyFlags nodeDirtyFlags = layer.GetDirtyFlags();
+  nodeDirtyFlags |= (layer.IsLocalMatrixDirty() ? NodePropertyFlags::TRANSFORM : NodePropertyFlags::NOTHING);
+
+  // recurse children
+  NodeContainer& children = layer.GetChildren();
+  const NodeIter endIter  = children.End();
+  for(NodeIter iter = children.Begin(); iter != endIter; ++iter)
+  {
+    Node& child = **iter;
+    UpdateLayers(child, nodeDirtyFlags, updateBufferIndex, layer);
+  }
+}
+
 } // namespace SceneGraph
 
 } // namespace Internal
index b9e5860..eeeb09e 100644 (file)
@@ -50,6 +50,14 @@ void ConstrainPropertyOwner(PropertyOwner& propertyOwner, BufferIndex updateBuff
 NodePropertyFlags UpdateNodeTree(Layer&       rootNode,
                                  BufferIndex  updateBufferIndex,
                                  RenderQueue& renderQueue);
+/**
+ * This updates all the sub-layer's reusability flags without affecting
+ * the root layer.
+ *
+ * @param layer The root layer
+ * @param updateBufferIndex The current buffer index
+ */
+void UpdateLayerTree(Layer& layer, BufferIndex updateBufferIndex);
 
 } // namespace SceneGraph
 
index c231eb8..c96b6ca 100644 (file)
@@ -880,6 +880,17 @@ void UpdateManager::UpdateNodes(BufferIndex bufferIndex)
   }
 }
 
+void UpdateManager::UpdateLayers(BufferIndex bufferIndex)
+{
+  for(auto&& scene : mImpl->scenes)
+  {
+    if(scene && scene->root)
+    {
+      SceneGraph::UpdateLayerTree(*scene->root, bufferIndex);
+    }
+  }
+}
+
 uint32_t UpdateManager::Update(float    elapsedSeconds,
                                uint32_t lastVSyncTimeMilliseconds,
                                uint32_t nextVSyncTimeMilliseconds,
@@ -955,8 +966,7 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
       mImpl->frameCallbackProcessor->Update(bufferIndex, elapsedSeconds);
     }
 
-    //Update node hierarchy, apply constraints and perform sorting / culling.
-    //This will populate each Layer with a list of renderers which are ready.
+    //Update node hierarchy, apply constraints,
     UpdateNodes(bufferIndex);
 
     //Apply constraints to RenderTasks, shaders
@@ -972,6 +982,9 @@ uint32_t UpdateManager::Update(float    elapsedSeconds,
       mImpl->nodeDirtyFlags |= NodePropertyFlags::TRANSFORM;
     }
 
+    //Initialise layer renderable reuse
+    UpdateLayers(bufferIndex);
+
     //Process Property Notifications
     ProcessPropertyNotifications(bufferIndex);
 
index 410d74c..23c5143 100644 (file)
@@ -731,6 +731,12 @@ private:
   void UpdateNodes(BufferIndex bufferIndex);
 
   /**
+   * initialize layer renderables
+   * @param[in] bufferIndex
+   */
+  void UpdateLayers(BufferIndex bufferIndex);
+
+  /**
    * Update Renderers
    * @param[in] bufferIndex to use
    */
index 9fea1de..1867063 100644 (file)
@@ -41,14 +41,15 @@ using NodeConstIter = NodeContainer::ConstIterator;
  * Flag whether property has changed, during the Update phase.
  */
 enum class NodePropertyFlags : uint8_t
-// 8 bits is enough for 4 flags (compiler will check it)
+// 8 bits is enough for 5 flags (compiler will check it)
 {
   NOTHING       = 0x000,
   TRANSFORM     = 0x001,
   VISIBLE       = 0x002,
   COLOR         = 0x004,
   CHILD_DELETED = 0x008,
-  ALL           = (CHILD_DELETED << 1) - 1 // all the flags
+  DEPTH_INDEX   = 0x010,
+  ALL           = (DEPTH_INDEX << 1) - 1 // all the flags
 };
 
 struct NodeDepthPair
index c34b684..a886a9b 100644 (file)
@@ -786,7 +786,11 @@ public:
    */
   void SetDepthIndex(uint32_t depthIndex)
   {
-    mDepthIndex = depthIndex;
+    if(depthIndex != mDepthIndex)
+    {
+      SetDirtyFlag(NodePropertyFlags::DEPTH_INDEX);
+      mDepthIndex = depthIndex;
+    }
   }
 
   /**