2 * Copyright (c) 2021 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 "dali-scene-loader/public-api/shader-definition.h"
20 #include "dali-scene-loader/public-api/utils.h"
21 #include <dali-scene-loader/internal/graphics/builtin-shader-extern-gen.h>
29 const std::string SHADER_HINT_OUTPUT_IS_TRANSPARENT("OUTPUT_IS_TRANSPARENT"); ///< Might generate transparent alpha from opaque inputs.
30 const std::string SHADER_HINT_MODIFIES_GEOMETRY("MODIFIES_GEOMETRY"); ///< Might change position of vertices, this option disables any culling optimizations.
34 ShaderDefinition::ShaderDefinition(const ShaderDefinition& other)
35 : mRendererState(other.mRendererState),
36 mVertexShaderPath(other.mVertexShaderPath),
37 mFragmentShaderPath(other.mFragmentShaderPath),
38 mDefines(other.mDefines),
40 mUniforms(other.mUniforms),
41 mUseBuiltInShader(other.mUseBuiltInShader)
45 void ShaderDefinition::ApplyDefine(std::string& shaderCode, const std::string& definevar)
47 const std::string IF_1 = "#if 1";
49 std::size_t found = shaderCode.find(definevar);
50 while(found != std::string::npos)
52 // Greater then "@" character means is a letter,
53 // therefore is not has the definevar we looking for.
54 if((found + definevar.length()) < shaderCode.length() && shaderCode.at(found + definevar.length()) > '@')
56 found = shaderCode.find(definevar, found + definevar.length());
59 if(found > 0u && shaderCode.at(found - 1) > '@')
61 found = shaderCode.find(definevar, found + definevar.length());
65 std::size_t defidx = shaderCode.rfind("#ifdef", found);
66 std::size_t newlineidx = shaderCode.rfind("\n", found);
67 if(newlineidx < defidx && defidx != std::string::npos)
69 shaderCode.replace(defidx, found - defidx + definevar.length(), IF_1);
70 found = defidx + IF_1.length();
74 found += definevar.length();
76 found = shaderCode.find(definevar, found);
80 ShaderDefinition::RawData
81 ShaderDefinition::LoadRaw(const std::string& shadersPath) const
86 if(!mUseBuiltInShader)
88 raw.mVertexShaderSource = LoadTextFile((shadersPath + mVertexShaderPath).c_str(), &fail);
91 raw.mFragmentShaderSource = LoadTextFile((shadersPath + mFragmentShaderPath).c_str(), &fail);
94 ExceptionFlinger(ASSERT_LOCATION) << "Failed to load shader source from '" << shadersPath + mFragmentShaderPath << "'.";
99 ExceptionFlinger(ASSERT_LOCATION) << "Failed to load shader source from '" << shadersPath + mVertexShaderPath << "'.";
104 raw.mVertexShaderSource = SHADER_DEFAULT_PHYSICALLY_BASED_SHADER_VERT.data();
105 raw.mFragmentShaderSource = SHADER_DEFAULT_PHYSICALLY_BASED_SHADER_FRAG.data();
110 for(auto definevar : mDefines)
112 ApplyDefine(raw.mVertexShaderSource, definevar);
113 ApplyDefine(raw.mFragmentShaderSource, definevar);
120 Shader ShaderDefinition::Load(RawData&& raw) const
122 uint32_t hints = Shader::Hint::NONE;
123 for(const auto& hint : mHints)
125 if(hint == SHADER_HINT_OUTPUT_IS_TRANSPARENT)
127 hints |= Shader::Hint::OUTPUT_IS_TRANSPARENT;
129 else if(hint == SHADER_HINT_MODIFIES_GEOMETRY)
131 hints |= Shader::Hint::MODIFIES_GEOMETRY;
135 Shader shader = Shader::New(raw.mVertexShaderSource, raw.mFragmentShaderSource, static_cast<Shader::Hint::Value>(hints));
136 for(Property::Map::SizeType i0 = 0, i1 = mUniforms.Count(); i0 != i1; ++i0)
138 auto pair = mUniforms.GetKeyValue(i0);
139 DALI_ASSERT_ALWAYS(pair.first.type == Property::Key::STRING);
140 shader.RegisterProperty(pair.first.stringKey, pair.second);
146 } // namespace SceneLoader