Created PartialRenderingDataProvider to store per-frame data 24/247424/12
authoradam.b <adam.b@samsung.com>
Tue, 8 Dec 2020 14:10:51 +0000 (14:10 +0000)
committeradam.b <adam.b@samsung.com>
Fri, 18 Dec 2020 16:07:37 +0000 (16:07 +0000)
Change-Id: Ief3717a29bced6f30faa96cfe117ffa93bd9a8d0

automated-tests/src/dali/utc-Dali-Actor.cpp
dali/internal/render/data-providers/node-data-provider.h
dali/internal/update/manager/render-instruction-processor.cpp

index dc23be2..069292d 100644 (file)
@@ -7929,7 +7929,7 @@ int utcDaliActorPartialUpdate(void)
   DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
 
   // Aligned by 16
-  clippingRect = Rect<int>(16, 736, 64, 64); // in screen coordinates, includes 3 last frames updates
+  clippingRect = Rect<int>(16, 736, 48, 64); // in screen coordinates, includes 3 last frames updates
   DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
   application.RenderWithPartialUpdate(damagedRects, clippingRect);
   DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
@@ -7951,7 +7951,7 @@ int utcDaliActorPartialUpdate(void)
 
   DALI_TEST_EQUALS(clippingRect.IsEmpty(), false, TEST_LOCATION);
   DALI_TEST_EQUALS(clippingRect.IsValid(), true, TEST_LOCATION);
-  DALI_TEST_EQUALS<Rect<int>>(clippingRect, Rect<int>(16, 736, 64, 64), TEST_LOCATION);
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, Rect<int>(16, 736, 48, 64), TEST_LOCATION);
 
   application.RenderWithPartialUpdate(damagedRects, clippingRect);
   DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
@@ -8119,10 +8119,20 @@ int utcDaliActorPartialUpdateSetProperty(void)
   DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
   DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
 
+  // Should be no damage rects, nothing changed
   damagedRects.clear();
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+  // Should be 1 damage rect due to change in size
+  damagedRects.clear();
+  actor.SetProperty(Actor::Property::SIZE, Vector3(26.0f, 26.0f, 0.0f));
+  application.SendNotification();
   application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
   DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
 
+  clippingRect = Rect<int>(16, 752, 32, 48); // new clipping rect size increased due to change in actor size
   DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
   application.RenderWithPartialUpdate(damagedRects, clippingRect);
   DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
@@ -8210,7 +8220,7 @@ int utcDaliActorPartialUpdateActorsWithSizeHint(void)
 
   DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
 
-  Rect<int> clippingRect = Rect<int>(0, 496, 160, 320);
+  Rect<int> clippingRect = Rect<int>(32, 560, 96, 176);
   DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
 
   application.RenderWithPartialUpdate(damagedRects, clippingRect);
index 0f768a3..efc0cb2 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENE_GRAPH_NODE_DATA_PROVIDER_H
 
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,6 +19,8 @@
  */
 
 #include <dali/internal/render/data-providers/uniform-map-data-provider.h>
