[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / public-api / loader / parse-renderer-state.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/parse-renderer-state.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/devel-api/common/map-wrapper.h>
23 #include <cstring>
24
25 namespace Dali::Scene3D::Loader
26 {
27 namespace RendererState
28 {
29 namespace
30 {
31 const std::map<std::string_view, Type>& GetComparisons()
32 {
33   static const std::map<std::string_view, Type> COMPARISONS{
34   #define DECL_COMPARISON(x) {#x, Comparison::x}
35     DECL_COMPARISON(NEVER),
36     DECL_COMPARISON(ALWAYS),
37     DECL_COMPARISON(LESS),
38     DECL_COMPARISON(GREATER),
39     DECL_COMPARISON(EQUAL),
40     DECL_COMPARISON(NOT_EQUAL),
41     DECL_COMPARISON(LESS_EQUAL),
42     DECL_COMPARISON(GREATER_EQUAL),
43   #undef DECL_COMPARISON
44   };
45   return COMPARISONS;
46 }
47
48 Type InterpretComparison(const std::string_view& str)
49 {
50   Type value = 0x0;
51   auto iFind = GetComparisons().find(str);
52   if(iFind != GetComparisons().end())
53   {
54     value = iFind->second;
55   }
56   return value;
57 }
58
59 const std::map<std::string_view, Type>& GetBlendFactors()
60 {
61   static const std::map<std::string_view, Type> BLEND_FACTORS{
62   #define DECL_BLEND_FACTOR(x) {#x, Dali::Scene3D::Loader::BlendFactor::x}
63     DECL_BLEND_FACTOR(ZERO),
64     DECL_BLEND_FACTOR(ONE),
65     DECL_BLEND_FACTOR(SRC_COLOR),
66     DECL_BLEND_FACTOR(ONE_MINUS_SRC_COLOR),
67     DECL_BLEND_FACTOR(SRC_ALPHA),
68     DECL_BLEND_FACTOR(ONE_MINUS_SRC_ALPHA),
69     DECL_BLEND_FACTOR(DST_ALPHA),
70     DECL_BLEND_FACTOR(ONE_MINUS_DST_ALPHA),
71     DECL_BLEND_FACTOR(DST_COLOR),
72     DECL_BLEND_FACTOR(ONE_MINUS_DST_COLOR),
73     DECL_BLEND_FACTOR(SRC_ALPHA_SATURATE),
74     DECL_BLEND_FACTOR(CONSTANT_COLOR),
75     DECL_BLEND_FACTOR(ONE_MINUS_CONSTANT_COLOR),
76     DECL_BLEND_FACTOR(CONSTANT_ALPHA),
77     DECL_BLEND_FACTOR(ONE_MINUS_CONSTANT_ALPHA),
78   #undef DECL_BLEND_FACTOR
79   };
80   return BLEND_FACTORS;
81 }
82
83 Type InterpretBlendFactor(const std::string_view& str, uint8_t item)
84 {
85   Type value = 0x0;
86   auto iFind = GetBlendFactors().find(str);
87   if(iFind != GetBlendFactors().end())
88   {
89     value = iFind->second << (BLEND_FACTOR_BASE_SHIFT + BLEND_FACTOR_ITEM_BITS * item);
90   }
91   return value;
92 }
93
94 const std::map<std::string_view, Type>& GetBufferModes()
95 {
96   static const std::map<std::string_view, Type> BUFFER_MODES{
97   #define DECL_BUFFER_MODE(x) {#x, BufferMode::x}
98     DECL_BUFFER_MODE(NONE),
99     DECL_BUFFER_MODE(AUTO),
100     DECL_BUFFER_MODE(COLOR),
101     DECL_BUFFER_MODE(STENCIL),
102     DECL_BUFFER_MODE(COLOR_STENCIL),
103   #undef DECL_BUFFER_MODE
104   };
105   return BUFFER_MODES;
106 }
107
108 Type InterpretBufferMode(const std::string_view& str)
109 {
110   Type value = 0x0;
111   auto iFind = GetBufferModes().find(str);
112   if(iFind != GetBufferModes().end())
113   {
114     value = iFind->second << BUFFER_MODE_SHIFT;
115   }
116   return value;
117 }
118
119 const std::map<std::string_view, Type (*)(const std::string_view&)>& GetRendererStateProcessors()
120 {
121   static const std::map<std::string_view, Type (*)(const std::string_view&)> RENDERER_STATE_PROCESSORS{
122     {"DEPTH_WRITE", [](const std::string_view&) -> Type { return DEPTH_WRITE; }},
123     {"DEPTH_TEST", [](const std::string_view&) -> Type { return DEPTH_TEST; }},
124     {"CULL_FRONT", [](const std::string_view&) -> Type { return CULL_FRONT; }},
125     {"CULL_BACK", [](const std::string_view&) -> Type { return CULL_BACK; }},
126     {"ALPHA_BLEND", [](const std::string_view&) -> Type { return ALPHA_BLEND; }},
127     {"DEPTH_FUNC", [](const std::string_view& arg) -> Type {
128        Type value = (arg[0] == ':') ? (InterpretComparison(std::string_view(arg.data() + 1, arg.size() - 1)) << DEPTH_FUNCTION_SHIFT) : 0x0;
129        return value;
130      }},
131     {"BLEND_SRC_RGB", [](const std::string_view& arg) -> Type {
132        Type value = (arg[0] == ':') ? InterpretBlendFactor(std::string_view(arg.data() + 1, arg.size() - 1), 0) : 0x0;
133        return value;
134      }},
135     {"BLEND_DST_RGB", [](const std::string_view& arg) -> Type {
136        Type value = (arg[0] == ':') ? InterpretBlendFactor(std::string_view(arg.data() + 1, arg.size() - 1), 1) : 0x0;
137        return value;
138      }},
139     {"BLEND_SRC_ALPHA", [](const std::string_view& arg) -> Type {
140        Type value = (arg[0] == ':') ? InterpretBlendFactor(std::string_view(arg.data() + 1, arg.size() - 1), 2) : 0x0;
141        return value;
142      }},
143     {"BLEND_DST_ALPHA", [](const std::string_view& arg) -> Type {
144        Type value = (arg[0] == ':') ? InterpretBlendFactor(std::string_view(arg.data() + 1, arg.size() - 1), 3) : 0x0;
145        return value;
146      }},
147     {"BUFFER_MODE", [](const std::string_view& arg) -> Type {
148        Type value = (arg[0] == ':') ? InterpretBufferMode(std::string_view(arg.data() + 1, arg.size() - 1)) : 0x0;
149        return value;
150      }},
151   };
152   return RENDERER_STATE_PROCESSORS;
153 }
154
155 } // namespace
156
157 Type Parse(const char* string, size_t length, StringCallback onError)
158 {
159   if(length == 0)
160   {
161     length = strlen(string);
162   }
163
164   Type value = 0x0;
165   auto iEnd  = string + length;
166   while(string != iEnd)
167   {
168     auto iNextToken = std::find(string, iEnd, '|');
169     auto iColon     = std::find(string, iNextToken, ':');
170     auto i          = GetRendererStateProcessors().find(std::string_view(string, iColon - string));
171     if(i != GetRendererStateProcessors().end() && size_t(std::distance(string, iNextToken)) >= i->first.size())
172     {
173       value |= i->second(std::string_view(string + i->first.size(), iNextToken - iColon));
174     }
175     else
176     {
177       onError("Not a valid RendererState: " + std::string(string, iNextToken));
178     }
179
180     string = iNextToken + (iNextToken != iEnd);
181   }
182
183   return value;
184 }
185
186 } // namespace RendererState
187 } // namespace Dali::Scene3D::Loader