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