Revert "[Tizen] Removed unused macro invocation from shader"
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / public-api / loader / shader-option.cpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-scene3d/public-api/loader/shader-option.h>
20
21 // EXTERNAL INCLUDES
22 #include <algorithm>
23 #include <ostream>
24 #include <sstream>
25 #include <string>
26
27 namespace Dali::Scene3D::Loader
28 {
29 namespace
30 {
31 static constexpr std::string_view OPTION_KEYWORD[] =
32   {
33     "GLTF_CHANNELS",
34     "THREE_TEX",
35     "BASECOLOR_TEX",
36     "METALLIC_ROUGHNESS_TEX",
37     "NORMAL_TEX",
38     "OCCLUSION",
39     "EMISSIVE_TEXTURE",
40     "ALPHA_TEST",
41     "SSS",
42     "MATERIAL_SPECULAR_TEXTURE",
43     "MATERIAL_SPECULAR_COLOR_TEXTURE",
44     "SKINNING",
45     "FLIP_V",
46     "COLOR_ATTRIBUTE",
47     "VEC4_TANGENT",
48     "MORPH_POSITION",
49     "MORPH_NORMAL",
50     "MORPH_TANGENT",
51     "MORPH_VERSION_2_0",
52 };
53 static constexpr uint32_t NUMBER_OF_OPTIONS = sizeof(OPTION_KEYWORD) / sizeof(OPTION_KEYWORD[0]);
54 static const char*        ADD_EXTRA_SKINNING_ATTRIBUTES{"ADD_EXTRA_SKINNING_ATTRIBUTES"};
55 static const char*        ADD_EXTRA_WEIGHTS{"ADD_EXTRA_WEIGHTS"};
56
57 inline void HashString(uint64_t& hash, const char* string)
58 {
59   char c;
60   while((c = *string++))
61   {
62     hash = hash * 33 + c;
63   }
64 }
65 } // namespace
66
67 ShaderOption::ShaderOption(const ShaderOption& rhs)
68 {
69   mOptionHash = rhs.mOptionHash;
70   for(auto& macroDef : rhs.mMacros)
71   {
72     mMacros.emplace_back(macroDef);
73   }
74 }
75
76 ShaderOption& ShaderOption::operator=(const ShaderOption& rhs)
77 {
78   if(this != &rhs)
79   {
80     mOptionHash = rhs.mOptionHash;
81     for(auto& macroDef : rhs.mMacros)
82     {
83       mMacros.emplace_back(macroDef);
84     }
85   }
86   return *this;
87 }
88
89 void ShaderOption::SetTransparency()
90 {
91   mOptionHash |= (1 << NUMBER_OF_OPTIONS);
92 }
93
94 void ShaderOption::AddOption(Type shaderOptionType)
95 {
96   mOptionHash |= (1 << static_cast<uint32_t>(shaderOptionType));
97 }
98
99 void ShaderOption::AddJointMacros(size_t numberOfJointSets)
100 {
101   // Add options for ADD_EXTRA_SKINNING_ATTRIBUTES and ADD_EXTRA_WEIGHTS:
102   if(numberOfJointSets > 1)
103   {
104     std::ostringstream attributes;
105     std::ostringstream weights;
106     for(size_t i = 1; i < numberOfJointSets; ++i)
107     {
108       attributes << "in vec4 aJoints" << i << ";\n";
109       attributes << "in vec4 aWeights" << i << ";\n";
110
111       weights << "bone +=\n"
112               << "uBone[int(aJoints" << i << ".x)] * aWeights" << i << ".x +\n"
113               << "uBone[int(aJoints" << i << ".y)] * aWeights" << i << ".y +\n"
114               << "uBone[int(aJoints" << i << ".z)] * aWeights" << i << ".z +\n"
115               << "uBone[int(aJoints" << i << ".w)] * aWeights" << i << ".w;\n";
116     }
117     AddMacroDefinition(ADD_EXTRA_SKINNING_ATTRIBUTES, attributes.str());
118     AddMacroDefinition(ADD_EXTRA_WEIGHTS, weights.str());
119   }
120 }
121
122 void ShaderOption::AddMacroDefinition(std::string macro, std::string definition)
123 {
124   auto iter = std::find_if(mMacros.begin(), mMacros.end(), [macro](ShaderOption::MacroDefinition& md) { return md.macro == macro; });
125   if(iter != mMacros.end())
126   {
127     iter->definition = definition;
128   }
129   else
130   {
131     mMacros.emplace_back(MacroDefinition{macro, definition});
132   }
133 }
134
135 const std::vector<ShaderOption::MacroDefinition>& ShaderOption::GetMacroDefinitions() const
136 {
137   return mMacros;
138 }
139
140 uint64_t ShaderOption::GetOptionHash() const
141 {
142   uint64_t optionHash = mOptionHash;
143   if(!mMacros.empty())
144   {
145     uint64_t hash = 5381;
146     for(auto& macroDef : mMacros)
147     {
148       HashString(hash, macroDef.macro.c_str());
149       HashString(hash, macroDef.definition.c_str());
150     }
151     optionHash |= (hash << 32 & 0xFFFFFFFF00000000);
152   }
153   return optionHash;
154 }
155
156 void ShaderOption::GetDefines(std::vector<std::string>& defines) const
157 {
158   defines.clear();
159   for(uint32_t i = 0; i < NUMBER_OF_OPTIONS; ++i)
160   {
161     if(mOptionHash & 1 << i)
162     {
163       defines.push_back(OPTION_KEYWORD[i].data());
164     }
165   }
166 }
167
168 std::string_view ShaderOption::GetDefineKeyword(Type shaderOptionType)
169 {
170   return OPTION_KEYWORD[static_cast<uint32_t>(shaderOptionType)];
171 }
172
173 } // namespace Dali::Scene3D::Loader