Fix the normalization factor calculation for blendshapes
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-internal / utc-Dali-TextureManager.cpp
1 /*
2  * Copyright (c) 2023 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
22 #include <dali-toolkit-test-suite-utils.h>
23 #include <toolkit-event-thread-callback.h>
24 #include <toolkit-timer.h>
25
26 #include <dali-toolkit/internal/texture-manager/texture-async-loading-helper.h>
27 #include <dali-toolkit/internal/texture-manager/texture-manager-impl.h>
28 #include <dali-toolkit/internal/texture-manager/texture-upload-observer.h>
29 #include <dali-toolkit/internal/visuals/image-atlas-manager.h>
30 #include <dali-toolkit/internal/visuals/visual-factory-impl.h> ///< For VisualFactory's member TextureManager.
31 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
32
33 #include <test-encoded-image-buffer.h>
34
35 #if defined(ELDBUS_ENABLED)
36 #include <automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dbus-wrapper.h>
37 #endif
38
39 using namespace Dali::Toolkit::Internal;
40
41 void utc_dali_toolkit_texture_manager_startup(void)
42 {
43   setenv("LOG_TEXTURE_MANAGER", "3", 1);
44   test_return_value = TET_UNDEF;
45 #if defined(ELDBUS_ENABLED)
46   DBusWrapper::Install(std::unique_ptr<DBusWrapper>(new TestDBusWrapper));
47 #endif
48 }
49
50 void utc_dali_toolkit_texture_manager_cleanup(void)
51 {
52   test_return_value = TET_PASS;
53 }
54
55 namespace
56 {
57 const char* TEST_IMAGE_FILE_NAME   = TEST_RESOURCE_DIR "/gallery-small-1.jpg";
58 const char* TEST_IMAGE_2_FILE_NAME = TEST_RESOURCE_DIR "/icon-delete.png";
59 const char* TEST_IMAGE_3_FILE_NAME = TEST_RESOURCE_DIR "/icon-edit.png";
60 const char* TEST_IMAGE_4_FILE_NAME = TEST_RESOURCE_DIR "/application-icon-20.png";
61 const char* TEST_MASK_FILE_NAME    = TEST_RESOURCE_DIR "/mask.png";
62
63 class TestObserver : public Dali::Toolkit::TextureUploadObserver
64 {
65 public:
66   enum class CompleteType
67   {
68     NOT_COMPLETED = 0,
69     UPLOAD_COMPLETE,
70     LOAD_COMPLETE
71   };
72
73 public:
74   TestObserver()
75   : mCompleteType(CompleteType::NOT_COMPLETED),
76     mLoaded(false),
77     mObserverCalled(false),
78     mTextureSet()
79   {
80   }
81
82   virtual void LoadComplete(bool loadSuccess, TextureInformation textureInformation) override
83   {
84     if(textureInformation.returnType == TextureUploadObserver::ReturnType::TEXTURE)
85     {
86       mCompleteType = CompleteType::UPLOAD_COMPLETE;
87     }
88     else
89     {
90       mCompleteType = CompleteType::LOAD_COMPLETE;
91     }
92     mLoaded         = loadSuccess;
93     mObserverCalled = true;
94     mTextureSet     = textureInformation.textureSet;
95   }
96
97   CompleteType mCompleteType;
98   bool         mLoaded;
99   bool         mObserverCalled;
100   TextureSet   mTextureSet;
101 };
102
103 class TestObserverRemoveAndGenerateUrl : public TestObserver
104 {
105 public:
106   TestObserverRemoveAndGenerateUrl(TextureManager* textureManagerPtr)
107   : TestObserver(),
108     mTextureManagerPtr(textureManagerPtr)
109   {
110   }
111
112   virtual void LoadComplete(bool loadSuccess, TextureInformation textureInformation) override
113   {
114     if(textureInformation.returnType == TextureUploadObserver::ReturnType::TEXTURE)
115     {
116       mCompleteType = CompleteType::UPLOAD_COMPLETE;
117     }
118     else
119     {
120       mCompleteType = CompleteType::LOAD_COMPLETE;
121     }
122     mLoaded         = loadSuccess;
123     mObserverCalled = true;
124     mTextureSet     = textureInformation.textureSet;
125
126     // Remove during LoadComplete
127     mTextureManagerPtr->RequestRemove(textureInformation.textureId, nullptr);
128
129     // ...And generate string which using texture id.
130     mGeneratedExternalUrl = mTextureManagerPtr->AddExternalTexture(mTextureSet);
131   }
132
133 public:
134   std::string mGeneratedExternalUrl;
135
136 protected:
137   TextureManager* mTextureManagerPtr; // Keep the pointer of texture manager.
138 };
139
140 class TestObserverWithCustomFunction : public TestObserver
141 {
142 public:
143   TestObserverWithCustomFunction()
144   : TestObserver(),
145     mSignals{},
146     mData{nullptr},
147     mKeepSignal{false}
148   {
149   }
150
151   virtual void LoadComplete(bool loadSuccess, TextureInformation textureInformation) override
152   {
153     if(textureInformation.returnType == TextureUploadObserver::ReturnType::TEXTURE)
154     {
155       mCompleteType = CompleteType::UPLOAD_COMPLETE;
156     }
157     else
158     {
159       mCompleteType = CompleteType::LOAD_COMPLETE;
160     }
161     mLoaded         = loadSuccess;
162     mObserverCalled = true;
163     mTextureSet     = textureInformation.textureSet;
164
165     // Execute signals.
166     for(size_t i = 0; i < mSignals.size(); i++)
167     {
168       mSignals[i](mData);
169     }
170
171     // Clear signals.
172     if(!mKeepSignal)
173     {
174       mSignals.clear();
175     }
176   }
177
178   void ConnectFunction(std::function<void(void*)> signal)
179   {
180     mSignals.push_back(signal);
181   }
182
183 public:
184   std::vector<std::function<void(void*)>> mSignals;
185   void*                                   mData;
186   bool                                    mKeepSignal;
187 };
188
189 } // namespace
190
191 int UtcTextureManagerRequestLoad(void)
192 {
193   ToolkitTestApplication application;
194
195   TextureManager textureManager; // Create new texture manager
196
197   TestObserver              observer;
198   std::string               filename("image.png");
199   auto                      preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
200   TextureManager::TextureId textureId   = textureManager.RequestLoad(
201     filename,
202     ImageDimensions(),
203     FittingMode::SCALE_TO_FILL,
204     SamplingMode::BOX_THEN_LINEAR,
205     TextureManager::UseAtlas::NO_ATLAS,
206     &observer,
207     true,
208     TextureManager::ReloadPolicy::CACHED,
209     preMultiply);
210
211   VisualUrl url = textureManager.GetVisualUrl(textureId);
212
213   DALI_TEST_EQUALS(url.GetUrl().compare(filename), 0, TEST_LOCATION);
214
215   END_TEST;
216 }
217
218 int UtcTextureManagerGenerateHash(void)
219 {
220   ToolkitTestApplication application;
221
222   TextureManager textureManager; // Create new texture manager
223
224   TestObserver              observer;
225   std::string               filename("image.png");
226   auto                      preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
227   TextureManager::TextureId textureId   = textureManager.RequestLoad(
228     filename,
229     ImageDimensions(),
230     FittingMode::SCALE_TO_FILL,
231     SamplingMode::BOX_THEN_LINEAR,
232     TextureManager::UseAtlas::NO_ATLAS,
233     &observer,
234     true,
235     TextureManager::ReloadPolicy::CACHED,
236     preMultiply);
237
238   VisualUrl url = textureManager.GetVisualUrl(textureId);
239
240   DALI_TEST_EQUALS(url.GetUrl().compare(filename), 0, TEST_LOCATION);
241
242   END_TEST;
243 }
244
245 int UtcTextureManagerEncodedImageBuffer(void)
246 {
247   ToolkitTestApplication application;
248   tet_infoline("UtcTextureManagerEncodedImageBuffer");
249
250   auto  visualFactory  = Toolkit::VisualFactory::Get();
251   auto& textureManager = GetImplementation(visualFactory).GetTextureManager(); // Use VisualFactory's texture manager
252
253   // Get encoded raw-buffer image and generate url
254   EncodedImageBuffer buffer1 = ConvertFileToEncodedImageBuffer(TEST_IMAGE_FILE_NAME);
255   EncodedImageBuffer buffer2 = ConvertFileToEncodedImageBuffer(TEST_IMAGE_FILE_NAME);
256
257   std::string url1 = textureManager.AddEncodedImageBuffer(buffer1);
258   std::string url2 = textureManager.AddEncodedImageBuffer(buffer1);
259   std::string url3 = VisualUrl::CreateBufferUrl(""); ///< Impossible Buffer URL. for coverage
260
261   // Check if same EncodedImageBuffer get same url
262   DALI_TEST_CHECK(url1 == url2);
263   // Reduce reference count
264   textureManager.RemoveEncodedImageBuffer(url1);
265   // Check whethere url1 still valid
266   DALI_TEST_CHECK(textureManager.GetEncodedImageBuffer(url1));
267
268   url2 = textureManager.AddEncodedImageBuffer(buffer2);
269   // Check if difference EncodedImageBuffer get difference url
270   DALI_TEST_CHECK(url1 != url2);
271
272   auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
273
274   TestObserver observer1;
275   textureManager.RequestLoad(
276     url1,
277     ImageDimensions(),
278     FittingMode::SCALE_TO_FILL,
279     SamplingMode::BOX_THEN_LINEAR,
280     TextureManager::UseAtlas::NO_ATLAS,
281     &observer1,
282     true, ///< orientationCorrection
283     TextureManager::ReloadPolicy::CACHED,
284     preMultiply);
285
286   DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
287   DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
288
289   application.SendNotification();
290   application.Render();
291
292   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
293
294   application.SendNotification();
295   application.Render();
296
297   DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
298   DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
299   DALI_TEST_EQUALS(observer1.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION);
300
301   TestObserver observer2;
302   // Syncload
303   Devel::PixelBuffer pixelBuffer = textureManager.LoadPixelBuffer(
304     url2,
305     ImageDimensions(),
306     FittingMode::SCALE_TO_FILL,
307     SamplingMode::BOX_THEN_LINEAR,
308     true, ///< synchronousLoading
309     &observer2,
310     true, ///< orientationCorrection
311     preMultiply);
312
313   DALI_TEST_CHECK(pixelBuffer);
314   DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION);
315   DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION);
316
317   // Asyncload
318   pixelBuffer = textureManager.LoadPixelBuffer(
319     url2,
320     ImageDimensions(),
321     FittingMode::SCALE_TO_FILL,
322     SamplingMode::BOX_THEN_LINEAR,
323     false, ///< synchronousLoading
324     &observer2,
325     true, ///< orientationCorrection
326     preMultiply);
327
328   DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION);
329   DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION);
330
331   application.SendNotification();
332   application.Render();
333
334   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
335
336   application.SendNotification();
337   application.Render();
338
339   DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION);
340   DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION);
341   DALI_TEST_EQUALS(observer2.mCompleteType, TestObserver::CompleteType::LOAD_COMPLETE, TEST_LOCATION);
342
343   textureManager.RemoveEncodedImageBuffer(url1);
344   textureManager.RemoveEncodedImageBuffer(url2);
345
346   // Now url1 and url2 is invalid type. mLoaded will return false
347
348   TestObserver observer3;
349   textureManager.RequestLoad(
350     url1,
351     ImageDimensions(),
352     FittingMode::SCALE_TO_FILL,
353     SamplingMode::BOX_THEN_LINEAR,
354     TextureManager::UseAtlas::NO_ATLAS,
355     &observer3,
356     true, ///< orientationCorrection
357     TextureManager::ReloadPolicy::CACHED,
358     preMultiply);
359
360   // Load will be success because url1 is cached
361   DALI_TEST_EQUALS(observer3.mLoaded, true, TEST_LOCATION);
362   DALI_TEST_EQUALS(observer3.mObserverCalled, true, TEST_LOCATION);
363   DALI_TEST_EQUALS(observer3.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION);
364
365   TestObserver observer4;
366   textureManager.RequestLoad(
367     url2,
368     ImageDimensions(),
369     FittingMode::SCALE_TO_FILL,
370     SamplingMode::BOX_THEN_LINEAR,
371     TextureManager::UseAtlas::NO_ATLAS,
372     &observer4,
373     true, ///< orientationCorrection
374     TextureManager::ReloadPolicy::FORCED,
375     preMultiply);
376
377   DALI_TEST_EQUALS(observer4.mLoaded, false, TEST_LOCATION);
378   DALI_TEST_EQUALS(observer4.mObserverCalled, false, TEST_LOCATION);
379   application.SendNotification();
380   application.Render();
381
382   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
383
384   application.SendNotification();
385   application.Render();
386
387   // Load will be failed becuase reloadpolicy is forced
388   DALI_TEST_EQUALS(observer4.mLoaded, false, TEST_LOCATION);
389   DALI_TEST_EQUALS(observer4.mObserverCalled, true, TEST_LOCATION);
390   DALI_TEST_EQUALS(observer4.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION);
391
392   TestObserver observer5;
393   pixelBuffer = textureManager.LoadPixelBuffer(
394     url2,
395     ImageDimensions(),
396     FittingMode::SCALE_TO_FILL,
397     SamplingMode::BOX_THEN_LINEAR,
398     true, ///< synchronousLoading
399     &observer5,
400     true, ///< orientationCorrection
401     preMultiply);
402
403   // Load will be faild because synchronousLoading doesn't use cached texture
404   DALI_TEST_CHECK(!pixelBuffer);
405   DALI_TEST_EQUALS(observer5.mLoaded, false, TEST_LOCATION);
406   DALI_TEST_EQUALS(observer5.mObserverCalled, false, TEST_LOCATION);
407
408   TestObserver observer6;
409   pixelBuffer = textureManager.LoadPixelBuffer(
410     url3,
411     ImageDimensions(),
412     FittingMode::SCALE_TO_FILL,
413     SamplingMode::BOX_THEN_LINEAR,
414     false, ///< synchronousLoading
415     &observer6,
416     true, ///< orientationCorrection
417     preMultiply);
418
419   DALI_TEST_EQUALS(observer6.mLoaded, false, TEST_LOCATION);
420   DALI_TEST_EQUALS(observer6.mObserverCalled, false, TEST_LOCATION);
421
422   application.SendNotification();
423   application.Render();
424
425   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
426
427   application.SendNotification();
428   application.Render();
429
430   // Load will be failed because url3 is invalid URL
431   DALI_TEST_EQUALS(observer6.mLoaded, false, TEST_LOCATION);
432   DALI_TEST_EQUALS(observer6.mObserverCalled, true, TEST_LOCATION);
433   DALI_TEST_EQUALS(observer6.mCompleteType, TestObserver::CompleteType::LOAD_COMPLETE, TEST_LOCATION);
434
435   END_TEST;
436 }
437
438 int UtcTextureManagerEncodedImageBufferReferenceCount(void)
439 {
440   ToolkitTestApplication application;
441   tet_infoline("UtcTextureManagerEncodedImageBuffer check reference count works well");
442
443   auto  visualFactory  = Toolkit::VisualFactory::Get();
444   auto& textureManager = GetImplementation(visualFactory).GetTextureManager(); // Use VisualFactory's texture manager
445
446   // Get encoded raw-buffer image and generate url
447   EncodedImageBuffer buffer1 = ConvertFileToEncodedImageBuffer(TEST_IMAGE_FILE_NAME);
448   EncodedImageBuffer buffer2 = ConvertFileToEncodedImageBuffer(TEST_IMAGE_FILE_NAME);
449
450   std::string url1 = textureManager.AddEncodedImageBuffer(buffer1);
451   std::string url2 = textureManager.AddEncodedImageBuffer(buffer1);
452
453   // Check if same EncodedImageBuffer get same url
454   DALI_TEST_CHECK(url1 == url2);
455
456   // Reduce reference count
457   textureManager.RemoveEncodedImageBuffer(url1);
458   // Check whethere url1 still valid
459   DALI_TEST_CHECK(textureManager.GetEncodedImageBuffer(url1));
460
461   // Reduce reference count
462   textureManager.RemoveEncodedImageBuffer(url1);
463   // Check whethere url1 is not valid anymore
464   DALI_TEST_CHECK(!textureManager.GetEncodedImageBuffer(url1));
465
466   // UseExternalTexture doesn't create new buffer.
467   // So, reference count is still zero.
468   textureManager.UseExternalResource(url1);
469   DALI_TEST_CHECK(!textureManager.GetEncodedImageBuffer(url1));
470
471   url1 = textureManager.AddEncodedImageBuffer(buffer1);
472
473   url2 = textureManager.AddEncodedImageBuffer(buffer2);
474   // Check if difference EncodedImageBuffer get difference url
475   DALI_TEST_CHECK(url1 != url2);
476
477   auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
478
479   // url1 load image by cache
480   TestObserver observer1;
481   textureManager.RequestLoad(
482     url1,
483     ImageDimensions(),
484     FittingMode::SCALE_TO_FILL,
485     SamplingMode::BOX_THEN_LINEAR,
486     TextureManager::UseAtlas::NO_ATLAS,
487     &observer1,
488     true, ///< orientationCorrection
489     TextureManager::ReloadPolicy::CACHED,
490     preMultiply);
491
492   DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
493   DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
494
495   application.SendNotification();
496   application.Render();
497
498   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
499
500   application.SendNotification();
501   application.Render();
502
503   DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
504   DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
505   DALI_TEST_EQUALS(observer1.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION);
506
507   // LoadPixelBuffer doen't use cache. url2 will not be cached
508   TestObserver       observer2;
509   Devel::PixelBuffer pixelBuffer = textureManager.LoadPixelBuffer(
510     url2,
511     ImageDimensions(),
512     FittingMode::SCALE_TO_FILL,
513     SamplingMode::BOX_THEN_LINEAR,
514     false, ///< synchronousLoading
515     &observer2,
516     true, ///< orientationCorrection
517     preMultiply);
518
519   DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION);
520   DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION);
521
522   application.SendNotification();
523   application.Render();
524
525   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
526
527   application.SendNotification();
528   application.Render();
529
530   DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION);
531   DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION);
532   DALI_TEST_EQUALS(observer2.mCompleteType, TestObserver::CompleteType::LOAD_COMPLETE, TEST_LOCATION);
533
534   // Decrease each url's reference count.
535   textureManager.RemoveEncodedImageBuffer(url1);
536   textureManager.RemoveEncodedImageBuffer(url2);
537
538   // url1 buffer is still have 1 reference count because it is cached.
539   // But url2 not valid because it is not cached.
540   DALI_TEST_CHECK(textureManager.GetEncodedImageBuffer(url1));
541   DALI_TEST_CHECK(!textureManager.GetEncodedImageBuffer(url2));
542
543   // Check url1 buffer have 1 reference count because it is cached.
544   textureManager.RemoveEncodedImageBuffer(url1);
545   DALI_TEST_CHECK(!textureManager.GetEncodedImageBuffer(url1));
546
547   END_TEST;
548 }
549
550 int UtcTextureManagerCachingForDifferentLoadingType(void)
551 {
552   ToolkitTestApplication application;
553   tet_infoline("UtcTextureManagerCachingForDifferentLoadingType");
554
555   TextureManager textureManager; // Create new texture manager
556
557   TestObserver observer1;
558   std::string  filename(TEST_IMAGE_FILE_NAME);
559   auto         preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
560   textureManager.RequestLoad(
561     filename,
562     ImageDimensions(),
563     FittingMode::SCALE_TO_FILL,
564     SamplingMode::BOX_THEN_LINEAR,
565     TextureManager::UseAtlas::NO_ATLAS,
566     &observer1,
567     true,
568     TextureManager::ReloadPolicy::CACHED,
569     preMultiply);
570
571   DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
572   DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
573
574   application.SendNotification();
575   application.Render();
576
577   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
578
579   application.SendNotification();
580   application.Render();
581
582   DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
583   DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
584   DALI_TEST_EQUALS(observer1.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION);
585
586   TestObserver       observer2;
587   Devel::PixelBuffer pixelBuffer = textureManager.LoadPixelBuffer(
588     filename,
589     ImageDimensions(),
590     FittingMode::SCALE_TO_FILL,
591     SamplingMode::BOX_THEN_LINEAR,
592     false,
593     &observer2,
594     true,
595     preMultiply);
596
597   DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION);
598   DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION);
599
600   application.SendNotification();
601   application.Render();
602
603   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
604
605   application.SendNotification();
606   application.Render();
607
608   DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION);
609   DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION);
610   DALI_TEST_EQUALS(observer2.mCompleteType, TestObserver::CompleteType::LOAD_COMPLETE, TEST_LOCATION);
611
612   END_TEST;
613 }
614
615 int UtcTextureManagerUseInvalidMask(void)
616 {
617   ToolkitTestApplication application;
618   tet_infoline("UtcTextureManagerUseInvalidMask");
619
620   TextureManager textureManager; // Create new texture manager
621
622   TestObserver                       observer;
623   std::string                        filename(TEST_IMAGE_FILE_NAME);
624   std::string                        maskname("");
625   TextureManager::MaskingDataPointer maskInfo = nullptr;
626   maskInfo.reset(new TextureManager::MaskingData());
627   maskInfo->mAlphaMaskUrl       = maskname;
628   maskInfo->mAlphaMaskId        = TextureManager::INVALID_TEXTURE_ID;
629   maskInfo->mCropToMask         = true;
630   maskInfo->mContentScaleFactor = 1.0f;
631
632   auto                          textureId(TextureManager::INVALID_TEXTURE_ID);
633   Vector4                       atlasRect(0.f, 0.f, 1.f, 1.f);
634   Dali::ImageDimensions         atlasRectSize(0, 0);
635   bool                          synchronousLoading(false);
636   bool                          atlasingStatus(false);
637   bool                          loadingStatus(false);
638   auto                          preMultiply         = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
639   ImageAtlasManagerPtr          atlasManager        = nullptr;
640   Toolkit::AtlasUploadObserver* atlasUploadObserver = nullptr;
641
642   textureManager.LoadTexture(
643     filename,
644     ImageDimensions(),
645     FittingMode::SCALE_TO_FILL,
646     SamplingMode::BOX_THEN_LINEAR,
647     maskInfo,
648     synchronousLoading,
649     textureId,
650     atlasRect,
651     atlasRectSize,
652     atlasingStatus,
653     loadingStatus,
654     &observer,
655     atlasUploadObserver,
656     atlasManager,
657     true,
658     TextureManager::ReloadPolicy::CACHED,
659     preMultiply);
660
661   DALI_TEST_EQUALS(observer.mLoaded, false, TEST_LOCATION);
662   DALI_TEST_EQUALS(observer.mObserverCalled, false, TEST_LOCATION);
663
664   application.SendNotification();
665   application.Render();
666
667   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
668
669   application.SendNotification();
670   application.Render();
671
672   DALI_TEST_EQUALS(observer.mLoaded, true, TEST_LOCATION);
673   DALI_TEST_EQUALS(observer.mObserverCalled, true, TEST_LOCATION);
674   DALI_TEST_EQUALS(observer.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION);
675
676   END_TEST;
677 }
678
679 int UtcTextureManagerUseInvalidMaskAndMaskLoadedFirst(void)
680 {
681   ToolkitTestApplication application;
682   tet_infoline("UtcTextureManagerUseInvalidMask when normal image loaded first, and mask image loaded first");
683   tet_infoline("Try to check PostLoad works well");
684
685   TextureManager textureManager; // Create new texture manager
686
687   TestObserver                       observer;
688   std::string                        filename(TEST_IMAGE_FILE_NAME);
689   std::string                        maskname("invalid.png");
690   TextureManager::MaskingDataPointer maskInfo = nullptr;
691   maskInfo.reset(new TextureManager::MaskingData());
692   maskInfo->mAlphaMaskUrl       = maskname;
693   maskInfo->mAlphaMaskId        = TextureManager::INVALID_TEXTURE_ID;
694   maskInfo->mCropToMask         = true;
695   maskInfo->mContentScaleFactor = 1.0f;
696
697   auto                          textureId(TextureManager::INVALID_TEXTURE_ID);
698   Vector4                       atlasRect(0.f, 0.f, 1.f, 1.f);
699   Dali::ImageDimensions         atlasRectSize(0, 0);
700   bool                          synchronousLoading(false);
701   bool                          atlasingStatus(false);
702   bool                          loadingStatus(false);
703   auto                          preMultiply         = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
704   ImageAtlasManagerPtr          atlasManager        = nullptr;
705   Toolkit::AtlasUploadObserver* atlasUploadObserver = nullptr;
706
707   textureManager.LoadTexture(
708     filename,
709     ImageDimensions(),
710     FittingMode::SCALE_TO_FILL,
711     SamplingMode::BOX_THEN_LINEAR,
712     maskInfo,
713     synchronousLoading,
714     textureId,
715     atlasRect,
716     atlasRectSize,
717     atlasingStatus,
718     loadingStatus,
719     &observer,
720     atlasUploadObserver,
721     atlasManager,
722     true,
723     TextureManager::ReloadPolicy::CACHED,
724     preMultiply);
725
726   DALI_TEST_EQUALS(observer.mLoaded, false, TEST_LOCATION);
727   DALI_TEST_EQUALS(observer.mObserverCalled, false, TEST_LOCATION);
728
729   application.SendNotification();
730   application.Render();
731
732   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
733
734   application.SendNotification();
735   application.Render();
736
737   DALI_TEST_EQUALS(observer.mLoaded, true, TEST_LOCATION);
738   DALI_TEST_EQUALS(observer.mObserverCalled, true, TEST_LOCATION);
739   DALI_TEST_EQUALS(observer.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION);
740
741   END_TEST;
742 }
743
744 int UtcTextureManagerUseInvalidMaskAndMaskLoadedLater(void)
745 {
746   ToolkitTestApplication application;
747   tet_infoline("UtcTextureManagerUseInvalidMask when normal image loaded first, and mask image loaded later");
748   tet_infoline("Try to check CheckForWaitingTexture called");
749
750   TextureManager textureManager; // Create new texture manager
751
752   TestObserver                       observer;
753   std::string                        filename(TEST_IMAGE_FILE_NAME);
754   std::string                        maskname("invalid.png");
755   TextureManager::MaskingDataPointer maskInfo = nullptr;
756   maskInfo.reset(new TextureManager::MaskingData());
757   maskInfo->mAlphaMaskUrl       = maskname;
758   maskInfo->mAlphaMaskId        = TextureManager::INVALID_TEXTURE_ID;
759   maskInfo->mCropToMask         = true;
760   maskInfo->mContentScaleFactor = 1.0f;
761
762   auto                          textureId(TextureManager::INVALID_TEXTURE_ID);
763   Vector4                       atlasRect(0.f, 0.f, 1.f, 1.f);
764   Dali::ImageDimensions         atlasRectSize(0, 0);
765   bool                          synchronousLoading(false);
766   bool                          atlasingStatus(false);
767   bool                          loadingStatus(false);
768   auto                          preMultiply         = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
769   ImageAtlasManagerPtr          atlasManager        = nullptr;
770   Toolkit::AtlasUploadObserver* atlasUploadObserver = nullptr;
771
772   textureManager.LoadTexture(
773     filename,
774     ImageDimensions(),
775     FittingMode::SCALE_TO_FILL,
776     SamplingMode::BOX_THEN_LINEAR,
777     maskInfo,
778     synchronousLoading,
779     textureId,
780     atlasRect,
781     atlasRectSize,
782     atlasingStatus,
783     loadingStatus,
784     &observer,
785     atlasUploadObserver,
786     atlasManager,
787     true,
788     TextureManager::ReloadPolicy::CACHED,
789     preMultiply);
790
791   DALI_TEST_EQUALS(observer.mLoaded, false, TEST_LOCATION);
792   DALI_TEST_EQUALS(observer.mObserverCalled, false, TEST_LOCATION);
793
794   application.SendNotification();
795   application.Render();
796
797   // CAPTION : HARD-CODING for coverage.
798   {
799     Dali::Devel::PixelBuffer pixelBuffer = textureManager.LoadPixelBuffer(
800       filename,
801       ImageDimensions(),
802       FittingMode::SCALE_TO_FILL,
803       SamplingMode::BOX_THEN_LINEAR,
804       true, ///< synchronousLoading
805       nullptr,
806       true, ///< orientationCorrection
807       preMultiply);
808
809     std::vector<Devel::PixelBuffer> pixelBuffers;
810     pixelBuffers.push_back(pixelBuffer);
811     textureManager.AsyncLoadComplete(textureId, pixelBuffers);
812     std::vector<Devel::PixelBuffer> maskBuffers;
813     textureManager.AsyncLoadComplete(maskInfo->mAlphaMaskId, maskBuffers);
814     textureManager.RequestRemove(maskInfo->mAlphaMaskId, nullptr);
815     textureManager.RequestRemove(textureId, &observer);
816   }
817
818   application.SendNotification();
819   application.Render();
820
821   DALI_TEST_EQUALS(observer.mLoaded, true, TEST_LOCATION);
822   DALI_TEST_EQUALS(observer.mObserverCalled, true, TEST_LOCATION);
823   DALI_TEST_EQUALS(observer.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION);
824
825   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
826
827   END_TEST;
828 }
829
830 int UtcTextureManagerSynchronousLoadingFail(void)
831 {
832   ToolkitTestApplication application;
833   tet_infoline("UtcTextureManagerSynchronousLoadingFail");
834
835   TextureManager textureManager; // Create new texture manager
836
837   std::string                        maskname("");
838   TextureManager::MaskingDataPointer maskInfo = nullptr;
839   maskInfo.reset(new TextureManager::MaskingData());
840   maskInfo->mAlphaMaskUrl       = maskname;
841   maskInfo->mAlphaMaskId        = TextureManager::INVALID_TEXTURE_ID;
842   maskInfo->mCropToMask         = true;
843   maskInfo->mContentScaleFactor = 1.0f;
844
845   std::string                   filename("dummy");
846   auto                          textureId(TextureManager::INVALID_TEXTURE_ID);
847   Vector4                       atlasRect(0.f, 0.f, 0.f, 0.f);
848   Dali::ImageDimensions         atlasRectSize(0, 0);
849   bool                          atlasingStatus(false);
850   bool                          loadingStatus(false);
851   auto                          preMultiply         = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
852   ImageAtlasManagerPtr          atlasManager        = nullptr;
853   Toolkit::AtlasUploadObserver* atlasUploadObserver = nullptr;
854
855   // load image synchronously.
856   TestObserver observer;
857   TextureSet   textureSet = textureManager.LoadTexture(
858     filename,
859     ImageDimensions(),
860     FittingMode::SCALE_TO_FILL,
861     SamplingMode::BOX_THEN_LINEAR,
862     maskInfo,
863     true, // synchronous loading.
864     textureId,
865     atlasRect,
866     atlasRectSize,
867     atlasingStatus,
868     loadingStatus,
869     &observer,
870     atlasUploadObserver,
871     atlasManager,
872     true,
873     TextureManager::ReloadPolicy::CACHED,
874     preMultiply);
875
876   DALI_TEST_EQUALS(loadingStatus, false, TEST_LOCATION);
877   DALI_TEST_CHECK(!textureSet);                                     // texture loading fail.
878   DALI_TEST_CHECK(textureId == TextureManager::INVALID_TEXTURE_ID); // invalid texture id is returned.
879
880   END_TEST;
881 }
882
883 int UtcTextureManagerCachingSynchronousLoading(void)
884 {
885   ToolkitTestApplication application;
886   tet_infoline("UtcTextureManagerCachingSynchronousLoading");
887
888   TextureManager textureManager; // Create new texture manager
889
890   std::string filename(TEST_IMAGE_FILE_NAME);
891
892   std::string                        maskname("");
893   TextureManager::MaskingDataPointer maskInfo = nullptr;
894   maskInfo.reset(new TextureManager::MaskingData());
895   maskInfo->mAlphaMaskUrl       = maskname;
896   maskInfo->mAlphaMaskId        = TextureManager::INVALID_TEXTURE_ID;
897   maskInfo->mCropToMask         = true;
898   maskInfo->mContentScaleFactor = 1.0f;
899
900   Vector4                       atlasRect(0.f, 0.f, 0.f, 0.f);
901   Dali::ImageDimensions         atlasRectSize(0, 0);
902   bool                          atlasingStatus(false);
903   bool                          loadingStatus(false);
904   auto                          preMultiply         = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
905   ImageAtlasManagerPtr          atlasManager        = nullptr;
906   Toolkit::AtlasUploadObserver* atlasUploadObserver = nullptr;
907
908   // load image synchronously.
909   TestObserver observer;
910   auto         textureId(TextureManager::INVALID_TEXTURE_ID);
911   TextureSet   textureSet = textureManager.LoadTexture(
912     filename,
913     ImageDimensions(),
914     FittingMode::SCALE_TO_FILL,
915     SamplingMode::BOX_THEN_LINEAR,
916     maskInfo,
917     true, // synchronous loading.
918     textureId,
919     atlasRect,
920     atlasRectSize,
921     atlasingStatus,
922     loadingStatus,
923     &observer,
924     atlasUploadObserver,
925     atlasManager,
926     true,
927     TextureManager::ReloadPolicy::CACHED,
928     preMultiply);
929
930   DALI_TEST_EQUALS(loadingStatus, false, TEST_LOCATION);
931   DALI_TEST_CHECK(textureSet); // texture is loaded.
932
933   // observer isn't called in synchronous loading.
934   DALI_TEST_EQUALS(observer.mLoaded, false, TEST_LOCATION);
935   DALI_TEST_EQUALS(observer.mObserverCalled, false, TEST_LOCATION);
936
937   // load same image asynchronously.
938   TestObserver asyncObserver;
939   auto         asyncTextureId(TextureManager::INVALID_TEXTURE_ID);
940   loadingStatus              = false;
941   TextureSet asyncTextureSet = textureManager.LoadTexture(
942     filename,
943     ImageDimensions(),
944     FittingMode::SCALE_TO_FILL,
945     SamplingMode::BOX_THEN_LINEAR,
946     maskInfo,
947     false, // asynchronous loading.
948     asyncTextureId,
949     atlasRect,
950     atlasRectSize,
951     atlasingStatus,
952     loadingStatus,
953     &asyncObserver,
954     atlasUploadObserver,
955     atlasManager,
956     true,
957     TextureManager::ReloadPolicy::CACHED,
958     preMultiply);
959
960   DALI_TEST_EQUALS(asyncTextureId, textureId, TEST_LOCATION); // texture is loaded.
961   DALI_TEST_EQUALS(loadingStatus, false, TEST_LOCATION);
962   DALI_TEST_CHECK(asyncTextureSet); // Cached texture.
963
964   // observer is directly called because textureSet is retrieved by cache.
965   DALI_TEST_EQUALS(asyncObserver.mLoaded, true, TEST_LOCATION);
966   DALI_TEST_EQUALS(asyncObserver.mObserverCalled, true, TEST_LOCATION);
967
968   END_TEST;
969 }
970
971 int UtcTextureManagerAsyncSyncAsync(void)
972 {
973   ToolkitTestApplication application;
974   tet_infoline("UtcTextureManagerAsyncSyncAsync");
975
976   TextureManager textureManager; // Create new texture manager
977
978   std::string filename(TEST_IMAGE_FILE_NAME);
979
980   std::string                        maskname("");
981   TextureManager::MaskingDataPointer maskInfo = nullptr;
982   maskInfo.reset(new TextureManager::MaskingData());
983   maskInfo->mAlphaMaskUrl       = maskname;
984   maskInfo->mAlphaMaskId        = TextureManager::INVALID_TEXTURE_ID;
985   maskInfo->mCropToMask         = true;
986   maskInfo->mContentScaleFactor = 1.0f;
987
988   Vector4                       atlasRect(0.f, 0.f, 0.f, 0.f);
989   Dali::ImageDimensions         atlasRectSize(0, 0);
990   bool                          atlasingStatus(false);
991   auto                          preMultiply         = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
992   ImageAtlasManagerPtr          atlasManager        = nullptr;
993   Toolkit::AtlasUploadObserver* atlasUploadObserver = nullptr;
994
995   // load image asynchronously.
996   TestObserver asyncObserver1;
997   auto         asyncTextureId1(TextureManager::INVALID_TEXTURE_ID);
998   bool         asyncLoadingStatus1 = false;
999   TextureSet   asyncTextureSet1    = textureManager.LoadTexture(
1000     filename,
1001     ImageDimensions(),
1002     FittingMode::SCALE_TO_FILL,
1003     SamplingMode::BOX_THEN_LINEAR,
1004     maskInfo,
1005     false, // asynchronous loading.
1006     asyncTextureId1,
1007     atlasRect,
1008     atlasRectSize,
1009     atlasingStatus,
1010     asyncLoadingStatus1,
1011     &asyncObserver1,
1012     atlasUploadObserver,
1013     atlasManager,
1014     true,
1015     TextureManager::ReloadPolicy::CACHED,
1016     preMultiply);
1017
1018   DALI_TEST_EQUALS(asyncLoadingStatus1, true, TEST_LOCATION); // texture is loading now.
1019   DALI_TEST_CHECK(!asyncTextureSet1);                         // texture is not loaded yet.
1020
1021   // observer is still not called.
1022   DALI_TEST_EQUALS(asyncObserver1.mLoaded, false, TEST_LOCATION);
1023   DALI_TEST_EQUALS(asyncObserver1.mObserverCalled, false, TEST_LOCATION);
1024
1025   // load same image synchronously just after asynchronous loading.
1026   TestObserver syncObserver;
1027   auto         textureId(TextureManager::INVALID_TEXTURE_ID);
1028   bool         syncLoadingStatus = false;
1029   TextureSet   syncTextureSet    = textureManager.LoadTexture(
1030     filename,
1031     ImageDimensions(),
1032     FittingMode::SCALE_TO_FILL,
1033     SamplingMode::BOX_THEN_LINEAR,
1034     maskInfo,
1035     true, // synchronous loading.
1036     textureId,
1037     atlasRect,
1038     atlasRectSize,
1039     atlasingStatus,
1040     syncLoadingStatus,
1041     &syncObserver,
1042     atlasUploadObserver,
1043     atlasManager,
1044     true,
1045     TextureManager::ReloadPolicy::CACHED,
1046     preMultiply);
1047
1048   DALI_TEST_EQUALS(asyncTextureId1, textureId, TEST_LOCATION); // texture is loaded.
1049   DALI_TEST_EQUALS(syncLoadingStatus, false, TEST_LOCATION);   // texture is loaded.
1050   DALI_TEST_CHECK(syncTextureSet);                             // texture is loaded.
1051
1052   // syncObserver isn't called in synchronous loading.
1053   DALI_TEST_EQUALS(syncObserver.mLoaded, false, TEST_LOCATION);
1054   DALI_TEST_EQUALS(syncObserver.mObserverCalled, false, TEST_LOCATION);
1055
1056   // asyncObserver1 is still not called too.
1057   DALI_TEST_EQUALS(asyncObserver1.mLoaded, false, TEST_LOCATION);
1058   DALI_TEST_EQUALS(asyncObserver1.mObserverCalled, false, TEST_LOCATION);
1059
1060   // load image asynchronously.
1061   TestObserver asyncObserver2;
1062   auto         asyncTextureId2(TextureManager::INVALID_TEXTURE_ID);
1063   bool         asyncLoadingStatus2 = false;
1064   TextureSet   asyncTextureSet2    = textureManager.LoadTexture(
1065     filename,
1066     ImageDimensions(),
1067     FittingMode::SCALE_TO_FILL,
1068     SamplingMode::BOX_THEN_LINEAR,
1069     maskInfo,
1070     false, // asynchronous loading.
1071     asyncTextureId2,
1072     atlasRect,
1073     atlasRectSize,
1074     atlasingStatus,
1075     asyncLoadingStatus2,
1076     &asyncObserver2,
1077     atlasUploadObserver,
1078     atlasManager,
1079     true,
1080     TextureManager::ReloadPolicy::CACHED,
1081     preMultiply);
1082
1083   DALI_TEST_EQUALS(asyncLoadingStatus2, false, TEST_LOCATION); // texture is loaded by previous sync request
1084   DALI_TEST_CHECK(asyncTextureSet2);                           // texture is loaded
1085   Texture syncTexture   = syncTextureSet.GetTexture(0u);
1086   Texture asyncTexture2 = asyncTextureSet2.GetTexture(0u);
1087   DALI_TEST_CHECK(syncTexture);
1088   DALI_TEST_CHECK(asyncTexture2);
1089   DALI_TEST_CHECK(asyncTexture2 == syncTexture); // check loaded two texture is same.
1090
1091   // observer is called synchronously because the texture is cached.
1092   DALI_TEST_EQUALS(asyncObserver2.mLoaded, true, TEST_LOCATION);
1093   DALI_TEST_EQUALS(asyncObserver2.mObserverCalled, true, TEST_LOCATION);
1094
1095   asyncObserver2.mLoaded         = false;
1096   asyncObserver2.mObserverCalled = false;
1097
1098   application.SendNotification();
1099   application.Render();
1100
1101   // Requested asynchronous loading at first is finished now and async observer is called now.
1102   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
1103   DALI_TEST_EQUALS(asyncObserver1.mLoaded, true, TEST_LOCATION);
1104   DALI_TEST_EQUALS(asyncObserver1.mObserverCalled, true, TEST_LOCATION);
1105   DALI_TEST_CHECK(asyncObserver1.mTextureSet);
1106
1107   Texture observerTexture = asyncObserver1.mTextureSet.GetTexture(0u);
1108   DALI_TEST_CHECK(observerTexture == asyncTexture2); // check loaded two texture is same.
1109
1110   // asyncObserver2 was already called so it isn't called here.
1111   DALI_TEST_EQUALS(asyncObserver2.mLoaded, false, TEST_LOCATION);
1112   DALI_TEST_EQUALS(asyncObserver2.mObserverCalled, false, TEST_LOCATION);
1113
1114   END_TEST;
1115 }
1116
1117 int UtcTextureManagerQueueRemoveDuringObserve(void)
1118 {
1119   ToolkitTestApplication application;
1120   tet_infoline("UtcTextureManagerQueueRemoveDuringObserve");
1121
1122   TextureManager textureManager; // Create new texture manager
1123
1124   TestObserverRemoveAndGenerateUrl observer(&textureManager); // special observer for this UTC.
1125
1126   std::string filename(TEST_IMAGE_FILE_NAME);
1127   auto        preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
1128
1129   TextureManager::TextureId textureId = textureManager.RequestLoad(
1130     filename,
1131     ImageDimensions(),
1132     FittingMode::SCALE_TO_FILL,
1133     SamplingMode::BOX_THEN_LINEAR,
1134     TextureManager::UseAtlas::NO_ATLAS,
1135     &observer,
1136     true,
1137     TextureManager::ReloadPolicy::CACHED,
1138     preMultiply);
1139
1140   DALI_TEST_EQUALS(observer.mLoaded, false, TEST_LOCATION);
1141   DALI_TEST_EQUALS(observer.mObserverCalled, false, TEST_LOCATION);
1142
1143   application.SendNotification();
1144   application.Render();
1145
1146   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
1147
1148   application.SendNotification();
1149   application.Render();
1150
1151   DALI_TEST_EQUALS(observer.mLoaded, true, TEST_LOCATION);
1152   DALI_TEST_EQUALS(observer.mObserverCalled, true, TEST_LOCATION);
1153   DALI_TEST_EQUALS(observer.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION);
1154
1155   tet_printf("loaded textureId is %d, generated url is %s\n", static_cast<int>(textureId), observer.mGeneratedExternalUrl.c_str());
1156
1157   DALI_TEST_CHECK(static_cast<int>(textureId) != std::stoi(VisualUrl::GetLocation(observer.mGeneratedExternalUrl))); // Check we don't reuse textureId during observe
1158
1159   // Decrease external texture reference count who observer created
1160   textureManager.RemoveExternalTexture(observer.mGeneratedExternalUrl);
1161
1162   application.SendNotification();
1163   application.Render();
1164
1165   END_TEST;
1166 }
1167
1168 int UtcTextureManagerRemoveDuringApplyMasking(void)
1169 {
1170   ToolkitTestApplication application;
1171   tet_infoline("UtcTextureManagerRemoveDuringApplyMasking");
1172
1173   TextureManager textureManager; // Create new texture manager
1174
1175   TestObserver observer1;
1176   TestObserver observer2;
1177
1178   std::string                        filename(TEST_IMAGE_FILE_NAME);
1179   std::string                        maskname(TEST_MASK_FILE_NAME);
1180   TextureManager::MaskingDataPointer maskInfo = nullptr;
1181   maskInfo.reset(new TextureManager::MaskingData());
1182   maskInfo->mAlphaMaskUrl       = maskname;
1183   maskInfo->mAlphaMaskId        = TextureManager::INVALID_TEXTURE_ID;
1184   maskInfo->mCropToMask         = true;
1185   maskInfo->mContentScaleFactor = 1.0f;
1186
1187   auto                          textureId1(TextureManager::INVALID_TEXTURE_ID);
1188   Vector4                       atlasRect(0.f, 0.f, 1.f, 1.f);
1189   Dali::ImageDimensions         atlasRectSize(0, 0);
1190   bool                          synchronousLoading(false);
1191   bool                          atlasingStatus(false);
1192   bool                          loadingStatus(false);
1193   auto                          preMultiply         = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
1194   ImageAtlasManagerPtr          atlasManager        = nullptr;
1195   Toolkit::AtlasUploadObserver* atlasUploadObserver = nullptr;
1196
1197   textureManager.LoadTexture(
1198     filename,
1199     ImageDimensions(),
1200     FittingMode::SCALE_TO_FILL,
1201     SamplingMode::BOX_THEN_LINEAR,
1202     maskInfo,
1203     synchronousLoading,
1204     textureId1,
1205     atlasRect,
1206     atlasRectSize,
1207     atlasingStatus,
1208     loadingStatus,
1209     &observer1,
1210     atlasUploadObserver,
1211     atlasManager,
1212     true,
1213     TextureManager::ReloadPolicy::CACHED,
1214     preMultiply);
1215
1216   DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
1217   DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
1218
1219   application.SendNotification();
1220   application.Render();
1221
1222   // Load image and mask image.
1223   // Now, LoadState become MASK_APPLYING
1224   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
1225
1226   tet_printf("Current textureId1:%d's state become MASK_APPLYING\n", static_cast<int>(textureId1));
1227
1228   application.SendNotification();
1229   application.Render();
1230
1231   DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
1232   DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
1233
1234   // Remove current textureId1. and request new texture again.
1235   textureManager.RequestRemove(textureId1, &observer1);
1236   auto textureId2 = textureManager.RequestLoad(
1237     filename,
1238     ImageDimensions(),
1239     FittingMode::SCALE_TO_FILL,
1240     SamplingMode::BOX_THEN_LINEAR,
1241     TextureManager::UseAtlas::NO_ATLAS,
1242     &observer2,
1243     true, ///< orientationCorrection
1244     TextureManager::ReloadPolicy::CACHED,
1245     preMultiply,
1246     synchronousLoading);
1247
1248   application.SendNotification();
1249   application.Render();
1250
1251   DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
1252   DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
1253   DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION);
1254   DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION);
1255
1256   tet_printf("textureId1:%d removed and textureId2:%d requested\n", static_cast<int>(textureId1), static_cast<int>(textureId2));
1257
1258   // CAPTION : HARD-CODING.
1259   {
1260     std::vector<Devel::PixelBuffer> pixelBuffers;
1261     textureManager.AsyncLoadComplete(textureId2, pixelBuffers);
1262     textureManager.RequestRemove(textureId2, &observer2);
1263   }
1264
1265   DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION); ///< Note that we call AsyncLoadComplete hardly with empty pixelbuffer.
1266   DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION);
1267   DALI_TEST_EQUALS(observer2.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION);
1268
1269   END_TEST;
1270 }
1271
1272 int UtcTextureManagerMaskCacheTest(void)
1273 {
1274   ToolkitTestApplication application;
1275   tet_infoline("UtcTextureManagerMaskCacheTest");
1276
1277   TextureManager textureManager; // Create new texture manager
1278
1279   TestObserver observer1;
1280   TestObserver observer2;
1281
1282   std::string                        filename(TEST_IMAGE_FILE_NAME);
1283   std::string                        filename2(TEST_IMAGE_2_FILE_NAME);
1284   std::string                        maskname(TEST_MASK_FILE_NAME);
1285   TextureManager::MaskingDataPointer maskInfo = nullptr;
1286   maskInfo.reset(new TextureManager::MaskingData());
1287   maskInfo->mAlphaMaskUrl       = maskname;
1288   maskInfo->mAlphaMaskId        = TextureManager::INVALID_TEXTURE_ID;
1289   maskInfo->mCropToMask         = true;
1290   maskInfo->mContentScaleFactor = 1.0f;
1291
1292   TextureManager::MaskingDataPointer maskInfo2 = nullptr;
1293   maskInfo2.reset(new TextureManager::MaskingData());
1294   maskInfo2->mAlphaMaskUrl       = maskname;
1295   maskInfo2->mAlphaMaskId        = TextureManager::INVALID_TEXTURE_ID;
1296   maskInfo2->mCropToMask         = true;
1297   maskInfo2->mContentScaleFactor = 1.0f;
1298
1299   auto                          textureId1(TextureManager::INVALID_TEXTURE_ID);
1300   auto                          textureId2(TextureManager::INVALID_TEXTURE_ID);
1301   Vector4                       atlasRect(0.f, 0.f, 1.f, 1.f);
1302   Dali::ImageDimensions         atlasRectSize(0, 0);
1303   bool                          synchronousLoading(false);
1304   bool                          atlasingStatus(false);
1305   bool                          loadingStatus(false);
1306   auto                          preMultiply         = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
1307   ImageAtlasManagerPtr          atlasManager        = nullptr;
1308   Toolkit::AtlasUploadObserver* atlasUploadObserver = nullptr;
1309
1310   textureManager.LoadTexture(
1311     filename,
1312     ImageDimensions(),
1313     FittingMode::SCALE_TO_FILL,
1314     SamplingMode::BOX_THEN_LINEAR,
1315     maskInfo,
1316     synchronousLoading,
1317     textureId1,
1318     atlasRect,
1319     atlasRectSize,
1320     atlasingStatus,
1321     loadingStatus,
1322     &observer1,
1323     atlasUploadObserver,
1324     atlasManager,
1325     true,
1326     TextureManager::ReloadPolicy::CACHED,
1327     preMultiply);
1328
1329   DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
1330   DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
1331
1332   application.SendNotification();
1333   application.Render();
1334
1335   // Load image and mask image.
1336   // Now, LoadState become MASK_APPLYING
1337   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
1338
1339   tet_printf("Current textureId1:%d's state become MASK_APPLYING\n", static_cast<int>(textureId1));
1340
1341   textureManager.LoadTexture(
1342     filename2,
1343     ImageDimensions(),
1344     FittingMode::SCALE_TO_FILL,
1345     SamplingMode::BOX_THEN_LINEAR,
1346     maskInfo2,
1347     synchronousLoading,
1348     textureId2,
1349     atlasRect,
1350     atlasRectSize,
1351     atlasingStatus,
1352     loadingStatus,
1353     &observer2,
1354     atlasUploadObserver,
1355     atlasManager,
1356     true,
1357     TextureManager::ReloadPolicy::CACHED,
1358     preMultiply);
1359
1360   application.SendNotification();
1361   application.Render();
1362
1363   // Load image2 + image1 apply mask + image2 apply mask = total 3 event trigger required.
1364   // Note that we use cached mask image.
1365   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
1366
1367   DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
1368   DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
1369   DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION);
1370   DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION);
1371
1372   try
1373   {
1374     // Remove textureId1 first, and then remove textureId2. Check whether segfault occured.
1375     textureManager.RequestRemove(textureId1, &observer1);
1376
1377     application.SendNotification();
1378     application.Render();
1379
1380     textureManager.RequestRemove(textureId2, &observer2);
1381
1382     application.SendNotification();
1383     application.Render();
1384
1385     TestObserver observer3;
1386     maskInfo.reset(new TextureManager::MaskingData());
1387     maskInfo->mAlphaMaskUrl       = maskname;
1388     maskInfo->mAlphaMaskId        = TextureManager::INVALID_TEXTURE_ID;
1389     maskInfo->mCropToMask         = true;
1390     maskInfo->mContentScaleFactor = 1.0f;
1391
1392     textureManager.LoadTexture(
1393       filename,
1394       ImageDimensions(),
1395       FittingMode::SCALE_TO_FILL,
1396       SamplingMode::BOX_THEN_LINEAR,
1397       maskInfo,
1398       synchronousLoading,
1399       textureId1,
1400       atlasRect,
1401       atlasRectSize,
1402       atlasingStatus,
1403       loadingStatus,
1404       &observer3,
1405       atlasUploadObserver,
1406       atlasManager,
1407       true,
1408       TextureManager::ReloadPolicy::CACHED,
1409       preMultiply);
1410
1411     DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
1412     DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
1413
1414     application.SendNotification();
1415     application.Render();
1416
1417     // Load image and mask image.
1418     DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
1419     DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
1420
1421     DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
1422     DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
1423
1424     // Apply mask.
1425     DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
1426
1427     DALI_TEST_EQUALS(observer3.mLoaded, true, TEST_LOCATION);
1428     DALI_TEST_EQUALS(observer3.mObserverCalled, true, TEST_LOCATION);
1429   }
1430   catch(...)
1431   {
1432     DALI_TEST_CHECK(false);
1433   }
1434
1435   END_TEST;
1436 }
1437
1438 int UtcTextureManagerRemoveDuringGPUMasking(void)
1439 {
1440   ToolkitTestApplication application;
1441   tet_infoline("UtcTextureManagerRemoveDuringGPUMasking");
1442   tet_infoline("Request 3 different GPU masking image.");
1443   tet_infoline("Control to mask image load last. and then, check execute result.");
1444
1445   TextureManager textureManager; // Create new texture manager
1446
1447   TestObserverWithCustomFunction  observer1;
1448   TestObserverWithCustomFunction  observer2;
1449   TestObserverWithCustomFunction* observer3 = new TestObserverWithCustomFunction(); // Deleted in observer1 loaded signal
1450   TestObserver                    observer4;
1451
1452   std::string filename1(TEST_IMAGE_FILE_NAME);
1453   std::string filename2(TEST_IMAGE_2_FILE_NAME);
1454   std::string filename3(TEST_IMAGE_3_FILE_NAME);
1455   std::string filename4(TEST_IMAGE_4_FILE_NAME);
1456
1457   auto textureId1(TextureManager::INVALID_TEXTURE_ID);
1458   auto textureId2(TextureManager::INVALID_TEXTURE_ID);
1459   auto textureId3(TextureManager::INVALID_TEXTURE_ID);
1460   auto textureId4(TextureManager::INVALID_TEXTURE_ID);
1461
1462   std::string                        maskname(TEST_MASK_FILE_NAME);
1463   TextureManager::MaskingDataPointer maskInfo[3] = {nullptr, nullptr, nullptr};
1464   for(int i = 0; i < 3; i++)
1465   {
1466     maskInfo[i].reset(new TextureManager::MaskingData());
1467     maskInfo[i]->mAlphaMaskUrl       = maskname;
1468     maskInfo[i]->mAlphaMaskId        = TextureManager::INVALID_TEXTURE_ID;
1469     maskInfo[i]->mCropToMask         = true;
1470     maskInfo[i]->mPreappliedMasking  = false; // To make GPU masking
1471     maskInfo[i]->mContentScaleFactor = 1.0f;
1472   }
1473   Vector4                       atlasRect(0.f, 0.f, 1.f, 1.f);
1474   Dali::ImageDimensions         atlasRectSize(0, 0);
1475   bool                          synchronousLoading(false);
1476   bool                          atlasingStatus(false);
1477   bool                          loadingStatus(false);
1478   auto                          preMultiply         = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
1479   ImageAtlasManagerPtr          atlasManager        = nullptr;
1480   Toolkit::AtlasUploadObserver* atlasUploadObserver = nullptr;
1481
1482   // Request image 1, 2, 3 with GPU masking
1483   textureManager.LoadTexture(
1484     filename1,
1485     ImageDimensions(),
1486     FittingMode::SCALE_TO_FILL,
1487     SamplingMode::BOX_THEN_LINEAR,
1488     maskInfo[0],
1489     synchronousLoading,
1490     textureId1,
1491     atlasRect,
1492     atlasRectSize,
1493     atlasingStatus,
1494     loadingStatus,
1495     &observer1,
1496     atlasUploadObserver,
1497     atlasManager,
1498     true,
1499     TextureManager::ReloadPolicy::CACHED,
1500     preMultiply);
1501
1502   textureManager.LoadTexture(
1503     filename2,
1504     ImageDimensions(),
1505     FittingMode::SCALE_TO_FILL,
1506     SamplingMode::BOX_THEN_LINEAR,
1507     maskInfo[1],
1508     synchronousLoading,
1509     textureId2,
1510     atlasRect,
1511     atlasRectSize,
1512     atlasingStatus,
1513     loadingStatus,
1514     &observer2,
1515     atlasUploadObserver,
1516     atlasManager,
1517     true,
1518     TextureManager::ReloadPolicy::CACHED,
1519     preMultiply);
1520
1521   textureManager.LoadTexture(
1522     filename3,
1523     ImageDimensions(),
1524     FittingMode::SCALE_TO_FILL,
1525     SamplingMode::BOX_THEN_LINEAR,
1526     maskInfo[2],
1527     synchronousLoading,
1528     textureId3,
1529     atlasRect,
1530     atlasRectSize,
1531     atlasingStatus,
1532     loadingStatus,
1533     observer3,
1534     atlasUploadObserver,
1535     atlasManager,
1536     true,
1537     TextureManager::ReloadPolicy::CACHED,
1538     preMultiply);
1539
1540   DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
1541   DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
1542   DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION);
1543   DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION);
1544   DALI_TEST_EQUALS(observer3->mLoaded, false, TEST_LOCATION);
1545   DALI_TEST_EQUALS(observer3->mObserverCalled, false, TEST_LOCATION);
1546   DALI_TEST_EQUALS(observer4.mLoaded, false, TEST_LOCATION);
1547   DALI_TEST_EQUALS(observer4.mObserverCalled, false, TEST_LOCATION);
1548
1549   // Check we use cached mask image
1550   DALI_TEST_CHECK(maskInfo[0]->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID);
1551   DALI_TEST_EQUALS(maskInfo[0]->mAlphaMaskId, maskInfo[1]->mAlphaMaskId, TEST_LOCATION);
1552   DALI_TEST_EQUALS(maskInfo[0]->mAlphaMaskId, maskInfo[2]->mAlphaMaskId, TEST_LOCATION);
1553
1554   // Connect observer1 custom function
1555   struct CustomData1
1556   {
1557     TextureManager*           textureManagerPtr{nullptr};
1558     TextureManager::TextureId removeTextureId{TextureManager::INVALID_TEXTURE_ID};
1559     TestObserver*             removeTextureObserver{nullptr};
1560   };
1561   CustomData1 data1;
1562   data1.textureManagerPtr     = &textureManager;
1563   data1.removeTextureId       = textureId3;
1564   data1.removeTextureObserver = observer3;
1565
1566   observer1.mData = &data1;
1567   observer1.ConnectFunction(
1568     [](void* data) {
1569       DALI_TEST_CHECK(data);
1570       CustomData1 data1 = *(CustomData1*)data;
1571
1572       DALI_TEST_CHECK(data1.textureManagerPtr);
1573       DALI_TEST_CHECK(data1.removeTextureId != TextureManager::INVALID_TEXTURE_ID);
1574       DALI_TEST_CHECK(data1.removeTextureObserver);
1575
1576       // Remove textureId3.
1577       data1.textureManagerPtr->RequestRemove(data1.removeTextureId, data1.removeTextureObserver);
1578
1579       // Destroy observer3
1580       delete data1.removeTextureObserver;
1581     });
1582
1583   // Connect observer2 custom function
1584   struct CustomData2
1585   {
1586     TextureManager*            textureManagerPtr{nullptr};
1587     std::string                addTextureUrl{};
1588     TextureManager::TextureId* addTextureIdPtr{nullptr};
1589     TestObserver*              addTextureObserver{nullptr};
1590   };
1591   CustomData2 data2;
1592   data2.textureManagerPtr  = &textureManager;
1593   data2.addTextureUrl      = filename4;
1594   data2.addTextureIdPtr    = &textureId4;
1595   data2.addTextureObserver = &observer4;
1596
1597   observer2.mData = &data2;
1598   observer2.ConnectFunction(
1599     [](void* data) {
1600       DALI_TEST_CHECK(data);
1601       CustomData2 data2 = *(CustomData2*)data;
1602
1603       DALI_TEST_CHECK(data2.textureManagerPtr);
1604       DALI_TEST_CHECK(!data2.addTextureUrl.empty());
1605       DALI_TEST_CHECK(data2.addTextureIdPtr);
1606       DALI_TEST_CHECK(data2.addTextureObserver);
1607
1608       auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
1609
1610       // Load textureId4
1611       (*data2.addTextureIdPtr) = data2.textureManagerPtr->RequestLoad(
1612         data2.addTextureUrl,
1613         ImageDimensions(),
1614         FittingMode::SCALE_TO_FILL,
1615         SamplingMode::BOX_THEN_LINEAR,
1616         TextureManager::UseAtlas::NO_ATLAS,
1617         data2.addTextureObserver,
1618         true,
1619         TextureManager::ReloadPolicy::CACHED,
1620         preMultiply);
1621     });
1622
1623   // Connect observer3 custom function
1624   struct CustomData3
1625   {
1626     TestObserver* self{nullptr};
1627     bool*         observerLoadedPtr{nullptr};
1628     bool*         observerCalleddPtr{nullptr};
1629   };
1630   CustomData3 data3;
1631   bool        observer3Loaded = false;
1632   bool        observer3Called = false;
1633   data3.self                  = observer3;
1634   data3.observerLoadedPtr     = &observer3Loaded;
1635   data3.observerCalleddPtr    = &observer3Called;
1636
1637   observer3->mData = &data3;
1638   observer3->ConnectFunction(
1639     [](void* data) {
1640       DALI_TEST_CHECK(data);
1641       CustomData3 data3 = *(CustomData3*)data;
1642
1643       DALI_TEST_CHECK(data3.self);
1644       DALI_TEST_CHECK(data3.observerLoadedPtr);
1645       DALI_TEST_CHECK(data3.observerCalleddPtr);
1646
1647       *data3.observerLoadedPtr  = data3.self->mLoaded;
1648       *data3.observerCalleddPtr = data3.self->mObserverCalled;
1649     });
1650
1651   application.SendNotification();
1652   application.Render();
1653
1654   tet_printf("Id info - mask : {%d}, 1 : {%d}, 2 : {%d}, 3 : {%d}, 4 : {%d}\n", static_cast<int>(maskInfo[0]->mAlphaMaskId), static_cast<int>(textureId1), static_cast<int>(textureId2), static_cast<int>(textureId3), static_cast<int>(textureId4));
1655
1656   // CAPTION : HARD-CODING.
1657   {
1658     // Complete async load 1, 2, 3.
1659     std::vector<Devel::PixelBuffer> pixelBuffers;
1660
1661     pixelBuffers.clear();
1662     pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888));
1663     textureManager.AsyncLoadComplete(textureId1, pixelBuffers);
1664     pixelBuffers.clear();
1665     pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888));
1666     textureManager.AsyncLoadComplete(textureId2, pixelBuffers);
1667     pixelBuffers.clear();
1668     pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888));
1669     textureManager.AsyncLoadComplete(textureId3, pixelBuffers);
1670
1671     // Ensure textureId3 remove request processed.
1672
1673     DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
1674     DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
1675     DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION);
1676     DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION);
1677     DALI_TEST_EQUALS(observer3Loaded, false, TEST_LOCATION);
1678     DALI_TEST_EQUALS(observer3Called, false, TEST_LOCATION);
1679     DALI_TEST_EQUALS(observer4.mLoaded, false, TEST_LOCATION);
1680     DALI_TEST_EQUALS(observer4.mObserverCalled, false, TEST_LOCATION);
1681
1682     // Complete mask load.
1683     pixelBuffers.clear();
1684     pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::L8));
1685     textureManager.AsyncLoadComplete(maskInfo[0]->mAlphaMaskId, pixelBuffers);
1686
1687     tet_printf("Id info after observer notify - mask : {%d}, 1 : {%d}, 2 : {%d}, 3 : {%d}, 4 : {%d}\n", static_cast<int>(maskInfo[0]->mAlphaMaskId), static_cast<int>(textureId1), static_cast<int>(textureId2), static_cast<int>(textureId3), static_cast<int>(textureId4));
1688
1689     // Check observer 1 and 2 called, but 3 and 4 not called.
1690     DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
1691     DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
1692     DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION);
1693     DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION);
1694     DALI_TEST_EQUALS(observer3Loaded, false, TEST_LOCATION);
1695     DALI_TEST_EQUALS(observer3Called, false, TEST_LOCATION);
1696     DALI_TEST_EQUALS(observer4.mLoaded, false, TEST_LOCATION);
1697     DALI_TEST_EQUALS(observer4.mObserverCalled, false, TEST_LOCATION);
1698
1699     // Check textureId4
1700     DALI_TEST_CHECK(textureId4 != TextureManager::INVALID_TEXTURE_ID);
1701
1702     // Complete 4.
1703     pixelBuffers.clear();
1704     pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888));
1705     textureManager.AsyncLoadComplete(textureId4, pixelBuffers);
1706
1707     DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
1708     DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
1709     DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION);
1710     DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION);
1711     DALI_TEST_EQUALS(observer3Loaded, false, TEST_LOCATION);
1712     DALI_TEST_EQUALS(observer3Called, false, TEST_LOCATION);
1713     DALI_TEST_EQUALS(observer4.mLoaded, true, TEST_LOCATION);
1714     DALI_TEST_EQUALS(observer4.mObserverCalled, true, TEST_LOCATION);
1715   }
1716
1717   END_TEST;
1718 }
1719
1720 int UtcTextureManagerDestroyObserverDuringObserve(void)
1721 {
1722   ToolkitTestApplication application;
1723   tet_infoline("UtcTextureManagerDestroyObserverDuringObserve");
1724   tet_infoline("Request 3 different image.");
1725   tet_infoline("Complete textureId1. After observer1 loaded done,");
1726   tet_infoline(" - Remove and destroy observer2");
1727   tet_infoline(" - Re-generate observer2 which has same address pointer with before.");
1728   tet_infoline(" - Remove and Reqeust third file by observer3");
1729   tet_infoline("Complete textureId2. and check old observer2 not emmited, and newly observer2 works.");
1730   tet_infoline("Complete textureId3. and check observer3 comes");
1731
1732   TextureManager textureManager; // Create new texture manager
1733
1734   TestObserverWithCustomFunction  observer1;
1735   TestObserverWithCustomFunction* observer2 = new TestObserverWithCustomFunction(); // Deleted in observer1 loaded signal.
1736   TestObserver                    observer3;
1737
1738   std::string filename1(TEST_IMAGE_FILE_NAME);
1739   std::string filename2(TEST_IMAGE_2_FILE_NAME);
1740   std::string filename3(TEST_IMAGE_3_FILE_NAME);
1741   std::string filename4(TEST_IMAGE_4_FILE_NAME);
1742
1743   auto textureId1(TextureManager::INVALID_TEXTURE_ID);
1744   auto textureId2(TextureManager::INVALID_TEXTURE_ID);
1745   auto textureId3(TextureManager::INVALID_TEXTURE_ID);
1746   auto textureId4(TextureManager::INVALID_TEXTURE_ID);
1747
1748   // Dummy reference value
1749   auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
1750
1751   // Request image 1, 2, 3.
1752   textureId1 = textureManager.RequestLoad(
1753     filename1,
1754     ImageDimensions(),
1755     FittingMode::SCALE_TO_FILL,
1756     SamplingMode::BOX_THEN_LINEAR,
1757     TextureManager::UseAtlas::NO_ATLAS,
1758     &observer1,
1759     true,
1760     TextureManager::ReloadPolicy::CACHED,
1761     preMultiply);
1762
1763   textureId2 = textureManager.RequestLoad(
1764     filename2,
1765     ImageDimensions(),
1766     FittingMode::SCALE_TO_FILL,
1767     SamplingMode::BOX_THEN_LINEAR,
1768     TextureManager::UseAtlas::NO_ATLAS,
1769     observer2,
1770     true,
1771     TextureManager::ReloadPolicy::CACHED,
1772     preMultiply);
1773
1774   textureId3 = textureManager.RequestLoad(
1775     filename3,
1776     ImageDimensions(),
1777     FittingMode::SCALE_TO_FILL,
1778     SamplingMode::BOX_THEN_LINEAR,
1779     TextureManager::UseAtlas::NO_ATLAS,
1780     &observer3,
1781     true,
1782     TextureManager::ReloadPolicy::CACHED,
1783     preMultiply);
1784
1785   struct CustomData1
1786   {
1787     TextureManager*                  textureManagerPtr{nullptr};
1788     TextureManager::TextureId        removeTextureId{TextureManager::INVALID_TEXTURE_ID};
1789     TestObserverWithCustomFunction** removeTextureObserver{nullptr};
1790     std::string                      resendFilename{};
1791     TextureManager::TextureId        resendTextureId{TextureManager::INVALID_TEXTURE_ID};
1792     TestObserver*                    resendTextureObserver{nullptr};
1793     std::string                      newlyFilename{};
1794     TextureManager::TextureId*       newlyTextureIdPtr{nullptr};
1795   };
1796   struct CustomData2
1797   {
1798     TextureManager* textureManagerPtr{nullptr};
1799     TestObserver*   self{nullptr};
1800     bool*           observerLoadedPtr{nullptr};
1801     bool*           observerCalledPtr{nullptr};
1802   };
1803
1804   bool        observer2Loaded    = false;
1805   bool        observer2Called    = false;
1806   bool        newObserver2Loaded = false;
1807   bool        newObserver2Called = false;
1808   CustomData2 newData2; // Used on observer1 function
1809
1810   // Connect observer1 custom function
1811   CustomData1 data1;
1812   data1.textureManagerPtr     = &textureManager;
1813   data1.removeTextureId       = textureId2;
1814   data1.removeTextureObserver = &observer2;
1815   data1.resendFilename        = filename3;
1816   data1.resendTextureId       = textureId3;
1817   data1.resendTextureObserver = &observer3;
1818   data1.newlyFilename         = filename2; // Same as observer2 filename
1819   data1.newlyTextureIdPtr     = &textureId4;
1820
1821   observer1.mData = &data1;
1822   observer1.ConnectFunction(
1823     [&](void* data) {
1824       DALI_TEST_CHECK(data);
1825       CustomData1 data1 = *(CustomData1*)data;
1826
1827       DALI_TEST_CHECK(data1.textureManagerPtr);
1828       DALI_TEST_CHECK(data1.removeTextureId != TextureManager::INVALID_TEXTURE_ID);
1829       DALI_TEST_CHECK(data1.removeTextureObserver);
1830       DALI_TEST_CHECK(*data1.removeTextureObserver);
1831       DALI_TEST_CHECK(!data1.resendFilename.empty());
1832       DALI_TEST_CHECK(data1.resendTextureId != TextureManager::INVALID_TEXTURE_ID);
1833       DALI_TEST_CHECK(data1.resendTextureObserver);
1834       DALI_TEST_CHECK(!data1.newlyFilename.empty());
1835       DALI_TEST_CHECK(data1.newlyTextureIdPtr);
1836       DALI_TEST_CHECK(*data1.newlyTextureIdPtr == TextureManager::INVALID_TEXTURE_ID);
1837
1838       // Remove textureId2.
1839       data1.textureManagerPtr->RequestRemove(data1.removeTextureId, *data1.removeTextureObserver);
1840
1841       auto removedObserver = *data1.removeTextureObserver;
1842
1843       // Destroy observer2.
1844       delete removedObserver;
1845
1846       // Create new observer. Make we use same pointer if we can.
1847       uint32_t maxTryCount = 100u;
1848       uint32_t tryCount    = 0u;
1849
1850       while(tryCount < maxTryCount)
1851       {
1852         *data1.removeTextureObserver = new TestObserverWithCustomFunction();
1853         if(removedObserver == *data1.removeTextureObserver) break;
1854         ++tryCount;
1855         delete *data1.removeTextureObserver;
1856       }
1857
1858       tet_printf("TryCount[%u] / Old observer2 : %p, newly observer2 : %p\n", tryCount, removedObserver, *data1.removeTextureObserver);
1859
1860       // Connect new observer2 custom function
1861       newData2.textureManagerPtr = &textureManager;
1862       newData2.self              = (*data1.removeTextureObserver);
1863       newData2.observerLoadedPtr = &newObserver2Loaded;
1864       newData2.observerCalledPtr = &newObserver2Called;
1865
1866       (*data1.removeTextureObserver)->mData = &newData2;
1867       (*data1.removeTextureObserver)->ConnectFunction([](void* data) {
1868         DALI_TEST_CHECK(data);
1869         CustomData2 data2 = *(CustomData2*)data;
1870
1871         tet_printf("New created observer running\n");
1872
1873         DALI_TEST_CHECK(data2.self);
1874         DALI_TEST_CHECK(data2.observerLoadedPtr);
1875         DALI_TEST_CHECK(data2.observerCalledPtr);
1876
1877         *data2.observerLoadedPtr = data2.self->mLoaded;
1878         *data2.observerCalledPtr = data2.self->mObserverCalled;
1879       });
1880
1881       // Dummy reference value
1882       auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
1883
1884       // Resend textureId3
1885       data1.textureManagerPtr->RequestRemove(data1.resendTextureId, data1.resendTextureObserver);
1886
1887       TextureManager::TextureId tempId;
1888       tempId = data1.textureManagerPtr->RequestLoad(
1889         data1.resendFilename,
1890         ImageDimensions(),
1891         FittingMode::SCALE_TO_FILL,
1892         SamplingMode::BOX_THEN_LINEAR,
1893         TextureManager::UseAtlas::NO_ATLAS,
1894         data1.resendTextureObserver,
1895         true,
1896         TextureManager::ReloadPolicy::CACHED,
1897         preMultiply);
1898
1899       DALI_TEST_CHECK(tempId == data1.resendTextureId);
1900
1901       // Request new task
1902
1903       tempId = data1.textureManagerPtr->RequestLoad(
1904         data1.newlyFilename,
1905         ImageDimensions(),
1906         FittingMode::SCALE_TO_FILL,
1907         SamplingMode::BOX_THEN_LINEAR,
1908         TextureManager::UseAtlas::NO_ATLAS,
1909         *data1.removeTextureObserver,
1910         true,
1911         TextureManager::ReloadPolicy::CACHED,
1912         preMultiply);
1913
1914       DALI_TEST_CHECK(tempId != TextureManager::INVALID_TEXTURE_ID);
1915       *data1.newlyTextureIdPtr = tempId;
1916     });
1917
1918   // Connect observer2 custom function
1919   CustomData2 data2;
1920   data2.textureManagerPtr = &textureManager;
1921   data2.self              = observer2;
1922   data2.observerLoadedPtr = &observer2Loaded;
1923   data2.observerCalledPtr = &observer2Called;
1924
1925   observer2->mData = &data2;
1926   observer2->ConnectFunction(
1927     [](void* data) {
1928       DALI_TEST_CHECK(data);
1929       CustomData2 data2 = *(CustomData2*)data;
1930
1931       tet_printf("Old created observer running. Something error occured!\n");
1932
1933       DALI_TEST_CHECK(data2.self);
1934       DALI_TEST_CHECK(data2.observerLoadedPtr);
1935       DALI_TEST_CHECK(data2.observerCalledPtr);
1936
1937       *data2.observerLoadedPtr = data2.self->mLoaded;
1938       *data2.observerCalledPtr = data2.self->mObserverCalled;
1939     });
1940
1941   application.SendNotification();
1942   application.Render();
1943
1944   tet_printf("Id info - 1 : {%d}, 2 : {%d}, 3 : {%d}, 4 : {%d}\n", static_cast<int>(textureId1), static_cast<int>(textureId2), static_cast<int>(textureId3), static_cast<int>(textureId4));
1945
1946   DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
1947   DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
1948   DALI_TEST_EQUALS(observer2Loaded, false, TEST_LOCATION);
1949   DALI_TEST_EQUALS(observer2Called, false, TEST_LOCATION);
1950   DALI_TEST_EQUALS(newObserver2Loaded, false, TEST_LOCATION);
1951   DALI_TEST_EQUALS(newObserver2Called, false, TEST_LOCATION);
1952   DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
1953   DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
1954
1955   DALI_TEST_CHECK(textureId4 == TextureManager::INVALID_TEXTURE_ID);
1956
1957   // CAPTION : HARD-CODING.
1958   // Run codes without exception.
1959   try
1960   {
1961     tet_printf("Complete async load 1 first.\n");
1962     std::vector<Devel::PixelBuffer> pixelBuffers;
1963
1964     pixelBuffers.clear();
1965     pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888));
1966     textureManager.AsyncLoadComplete(textureId1, pixelBuffers);
1967
1968     tet_printf("Now observer2 deleted, observer3 resended, observer2 re-created.\n");
1969     DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
1970     DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
1971     DALI_TEST_EQUALS(observer2Loaded, false, TEST_LOCATION);
1972     DALI_TEST_EQUALS(observer2Called, false, TEST_LOCATION);
1973     DALI_TEST_EQUALS(newObserver2Loaded, false, TEST_LOCATION);
1974     DALI_TEST_EQUALS(newObserver2Called, false, TEST_LOCATION);
1975     DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
1976     DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
1977
1978     tet_printf("Id info - 1 : {%d}, 2 : {%d}, 3 : {%d}, 4 : {%d}\n", static_cast<int>(textureId1), static_cast<int>(textureId2), static_cast<int>(textureId3), static_cast<int>(textureId4));
1979
1980     DALI_TEST_CHECK(textureId4 == textureId2);
1981
1982     // Remove processor excute.
1983     application.SendNotification();
1984     application.Render();
1985
1986     tet_printf("Complete async load 2. Let we check old version observer2 ignored and newly observer2 loaded.\n");
1987     pixelBuffers.clear();
1988     pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888));
1989     textureManager.AsyncLoadComplete(textureId2, pixelBuffers);
1990
1991     DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
1992     DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
1993     DALI_TEST_EQUALS(observer2Loaded, false, TEST_LOCATION);
1994     DALI_TEST_EQUALS(observer2Called, false, TEST_LOCATION);
1995     DALI_TEST_EQUALS(newObserver2Loaded, true, TEST_LOCATION);
1996     DALI_TEST_EQUALS(newObserver2Called, true, TEST_LOCATION);
1997     // We don't check observer3 not loaded case because SendNotification can process AsyncTask.
1998     //DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
1999     //DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
2000
2001     tet_printf("Complete async load 3.\n");
2002     pixelBuffers.clear();
2003     pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888));
2004     textureManager.AsyncLoadComplete(textureId3, pixelBuffers);
2005
2006     DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
2007     DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
2008     DALI_TEST_EQUALS(observer2Loaded, false, TEST_LOCATION);
2009     DALI_TEST_EQUALS(observer2Called, false, TEST_LOCATION);
2010     DALI_TEST_EQUALS(newObserver2Loaded, true, TEST_LOCATION);
2011     DALI_TEST_EQUALS(newObserver2Called, true, TEST_LOCATION);
2012     DALI_TEST_EQUALS(observer3.mLoaded, true, TEST_LOCATION);
2013     DALI_TEST_EQUALS(observer3.mObserverCalled, true, TEST_LOCATION);
2014   }
2015   catch(...)
2016   {
2017     DALI_TEST_CHECK(false);
2018   }
2019
2020   END_TEST;
2021 }