partial rendering 10/240310/9
authorJoogab Yun <joogab.yun@samsung.com>
Wed, 5 Aug 2020 07:42:24 +0000 (16:42 +0900)
committerJoogab Yun <joogab.yun@samsung.com>
Fri, 25 Sep 2020 07:35:37 +0000 (16:35 +0900)
1. Modify dirtyRects to have scene for multi window support.
  - Looking at a single dirtyRect in multiple windows causes problems.

2. Add Scissor for partial rendering

Change-Id: Iec8455c2b948d4344ab805d4426e2a17a447af99

dali/internal/event/common/scene-impl.cpp [changed mode: 0644->0755]
dali/internal/event/common/scene-impl.h [changed mode: 0644->0755]
dali/internal/render/common/render-algorithms.cpp [changed mode: 0644->0755]
dali/internal/render/common/render-manager.cpp [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index 7f85aa1..496fba4
@@ -375,6 +375,11 @@ Integration::Scene::WheelEventSignalType& Scene::WheelEventSignal()
   return mWheelEventSignal;
 }
 
+std::vector<Dali::Internal::SceneGraph::DirtyRect>& Scene::GetItemsDirtyRects()
+{
+  return mItemsDirtyRects;
+}
+
 } // Internal
 
 } // Dali
old mode 100644 (file)
new mode 100755 (executable)
index 96b8a8f..67d08d5
@@ -44,6 +44,54 @@ namespace Internal
 namespace SceneGraph
 {
 class Scene;
+
+struct DirtyRect
+{
+  DirtyRect(Node* node, Render::Renderer* renderer, int frame, Rect<int>& rect)
+  : node(node),
+    renderer(renderer),
+    frame(frame),
+    rect(rect),
+    visited(true)
+  {
+  }
+
+  DirtyRect()
+  : node(nullptr),
+    renderer(nullptr),
+    frame(0),
+    rect(),
+    visited(true)
+  {
+  }
+
+  bool operator<(const DirtyRect& rhs) const
+  {
+    if (node == rhs.node)
+    {
+      if (renderer == rhs.renderer)
+      {
+        return frame > rhs.frame; // Most recent rects come first
+      }
+      else
+      {
+        return renderer < rhs.renderer;
+      }
+    }
+    else
+    {
+      return node < rhs.node;
+    }
+  }
+
+  Node* node;
+  Render::Renderer* renderer;
+  int frame;
+
+  Rect<int> rect;
+  bool visited;
+};
+
 }
 
 class EventProcessor;
@@ -260,6 +308,13 @@ public:
    */
   Integration::Scene::WheelEventSignalType& WheelEventSignal();
 
+  /**
+   * @brief Get ItemsDirtyRects
+   *
+   * @return the ItemsDirtyRects
+   */
+  std::vector<Dali::Internal::SceneGraph::DirtyRect>& GetItemsDirtyRects();
+
 public:
 
   /**
@@ -327,6 +382,8 @@ private:
 
   // The wheel event signal
   Integration::Scene::WheelEventSignalType mWheelEventSignal;
+
+  std::vector<Dali::Internal::SceneGraph::DirtyRect>                    mItemsDirtyRects;
 };
 
 } // Internal
old mode 100644 (file)
new mode 100755 (executable)
index 744ae86..f5d540c
@@ -418,6 +418,7 @@ inline void RenderAlgorithms::ProcessRenderList( const RenderList& renderList,
   if (!rootClippingRect.IsEmpty())
   {
     context.SetScissorTest( true );
+    context.Scissor( rootClippingRect.x, rootClippingRect.y, rootClippingRect.width, rootClippingRect.height );
     mScissorStack.push_back( rootClippingRect );
   }
   // We are not performing a layer clip and no clipping rect set. Add the viewport as the root scissor rectangle.
old mode 100644 (file)
new mode 100755 (executable)
index d3db8f3..e885c33
@@ -48,53 +48,6 @@ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_REN
 } // unnamed namespace
 #endif
 
-struct DirtyRect
-{
-  DirtyRect(Node* node, Render::Renderer* renderer, int frame, Rect<int>& rect)
-  : node(node),
-    renderer(renderer),
-    frame(frame),
-    rect(rect),
-    visited(true)
-  {
-  }
-
-  DirtyRect()
-  : node(nullptr),
-    renderer(nullptr),
-    frame(0),
-    rect(),
-    visited(true)
-  {
-  }
-
-  bool operator<(const DirtyRect& rhs) const
-  {
-    if (node == rhs.node)
-    {
-      if (renderer == rhs.renderer)
-      {
-        return frame > rhs.frame; // Most recent rects come first
-      }
-      else
-      {
-        return renderer < rhs.renderer;
-      }
-    }
-    else
-    {
-      return node < rhs.node;
-    }
-  }
-
-  Node* node;
-  Render::Renderer* renderer;
-  int frame;
-
-  Rect<int> rect;
-  bool visited;
-};
-
 /**
  * Structure to contain internal data
  */
@@ -124,8 +77,7 @@ struct RenderManager::Impl
     programController( glAbstraction ),
     depthBufferAvailable( depthBufferAvailableParam ),
     stencilBufferAvailable( stencilBufferAvailableParam ),
