Optimized program retrieval from the cache 39/260339/5
authorAdam Bialogonski <adam.b@samsung.com>
Fri, 25 Jun 2021 14:25:48 +0000 (15:25 +0100)
committerAdam Bialogonski <adam.b@samsung.com>
Fri, 25 Jun 2021 14:28:53 +0000 (15:28 +0100)
Change-Id: I6dda5244b32a2cc5c21285673d7a125cd36caaee

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

index 4a2a786..6d0f0b7 100644 (file)
@@ -432,41 +432,45 @@ bool Renderer::Render(Graphics::CommandBuffer&                             comma
 
   // Create Program
   ShaderDataPtr            shaderData   = mRenderDataProvider->GetShader().GetShaderData();
-  const std::vector<char>& vertShader   = shaderData->GetShaderForPipelineStage(Graphics::PipelineStage::VERTEX_SHADER);
-  const std::vector<char>& fragShader   = shaderData->GetShaderForPipelineStage(Graphics::PipelineStage::FRAGMENT_SHADER);
-  Dali::Graphics::Shader&  vertexShader = mShaderCache->GetShader(
-    vertShader,
-    Graphics::PipelineStage::VERTEX_SHADER,
-    shaderData->GetSourceMode());
-
-  Dali::Graphics::Shader& fragmentShader = mShaderCache->GetShader(
-    fragShader,
-    Graphics::PipelineStage::FRAGMENT_SHADER,
-    shaderData->GetSourceMode());
-
-  std::vector<Graphics::ShaderState> shaderStates{
-    Graphics::ShaderState()
-      .SetShader(vertexShader)
-      .SetPipelineStage(Graphics::PipelineStage::VERTEX_SHADER),
-    Graphics::ShaderState()
-      .SetShader(fragmentShader)
-      .SetPipelineStage(Graphics::PipelineStage::FRAGMENT_SHADER)};
-
-  auto createInfo = Graphics::ProgramCreateInfo();
-  createInfo.SetShaderState(shaderStates);
-
-  auto     graphicsProgram = mGraphicsController->CreateProgram(createInfo, nullptr);
+
   Program* program         = Program::New(*mProgramCache,
                                   shaderData,
-                                  *mGraphicsController,
-                                  std::move(graphicsProgram));
-
+                                  *mGraphicsController);
   if(!program)
   {
     DALI_LOG_ERROR("Failed to get program for shader at address %p.\n", reinterpret_cast<void*>(&mRenderDataProvider->GetShader()));
     return false;
   }
 
+  // If program doesn't have Gfx program object assigned yet, prepare it.
+  if(!program->GetGraphicsProgramPtr())
+  {
+    const std::vector<char> &vertShader   = shaderData->GetShaderForPipelineStage(Graphics::PipelineStage::VERTEX_SHADER);
+    const std::vector<char> &fragShader   = shaderData->GetShaderForPipelineStage(Graphics::PipelineStage::FRAGMENT_SHADER);
+    Dali::Graphics::Shader  &vertexShader = mShaderCache->GetShader(
+      vertShader,
+      Graphics::PipelineStage::VERTEX_SHADER,
+      shaderData->GetSourceMode());
+
+    Dali::Graphics::Shader &fragmentShader = mShaderCache->GetShader(
+      fragShader,
+      Graphics::PipelineStage::FRAGMENT_SHADER,
+      shaderData->GetSourceMode());
+
+    std::vector<Graphics::ShaderState> shaderStates{
+      Graphics::ShaderState()
+        .SetShader(vertexShader)
+        .SetPipelineStage(Graphics::PipelineStage::VERTEX_SHADER),
+      Graphics::ShaderState()
+        .SetShader(fragmentShader)
+        .SetPipelineStage(Graphics::PipelineStage::FRAGMENT_SHADER)};
+
+    auto createInfo = Graphics::ProgramCreateInfo();
+    createInfo.SetShaderState(shaderStates);
+    auto graphicsProgram = mGraphicsController->CreateProgram(createInfo, nullptr);
+    program->SetGraphicsProgram(std::move(graphicsProgram));
+  }
+
   // Prepare the graphics pipeline. This may either re-use an existing pipeline or create a new one.
   auto& pipeline = PrepareGraphicsPipeline(*program, instruction, node, blend);
 
index 3a3c8e6..56ba362 100644 (file)
@@ -72,37 +72,30 @@ inline uint32_t GetUniformBufferDataAlignment(uint32_t dataSize)
 
 // IMPLEMENTATION
 
-Program* Program::New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController, Graphics::UniquePtr<Graphics::Program>&& gfxProgram)
+Program* Program::New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController)
 {
-  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);
-
-  size_t shaderHash = programId;
+  size_t shaderHash = shaderData->GetHashValue();
 
   Program* program = cache.GetProgram(shaderHash);
 
   if(nullptr == program)
   {
     // program not found so create it
-    program = new Program(cache, shaderData, gfxController, std::move(gfxProgram));
+    program = new Program(cache, shaderData, gfxController);
     cache.AddProgram(shaderHash, program);
   }
 
   return program;
 }
 
-Program::Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& controller, Graphics::UniquePtr<Graphics::Program>&& gfxProgram)
+Program::Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& controller)
 : mCache(cache),
   mProjectionMatrix(nullptr),
   mViewMatrix(nullptr),
-  mGfxProgram(std::move(gfxProgram)),
+  mGfxProgram(nullptr),
   mGfxController(controller),
   mProgramData(shaderData)
 {
-  BuildReflection(controller.GetProgramReflection(*mGfxProgram.get()));
 }
 
 Program::~Program() = default;
@@ -183,6 +176,13 @@ void Program::BuildReflection(const Graphics::Reflection& graphicsReflection)
   }
 }
 
+void Program::SetGraphicsProgram( Graphics::UniquePtr<Graphics::Program>&& program )
+{
+  mGfxProgram = std::move(program);
+  BuildReflection(mGfxController.GetProgramReflection(*mGfxProgram.get()));
+}
+
+
 bool Program::GetUniform(const std::string& name, size_t hashedName, Graphics::UniformInfo& out) const
 {
   if(mReflection.empty())
index 05a6e70..d6cde0f 100644 (file)
@@ -74,10 +74,9 @@ public:
    *                        and optionally precompiled binary. If the binary is empty the program bytecode
    *                        is copied into it after compilation and linking)
    * @param[in]  gfxController Reference to valid graphics Controller object
-   * @param[in]  gfxProgram Reference to valid graphics Program object
    * @return pointer to the program
    */
 static Program* New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController, Graphics::UniquePtr<Graphics::Program>&& gfxProgram);
static Program* New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController);
 
   /**
    * Set the projection matrix that has currently been sent
@@ -120,6 +119,13 @@ public:
     return *mGfxProgram;
   }
 
+  [[nodiscard]] Graphics::Program* GetGraphicsProgramPtr() const
+  {
+    return mGfxProgram.get();
+  }
+
+  void SetGraphicsProgram( Graphics::UniquePtr<Graphics::Program>&& program );
+
   /**
    * Retrieves uniform data.
    * The lookup tries to minimise string comparisons. Ideally, when the hashedName is known
@@ -145,10 +151,9 @@ 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] gfxProgram Graphics Program object
    * @param[in] gfxController Reference to Graphics Controller object
    */
-  Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController, Graphics::UniquePtr<Graphics::Program>&& gfxProgram);
+  Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController);
 
 public:
   Program()               = delete;            ///< default constructor, not defined