Refactor SceneGraphProperty handling code in event side to make RegisterProperty...
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-Shader.cpp
1 /*
2  * Copyright (c) 2017 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 UtcDaliShaderDownCast01(void)
98 {
99   TestApplication application;
100
101   Shader shader = Shader::New(VertexSource, FragmentSource);
102
103   BaseHandle handle(shader);
104   Shader shader2 = Shader::DownCast(handle);
105   DALI_TEST_EQUALS( (bool)shader2, true, TEST_LOCATION );
106   END_TEST;
107 }
108
109 int UtcDaliShaderDownCast02(void)
110 {
111   TestApplication application;
112
113   Handle handle = Handle::New(); // Create a custom object
114   Shader shader = Shader::DownCast(handle);
115   DALI_TEST_EQUALS( (bool)shader, false, TEST_LOCATION );
116   END_TEST;
117 }
118
119 int UtcDaliShaderDefaultProperties(void)
120 {
121   TestApplication application;
122 // from shader-impl.cpp
123 // DALI_PROPERTY( "program",       MAP,     true,     false,     false,  Dali::Shader::Property::PROGRAM )
124
125   Shader shader = Shader::New(VertexSource, FragmentSource);
126   DALI_TEST_EQUALS( shader.GetPropertyCount(), 1, TEST_LOCATION );
127
128   DALI_TEST_EQUALS( shader.GetPropertyName( Shader::Property::PROGRAM ), "program", TEST_LOCATION );
129   DALI_TEST_EQUALS( shader.GetPropertyIndex( "program" ), (Property::Index)Shader::Property::PROGRAM, TEST_LOCATION );
130   DALI_TEST_EQUALS( shader.GetPropertyType( Shader::Property::PROGRAM ), Property::MAP, TEST_LOCATION );
131   DALI_TEST_EQUALS( shader.IsPropertyWritable( Shader::Property::PROGRAM ), true, TEST_LOCATION );
132   DALI_TEST_EQUALS( shader.IsPropertyAnimatable( Shader::Property::PROGRAM ), false, TEST_LOCATION );
133   DALI_TEST_EQUALS( shader.IsPropertyAConstraintInput( Shader::Property::PROGRAM ), false, TEST_LOCATION );
134
135   END_TEST;
136 }
137
138 int UtcDaliShaderConstraint01(void)
139 {
140   TestApplication application;
141
142   tet_infoline("Test that a non-uniform shader property can be constrained");
143
144   Shader shader = Shader::New(VertexSource, FragmentSource);
145   Geometry geometry = CreateQuadGeometry();
146   Renderer renderer = Renderer::New( geometry, shader );
147
148   Actor actor = Actor::New();
149   actor.AddRenderer(renderer);
150   actor.SetSize(400, 400);
151   Stage::GetCurrent().Add(actor);
152
153   Vector4 initialColor = Color::WHITE;
154   Property::Index colorIndex = shader.RegisterProperty( "uFadeColor", initialColor );
155
156   application.SendNotification();
157   application.Render(0);
158   DALI_TEST_EQUALS( shader.GetProperty<Vector4>(colorIndex), initialColor, TEST_LOCATION );
159
160   // Apply constraint
161   Constraint constraint = Constraint::New<Vector4>( shader, colorIndex, TestConstraintNoBlue );
162   constraint.Apply();
163   application.SendNotification();
164   application.Render(0);
165
166   // Expect no blue component in either buffer - yellow
167   DALI_TEST_EQUALS( shader.GetCurrentProperty< Vector4 >( colorIndex ), Color::YELLOW, TEST_LOCATION );
168   application.Render(0);
169   DALI_TEST_EQUALS( shader.GetCurrentProperty< Vector4 >( colorIndex ), Color::YELLOW, TEST_LOCATION );
170
171   shader.RemoveConstraints();
172   shader.SetProperty(colorIndex, Color::WHITE );
173   application.SendNotification();
174   application.Render(0);
175   DALI_TEST_EQUALS( shader.GetCurrentProperty< Vector4 >( colorIndex ), Color::WHITE, TEST_LOCATION );
176
177   END_TEST;
178 }
179
180 int UtcDaliShaderConstraint02(void)
181 {
182   TestApplication application;
183
184   tet_infoline("Test that a uniform map shader property can be constrained");
185
186   Shader shader = Shader::New(VertexSource, FragmentSource);
187   Geometry geometry = CreateQuadGeometry();
188   Renderer renderer = Renderer::New( geometry, shader );
189
190   Actor actor = Actor::New();
191   actor.AddRenderer(renderer);
192   actor.SetSize(400, 400);
193   Stage::GetCurrent().Add(actor);
194   application.SendNotification();
195   application.Render(0);
196
197   Vector4 initialColor = Color::WHITE;
198   Property::Index colorIndex = shader.RegisterProperty( "uFadeColor", initialColor );
199
200   TestGlAbstraction& gl = application.GetGlAbstraction();
201
202   application.SendNotification();
203   application.Render(0);
204
205   Vector4 actualValue(Vector4::ZERO);
206   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
207   DALI_TEST_EQUALS( actualValue, initialColor, TEST_LOCATION );
208
209   // Apply constraint
210   Constraint constraint = Constraint::New<Vector4>( shader, colorIndex, TestConstraintNoBlue );
211   constraint.Apply();
212   application.SendNotification();
213   application.Render(0);
214
215    // Expect no blue component in either buffer - yellow
216   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
217   DALI_TEST_EQUALS( actualValue, Color::YELLOW, TEST_LOCATION );
218
219   application.Render(0);
220   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
221   DALI_TEST_EQUALS( actualValue, Color::YELLOW, TEST_LOCATION );
222
223   shader.RemoveConstraints();
224   shader.SetProperty(colorIndex, Color::WHITE );
225   application.SendNotification();
226   application.Render(0);
227
228   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
229   DALI_TEST_EQUALS( actualValue, Color::WHITE, TEST_LOCATION );
230
231   END_TEST;
232 }
233
234 int UtcDaliShaderAnimatedProperty01(void)
235 {
236   TestApplication application;
237
238   tet_infoline("Test that a non-uniform shader property can be animated");
239
240   Shader shader = Shader::New(VertexSource, FragmentSource);
241   Geometry geometry = CreateQuadGeometry();
242   Renderer renderer = Renderer::New( geometry, shader );
243
244   Actor actor = Actor::New();
245   actor.AddRenderer(renderer);
246   actor.SetSize(400, 400);
247   Stage::GetCurrent().Add(actor);
248
249   Vector4 initialColor = Color::WHITE;
250   Property::Index colorIndex = shader.RegisterProperty( "uFadeColor", initialColor );
251
252   application.SendNotification();
253   application.Render(0);
254   DALI_TEST_EQUALS( shader.GetProperty<Vector4>(colorIndex), initialColor, TEST_LOCATION );
255
256   Animation  animation = Animation::New(1.0f);
257   KeyFrames keyFrames = KeyFrames::New();
258   keyFrames.Add(0.0f, initialColor);
259   keyFrames.Add(1.0f, Color::TRANSPARENT);
260   animation.AnimateBetween( Property( shader, colorIndex ), keyFrames );
261   animation.Play();
262
263   application.SendNotification();
264   application.Render(500);
265
266   DALI_TEST_EQUALS( shader.GetCurrentProperty< Vector4 >( colorIndex ), Color::WHITE * 0.5f, TEST_LOCATION );
267
268   application.Render(500);
269
270   DALI_TEST_EQUALS( shader.GetCurrentProperty< Vector4 >( colorIndex ), Color::TRANSPARENT, TEST_LOCATION );
271
272   END_TEST;
273 }
274
275 int UtcDaliShaderAnimatedProperty02(void)
276 {
277   TestApplication application;
278
279   tet_infoline("Test that a uniform map shader property can be animated");
280
281   Shader shader = Shader::New(VertexSource, FragmentSource);
282   Geometry geometry = CreateQuadGeometry();
283   Renderer renderer = Renderer::New( geometry, shader );
284
285   Actor actor = Actor::New();
286   actor.AddRenderer(renderer);
287   actor.SetSize(400, 400);
288   Stage::GetCurrent().Add(actor);
289   application.SendNotification();
290   application.Render(0);
291
292   Vector4 initialColor = Color::WHITE;
293   Property::Index colorIndex = shader.RegisterProperty( "uFadeColor", initialColor );
294
295   TestGlAbstraction& gl = application.GetGlAbstraction();
296
297   application.SendNotification();
298   application.Render(0);
299
300   Vector4 actualValue(Vector4::ZERO);
301   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
302   DALI_TEST_EQUALS( actualValue, initialColor, TEST_LOCATION );
303
304   Animation  animation = Animation::New(1.0f);
305   KeyFrames keyFrames = KeyFrames::New();
306   keyFrames.Add(0.0f, initialColor);
307   keyFrames.Add(1.0f, Color::TRANSPARENT);
308   animation.AnimateBetween( Property( shader, colorIndex ), keyFrames );
309   animation.Play();
310
311   application.SendNotification();
312   application.Render(500);
313
314   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
315   DALI_TEST_EQUALS( actualValue, Color::WHITE * 0.5f, TEST_LOCATION );
316
317   application.Render(500);
318   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
319   DALI_TEST_EQUALS( actualValue, Color::TRANSPARENT, TEST_LOCATION );
320
321   // change shader program
322   Property::Map map;
323   map["vertex"] = VertexSource;
324   map["fragment"] = FragmentSource;
325   map["hints"] = "MODIFIES_GEOMETRY";
326   shader.SetProperty( Shader::Property::PROGRAM, Property::Value(map) );
327   application.SendNotification();
328   application.Render(100);
329
330   // register another custom property as well
331   Property::Index customIndex = shader.RegisterProperty( "uCustom", Vector3(1,2,3) );
332   DALI_TEST_EQUALS( shader.GetProperty<Vector3>( customIndex ), Vector3(1,2,3), TEST_LOCATION );
333
334   application.SendNotification();
335   application.Render(100);
336
337   DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "uFadeColor", actualValue ) );
338   DALI_TEST_EQUALS( actualValue, Color::TRANSPARENT, TEST_LOCATION );
339
340   Vector3 customValue;
341   DALI_TEST_CHECK( gl.GetUniformValue<Vector3>( "uCustom", customValue ) );
342   DALI_TEST_EQUALS( customValue, Vector3(1,2,3), TEST_LOCATION );
343   END_TEST;
344 }
345
346 int UtcDaliShaderProgramProperty(void)
347 {
348   TestApplication application;
349
350   tet_infoline("Test get/set progam property");
351
352   Shader shader = Shader::New("", "");
353   std::string hintSet = "MODIFIES_GEOMETRY";
354
355   Property::Map map;
356   map["vertex"] = VertexSource;
357   map["fragment"] = FragmentSource;
358   map["hints"] = hintSet;
359
360   shader.SetProperty( Shader::Property::PROGRAM, Property::Value(map) );
361   // register a custom property as well
362   Property::Index customIndex = shader.RegisterProperty( "custom", Vector3(1,2,3) );
363   DALI_TEST_EQUALS( shader.GetProperty<Vector3>( customIndex ), Vector3(1,2,3), TEST_LOCATION );
364
365   Property::Value value = shader.GetProperty(Shader::Property::PROGRAM);
366   DALI_TEST_CHECK( value.GetType() == Property::MAP);
367   const Property::Map* outMap = value.GetMap();
368
369   std::string v = (*outMap)["vertex"].Get<std::string>();
370   std::string f = (*outMap)["fragment"].Get<std::string>();
371   std::string h = (*outMap)["hints"].Get<std::string>();
372
373   DALI_TEST_CHECK( v == VertexSource );
374   DALI_TEST_CHECK( f == FragmentSource );
375   DALI_TEST_CHECK( h == hintSet );
376
377   value = shader.GetCurrentProperty( Shader::Property::PROGRAM );
378   DALI_TEST_CHECK( value.GetType() == Property::MAP);
379   outMap = value.GetMap();
380   // check that changing the shader did not cause us to loose custom property
381   DALI_TEST_EQUALS( shader.GetProperty<Vector3>( customIndex ), Vector3(1,2,3), TEST_LOCATION );
382   using Dali::Animation;
383   Animation animation = Animation::New( 0.1f );
384   animation.AnimateTo( Property( shader, customIndex ), Vector3(4,5,6) );
385   animation.Play();
386   application.SendNotification();
387   application.Render(100);
388   DALI_TEST_EQUALS( shader.GetProperty<Vector3>( customIndex ), Vector3(4,5,6), TEST_LOCATION );
389
390   v = (*outMap)["vertex"].Get<std::string>();
391   f = (*outMap)["fragment"].Get<std::string>();
392   h = (*outMap)["hints"].Get<std::string>();
393
394   DALI_TEST_CHECK( v == VertexSource );
395   DALI_TEST_CHECK( f == FragmentSource );
396   DALI_TEST_CHECK( h == hintSet );
397
398   std::string hintGot;
399
400   hintSet = "OUTPUT_IS_TRANSPARENT,MODIFIES_GEOMETRY";
401   map["hints"] = hintSet;
402   shader.SetProperty( Shader::Property::PROGRAM, Property::Value(map) );
403   value = shader.GetProperty(Shader::Property::PROGRAM);
404   hintGot = (*value.GetMap())["hints"].Get<std::string>();
405   DALI_TEST_CHECK( hintGot == hintSet );
406
407   hintSet = "OUTPUT_IS_TRANSPARENT";
408   map["hints"] = hintSet;
409   shader.SetProperty( Shader::Property::PROGRAM, Property::Value(map) );
410   value = shader.GetProperty(Shader::Property::PROGRAM);
411   hintGot = (*value.GetMap())["hints"].Get<std::string>();
412   DALI_TEST_CHECK( hintGot == hintSet );
413
414   hintSet = "NONE";
415   map["hints"] = hintSet;
416   shader.SetProperty( Shader::Property::PROGRAM, Property::Value(map) );
417   value = shader.GetProperty(Shader::Property::PROGRAM);
418   hintGot = (*value.GetMap())["hints"].Get<std::string>();
419   DALI_TEST_CHECK( hintGot == hintSet );
420
421   hintSet = "";
422   map["hints"] = hintSet;
423   shader.SetProperty( Shader::Property::PROGRAM, Property::Value(map) );
424   value = shader.GetProperty(Shader::Property::PROGRAM);
425   hintGot = (*value.GetMap())["hints"].Get<std::string>();
426   DALI_TEST_CHECK( hintGot == "NONE" );
427
428   END_TEST;
429 }