2804868b0474d71877e87dcea93eb07105ce8512
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / utc-Dali-AnimatedImageVisual.cpp
1
2 /*
3  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <iostream>
19 #include <stdlib.h>
20 #include <dali-toolkit-test-suite-utils.h>
21 #include <toolkit-timer.h>
22 #include <toolkit-event-thread-callback.h>
23 #include <dali-toolkit/dali-toolkit.h>
24 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
25 #include <dali-toolkit/devel-api/controls/control-devel.h>
26 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
27 #include "dummy-control.h"
28
29 using namespace Dali;
30 using namespace Dali::Toolkit;
31
32 void dali_animated_image_visual_startup(void)
33 {
34   test_return_value = TET_UNDEF;
35 }
36
37 void dali_animated_image_visual_cleanup(void)
38 {
39   test_return_value = TET_PASS;
40 }
41
42 namespace
43 {
44 const char* TEST_IMAGE_FILE_NAME =  TEST_RESOURCE_DIR  "/application-icon-%02d.png";
45 const char* TEST_GIF_FILE_NAME = TEST_RESOURCE_DIR "/anim.gif";
46 }
47
48
49 void CopyUrlsIntoArray( Property::Array& urls, int startIndex=0 )
50 {
51   for( int i=20+startIndex;i<=30;++i)
52   {
53     char* url;
54     if(asprintf(&url, TEST_IMAGE_FILE_NAME, i) > 0)
55     {
56       Property::Value value(url);
57       urls.Add(value);
58       free(url);
59     }
60   }
61 }
62
63 int UtcDaliAnimatedImageVisualGetPropertyMap01(void)
64 {
65   ToolkitTestApplication application;
66   tet_infoline( "UtcDaliAnimatedImageVisualGetPropertyMap" );
67
68   // request AnimatedImageVisual with a property map
69   VisualFactory factory = VisualFactory::Get();
70   Visual::Base animatedImageVisual = factory.CreateVisual(
71     Property::Map()
72     .Add( Toolkit::Visual::Property::TYPE, Visual::ANIMATED_IMAGE )
73     .Add( ImageVisual::Property::URL, TEST_GIF_FILE_NAME )
74     .Add( ImageVisual::Property::PIXEL_AREA, Vector4() )
75     .Add( ImageVisual::Property::WRAP_MODE_U, WrapMode::REPEAT )
76     .Add( ImageVisual::Property::WRAP_MODE_V, WrapMode::DEFAULT ));
77
78   Property::Map resultMap;
79   animatedImageVisual.CreatePropertyMap( resultMap );
80   // check the property values from the returned map from a visual
81   Property::Value* value = resultMap.Find( Toolkit::Visual::Property::TYPE,  Property::INTEGER );
82   DALI_TEST_CHECK( value );
83   DALI_TEST_CHECK( value->Get<int>() == Visual::ANIMATED_IMAGE );
84
85   value = resultMap.Find( ImageVisual::Property::URL,  Property::STRING );
86   DALI_TEST_CHECK( value );
87   DALI_TEST_CHECK( value->Get<std::string>() == TEST_GIF_FILE_NAME );
88
89   // request AnimatedImageVisual with an URL
90   Visual::Base animatedImageVisual2 = factory.CreateVisual( TEST_GIF_FILE_NAME, ImageDimensions() );
91   resultMap.Clear();
92   animatedImageVisual2.CreatePropertyMap( resultMap );
93   // check the property values from the returned map from a visual
94   value = resultMap.Find( Toolkit::Visual::Property::TYPE,  Property::INTEGER );
95   DALI_TEST_CHECK( value );
96   DALI_TEST_CHECK( value->Get<int>() == Visual::ANIMATED_IMAGE );
97
98   value = resultMap.Find( ImageVisual::Property::URL,  Property::STRING );
99   DALI_TEST_CHECK( value );
100   DALI_TEST_CHECK( value->Get<std::string>() == TEST_GIF_FILE_NAME );
101
102   END_TEST;
103 }
104
105
106 int UtcDaliAnimatedImageVisualGetPropertyMap02(void)
107 {
108   ToolkitTestApplication application;
109   tet_infoline( "UtcDaliAnimatedImageVisualGetPropertyMap for multi image" );
110
111   // request AnimatedImageVisual with a property map
112   VisualFactory factory = VisualFactory::Get();
113   Property::Array urls;
114   CopyUrlsIntoArray( urls );
115
116   Visual::Base animatedImageVisual = factory.CreateVisual(
117     Property::Map()
118     .Add( Toolkit::Visual::Property::TYPE, Visual::ANIMATED_IMAGE )
119     .Add( "url", urls )
120     .Add( "batchSize", 4 )
121     .Add( "cacheSize", 8 )
122     .Add( "loopCount", 10 )
123     .Add( "frameDelay", 200 )
124     .Add( "pixelArea", Vector4() )
125     .Add( "wrapModeU", WrapMode::REPEAT )
126     .Add( "wrapModeV", WrapMode::DEFAULT ));
127
128   Property::Map resultMap;
129   animatedImageVisual.CreatePropertyMap( resultMap );
130   // check the property values from the returned map from a visual
131   Property::Value* value = resultMap.Find( Toolkit::Visual::Property::TYPE,  Property::INTEGER );
132   DALI_TEST_CHECK( value );
133   DALI_TEST_CHECK( value->Get<int>() == Visual::ANIMATED_IMAGE );
134
135   value = resultMap.Find( ImageVisual::Property::URL, "url" );
136   DALI_TEST_CHECK( value );
137   Property::Array* resultUrls = value->GetArray();
138   DALI_TEST_CHECK( resultUrls );
139   DALI_TEST_EQUALS( resultUrls->Count(), urls.Count(), TEST_LOCATION );
140
141   value = resultMap.Find( ImageVisual::Property::BATCH_SIZE, "batchSize" );
142   DALI_TEST_CHECK( value );
143   DALI_TEST_EQUALS( value->Get<int>(), 4, TEST_LOCATION );
144
145   value = resultMap.Find( ImageVisual::Property::CACHE_SIZE, "cacheSize" );
146   DALI_TEST_CHECK( value );
147   DALI_TEST_EQUALS( value->Get<int>(), 8, TEST_LOCATION );
148
149   value = resultMap.Find( Toolkit::DevelImageVisual::Property::LOOP_COUNT, "loopCount" );
150   DALI_TEST_CHECK( value );
151   DALI_TEST_EQUALS( value->Get<int>(), 10, TEST_LOCATION );
152
153   value = resultMap.Find( ImageVisual::Property::FRAME_DELAY, "frameDelay" );
154   DALI_TEST_CHECK( value );
155   DALI_TEST_EQUALS( value->Get<int>(), 200, TEST_LOCATION );
156
157   END_TEST;
158 }
159
160
161
162
163 int UtcDaliAnimatedImageVisualMultiImage01(void)
164 {
165   ToolkitTestApplication application;
166   TestGlAbstraction& gl = application.GetGlAbstraction();
167
168   Property::Array urls;
169   CopyUrlsIntoArray( urls );
170
171   {
172     Property::Map propertyMap;
173     propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE );
174     propertyMap.Insert( ImageVisual::Property::URL, Property::Value(urls) );
175     propertyMap.Insert( ImageVisual::Property::BATCH_SIZE, 4);
176     propertyMap.Insert( ImageVisual::Property::CACHE_SIZE, 8);
177     propertyMap.Insert( ImageVisual::Property::FRAME_DELAY, 100);
178
179     VisualFactory factory = VisualFactory::Get();
180     Visual::Base visual = factory.CreateVisual( propertyMap );
181
182     // Expect that a batch of 4 textures has been requested. These will be serially loaded
183     // below.
184
185     DummyControl dummyControl = DummyControl::New(true);
186     Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
187     dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
188
189     dummyControl.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
190     Stage::GetCurrent().Add( dummyControl );
191     application.SendNotification();
192     application.Render(16);
193
194     tet_infoline( "Ready the visual after the visual is on stage" );
195     DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 4 ), true, TEST_LOCATION );
196
197     tet_infoline( "Test that a timer has been started" );
198     DALI_TEST_EQUALS( Test::GetTimerCount(), 1, TEST_LOCATION );
199
200     TraceCallStack& textureTrace = gl.GetTextureTrace();
201     textureTrace.Enable(true);
202
203     application.SendNotification();
204     application.Render(16);
205
206     DALI_TEST_EQUALS( gl.GetLastGenTextureId(), 4, TEST_LOCATION );
207     DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
208
209     tet_infoline( "Test that after 1 tick, and file loads completed, that we have 7 textures" );
210     Test::EmitGlobalTimerSignal();
211
212     // Expect the second batch has been requested
213     DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 4 ), true, TEST_LOCATION );
214
215     application.SendNotification();
216     application.Render(16);
217     DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 7, TEST_LOCATION );
218
219
220     tet_infoline( "Test that after 2 ticks that we have 6 textures" );
221
222     Test::EmitGlobalTimerSignal();
223     application.SendNotification();
224     application.Render(16);
225     DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 6, TEST_LOCATION );
226
227     tet_infoline("And that at least 2 textures were requested");
228     DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 2 ), true, TEST_LOCATION );
229     application.SendNotification();
230     application.Render(16);
231     DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 8, TEST_LOCATION );
232
233
234     tet_infoline( "Test that after 3rd tick that we have 7 textures and 1 request" );
235     Test::EmitGlobalTimerSignal();
236     application.SendNotification();
237     application.Render(16);
238     DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 7, TEST_LOCATION );
239
240     DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
241     application.SendNotification();
242     application.Render(16);
243     DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 8, TEST_LOCATION );
244
245     dummyControl.Unparent();
246   }
247   tet_infoline("Test that removing the visual from stage deletes all textures");
248   application.SendNotification();
249   application.Render(16);
250   DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 0, TEST_LOCATION );
251
252   END_TEST;
253 }
254
255 int UtcDaliAnimatedImageVisualMultiImage02(void)
256 {
257   ToolkitTestApplication application;
258   TestGlAbstraction& gl = application.GetGlAbstraction();
259
260   tet_infoline( "Test that the animated visual still works with zero sized cache" );
261
262   {
263     Property::Array urls;
264     CopyUrlsIntoArray( urls );
265
266     Property::Map propertyMap;
267     propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE );
268     propertyMap.Insert( ImageVisual::Property::URL, Property::Value(urls) );
269     propertyMap.Insert( ImageVisual::Property::BATCH_SIZE, 0);
270     propertyMap.Insert( ImageVisual::Property::CACHE_SIZE, 0);
271     propertyMap.Insert( ImageVisual::Property::FRAME_DELAY, 100);
272
273     VisualFactory factory = VisualFactory::Get();
274     Visual::Base visual = factory.CreateVisual( propertyMap ); // TexMgr::Request load tId:0
275
276     // Expect that each image is loaded each tick
277
278     DummyControl dummyControl = DummyControl::New(true);
279     Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
280     dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
281
282     dummyControl.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
283     Stage::GetCurrent().Add( dummyControl );
284     application.SendNotification();
285     application.Render(16);
286
287     tet_infoline( "Ready the visual after the visual is on stage" );
288     DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
289     application.SendNotification();
290     application.Render(16);//glGenTextures 1
291     DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 1, TEST_LOCATION );
292
293     tet_infoline( "Test that each tick, a new image is requested" );
294     Test::EmitGlobalTimerSignal(); // TexMgr::Remove tId:0
295     application.SendNotification();
296     application.Render(16);
297     DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1, 10 ), true, TEST_LOCATION );
298     application.SendNotification();
299     application.Render(16);//glGenTextures 2
300     DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 1, TEST_LOCATION );
301
302     tet_infoline( "Test that each tick, a new image is requested" );
303     Test::EmitGlobalTimerSignal(); // Internal::~TextureSet()
304     application.SendNotification();
305     application.Render(16);//glDeleteTextures 2
306     DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1, 10 ), true, TEST_LOCATION );
307     application.SendNotification();
308     application.Render(16);//glGenTextures 3
309     DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 1, TEST_LOCATION );
310
311     tet_infoline( "Test that each tick, a new image is requested" );
312     Test::EmitGlobalTimerSignal();
313     application.SendNotification();
314     application.Render(16);//glDeleteTextures 3
315     DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1, 10 ), true, TEST_LOCATION );
316     application.SendNotification();
317     application.Render(16);//Gen4
318     DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 1, TEST_LOCATION );
319     dummyControl.Unparent();
320   }
321   tet_infoline("Test that removing the visual from stage deletes all textures");
322   application.SendNotification();
323   application.Render(16);
324   DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 0, TEST_LOCATION );
325
326   END_TEST;
327 }
328
329 int UtcDaliAnimatedImageVisualMultiImage03(void)
330 {
331   ToolkitTestApplication application;
332   TestGlAbstraction& gl = application.GetGlAbstraction();
333
334   {
335     Property::Array urls1, urls2;
336     CopyUrlsIntoArray( urls1 );
337     CopyUrlsIntoArray( urls2 );
338
339     Property::Map animatedImageMap1;
340     animatedImageMap1.Insert(Visual::Property::TYPE, Visual::IMAGE );
341     animatedImageMap1.Insert( ImageVisual::Property::URL, Property::Value(urls1) );
342     animatedImageMap1.Insert( ImageVisual::Property::BATCH_SIZE, 3);
343     animatedImageMap1.Insert( ImageVisual::Property::CACHE_SIZE, 3);
344     animatedImageMap1.Insert( ImageVisual::Property::FRAME_DELAY, 100);
345
346     Property::Map animatedImageMap2;
347     animatedImageMap2.Insert(Visual::Property::TYPE, Visual::IMAGE );
348     animatedImageMap2.Insert( ImageVisual::Property::URL, Property::Value(urls2) );
349     animatedImageMap2.Insert( ImageVisual::Property::BATCH_SIZE, 2);
350     animatedImageMap2.Insert( ImageVisual::Property::CACHE_SIZE, 2);
351     animatedImageMap2.Insert( ImageVisual::Property::FRAME_DELAY, 100);
352
353     VisualFactory factory = VisualFactory::Get();
354     Visual::Base animatedImageVisual1 = factory.CreateVisual( animatedImageMap1 );
355
356     tet_infoline( "Create two image views with the same URLs, offset by 1 frame.");
357
358     DummyControl dummyControl1 = DummyControl::New(true);
359     Impl::DummyControl& dummyImpl1 = static_cast<Impl::DummyControl&>(dummyControl1.GetImplementation());
360     dummyImpl1.RegisterVisual( DummyControl::Property::TEST_VISUAL, animatedImageVisual1 );
361     dummyControl1.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
362     Stage::GetCurrent().Add( dummyControl1 );
363
364     application.SendNotification();
365     application.Render(16);
366
367     tet_infoline( "Ready the requested image after the first visual is on stage" );
368     DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 3 ), true, TEST_LOCATION );
369     application.SendNotification();
370     application.Render(16);
371     DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 3, TEST_LOCATION );
372
373     Visual::Base animatedImageVisual2 = factory.CreateVisual( animatedImageMap2 );
374     DummyControl dummyControl2 = DummyControl::New(true);
375     Impl::DummyControl& dummyImpl2 = static_cast<Impl::DummyControl&>(dummyControl2.GetImplementation());
376     dummyImpl2.RegisterVisual( DummyControl::Property::TEST_VISUAL, animatedImageVisual2 );
377     dummyControl2.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
378     Stage::GetCurrent().Add( dummyControl2 );
379     application.SendNotification();
380     application.Render(16);
381
382     tet_infoline( "The texture cache should be holding the requested images; check that the renderer has a texture" );
383     TextureSet ts = dummyControl2.GetRendererAt(0).GetTextures();
384     Texture t1 = ts.GetTexture( 0 );
385     DALI_TEST_EQUALS( ts.GetTextureCount(), 1, TEST_LOCATION );
386
387     tet_infoline( "Test that on the first tick, 1 new image is requested" );
388     Test::EmitGlobalTimerSignal(); // Both visuals should tick
389
390     DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
391     DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 3, TEST_LOCATION );
392
393     ts = dummyControl2.GetRendererAt(0).GetTextures();
394     Texture t2 = ts.GetTexture( 0 );
395     DALI_TEST_CHECK( t1 != t2 );
396
397     dummyControl1.Unparent();
398     dummyControl2.Unparent();
399   }
400   tet_infoline("Test that removing the visual from stage deletes all textures");
401   application.SendNotification();
402   application.Render(16);
403   DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 0, TEST_LOCATION );
404
405   END_TEST;
406 }
407
408
409 int UtcDaliAnimatedImageVisualMultiImage04(void)
410 {
411   ToolkitTestApplication application;
412   TestGlAbstraction& gl = application.GetGlAbstraction();
413   TraceCallStack& textureTrace = gl.GetTextureTrace();
414   textureTrace.Enable(true);
415
416   tet_infoline( "Test that if the cache size is the same as the number of urls, that once the cache is full, no new images are loaded" );
417
418   Property::Array urls;
419   CopyUrlsIntoArray( urls );
420
421   {
422     Property::Map propertyMap;
423     propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE );
424     propertyMap.Insert( ImageVisual::Property::URL, Property::Value(urls) );
425     propertyMap.Insert( ImageVisual::Property::BATCH_SIZE, 6);
426     propertyMap.Insert( ImageVisual::Property::CACHE_SIZE, 11);
427     propertyMap.Insert( ImageVisual::Property::FRAME_DELAY, 100);
428
429     VisualFactory factory = VisualFactory::Get();
430     Visual::Base visual = factory.CreateVisual( propertyMap );
431
432     tet_infoline( "Expect that a batch of 7 textures has been requested." );
433
434     DummyControl dummyControl = DummyControl::New(true);
435     Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
436     dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
437
438     dummyControl.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
439     Stage::GetCurrent().Add( dummyControl );
440     application.SendNotification();
441     application.Render(16);
442
443     tet_infoline( "Wait for the first batch to complete" );
444     DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 6 ), true, TEST_LOCATION );
445
446     tet_infoline( "Test that a timer has been started" );
447     DALI_TEST_EQUALS( Test::GetTimerCount(), 1, TEST_LOCATION );
448
449     application.SendNotification();
450     application.Render(16);
451
452     DALI_TEST_EQUALS( gl.GetLastGenTextureId(), 6, TEST_LOCATION );
453     tet_infoline( "Test that after 1 tick, and 5 file loads completed, that we have 11 textures" );
454     Test::EmitGlobalTimerSignal();
455     application.SendNotification();
456     application.Render(16);
457
458     // Expect the second batch has been requested
459     DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 5 ), true, TEST_LOCATION );
460
461     application.SendNotification();
462     application.Render(16);
463     DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 11, TEST_LOCATION );
464
465     tet_infoline( "Test that after 2 ticks that we have 11 textures and no requests" );
466
467     Test::EmitGlobalTimerSignal();
468     application.SendNotification();
469     application.Render(16);
470     DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1, 5 ), false, TEST_LOCATION );
471     application.SendNotification();
472     application.Render(16);
473     DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 11, TEST_LOCATION );
474
475     tet_infoline( "Test that after 3rd tick that we have 11 textures and no requests" );
476     Test::EmitGlobalTimerSignal();
477     application.SendNotification();
478     application.Render(16);
479
480     DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1, 5 ), false, TEST_LOCATION );
481     application.SendNotification();
482     application.Render(16);
483     DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 11, TEST_LOCATION );
484
485     dummyControl.Unparent();
486   }
487
488   tet_infoline("Test that removing the visual from stage deletes all textures");
489   application.SendNotification();
490   application.Render(16);
491   DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 0, TEST_LOCATION );
492
493   END_TEST;
494 }
495
496
497 int UtcDaliAnimatedImageVisualMultiImage05(void)
498 {
499   ToolkitTestApplication application;
500   TestGlAbstraction& gl = application.GetGlAbstraction();
501
502   tet_infoline( "Test that if the cache size is the same as the number of urls, that removing a partially loaded visual removes all textures" );
503
504   Property::Array urls;
505   CopyUrlsIntoArray( urls );
506
507   {
508     Property::Map propertyMap;
509     propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE );
510     propertyMap.Insert( ImageVisual::Property::URL, Property::Value(urls) );
511     propertyMap.Insert( ImageVisual::Property::BATCH_SIZE, 4);
512     propertyMap.Insert( ImageVisual::Property::CACHE_SIZE, 11);
513     propertyMap.Insert( ImageVisual::Property::FRAME_DELAY, 100);
514
515     VisualFactory factory = VisualFactory::Get();
516     Visual::Base visual = factory.CreateVisual( propertyMap );
517
518     tet_infoline( "Expect that a batch of 4 textures has been requested." );
519
520     DummyControl dummyControl = DummyControl::New(true);
521     Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
522     dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
523
524     dummyControl.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
525     Stage::GetCurrent().Add( dummyControl );
526     application.SendNotification();
527     application.Render(16);
528
529     tet_infoline( "Wait for the first batch to complete" );
530     DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 4 ), true, TEST_LOCATION );
531
532     tet_infoline( "Test that a timer has been started" );
533     DALI_TEST_EQUALS( Test::GetTimerCount(), 1, TEST_LOCATION );
534
535     application.SendNotification();
536     application.Render(16);
537
538     tet_infoline( "Test that a timer has been started" );
539     Test::EmitGlobalTimerSignal();
540     application.SendNotification();
541     application.Render(16);
542
543     dummyControl.Unparent();
544   }
545
546   application.SendNotification();
547   application.Render(16);
548   DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 0, TEST_LOCATION );
549
550   tet_infoline( "Test that pending batch of image loads are cancelled instead of uploaded");
551   DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 4 ), true, TEST_LOCATION );
552   application.SendNotification();
553   application.Render(16);
554   DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 0, TEST_LOCATION );
555
556   END_TEST;
557 }
558
559 void TestLoopCount( ToolkitTestApplication &application, DummyControl &dummyControl, uint16_t frameCount, uint16_t loopCount, const char * location )
560 {
561   TestGlAbstraction& gl = application.GetGlAbstraction();
562   TraceCallStack& textureTrace = gl.GetTextureTrace();
563
564   textureTrace.Enable(true);
565   Stage::GetCurrent().Add( dummyControl );
566   application.SendNotification();
567   application.Render(16);
568
569   tet_infoline( "Test that a timer has been created" );
570   DALI_TEST_EQUALS( Test::GetTimerCount(), 1, TEST_INNER_LOCATION( location ) );
571
572   for ( uint16_t i = 0; i <= loopCount; i++ )
573   {
574     for ( uint16_t j = 0; j < frameCount; j++ )
575     {
576       tet_printf( "Test that after %u ticks, and we have %u frame \n", j + 1u, j + 1u );
577       Test::EmitGlobalTimerSignal();
578       application.SendNotification();
579       application.Render(16);
580       DALI_TEST_EQUALS( gl.GetNumGeneratedTextures(), 1, TEST_INNER_LOCATION( location ) );
581       DALI_TEST_EQUALS( Test::AreTimersRunning(), true, TEST_INNER_LOCATION( location ) );
582     }
583     tet_printf( "\nTest Loop %u \n", i );
584   }
585
586   tet_printf( "Test that after %u loops, and we have no frame. Timer should stop \n", loopCount );
587   Test::EmitGlobalTimerSignal();
588   application.SendNotification();
589   application.Render(16);
590   DALI_TEST_EQUALS( Test::AreTimersRunning(), false, TEST_INNER_LOCATION( location ) );
591
592   dummyControl.Unparent();
593 }
594
595 int UtcDaliAnimatedImageVisualLoopCount(void)
596 {
597   ToolkitTestApplication application;
598
599   tet_infoline( "UtcDaliAnimatedImageVisualLoopCount" );
600
601   {
602     // request AnimatedImageVisual with a property map
603     // Test with no (0) loop count
604     VisualFactory factory = VisualFactory::Get();
605     Visual::Base animatedImageVisual = factory.CreateVisual(
606       Property::Map()
607       .Add( Toolkit::Visual::Property::TYPE, Visual::ANIMATED_IMAGE )
608       .Add( ImageVisual::Property::URL, TEST_GIF_FILE_NAME )
609       .Add( ImageVisual::Property::PIXEL_AREA, Vector4() )
610       .Add( ImageVisual::Property::WRAP_MODE_U, WrapMode::REPEAT )
611       .Add( ImageVisual::Property::WRAP_MODE_V, WrapMode::DEFAULT )
612       .Add( DevelImageVisual::Property::LOOP_COUNT, 0 ));
613
614     DummyControl dummyControl = DummyControl::New(true);
615     Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
616     dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, animatedImageVisual );
617     dummyControl.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
618
619     TestLoopCount( application, dummyControl, 4, 0, TEST_LOCATION );
620
621     // Test with no (1) loop count. Request AnimatedImageVisual with a property map
622     animatedImageVisual = factory.CreateVisual(
623       Property::Map()
624       .Add( Toolkit::Visual::Property::TYPE, Visual::ANIMATED_IMAGE )
625       .Add( ImageVisual::Property::URL, TEST_GIF_FILE_NAME )
626       .Add( ImageVisual::Property::PIXEL_AREA, Vector4() )
627       .Add( ImageVisual::Property::WRAP_MODE_U, WrapMode::REPEAT )
628       .Add( ImageVisual::Property::WRAP_MODE_V, WrapMode::DEFAULT )
629       .Add( DevelImageVisual::Property::LOOP_COUNT, 1 ));
630
631     dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, animatedImageVisual );
632
633     TestLoopCount( application, dummyControl, 4, 1, TEST_LOCATION );
634
635     // Test with no (100) loop count. Request AnimatedImageVisual with a property map
636     animatedImageVisual = factory.CreateVisual(
637       Property::Map()
638       .Add( Toolkit::Visual::Property::TYPE, Visual::ANIMATED_IMAGE )
639       .Add( ImageVisual::Property::URL, TEST_GIF_FILE_NAME )
640       .Add( ImageVisual::Property::PIXEL_AREA, Vector4() )
641       .Add( ImageVisual::Property::WRAP_MODE_U, WrapMode::REPEAT )
642       .Add( ImageVisual::Property::WRAP_MODE_V, WrapMode::DEFAULT )
643       .Add( DevelImageVisual::Property::LOOP_COUNT, 100 ));
644
645     dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, animatedImageVisual );
646
647     TestLoopCount( application, dummyControl, 4, 100, TEST_LOCATION );
648   }
649
650   END_TEST;
651 }