Bugfix: Gfx program discarded while DALi ProgramCache still holds to the GL resource 63/254363/2
authorAdam Bialogonski <adam.b@samsung.com>
Mon, 1 Mar 2021 14:06:05 +0000 (14:06 +0000)
committerAdam Bialogonski <adam.b@samsung.com>
Mon, 1 Mar 2021 14:07:51 +0000 (14:07 +0000)
Fix:
DALi Program takes now ownership over Gfx Program and keep's it alive as long as necessary.

Change-Id: If8563d5474510d460c712188702e0ab64541a311

dali/internal/render/renderers/render-renderer.cpp
dali/internal/render/renderers/render-renderer.h
dali/internal/render/shaders/program.cpp
dali/internal/render/shaders/program.h

index cac206d..e6c6df2 100644 (file)
@@ -761,11 +761,11 @@ void Renderer::Render(Context&                                             conte
   auto createInfo = Graphics::ProgramCreateInfo();
   createInfo.SetShaderState(shaderStates);
 
-  mGraphicsProgram = mGraphicsController->CreateProgram(createInfo, std::move(mGraphicsProgram));
+  auto graphicsProgram = mGraphicsController->CreateProgram(createInfo, nullptr);
   Program* program = Program::New(*mProgramCache,
                                   shaderData,
                                   *mGraphicsController,
-                                  *mGraphicsProgram,
+                                  std::move(graphicsProgram),
                                   (shaderData->GetHints() & Dali::Shader::Hint::MODIFIES_GEOMETRY) != 0x0);
 
   if(!program)
@@ -911,7 +911,7 @@ Graphics::UniquePtr<Graphics::Pipeline> Renderer::PrepareGraphicsPipeline(
     mUpdateAttributeLocations = true;
   }
 
-  auto& reflection = mGraphicsController->GetProgramReflection(*mGraphicsProgram.get());
+  auto& reflection = mGraphicsController->GetProgramReflection(program.GetGraphicsProgram());
 
   /**
    * Bind Attributes
@@ -954,7 +954,7 @@ Graphics::UniquePtr<Graphics::Pipeline> Renderer::PrepareGraphicsPipeline(
   inputAssemblyState.SetTopology(mGeometry->GetTopology());
 
   // Get the program
-  programState.SetProgram(*mGraphicsProgram.get());
+  programState.SetProgram(program.GetGraphicsProgram());
 
   Graphics::RasterizationState rasterizationState{};
 
index a629e11..51fa74f 100644 (file)
@@ -466,7 +466,6 @@ private:
   ProgramCache*        mProgramCache{};
   Render::ShaderCache* mShaderCache{};
 
-  Graphics::UniquePtr<Graphics::Program>  mGraphicsProgram{};  ///< The graphics program. (Cached implementation)
   Graphics::UniquePtr<Graphics::Pipeline> mGraphicsPipeline{}; ///< The graphics pipeline. (Cached implementation)
   std::vector<Graphics::ShaderState>      mShaderStates{};
 
index 725974c..6d42581 100644 (file)
@@ -100,13 +100,13 @@ const char* const gStdUniforms[Program::UNIFORM_TYPE_LAST] =
 
 // IMPLEMENTATION
 
-Program* Program::New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController, Graphics::Program& gfxProgram, bool modifiesGeometry)
+Program* Program::New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController, Graphics::UniquePtr<Graphics::Program>&& gfxProgram, bool modifiesGeometry)
 {
   uint32_t programId{0u};
 
   // Get program id and use it as hash for the cache
   // in order to maintain current functionality as long as needed
-  gfxController.GetProgramParameter( gfxProgram, 1, &programId );
+  gfxController.GetProgramParameter( *gfxProgram, 1, &programId );
 
   size_t   shaderHash = programId;
 
@@ -115,7 +115,7 @@ Program* Program::New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, G
   if(nullptr == program)
   {
     // program not found so create it
-    program = new Program(cache, shaderData, programId, modifiesGeometry);
+    program = new Program(cache, shaderData, gfxController, std::move(gfxProgram), modifiesGeometry);
     program->Load();
     cache.AddProgram(shaderHash, program);
   }
@@ -632,7 +632,7 @@ bool Program::ModifiesGeometry()
   return mModifiesGeometry;
 }
 
-Program::Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, uint32_t programId, bool modifiesGeometry)
+Program::Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& controller, Graphics::UniquePtr<Graphics::Program>&& gfxProgram, bool modifiesGeometry)
 : mCache(cache),
   mGlAbstraction(mCache.GetGlAbstraction()),
   mProjectionMatrix(nullptr),
@@ -641,6 +641,8 @@ Program::Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, uint32
   mVertexShaderId(0),
   mFragmentShaderId(0),
   mProgramId(0),
+  mGfxProgram( std::move(gfxProgram)),
+  mGfxController( controller ),
   mProgramData(shaderData),
   mModifiesGeometry(modifiesGeometry)
 {
@@ -662,7 +664,9 @@ Program::Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, uint32
   // reset values
   ResetAttribsUniformCache();
 
-  mProgramId = programId;
+  // Get program id and use it as hash for the cache
+  // in order to maintain current functionality as long as needed
+  mGfxController.GetProgramParameter( *mGfxProgram, 1, &mProgramId );
   mLinked = true;
 }
 
index 9a801d8..d1047b5 100644 (file)
@@ -112,7 +112,7 @@ public:
    * @param[in] modifiesGeometry True if the shader modifies geometry
    * @return pointer to the program
    */
-  static Program* New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController, Graphics::Program& gfxProgram, bool modifiesGeometry);
+  static Program* New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController, Graphics::UniquePtr<Graphics::Program>&& gfxProgram, bool modifiesGeometry);
 
   /**
    * Takes this program into use
@@ -313,15 +313,21 @@ public:
     return mProgramId;
   }
 
+  [[nodiscard]] Graphics::Program& GetGraphicsProgram() const
+  {
+    return *mGfxProgram;
+  }
+
 private: // Implementation
   /**
    * Constructor, private so no direct instantiation
    * @param[in] cache where the programs are stored
    * @param[in] shaderData A smart pointer to a data structure containing the program source and binary
-   * @param[in] programId A GL program id
+   * @param[in] gfxProgram Graphics Program object
+   * @param[in] gfxController Reference to Graphics Controller object
    * @param[in] modifiesGeometry True if the vertex shader changes geometry
    */
-  Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, uint32_t programId, bool modifiesGeometry);
+  Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController, Graphics::UniquePtr<Graphics::Program>&& gfxProgram, bool modifiesGeometry);
 
 public:
   /**
@@ -377,6 +383,8 @@ private:                                         // Data
   GLuint                      mVertexShaderId;   ///< GL identifier for vertex shader
   GLuint                      mFragmentShaderId; ///< GL identifier for fragment shader
   GLuint                      mProgramId;        ///< GL identifier for program
+  Graphics::UniquePtr<Graphics::Program> mGfxProgram; ///< Gfx program
+  Graphics::Controller&       mGfxController;    /// < Gfx controller
   Internal::ShaderDataPtr     mProgramData;      ///< Shader program source and binary (when compiled & linked or loaded)
 
   // location caches