Revert "[Tizen] Revert "Remove unused program / shader caches""
authorEunki, Hong <eunkiki.hong@samsung.com>
Wed, 25 Oct 2023 07:35:47 +0000 (16:35 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Wed, 25 Oct 2023 07:35:47 +0000 (16:35 +0900)
This reverts commit 61260ce7f5a57f1f4cd57f4ac7b665d0384fee63.

dali/internal/render/common/render-manager.cpp
dali/internal/render/renderers/shader-cache.cpp
dali/internal/render/renderers/shader-cache.h
dali/internal/render/shaders/program-controller.cpp
dali/internal/render/shaders/program-controller.h

index 8423471..a5b4953 100644 (file)
@@ -64,6 +64,8 @@ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_REN
 
 namespace
 {
+constexpr uint32_t CACHE_CLEAN_FRAME_COUNT = 600u; // 60fps * 10sec
+
 inline Graphics::Rect2D RecalculateScissorArea(const Graphics::Rect2D& scissorArea, int orientation, const Rect<int32_t>& viewportRect)
 {
   Graphics::Rect2D newScissorArea;
@@ -515,6 +517,13 @@ void RenderManager::PreRender(Integration::RenderStatus& status, bool forceClear
   // Reset pipeline cache before rendering
   mImpl->pipelineCache->PreRender();
 
+  // Let we collect reference counts during CACHE_CLEAN_FRAME_COUNT frames.
+  if(mImpl->frameCount % CACHE_CLEAN_FRAME_COUNT == 1)
+  {
+    mImpl->programController.ResetReferenceCount();
+    mImpl->shaderCache.ResetReferenceCount();
+  }
+
   mImpl->commandBufferSubmitted = false;
 }
 
@@ -1190,6 +1199,13 @@ void RenderManager::PostRender()
     count += scene->GetRenderInstructions().Count(mImpl->renderBufferIndex);
   }
 
+  // Remove unused shader and programs during CACHE_CLEAN_FRAME_COUNT frames.
+  if(mImpl->frameCount % CACHE_CLEAN_FRAME_COUNT == 0)
+  {
+    mImpl->programController.ClearUnusedCache();
+    mImpl->shaderCache.ClearUnusedCache();
+  }
+
   const bool haveInstructions = count > 0u;
 
   // If this frame was rendered due to instructions existing, we mark this so we know to clear the next frame.
index d4f5f16..90d042c 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.
@@ -34,6 +34,7 @@ Dali::Graphics::Shader& ShaderCache::GetShader(const std::vector<char>& shaderCo
   {
     if(item.shaderCode == shaderCode && item.stage == stage && item.type == type)
     {
+      ++item.refCount;
       return *item.shader.get();
     }
   }
@@ -50,6 +51,29 @@ Dali::Graphics::Shader& ShaderCache::GetShader(const std::vector<char>& shaderCo
   return *mItems.back().shader.get();
 }
 
+void ShaderCache::ResetReferenceCount()
+{
+  for(auto&& item : mItems)
+  {
+    item.refCount = 0u;
+  }
+}
+
+void ShaderCache::ClearUnusedCache()
+{
+  for(auto iter = mItems.begin(); iter != mItems.end();)
+  {
+    if(iter->refCount == 0u)
+    {
+      iter = mItems.erase(iter);
+    }
+    else
+    {
+      ++iter;
+    }
+  }
+}
+
 } // namespace Render
 } // namespace Internal
 } // namespace Dali
