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