// 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);
// 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;
}
}
+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())
* 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
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
* 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