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