d09195dfecec51ac944657f533b0185fe95383ca
[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 <string>
24
25 namespace Dali::Scene3D::Loader
26 {
27 namespace
28 {
29 static constexpr std::string_view OPTION_KEYWORD[] =
30   {
31     "GLTF_CHANNELS",
32     "THREE_TEX",
33     "BASECOLOR_TEX",
34     "METALLIC_ROUGHNESS_TEX",
35     "NORMAL_TEX",
36     "OCCLUSION",
37     "EMISSIVE_TEXTURE",
38     "ALPHA_TEST",
39     "SSS",
40     "MATERIAL_SPECULAR_TEXTURE",
41     "MATERIAL_SPECULAR_COLOR_TEXTURE",
42     "SKINNING",
43     "FLIP_V",
44     "COLOR_ATTRIBUTE",
45     "VEC4_TANGENT",
46     "MORPH_POSITION",
47     "MORPH_NORMAL",
48     "MORPH_TANGENT",
49     "MORPH_VERSION_2_0",
50 };
51 static constexpr uint32_t NUMBER_OF_OPTIONS = sizeof(OPTION_KEYWORD) / sizeof(OPTION_KEYWORD[0]);
52
53 inline void HashString(std::uint64_t& hash, const char* string)
54 {
55   char c;
56   while((c = *string++))
57   {
58     hash = hash * 33 + c;
59   }
60 }
61 } // namespace
62
63 ShaderOption::ShaderOption(const ShaderOption& rhs)
64 {
65   mOptionHash = rhs.mOptionHash;
66   for(auto& macroDef : rhs.mMacros)
67   {
68     mMacros.emplace_back(macroDef);
69   }
70 }
71
72 ShaderOption& ShaderOption::operator=(const ShaderOption& rhs)
73 {
74   if(this != &rhs)
75   {
76     mOptionHash = rhs.mOptionHash;
77     for(auto& macroDef : rhs.mMacros)
78     {
79       mMacros.emplace_back(macroDef);
80     }
81   }
82   return *this;
83 }
84
85 void ShaderOption::SetTransparency()
86 {
87   mOptionHash |= (1 << NUMBER_OF_OPTIONS);
88 }
89
90 void ShaderOption::AddOption(Type shaderOptionType)
91 {
92   mOptionHash |= (1 << static_cast<uint32_t>(shaderOptionType));
93 }
94
95 void ShaderOption::AddMacroDefinition(std::string macro, std::string definition)
96 {
97   auto iter = std::find_if(mMacros.begin(), mMacros.end(), [macro](ShaderOption::MacroDefinition& md) { return md.macro == macro; });
98   if(iter != mMacros.end())
99   {
100     iter->definition = definition;
101   }
102   else
103   {
104     mMacros.emplace_back(MacroDefinition{macro, definition});
105   }
106 }
107
108 const std::vector<ShaderOption::MacroDefinition>& ShaderOption::GetMacroDefinitions() const
109 {
110   return mMacros;
111 }
112
113 uint64_t ShaderOption::GetOptionHash() const
114 {
115   uint64_t optionHash = mOptionHash;
116   if(!mMacros.empty())
117   {
118     uint64_t hash = 5381;
119     for(auto& macroDef : mMacros)
120     {
121       HashString(hash, macroDef.macro.c_str());
122       HashString(hash, macroDef.definition.c_str());
123     }
124     optionHash |= (hash << 32 & 0xFFFFFFFF00000000);
125   }
126   return optionHash;
127 }
128
129 void ShaderOption::GetDefines(std::vector<std::string>& defines) const
130 {
131   defines.clear();
132   for(uint32_t i = 0; i < NUMBER_OF_OPTIONS; ++i)
133   {
134     if(mOptionHash & 1 << i)
135     {
136       defines.push_back(OPTION_KEYWORD[i].data());
137     }
138   }
139 }
140
141 std::string_view ShaderOption::GetDefineKeyword(Type shaderOptionType)
142 {
143   return OPTION_KEYWORD[static_cast<uint32_t>(shaderOptionType)];
144 }
145
146 } // namespace Dali::Scene3D::Loader