[Tizen] Remove VAO cache if invalidate pipeline 21/292721/2
authorEunki, Hong <eunkiki.hong@samsung.com>
Tue, 20 Dec 2022 04:50:59 +0000 (13:50 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Fri, 12 May 2023 08:11:25 +0000 (17:11 +0900)
This is a combination of 2 commits.

Cache VAO with the locations hash

Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
Remove VAO cache if invalidate pipeline

Delete VAO cache map if pipeline destroied.
So we can avoid equal ProgramImpl pointer which already destroyied program.

Change-Id: I1fa614b07c4b80e13c2ca23f275950a9672b3542
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
dali/internal/graphics/gles-impl/gles-context.cpp

index 9c5fa87..32f490d 100644 (file)
@@ -34,6 +34,7 @@
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 #include <map>
+#include <unordered_map>
 
 namespace Dali::Graphics::GLES
 {
@@ -53,30 +54,35 @@ struct Context::Impl
    * that VertexInputState has been set correctly for the pipeline.
    *
    */
-  void BindProgramVAO(GLES::ProgramImpl* program, const VertexInputState& vertexInputState)
+  void BindProgramVAO(const GLES::ProgramImpl* program, const VertexInputState& vertexInputState)
   {
+    // Calculate attributes location hash unordered.
+    std::size_t hash = 0;
+    for(const auto& attr : vertexInputState.attributes)
+    {
+      hash ^= std::hash<uint32_t>{}(attr.location);
+    }
+
     auto& gl   = *mController.GetGL();
     auto  iter = mProgramVAOMap.find(program);
     if(iter != mProgramVAOMap.end())
     {
-      if(mProgramVAOCurrentState != iter->second)
-      {
-        mProgramVAOCurrentState = iter->second;
-        gl.BindVertexArray(iter->second);
-      }
-
-      // We should re-check enable attribute usage because geometry might be changed.
-      for(const auto& attr : vertexInputState.attributes)
+      auto attributeIter = iter->second.find(hash);
+      if(attributeIter != iter->second.end())
       {
-        gl.EnableVertexAttribArray(attr.location);
+        if(mProgramVAOCurrentState != attributeIter->second)
+        {
+          mProgramVAOCurrentState = attributeIter->second;
+          gl.BindVertexArray(attributeIter->second);
+        }
+        return;
       }
-      return;
     }
 
     uint32_t vao;
     gl.GenVertexArrays(1, &vao);
     gl.BindVertexArray(vao);
-    mProgramVAOMap[program] = vao;
+    mProgramVAOMap[program][hash] = vao;
     for(const auto& attr : vertexInputState.attributes)
     {
       gl.EnableVertexAttribArray(attr.location);
@@ -212,9 +218,9 @@ struct Context::Impl
   const GLES::RenderPass*   mCurrentRenderPass{nullptr};
 
   // Each context must have own VAOs as they cannot be shared
-  std::map<GLES::ProgramImpl*, uint32_t> mProgramVAOMap;              ///< GL program-VAO map
-  uint32_t                               mProgramVAOCurrentState{0u}; ///< Currently bound VAO
-  GLStateCache                           mGlStateCache{};             ///< GL status cache
+  std::unordered_map<const GLES::ProgramImpl*, std::map<std::size_t, uint32_t>> mProgramVAOMap;              ///< GL program-VAO map
+  uint32_t                                                                      mProgramVAOCurrentState{0u}; ///< Currently bound VAO
+  GLStateCache                                                                  mGlStateCache{};             ///< GL status cache
 
   bool mGlContextCreated{false}; ///< True if the OpenGL context has been created
 
@@ -1015,6 +1021,34 @@ void Context::InvalidateCachedPipeline(GLES::Pipeline* pipeline)
   {
     mImpl->mCurrentPipeline = nullptr;
   }
+
+  // Remove cached VAO map
+  auto* gl = mImpl->mController.GetGL();
+  if(gl)
+  {
+    const auto* program = pipeline->GetCreateInfo().programState->program;
+    if(program)
+    {
+      const auto* programImpl = static_cast<const GLES::Program*>(program)->GetImplementation();
+      if(programImpl)
+      {
+        auto iter = mImpl->mProgramVAOMap.find(programImpl);
+        if(iter != mImpl->mProgramVAOMap.end())
+        {
+          for(auto& attributeHashPair : iter->second)
+          {
+            auto vao = attributeHashPair.second;
+            gl->DeleteVertexArrays(1, &vao);
+            if(mImpl->mProgramVAOCurrentState == vao)
+            {
+              mImpl->mProgramVAOCurrentState = 0u;
+            }
+          }
+          mImpl->mProgramVAOMap.erase(iter);
+        }
+      }
+    }
+  }
 }
 
 void Context::PrepareForNativeRendering()