+#include <dali/public-api/math/matrix.h>
+#include <cstring>
 
 namespace Dali
 {
@@ -27,13 +29,101 @@ class Matrix;
 
 namespace Internal
 {
+
 namespace SceneGraph
 {
 
+class Node;
+class Renderer;
+class TextureSet;
+
+/**
+ * Structure to store partial rendering cache data
+ */
+struct PartialRenderingCacheInfo
+{
+  Node*             node{nullptr};        /// Node associated with the entry
+  const Renderer*   renderer{nullptr};    /// Renderer object
+  const TextureSet* textureSet{nullptr};  /// TextureSet object
+  Matrix            matrix{};             /// Model-view matrix
+  Vector4           color{};              /// Color
+  Vector3           size{};               /// Size
+  Vector3           updatedSize{};        /// Updated size
+  bool              isOpaque{};           /// Opacity state
+  uint32_t          depthIndex{0u};       /// Depth index
+};
+
+/**
+ * Structure contains partial rendering data used in order to determine
+ * whether anything has changed and node has to be updated
+ */
+struct PartialRenderingNodeData
+{
+  /**
+   * @brief Retrieves current PartialDataCacheInfo structure
+   * @return Current PartialDataCacheInfo structure
+   */
+  PartialRenderingCacheInfo& GetCurrentCacheInfo()
+  {
+    return mData[mCurrentIndex];
+  }
+
+  /**
+   * @brief Tests whether cache changed since last frame
+   * @return True if changed
+   */
+  bool IsUpdated()
+  {
+    return 0 != memcmp( &mData[0], &mData[1], sizeof(PartialRenderingCacheInfo) );
+  }
+
+  /**
+   * @brief Swaps cache buffers
+   */
+  void SwapBuffers()
+  {
+    mCurrentIndex = static_cast<uint8_t>((~mCurrentIndex) & 1);
+  }
+
+  PartialRenderingCacheInfo mData[2u]; /// Double-buffered data
+  uint8_t mCurrentIndex {0u}; /// Current buffer index
+};
+
+/**
+ * An interface to provide partial rendering data
+ */
+class PartialRenderingDataProvider
+{
+public:
+
+  /**
+   * Constructor
+   */
+  PartialRenderingDataProvider() = default;
+
+  /**
+   * Destructor
+   */
+  virtual ~PartialRenderingDataProvider() = default;
+
+  /**
+   * @brief Returns partial rendering data associated with the node.
+   * @return A valid pointer to the partial rendering data or nullptr
+   */
+  PartialRenderingNodeData& GetPartialRenderingData()
+  {
+    return mPartialRenderingData;
+  }
+
+protected:
+
+  PartialRenderingNodeData mPartialRenderingData;
+};
+
 /**
  * An interface to provide data for a Renderer
  */
-class NodeDataProvider : UniformMapDataProvider
+class NodeDataProvider : UniformMapDataProvider, public PartialRenderingDataProvider
 {
 public:
 
index 057e66e..7508c73 100644 (file)
@@ -176,31 +176,36 @@ inline void AddRendererToRenderList(BufferIndex updateBufferIndex,
       // Get the next free RenderItem.
       RenderItem& item = renderList.GetNextFreeItem();
 
-      item.mIsUpdated = (item.mNode != renderable.mNode);
-      item.mNode = renderable.mNode;
+      // Get cached values
+      auto& partialRenderingData = node->GetPartialRenderingData();
 
-      bool prevIsOpaque = item.mIsOpaque;
-      item.mIsOpaque = (opacityType == Renderer::OPAQUE);
-      item.mIsUpdated |= (prevIsOpaque != item.mIsOpaque);
+      auto& partialRenderingCacheInfo = node->GetPartialRenderingData().GetCurrentCacheInfo();
+
+      partialRenderingCacheInfo.node = node;
+      partialRenderingCacheInfo.isOpaque = (opacityType == Renderer::OPAQUE);
+      partialRenderingCacheInfo.renderer = renderable.mRenderer;
+      partialRenderingCacheInfo.color = renderable.mNode->GetColor(updateBufferIndex);
+      partialRenderingCacheInfo.depthIndex = renderable.mNode->GetDepthIndex();
+
+      if( renderable.mRenderer )
+      {
+        partialRenderingCacheInfo.textureSet = renderable.mRenderer->GetTextures();
+      }
 
-      Vector4 prevColor = item.mColor;
+      item.mNode = renderable.mNode;
+      item.mIsOpaque = (opacityType == Renderer::OPAQUE);
       item.mColor = renderable.mNode->GetColor(updateBufferIndex);
-      item.mIsUpdated |= (prevColor != item.mColor);
 
-      int prevDepthIndex = item.mDepthIndex;
       item.mDepthIndex = 0;
       if (!isLayer3d)
       {
         item.mDepthIndex = renderable.mNode->GetDepthIndex();
       }
 
-      Render::Renderer* prevRenderer = item.mRenderer;
       if (DALI_LIKELY(renderable.mRenderer))
       {
         item.mRenderer = &renderable.mRenderer->GetRenderer();
-        const void* prevTextureSet = item.mTextureSet;
         item.mTextureSet = renderable.mRenderer->GetTextures();
-        item.mIsUpdated |= (prevTextureSet != item.mTextureSet);
         item.mDepthIndex += renderable.mRenderer->GetDepthIndex();
       }
       else
@@ -208,29 +213,15 @@ inline void AddRendererToRenderList(BufferIndex updateBufferIndex,
         item.mRenderer = nullptr;
       }
 
-      item.mIsUpdated |= (prevDepthIndex != item.mDepthIndex);
-      item.mIsUpdated |= (prevRenderer != item.mRenderer);
       item.mIsUpdated |= isLayer3d;
 
-      if (!item.mIsUpdated)
-      {
-        Matrix prevModelViewMatrix = item.mModelViewMatrix;
-        Vector3 prevSize = item.mSize;
-
-        // Save ModelView matrix onto the item.
-        node->GetWorldMatrixAndSize( item.mModelMatrix, item.mSize );
-        Matrix::Multiply( item.mModelViewMatrix, item.mModelMatrix, viewMatrix );
+      // Save ModelView matrix onto the item.
+      node->GetWorldMatrixAndSize( item.mModelMatrix, item.mSize );
+      Matrix::Multiply( item.mModelViewMatrix, item.mModelMatrix, viewMatrix );
 
-        item.mIsUpdated = ((prevSize != item.mSize) || (item.mModelViewMatrix != prevModelViewMatrix));
-      }
-      else
-      {
-        // Save ModelView matrix onto the item.
-        node->GetWorldMatrixAndSize( item.mModelMatrix, item.mSize );
-        Matrix::Multiply( item.mModelViewMatrix, item.mModelMatrix, viewMatrix );
-      }
+      partialRenderingCacheInfo.matrix = item.mModelViewMatrix;
+      partialRenderingCacheInfo.size = item.mSize;
 
-      item.mUpdateSize = node->GetUpdateSizeHint();
       if (item.mUpdateSize == Vector3::ZERO)
       {
         // RenderItem::CalculateViewportSpaceAABB cannot cope with z transform
@@ -240,8 +231,11 @@ inline void AddRendererToRenderList(BufferIndex updateBufferIndex,
           item.mUpdateSize = item.mSize;
         }
       }
-    }
+      partialRenderingCacheInfo.updatedSize = item.mUpdateSize;
 
+      item.mIsUpdated = partialRenderingData.IsUpdated() || item.mIsUpdated;
+      partialRenderingData.SwapBuffers();
+    }
     node->SetCulled( updateBufferIndex, false );
   }
   else