index 5f00aba..9ed2034 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SHADER_CACHE_H
 
 /*
- * 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.
@@ -38,6 +38,8 @@ struct ShaderCache
     Item()            = default;
     Item(const Item&) = delete;
     Item(Item&&)      = default;
+    Item& operator=(const Item&) = delete;
+    Item& operator=(Item&&) = default;
 
     Item(Graphics::UniquePtr<Dali::Graphics::Shader> shader,
          const std::vector<char>&                    shaderCode,
@@ -46,7 +48,8 @@ struct ShaderCache
     : shader(std::move(shader)),
       shaderCode(shaderCode),
       stage(stage),
-      type(type)
+      type(type),
+      refCount{1u}
     {
     }
 
@@ -56,6 +59,7 @@ struct ShaderCache
     std::vector<char>                           shaderCode;
     Graphics::PipelineStage                     stage;
     Graphics::ShaderSourceMode                  type;
+    uint16_t                                    refCount;
   };
 
   /**
@@ -67,6 +71,7 @@ struct ShaderCache
 
   /**
    * Get a shader from it's source code
+   * It will increate getted shader item reference count.
    *
    * @param[in] shaderCode The shader code
    * @param[in] stage The pipeline stage (e.g. VERTEX_SHADER or FRAGMENT_SHADER etc.)
@@ -75,6 +80,16 @@ struct ShaderCache
    */
   Dali::Graphics::Shader& GetShader(const std::vector<char>& shaderCode, Graphics::PipelineStage stage, Graphics::ShaderSourceMode type);
 
+  /**
+   * @brief Reset all items reference count as 0.
+   */
+  void ResetReferenceCount();
+
+  /**
+   * @brief Clear items who the reference count is 0.
+   */
+  void ClearUnusedCache();
+
 private:
   std::vector<Item>           mItems;
   Dali::Graphics::Controller& mController;
index f72f937..b15715e 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.
@@ -45,6 +45,29 @@ void ProgramController::ResetProgramMatrices()
   }
 }
 
+void ProgramController::ResetReferenceCount()
+{
+  for(auto&& item : mProgramCache)
+  {
+    item->ClearReferenceCount();
+  }
+}
+
+void ProgramController::ClearUnusedCache()
+{
+  for(auto iter = mProgramCache.Begin(); iter != mProgramCache.End();)
+  {
+    if((*iter)->GetReferenceCount() == 0u)
+    {
+      iter = mProgramCache.Erase(iter);
+    }
+    else
+    {
+      ++iter;
+    }
+  }
+}
+
 Program* ProgramController::GetProgram(size_t shaderHash)
 {
   Program*              program = nullptr;
@@ -54,6 +77,7 @@ Program* ProgramController::GetProgram(size_t shaderHash)
     size_t hash = (*iter)->GetHash();
     if(shaderHash == hash)
     {
+      (*iter)->Reference();
       program = (*iter)->GetProgram();
       break;
     }
index 0ea1a7a..062a96f 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_PROGRAM_CONTROLLER_H
 
 /*
- * 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.
@@ -50,7 +50,8 @@ public:
      */
     ProgramPair(Program* program, size_t shaderHash)
     : mProgram(program),
-      mShaderHash(shaderHash)
+      mShaderHash(shaderHash),
+      mRefCount{1u}
     {
     }
 
@@ -80,12 +81,28 @@ public:
       return mShaderHash;
     }
 
+    [[nodiscard]] inline uint16_t GetReferenceCount() const
+    {
+      return mRefCount;
+    }
+
+    void Reference()
+    {
+      ++mRefCount;
+    }
+
+    void ClearReferenceCount()
+    {
+      mRefCount = 0u;
+    }
+
     ProgramPair(const ProgramPair&) = delete;
     ProgramPair& operator=(const ProgramPair&) = delete;
 
   private: // Data
     Program* mProgram;
     size_t   mShaderHash;
+    uint16_t mRefCount;
   };
 
   /**
@@ -108,6 +125,16 @@ public: // API
    */
   void ResetProgramMatrices();
 
+  /**
+   * @brief Reset all program reference count as 0.
+   */
+  void ResetReferenceCount();
+
+  /**
+   * @brief Clear program who the reference count is 0.
+   */
+  void ClearUnusedCache();
+
 private: // From ProgramCache
   /**
    * @copydoc ProgramCache::GetProgram