2 * Copyright (c) 2020 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.
18 // Enable debug log for test coverage
19 #define DEBUG_ENABLED 1
21 #include "dali-scene3d/public-api/loader/renderer-state.h"
22 #include "dali-scene3d/public-api/loader/parse-renderer-state.h"
23 #include "dali-scene3d/public-api/loader/utils.h"
24 #include <dali-test-suite-utils.h>
27 using namespace Dali::Scene3D::Loader;
29 namespace sl = Dali::Scene3D::Loader;
30 namespace rs = RendererState;
32 int UtcDaliRendererStateFromBlendFactors(void)
34 rs::Type state = rs::FromBlendFactors(sl::BlendFactor::ZERO, sl::BlendFactor::ONE,
35 sl::BlendFactor::SRC_COLOR, sl::BlendFactor::ONE_MINUS_SRC_COLOR);
37 DALI_TEST_EQUAL((state >> rs::BLEND_FACTOR_BASE_SHIFT) & rs::BLEND_FACTOR_ITEM_MASK, rs::Type(sl::BlendFactor::ZERO));
38 DALI_TEST_EQUAL((state >> (rs::BLEND_FACTOR_BASE_SHIFT + rs::BLEND_FACTOR_ITEM_BITS)) &
39 rs::BLEND_FACTOR_ITEM_MASK, rs::Type(sl::BlendFactor::ONE));
40 DALI_TEST_EQUAL((state >> (rs::BLEND_FACTOR_BASE_SHIFT + rs::BLEND_FACTOR_ITEM_BITS * 2)) &
41 rs::BLEND_FACTOR_ITEM_MASK, rs::Type(sl::BlendFactor::SRC_COLOR));
42 DALI_TEST_EQUAL((state >> (rs::BLEND_FACTOR_BASE_SHIFT + rs::BLEND_FACTOR_ITEM_BITS * 3)) &
43 rs::BLEND_FACTOR_ITEM_MASK, rs::Type(sl::BlendFactor::ONE_MINUS_SRC_COLOR));
48 #define HELP_TEST_RENDERER_STATE(property, resetValue, state, checkValue, renderer)\
49 renderer.SetProperty(property, ~(resetValue));\
50 rs::Apply((state), (renderer));\
51 printf("%s %s vs %s\n", #property, #state, #checkValue);\
52 DALI_TEST_EQUAL(renderer.GetProperty(property).Get<decltype(checkValue)>(), (checkValue));
54 int UtcDaliRendererStateApply(void)
57 auto vsh = "void main() { gl_Position = vec4(0.); }";
58 auto fsh = "void main() { gl_FragColor = vec4(1.); }";
59 Geometry geom = Geometry::New();
60 Shader shader = Shader::New(vsh, fsh);
61 Renderer renderer = Renderer::New(geom, shader);
63 HELP_TEST_RENDERER_STATE(Renderer::Property::DEPTH_TEST_MODE, DepthTestMode::OFF, rs::DEPTH_TEST, DepthTestMode::ON, renderer);
65 HELP_TEST_RENDERER_STATE(Renderer::Property::BLEND_MODE, BlendMode::OFF, rs::ALPHA_BLEND, BlendMode::ON, renderer);
66 HELP_TEST_RENDERER_STATE(Renderer::Property::BLEND_MODE, BlendMode::OFF, ~(rs::ALPHA_BLEND), BlendMode::USE_ACTOR_OPACITY, renderer);
68 HELP_TEST_RENDERER_STATE(Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::NONE, rs::CULL_FRONT, FaceCullingMode::FRONT, renderer);
69 HELP_TEST_RENDERER_STATE(Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::NONE, rs::CULL_BACK, FaceCullingMode::BACK, renderer);
70 HELP_TEST_RENDERER_STATE(Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::NONE, rs::CULL_FRONT | rs::CULL_BACK,
71 FaceCullingMode::FRONT_AND_BACK, renderer);
73 #define DEPTH_FUNC_PAIR(x) { Comparison::x << rs::DEPTH_FUNCTION_SHIFT, DepthFunction::x }
74 const std::pair<rs::Type, DepthFunction::Type> depthFunctionPairs[] {
75 DEPTH_FUNC_PAIR(NEVER),
76 DEPTH_FUNC_PAIR(ALWAYS),
77 DEPTH_FUNC_PAIR(LESS),
78 DEPTH_FUNC_PAIR(GREATER),
79 DEPTH_FUNC_PAIR(EQUAL),
80 DEPTH_FUNC_PAIR(NOT_EQUAL),
81 DEPTH_FUNC_PAIR(LESS_EQUAL),
82 DEPTH_FUNC_PAIR(GREATER_EQUAL),
84 #undef DEPTH_FUNC_PAIR
85 for (auto& p : depthFunctionPairs)
87 HELP_TEST_RENDERER_STATE(Renderer::Property::DEPTH_FUNCTION, DepthFunction::LESS, p.first, p.second, renderer);
90 #define BLEND_FACTOR_PAIR(x) { sl::BlendFactor::x, BlendFactor::x }
91 const std::pair<rs::Type, BlendFactor::Type> BLEND_FACTORS[] {
92 BLEND_FACTOR_PAIR(ZERO),
93 BLEND_FACTOR_PAIR(ONE),
94 BLEND_FACTOR_PAIR(SRC_COLOR),
95 BLEND_FACTOR_PAIR(ONE_MINUS_SRC_COLOR),
96 BLEND_FACTOR_PAIR(SRC_ALPHA),
97 BLEND_FACTOR_PAIR(ONE_MINUS_SRC_ALPHA),
98 BLEND_FACTOR_PAIR(DST_COLOR),
99 BLEND_FACTOR_PAIR(ONE_MINUS_DST_COLOR),
100 BLEND_FACTOR_PAIR(DST_ALPHA),
101 BLEND_FACTOR_PAIR(ONE_MINUS_DST_ALPHA),
102 BLEND_FACTOR_PAIR(SRC_ALPHA_SATURATE),
103 BLEND_FACTOR_PAIR(CONSTANT_COLOR),
104 BLEND_FACTOR_PAIR(ONE_MINUS_CONSTANT_COLOR),
105 BLEND_FACTOR_PAIR(CONSTANT_ALPHA),
106 BLEND_FACTOR_PAIR(ONE_MINUS_CONSTANT_ALPHA),
108 #undef BLEND_FACTOR_PAIR
109 for (auto property: {
110 Renderer::Property::BLEND_FACTOR_SRC_RGB,
111 Renderer::Property::BLEND_FACTOR_DEST_RGB,
112 Renderer::Property::BLEND_FACTOR_SRC_ALPHA,
113 Renderer::Property::BLEND_FACTOR_DEST_ALPHA,
116 const auto itemShift = rs::BLEND_FACTOR_ITEM_BITS * (property - Renderer::Property::BLEND_FACTOR_SRC_RGB);
117 const auto shift = rs::BLEND_FACTOR_BASE_SHIFT + itemShift;
118 for (auto& value: BLEND_FACTORS)
120 HELP_TEST_RENDERER_STATE(property, BlendFactor::ZERO, value.first << shift, value.second, renderer);
124 #define RENDER_MODE_PAIR(x) { BufferMode::x << rs::BUFFER_MODE_SHIFT, RenderMode::x }
125 std::pair<rs::Type, RenderMode::Type> renderModePairs[] {
126 // same as our reset value: RENDER_MODE_PAIR(NONE),
127 RENDER_MODE_PAIR(AUTO),
128 RENDER_MODE_PAIR(COLOR),
129 RENDER_MODE_PAIR(STENCIL),
130 RENDER_MODE_PAIR(COLOR_STENCIL),
132 #undef RENDER_MODE_PAIR
133 for (auto& p: renderModePairs)
135 HELP_TEST_RENDERER_STATE(Renderer::Property::RENDER_MODE, RenderMode::NONE, p.first, p.second, renderer);
141 int UtcDaliRendererStateParseEmpty(void)
144 auto onError = [&](const std::string& e) { error = e; };
146 DALI_TEST_EQUAL(rs::Parse("", 0, onError), uint32_t(rs::NONE));
147 DALI_TEST_CHECK(error.empty());
151 int UtcDaliRendererStateParseInvalid(void)
154 auto onError = [&](const std::string& e) { error = e; };
156 DALI_TEST_EQUAL(rs::Parse("definitelyNotAValidRendererState", 0, onError), uint32_t(rs::NONE));
157 DALI_TEST_CHECK(strstr(error.c_str(), "Not a valid RendererState") != nullptr);
165 std::string_view name;
168 void Apply(std::ostream& stream, uint8_t shift, uint32_t& result) const
171 result |= expected << shift;
175 struct StateGenerator
177 std::string_view name;
180 std::vector<Option> permutations;
183 #define STRING_STATE_PAIR(x, y) { #x, y::x }
184 const decltype(StateGenerator::permutations) BLEND_FACTORS {
185 { "", sl::BlendFactor::OMIT },
186 STRING_STATE_PAIR(ZERO, sl::BlendFactor),
187 STRING_STATE_PAIR(ONE, sl::BlendFactor),
188 STRING_STATE_PAIR(SRC_COLOR, sl::BlendFactor),
189 STRING_STATE_PAIR(ONE_MINUS_SRC_COLOR, sl::BlendFactor),
190 STRING_STATE_PAIR(SRC_ALPHA, sl::BlendFactor),
191 STRING_STATE_PAIR(ONE_MINUS_SRC_ALPHA, sl::BlendFactor),
192 STRING_STATE_PAIR(DST_COLOR, sl::BlendFactor),
193 STRING_STATE_PAIR(ONE_MINUS_DST_COLOR, sl::BlendFactor),
194 STRING_STATE_PAIR(DST_ALPHA, sl::BlendFactor),
195 STRING_STATE_PAIR(ONE_MINUS_DST_ALPHA, sl::BlendFactor),
196 STRING_STATE_PAIR(SRC_ALPHA_SATURATE, sl::BlendFactor),
197 STRING_STATE_PAIR(CONSTANT_COLOR, sl::BlendFactor),
198 STRING_STATE_PAIR(ONE_MINUS_CONSTANT_COLOR, sl::BlendFactor),
199 STRING_STATE_PAIR(CONSTANT_ALPHA, sl::BlendFactor),
200 STRING_STATE_PAIR(ONE_MINUS_CONSTANT_ALPHA, sl::BlendFactor),
203 const StateGenerator PERMUTATORS[] {
204 { "DEPTH_FUNC:", rs::DEPTH_FUNCTION_SHIFT, {
205 { "", Comparison::OMIT },
206 STRING_STATE_PAIR(NEVER, Comparison),
207 STRING_STATE_PAIR(ALWAYS, Comparison),
208 STRING_STATE_PAIR(LESS, Comparison),
209 STRING_STATE_PAIR(GREATER, Comparison),
210 STRING_STATE_PAIR(EQUAL, Comparison),
211 STRING_STATE_PAIR(NOT_EQUAL, Comparison),
212 STRING_STATE_PAIR(LESS_EQUAL, Comparison),
213 STRING_STATE_PAIR(GREATER_EQUAL, Comparison),
215 { "BLEND_SRC_RGB:", rs::BLEND_FACTOR_BASE_SHIFT, BLEND_FACTORS },
216 { "BLEND_DST_RGB:", rs::BLEND_FACTOR_BASE_SHIFT + rs::BLEND_FACTOR_ITEM_BITS, BLEND_FACTORS },
217 { "BLEND_SRC_ALPHA:", rs::BLEND_FACTOR_BASE_SHIFT + rs::BLEND_FACTOR_ITEM_BITS * 2, BLEND_FACTORS },
218 { "BLEND_DST_ALPHA:", rs::BLEND_FACTOR_BASE_SHIFT + rs::BLEND_FACTOR_ITEM_BITS * 3, BLEND_FACTORS },
219 { "BUFFER_MODE:", rs::BUFFER_MODE_SHIFT, {
220 { "", BufferMode::OMIT },
221 STRING_STATE_PAIR(NONE, BufferMode),
222 STRING_STATE_PAIR(AUTO, BufferMode),
223 STRING_STATE_PAIR(COLOR, BufferMode),
224 STRING_STATE_PAIR(STENCIL, BufferMode),
225 STRING_STATE_PAIR(COLOR_STENCIL, BufferMode),
228 { "", 0, { STRING_STATE_PAIR(DEPTH_WRITE, rs) } },
229 { "", 0, { STRING_STATE_PAIR(DEPTH_TEST, rs) } },
230 { "", 0, { STRING_STATE_PAIR(CULL_FRONT, rs) } },
231 { "", 0, { STRING_STATE_PAIR(CULL_BACK, rs) } },
232 { "", 0, { STRING_STATE_PAIR(ALPHA_BLEND, rs) } },
235 #undef STRING_STATE_PAIR
238 int UtcDaliRendererStateParseIndividual(void)
241 auto onError = [&](const std::string& e) { error = e; };
244 for (auto& p: PERMUTATORS)
246 for (auto& o: p.permutations)
248 StreamBuffer streamBuf(buffer, sizeof(buffer));
249 std::ostream stream(&streamBuf);
253 uint32_t expected = 0x0;
254 o.Apply(stream, p.shift, expected);
257 printf("%s -> %d\n", buffer, expected);
258 DALI_TEST_EQUAL(rs::Parse(buffer, 0, onError), expected);
259 DALI_TEST_CHECK(error.empty());
266 int UtcDaliRendererStateParseCombined(void)
268 constexpr uint32_t count = std::extent<decltype(PERMUTATORS)>::value;
269 constexpr uint32_t prime = 13;
270 static_assert(prime > count);
271 constexpr uint32_t skip = 3 * count * count + 7 * count + 1;
272 static_assert(skip % prime != 0);
275 auto onError = [&](const std::string& e) { error = e; };
277 std::vector<rs::Type> expectedValues;
280 for (uint32_t i = 0; i < count; ++i)
282 StreamBuffer streamBuf(buffer, sizeof(buffer));
283 std::ostream stream(&streamBuf);
285 uint32_t expected = 0x0;
288 for (uint32_t j = 0; j < count; ++j)
290 iTmp = (iTmp + skip) % count;
291 DALI_TEST_CHECK(iTmp < count);
298 auto& perm = PERMUTATORS[iTmp];
300 perm.permutations.back().Apply(stream, perm.shift, expected);
305 DALI_TEST_EQUAL(rs::Parse(buffer, 0, onError), expected);
306 DALI_TEST_CHECK(error.empty());
308 auto iFind = std::lower_bound(expectedValues.begin(), expectedValues.end(), expected);
309 if (iFind == expectedValues.end() || *iFind != expected)
311 expectedValues.insert(iFind, expected);
313 DALI_TEST_EQUAL(expectedValues.size(), 1u);