278af127312afee3fc4a2577b5a883b3dc3a64eb
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-Shader.cpp
1 /*
2  * Copyright (c) 2020 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 #include <iostream>
19
20 #include <stdlib.h>
21 #include <dali/public-api/dali-core.h>
22 #include <dali-test-suite-utils.h>
23 #include <mesh-builder.h>
24
25 using namespace Dali;
26
27 void utc_dali_shader_startup(void)
28 {
29   test_return_value = TET_UNDEF;
30 }
31
32 void utc_dali_shader_cleanup(void)
33 {
34   test_return_value = TET_PASS;
35 }
36
37 namespace
38 {
39
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";
43
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";
47
48
49 void TestConstraintNoBlue( Vector4& current, const PropertyInputContainer& inputs )
50 {
51   current.b = 0.0f;
52 }
53
54
55 } // anon namespace
56
57
58 int UtcDaliShaderMethodNew01(void)
59 {
60   TestApplication application;
61
62   Shader shader = Shader::New( VertexSource, FragmentSource );
63   DALI_TEST_EQUALS((bool)shader, true, TEST_LOCATION);
64   END_TEST;
65 }
66
67 int UtcDaliShaderMethodNew02(void)
68 {
69   TestApplication application;
70
71   Shader shader;
72   DALI_TEST_EQUALS((bool)shader, false, TEST_LOCATION);
73   END_TEST;
74 }
75
76 int UtcDaliShaderAssignmentOperator(void)
77 {
78   TestApplication application;
79
80   Shader shader1 = Shader::New(VertexSource, FragmentSource);
81
82   Shader shader2;
83
84   DALI_TEST_CHECK(!(shader1 == shader2));
85
86   shader2 = shader1;
87
88   DALI_TEST_CHECK(shader1 == shader2);
89
90   shader2 = Shader::New(VertexSource, FragmentSource);;
91
92   DALI_TEST_CHECK(!(shader1 == shader2));
93
94   END_TEST;
95 }
96
97 int UtcDaliShaderMoveConstructor(void)
98 {
99   TestApplication application;
100
101   Shader shader = Shader::New(VertexSource, FragmentSource);
102   DALI_TEST_CHECK( shader );
103   DALI_TEST_EQUALS( 1, shader.GetBaseObject().ReferenceCount(), TEST_LOCATION );
104
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 );
109
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 );
115
116   END_TEST;
117 }
118
119 int UtcDaliShaderMoveAssignment(void)
120 {
121   TestApplication application;
122
123   Shader shader = Shader::New(VertexSource, FragmentSource);
124   DALI_TEST_CHECK( shader );
125   DALI_TEST_EQUALS( 1, shader.GetBaseObject().ReferenceCount(), TEST_LOCATION );
126
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 );
131
132   Shader move;
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 );
138
139   END_TEST;
140 }
141
142 int UtcDaliShaderDownCast01(void)
143 {
144   TestApplication application;
145
146   Shader shader = Shader::New(VertexSource, FragmentSource);
147
148   BaseHandle handle(shader);
149   Shader shader2 = Shader::DownCast(handle);
150   DALI_TEST_EQUALS( (bool)shader2, true, TEST_LOCATION );
151   END_TEST;
152 }
153
154 int UtcDaliShaderDownCast02(void)
155 {
156   TestApplication application;
157
158   Handle handle = Handle::New(); // Create a custom object
159   Shader shader = Shader::DownCast(handle);
160   DALI_TEST_EQUALS( (bool)shader, false, TEST_LOCATION );
161   END_TEST;
162 }
163
164 int UtcDaliShaderDefaultProperties(void)
165 {
166   TestApplication application;
167 // from shader-impl.cpp
168 // DALI_PROPERTY( "program",       MAP,     true,     false,     false,  Dali::Shader::Property::PROGRAM )
169
170   Shader shader = Shader::New(VertexSource, FragmentSource);
171   DALI_TEST_EQUALS( shader.GetPropertyCount(), 1, TEST_LOCATION );
172
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 );
179
180   END_TEST;
181 }
182
183 int UtcDaliShaderConstraint01(void)
184 {
185   TestApplication application;
186
187   tet_infoline("Test that a non-uniform shader property can be constrained");
188
189   Shader shader = Shader::New(VertexSource, FragmentSource);
190   Geometry geometry = CreateQuadGeometry();
191   Renderer renderer = Renderer::New( geometry, shader );
192
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);
197
198   Vector4 initialColor = Color::WHITE;
199   Property::Index colorIndex = shader.RegisterProperty( "uFadeColor", initialColor );
200
201   application.SendNotification();
202   application.Render(0);
203   DALI_TEST_EQUALS( shader.GetProperty<Vector4>(colorIndex), initialColor, TEST_LOCATION );
204
205   // Apply constraint
206   Constraint constraint = Constraint::New<Vector4>( shader, colorIndex, TestConstraintNoBlue );
207   constraint.Apply();
208   application.SendNotification();
209   application.Render(0);
210
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 );
215
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 );
221
222   END_TEST;
223 }
224
225 int UtcDaliShaderConstraint02(void)
226 {
227   TestApplication application;
228
229   tet_infoline("Test that a uniform map shader property can be constrained");
230
231   Shader shader = Shader::New(VertexSource, FragmentSource);
232   Geometry geometry = CreateQuadGeometry();
233   Renderer renderer = Renderer::New( geometry, shader );
234
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);
241
242   Vector4 initialColor = Color::WHITE;
243   Property::Index colorIndex = shader.RegisterProperty( "uFadeColor", initialColor );
244
245   TestGlAbstraction& gl = application.GetGlAbstraction();
246
247   application.SendNotification();
248   application.Render(0);
249
250   Vector4 actualValue(Vector4::ZERO);
251   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
252   DALI_TEST_EQUALS( actualValue, initialColor, TEST_LOCATION );
253
254   // Apply constraint
255   Constraint constraint = Constraint::New<Vector4>( shader, colorIndex, TestConstraintNoBlue );
256   constraint.Apply();
257   application.SendNotification();
258   application.Render(0);
259
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 );
263
264   application.Render(0);
265   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
266   DALI_TEST_EQUALS( actualValue, Color::YELLOW, TEST_LOCATION );
267
268   shader.RemoveConstraints();
269   shader.SetProperty(colorIndex, Color::WHITE );
270   application.SendNotification();
271   application.Render(0);
272
273   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
274   DALI_TEST_EQUALS( actualValue, Color::WHITE, TEST_LOCATION );
275
276   END_TEST;
277 }
278
279 int UtcDaliShaderAnimatedProperty01(void)
280 {
281   TestApplication application;
282
283   tet_infoline("Test that a non-uniform shader property can be animated");
284
285   Shader shader = Shader::New(VertexSource, FragmentSource);
286   Geometry geometry = CreateQuadGeometry();
287   Renderer renderer = Renderer::New( geometry, shader );
288
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);
293
294   Vector4 initialColor = Color::WHITE;
295   Property::Index colorIndex = shader.RegisterProperty( "uFadeColor", initialColor );
296
297   application.SendNotification();
298   application.Render(0);
299   DALI_TEST_EQUALS( shader.GetProperty<Vector4>(colorIndex), initialColor, TEST_LOCATION );
300
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 );
306   animation.Play();
307
308   application.SendNotification();
309   application.Render(500);
310
311   DALI_TEST_EQUALS( shader.GetCurrentProperty< Vector4 >( colorIndex ), Color::WHITE * 0.5f, TEST_LOCATION );
312
313   application.Render(500);
314
315   DALI_TEST_EQUALS( shader.GetCurrentProperty< Vector4 >( colorIndex ), Color::TRANSPARENT, TEST_LOCATION );
316
317   END_TEST;
318 }
319
320 int UtcDaliShaderAnimatedProperty02(void)
321 {
322   TestApplication application;
323
324   tet_infoline("Test that a uniform map shader property can be animated");
325
326   Shader shader = Shader::New(VertexSource, FragmentSource);
327   Geometry geometry = CreateQuadGeometry();
328   Renderer renderer = Renderer::New( geometry, shader );
329
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);
336
337   Vector4 initialColor = Color::WHITE;
338   Property::Index colorIndex = shader.RegisterProperty( "uFadeColor", initialColor );
339
340   TestGlAbstraction& gl = application.GetGlAbstraction();
341
342   application.SendNotification();
343   application.Render(0);
344
345   Vector4 actualValue(Vector4::ZERO);
346   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
347   DALI_TEST_EQUALS( actualValue, initialColor, TEST_LOCATION );
348
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 );
354   animation.Play();
355
356   application.SendNotification();
357   application.Render(500);
358
359   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
360   DALI_TEST_EQUALS( actualValue, Color::WHITE * 0.5f, TEST_LOCATION );
361
362   application.Render(500);
363   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
364   DALI_TEST_EQUALS( actualValue, Color::TRANSPARENT, TEST_LOCATION );
365
366   // change shader program
367   Property::Map map;
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);
374
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 );
378
379   application.SendNotification();
380   application.Render(100);
381
382   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
383   DALI_TEST_EQUALS( actualValue, Color::TRANSPARENT, TEST_LOCATION );
384
385   Vector3 customValue;
386   DALI_TEST_CHECK( gl.GetUniformValue<Vector3>( "uCustom", customValue ) );
387   DALI_TEST_EQUALS( customValue, Vector3(1,2,3), TEST_LOCATION );
388   END_TEST;
389 }
390
391 int UtcDaliShaderProgramProperty(void)
392 {
393   TestApplication application;
394
395   tet_infoline("Test get/set progam property");
396
397   Shader shader = Shader::New("", "");
398   std::string hintSet = "MODIFIES_GEOMETRY";
399
400   Property::Map map;
401   map["vertex"] = VertexSource;
402   map["fragment"] = FragmentSource;
403   map["hints"] = hintSet;
404
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 );
409
410   Property::Value value = shader.GetProperty(Shader::Property::PROGRAM);
411   DALI_TEST_CHECK( value.GetType() == Property::MAP);
412   const Property::Map* outMap = value.GetMap();
413
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>();
417
418   DALI_TEST_CHECK( v == VertexSource );
419   DALI_TEST_CHECK( f == FragmentSource );
420   DALI_TEST_CHECK( h == hintSet );
421
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) );
430   animation.Play();
431   application.SendNotification();
432   application.Render(100);
433   DALI_TEST_EQUALS( shader.GetProperty<Vector3>( customIndex ), Vector3(4,5,6), TEST_LOCATION );
434
435   v = (*outMap)["vertex"].Get<std::string>();
436   f = (*outMap)["fragment"].Get<std::string>();
437   h = (*outMap)["hints"].Get<std::string>();
438
439   DALI_TEST_CHECK( v == VertexSource );
440   DALI_TEST_CHECK( f == FragmentSource );
441   DALI_TEST_CHECK( h == hintSet );
442
443   std::string hintGot;
444
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 );
451
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 );
458
459   hintSet = "NONE";
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 );
465
466   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" );
472
473   END_TEST;
474 }