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