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