for(const auto& uniform : mActiveUniforms)
{
- std::string name = uniform.name;
- if(uniform.size <= 1)
- {
- GetUniformLocation(program, name.c_str());
- }
- else
- {
- // Convert single active uniform from "uBlah[0]" or "uStruct[0].element" to N versions of the same
- std::string suffix;
- auto iter = name.find("["); // Search for index operator
- if(iter != std::string::npos)
- {
- name = uniform.name.substr(0, iter); // Strip off index operator
- iter = uniform.name.find("]");
- if(iter != std::string::npos && iter + 1 != uniform.name.length())
- {
- suffix = uniform.name.substr(iter + 1);
- }
- }
- for(int i = 0; i < uniform.size; ++i)
- {
- std::stringstream nss;
- nss << name << "[" << i << "]" << suffix;
- GetUniformLocation(program, nss.str().c_str()); // Generate N uniforms in the uniform map
- }
- }
+ GetUniformLocation(program, uniform.name.c_str());
}
for(const auto& uniform : mCustomUniformData)
${internal_src_dir}/render/renderers/render-sampler.cpp
${internal_src_dir}/render/renderers/render-texture.cpp
${internal_src_dir}/render/renderers/render-vertex-buffer.cpp
+ ${internal_src_dir}/render/renderers/shader-cache.cpp
${internal_src_dir}/render/renderers/uniform-buffer.cpp
${internal_src_dir}/render/renderers/uniform-buffer-manager.cpp
${internal_src_dir}/render/renderers/uniform-buffer-view.cpp
#include <dali/internal/render/renderers/pipeline-cache.h>
#include <dali/internal/render/renderers/render-frame-buffer.h>
#include <dali/internal/render/renderers/render-texture.h>
+#include <dali/internal/render/renderers/shader-cache.h>
#include <dali/internal/render/renderers/uniform-buffer-manager.h>
#include <dali/internal/render/renderers/uniform-buffer.h>
#include <dali/internal/render/shaders/program-controller.h>
: graphicsController(graphicsController),
renderAlgorithms(graphicsController),
programController(graphicsController),
+ shaderCache(graphicsController),
depthBufferAvailable(depthBufferAvailableParam),
stencilBufferAvailable(stencilBufferAvailableParam),
partialUpdateAvailable(partialUpdateAvailableParam)
OwnerKeyContainer<Render::Texture> textureDiscardQueue; ///< Discarded textures
- ProgramController programController; ///< Owner of the programs
+ ProgramController programController; ///< Owner of the programs
+ Render::ShaderCache shaderCache; ///< The cache for the graphics shaders
std::unique_ptr<Render::UniformBufferManager> uniformBufferManager; ///< The uniform buffer manager
std::unique_ptr<Render::PipelineCache> pipelineCache;
void RenderManager::AddRenderer(const Render::RendererKey& renderer)
{
// Initialize the renderer as we are now in render thread
- renderer->Initialize(mImpl->graphicsController, mImpl->programController, *(mImpl->uniformBufferManager.get()), *(mImpl->pipelineCache.get()));
+ renderer->Initialize(mImpl->graphicsController, mImpl->programController, mImpl->shaderCache, *(mImpl->uniformBufferManager.get()), *(mImpl->pipelineCache.get()));
mImpl->rendererContainer.PushBack(renderer);
}
if(mImpl->frameCount % CACHE_CLEAN_FRAME_COUNT == 1)
{
mImpl->programController.ResetReferenceCount();
+ mImpl->shaderCache.ResetReferenceCount();
}
*/
if(mImpl->frameCount % CACHE_CLEAN_FRAME_COUNT == 0)
{
mImpl->programController.ClearUnusedCache();
+ mImpl->shaderCache.ClearUnusedCache();
}
*/
#include <dali/internal/render/renderers/render-sampler.h>
#include <dali/internal/render/renderers/render-texture.h>
#include <dali/internal/render/renderers/render-vertex-buffer.h>
+#include <dali/internal/render/renderers/shader-cache.h>
#include <dali/internal/render/renderers/uniform-buffer-view.h>
#include <dali/internal/render/renderers/uniform-buffer.h>
#include <dali/internal/render/shaders/program.h>
mBlendingOptions.SetBlendColor(blendColor);
}
-void Renderer::Initialize(Graphics::Controller& graphicsController, ProgramCache& programCache, Render::UniformBufferManager& uniformBufferManager, Render::PipelineCache& pipelineCache)
+void Renderer::Initialize(Graphics::Controller& graphicsController, ProgramCache& programCache, Render::ShaderCache& shaderCache, Render::UniformBufferManager& uniformBufferManager, Render::PipelineCache& pipelineCache)
{
mGraphicsController = &graphicsController;
mProgramCache = &programCache;
+ mShaderCache = &shaderCache;
mUniformBufferManager = &uniformBufferManager;
mPipelineCache = &pipelineCache;
}
// If program doesn't have Gfx program object assigned yet, prepare it.
if(!program->GetGraphicsProgramPtr())
{
- Graphics::ShaderCreateInfo vertexShaderCreateInfo;
- vertexShaderCreateInfo.SetPipelineStage(Graphics::PipelineStage::VERTEX_SHADER);
- vertexShaderCreateInfo.SetSourceMode(shaderData->GetSourceMode());
- const std::vector<char>& vertexShaderSrc = shaderData->GetShaderForPipelineStage(Graphics::PipelineStage::VERTEX_SHADER);
- vertexShaderCreateInfo.SetSourceSize(vertexShaderSrc.size());
- vertexShaderCreateInfo.SetSourceData(static_cast<const void*>(vertexShaderSrc.data()));
- auto vertexShader = mGraphicsController->CreateShader(vertexShaderCreateInfo, nullptr);
-
- Graphics::ShaderCreateInfo fragmentShaderCreateInfo;
- fragmentShaderCreateInfo.SetPipelineStage(Graphics::PipelineStage::FRAGMENT_SHADER);
- fragmentShaderCreateInfo.SetSourceMode(shaderData->GetSourceMode());
- const std::vector<char>& fragmentShaderSrc = shaderData->GetShaderForPipelineStage(Graphics::PipelineStage::FRAGMENT_SHADER);
- fragmentShaderCreateInfo.SetSourceSize(fragmentShaderSrc.size());
- fragmentShaderCreateInfo.SetSourceData(static_cast<const void*>(fragmentShaderSrc.data()));
- auto fragmentShader = mGraphicsController->CreateShader(fragmentShaderCreateInfo, nullptr);
+ 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.get())
+ .SetShader(vertexShader)
.SetPipelineStage(Graphics::PipelineStage::VERTEX_SHADER),
Graphics::ShaderState()
- .SetShader(*fragmentShader.get())
+ .SetShader(fragmentShader)
.SetPipelineStage(Graphics::PipelineStage::FRAGMENT_SHADER)};
auto createInfo = Graphics::ProgramCreateInfo();
namespace Render
{
+struct ShaderCache;
class PipelineCache;
struct PipelineCacheL2;
class UniformBufferManager;
* This is called when the renderer is inside render thread
* @param[in] graphicsController The graphics controller to use
* @param[in] programCache Cache of program objects
+ * @param[in] shaderCache Cache of shaders
* @param[in] uniformBufferManager Uniform buffer manager
* @param[in] pipelineCache Cache of pipelines
*/
void Initialize(Graphics::Controller& graphicsController,
ProgramCache& programCache,
+ Render::ShaderCache& shaderCache,
Render::UniformBufferManager& uniformBufferManager,
Render::PipelineCache& pipelineCache);
Render::Geometry* mGeometry;
- ProgramCache* mProgramCache{nullptr};
+ ProgramCache* mProgramCache{nullptr};
+ Render::ShaderCache* mShaderCache{nullptr};
Render::UniformBufferManager* mUniformBufferManager{};
std::vector<Graphics::UniformBufferBinding> mUniformBufferBindings{};
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dali/graphics-api/graphics-controller.h>
+#include <dali/internal/render/renderers/shader-cache.h>
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Render
+{
+ShaderCache::ShaderCache(Dali::Graphics::Controller& controller)
+: mController(controller)
+{
+}
+
+Dali::Graphics::Shader& ShaderCache::GetShader(const std::vector<char>& shaderCode, Graphics::PipelineStage stage, Graphics::ShaderSourceMode type)
+{
+ for(auto&& item : mItems)
+ {
+ if(item.shaderCode == shaderCode && item.stage == stage && item.type == type)
+ {
+ ++item.refCount;
+ return *item.shader.get();
+ }
+ }
+
+ Graphics::ShaderCreateInfo shaderCreateInfo;
+ shaderCreateInfo.SetPipelineStage(stage);
+ shaderCreateInfo.SetSourceData(static_cast<const void*>(shaderCode.data()));
+ shaderCreateInfo.SetSourceSize(shaderCode.size());
+ shaderCreateInfo.SetSourceMode(type);
+
+ Graphics::UniquePtr<Graphics::Shader> shader = mController.CreateShader(shaderCreateInfo, nullptr);
+
+ mItems.emplace_back(std::move(shader), shaderCode, stage, type);
+ 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
--- /dev/null
+#ifndef DALI_INTERNAL_SHADER_CACHE_H
+#define DALI_INTERNAL_SHADER_CACHE_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dali/graphics-api/graphics-controller.h>
+#include <dali/graphics-api/graphics-shader-create-info.h>
+#include <dali/graphics-api/graphics-shader.h>
+#include <memory>
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Render
+{
+/**
+ * Caches graphics shaders as they are created by SceneGraph::Shader.
+ */
+struct ShaderCache
+{
+ struct Item
+ {
+ 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,
+ Graphics::PipelineStage stage,
+ Graphics::ShaderSourceMode type)
+ : shader(std::move(shader)),
+ shaderCode(shaderCode),
+ stage(stage),
+ type(type),
+ refCount{1u}
+ {
+ }
+
+ ~Item() = default;
+
+ Graphics::UniquePtr<Dali::Graphics::Shader> shader{nullptr};
+ std::vector<char> shaderCode;
+ Graphics::PipelineStage stage;
+ Graphics::ShaderSourceMode type;
+ uint16_t refCount;
+ };
+
+ /**
+ * Constructor
+ *
+ * @param[in] controller The graphics controller
+ */
+ explicit ShaderCache(Dali::Graphics::Controller& controller);
+
+ /**
+ * 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.)
+ * @param[in] type The type of the shader (i.e. text or binary)
+ * @return the graphics shader
+ */
+ 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;
+};
+
+} // namespace Render
+} // namespace Internal
+} // namespace Dali
+
+#endif //DALI_INTERNAL_SHADER_CACHE_H