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