-    partialUpdateAvailable( partialUpdateAvailableParam ),
-    itemsCheckSum(0)
+    partialUpdateAvailable( partialUpdateAvailableParam )
   {
      // Create thread pool with just one thread ( there may be a need to create more threads in the future ).
     threadPool = std::unique_ptr<Dali::ThreadPool>( new Dali::ThreadPool() );
@@ -222,8 +174,6 @@ struct RenderManager::Impl
   std::unique_ptr<Dali::ThreadPool>         threadPool;               ///< The thread pool
   Vector<GLuint>                            boundTextures;            ///< The textures bound for rendering
   Vector<GLuint>                            textureDependencyList;    ///< The dependency list of binded textures
-  std::size_t                               itemsCheckSum;            ///< The damaged render items checksum from previous prerender phase.
-  std::vector<DirtyRect>                    itemsDirtyRects;
 };
 
 RenderManager* RenderManager::New( Integration::GlAbstraction& glAbstraction,
@@ -648,15 +598,19 @@ void RenderManager::PreRender( Integration::Scene& scene, std::vector<Rect<int>>
   // Clean collected dirty/damaged rects on exit if 3d layer or 3d node or other conditions.
   DamagedRectsCleaner damagedRectCleaner(damagedRects);
 
+
+
+  Internal::Scene& sceneInternal = GetImplementation(scene);
+  SceneGraph::Scene* sceneObject = sceneInternal.GetSceneObject();
+
   // Mark previous dirty rects in the sorted array. The array is already sorted by node and renderer, frame number.
-  // so you don't need to sort: std::stable_sort(mImpl->itemsDirtyRects.begin(), mImpl->itemsDirtyRects.end());
-  for (DirtyRect& dirtyRect : mImpl->itemsDirtyRects)
+  // so you don't need to sort: std::stable_sort(itemsDirtyRects.begin(), itemsDirtyRects.end());
+  std::vector<DirtyRect>& itemsDirtyRects = sceneInternal.GetItemsDirtyRects();
+  for (DirtyRect& dirtyRect : itemsDirtyRects)
   {
     dirtyRect.visited = false;
   }
 
-  Internal::Scene& sceneInternal = GetImplementation(scene);
-  SceneGraph::Scene* sceneObject = sceneInternal.GetSceneObject();
   uint32_t count = sceneObject->GetRenderInstructions().Count( mImpl->renderBufferIndex );
   for (uint32_t i = 0; i < count; ++i)
   {
@@ -759,11 +713,11 @@ void RenderManager::PreRender( Integration::Scene& scene, std::vector<Rect<int>>
                 // 2. Mark the related dirty rects as visited so they will not be removed below.
                 // 3. Keep only last 3 dirty rects for the same node and renderer (Tizen uses 3 back buffers, Ubuntu 1).
                 dirtyRect.rect = rect;
-                auto dirtyRectPos = std::lower_bound(mImpl->itemsDirtyRects.begin(), mImpl->itemsDirtyRects.end(), dirtyRect);
-                dirtyRectPos = mImpl->itemsDirtyRects.insert(dirtyRectPos, dirtyRect);
+                auto dirtyRectPos = std::lower_bound(itemsDirtyRects.begin(), itemsDirtyRects.end(), dirtyRect);
+                dirtyRectPos = itemsDirtyRects.insert(dirtyRectPos, dirtyRect);
 
                 int c = 1;
-                while (++dirtyRectPos != mImpl->itemsDirtyRects.end())
+                while (++dirtyRectPos != itemsDirtyRects.end())
                 {
                   if (dirtyRectPos->node != item.mNode || dirtyRectPos->renderer != item.mRenderer)
                   {
@@ -777,7 +731,7 @@ void RenderManager::PreRender( Integration::Scene& scene, std::vector<Rect<int>>
                   c++;
                   if (c > 3) // no more then 3 previous rects
                   {
-                    mImpl->itemsDirtyRects.erase(dirtyRectPos);
+                    itemsDirtyRects.erase(dirtyRectPos);
                     break;
                   }
                 }
@@ -789,8 +743,8 @@ void RenderManager::PreRender( Integration::Scene& scene, std::vector<Rect<int>>
             {
               // 1. The item is not dirty, the node and renderer referenced by the item are still exist.
               // 2. Mark the related dirty rects as visited so they will not be removed below.
-              auto dirtyRectPos = std::lower_bound(mImpl->itemsDirtyRects.begin(), mImpl->itemsDirtyRects.end(), dirtyRect);
-              while (dirtyRectPos != mImpl->itemsDirtyRects.end())
+              auto dirtyRectPos = std::lower_bound(itemsDirtyRects.begin(), itemsDirtyRects.end(), dirtyRect);
+              while (dirtyRectPos != itemsDirtyRects.end())
               {
                 if (dirtyRectPos->node != item.mNode || dirtyRectPos->renderer != item.mRenderer)
                 {
@@ -808,9 +762,9 @@ void RenderManager::PreRender( Integration::Scene& scene, std::vector<Rect<int>>
   }
 
   // Check removed nodes or removed renderers dirty rects
-  auto i = mImpl->itemsDirtyRects.begin();
-  auto j = mImpl->itemsDirtyRects.begin();
-  while (i != mImpl->itemsDirtyRects.end())
+  auto i = itemsDirtyRects.begin();
+  auto j = itemsDirtyRects.begin();
+  while (i != itemsDirtyRects.end())
   {
     if (i->visited)
     {
@@ -824,7 +778,7 @@ void RenderManager::PreRender( Integration::Scene& scene, std::vector<Rect<int>>
     i++;
   }
 
-  mImpl->itemsDirtyRects.resize(j - mImpl->itemsDirtyRects.begin());
+  itemsDirtyRects.resize(j - itemsDirtyRects.begin());
   damagedRectCleaner.SetCleanOnReturn(false);
 }