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.
21 #include <dali/public-api/dali-core.h>
22 #include <dali-test-suite-utils.h>
23 #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;
40 static const char* VertexSource =
41 "This is a custom vertex shader\n"
42 "made on purpose to look nothing like a normal vertex shader inside dali\n";
44 static const char* FragmentSource =
45 "This is a custom fragment shader\n"
46 "made on purpose to look nothing like a normal fragment shader inside dali\n";
49 void TestConstraintNoBlue( Vector4& current, const PropertyInputContainer& inputs )
58 int UtcDaliShaderMethodNew01(void)
60 TestApplication application;
62 Shader shader = Shader::New( VertexSource, FragmentSource );
63 DALI_TEST_EQUALS((bool)shader, true, TEST_LOCATION);
67 int UtcDaliShaderMethodNew02(void)
69 TestApplication application;
72 DALI_TEST_EQUALS((bool)shader, false, TEST_LOCATION);
76 int UtcDaliShaderAssignmentOperator(void)
78 TestApplication application;
80 Shader shader1 = Shader::New(VertexSource, FragmentSource);
84 DALI_TEST_CHECK(!(shader1 == shader2));
88 DALI_TEST_CHECK(shader1 == shader2);
90 shader2 = Shader::New(VertexSource, FragmentSource);;
92 DALI_TEST_CHECK(!(shader1 == shader2));
97 int UtcDaliShaderMoveConstructor(void)
99 TestApplication application;
101 Shader shader = Shader::New(VertexSource, FragmentSource);
102 DALI_TEST_CHECK( shader );
103 DALI_TEST_EQUALS( 1, shader.GetBaseObject().ReferenceCount(), TEST_LOCATION );
105 // Register a custom property
106 Vector2 vec( 1.0f, 2.0f );
107 Property::Index customIndex = shader.RegisterProperty( "custom", vec );
108 DALI_TEST_EQUALS( shader.GetProperty<Vector2>( customIndex ), vec, TEST_LOCATION );
110 Shader move = std::move( shader );
111 DALI_TEST_CHECK( move );
112 DALI_TEST_EQUALS( 1, move.GetBaseObject().ReferenceCount(), TEST_LOCATION );
113 DALI_TEST_EQUALS( move.GetProperty<Vector2>( customIndex ), vec, TEST_LOCATION );
114 DALI_TEST_CHECK( !shader );
119 int UtcDaliShaderMoveAssignment(void)
121 TestApplication application;
123 Shader shader = Shader::New(VertexSource, FragmentSource);
124 DALI_TEST_CHECK( shader );
125 DALI_TEST_EQUALS( 1, shader.GetBaseObject().ReferenceCount(), TEST_LOCATION );
127 // Register a custom property
128 Vector2 vec( 1.0f, 2.0f );
129 Property::Index customIndex = shader.RegisterProperty( "custom", vec );
130 DALI_TEST_EQUALS( shader.GetProperty<Vector2>( customIndex ), vec, TEST_LOCATION );
133 move = std::move( shader );
134 DALI_TEST_CHECK( move );
135 DALI_TEST_EQUALS( 1, move.GetBaseObject().ReferenceCount(), TEST_LOCATION );
136 DALI_TEST_EQUALS( move.GetProperty<Vector2>( customIndex ), vec, TEST_LOCATION );
137 DALI_TEST_CHECK( !shader );
142 int UtcDaliShaderDownCast01(void)
144 TestApplication application;
146 Shader shader = Shader::New(VertexSource, FragmentSource);
148 BaseHandle handle(shader);
149 Shader shader2 = Shader::DownCast(handle);
150 DALI_TEST_EQUALS( (bool)shader2, true, TEST_LOCATION );
154 int UtcDaliShaderDownCast02(void)
156 TestApplication application;
158 Handle handle = Handle::New(); // Create a custom object
159 Shader shader = Shader::DownCast(handle);
160 DALI_TEST_EQUALS( (bool)shader, false, TEST_LOCATION );
164 int UtcDaliShaderDefaultProperties(void)
166 TestApplication application;
167 // from shader-impl.cpp
168 // DALI_PROPERTY( "program", MAP, true, false, false, Dali::Shader::Property::PROGRAM )
170 Shader shader = Shader::New(VertexSource, FragmentSource);
171 DALI_TEST_EQUALS( shader.GetPropertyCount(), 1, TEST_LOCATION );
173 DALI_TEST_EQUALS( shader.GetPropertyName( Shader::Property::PROGRAM ), "program", TEST_LOCATION );
174 DALI_TEST_EQUALS( shader.GetPropertyIndex( "program" ), (Property::Index)Shader::Property::PROGRAM, TEST_LOCATION );
175 DALI_TEST_EQUALS( shader.GetPropertyType( Shader::Property::PROGRAM ), Property::MAP, TEST_LOCATION );
176 DALI_TEST_EQUALS( shader.IsPropertyWritable( Shader::Property::PROGRAM ), true, TEST_LOCATION );
177 DALI_TEST_EQUALS( shader.IsPropertyAnimatable( Shader::Property::PROGRAM ), false, TEST_LOCATION );
178 DALI_TEST_EQUALS( shader.IsPropertyAConstraintInput( Shader::Property::PROGRAM ), false, TEST_LOCATION );
183 int UtcDaliShaderConstraint01(void)
185 TestApplication application;
187 tet_infoline("Test that a non-uniform shader property can be constrained");
189 Shader shader = Shader::New(VertexSource, FragmentSource);
190 Geometry geometry = CreateQuadGeometry();
191 Renderer renderer = Renderer::New( geometry, shader );
193 Actor actor = Actor::New();
194 actor.AddRenderer(renderer);
195 actor.SetProperty( Actor::Property::SIZE, Vector2( 400.0f, 400.0f ) );
196 application.GetScene().Add(actor);
198 Vector4 initialColor = Color::WHITE;
199 Property::Index colorIndex = shader.RegisterProperty( "uFadeColor", initialColor );
201 application.SendNotification();
202 application.Render(0);
203 DALI_TEST_EQUALS( shader.GetProperty<Vector4>(colorIndex), initialColor, TEST_LOCATION );
206 Constraint constraint = Constraint::New<Vector4>( shader, colorIndex, TestConstraintNoBlue );
208 application.SendNotification();
209 application.Render(0);
211 // Expect no blue component in either buffer - yellow
212 DALI_TEST_EQUALS( shader.GetCurrentProperty< Vector4 >( colorIndex ), Color::YELLOW, TEST_LOCATION );
213 application.Render(0);
214 DALI_TEST_EQUALS( shader.GetCurrentProperty< Vector4 >( colorIndex ), Color::YELLOW, TEST_LOCATION );
216 shader.RemoveConstraints();
217 shader.SetProperty(colorIndex, Color::WHITE );
218 application.SendNotification();
219 application.Render(0);
220 DALI_TEST_EQUALS( shader.GetCurrentProperty< Vector4 >( colorIndex ), Color::WHITE, TEST_LOCATION );
225 int UtcDaliShaderConstraint02(void)
227 TestApplication application;
229 tet_infoline("Test that a uniform map shader property can be constrained");
231 Shader shader = Shader::New(VertexSource, FragmentSource);
232 Geometry geometry = CreateQuadGeometry();
233 Renderer renderer = Renderer::New( geometry, shader );
235 Actor actor = Actor::New();
236 actor.AddRenderer(renderer);
237 actor.SetProperty( Actor::Property::SIZE, Vector2( 400.0f, 400.0f ) );
238 application.GetScene().Add(actor);
239 application.SendNotification();
240 application.Render(0);
242 Vector4 initialColor = Color::WHITE;
243 Property::Index colorIndex = shader.RegisterProperty( "uFadeColor", initialColor );
245 TestGlAbstraction& gl = application.GetGlAbstraction();
247 application.SendNotification();
248 application.Render(0);
250 Vector4 actualValue(Vector4::ZERO);
251 DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
252 DALI_TEST_EQUALS( actualValue, initialColor, TEST_LOCATION );
255 Constraint constraint = Constraint::New<Vector4>( shader, colorIndex, TestConstraintNoBlue );
257 application.SendNotification();
258 application.Render(0);
260 // Expect no blue component in either buffer - yellow
261 DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
262 DALI_TEST_EQUALS( actualValue, Color::YELLOW, TEST_LOCATION );
264 application.Render(0);
265 DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
266 DALI_TEST_EQUALS( actualValue, Color::YELLOW, TEST_LOCATION );
268 shader.RemoveConstraints();
269 shader.SetProperty(colorIndex, Color::WHITE );
270 application.SendNotification();
271 application.Render(0);
273 DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
274 DALI_TEST_EQUALS( actualValue, Color::WHITE, TEST_LOCATION );
279 int UtcDaliShaderAnimatedProperty01(void)
281 TestApplication application;
283 tet_infoline("Test that a non-uniform shader property can be animated");
285 Shader shader = Shader::New(VertexSource, FragmentSource);
286 Geometry geometry = CreateQuadGeometry();
287 Renderer renderer = Renderer::New( geometry, shader );
289 Actor actor = Actor::New();
290 actor.AddRenderer(renderer);
291 actor.SetProperty( Actor::Property::SIZE, Vector2( 400.0f, 400.0f ) );
292 application.GetScene().Add(actor);
294 Vector4 initialColor = Color::WHITE;
295 Property::Index colorIndex = shader.RegisterProperty( "uFadeColor", initialColor );
297 application.SendNotification();
298 application.Render(0);
299 DALI_TEST_EQUALS( shader.GetProperty<Vector4>(colorIndex), initialColor, TEST_LOCATION );
301 Animation animation = Animation::New(1.0f);
302 KeyFrames keyFrames = KeyFrames::New();
303 keyFrames.Add(0.0f, initialColor);
304 keyFrames.Add(1.0f, Color::TRANSPARENT);
305 animation.AnimateBetween( Property( shader, colorIndex ), keyFrames );
308 application.SendNotification();
309 application.Render(500);
311 DALI_TEST_EQUALS( shader.GetCurrentProperty< Vector4 >( colorIndex ), Color::WHITE * 0.5f, TEST_LOCATION );
313 application.Render(500);
315 DALI_TEST_EQUALS( shader.GetCurrentProperty< Vector4 >( colorIndex ), Color::TRANSPARENT, TEST_LOCATION );
320 int UtcDaliShaderAnimatedProperty02(void)
322 TestApplication application;
324 tet_infoline("Test that a uniform map shader property can be animated");
326 Shader shader = Shader::New(VertexSource, FragmentSource);
327 Geometry geometry = CreateQuadGeometry();
328 Renderer renderer = Renderer::New( geometry, shader );
330 Actor actor = Actor::New();
331 actor.AddRenderer(renderer);
332 actor.SetProperty( Actor::Property::SIZE, Vector2( 400.0f, 400.0f ) );
333 application.GetScene().Add(actor);
334 application.SendNotification();
335 application.Render(0);
337 Vector4 initialColor = Color::WHITE;
338 Property::Index colorIndex = shader.RegisterProperty( "uFadeColor", initialColor );
340 TestGlAbstraction& gl = application.GetGlAbstraction();
342 application.SendNotification();
343 application.Render(0);
345 Vector4 actualValue(Vector4::ZERO);
346 DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
347 DALI_TEST_EQUALS( actualValue, initialColor, TEST_LOCATION );
349 Animation animation = Animation::New(1.0f);
350 KeyFrames keyFrames = KeyFrames::New();
351 keyFrames.Add(0.0f, initialColor);
352 keyFrames.Add(1.0f, Color::TRANSPARENT);
353 animation.AnimateBetween( Property( shader, colorIndex ), keyFrames );
356 application.SendNotification();
357 application.Render(500);
359 DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
360 DALI_TEST_EQUALS( actualValue, Color::WHITE * 0.5f, TEST_LOCATION );
362 application.Render(500);
363 DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
364 DALI_TEST_EQUALS( actualValue, Color::TRANSPARENT, TEST_LOCATION );
366 // change shader program
368 map["vertex"] = VertexSource;
369 map["fragment"] = FragmentSource;
370 map["hints"] = "MODIFIES_GEOMETRY";
371 shader.SetProperty( Shader::Property::PROGRAM, Property::Value(map) );
372 application.SendNotification();
373 application.Render(100);
375 // register another custom property as well
376 Property::Index customIndex = shader.RegisterProperty( "uCustom", Vector3(1,2,3) );
377 DALI_TEST_EQUALS( shader.GetProperty<Vector3>( customIndex ), Vector3(1,2,3), TEST_LOCATION );
379 application.SendNotification();
380 application.Render(100);
382 DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
383 DALI_TEST_EQUALS( actualValue, Color::TRANSPARENT, TEST_LOCATION );
386 DALI_TEST_CHECK( gl.GetUniformValue<Vector3>( "uCustom", customValue ) );
387 DALI_TEST_EQUALS( customValue, Vector3(1,2,3), TEST_LOCATION );
391 int UtcDaliShaderProgramProperty(void)
393 TestApplication application;
395 tet_infoline("Test get/set progam property");
397 Shader shader = Shader::New("", "");
398 std::string hintSet = "MODIFIES_GEOMETRY";
401 map["vertex"] = VertexSource;
402 map["fragment"] = FragmentSource;
403 map["hints"] = hintSet;
405 shader.SetProperty( Shader::Property::PROGRAM, Property::Value(map) );
406 // register a custom property as well
407 Property::Index customIndex = shader.RegisterProperty( "custom", Vector3(1,2,3) );
408 DALI_TEST_EQUALS( shader.GetProperty<Vector3>( customIndex ), Vector3(1,2,3), TEST_LOCATION );
410 Property::Value value = shader.GetProperty(Shader::Property::PROGRAM);
411 DALI_TEST_CHECK( value.GetType() == Property::MAP);
412 const Property::Map* outMap = value.GetMap();
414 std::string v = (*outMap)["vertex"].Get<std::string>();
415 std::string f = (*outMap)["fragment"].Get<std::string>();
416 std::string h = (*outMap)["hints"].Get<std::string>();
418 DALI_TEST_CHECK( v == VertexSource );
419 DALI_TEST_CHECK( f == FragmentSource );
420 DALI_TEST_CHECK( h == hintSet );
422 value = shader.GetCurrentProperty( Shader::Property::PROGRAM );
423 DALI_TEST_CHECK( value.GetType() == Property::MAP);
424 outMap = value.GetMap();
425 // check that changing the shader did not cause us to loose custom property
426 DALI_TEST_EQUALS( shader.GetProperty<Vector3>( customIndex ), Vector3(1,2,3), TEST_LOCATION );
427 using Dali::Animation;
428 Animation animation = Animation::New( 0.1f );
429 animation.AnimateTo( Property( shader, customIndex ), Vector3(4,5,6) );
431 application.SendNotification();
432 application.Render(100);
433 DALI_TEST_EQUALS( shader.GetProperty<Vector3>( customIndex ), Vector3(4,5,6), TEST_LOCATION );
435 v = (*outMap)["vertex"].Get<std::string>();
436 f = (*outMap)["fragment"].Get<std::string>();
437 h = (*outMap)["hints"].Get<std::string>();
439 DALI_TEST_CHECK( v == VertexSource );
440 DALI_TEST_CHECK( f == FragmentSource );
441 DALI_TEST_CHECK( h == hintSet );
445 hintSet = "OUTPUT_IS_TRANSPARENT,MODIFIES_GEOMETRY";
446 map["hints"] = hintSet;
447 shader.SetProperty( Shader::Property::PROGRAM, Property::Value(map) );
448 value = shader.GetProperty(Shader::Property::PROGRAM);
449 hintGot = (*value.GetMap())["hints"].Get<std::string>();
450 DALI_TEST_CHECK( hintGot == hintSet );
452 hintSet = "OUTPUT_IS_TRANSPARENT";
453 map["hints"] = hintSet;
454 shader.SetProperty( Shader::Property::PROGRAM, Property::Value(map) );
455 value = shader.GetProperty(Shader::Property::PROGRAM);
456 hintGot = (*value.GetMap())["hints"].Get<std::string>();
457 DALI_TEST_CHECK( hintGot == hintSet );
460 map["hints"] = hintSet;
461 shader.SetProperty( Shader::Property::PROGRAM, Property::Value(map) );
462 value = shader.GetProperty(Shader::Property::PROGRAM);
463 hintGot = (*value.GetMap())["hints"].Get<std::string>();
464 DALI_TEST_CHECK( hintGot == hintSet );
467 map["hints"] = hintSet;
468 shader.SetProperty( Shader::Property::PROGRAM, Property::Value(map) );
469 value = shader.GetProperty(Shader::Property::PROGRAM);
470 hintGot = (*value.GetMap())["hints"].Get<std::string>();
471 DALI_TEST_CHECK( hintGot == "NONE" );