2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <dali/public-api/dali-core.h>
22 #include <dali-test-suite-utils.h>
24 // Internal headers are allowed here
25 #include <dali/internal/event/common/thread-local-storage.h>
26 #include <dali/internal/event/images/image-factory.h>
27 #include <dali/internal/event/resources/resource-ticket.h>
31 using Internal::ResourceTicketPtr;
32 using Internal::ImageFactory;
33 using Internal::ImageFactoryCache::RequestPtr;
39 static const char* gTestImageFilename = "icon_wrt.png";
41 static void EmulateImageLoaded( TestApplication& application, unsigned int width, unsigned int height )
43 // emulate load success
44 Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
45 Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
46 Integration::ResourcePointer resource( bitmap );
47 bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, width, height, width, height );
50 application.GetPlatform().SetResourceLoaded( request->GetId(), request->GetType()->id, resource );
53 application.SendNotification();
56 application.SendNotification();
60 } //anonymous namespace
63 // High-level test for image factory request cache
64 int UtcDaliImageFactoryUseCachedRequest01(void)
66 TestApplication application;
68 tet_infoline( "UtcDaliImageFactoryCachedRequest01 - Request same image more than once" );
70 Image image = Image::New( gTestImageFilename );
72 application.SendNotification();
74 DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
75 application.GetPlatform().ResetTrace();
77 Image image2 = Image::New( gTestImageFilename );
79 application.SendNotification();
82 // check resource is not loaded twice
83 DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
84 application.GetPlatform().ResetTrace();
86 Image image3 = Image::New( gTestImageFilename );
88 application.SendNotification();
90 DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
94 // High-level test for image factory request cache
95 int UtcDaliImageFactoryUseCachedRequest02(void)
97 TestApplication application;
99 // testing resource deletion when taken off stage
100 tet_infoline( "UtcDaliImageFactoryCachedRequest02 - Discard previously requested resource" );
102 Image image = Image::New( gTestImageFilename, Image::Immediate, Image::Unused );
103 ImageActor actor = ImageActor::New( image );
105 application.SendNotification();
106 application.Render();
108 DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
109 application.GetPlatform().ResetTrace();
111 // Add actor to stage
112 Stage::GetCurrent().Add( actor );
114 application.Render();
115 application.SendNotification();
116 application.Render();
117 application.SendNotification();
119 // Release the resource, request is still cached
120 Stage::GetCurrent().Remove( actor );
121 application.Render();
122 application.SendNotification();
123 application.Render();
124 application.SendNotification();
126 // Should find stale request in cache, so load image from filesystem
127 Image image2 = Image::New( gTestImageFilename );
129 application.SendNotification();
130 application.Render();
132 DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
133 application.GetPlatform().ResetTrace();
135 // Resource is reloaded
136 Image image3 = Image::New( gTestImageFilename );
138 application.SendNotification();
139 application.Render();
140 application.SendNotification();
141 application.Render();
143 DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
147 // Low-level test for image factory request cache
148 int UtcDaliImageFactoryUseCachedRequest03(void)
150 TestApplication application;
151 tet_infoline( "UtcDaliImageFactoryCachedRequest03 - Request same image more than once - Request Ids" );
153 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
155 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
156 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
158 RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, NULL );
159 ResourceTicketPtr ticket2 = imageFactory.Load( *req2.Get() );
160 DALI_TEST_EQUALS( req, req2, TEST_LOCATION );
161 DALI_TEST_EQUALS( ticket, ticket2, TEST_LOCATION );
163 req2 = imageFactory.RegisterRequest( gTestImageFilename, NULL );
164 ResourceTicketPtr ticket3 = imageFactory.Load( *req2.Get() );
165 DALI_TEST_EQUALS( req, req2, TEST_LOCATION );
166 DALI_TEST_EQUALS( ticket, ticket3, TEST_LOCATION );
168 // request differs in scaled size - not default size
169 ImageAttributes attr = ImageAttributes::New( 80, 160, Pixel::BGR8888 );
170 req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr );
171 ResourceTicketPtr ticket4 = imageFactory.Load( *req2.Get() );
172 DALI_TEST_CHECK( req != req2 );
176 // Low-level test for image factory request cache
177 int UtcDaliImageFactoryUseCachedRequest04(void)
179 TestApplication application;
180 tet_infoline( "UtcDaliImageFactoryCachedRequest04 - Request same image with different Image objects - Request Ids" );
182 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
184 ImageAttributes attr = ImageAttributes::New( 80, 160, Pixel::BGR8888 );
185 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, &attr );
187 ImageAttributes attr2 = ImageAttributes::New( 80, 160, Pixel::BGR8888 );
188 RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr2 );
189 DALI_TEST_EQUALS( req, req2, TEST_LOCATION );
193 // Different requests, compatible resource
194 int UtcDaliImageFactoryCompatibleResource01(void)
196 TestApplication application;
197 tet_infoline( "UtcDaliImageFactoryCompatibleResource01 - Two requests mapping to same resource" );
199 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
201 Vector2 testSize(80.0f, 80.0f);
202 application.GetPlatform().SetClosestImageSize(testSize);
204 // request with default attributes ( size is 0,0 )
205 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
206 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
208 application.SendNotification();
209 application.Render();
210 application.SendNotification();
211 application.Render();
213 // emulate load success
214 EmulateImageLoaded( application, 80, 80 );
216 // Request a second load using exact-match image size:
217 ImageAttributes attr = ImageAttributes::New();
218 attr.SetSize( 80, 80 );
219 RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr );
220 ResourceTicketPtr ticket2 = imageFactory.Load( *req2.Get() );
222 DALI_TEST_CHECK( req != req2 ); // different requests
223 DALI_TEST_EQUALS( ticket->GetId(), ticket2->GetId(), TEST_LOCATION ); // same resource
227 // Different requests, compatible resource
228 int UtcDaliImageFactoryCompatibleResource02(void)
230 TestApplication application;
231 tet_infoline( "UtcDaliImageFactoryCompatibleResource02 - Two requests mapping to same resource." );
233 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
235 Vector2 testSize( 2048.0f, 2048.0f );
236 application.GetPlatform().SetClosestImageSize( testSize );
238 // request with default attributes ( size is 0,0 )
239 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
240 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
242 application.SendNotification();
243 application.Render();
244 application.SendNotification();
245 application.Render();
247 // emulate load success
248 EmulateImageLoaded( application, testSize.x, testSize.y );
250 // Request slightly bigger size than actual image.
251 // This will load the same resource as the ImageFactory cache uses a small fudge factor in matching.
252 // See UtcDaliImageFactoryReload06
253 ImageAttributes attr = ImageAttributes::New();
254 attr.SetSize( testSize.x + 1, testSize.y + 1 );
255 RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr );
256 ResourceTicketPtr ticket2 = imageFactory.Load( *req2.Get() );
258 DALI_TEST_CHECK( req != req2 ); // different requests
259 DALI_TEST_EQUALS( ticket->GetId(), ticket2->GetId(), TEST_LOCATION ); // same resource
263 // Different requests, incompatible resource, so two loads result:
264 int UtcDaliImageFactoryInCompatibleResource(void)
266 TestApplication application;
267 tet_infoline( "UtcDaliImageFactoryCompatibleResource02 - Two requests mapping to same resource." );
269 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
271 Vector2 testSize(2048.0f, 2048.0f);
272 application.GetPlatform().SetClosestImageSize(testSize);
274 // request with default attributes ( size is 0,0 )
275 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
276 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
278 application.SendNotification();
279 application.Render();
280 application.SendNotification();
281 application.Render();
283 // emulate load success
284 EmulateImageLoaded( application, testSize.x, testSize.y );
286 // Request substantially different size than actual image.
287 // This will issue a second resource load as difference in sizes is greater than
288 // the small fudge factor used in the ImageFactory cache.
289 ImageAttributes attr = ImageAttributes::New();
290 attr.SetSize( testSize.x - 16, testSize.y - 16 );
291 RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr );
292 ResourceTicketPtr ticket2 = imageFactory.Load( *req2.Get() );
294 DALI_TEST_CHECK( req != req2 ); // different requests
295 DALI_TEST_CHECK( ticket->GetId() != ticket2->GetId() ); // differnet resources
299 // Different requests, compatible resource
300 int UtcDaliImageFactoryCompatibleResource03(void)
302 TestApplication application;
303 tet_infoline( "UtcDaliImageFactoryCompatibleResource03 - Two requests mapping to same resource" );
305 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
307 Vector2 testSize(80.0f, 80.0f);
308 application.GetPlatform().SetClosestImageSize(testSize);
310 // this time use defined attributes, nut just NULL
311 ImageAttributes attr = ImageAttributes::New();
312 attr.SetSize( 120, 120 );
314 // request with default attributes ( size is 0,0 )
315 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, &attr );
316 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
318 application.SendNotification();
319 application.Render();
320 application.SendNotification();
321 application.Render();
323 // emulate load success
324 EmulateImageLoaded( application, 80, 80 );
326 ImageAttributes attr2 = ImageAttributes::New();
327 attr2.SetSize( 80, 80 );
328 RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr2 );
329 ResourceTicketPtr ticket2 = imageFactory.Load( *req2.Get() );
331 DALI_TEST_CHECK( req != req2 ); // different requests
332 DALI_TEST_EQUALS( ticket->GetId(), ticket2->GetId(), TEST_LOCATION ); // same resource
336 // Test for reloading image
337 int UtcDaliImageFactoryReload01(void)
339 TestApplication application;
340 tet_infoline( "UtcDaliImageFactoryReload01 - Reload unchanged image" );
342 Vector2 testSize(80.0f, 80.0f);
343 application.GetPlatform().SetClosestImageSize(testSize);
345 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
347 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
348 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
350 ResourceTicketPtr ticket2 = imageFactory.Reload( *req.Get() );
351 DALI_TEST_EQUALS( ticket, ticket2, TEST_LOCATION );
353 ResourceTicketPtr ticket3 = imageFactory.Reload( *req.Get() );
354 DALI_TEST_EQUALS( ticket, ticket3, TEST_LOCATION );
358 // Testing file system access when reloading image
359 int UtcDaliImageFactoryReload02(void)
361 TestApplication application;
362 tet_infoline( "UtcDaliImageFactoryReload02 - Reload unchanged image" );
364 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
366 Vector2 testSize(80.0f, 80.0f);
367 application.GetPlatform().SetClosestImageSize(testSize);
369 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
370 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
372 application.SendNotification();
373 application.Render();
374 application.SendNotification();
375 application.Render();
377 DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
378 application.GetPlatform().ResetTrace();
380 ResourceTicketPtr ticket2 = imageFactory.Reload( *req.Get() );
382 application.SendNotification();
383 application.Render();
384 application.SendNotification();
385 application.Render();
387 DALI_TEST_EQUALS( ticket, ticket2, TEST_LOCATION );
388 // resource is still loading, do not issue another request
389 DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
391 // emulate load success
392 EmulateImageLoaded( application, 80, 80 );
394 ResourceTicketPtr ticket3 = imageFactory.Reload( *req.Get() );
396 application.SendNotification();
397 application.Render();
398 application.SendNotification();
399 application.Render();
401 DALI_TEST_EQUALS( ticket, ticket3, TEST_LOCATION );
402 DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
403 application.GetPlatform().ResetTrace();
405 ticket3 = imageFactory.Reload( *req.Get() );
407 application.SendNotification();
408 application.Render();
409 application.SendNotification();
410 application.Render();
412 DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
416 // Test for reloading changed image
417 int UtcDaliImageFactoryReload03(void)
419 TestApplication application;
420 tet_infoline( "UtcDaliImageFactoryReload03 - Reload changed image" );
422 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
424 Vector2 testSize( 80.0f, 80.0f );
425 application.GetPlatform().SetClosestImageSize( testSize );
427 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
428 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
430 application.SendNotification();
431 application.Render();
433 // emulate load success
434 EmulateImageLoaded( application, 80, 80 );
436 Vector2 newSize( 192.0f, 192.0f );
437 application.GetPlatform().SetClosestImageSize( newSize );
439 // Image file changed size, new resource request should be issued
440 ResourceTicketPtr ticket2 = imageFactory.Reload( *req.Get() );
441 DALI_TEST_CHECK( ticket != ticket2 );
443 ResourceTicketPtr ticket3 = imageFactory.Reload( *req.Get() );
444 DALI_TEST_EQUALS( ticket2, ticket3, TEST_LOCATION );
448 // Testing file system access when reloading image
449 int UtcDaliImageFactoryReload04(void)
451 TestApplication application;
452 tet_infoline( "UtcDaliImageFactoryReload04 - Reload unchanged image" );
454 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
456 Vector2 testSize(80.0f, 80.0f);
457 application.GetPlatform().SetClosestImageSize(testSize);
459 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
460 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
462 application.SendNotification();
463 application.Render();
465 DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
466 application.GetPlatform().ResetTrace();
468 ResourceTicketPtr ticket2 = imageFactory.Reload( *req.Get() );
470 application.SendNotification();
471 application.Render();
472 application.SendNotification();
473 application.Render();
475 DALI_TEST_EQUALS( ticket, ticket2, TEST_LOCATION );
476 // resource is still loading, do not issue another request
477 DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
479 // emulate load success
480 EmulateImageLoaded( application, 80, 80 );
482 ResourceTicketPtr ticket3 = imageFactory.Reload( *req.Get() );
484 application.SendNotification();
485 application.Render();
486 application.SendNotification();
487 application.Render();
489 // size didn't change, using same ticket
490 DALI_TEST_EQUALS( ticket, ticket3, TEST_LOCATION );
491 DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
492 application.GetPlatform().ResetTrace();
495 ticket3 = imageFactory.Reload( *req.Get() );
496 application.SendNotification();
497 application.Render();
498 application.SendNotification();
499 application.Render();
501 DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
505 // Testing OnDemand + Reload
506 // Reload should have no effect if OnDemand Image is not loaded yet, as stated in the API documentation
507 int UtcDaliImageFactoryReload05(void)
509 TestApplication application;
511 tet_infoline( "UtcDaliImageFactoryReload05 - Reload OnDemand image" );
513 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
515 Vector2 testSize(80.0f, 80.0f);
516 application.GetPlatform().SetClosestImageSize(testSize);
519 ImageAttributes attr = ImageAttributes::New();
520 attr.SetSize( 80, 80 );
522 // this happens first when loading Image OnDemand
523 req = imageFactory.RegisterRequest( gTestImageFilename, &attr );
525 application.SendNotification();
526 application.Render();
528 ResourceTicketPtr ticket = imageFactory.Reload( *req.Get() );
530 DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
531 DALI_TEST_CHECK( !ticket );
533 // this happens when Image is put on stage
534 ticket = imageFactory.Load( *req.Get() );
536 application.SendNotification();
537 application.Render();
539 DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
540 DALI_TEST_CHECK( ticket );
541 application.GetPlatform().ResetTrace();
543 ticket = imageFactory.Reload( *req.Get() );
545 application.SendNotification();
546 application.Render();
547 application.SendNotification();
548 application.Render();
550 // still loading, no new request
551 DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
553 // emulate load success
554 EmulateImageLoaded( application, 80, 80 );
556 ticket = imageFactory.Reload( *req.Get() );
558 application.SendNotification();
559 application.Render();
561 application.SendNotification();
562 application.Render();
565 DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
569 // Initally two different requests map to same resource.
570 // After overwriting the file, they load different image resources.
571 int UtcDaliImageFactoryReload06(void)
573 TestApplication application;
574 tet_infoline( "UtcDaliImageFactoryReload06 - Two requests first mapping to same resource, then different resources." );
576 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
578 Vector2 testSize(2048.0f, 2048.0f);
579 application.GetPlatform().SetClosestImageSize( testSize );
581 // request with default attributes ( size is 0,0 )
582 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
583 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
585 application.SendNotification();
586 application.Render();
587 application.SendNotification();
588 application.Render();
590 // emulate load success
591 EmulateImageLoaded( application, testSize.x, testSize.y );
593 // Request bigger size than actual image.
594 // This will load the same resource.
595 // However if image size changes later on to eg. 512*512 (file is overwritten),
596 // reissuing these two requests will load different resources.
597 ImageAttributes attr = ImageAttributes::New();
598 attr.SetSize( testSize.x + 1, testSize.y + 1 );
599 RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr );
600 ResourceTicketPtr ticket2 = imageFactory.Load( *req2.Get() );
602 DALI_TEST_CHECK( req != req2 ); // different requests
603 DALI_TEST_EQUALS( ticket->GetId(), ticket2->GetId(), TEST_LOCATION ); // same resource
605 Vector2 newSize(512.0f, 512.0f);
606 application.GetPlatform().SetClosestImageSize(newSize);
608 // reload fixed size (192,192) request
609 ticket2 = imageFactory.Reload( *req2.Get() );
611 // emulate load success
612 // note: this is the only way to emulate what size is loaded by platform abstraction
613 EmulateImageLoaded( application, testSize.x + 1, testSize.y + 1 );
615 // reload default size request
616 ticket = imageFactory.Reload( *req.Get() );
618 DALI_TEST_CHECK( ticket->GetId() != ticket2->GetId() ); // different resources