1 #ifndef DALI_INTERNAL_SHADER_DATA_H
2 #define DALI_INTERNAL_SHADER_DATA_H
5 * Copyright (c) 2024 Samsung Electronics Co., Ltd.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
23 #include <string_view>
26 #include <dali/graphics-api/graphics-types.h>
27 #include <dali/public-api/common/dali-vector.h>
28 #include <dali/public-api/object/ref-object.h>
29 #include <dali/public-api/rendering/shader.h> // ShaderHints
36 using ShaderDataPtr = IntrusivePtr<ShaderData>;
40 template<typename StdStringType>
41 inline std::vector<char> StringToVector(const StdStringType& str)
43 auto retval = std::vector<char>{};
44 retval.insert(retval.begin(), str.begin(), str.end());
45 retval.push_back('\0');
53 * A container for shader source code and compiled binary byte code.
55 class ShaderData : public Dali::RefObject
60 * @param[in] vertexSource Source code for vertex program
61 * @param[in] fragmentSource Source code for fragment program
62 * @param[in] hints Hints for rendering
63 * @param[in] renderPassTag RenderPassTag to match shader data and render task.
64 * @param[in] name Shader name for debug.
66 ShaderData(std::string vertexSource, std::string fragmentSource, const Dali::Shader::Hint::Value hints, uint32_t renderPassTag, std::string_view name)
68 mVertexShader(StringToVector(vertexSource)),
69 mFragmentShader(StringToVector(fragmentSource)),
71 mSourceMode(Graphics::ShaderSourceMode::TEXT),
72 mRenderPassTag(renderPassTag),
75 UpdateShaderVersion(mVertexShader, mVertexShaderVersion);
76 UpdateShaderVersion(mFragmentShader, mFragmentShaderVersion);
81 * @param[in] vertexSource Source code for vertex program
82 * @param[in] fragmentSource Source code for fragment program
83 * @param[in] hints Hints for rendering
84 * @param[in] renderPassTag RenderPassTag to match shader data and render task.
85 * @param[in] name Shader name for debug.
87 ShaderData(std::string_view vertexSource, std::string_view fragmentSource, const Dali::Shader::Hint::Value hints, uint32_t renderPassTag, std::string_view name)
89 mVertexShader(StringToVector(vertexSource)),
90 mFragmentShader(StringToVector(fragmentSource)),
92 mSourceMode(Graphics::ShaderSourceMode::TEXT),
93 mRenderPassTag(renderPassTag),
96 UpdateShaderVersion(mVertexShader, mVertexShaderVersion);
97 UpdateShaderVersion(mFragmentShader, mFragmentShaderVersion);
101 * Creates a shader data containing binary content
102 * @param[in] vertexSource Source code for vertex program
103 * @param[in] fragmentSource Source code for fragment program
104 * @param[in] hints Hints for rendering
105 * @param[in] renderPassTag RenderPassTag to match shader data and render task.
106 * @param[in] name Shader name for debug.
108 ShaderData(std::vector<char>& vertexSource, std::vector<char>& fragmentSource, const Dali::Shader::Hint::Value hints, uint32_t renderPassTag, std::string_view name)
110 mVertexShader(vertexSource),
111 mFragmentShader(fragmentSource),
113 mSourceMode(Graphics::ShaderSourceMode::BINARY),
114 mRenderPassTag(renderPassTag),
117 UpdateShaderVersion(mVertexShader, mVertexShaderVersion);
118 UpdateShaderVersion(mFragmentShader, mFragmentShaderVersion);
122 * Query whether a shader hint is set.
124 * @warning This method is called from Update Algorithms.
126 * @pre The shader has been initialized.
127 * @param[in] hint The hint to check.
128 * @return True if the given hint is set.
130 [[nodiscard]] bool HintEnabled(Dali::Shader::Hint::Value hint) const
132 return mHints & hint;
137 * Protected Destructor
138 * A reference counted object may only be deleted by calling Unreference()
140 ~ShaderData() override
142 // vector releases its data
147 * Set hash value which is created with vertex and fragment shader code
148 * @param [in] shaderHash hash key created with vertex and fragment shader code
150 void SetHashValue(size_t shaderHash)
152 DALI_ASSERT_DEBUG(shaderHash != size_t(-1));
153 mShaderHash = shaderHash;
157 * Get hash value which is created with vertex and fragment shader code
158 * @return shaderHash hash key created with vertex and fragment shader code
160 size_t GetHashValue() const
162 DALI_ASSERT_DEBUG(mShaderHash != size_t(-1));
167 * @return the vertex shader
169 const char* GetVertexShader() const
171 return &mVertexShader[0];
175 * @return the vertex shader
177 const char* GetFragmentShader() const
179 return &mFragmentShader[0];
183 * Returns a std::vector containing the shader code associated with particular pipeline stage
184 * @param[in] the graphics pipeline stage
185 * @return the shader code
187 const std::vector<char>& GetShaderForPipelineStage(Graphics::PipelineStage stage) const
189 if(stage == Graphics::PipelineStage::VERTEX_SHADER)
191 return mVertexShader;
193 else if(stage == Graphics::PipelineStage::FRAGMENT_SHADER)
195 return mFragmentShader;
199 // DALI_LOG_ERROR("Unsupported shader stage\n");
200 static const std::vector<char> emptyShader;
208 Dali::Shader::Hint::Value GetHints() const
213 * Check whether there is a compiled binary available
214 * @return true if this objects contains a compiled binary
216 bool HasBinary() const
218 return 0 != mBuffer.Size();
222 * Allocate a buffer for the compiled binary bytecode
223 * @param[in] size The size of the buffer in bytes
225 void AllocateBuffer(std::size_t size)
227 mBuffer.Resize(size);
231 * Get the program buffer
232 * @return reference to the buffer
234 std::size_t GetBufferSize() const
236 return mBuffer.Size();
240 * Get the data that the buffer points to
241 * @return raw pointer to the buffer data
243 uint8_t* GetBufferData()
245 DALI_ASSERT_DEBUG(mBuffer.Size() > 0);
250 * Get the data that the buffer points to
251 * @return raw pointer to the buffer data
253 Dali::Vector<uint8_t>& GetBuffer()
259 * Get the source mode of shader data
260 * @return the source mode of shader data ( text or binary )
262 Graphics::ShaderSourceMode GetSourceMode() const
268 * Get Render Pass of shader data
269 * @return RenderPassTag for Render Pass of this shader data, Default value is 0.
271 uint32_t GetRenderPassTag() const
273 return mRenderPassTag;
277 * Get Name of shader data
278 * @return Name for this shader data, Default value is empty string.
280 const std::string& GetName() const
286 * Returns DALi specific vertex shader version
287 * @return valid version number
289 uint32_t GetVertexShaderVersion() const
291 return mVertexShaderVersion;
295 * Returns DALi specific fragment shader version
296 * @return valid version number
298 uint32_t GetFragmentShaderVersion() const
300 return mFragmentShaderVersion;
303 private: // Not implemented
304 ShaderData(const ShaderData& other); ///< no copying of this object
305 ShaderData& operator=(const ShaderData& rhs); ///< no copying of this object
309 * Updates shader version.
311 void UpdateShaderVersion(std::vector<char>& code, uint32_t& outVersion)
313 // The version may be updated only for GLSL language.
314 // If we support direct SPIRV this will be skipped
315 std::string_view strView = code.data();
317 // find first occurence of 'version' tag
318 // the tag is expected at the start of line
319 static const std::string VERSION_TAG = "//@version";
321 auto pos = strView.find(VERSION_TAG);
322 if(pos != std::string_view::npos && (pos == 0 || strView[pos - 1] == '\n'))
326 outVersion = std::strtoul(strView.data() + pos + VERSION_TAG.length(), &end, 10);
335 std::size_t mShaderHash; ///< hash key created with vertex and fragment shader code
336 std::vector<char> mVertexShader; ///< source code for vertex program
337 std::vector<char> mFragmentShader; ///< source code for fragment program
338 Dali::Shader::Hint::Value mHints; ///< take a hint
339 Dali::Vector<uint8_t> mBuffer; ///< buffer containing compiled binary bytecode
340 Graphics::ShaderSourceMode mSourceMode; ///< Source mode of shader data ( text or binary )
341 uint32_t mRenderPassTag{0u}; ///< Render Pass Tag for this shader
342 std::string mName{""}; ///< Name for this shader
343 uint32_t mVertexShaderVersion; ///< Vertex shader version
344 uint32_t mFragmentShaderVersion; ///< Fragment shader version
347 } // namespace Internal
351 #endif // DALI_INTERNAL_SHADER_DATA_H