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>
28 #include <dali/internal/common/image-attributes.h>
32 using Internal::ResourceTicketPtr;
33 using Internal::ImageFactory;
34 using Internal::ImageFactoryCache::RequestPtr;
35 using Internal::ImageAttributes;
40 static const char* gTestImageFilename = "icon_wrt.png";
42 static void EmulateImageLoaded( TestApplication& application, unsigned int width, unsigned int height )
44 // emulate load success
45 Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
46 Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_DISCARD );
47 Integration::ResourcePointer resource( bitmap );
48 bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, width, height, width, height );
51 application.GetPlatform().SetResourceLoaded( request->GetId(), request->GetType()->id, resource );
54 application.SendNotification();
57 application.SendNotification();
61 } //anonymous namespace
64 // High-level test for image factory request cache
65 int UtcDaliImageFactoryUseCachedRequest01(void)
67 TestApplication application;
69 tet_infoline( "UtcDaliImageFactoryCachedRequest01 - Request same image more than once" );
71 Image image = ResourceImage::New( gTestImageFilename );
73 application.SendNotification();
75 DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
76 application.GetPlatform().ResetTrace();
78 Image image2 = ResourceImage::New( gTestImageFilename );
80 application.SendNotification();
83 // check resource is not loaded twice
84 DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
85 application.GetPlatform().ResetTrace();
87 Image image3 = ResourceImage::New( gTestImageFilename );
89 application.SendNotification();
91 DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
95 // High-level test for image factory request cache
96 int UtcDaliImageFactoryUseCachedRequest02(void)
98 TestApplication application;
100 // testing resource deletion when taken off stage
101 tet_infoline( "UtcDaliImageFactoryCachedRequest02 - Discard previously requested resource" );
103 Image image = ResourceImage::New( gTestImageFilename, ResourceImage::IMMEDIATE, Image::UNUSED );
104 Actor actor = CreateRenderableActor( image );
106 application.SendNotification();
107 application.Render();
109 DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
110 application.GetPlatform().ResetTrace();
112 // Add actor to stage
113 Stage::GetCurrent().Add( actor );
115 application.Render();
116 application.SendNotification();
117 application.Render();
118 application.SendNotification();
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();
127 // Should find stale request in cache, so load image from filesystem
128 Image image2 = ResourceImage::New( gTestImageFilename );
130 application.SendNotification();
131 application.Render();
133 DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
134 application.GetPlatform().ResetTrace();
136 // Resource is reloaded
137 Image image3 = ResourceImage::New( gTestImageFilename );
139 application.SendNotification();
140 application.Render();
141 application.SendNotification();
142 application.Render();
144 DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
148 // Low-level test for image factory request cache
149 int UtcDaliImageFactoryUseCachedRequest03(void)
151 TestApplication application;
152 tet_infoline( "UtcDaliImageFactoryCachedRequest03 - Request same image more than once - Request Ids" );
154 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
156 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
157 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
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 );
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 );
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 );
177 // Low-level test for image factory request cache
178 int UtcDaliImageFactoryUseCachedRequest04(void)
180 TestApplication application;
181 tet_infoline( "UtcDaliImageFactoryCachedRequest04 - Request same image with different Image objects - Request Ids" );
183 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
185 ImageAttributes attr = ImageAttributes::New( 80, 160 );
186 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, &attr );
188 ImageAttributes attr2 = ImageAttributes::New( 80, 160 );
189 RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr2 );
190 DALI_TEST_EQUALS( req, req2, TEST_LOCATION );
194 // Different requests, compatible resource
195 int UtcDaliImageFactoryCompatibleResource01(void)
197 TestApplication application;
198 tet_infoline( "UtcDaliImageFactoryCompatibleResource01 - Two requests mapping to same resource" );
200 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
202 Vector2 testSize(80.0f, 80.0f);
203 application.GetPlatform().SetClosestImageSize(testSize);
205 // request with default attributes ( size is 0,0 )
206 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
207 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
209 application.SendNotification();
210 application.Render();
211 application.SendNotification();
212 application.Render();
214 // emulate load success
215 EmulateImageLoaded( application, 80, 80 );
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() );
223 DALI_TEST_CHECK( req != req2 ); // different requests
224 DALI_TEST_EQUALS( ticket->GetId(), ticket2->GetId(), TEST_LOCATION ); // same resource
228 // Different requests, compatible resource
229 int UtcDaliImageFactoryCompatibleResource02(void)
231 TestApplication application;
232 tet_infoline( "UtcDaliImageFactoryCompatibleResource02 - Two requests mapping to same resource." );
234 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
236 Vector2 testSize( 2048.0f, 2048.0f );
237 application.GetPlatform().SetClosestImageSize( testSize );
239 // request with default attributes ( size is 0,0 )
240 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
241 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
243 application.SendNotification();
244 application.Render();
245 application.SendNotification();
246 application.Render();
248 // emulate load success
249 EmulateImageLoaded( application, testSize.x, testSize.y );
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() );
259 DALI_TEST_CHECK( req != req2 ); // different requests
260 DALI_TEST_EQUALS( ticket->GetId(), ticket2->GetId(), TEST_LOCATION ); // same resource
264 // Different requests, incompatible resource, so two loads result:
265 int UtcDaliImageFactoryInCompatibleResource(void)
267 TestApplication application;
268 tet_infoline( "UtcDaliImageFactoryCompatibleResource02 - Two requests mapping to same resource." );
270 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
272 Vector2 testSize(2048.0f, 2048.0f);
273 application.GetPlatform().SetClosestImageSize(testSize);
275 // request with default attributes ( size is 0,0 )
276 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
277 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
279 application.SendNotification();
280 application.Render();
281 application.SendNotification();
282 application.Render();
284 // emulate load success
285 EmulateImageLoaded( application, testSize.x, testSize.y );
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() );
295 DALI_TEST_CHECK( req != req2 ); // different requests
296 DALI_TEST_CHECK( ticket->GetId() != ticket2->GetId() ); // differnet resources
300 // Different requests, compatible resource
301 int UtcDaliImageFactoryCompatibleResource03(void)
303 TestApplication application;
304 tet_infoline( "UtcDaliImageFactoryCompatibleResource03 - Two requests mapping to same resource" );
306 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
308 Vector2 testSize(80.0f, 80.0f);
309 application.GetPlatform().SetClosestImageSize(testSize);
311 // this time use defined attributes, nut just NULL
312 ImageAttributes attr = ImageAttributes::New();
313 attr.SetSize( 120, 120 );
315 // request with default attributes ( size is 0,0 )
316 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, &attr );
317 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
319 application.SendNotification();
320 application.Render();
321 application.SendNotification();
322 application.Render();
324 // emulate load success
325 EmulateImageLoaded( application, 80, 80 );
327 ImageAttributes attr2 = ImageAttributes::New();
328 attr2.SetSize( 80, 80 );
329 RequestPtr req2 = imageFactory.RegisterRequest( gTestImageFilename, &attr2 );
330 ResourceTicketPtr ticket2 = imageFactory.Load( *req2.Get() );
332 DALI_TEST_CHECK( req != req2 ); // different requests
333 DALI_TEST_EQUALS( ticket->GetId(), ticket2->GetId(), TEST_LOCATION ); // same resource
337 // Test for reloading image
338 int UtcDaliImageFactoryReload01(void)
340 TestApplication application;
341 tet_infoline( "UtcDaliImageFactoryReload01 - Reload unchanged image" );
343 Vector2 testSize(80.0f, 80.0f);
344 application.GetPlatform().SetClosestImageSize(testSize);
346 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
348 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
349 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
351 ResourceTicketPtr ticket2 = imageFactory.Reload( *req.Get() );
352 DALI_TEST_EQUALS( ticket, ticket2, TEST_LOCATION );
354 ResourceTicketPtr ticket3 = imageFactory.Reload( *req.Get() );
355 DALI_TEST_EQUALS( ticket, ticket3, TEST_LOCATION );
359 // Testing file system access when reloading image
360 int UtcDaliImageFactoryReload02(void)
362 TestApplication application;
363 tet_infoline( "UtcDaliImageFactoryReload02 - Reload unchanged image" );
365 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
367 Vector2 testSize(80.0f, 80.0f);
368 application.GetPlatform().SetClosestImageSize(testSize);
370 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
371 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
373 application.SendNotification();
374 application.Render();
375 application.SendNotification();
376 application.Render();
378 DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
379 application.GetPlatform().ResetTrace();
381 ResourceTicketPtr ticket2 = imageFactory.Reload( *req.Get() );
383 application.SendNotification();
384 application.Render();
385 application.SendNotification();
386 application.Render();
388 DALI_TEST_EQUALS( ticket, ticket2, TEST_LOCATION );
389 // resource is still loading, do not issue another request
390 DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
392 // emulate load success
393 EmulateImageLoaded( application, 80, 80 );
395 ResourceTicketPtr ticket3 = imageFactory.Reload( *req.Get() );
397 application.SendNotification();
398 application.Render();
399 application.SendNotification();
400 application.Render();
402 DALI_TEST_EQUALS( ticket, ticket3, TEST_LOCATION );
403 DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
404 application.GetPlatform().ResetTrace();
406 ticket3 = imageFactory.Reload( *req.Get() );
408 application.SendNotification();
409 application.Render();
410 application.SendNotification();
411 application.Render();
413 DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
417 // Test for reloading changed image
418 int UtcDaliImageFactoryReload03(void)
420 TestApplication application;
421 tet_infoline( "UtcDaliImageFactoryReload03 - Reload changed image" );
423 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
425 Vector2 testSize( 80.0f, 80.0f );
426 application.GetPlatform().SetClosestImageSize( testSize );
428 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
429 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
431 application.SendNotification();
432 application.Render();
434 // emulate load success
435 EmulateImageLoaded( application, 80, 80 );
437 Vector2 newSize( 192.0f, 192.0f );
438 application.GetPlatform().SetClosestImageSize( newSize );
440 // Image file changed size, new resource request should be issued
441 ResourceTicketPtr ticket2 = imageFactory.Reload( *req.Get() );
442 DALI_TEST_CHECK( ticket != ticket2 );
444 ResourceTicketPtr ticket3 = imageFactory.Reload( *req.Get() );
445 DALI_TEST_EQUALS( ticket2, ticket3, TEST_LOCATION );
449 // Testing file system access when reloading image
450 int UtcDaliImageFactoryReload04(void)
452 TestApplication application;
453 tet_infoline( "UtcDaliImageFactoryReload04 - Reload unchanged image" );
455 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
457 Vector2 testSize(80.0f, 80.0f);
458 application.GetPlatform().SetClosestImageSize(testSize);
460 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
461 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
463 application.SendNotification();
464 application.Render();
466 DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
467 application.GetPlatform().ResetTrace();
469 ResourceTicketPtr ticket2 = imageFactory.Reload( *req.Get() );
471 application.SendNotification();
472 application.Render();
473 application.SendNotification();
474 application.Render();
476 DALI_TEST_EQUALS( ticket, ticket2, TEST_LOCATION );
477 // resource is still loading, do not issue another request
478 DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
480 // emulate load success
481 EmulateImageLoaded( application, 80, 80 );
483 ResourceTicketPtr ticket3 = imageFactory.Reload( *req.Get() );
485 application.SendNotification();
486 application.Render();
487 application.SendNotification();
488 application.Render();
490 // size didn't change, using same ticket
491 DALI_TEST_EQUALS( ticket, ticket3, TEST_LOCATION );
492 DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
493 application.GetPlatform().ResetTrace();
496 ticket3 = imageFactory.Reload( *req.Get() );
497 application.SendNotification();
498 application.Render();
499 application.SendNotification();
500 application.Render();
502 DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
506 // Testing OnDemand + Reload
507 // Reload should have no effect if OnDemand Image is not loaded yet, as stated in the API documentation
508 int UtcDaliImageFactoryReload05(void)
510 TestApplication application;
512 tet_infoline( "UtcDaliImageFactoryReload05 - Reload OnDemand image" );
514 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
516 Vector2 testSize(80.0f, 80.0f);
517 application.GetPlatform().SetClosestImageSize(testSize);
520 ImageAttributes attr = ImageAttributes::New();
521 attr.SetSize( 80, 80 );
523 // this happens first when loading Image OnDemand
524 req = imageFactory.RegisterRequest( gTestImageFilename, &attr );
526 application.SendNotification();
527 application.Render();
529 ResourceTicketPtr ticket = imageFactory.Reload( *req.Get() );
531 DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
532 DALI_TEST_CHECK( !ticket );
534 // this happens when Image is put on stage
535 ticket = imageFactory.Load( *req.Get() );
537 application.SendNotification();
538 application.Render();
540 DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
541 DALI_TEST_CHECK( ticket );
542 application.GetPlatform().ResetTrace();
544 ticket = imageFactory.Reload( *req.Get() );
546 application.SendNotification();
547 application.Render();
548 application.SendNotification();
549 application.Render();
551 // still loading, no new request
552 DALI_TEST_CHECK( !application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
554 // emulate load success
555 EmulateImageLoaded( application, 80, 80 );
557 ticket = imageFactory.Reload( *req.Get() );
559 application.SendNotification();
560 application.Render();
562 application.SendNotification();
563 application.Render();
566 DALI_TEST_CHECK( application.GetPlatform().WasCalled( TestPlatformAbstraction::LoadResourceFunc ) );
570 // Initally two different requests map to same resource.
571 // After overwriting the file, they load different image resources.
572 int UtcDaliImageFactoryReload06(void)
574 TestApplication application;
575 tet_infoline( "UtcDaliImageFactoryReload06 - Two requests first mapping to same resource, then different resources." );
577 ImageFactory& imageFactory = Internal::ThreadLocalStorage::Get().GetImageFactory();
579 Vector2 testSize(2048.0f, 2048.0f);
580 application.GetPlatform().SetClosestImageSize( testSize );
582 // request with default attributes ( size is 0,0 )
583 RequestPtr req = imageFactory.RegisterRequest( gTestImageFilename, NULL );
584 ResourceTicketPtr ticket = imageFactory.Load( *req.Get() );
586 application.SendNotification();
587 application.Render();
588 application.SendNotification();
589 application.Render();
591 // emulate load success
592 EmulateImageLoaded( application, testSize.x, testSize.y );
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() );
603 DALI_TEST_CHECK( req != req2 ); // different requests
604 DALI_TEST_EQUALS( ticket->GetId(), ticket2->GetId(), TEST_LOCATION ); // same resource
606 Vector2 newSize(512.0f, 512.0f);
607 application.GetPlatform().SetClosestImageSize(newSize);
609 // reload fixed size (192,192) request
610 ticket2 = imageFactory.Reload( *req2.Get() );
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 );
616 // reload default size request
617 ticket = imageFactory.Reload( *req.Get() );
619 DALI_TEST_CHECK( ticket->GetId() != ticket2->GetId() ); // different resources