2 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "gles-graphics-shader.h"
22 #include <dali/integration-api/debug.h>
23 #include "egl-graphics-controller.h"
25 namespace Dali::Graphics::GLES
27 struct ShaderImpl::Impl
29 explicit Impl(Graphics::EglGraphicsController& _controller, const Graphics::ShaderCreateInfo& _createInfo)
30 : controller(_controller)
32 createInfo.pipelineStage = _createInfo.pipelineStage;
33 createInfo.shaderlanguage = _createInfo.shaderlanguage;
34 createInfo.sourceMode = _createInfo.sourceMode;
35 createInfo.sourceSize = _createInfo.sourceSize;
37 // Make a copy of source code
38 source.resize(_createInfo.sourceSize);
39 std::copy(reinterpret_cast<const char*>(_createInfo.sourceData),
40 reinterpret_cast<const char*>(_createInfo.sourceData) + _createInfo.sourceSize,
44 createInfo.sourceData = source.data();
51 auto gl = controller.GetGL();
60 GLenum pipelineStage{0u};
61 switch(createInfo.pipelineStage)
63 case Graphics::PipelineStage::TOP_OF_PIPELINE:
67 case Graphics::PipelineStage::VERTEX_SHADER:
69 pipelineStage = GL_VERTEX_SHADER;
72 case Graphics::PipelineStage::GEOMETRY_SHADER:
76 case Graphics::PipelineStage::FRAGMENT_SHADER:
78 pipelineStage = GL_FRAGMENT_SHADER;
81 case Graphics::PipelineStage::COMPUTE_SHADER:
85 case Graphics::PipelineStage::TESSELATION_CONTROL:
89 case Graphics::PipelineStage::TESSELATION_EVALUATION:
93 case Graphics::PipelineStage::BOTTOM_OF_PIPELINE:
101 auto shader = gl->CreateShader(pipelineStage);
102 const auto src = reinterpret_cast<const char*>(createInfo.sourceData);
103 GLint size = createInfo.sourceSize;
104 gl->ShaderSource(shader, 1, const_cast<const char**>(&src), &size);
105 gl->CompileShader(shader);
108 gl->GetShaderiv(shader, GL_COMPILE_STATUS, &status);
109 if(status != GL_TRUE)
113 gl->GetShaderInfoLog(shader, 4096, &size, output);
114 DALI_LOG_ERROR("Code: %s\n", reinterpret_cast<const char*>(createInfo.sourceData));
115 DALI_LOG_ERROR("glCompileShader() failed: \n%s\n", output);
116 gl->DeleteShader(shader);
128 auto gl = controller.GetGL();
132 gl->DeleteShader(glShader);
137 EglGraphicsController& controller;
138 ShaderCreateInfo createInfo;
139 std::vector<char> source{};
142 uint32_t refCount{0u};
143 uint32_t flushCount{0u}; ///< Number of frames at refCount=0
146 ShaderImpl::ShaderImpl(const Graphics::ShaderCreateInfo& createInfo, Graphics::EglGraphicsController& controller)
148 mImpl = std::make_unique<Impl>(controller, createInfo);
151 ShaderImpl::~ShaderImpl()
153 if(!mImpl->controller.IsShuttingDown())
159 uint32_t ShaderImpl::Retain()
161 mImpl->flushCount = 0;
162 return ++mImpl->refCount;
165 uint32_t ShaderImpl::Release()
167 uint32_t remainingCount = --mImpl->refCount;
168 mImpl->flushCount = 0;
169 return remainingCount;
172 [[nodiscard]] uint32_t ShaderImpl::GetRefCount() const
174 return mImpl->refCount;
177 [[nodiscard]] uint32_t ShaderImpl::IncreaseFlushCount()
179 return ++mImpl->flushCount;
182 [[nodiscard]] uint32_t ShaderImpl::GetFlushCount() const
184 return mImpl->flushCount;
188 * @brief Compiles shader
190 * @return True on success
192 [[nodiscard]] bool ShaderImpl::Compile() const
194 return mImpl->Compile();
197 [[nodiscard]] uint32_t ShaderImpl::GetGLShader() const
199 return mImpl->glShader;
202 const ShaderCreateInfo& ShaderImpl::GetCreateInfo() const
204 return mImpl->createInfo;
207 [[nodiscard]] EglGraphicsController& ShaderImpl::GetController() const
209 return mImpl->controller;
214 if(!mShader->Release())
216 GetImplementation()->GetController().GetPipelineCache().MarkShaderCacheFlushRequired();
220 [[nodiscard]] const ShaderCreateInfo& Shader::GetCreateInfo() const
222 return GetImplementation()->GetCreateInfo();
225 void Shader::DiscardResource()
227 auto& controller = GetImplementation()->GetController();
228 if(!controller.IsShuttingDown())
230 controller.DiscardResource(this);
234 } // namespace Dali::Graphics::GLES