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 #include <dali-test-suite-utils.h>
19 #include <dali/public-api/dali-core.h>
20 #include <mesh-builder.h>
27 void utc_dali_shader_startup(void)
29 test_return_value = TET_UNDEF;
32 void utc_dali_shader_cleanup(void)
34 test_return_value = TET_PASS;
39 static const char* VertexSource =
40 "This is a custom vertex shader\n"
41 "made on purpose to look nothing like a normal vertex shader inside dali\n";
43 static const char* FragmentSource =
44 "This is a custom fragment shader\n"
45 "made on purpose to look nothing like a normal fragment shader inside dali\n";
47 void TestConstraintNoBlue(Vector4& current, const PropertyInputContainer& inputs)
54 int UtcDaliShaderMethodNew01(void)
56 TestApplication application;
58 Shader shader = Shader::New(VertexSource, FragmentSource);
59 DALI_TEST_EQUALS((bool)shader, true, TEST_LOCATION);
63 int UtcDaliShaderMethodNew02(void)
65 TestApplication application;
68 DALI_TEST_EQUALS((bool)shader, false, TEST_LOCATION);
72 int UtcDaliShaderAssignmentOperator(void)
74 TestApplication application;
76 Shader shader1 = Shader::New(VertexSource, FragmentSource);
80 DALI_TEST_CHECK(!(shader1 == shader2));
84 DALI_TEST_CHECK(shader1 == shader2);
86 shader2 = Shader::New(VertexSource, FragmentSource);
89 DALI_TEST_CHECK(!(shader1 == shader2));
94 int UtcDaliShaderMoveConstructor(void)
96 TestApplication application;
98 Shader shader = Shader::New(VertexSource, FragmentSource);
99 DALI_TEST_CHECK(shader);
100 DALI_TEST_EQUALS(1, shader.GetBaseObject().ReferenceCount(), TEST_LOCATION);
102 // Register a custom property
103 Vector2 vec(1.0f, 2.0f);
104 Property::Index customIndex = shader.RegisterProperty("custom", vec);
105 DALI_TEST_EQUALS(shader.GetProperty<Vector2>(customIndex), vec, TEST_LOCATION);
107 Shader move = std::move(shader);
108 DALI_TEST_CHECK(move);
109 DALI_TEST_EQUALS(1, move.GetBaseObject().ReferenceCount(), TEST_LOCATION);
110 DALI_TEST_EQUALS(move.GetProperty<Vector2>(customIndex), vec, TEST_LOCATION);
111 DALI_TEST_CHECK(!shader);
116 int UtcDaliShaderMoveAssignment(void)
118 TestApplication application;
120 Shader shader = Shader::New(VertexSource, FragmentSource);
121 DALI_TEST_CHECK(shader);
122 DALI_TEST_EQUALS(1, shader.GetBaseObject().ReferenceCount(), TEST_LOCATION);
124 // Register a custom property
125 Vector2 vec(1.0f, 2.0f);
126 Property::Index customIndex = shader.RegisterProperty("custom", vec);
127 DALI_TEST_EQUALS(shader.GetProperty<Vector2>(customIndex), vec, TEST_LOCATION);
130 move = std::move(shader);
131 DALI_TEST_CHECK(move);
132 DALI_TEST_EQUALS(1, move.GetBaseObject().ReferenceCount(), TEST_LOCATION);
133 DALI_TEST_EQUALS(move.GetProperty<Vector2>(customIndex), vec, TEST_LOCATION);
134 DALI_TEST_CHECK(!shader);
139 int UtcDaliShaderDownCast01(void)
141 TestApplication application;
143 Shader shader = Shader::New(VertexSource, FragmentSource);
145 BaseHandle handle(shader);
146 Shader shader2 = Shader::DownCast(handle);
147 DALI_TEST_EQUALS((bool)shader2, true, TEST_LOCATION);
151 int UtcDaliShaderDownCast02(void)
153 TestApplication application;
155 Handle handle = Handle::New(); // Create a custom object
156 Shader shader = Shader::DownCast(handle);
157 DALI_TEST_EQUALS((bool)shader, false, TEST_LOCATION);
161 int UtcDaliShaderDefaultProperties(void)
163 TestApplication application;
164 // from shader-impl.cpp
165 // DALI_PROPERTY( "program", MAP, true, false, false, Dali::Shader::Property::PROGRAM )
167 Shader shader = Shader::New(VertexSource, FragmentSource);
168 DALI_TEST_EQUALS(shader.GetPropertyCount(), 1, TEST_LOCATION);
170 DALI_TEST_EQUALS(shader.GetPropertyName(Shader::Property::PROGRAM), "program", TEST_LOCATION);
171 DALI_TEST_EQUALS(shader.GetPropertyIndex("program"), (Property::Index)Shader::Property::PROGRAM, TEST_LOCATION);
172 DALI_TEST_EQUALS(shader.GetPropertyType(Shader::Property::PROGRAM), Property::MAP, TEST_LOCATION);
173 DALI_TEST_EQUALS(shader.IsPropertyWritable(Shader::Property::PROGRAM), true, TEST_LOCATION);
174 DALI_TEST_EQUALS(shader.IsPropertyAnimatable(Shader::Property::PROGRAM), false, TEST_LOCATION);
175 DALI_TEST_EQUALS(shader.IsPropertyAConstraintInput(Shader::Property::PROGRAM), false, TEST_LOCATION);
180 int UtcDaliShaderConstraint01(void)
182 TestApplication application;
184 tet_infoline("Test that a non-uniform shader property can be constrained");
186 Shader shader = Shader::New(VertexSource, FragmentSource);
187 Geometry geometry = CreateQuadGeometry();
188 Renderer renderer = Renderer::New(geometry, shader);
190 Actor actor = Actor::New();
191 actor.AddRenderer(renderer);
192 actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
193 application.GetScene().Add(actor);
195 Vector4 initialColor = Color::WHITE;
196 Property::Index colorIndex = shader.RegisterProperty("uFadeColor", initialColor);
198 application.SendNotification();
199 application.Render(0);
200 DALI_TEST_EQUALS(shader.GetProperty<Vector4>(colorIndex), initialColor, TEST_LOCATION);
203 Constraint constraint = Constraint::New<Vector4>(shader, colorIndex, TestConstraintNoBlue);
205 application.SendNotification();
206 application.Render(0);
208 // Expect no blue component in either buffer - yellow
209 DALI_TEST_EQUALS(shader.GetCurrentProperty<Vector4>(colorIndex), Color::YELLOW, TEST_LOCATION);
210 application.Render(0);
211 DALI_TEST_EQUALS(shader.GetCurrentProperty<Vector4>(colorIndex), Color::YELLOW, TEST_LOCATION);
213 shader.RemoveConstraints();
214 shader.SetProperty(colorIndex, Color::WHITE);
215 application.SendNotification();
216 application.Render(0);
217 DALI_TEST_EQUALS(shader.GetCurrentProperty<Vector4>(colorIndex), Color::WHITE, TEST_LOCATION);
222 int UtcDaliShaderConstraint02(void)
224 TestApplication application;
226 tet_infoline("Test that a uniform map shader property can be constrained");
228 Shader shader = Shader::New(VertexSource, FragmentSource);
229 Geometry geometry = CreateQuadGeometry();
230 Renderer renderer = Renderer::New(geometry, shader);
232 Actor actor = Actor::New();
233 actor.AddRenderer(renderer);
234 actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
235 application.GetScene().Add(actor);
236 application.SendNotification();
237 application.Render(0);
239 Vector4 initialColor = Color::WHITE;
240 Property::Index colorIndex = shader.RegisterProperty("uFadeColor", initialColor);
242 TestGlAbstraction& gl = application.GetGlAbstraction();
244 application.SendNotification();
245 application.Render(0);
247 Vector4 actualValue(Vector4::ZERO);
248 DALI_TEST_CHECK(gl.GetUniformValue<Vector4>("uFadeColor", actualValue));
249 DALI_TEST_EQUALS(actualValue, initialColor, TEST_LOCATION);
252 Constraint constraint = Constraint::New<Vector4>(shader, colorIndex, TestConstraintNoBlue);
254 application.SendNotification();
255 application.Render(0);
257 // Expect no blue component in either buffer - yellow
258 DALI_TEST_CHECK(gl.GetUniformValue<Vector4>("uFadeColor", actualValue));
259 DALI_TEST_EQUALS(actualValue, Color::YELLOW, TEST_LOCATION);
261 application.Render(0);
262 DALI_TEST_CHECK(gl.GetUniformValue<Vector4>("uFadeColor", actualValue));
263 DALI_TEST_EQUALS(actualValue, Color::YELLOW, TEST_LOCATION);
265 shader.RemoveConstraints();
266 shader.SetProperty(colorIndex, Color::WHITE);
267 application.SendNotification();
268 application.Render(0);
270 DALI_TEST_CHECK(gl.GetUniformValue<Vector4>("uFadeColor", actualValue));
271 DALI_TEST_EQUALS(actualValue, Color::WHITE, TEST_LOCATION);
276 int UtcDaliShaderAnimatedProperty01(void)
278 TestApplication application;
280 tet_infoline("Test that a non-uniform shader property can be animated");
282 Shader shader = Shader::New(VertexSource, FragmentSource);
283 Geometry geometry = CreateQuadGeometry();
284 Renderer renderer = Renderer::New(geometry, shader);
286 Actor actor = Actor::New();
287 actor.AddRenderer(renderer);
288 actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
289 application.GetScene().Add(actor);
291 Vector4 initialColor = Color::WHITE;
292 Property::Index colorIndex = shader.RegisterProperty("uFadeColor", initialColor);
294 application.SendNotification();
295 application.Render(0);
296 DALI_TEST_EQUALS(shader.GetProperty<Vector4>(colorIndex), initialColor, TEST_LOCATION);
298 Animation animation = Animation::New(1.0f);
299 KeyFrames keyFrames = KeyFrames::New();
300 keyFrames.Add(0.0f, initialColor);
301 keyFrames.Add(1.0f, Color::TRANSPARENT);
302 animation.AnimateBetween(Property(shader, colorIndex), keyFrames);
305 application.SendNotification();
306 application.Render(500);
308 DALI_TEST_EQUALS(shader.GetCurrentProperty<Vector4>(colorIndex), Color::WHITE * 0.5f, TEST_LOCATION);
310 application.Render(500);
312 DALI_TEST_EQUALS(shader.GetCurrentProperty<Vector4>(colorIndex), Color::TRANSPARENT, TEST_LOCATION);
317 int UtcDaliShaderAnimatedProperty02(void)
319 TestApplication application;
321 tet_infoline("Test that a uniform map shader property can be animated");
323 Shader shader = Shader::New(VertexSource, FragmentSource);
324 Geometry geometry = CreateQuadGeometry();
325 Renderer renderer = Renderer::New(geometry, shader);
327 Actor actor = Actor::New();
328 actor.AddRenderer(renderer);
329 actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
330 application.GetScene().Add(actor);
331 application.SendNotification();
332 application.Render(0);
334 Vector4 initialColor = Color::WHITE;
335 Property::Index colorIndex = shader.RegisterProperty("uFadeColor", initialColor);
337 TestGlAbstraction& gl = application.GetGlAbstraction();
339 application.SendNotification();
340 application.Render(0);
342 Vector4 actualValue(Vector4::ZERO);
343 DALI_TEST_CHECK(gl.GetUniformValue<Vector4>("uFadeColor", actualValue));
344 DALI_TEST_EQUALS(actualValue, initialColor, TEST_LOCATION);
346 Animation animation = Animation::New(1.0f);
347 KeyFrames keyFrames = KeyFrames::New();
348 keyFrames.Add(0.0f, initialColor);
349 keyFrames.Add(1.0f, Color::TRANSPARENT);
350 animation.AnimateBetween(Property(shader, colorIndex), keyFrames);
353 application.SendNotification();
354 application.Render(500);
356 DALI_TEST_CHECK(gl.GetUniformValue<Vector4>("uFadeColor", actualValue));
357 DALI_TEST_EQUALS(actualValue, Color::WHITE * 0.5f, TEST_LOCATION);
359 application.Render(500);
360 DALI_TEST_CHECK(gl.GetUniformValue<Vector4>("uFadeColor", actualValue));
361 DALI_TEST_EQUALS(actualValue, Color::TRANSPARENT, TEST_LOCATION);
363 // change shader program
365 map["vertex"] = VertexSource;
366 map["fragment"] = FragmentSource;
367 map["hints"] = "MODIFIES_GEOMETRY";
368 shader.SetProperty(Shader::Property::PROGRAM, Property::Value(map));
369 application.SendNotification();
370 application.Render(100);
372 // register another custom property as well
373 Property::Index customIndex = shader.RegisterProperty("uCustom3", Vector3(1, 2, 3));
374 DALI_TEST_EQUALS(shader.GetProperty<Vector3>(customIndex), Vector3(1, 2, 3), TEST_LOCATION);
376 application.SendNotification();
377 application.Render(100);
379 DALI_TEST_CHECK(gl.GetUniformValue<Vector4>("uFadeColor", actualValue));
380 DALI_TEST_EQUALS(actualValue, Color::TRANSPARENT, TEST_LOCATION);
383 DALI_TEST_CHECK(gl.GetUniformValue<Vector3>("uCustom3", customValue));
384 DALI_TEST_EQUALS(customValue, Vector3(1, 2, 3), TEST_LOCATION);
388 int UtcDaliShaderProgramProperty(void)
390 TestApplication application;
392 tet_infoline("Test get/set progam property");
394 Shader shader = Shader::New("", "");
395 std::string hintSet = "MODIFIES_GEOMETRY";
398 map["vertex"] = VertexSource;
399 map["fragment"] = FragmentSource;
400 map["hints"] = hintSet;
402 shader.SetProperty(Shader::Property::PROGRAM, Property::Value(map));
403 // register a custom property as well
404 Property::Index customIndex = shader.RegisterProperty("custom", Vector3(1, 2, 3));
405 DALI_TEST_EQUALS(shader.GetProperty<Vector3>(customIndex), Vector3(1, 2, 3), TEST_LOCATION);
407 Property::Value value = shader.GetProperty(Shader::Property::PROGRAM);
408 DALI_TEST_CHECK(value.GetType() == Property::MAP);
409 const Property::Map* outMap = value.GetMap();
411 std::string v = (*outMap)["vertex"].Get<std::string>();
412 std::string f = (*outMap)["fragment"].Get<std::string>();
413 std::string h = (*outMap)["hints"].Get<std::string>();
415 DALI_TEST_CHECK(v == VertexSource);
416 DALI_TEST_CHECK(f == FragmentSource);
417 DALI_TEST_CHECK(h == hintSet);
419 value = shader.GetCurrentProperty(Shader::Property::PROGRAM);
420 DALI_TEST_CHECK(value.GetType() == Property::MAP);
421 outMap = value.GetMap();
422 // check that changing the shader did not cause us to loose custom property
423 DALI_TEST_EQUALS(shader.GetProperty<Vector3>(customIndex), Vector3(1, 2, 3), TEST_LOCATION);
424 using Dali::Animation;
425 Animation animation = Animation::New(0.1f);
426 animation.AnimateTo(Property(shader, customIndex), Vector3(4, 5, 6));
428 application.SendNotification();
429 application.Render(100);
430 DALI_TEST_EQUALS(shader.GetProperty<Vector3>(customIndex), Vector3(4, 5, 6), TEST_LOCATION);
432 v = (*outMap)["vertex"].Get<std::string>();
433 f = (*outMap)["fragment"].Get<std::string>();
434 h = (*outMap)["hints"].Get<std::string>();
436 DALI_TEST_CHECK(v == VertexSource);
437 DALI_TEST_CHECK(f == FragmentSource);
438 DALI_TEST_CHECK(h == hintSet);
442 hintSet = "OUTPUT_IS_TRANSPARENT,MODIFIES_GEOMETRY";
443 map["hints"] = hintSet;
444 shader.SetProperty(Shader::Property::PROGRAM, Property::Value(map));
445 value = shader.GetProperty(Shader::Property::PROGRAM);
446 hintGot = (*value.GetMap())["hints"].Get<std::string>();
447 DALI_TEST_CHECK(hintGot == hintSet);
449 hintSet = "OUTPUT_IS_TRANSPARENT";
450 map["hints"] = hintSet;
451 shader.SetProperty(Shader::Property::PROGRAM, Property::Value(map));
452 value = shader.GetProperty(Shader::Property::PROGRAM);
453 hintGot = (*value.GetMap())["hints"].Get<std::string>();
454 DALI_TEST_CHECK(hintGot == hintSet);
457 map["hints"] = hintSet;
458 shader.SetProperty(Shader::Property::PROGRAM, Property::Value(map));
459 value = shader.GetProperty(Shader::Property::PROGRAM);
460 hintGot = (*value.GetMap())["hints"].Get<std::string>();
461 DALI_TEST_CHECK(hintGot == hintSet);
464 map["hints"] = hintSet;
465 shader.SetProperty(Shader::Property::PROGRAM, Property::Value(map));
466 value = shader.GetProperty(Shader::Property::PROGRAM);
467 hintGot = (*value.GetMap())["hints"].Get<std::string>();
468 DALI_TEST_CHECK(hintGot == "NONE");