Reduce some useless if check during prepare render instructions 62/300862/4
authorEunki, Hong <eunkiki.hong@samsung.com>
Fri, 3 Nov 2023 02:52:44 +0000 (11:52 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Fri, 3 Nov 2023 03:55:31 +0000 (12:55 +0900)
- Reduce overhead when we get ShaderData
- Do not check RenderingBehaviour multiple times.
- Remove some useless IntrusivePtr copy operation (Reference / Unreference)

Change-Id: I2215f7bacff6571c2508848ebda1ea67d52b8c98
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
dali/internal/event/rendering/shader-impl.cpp
dali/internal/render/renderers/render-renderer.cpp
dali/internal/render/shaders/program.cpp
dali/internal/render/shaders/program.h
dali/internal/render/shaders/render-shader.cpp
dali/internal/render/shaders/render-shader.h
dali/internal/update/manager/render-instruction-processor.cpp
dali/internal/update/manager/render-task-processor.cpp
dali/internal/update/rendering/scene-graph-renderer.cpp

index 57b8b59..e1f9005 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -90,8 +90,8 @@ Property::Value HintString(const Dali::Shader::Hint::Value& hints)
 
 void GetShaderData(const Property::Map& shaderMap, std::string& vertexShader, std::string& fragmentShader, uint32_t& renderPassTag, Dali::Shader::Hint::Value& hints)
 {
-  hints      = Dali::Shader::Hint::NONE;
-  renderPassTag = 0u;
+  hints         = Dali::Shader::Hint::NONE;
+  renderPassTag = DEFAULT_RENDER_PASS_TAG;
 
   if(Property::Value* value = shaderMap.Find("vertex"))
   {
@@ -194,11 +194,11 @@ Property::Value Shader::GetDefaultProperty(Property::Index index) const
       if(mShaderDataList.size() == 1u)
       {
         Dali::Property::Map map;
-        map["vertex"]     = Property::Value(mShaderDataList.front()->GetVertexShader());
-        map["fragment"]   = Property::Value(mShaderDataList.front()->GetFragmentShader());
+        map["vertex"]        = Property::Value(mShaderDataList.front()->GetVertexShader());
+        map["fragment"]      = Property::Value(mShaderDataList.front()->GetFragmentShader());
         map["renderPassTag"] = Property::Value(static_cast<int32_t>(mShaderDataList.front()->GetRenderPassTag()));
-        map["hints"]      = HintString(mShaderDataList.front()->GetHints());
-        value             = map;
+        map["hints"]         = HintString(mShaderDataList.front()->GetHints());
+        value                = map;
       }
       else
       {
@@ -208,10 +208,10 @@ Property::Value Shader::GetDefaultProperty(Property::Index index) const
           if(shaderData)
           {
             Dali::Property::Map map;
-            map["vertex"]     = Property::Value(shaderData->GetVertexShader());
-            map["fragment"]   = Property::Value(shaderData->GetFragmentShader());
+            map["vertex"]        = Property::Value(shaderData->GetVertexShader());
+            map["fragment"]      = Property::Value(shaderData->GetFragmentShader());
             map["renderPassTag"] = Property::Value(static_cast<int32_t>(shaderData->GetRenderPassTag()));
-            map["hints"]      = HintString(shaderData->GetHints());
+            map["hints"]         = HintString(shaderData->GetHints());
             array.PushBack(map);
           }
         }
@@ -245,8 +245,7 @@ void Shader::UpdateShaderData(std::string_view          vertexSource,
   size_t                  shaderHash;
   Internal::ShaderDataPtr shaderData = shaderFactory.Load(vertexSource, fragmentSource, hints, renderPassTag, shaderHash);
 
-  std::vector<Internal::ShaderDataPtr>::iterator shaderDataIterator = std::find_if(mShaderDataList.begin(), mShaderDataList.end(), [&shaderData](const Internal::ShaderDataPtr& shaderDataItem)
-                                                                                   { return shaderDataItem->GetRenderPassTag() == shaderData->GetRenderPassTag(); });
+  std::vector<Internal::ShaderDataPtr>::iterator shaderDataIterator = std::find_if(mShaderDataList.begin(), mShaderDataList.end(), [&shaderData](const Internal::ShaderDataPtr& shaderDataItem) { return shaderDataItem->GetRenderPassTag() == shaderData->GetRenderPassTag(); });
   if(shaderDataIterator != mShaderDataList.end())
   {
     *shaderDataIterator = shaderData;
@@ -269,7 +268,7 @@ void Shader::SetShaderProperty(const Dali::Property::Value& shaderMap)
     {
       std::string               vertex;
       std::string               fragment;
-      uint32_t                  renderPassTag{0u};
+      uint32_t                  renderPassTag{DEFAULT_RENDER_PASS_TAG};
       Dali::Shader::Hint::Value hints(Dali::Shader::Hint::NONE);
       GetShaderData(*map, vertex, fragment, renderPassTag, hints);
 
@@ -289,7 +288,7 @@ void Shader::SetShaderProperty(const Dali::Property::Value& shaderMap)
         {
           std::string               vertex;
           std::string               fragment;
-          uint32_t                  renderPassTag{0u};
+          uint32_t                  renderPassTag{DEFAULT_RENDER_PASS_TAG};
           Dali::Shader::Hint::Value hints(Dali::Shader::Hint::NONE);
           GetShaderData(*map, vertex, fragment, renderPassTag, hints);
 
index 2762d44..8eb8120 100644 (file)
@@ -488,7 +488,7 @@ Program* Renderer::PrepareProgram(const SceneGraph::RenderInstruction& instructi
   // Create Program
   const SceneGraph::Shader& shader = mRenderDataProvider->GetShader();
 
-  ShaderDataPtr shaderData = shader.GetShaderData(instruction.mRenderPassTag);
+  const ShaderDataPtr& shaderData = shader.GetShaderData(instruction.mRenderPassTag);
   if(!shaderData)
   {
     DALI_LOG_ERROR("Failed to get shader data.\n");
@@ -696,7 +696,7 @@ std::size_t Renderer::BuildUniformIndexMap(BufferIndex bufferIndex, const SceneG
 
   // Specially, if node don't have uniformMap, we mark nodePtr as nullptr.
   // So, all nodes without uniformMap will share same UniformIndexMap, contains only render data providers.
-  const auto nodePtr = uniformMapNode.Count() ? &node : nullptr;
+  const auto nodePtr    = uniformMapNode.Count() ? &node : nullptr;
   const auto programPtr = &program;
 
   const auto nodeChangeCounter          = nodePtr ? uniformMapNode.GetChangeCounter() : 0;
index 1acafae..bdc7053 100644 (file)
@@ -74,7 +74,7 @@ inline uint32_t AlignSize(uint32_t dataSize, uint32_t alignSize)
 
 // IMPLEMENTATION
 
-Program* Program::New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController)
+Program* Program::New(ProgramCache& cache, const Internal::ShaderDataPtr& shaderData, Graphics::Controller& gfxController)
 {
   size_t shaderHash = shaderData->GetHashValue();
 
@@ -97,7 +97,7 @@ Program::Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphi
   mViewMatrix(nullptr),
   mGfxProgram(nullptr),
   mGfxController(controller),
-  mProgramData(shaderData)
+  mProgramData(std::move(shaderData))
 {
 }
 
index 5e46c39..8130f93 100644 (file)
@@ -84,7 +84,7 @@ public:
    * @param[in]  gfxController Reference to valid graphics Controller object
    * @return pointer to the program
    */
-  static Program* New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController);
+  static Program* New(ProgramCache& cache, const Internal::ShaderDataPtr& shaderData, Graphics::Controller& gfxController);
 
   /**
    * Set the projection matrix that has currently been sent
index 5e03ec1..cee4b2f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -31,7 +31,6 @@ namespace Internal
 {
 namespace SceneGraph
 {
-
 namespace
 {
 static constexpr uint32_t DEFAULT_RENDER_PASS_TAG = 0u;
@@ -43,45 +42,38 @@ Shader::~Shader()
 
 void Shader::UpdateShaderData(ShaderDataPtr shaderData)
 {
+  if(shaderData->GetRenderPassTag() == DEFAULT_RENDER_PASS_TAG)
+  {
+    mDefaultShaderData = std::move(shaderData);
+    return;
+  }
+
   DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, "%d\n", shaderData->GetHashValue());
-  std::vector<Internal::ShaderDataPtr>::iterator shaderDataIterator = std::find_if(mShaderDataList.begin(), mShaderDataList.end(), [&shaderData](const Internal::ShaderDataPtr& shaderDataItem)
-                                                                                   { return shaderDataItem->GetRenderPassTag() == shaderData->GetRenderPassTag(); });
+  std::vector<Internal::ShaderDataPtr>::iterator shaderDataIterator = std::find_if(mShaderDataList.begin(), mShaderDataList.end(), [&shaderData](const Internal::ShaderDataPtr& shaderDataItem) { return shaderDataItem->GetRenderPassTag() == shaderData->GetRenderPassTag(); });
   if(shaderDataIterator != mShaderDataList.end())
   {
-    *shaderDataIterator = shaderData;
+    *shaderDataIterator = std::move(shaderData);
   }
   else
   {
-    mShaderDataList.push_back(shaderData);
+    mShaderDataList.push_back(std::move(shaderData));
   }
 }
 
 ShaderDataPtr Shader::GetShaderData(uint32_t renderPassTag) const
 {
-  if(mShaderDataList.empty())
-  {
-    return nullptr;
-  }
-
-  Internal::ShaderDataPtr returnShaderData = nullptr;
-  for(auto && shaderData : mShaderDataList)
+  if(renderPassTag != DEFAULT_RENDER_PASS_TAG)
   {
-    if(shaderData->GetRenderPassTag() == renderPassTag)
-    {
-      return shaderData;
-    }
-    if(shaderData->GetRenderPassTag() == DEFAULT_RENDER_PASS_TAG)
+    for(auto&& shaderData : mShaderDataList)
     {
-      returnShaderData = shaderData;
+      if(shaderData->GetRenderPassTag() == renderPassTag)
+      {
+        return shaderData;
+      }
     }
   }
 
-  if(returnShaderData)
-  {
-    return returnShaderData;
-  }
-
-  return mShaderDataList.front();
+  return mDefaultShaderData;
 }
 
 } // namespace SceneGraph
index d94224e..9be08d6 100644 (file)
@@ -70,7 +70,8 @@ public:
   [[nodiscard]] ShaderDataPtr GetShaderData(uint32_t renderPassTag) const;
 
 private: // Data
-  std::vector<ShaderDataPtr> mShaderDataList;
+  ShaderDataPtr              mDefaultShaderData{nullptr};
+  std::vector<ShaderDataPtr> mShaderDataList{};
 };
 
 inline void UpdateShaderDataMessage(EventThreadServices& eventThreadServices, const Shader& shader, ShaderDataPtr shaderData)
index cb75c1b..09fa6d5 100644 (file)
@@ -209,10 +209,24 @@ inline void AddRendererToRenderList(BufferIndex               updateBufferIndex,
   Matrix  nodeModelViewMatrix(false);
   bool    nodeModelViewMatrixSet(false);
 
+  const bool rendererExist(renderable.mRenderer);
+
   // Don't cull items which have render callback
-  bool hasRenderCallback = (renderable.mRenderer && renderable.mRenderer->GetRenderCallback());
+  bool hasRenderCallback = (rendererExist && renderable.mRenderer->GetRenderCallback());
+
+  auto requiredInsideCheck = [&]() {
+    if(cull &&
+       !hasRenderCallback &&
+       node->GetClippingMode() == ClippingMode::DISABLED &&
+       rendererExist)
+    {
+      const auto& shaderData = renderable.mRenderer->GetShader().GetShaderData(renderPass);
+      return (shaderData && !shaderData->HintEnabled(Dali::Shader::Hint::MODIFIES_GEOMETRY));
+    }
+    return false;
+  };
 
-  if(cull && renderable.mRenderer && !hasRenderCallback && renderable.mRenderer->GetShader().GetShaderData(renderPass) && !renderable.mRenderer->GetShader().GetShaderData(renderPass)->HintEnabled(Dali::Shader::Hint::MODIFIES_GEOMETRY) && node->GetClippingMode() == ClippingMode::DISABLED)
+  if(requiredInsideCheck())
   {
     const Vector4& boundingSphere = node->GetBoundingSphere();
     inside                        = (boundingSphere.w > Math::MACHINE_EPSILON_1000) &&
@@ -254,7 +268,7 @@ inline void AddRendererToRenderList(BufferIndex               updateBufferIndex,
     bool isOpaque = true;
     if(!hasRenderCallback)
     {
-      Renderer::OpacityType opacityType = renderable.mRenderer ? renderable.mRenderer->GetOpacityType(updateBufferIndex, renderPass, *node) : Renderer::OPAQUE;
+      Renderer::OpacityType opacityType = rendererExist ? renderable.mRenderer->GetOpacityType(updateBufferIndex, renderPass, *node) : Renderer::OPAQUE;
 
       // We can skip render when node is not clipping and transparent
       skipRender = (opacityType == Renderer::TRANSPARENT && node->GetClippingMode() == ClippingMode::DISABLED);
@@ -271,7 +285,7 @@ inline void AddRendererToRenderList(BufferIndex               updateBufferIndex,
       item.mIsOpaque   = isOpaque;
       item.mDepthIndex = isLayer3d ? 0 : node->GetDepthIndex();
 
-      if(DALI_LIKELY(renderable.mRenderer))
+      if(DALI_LIKELY(rendererExist))
       {
         item.mRenderer   = renderable.mRenderer->GetRenderer();
         item.mTextureSet = renderable.mRenderer->GetTextureSet();
index 865e910..c1460e2 100644 (file)
@@ -92,9 +92,9 @@ Layer* FindLayer(Node& node)
  * @param[in]  clippingDepth The current stencil clipping depth
  * @param[in]  clippingDepth The current scissor clipping depth
  * @param[out] clippingUsed  Gets set to true if any clipping nodes have been found
- * @return true if rendering should be kept, false otherwise.
+ * @param[out] keepRendering Gets set to true if rendering should be kept.
  */
-bool AddRenderablesForTask(BufferIndex updateBufferIndex,
+void AddRenderablesForTask(BufferIndex updateBufferIndex,
                            Node&       node,
                            Layer&      currentLayer,
                            RenderTask& renderTask,
@@ -102,15 +102,14 @@ bool AddRenderablesForTask(BufferIndex updateBufferIndex,
                            uint32_t&   currentClippingId,
                            uint32_t    clippingDepth,
                            uint32_t    scissorDepth,
-                           bool&       clippingUsed)
+                           bool&       clippingUsed,
+                           bool&       keepRendering)
 {
-  bool keepRendering = false;
-
   // Short-circuit for invisible nodes
   if(!node.IsVisible(updateBufferIndex))
   {
     node.GetPartialRenderingData().mVisible = false;
-    return keepRendering;
+    return;
   }
 
   // If the node was not previously visible
@@ -123,7 +122,7 @@ bool AddRenderablesForTask(BufferIndex updateBufferIndex,
   // Check whether node is exclusive to a different render-task
   if(node.GetExclusiveRenderTaskCount() && !node.IsExclusiveRenderTask(&renderTask))
   {
-    return keepRendering;
+    return;
   }
 
   // Assume all children go to this layer (if this node is a layer).
@@ -185,10 +184,8 @@ bool AddRenderablesForTask(BufferIndex updateBufferIndex,
   for(NodeIter iter = children.Begin(); iter != endIter; ++iter)
   {
     Node& child = **iter;
-    keepRendering |= AddRenderablesForTask(updateBufferIndex, child, *layer, renderTask, inheritedDrawMode, currentClippingId, clippingDepth, scissorDepth, clippingUsed);
+    AddRenderablesForTask(updateBufferIndex, child, *layer, renderTask, inheritedDrawMode, currentClippingId, clippingDepth, scissorDepth, clippingUsed, keepRendering);
   }
-
-  return keepRendering;
 }
 
 /**
@@ -201,17 +198,18 @@ bool AddRenderablesForTask(BufferIndex updateBufferIndex,
  * @param[in]  sortedLayers               The layers containing lists of opaque / transparent renderables.
  * @param[out] instructions               The instructions for rendering the next frame.
  * @param[in]  renderInstructionProcessor An instance of the RenderInstructionProcessor used to sort and handle the renderers for each layer.
+ * @param[out] keepRendering              Gets set to true if rendering should be kept.
  * @param[in]  renderToFboEnabled         Whether rendering into the Frame Buffer Object is enabled (used to measure FPS above 60)
  * @param[in]  isRenderingToFbo           Whether this frame is being rendered into the Frame Buffer Object (used to measure FPS above 60)
  * @param[in]  processOffscreen           Whether the offscreen render tasks are the ones processed. Otherwise it processes the onscreen tasks.
- * @return true if rendering should be kept, false otherwise.
  */
-bool ProcessTasks(BufferIndex                          updateBufferIndex,
+void ProcessTasks(BufferIndex                          updateBufferIndex,
                   RenderTaskList::RenderTaskContainer& taskContainer,
                   Layer&                               rootNode,
                   SortedLayerPointers&                 sortedLayers,
                   RenderInstructionContainer&          instructions,
                   RenderInstructionProcessor&          renderInstructionProcessor,
+                  bool&                                keepRendering,
                   bool                                 renderToFboEnabled,
                   bool                                 isRenderingToFbo,
                   bool                                 processOffscreen)
@@ -220,7 +218,6 @@ bool ProcessTasks(BufferIndex                          updateBufferIndex,
   bool     hasClippingNodes = false;
 
   bool isFirstRenderTask = true;
-  bool keepRendering     = false;
 
   // Retrieve size of Scene and default camera position to update viewport of each RenderTask if the RenderTask uses ViewportGuideNode.
   RenderTaskList::RenderTaskContainer::Iterator iter                  = taskContainer.Begin();
@@ -281,15 +278,16 @@ bool ProcessTasks(BufferIndex                          updateBufferIndex,
         sortedLayer->ClearRenderables();
       }
 
-      keepRendering |= AddRenderablesForTask(updateBufferIndex,
-                                             *sourceNode,
-                                             *layer,
-                                             renderTask,
-                                             sourceNode->GetDrawMode(),
-                                             clippingId,
-                                             0u,
-                                             0u,
-                                             hasClippingNodes);
+      AddRenderablesForTask(updateBufferIndex,
+                            *sourceNode,
+                            *layer,
+                            renderTask,
+                            sourceNode->GetDrawMode(),
+                            clippingId,
+                            0u,
+                            0u,
+                            hasClippingNodes,
+                            keepRendering);
 
       renderInstructionProcessor.Prepare(updateBufferIndex,
                                          sortedLayers,
@@ -310,8 +308,6 @@ bool ProcessTasks(BufferIndex                          updateBufferIndex,
       }
     }
   }
-
-  return keepRendering;
 }
 
 } // Anonymous namespace.
@@ -347,30 +343,32 @@ bool RenderTaskProcessor::Process(BufferIndex                 updateBufferIndex,
 
   // First process off screen render tasks - we may need the results of these for the on screen renders
 
-  keepRendering = ProcessTasks(updateBufferIndex,
-                               taskContainer,
-                               rootNode,
-                               sortedLayers,
-                               instructions,
-                               mRenderInstructionProcessor,
-                               renderToFboEnabled,
-                               isRenderingToFbo,
-                               true);
+  ProcessTasks(updateBufferIndex,
+               taskContainer,
+               rootNode,
+               sortedLayers,
+               instructions,
+               mRenderInstructionProcessor,
+               keepRendering,
+               renderToFboEnabled,
+               isRenderingToFbo,
+               true);
 
   DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "RenderTaskProcessor::Process() Onscreen\n");
 
   // Now that the off screen renders are done we can process on screen render tasks.
   // Reset the clipping Id for the OnScreen render tasks.
 
-  keepRendering |= ProcessTasks(updateBufferIndex,
-                                taskContainer,
-                                rootNode,
-                                sortedLayers,
-                                instructions,
-                                mRenderInstructionProcessor,
-                                renderToFboEnabled,
-                                isRenderingToFbo,
-                                false);
+  ProcessTasks(updateBufferIndex,
+               taskContainer,
+               rootNode,
+               sortedLayers,
+               instructions,
+               mRenderInstructionProcessor,
+               keepRendering,
+               renderToFboEnabled,
+               isRenderingToFbo,
+               false);
 
   return keepRendering;
 }
index 7ca244e..85c269a 100644 (file)
@@ -684,10 +684,14 @@ Renderer::OpacityType Renderer::GetOpacityType(BufferIndex updateBufferIndex, ui
         break;
       }
 
-      if(mShader->GetShaderData(renderPass))
+      if(mTextureSet && mTextureSet->HasAlpha())
       {
-        bool shaderRequiresBlending(mShader->GetShaderData(renderPass)->HintEnabled(Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT));
-        if(shaderRequiresBlending || (mTextureSet && mTextureSet->HasAlpha()))
+        opacityType = Renderer::TRANSLUCENT;
+      }
+      else
+      {
+        const auto& shaderData = mShader->GetShaderData(renderPass);
+        if(shaderData && shaderData->HintEnabled(Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT))
         {
           opacityType = Renderer::TRANSLUCENT;
         }