[dali_1.3.40] Merge branch 'devel/master'
[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     updateProxy.GetWorldMatrixAndSize( mActorId, mWorldMatrix, mSize );
76     mWorldMatrixGetWorldMatrixCall = updateProxy.GetWorldMatrix( mActorId );
77     mSizeGetSizeCall = updateProxy.GetSize( mActorId );
78     mPositionGetPositionCall = updateProxy.GetPosition( mActorId );
79     updateProxy.GetPositionAndSize( mActorId, mPositionGetPositionAndSizeCall, mSizeGetPositionAndSizeCall );
80     mWorldColor = updateProxy.GetWorldColor( mActorId );
81   }
82
83   const unsigned int mActorId;
84
85   Matrix mWorldMatrix;
86   Matrix mWorldMatrixGetWorldMatrixCall;
87   Vector3 mSize;
88   Vector3 mSizeGetSizeCall;
89   Vector3 mPositionGetPositionCall;
90   Vector3 mPositionGetPositionAndSizeCall;
91   Vector3 mSizeGetPositionAndSizeCall;
92   Vector4 mWorldColor;
93 };
94
95 class FrameCallbackSetter : public FrameCallbackBasic
96 {
97 public:
98
99   FrameCallbackSetter(
100       unsigned int actorId,
101       const Matrix& matrixToSet,
102       const Vector3& sizeToSet,
103       const Vector3& positionToSet,
104       const Vector4& colorToSet )
105   : mActorId( actorId ),
106     mMatrixToSet( matrixToSet ),
107     mSizeToSet( sizeToSet ),
108     mPositionToSet( positionToSet ),
109     mColorToSet( colorToSet )
110   {
111   }
112
113   virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds )
114   {
115     FrameCallbackBasic::Update( updateProxy, elapsedSeconds );
116     updateProxy.SetWorldMatrix( mActorId, mMatrixToSet );
117     updateProxy.SetSize( mActorId, mSizeToSet );
118     updateProxy.GetWorldMatrixAndSize( mActorId, mWorldMatrixAfterSetting, mSizeAfterSetting );
119     updateProxy.SetPosition( mActorId, mPositionToSet );
120     mPositionAfterSetting = updateProxy.GetPosition( mActorId );
121     updateProxy.SetWorldColor( mActorId, mColorToSet );
122     mColorAfterSetting = updateProxy.GetWorldColor( mActorId );
123   }
124
125   const unsigned int mActorId;
126   const Matrix& mMatrixToSet;
127   const Vector3& mSizeToSet;
128   const Vector3& mPositionToSet;
129   const Vector4& mColorToSet;
130
131   Matrix mWorldMatrixAfterSetting;
132   Vector3 mSizeAfterSetting;
133   Vector3 mPositionAfterSetting;
134   Vector4 mColorAfterSetting;
135 };
136
137 class FrameCallbackMultipleActors : public FrameCallbackBasic
138 {
139 public:
140
141   FrameCallbackMultipleActors()
142   {
143   }
144
145   virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds )
146   {
147     FrameCallbackBasic::Update( updateProxy, elapsedSeconds );
148     for( auto&& i : mActorIds )
149     {
150       Matrix matrix( false );
151       Vector3 size;
152       updateProxy.GetWorldMatrixAndSize( i, matrix, size );
153       mWorldMatrices[ i ] = matrix;
154       mSizes[ i ] = size;
155     }
156   }
157
158   Vector< unsigned int > mActorIds;
159
160   std::map< unsigned int, Matrix > mWorldMatrices;
161   std::map< unsigned int, Vector3 > mSizes;
162 };
163
164 ///////////////////////////////////////////////////////////////////////////////
165
166 int UtcDaliFrameCallbackCheckInstallationAndRemoval(void)
167 {
168   TestApplication application;
169
170   FrameCallbackBasic frameCallback;
171
172   Stage stage = Stage::GetCurrent();
173   DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
174
175   application.SendNotification();
176   application.Render();
177
178   DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
179
180   frameCallback.mCalled = false;
181
182   DevelStage::RemoveFrameCallback( stage, frameCallback );
183
184   application.SendNotification();
185   application.Render();
186
187   DALI_TEST_EQUALS( frameCallback.mCalled, false, TEST_LOCATION );
188
189   END_TEST;
190 }
191
192 int UtcDaliFrameCallbackGetters(void)
193 {
194   TestApplication application;
195   Vector2 actorSize( 200, 300 );
196   Vector4 color( 0.5f, 0.6f, 0.7f, 0.8f );
197   Vector3 position( 10.0f, 20.0f, 30.0f );
198
199   Actor actor = Actor::New();
200   actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
201   actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
202   actor.SetSize( actorSize );
203   actor.SetColor( color );
204   actor.SetPosition( position );
205
206   Stage stage = Stage::GetCurrent();
207   stage.Add( actor );
208   Vector2 stageSize = stage.GetSize();
209
210   FrameCallbackOneActor frameCallback( actor.GetId() );
211   DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
212
213   application.SendNotification();
214   application.Render();
215
216   Vector3 expectedPosition( -stageSize.width * 0.5f + actorSize.width * 0.5f + position.x,
217                             -stageSize.height * 0.5f + actorSize.height * 0.5f + position.y,
218                             0.0f + position.z );
219
220   Matrix expectedWorldMatrix( false );
221   expectedWorldMatrix.SetIdentity();
222   expectedWorldMatrix.SetTranslation( expectedPosition );
223
224   DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
225   DALI_TEST_EQUALS( frameCallback.mWorldMatrix, expectedWorldMatrix, TEST_LOCATION );
226   DALI_TEST_EQUALS( frameCallback.mWorldMatrixGetWorldMatrixCall, expectedWorldMatrix, TEST_LOCATION );
227   DALI_TEST_EQUALS( frameCallback.mSize, Vector3( actorSize.width, actorSize.height, 0.0f ), TEST_LOCATION );
228   DALI_TEST_EQUALS( frameCallback.mSizeGetSizeCall, Vector3( actorSize.width, actorSize.height, 0.0f ), TEST_LOCATION );
229   DALI_TEST_EQUALS( frameCallback.mPositionGetPositionCall, expectedPosition, TEST_LOCATION );
230   DALI_TEST_EQUALS( frameCallback.mPositionGetPositionAndSizeCall, expectedPosition, TEST_LOCATION );
231   DALI_TEST_EQUALS( frameCallback.mSizeGetPositionAndSizeCall, Vector3( actorSize.width, actorSize.height, 0.0f ), TEST_LOCATION );
232   DALI_TEST_EQUALS( frameCallback.mWorldColor, color, TEST_LOCATION );
233
234   END_TEST;
235 }
236
237 int UtcDaliFrameCallbackSetters(void)
238 {
239   TestApplication application;
240   Vector2 actorSize( 200, 300 );
241
242   Actor actor = Actor::New();
243   actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
244   actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
245   actor.SetSize( actorSize );
246
247   Stage stage = Stage::GetCurrent();
248   stage.Add( actor );
249   Vector2 stageSize = stage.GetSize();
250
251   Matrix matrixToSet( Matrix::IDENTITY );
252   matrixToSet.SetTranslation( Vector3( 100.0f, 500.0f, 50.0f ) );
253   Vector3 sizeToSet( 1.0f, 2.0f, 3.0f );
254   Vector3 positionToSet( 10.0f, 20.0f, 30.0f );
255   Vector4 colorToSet( Color::MAGENTA );
256
257   FrameCallbackSetter frameCallback( actor.GetId(), matrixToSet, sizeToSet, positionToSet, colorToSet );
258   DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
259
260   application.SendNotification();
261   application.Render();
262
263   Matrix expectedWorldMatrix( false );
264   expectedWorldMatrix.SetIdentity();
265   expectedWorldMatrix.SetTranslation( Vector3( -stageSize.width * 0.5f + actorSize.width * 0.5f,
266                                                -stageSize.height * 0.5f + actorSize.height * 0.5f,
267                                                0.0f ) );
268
269   DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
270   DALI_TEST_CHECK( expectedWorldMatrix != matrixToSet );
271   DALI_TEST_EQUALS( frameCallback.mWorldMatrixAfterSetting, matrixToSet, TEST_LOCATION );
272   DALI_TEST_EQUALS( frameCallback.mSizeAfterSetting, sizeToSet, TEST_LOCATION );
273   DALI_TEST_EQUALS( frameCallback.mPositionAfterSetting, positionToSet, TEST_LOCATION );
274   DALI_TEST_EQUALS( frameCallback.mColorAfterSetting, colorToSet, TEST_LOCATION );
275
276   END_TEST;
277 }
278
279 int UtcDaliFrameCallbackMultipleActors(void)
280 {
281   /**
282    * Tree:
283    *              root-layer
284    *              /        \
285    *             /          \
286    *            /            \
287    *           /              \
288    *        actorA           actorE
289    *         / \              / \
290    *        /   \            /   \
291    *    actorB  actorD   actorF actorG
292    *      /                        \
293    *   actorC                     actorH
294    *
295    *  Screen positions:
296    *  -----------------------
297    *  |actorA|actorD        |
298    *  |      actorB         |
299    *  |      actorC         |
300    *  |                     |
301    *  |                     |
302    *  |                     |
303    *  |                     |
304    *  |                     |
305    *  |actorF       actorH  |
306    *  |actorE|actorG        |
307    *  -----------------------
308    */
309
310   TestApplication application;
311   Stage stage = Stage::GetCurrent();
312   const Vector2 stageSize = stage.GetSize();
313
314   std::map< char, Vector3 > sizes;
315   sizes['A'] = Vector3(  50.0f,  50.0f, 0.0f );
316   sizes['B'] = Vector3( 100.0f, 100.0f, 0.0f );
317   sizes['C'] = Vector3( 150.0f, 150.0f, 0.0f );
318   sizes['D'] = Vector3( 200.0f, 200.0f, 0.0f );
319   sizes['E'] = Vector3( 250.0f, 250.0f, 0.0f );
320   sizes['F'] = Vector3( 300.0f, 300.0f, 0.0f );
321   sizes['G'] = Vector3( 350.0f, 350.0f, 0.0f );
322   sizes['H'] = Vector3( 400.0f, 350.0f, 0.0f );
323
324   std::map< char, Matrix > matrices;
325   for( char i = 'A'; i <= 'H'; ++i )
326   {
327     matrices[i] = Matrix::IDENTITY;
328   }
329
330   matrices['A'].SetTranslation( Vector3( -stageSize.width * 0.5f + sizes['A'].width * 0.5f,
331                                          -stageSize.height * 0.5f + sizes['A'].height * 0.5f,
332                                          0.0f ) );
333   matrices['B'].SetTranslation( Vector3( matrices['A'].GetTranslation3() + sizes['A'] * 0.5f + sizes['B'] * 0.5f ) );
334   matrices['C'].SetTranslation( Vector3( matrices['B'].GetTranslation3().x,
335                                          matrices['B'].GetTranslation3().y + sizes['B'].height * 0.5f + sizes['C'].height * 0.5f,
336                                          0.0f ) );
337   matrices['D'].SetTranslation( Vector3( matrices['A'].GetTranslation3().x + sizes['A'].width * 0.5f + sizes['D'].width * 0.5f,
338                                          matrices['A'].GetTranslation3().y,
339                                          0.0f ) );
340   matrices['E'].SetTranslation( Vector3( -stageSize.width * 0.5f + sizes['E'].width * 0.5f,
341                                          stageSize.height * 0.5f - sizes['E'].height * 0.5f,
342                                          0.0f ) );
343   matrices['F'].SetTranslation( Vector3( matrices['E'].GetTranslation3().x,
344                                          matrices['E'].GetTranslation3().y - sizes['E'].height * 0.5f - sizes['F'].height * 0.5f,
345                                          0.0f ) );
346   matrices['G'].SetTranslation( Vector3( matrices['E'].GetTranslation3().x + sizes['E'].width * 0.5f + sizes['G'].width * 0.5f,
347                                          matrices['E'].GetTranslation3().y,
348                                          0.0f ) );
349   matrices['H'].SetTranslation( Vector3( matrices['G'].GetTranslation3().x + sizes['G'].width * 0.5f + sizes['H'].width * 0.5f,
350                                          matrices['G'].GetTranslation3().y - sizes['G'].height * 0.5f - sizes['H'].height * 0.5f,
351                                          0.0f ) );
352
353   Actor actorA = Actor::New();
354   actorA.SetParentOrigin( ParentOrigin::TOP_LEFT );
355   actorA.SetAnchorPoint( AnchorPoint::TOP_LEFT );
356   actorA.SetSize( sizes['A'] );
357   stage.Add( actorA );
358
359   Actor actorB = Actor::New();
360   actorB.SetParentOrigin( ParentOrigin::BOTTOM_RIGHT );
361   actorB.SetAnchorPoint( AnchorPoint::TOP_LEFT );
362   actorB.SetSize( sizes['B'] );
363   actorA.Add( actorB );
364
365   Actor actorC = Actor::New();
366   actorC.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
367   actorC.SetAnchorPoint( AnchorPoint::TOP_CENTER );
368   actorC.SetSize( sizes['C'] );
369   actorB.Add( actorC );
370
371   Actor actorD = Actor::New();
372   actorD.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
373   actorD.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
374   actorD.SetSize( sizes['D'] );
375   actorA.Add( actorD );
376
377   Actor actorE = Actor::New();
378   actorE.SetParentOrigin( ParentOrigin::BOTTOM_LEFT );
379   actorE.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT );
380   actorE.SetSize( sizes['E'] );
381   stage.Add( actorE );
382
383   Actor actorF = Actor::New();
384   actorF.SetParentOrigin( ParentOrigin::TOP_CENTER );
385   actorF.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
386   actorF.SetSize( sizes['F'] );
387   actorE.Add( actorF );
388
389   Actor actorG = Actor::New();
390   actorG.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
391   actorG.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
392   actorG.SetSize( sizes['G'] );
393   actorE.Add( actorG );
394
395   Actor actorH = Actor::New();
396   actorH.SetParentOrigin( ParentOrigin::TOP_RIGHT );
397   actorH.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT );
398   actorH.SetSize( sizes['H'] );
399   actorG.Add( actorH );
400
401   std::map< char, unsigned int > actorIds;
402   actorIds['A'] = actorA.GetId();
403   actorIds['B'] = actorB.GetId();
404   actorIds['C'] = actorC.GetId();
405   actorIds['D'] = actorD.GetId();
406   actorIds['E'] = actorE.GetId();
407   actorIds['F'] = actorF.GetId();
408   actorIds['G'] = actorG.GetId();
409   actorIds['H'] = actorH.GetId();
410
411   FrameCallbackMultipleActors frameCallback;
412   for( auto&& i : actorIds )
413   {
414     frameCallback.mActorIds.PushBack( i.second );
415   }
416
417   DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
418
419   application.SendNotification();
420   application.Render();
421
422   DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
423
424   for( char i = 'A'; i <= 'H'; ++i )
425   {
426     DALI_TEST_EQUALS( frameCallback.mWorldMatrices[ actorIds[ i ] ], matrices[ i ], TEST_LOCATION );
427     DALI_TEST_EQUALS( frameCallback.mSizes[ actorIds[ i ] ], sizes[ i ], TEST_LOCATION );
428   }
429
430   // Render again to make sure it still gets called and gives the correct values (in case any optimisations break this)
431   frameCallback.mCalled = false;
432
433   application.SendNotification();
434   application.Render();
435
436   DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
437
438   for( char i = 'A'; i <= 'H'; ++i )
439   {
440     DALI_TEST_EQUALS( frameCallback.mWorldMatrices[ actorIds[ i ] ], matrices[ i ], TEST_LOCATION );
441     DALI_TEST_EQUALS( frameCallback.mSizes[ actorIds[ i ] ], sizes[ i ], TEST_LOCATION );
442   }
443
444   END_TEST;
445 }
446
447 int UtcDaliFrameCallbackCheckActorNotAdded(void)
448 {
449   TestApplication application;
450
451   Actor actor = Actor::New();
452   actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
453   actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
454   actor.SetSize( 200, 300 );
455
456   Stage stage = Stage::GetCurrent();
457   FrameCallbackOneActor frameCallback( actor.GetId() );
458   DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
459
460   application.SendNotification();
461   application.Render();
462
463   DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
464   DALI_TEST_EQUALS( frameCallback.mWorldMatrix, Matrix(true) /* Unchanged Matrix */, TEST_LOCATION );
465   DALI_TEST_EQUALS( frameCallback.mWorldMatrixGetWorldMatrixCall, Matrix::IDENTITY, TEST_LOCATION );
466   DALI_TEST_EQUALS( frameCallback.mSize, Vector3::ZERO, TEST_LOCATION );
467   DALI_TEST_EQUALS( frameCallback.mSizeGetSizeCall, Vector3::ZERO, TEST_LOCATION );
468
469   END_TEST;
470 }