694cb43eda9da8f8ec281b28997ee7106d1dde8c
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-FrameCallbackInterface.cpp
1 /*
2  * Copyright (c) 2018 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/devel-api/common/map-wrapper.h>
23 #include <dali/devel-api/common/stage-devel.h>
24 #include <dali/devel-api/update/frame-callback-interface.h>
25 #include <dali/devel-api/update/update-proxy.h>
26 #include <dali-test-suite-utils.h>
27
28 using namespace Dali;
29
30 void utc_dali_frame_callback_interface_startup(void)
31 {
32   test_return_value = TET_UNDEF;
33 }
34
35 void utc_dali_frame_callback_interface_cleanup(void)
36 {
37   test_return_value = TET_PASS;
38 }
39
40 ///////////////////////////////////////////////////////////////////////////////
41 namespace
42 {
43
44 class FrameCallbackBasic : public FrameCallbackInterface
45 {
46 public:
47
48   FrameCallbackBasic()
49   : mCalled( false )
50   {
51   }
52
53   virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds )
54   {
55     mCalled = true;
56   }
57
58   bool mCalled;
59 };
60
61 } // anon namespace
62
63 class FrameCallbackOneActor : public FrameCallbackBasic
64 {
65 public:
66
67   FrameCallbackOneActor( unsigned int actorId )
68   : mActorId( actorId )
69   {
70   }
71
72   virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds )
73   {
74     FrameCallbackBasic::Update( updateProxy, elapsedSeconds );
75     mSizeGetSizeCall = updateProxy.GetSize( mActorId );
76     mPositionGetPositionCall = updateProxy.GetPosition( mActorId );
77     updateProxy.GetPositionAndSize( mActorId, mPositionGetPositionAndSizeCall, mSizeGetPositionAndSizeCall );
78     mColor = updateProxy.GetColor( mActorId );
79     mScale = updateProxy.GetScale( mActorId );
80   }
81
82   const unsigned int mActorId;
83
84   Vector3 mSizeGetSizeCall;
85   Vector3 mPositionGetPositionCall;
86   Vector3 mPositionGetPositionAndSizeCall;
87   Vector3 mSizeGetPositionAndSizeCall;
88   Vector4 mColor;
89   Vector3 mScale;
90 };
91
92 class FrameCallbackSetter : public FrameCallbackBasic
93 {
94 public:
95
96   FrameCallbackSetter(
97       unsigned int actorId,
98       const Vector3& sizeToSet,
99       const Vector3& positionToSet,
100       const Vector4& colorToSet,
101       const Vector3& scaleToSet )
102   : mActorId( actorId ),
103     mSizeToSet( sizeToSet ),
104     mPositionToSet( positionToSet ),
105     mColorToSet( colorToSet ),
106     mScaleToSet( scaleToSet )
107   {
108   }
109
110   virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds )
111   {
112     FrameCallbackBasic::Update( updateProxy, elapsedSeconds );
113     updateProxy.SetSize( mActorId, mSizeToSet );
114     updateProxy.SetPosition( mActorId, mPositionToSet );
115     updateProxy.SetColor( mActorId, mColorToSet );
116     updateProxy.SetScale( mActorId, mScaleToSet );
117     mSizeAfterSetting = updateProxy.GetSize( mActorId );
118     mPositionAfterSetting = updateProxy.GetPosition( mActorId );
119     mColorAfterSetting = updateProxy.GetColor( mActorId );
120     mScaleAfterSetting = updateProxy.GetScale( mActorId );
121   }
122
123   const unsigned int mActorId;
124   const Vector3& mSizeToSet;
125   const Vector3& mPositionToSet;
126   const Vector4& mColorToSet;
127   const Vector3& mScaleToSet;
128
129   Vector3 mSizeAfterSetting;
130   Vector3 mPositionAfterSetting;
131   Vector4 mColorAfterSetting;
132   Vector3 mScaleAfterSetting;
133 };
134
135 class FrameCallbackBaker : public FrameCallbackBasic
136 {
137 public:
138
139   FrameCallbackBaker(
140       unsigned int actorId,
141       const Vector3& sizeToSet,
142       const Vector3& positionToSet,
143       const Vector4& colorToSet,
144       const Vector3& scaleToSet )
145   : mActorId( actorId ),
146     mSizeToSet( sizeToSet ),
147     mPositionToSet( positionToSet ),
148     mColorToSet( colorToSet ),
149     mScaleToSet( scaleToSet )
150   {
151   }
152
153   virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds )
154   {
155     FrameCallbackBasic::Update( updateProxy, elapsedSeconds );
156     updateProxy.BakeSize( mActorId, mSizeToSet );
157     updateProxy.BakePosition( mActorId, mPositionToSet );
158     updateProxy.BakeColor( mActorId, mColorToSet );
159     updateProxy.BakeScale( mActorId, mScaleToSet );
160     mSizeAfterSetting = updateProxy.GetSize( mActorId );
161     mPositionAfterSetting = updateProxy.GetPosition( mActorId );
162     mColorAfterSetting = updateProxy.GetColor( mActorId );
163     mScaleAfterSetting = updateProxy.GetScale( mActorId );
164   }
165
166   const unsigned int mActorId;
167   const Vector3& mSizeToSet;
168   const Vector3& mPositionToSet;
169   const Vector4& mColorToSet;
170   const Vector3& mScaleToSet;
171
172   Vector3 mSizeAfterSetting;
173   Vector3 mPositionAfterSetting;
174   Vector4 mColorAfterSetting;
175   Vector3 mScaleAfterSetting;
176 };
177
178
179 class FrameCallbackMultipleActors : public FrameCallbackBasic
180 {
181 public:
182
183   FrameCallbackMultipleActors()
184   {
185   }
186
187   virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds )
188   {
189     FrameCallbackBasic::Update( updateProxy, elapsedSeconds );
190     for( auto&& i : mActorIds )
191     {
192       Vector3 position;
193       Vector3 size;
194       updateProxy.GetPositionAndSize( i, position, size );
195       mPositions[ i ] = position;
196       mSizes[ i ] = size;
197     }
198   }
199
200   Vector< unsigned int > mActorIds;
201
202   std::map< unsigned int, Vector3 > mPositions;
203   std::map< unsigned int, Vector3 > mSizes;
204 };
205
206 ///////////////////////////////////////////////////////////////////////////////
207
208 int UtcDaliFrameCallbackCheckInstallationAndRemoval(void)
209 {
210   TestApplication application;
211
212   FrameCallbackBasic frameCallback;
213
214   Stage stage = Stage::GetCurrent();
215   DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
216
217   application.SendNotification();
218   application.Render();
219
220   DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
221
222   frameCallback.mCalled = false;
223
224   DevelStage::RemoveFrameCallback( stage, frameCallback );
225
226   application.SendNotification();
227   application.Render();
228
229   DALI_TEST_EQUALS( frameCallback.mCalled, false, TEST_LOCATION );
230
231   END_TEST;
232 }
233
234 int UtcDaliFrameCallbackGetters(void)
235 {
236   TestApplication application;
237   Vector2 actorSize( 200, 300 );
238   Vector4 color( 0.5f, 0.6f, 0.7f, 0.8f );
239   Vector3 position( 10.0f, 20.0f, 30.0f );
240   Vector3 scale( 2.0f, 4.0f, 6.0f );
241
242   Actor actor = Actor::New();
243   actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
244   actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
245   actor.SetSize( actorSize );
246   actor.SetColor( color );
247   actor.SetPosition( position );
248   actor.SetScale( scale );
249
250   Stage stage = Stage::GetCurrent();
251   stage.Add( actor );
252
253   FrameCallbackOneActor frameCallback( actor.GetId() );
254   DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
255
256   application.SendNotification();
257   application.Render();
258
259   DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
260   DALI_TEST_EQUALS( frameCallback.mSizeGetSizeCall, Vector3( actorSize.width, actorSize.height, 0.0f ), TEST_LOCATION );
261   DALI_TEST_EQUALS( frameCallback.mPositionGetPositionCall, position, TEST_LOCATION );
262   DALI_TEST_EQUALS( frameCallback.mPositionGetPositionAndSizeCall, position, TEST_LOCATION );
263   DALI_TEST_EQUALS( frameCallback.mSizeGetPositionAndSizeCall, Vector3( actorSize.width, actorSize.height, 0.0f ), TEST_LOCATION );
264   DALI_TEST_EQUALS( frameCallback.mColor, color, TEST_LOCATION );
265   DALI_TEST_EQUALS( frameCallback.mScale, scale, TEST_LOCATION );
266
267   END_TEST;
268 }
269
270 int UtcDaliFrameCallbackSetters(void)
271 {
272   TestApplication application;
273   Vector2 actorSize( 200, 300 );
274
275   Actor actor = Actor::New();
276   actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
277   actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
278   actor.SetSize( actorSize );
279
280   Stage stage = Stage::GetCurrent();
281   stage.Add( actor );
282
283   Vector3 sizeToSet( 1.0f, 2.0f, 3.0f );
284   Vector3 positionToSet( 10.0f, 20.0f, 30.0f );
285   Vector4 colorToSet( Color::MAGENTA );
286   Vector3 scaleToSet( 1.0f, 3.0f, 5.0f );
287
288   FrameCallbackSetter frameCallback( actor.GetId(), sizeToSet, positionToSet, colorToSet, scaleToSet );
289   DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
290
291   application.SendNotification();
292   application.Render();
293
294   DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
295   DALI_TEST_EQUALS( frameCallback.mSizeAfterSetting, sizeToSet, TEST_LOCATION );
296   DALI_TEST_EQUALS( frameCallback.mPositionAfterSetting, positionToSet, TEST_LOCATION );
297   DALI_TEST_EQUALS( frameCallback.mColorAfterSetting, colorToSet, TEST_LOCATION );
298   DALI_TEST_EQUALS( frameCallback.mScaleAfterSetting, scaleToSet, TEST_LOCATION );
299
300   // Ensure the actual actor values haven't changed as we didn't bake the values after removing the callback
301   DevelStage::RemoveFrameCallback( stage, frameCallback );
302
303   application.SendNotification();
304   application.Render();
305
306   DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::POSITION ).Get< Vector3 >(), Vector3::ZERO, TEST_LOCATION );
307   DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::SIZE ).Get< Vector3 >(), Vector3( actorSize ), TEST_LOCATION );
308   DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::COLOR ).Get< Vector4 >(), Color::WHITE, TEST_LOCATION );
309   DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::SCALE ).Get< Vector3 >(), Vector3::ONE, TEST_LOCATION );
310
311   END_TEST;
312 }
313
314 int UtcDaliFrameCallbackBake(void)
315 {
316   TestApplication application;
317   Vector2 actorSize( 200, 300 );
318
319   Actor actor = Actor::New();
320   actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
321   actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
322   actor.SetSize( actorSize );
323
324   Stage stage = Stage::GetCurrent();
325   stage.Add( actor );
326
327   Vector3 sizeToSet( 1.0f, 2.0f, 3.0f );
328   Vector3 positionToSet( 10.0f, 20.0f, 30.0f );
329   Vector4 colorToSet( Color::MAGENTA );
330   Vector3 scaleToSet( 1.0f, 3.0f, 5.0f );
331
332   FrameCallbackBaker frameCallback( actor.GetId(), sizeToSet, positionToSet, colorToSet, scaleToSet );
333   DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
334
335   application.SendNotification();
336   application.Render();
337
338   DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
339   DALI_TEST_EQUALS( frameCallback.mSizeAfterSetting, sizeToSet, TEST_LOCATION );
340   DALI_TEST_EQUALS( frameCallback.mPositionAfterSetting, positionToSet, TEST_LOCATION );
341   DALI_TEST_EQUALS( frameCallback.mColorAfterSetting, colorToSet, TEST_LOCATION );
342   DALI_TEST_EQUALS( frameCallback.mScaleAfterSetting, scaleToSet, TEST_LOCATION );
343
344   // Ensure the new values are saved after removing the callback
345   DevelStage::RemoveFrameCallback( stage, frameCallback );
346
347   application.SendNotification();
348   application.Render();
349
350   DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::POSITION ).Get< Vector3 >(), positionToSet, TEST_LOCATION );
351   DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::SIZE ).Get< Vector3 >(), sizeToSet, TEST_LOCATION );
352   DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::COLOR ).Get< Vector4 >(), colorToSet, TEST_LOCATION );
353   DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::SCALE ).Get< Vector3 >(), scaleToSet, TEST_LOCATION );
354
355   END_TEST;
356 }
357
358
359 int UtcDaliFrameCallbackMultipleActors(void)
360 {
361   /**
362    * Tree:
363    *              root-layer
364    *              /        \
365    *             /          \
366    *            /            \
367    *           /              \
368    *        actorA           actorE
369    *         / \              / \
370    *        /   \            /   \
371    *    actorB  actorD   actorF actorG
372    *      /                        \
373    *   actorC                     actorH
374    *
375    *  Screen positions (with minor alterations due to local position):
376    *  -----------------------
377    *  |actorA|actorD        |
378    *  |      actorB         |
379    *  |      actorC         |
380    *  |                     |
381    *  |                     |
382    *  |                     |
383    *  |                     |
384    *  |                     |
385    *  |actorF       actorH  |
386    *  |actorE|actorG        |
387    *  -----------------------
388    */
389
390   TestApplication application;
391   Stage stage = Stage::GetCurrent();
392
393   std::map< char, Vector3 > sizes;
394   sizes['A'] = Vector3(  50.0f,  50.0f, 0.0f );
395   sizes['B'] = Vector3( 100.0f, 100.0f, 0.0f );
396   sizes['C'] = Vector3( 150.0f, 150.0f, 0.0f );
397   sizes['D'] = Vector3( 200.0f, 200.0f, 0.0f );
398   sizes['E'] = Vector3( 250.0f, 250.0f, 0.0f );
399   sizes['F'] = Vector3( 300.0f, 300.0f, 0.0f );
400   sizes['G'] = Vector3( 350.0f, 350.0f, 0.0f );
401   sizes['H'] = Vector3( 400.0f, 350.0f, 0.0f );
402
403   std::map< char, Vector3 > positions;
404   positions['A'] = Vector3(  0.0f,  1.0f,  2.0f );
405   positions['B'] = Vector3(  2.0f,  3.0f,  4.0f );
406   positions['C'] = Vector3(  5.0f,  6.0f,  7.0f );
407   positions['D'] = Vector3(  8.0f,  9.0f, 10.0f );
408   positions['E'] = Vector3( 11.0f, 12.0f, 13.0f );
409   positions['F'] = Vector3( 14.0f, 15.0f, 16.0f );
410   positions['G'] = Vector3( 17.0f, 18.0f, 19.0f );
411   positions['H'] = Vector3( 20.0f, 21.0f, 22.0f );
412
413   Actor actorA = Actor::New();
414   actorA.SetParentOrigin( ParentOrigin::TOP_LEFT );
415   actorA.SetAnchorPoint( AnchorPoint::TOP_LEFT );
416   actorA.SetSize( sizes['A'] );
417   actorA.SetPosition( positions['A'] );
418   stage.Add( actorA );
419
420   Actor actorB = Actor::New();
421   actorB.SetParentOrigin( ParentOrigin::BOTTOM_RIGHT );
422   actorB.SetAnchorPoint( AnchorPoint::TOP_LEFT );
423   actorB.SetSize( sizes['B'] );
424   actorB.SetPosition( positions['B'] );
425   actorA.Add( actorB );
426
427   Actor actorC = Actor::New();
428   actorC.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
429   actorC.SetAnchorPoint( AnchorPoint::TOP_CENTER );
430   actorC.SetSize( sizes['C'] );
431   actorC.SetPosition( positions['C'] );
432   actorB.Add( actorC );
433
434   Actor actorD = Actor::New();
435   actorD.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
436   actorD.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
437   actorD.SetSize( sizes['D'] );
438   actorD.SetPosition( positions['D'] );
439   actorA.Add( actorD );
440
441   Actor actorE = Actor::New();
442   actorE.SetParentOrigin( ParentOrigin::BOTTOM_LEFT );
443   actorE.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT );
444   actorE.SetSize( sizes['E'] );
445   actorE.SetPosition( positions['E'] );
446   stage.Add( actorE );
447
448   Actor actorF = Actor::New();
449   actorF.SetParentOrigin( ParentOrigin::TOP_CENTER );
450   actorF.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
451   actorF.SetSize( sizes['F'] );
452   actorF.SetPosition( positions['F'] );
453   actorE.Add( actorF );
454
455   Actor actorG = Actor::New();
456   actorG.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
457   actorG.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
458   actorG.SetSize( sizes['G'] );
459   actorG.SetPosition( positions['G'] );
460   actorE.Add( actorG );
461
462   Actor actorH = Actor::New();
463   actorH.SetParentOrigin( ParentOrigin::TOP_RIGHT );
464   actorH.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT );
465   actorH.SetSize( sizes['H'] );
466   actorH.SetPosition( positions['H'] );
467   actorG.Add( actorH );
468
469   std::map< char, unsigned int > actorIds;
470   actorIds['A'] = actorA.GetId();
471   actorIds['B'] = actorB.GetId();
472   actorIds['C'] = actorC.GetId();
473   actorIds['D'] = actorD.GetId();
474   actorIds['E'] = actorE.GetId();
475   actorIds['F'] = actorF.GetId();
476   actorIds['G'] = actorG.GetId();
477   actorIds['H'] = actorH.GetId();
478
479   FrameCallbackMultipleActors frameCallback;
480   for( auto&& i : actorIds )
481   {
482     frameCallback.mActorIds.PushBack( i.second );
483   }
484
485   DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
486
487   application.SendNotification();
488   application.Render();
489
490   DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
491
492   for( char i = 'A'; i <= 'H'; ++i )
493   {
494     DALI_TEST_EQUALS( frameCallback.mPositions[ actorIds[ i ] ], positions[ i ], TEST_LOCATION );
495     DALI_TEST_EQUALS( frameCallback.mSizes[ actorIds[ i ] ], sizes[ i ], TEST_LOCATION );
496   }
497
498   // Render again to make sure it still gets called and gives the correct values (in case any optimisations break this)
499   frameCallback.mCalled = false;
500
501   application.SendNotification();
502   application.Render();
503
504   DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
505
506   for( char i = 'A'; i <= 'H'; ++i )
507   {
508     DALI_TEST_EQUALS( frameCallback.mPositions[ actorIds[ i ] ], positions[ i ], TEST_LOCATION );
509     DALI_TEST_EQUALS( frameCallback.mSizes[ actorIds[ i ] ], sizes[ i ], TEST_LOCATION );
510   }
511
512   END_TEST;
513 }
514
515 int UtcDaliFrameCallbackCheckActorNotAdded(void)
516 {
517   TestApplication application;
518
519   Actor actor = Actor::New();
520   actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
521   actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
522   actor.SetSize( 200, 300 );
523
524   Stage stage = Stage::GetCurrent();
525   FrameCallbackOneActor frameCallback( actor.GetId() );
526   DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
527
528   application.SendNotification();
529   application.Render();
530
531   // All should be default constructed objects
532   DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
533   DALI_TEST_EQUALS( frameCallback.mPositionGetPositionCall, Vector3::ZERO, TEST_LOCATION );
534   DALI_TEST_EQUALS( frameCallback.mSizeGetSizeCall, Vector3::ZERO, TEST_LOCATION );
535   DALI_TEST_EQUALS( frameCallback.mColor, Vector4::ZERO, TEST_LOCATION );
536   DALI_TEST_EQUALS( frameCallback.mScale, Vector3::ZERO, TEST_LOCATION );
537
538   END_TEST;
539 }