Dali 3D User Interface Engine
utc-Dali-Internal-ImageFactory.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 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>
22 #include <dali-test-suite-utils.h>
23 
24 // Internal headers are allowed here
29 
30 using namespace Dali;
31 
33 using Internal::ImageFactory;
35 using Internal::ImageAttributes;
36 
37 namespace
38 {
39 
40 static const char* gTestImageFilename = "icon_wrt.png";
41 
42 static void EmulateImageLoaded( TestApplication& application, unsigned int width, unsigned int height )
43 {
44  // emulate load success
45  Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
47  Integration::ResourcePointer resource( bitmap );
48  bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, width, height, width, height );
49  if( request )
50  {
51  application.GetPlatform().SetResourceLoaded( request->GetId(), request->GetType()->id, resource );
52  }
53 
54  application.SendNotification();
55  application.Render();
56 
57  application.SendNotification();
58  application.Render();
59 }
60 
61 } //anonymous namespace
62 
63 
64 // High-level test for image factory request cache
66 {
67  TestApplication application;
68 
69  tet_infoline( "UtcDaliImageFactoryCachedRequest01 - Request same image more than once" );
70 
72 
73  application.SendNotification();
74  application.Render();
76  application.GetPlatform().ResetTrace();
77 
79 
80  application.SendNotification();
81  application.Render();
82 
83  // check resource is not loaded twice
85  application.GetPlatform().ResetTrace();
86 
88 
89  application.SendNotification();
90  application.Render();
92  END_TEST;
93 }
94 
95 // High-level test for image factory request cache
97 {
98  TestApplication application;
99 
100  // testing resource deletion when taken off stage
101  tet_infoline( "UtcDaliImageFactoryCachedRequest02 - Discard previously requested resource" );
102 
104  ImageActor actor = ImageActor::New( image );
105 
106  application.SendNotification();
107  application.Render();
108 
110  application.GetPlatform().ResetTrace();
111 
112  // Add actor to stage
113  Stage::GetCurrent().Add( actor );
114 
115  application.Render();
116  application.SendNotification();
117  application.Render();
118  application.SendNotification();
119 
120  // Release the resource, request is still cached
121  Stage::GetCurrent().Remove( actor );
122  application.Render();
123  application.SendNotification();
124  application.Render();
125  application.SendNotification();
126 
127  // Should find stale request in cache, so load image from filesystem
129 
130  application.SendNotification();
131  application.Render();
132 
134  application.GetPlatform().ResetTrace();
135 
136  // Resource is reloaded
138 
139  application.SendNotification();
140  application.Render();
141  application.SendNotification();
142  application.Render();
143 
145  END_TEST;
146 }
147 
148 // Low-level test for image factory request cache
150 {
151  TestApplication application;
152  tet_infoline( "UtcDaliImageFactoryCachedRequest03 - Request same image more than once - Request Ids" );
153 
154  ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
155 
156  RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
157  ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
158 
159  RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, NULL );
160  ResourceTicketPtr ticket2 = imageFactory.Load( *req2.Get() );
161  DALI_TEST_EQUALS( req, req2, TEST_LOCATION );
162  DALI_TEST_EQUALS( ticket, ticket2, TEST_LOCATION );
163 
164  req2 = imageFactory.RegisterRequest( gTestImageFilename, NULL );
165  ResourceTicketPtr ticket3 = imageFactory.Load( *req2.Get() );
166  DALI_TEST_EQUALS( req, req2, TEST_LOCATION );
167  DALI_TEST_EQUALS( ticket, ticket3, TEST_LOCATION );
168 
169  // request differs in scaled size - not default size
170  ImageAttributes attr = ImageAttributes::New( 80, 160);
171  req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr );
172  ResourceTicketPtr ticket4 = imageFactory.Load( *req2.Get() );
173  DALI_TEST_CHECK( req != req2 );
174  END_TEST;
175 }
176 
177 // Low-level test for image factory request cache
179 {
180  TestApplication application;
181  tet_infoline( "UtcDaliImageFactoryCachedRequest04 - Request same image with different Image objects - Request Ids" );
182 
183  ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
184 
185  ImageAttributes attr = ImageAttributes::New( 80, 160 );
186  RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, &attr );
187 
188  ImageAttributes attr2 = ImageAttributes::New( 80, 160 );
189  RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr2 );
190  DALI_TEST_EQUALS( req, req2, TEST_LOCATION );
191  END_TEST;
192 }
193 
194 // Different requests, compatible resource
196 {
197  TestApplication application;
198  tet_infoline( "UtcDaliImageFactoryCompatibleResource01 - Two requests mapping to same resource" );
199 
200  ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
201 
202  Vector2 testSize(80.0f, 80.0f);
203  application.GetPlatform().SetClosestImageSize(testSize);
204 
205  // request with default attributes ( size is 0,0 )
206  RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
207  ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
208 
209  application.SendNotification();
210  application.Render();
211  application.SendNotification();
212  application.Render();
213 
214  // emulate load success
215  EmulateImageLoaded( application, 80, 80 );
216 
217  // Request a second load using exact-match image size:
218  ImageAttributes attr = ImageAttributes::New();
219  attr.SetSize( 80, 80 );
220  RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr );
221  ResourceTicketPtr ticket2 = imageFactory.Load( *req2.Get() );
222 
223  DALI_TEST_CHECK( req != req2 ); // different requests
224  DALI_TEST_EQUALS( ticket->GetId(), ticket2->GetId(), TEST_LOCATION ); // same resource
225  END_TEST;
226 }
227 
228 // Different requests, compatible resource
230 {
231  TestApplication application;
232  tet_infoline( "UtcDaliImageFactoryCompatibleResource02 - Two requests mapping to same resource." );
233 
234  ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
235 
236  Vector2 testSize( 2048.0f, 2048.0f );
237  application.GetPlatform().SetClosestImageSize( testSize );
238 
239  // request with default attributes ( size is 0,0 )
240  RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
241  ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
242 
243  application.SendNotification();
244  application.Render();
245  application.SendNotification();
246  application.Render();
247 
248  // emulate load success
249  EmulateImageLoaded( application, testSize.x, testSize.y );
250 
251  // Request slightly bigger size than actual image.
252  // This will load the same resource as the ImageFactory cache uses a small fudge factor in matching.
253  // See UtcDaliImageFactoryReload06
254  ImageAttributes attr = ImageAttributes::New();
255  attr.SetSize( testSize.x + 1, testSize.y + 1 );
256  RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr );
257  ResourceTicketPtr ticket2 = imageFactory.Load( *req2.Get() );
258 
259  DALI_TEST_CHECK( req != req2 ); // different requests
260  DALI_TEST_EQUALS( ticket->GetId(), ticket2->GetId(), TEST_LOCATION ); // same resource
261  END_TEST;
262 }
263 
264 // Different requests, incompatible resource, so two loads result:
266 {
267  TestApplication application;
268  tet_infoline( "UtcDaliImageFactoryCompatibleResource02 - Two requests mapping to same resource." );
269 
270  ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
271 
272  Vector2 testSize(2048.0f, 2048.0f);
273  application.GetPlatform().SetClosestImageSize(testSize);
274 
275  // request with default attributes ( size is 0,0 )
276  RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
277  ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
278 
279  application.SendNotification();
280  application.Render();
281  application.SendNotification();
282  application.Render();
283 
284  // emulate load success
285  EmulateImageLoaded( application, testSize.x, testSize.y );
286 
287  // Request substantially different size than actual image.
288  // This will issue a second resource load as difference in sizes is greater than
289  // the small fudge factor used in the ImageFactory cache.
290  ImageAttributes attr = ImageAttributes::New();
291  attr.SetSize( testSize.x - 16, testSize.y - 16 );
292  RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr );
293  ResourceTicketPtr ticket2 = imageFactory.Load( *req2.Get() );
294 
295  DALI_TEST_CHECK( req != req2 ); // different requests
296  DALI_TEST_CHECK( ticket->GetId() != ticket2->GetId() ); // differnet resources
297  END_TEST;
298 }
299 
300 // Different requests, compatible resource
302 {
303  TestApplication application;
304  tet_infoline( "UtcDaliImageFactoryCompatibleResource03 - Two requests mapping to same resource" );
305 
306  ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
307 
308  Vector2 testSize(80.0f, 80.0f);
309  application.GetPlatform().SetClosestImageSize(testSize);
310 
311  // this time use defined attributes, nut just NULL
312  ImageAttributes attr = ImageAttributes::New();
313  attr.SetSize( 120, 120 );
314 
315  // request with default attributes ( size is 0,0 )
316  RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, &attr );
317  ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
318 
319  application.SendNotification();
320  application.Render();
321  application.SendNotification();
322  application.Render();
323 
324  // emulate load success
325  EmulateImageLoaded( application, 80, 80 );
326 
327  ImageAttributes attr2 = ImageAttributes::New();
328  attr2.SetSize( 80, 80 );
329  RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr2 );
330  ResourceTicketPtr ticket2 = imageFactory.Load( *req2.Get() );
331 
332  DALI_TEST_CHECK( req != req2 ); // different requests
333  DALI_TEST_EQUALS( ticket->GetId(), ticket2->GetId(), TEST_LOCATION ); // same resource
334  END_TEST;
335 }
336 
337 // Test for reloading image
339 {
340  TestApplication application;
341  tet_infoline( "UtcDaliImageFactoryReload01 - Reload unchanged image" );
342 
343  Vector2 testSize(80.0f, 80.0f);
344  application.GetPlatform().SetClosestImageSize(testSize);
345 
346  ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
347 
348  RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
349  ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
350 
351  ResourceTicketPtr ticket2 = imageFactory.Reload( *req.Get() );
352  DALI_TEST_EQUALS( ticket, ticket2, TEST_LOCATION );
353 
354  ResourceTicketPtr ticket3 = imageFactory.Reload( *req.Get() );
355  DALI_TEST_EQUALS( ticket, ticket3, TEST_LOCATION );
356  END_TEST;
357 }
358 
359 // Testing file system access when reloading image
361 {
362  TestApplication application;
363  tet_infoline( "UtcDaliImageFactoryReload02 - Reload unchanged image" );
364 
365  ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
366 
367  Vector2 testSize(80.0f, 80.0f);
368  application.GetPlatform().SetClosestImageSize(testSize);
369 
370  RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
371  ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
372 
373  application.SendNotification();
374  application.Render();
375  application.SendNotification();
376  application.Render();
377 
379  application.GetPlatform().ResetTrace();
380 
381  ResourceTicketPtr ticket2 = imageFactory.Reload( *req.Get() );
382 
383  application.SendNotification();
384  application.Render();
385  application.SendNotification();
386  application.Render();
387 
388  DALI_TEST_EQUALS( ticket, ticket2, TEST_LOCATION );
389  // resource is still loading, do not issue another request
391 
392  // emulate load success
393  EmulateImageLoaded( application, 80, 80 );
394 
395  ResourceTicketPtr ticket3 = imageFactory.Reload( *req.Get() );
396 
397  application.SendNotification();
398  application.Render();
399  application.SendNotification();
400  application.Render();
401 
402  DALI_TEST_EQUALS( ticket, ticket3, TEST_LOCATION );
404  application.GetPlatform().ResetTrace();
405 
406  ticket3 = imageFactory.Reload( *req.Get() );
407 
408  application.SendNotification();
409  application.Render();
410  application.SendNotification();
411  application.Render();
412 
414  END_TEST;
415 }
416 
417 // Test for reloading changed image
419 {
420  TestApplication application;
421  tet_infoline( "UtcDaliImageFactoryReload03 - Reload changed image" );
422 
423  ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
424 
425  Vector2 testSize( 80.0f, 80.0f );
426  application.GetPlatform().SetClosestImageSize( testSize );
427 
428  RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
429  ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
430 
431  application.SendNotification();
432  application.Render();
433 
434  // emulate load success
435  EmulateImageLoaded( application, 80, 80 );
436 
437  Vector2 newSize( 192.0f, 192.0f );
438  application.GetPlatform().SetClosestImageSize( newSize );
439 
440  // Image file changed size, new resource request should be issued
441  ResourceTicketPtr ticket2 = imageFactory.Reload( *req.Get() );
442  DALI_TEST_CHECK( ticket != ticket2 );
443 
444  ResourceTicketPtr ticket3 = imageFactory.Reload( *req.Get() );
445  DALI_TEST_EQUALS( ticket2, ticket3, TEST_LOCATION );
446  END_TEST;
447 }
448 
449 // Testing file system access when reloading image
451 {
452  TestApplication application;
453  tet_infoline( "UtcDaliImageFactoryReload04 - Reload unchanged image" );
454 
455  ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
456 
457  Vector2 testSize(80.0f, 80.0f);
458  application.GetPlatform().SetClosestImageSize(testSize);
459 
460  RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
461  ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
462 
463  application.SendNotification();
464  application.Render();
465 
467  application.GetPlatform().ResetTrace();
468 
469  ResourceTicketPtr ticket2 = imageFactory.Reload( *req.Get() );
470 
471  application.SendNotification();
472  application.Render();
473  application.SendNotification();
474  application.Render();
475 
476  DALI_TEST_EQUALS( ticket, ticket2, TEST_LOCATION );
477  // resource is still loading, do not issue another request
479 
480  // emulate load success
481  EmulateImageLoaded( application, 80, 80 );
482 
483  ResourceTicketPtr ticket3 = imageFactory.Reload( *req.Get() );
484 
485  application.SendNotification();
486  application.Render();
487  application.SendNotification();
488  application.Render();
489 
490  // size didn't change, using same ticket
491  DALI_TEST_EQUALS( ticket, ticket3, TEST_LOCATION );
493  application.GetPlatform().ResetTrace();
494 
495  // still loading
496  ticket3 = imageFactory.Reload( *req.Get() );
497  application.SendNotification();
498  application.Render();
499  application.SendNotification();
500  application.Render();
501 
503  END_TEST;
504 }
505 
506 // Testing OnDemand + Reload
507 // Reload should have no effect if OnDemand Image is not loaded yet, as stated in the API documentation
509 {
510  TestApplication application;
511 
512  tet_infoline( "UtcDaliImageFactoryReload05 - Reload OnDemand image" );
513 
514  ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
515 
516  Vector2 testSize(80.0f, 80.0f);
517  application.GetPlatform().SetClosestImageSize(testSize);
518 
519  RequestPtr req;
520  ImageAttributes attr = ImageAttributes::New();
521  attr.SetSize( 80, 80 );
522 
523  // this happens first when loading Image OnDemand
524  req = imageFactory.RegisterRequest( gTestImageFilename, &attr );
525 
526  application.SendNotification();
527  application.Render();
528 
529  ResourceTicketPtr ticket = imageFactory.Reload( *req.Get() );
530 
532  DALI_TEST_CHECK( !ticket );
533 
534  // this happens when Image is put on stage
535  ticket = imageFactory.Load( *req.Get() );
536 
537  application.SendNotification();
538  application.Render();
539 
541  DALI_TEST_CHECK( ticket );
542  application.GetPlatform().ResetTrace();
543 
544  ticket = imageFactory.Reload( *req.Get() );
545 
546  application.SendNotification();
547  application.Render();
548  application.SendNotification();
549  application.Render();
550 
551  // still loading, no new request
553 
554  // emulate load success
555  EmulateImageLoaded( application, 80, 80 );
556 
557  ticket = imageFactory.Reload( *req.Get() );
558 
559  application.SendNotification();
560  application.Render();
561 
562  application.SendNotification();
563  application.Render();
564 
565 
567  END_TEST;
568 }
569 
570 // Initally two different requests map to same resource.
571 // After overwriting the file, they load different image resources.
573 {
574  TestApplication application;
575  tet_infoline( "UtcDaliImageFactoryReload06 - Two requests first mapping to same resource, then different resources." );
576 
577  ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
578 
579  Vector2 testSize(2048.0f, 2048.0f);
580  application.GetPlatform().SetClosestImageSize( testSize );
581 
582  // request with default attributes ( size is 0,0 )
583  RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
584  ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
585 
586  application.SendNotification();
587  application.Render();
588  application.SendNotification();
589  application.Render();
590 
591  // emulate load success
592  EmulateImageLoaded( application, testSize.x, testSize.y );
593 
594  // Request bigger size than actual image.
595  // This will load the same resource.
596  // However if image size changes later on to eg. 512*512 (file is overwritten),
597  // reissuing these two requests will load different resources.
598  ImageAttributes attr = ImageAttributes::New();
599  attr.SetSize( testSize.x + 1, testSize.y + 1 );
600  RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr );
601  ResourceTicketPtr ticket2 = imageFactory.Load( *req2.Get() );
602 
603  DALI_TEST_CHECK( req != req2 ); // different requests
604  DALI_TEST_EQUALS( ticket->GetId(), ticket2->GetId(), TEST_LOCATION ); // same resource
605 
606  Vector2 newSize(512.0f, 512.0f);
607  application.GetPlatform().SetClosestImageSize(newSize);
608 
609  // reload fixed size (192,192) request
610  ticket2 = imageFactory.Reload( *req2.Get() );
611 
612  // emulate load success
613  // note: this is the only way to emulate what size is loaded by platform abstraction
614  EmulateImageLoaded( application, testSize.x + 1, testSize.y + 1 );
615 
616  // reload default size request
617  ticket = imageFactory.Reload( *req.Get() );
618 
619  DALI_TEST_CHECK( ticket->GetId() != ticket2->GetId() ); // different resources
620  END_TEST;
621 }
Dali Docs Home
Read more about Dali