[dali_2.2.25] Merge branch 'devel/master' 02/292402/1
authorAdam Bialogonski <adam.b@samsung.com>
Fri, 5 May 2023 10:21:34 +0000 (11:21 +0100)
committerAdam Bialogonski <adam.b@samsung.com>
Fri, 5 May 2023 10:21:34 +0000 (11:21 +0100)
Change-Id: I340ef7b5d4a4bdabbc7a5f7e6824b85ba12e7c82

24 files changed:
automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp
automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp
dali-scene3d/internal/model-components/model-primitive-impl.cpp
dali-scene3d/public-api/loader/animation-definition.cpp
dali-scene3d/public-api/loader/animation-definition.h
dali-scene3d/public-api/loader/blend-shape-details.cpp
dali-scene3d/public-api/loader/blend-shape-details.h
dali-toolkit/internal/texture-manager/texture-manager-impl.cpp
dali-toolkit/internal/texture-manager/texture-manager-impl.h
dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp
dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp
dali-toolkit/internal/visuals/animated-image/fixed-image-cache.h
dali-toolkit/internal/visuals/animated-image/image-cache.cpp
dali-toolkit/internal/visuals/animated-image/image-cache.h
dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp
dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.h
dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp
dali-toolkit/internal/visuals/animated-image/rolling-image-cache.h
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/image/image-visual.h
dali-toolkit/internal/visuals/npatch/npatch-visual.cpp
dali-toolkit/public-api/dali-toolkit-version.cpp
dali-toolkit/public-api/visuals/image-visual-properties.h
packaging/dali-toolkit.spec

index f12b096..8c63d53 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -124,7 +124,7 @@ public:
     mTextureSet     = textureInformation.textureSet;
 
     // Remove during LoadComplete
-    mTextureManagerPtr->Remove(textureInformation.textureId, nullptr);
+    mTextureManagerPtr->RequestRemove(textureInformation.textureId, nullptr);
 
     // ...And generate string which using texture id.
     mGeneratedExternalUrl = mTextureManagerPtr->AddExternalTexture(mTextureSet);
@@ -794,7 +794,7 @@ int UtcTextureManagerUseInvalidMaskAndMaskLoadedLater(void)
   application.SendNotification();
   application.Render();
 
-  // CAPTION : HARD-CODING for coverage. If you are a good boy, Do not follow this code.
+  // CAPTION : HARD-CODING for coverage.
   {
     Dali::Devel::PixelBuffer pixelBuffer = textureManager.LoadPixelBuffer(
       filename,
@@ -811,8 +811,8 @@ int UtcTextureManagerUseInvalidMaskAndMaskLoadedLater(void)
     textureManager.AsyncLoadComplete(textureId, pixelBuffers);
     std::vector<Devel::PixelBuffer> maskBuffers;
     textureManager.AsyncLoadComplete(maskInfo->mAlphaMaskId, maskBuffers);
-    textureManager.Remove(maskInfo->mAlphaMaskId, nullptr);
-    textureManager.Remove(textureId, &observer);
+    textureManager.RequestRemove(maskInfo->mAlphaMaskId, nullptr);
+    textureManager.RequestRemove(textureId, &observer);
   }
 
   application.SendNotification();
@@ -1232,7 +1232,7 @@ int UtcTextureManagerRemoveDuringApplyMasking(void)
   DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
 
   // Remove current textureId1. and request new texture again.
-  textureManager.Remove(textureId1, &observer1);
+  textureManager.RequestRemove(textureId1, &observer1);
   auto textureId2 = textureManager.RequestLoad(
     filename,
     ImageDimensions(),
@@ -1259,7 +1259,7 @@ int UtcTextureManagerRemoveDuringApplyMasking(void)
   {
     std::vector<Devel::PixelBuffer> pixelBuffers;
     textureManager.AsyncLoadComplete(textureId2, pixelBuffers);
-    textureManager.Remove(textureId2, &observer2);
+    textureManager.RequestRemove(textureId2, &observer2);
   }
 
   DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION); ///< Note that we call AsyncLoadComplete hardly with empty pixelbuffer.
@@ -1372,8 +1372,15 @@ int UtcTextureManagerMaskCacheTest(void)
   try
   {
     // Remove textureId1 first, and then remove textureId2. Check whether segfault occured.
-    textureManager.Remove(textureId1, &observer1);
-    textureManager.Remove(textureId2, &observer2);
+    textureManager.RequestRemove(textureId1, &observer1);
+
+    application.SendNotification();
+    application.Render();
+
+    textureManager.RequestRemove(textureId2, &observer2);
+
+    application.SendNotification();
+    application.Render();
 
     TestObserver observer3;
     maskInfo.reset(new TextureManager::MaskingData());
@@ -1437,10 +1444,10 @@ int UtcTextureManagerRemoveDuringGPUMasking(void)
 
   TextureManager textureManager; // Create new texture manager
 
-  TestObserverWithCustomFunction observer1;
-  TestObserverWithCustomFunction observer2;
-  TestObserver                   observer3;
-  TestObserver                   observer4;
+  TestObserverWithCustomFunction  observer1;
+  TestObserverWithCustomFunction  observer2;
+  TestObserverWithCustomFunction* observer3 = new TestObserverWithCustomFunction(); // Deleted in observer1 loaded signal
+  TestObserver                    observer4;
 
   std::string filename1(TEST_IMAGE_FILE_NAME);
   std::string filename2(TEST_IMAGE_2_FILE_NAME);
@@ -1523,7 +1530,7 @@ int UtcTextureManagerRemoveDuringGPUMasking(void)
     atlasRectSize,
     atlasingStatus,
     loadingStatus,
-    &observer3,
+    observer3,
     atlasUploadObserver,
     atlasManager,
     true,
@@ -1534,8 +1541,8 @@ int UtcTextureManagerRemoveDuringGPUMasking(void)
   DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
   DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION);
   DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION);
-  DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
-  DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(observer3->mLoaded, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(observer3->mObserverCalled, false, TEST_LOCATION);
   DALI_TEST_EQUALS(observer4.mLoaded, false, TEST_LOCATION);
   DALI_TEST_EQUALS(observer4.mObserverCalled, false, TEST_LOCATION);
 
@@ -1554,7 +1561,7 @@ int UtcTextureManagerRemoveDuringGPUMasking(void)
   CustomData1 data1;
   data1.textureManagerPtr     = &textureManager;
   data1.removeTextureId       = textureId3;
-  data1.removeTextureObserver = &observer3;
+  data1.removeTextureObserver = observer3;
 
   observer1.mData = &data1;
   observer1.ConnectFunction(
@@ -1566,8 +1573,11 @@ int UtcTextureManagerRemoveDuringGPUMasking(void)
       DALI_TEST_CHECK(data1.removeTextureId != TextureManager::INVALID_TEXTURE_ID);
       DALI_TEST_CHECK(data1.removeTextureObserver);
 
-      // Remove textureId3
-      data1.textureManagerPtr->Remove(data1.removeTextureId, data1.removeTextureObserver);
+      // Remove textureId3.
+      data1.textureManagerPtr->RequestRemove(data1.removeTextureId, data1.removeTextureObserver);
+
+      // Destroy observer3
+      delete data1.removeTextureObserver;
     });
 
   // Connect observer2 custom function
@@ -1610,6 +1620,34 @@ int UtcTextureManagerRemoveDuringGPUMasking(void)
         preMultiply);
     });
 
+  // Connect observer3 custom function
+  struct CustomData3
+  {
+    TestObserver* self{nullptr};
+    bool*         observerLoadedPtr{nullptr};
+    bool*         observerCalleddPtr{nullptr};
+  };
+  CustomData3 data3;
+  bool        observer3Loaded = false;
+  bool        observer3Called = false;
+  data3.self                  = observer3;
+  data3.observerLoadedPtr     = &observer3Loaded;
+  data3.observerCalleddPtr    = &observer3Called;
+
+  observer3->mData = &data3;
+  observer3->ConnectFunction(
+    [](void* data) {
+      DALI_TEST_CHECK(data);
+      CustomData3 data3 = *(CustomData3*)data;
+
+      DALI_TEST_CHECK(data3.self);
+      DALI_TEST_CHECK(data3.observerLoadedPtr);
+      DALI_TEST_CHECK(data3.observerCalleddPtr);
+
+      *data3.observerLoadedPtr  = data3.self->mLoaded;
+      *data3.observerCalleddPtr = data3.self->mObserverCalled;
+    });
+
   application.SendNotification();
   application.Render();
 
@@ -1630,12 +1668,14 @@ int UtcTextureManagerRemoveDuringGPUMasking(void)
     pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888));
     textureManager.AsyncLoadComplete(textureId3, pixelBuffers);
 
+    // Ensure textureId3 remove request processed.
+
     DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
     DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
     DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION);
     DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION);
-    DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
-    DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer3Loaded, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer3Called, false, TEST_LOCATION);
     DALI_TEST_EQUALS(observer4.mLoaded, false, TEST_LOCATION);
     DALI_TEST_EQUALS(observer4.mObserverCalled, false, TEST_LOCATION);
 
@@ -1651,8 +1691,8 @@ int UtcTextureManagerRemoveDuringGPUMasking(void)
     DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
     DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION);
     DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION);
-    DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
-    DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer3Loaded, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer3Called, false, TEST_LOCATION);
     DALI_TEST_EQUALS(observer4.mLoaded, false, TEST_LOCATION);
     DALI_TEST_EQUALS(observer4.mObserverCalled, false, TEST_LOCATION);
 
@@ -1668,11 +1708,314 @@ int UtcTextureManagerRemoveDuringGPUMasking(void)
     DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
     DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION);
     DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION);
-    DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
-    DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer3Loaded, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer3Called, false, TEST_LOCATION);
     DALI_TEST_EQUALS(observer4.mLoaded, true, TEST_LOCATION);
     DALI_TEST_EQUALS(observer4.mObserverCalled, true, TEST_LOCATION);
   }
 
   END_TEST;
+}
+
+int UtcTextureManagerDestroyObserverDuringObserve(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcTextureManagerDestroyObserverDuringObserve");
+  tet_infoline("Request 3 different image.");
+  tet_infoline("Complete textureId1. After observer1 loaded done,");
+  tet_infoline(" - Remove and destroy observer2");
+  tet_infoline(" - Re-generate observer2 which has same address pointer with before.");
+  tet_infoline(" - Remove and Reqeust third file by observer3");
+  tet_infoline("Complete textureId2. and check old observer2 not emmited, and newly observer2 works.");
+  tet_infoline("Complete textureId3. and check observer3 comes");
+
+  TextureManager textureManager; // Create new texture manager
+
+  TestObserverWithCustomFunction  observer1;
+  TestObserverWithCustomFunction* observer2 = new TestObserverWithCustomFunction(); // Deleted in observer1 loaded signal.
+  TestObserver                    observer3;
+
+  std::string filename1(TEST_IMAGE_FILE_NAME);
+  std::string filename2(TEST_IMAGE_2_FILE_NAME);
+  std::string filename3(TEST_IMAGE_3_FILE_NAME);
+  std::string filename4(TEST_IMAGE_4_FILE_NAME);
+
+  auto textureId1(TextureManager::INVALID_TEXTURE_ID);
+  auto textureId2(TextureManager::INVALID_TEXTURE_ID);
+  auto textureId3(TextureManager::INVALID_TEXTURE_ID);
+  auto textureId4(TextureManager::INVALID_TEXTURE_ID);
+
+  // Dummy reference value
+  auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+
+  // Request image 1, 2, 3.
+  textureId1 = textureManager.RequestLoad(
+    filename1,
+    ImageDimensions(),
+    FittingMode::SCALE_TO_FILL,
+    SamplingMode::BOX_THEN_LINEAR,
+    TextureManager::UseAtlas::NO_ATLAS,
+    &observer1,
+    true,
+    TextureManager::ReloadPolicy::CACHED,
+    preMultiply);
+
+  textureId2 = textureManager.RequestLoad(
+    filename2,
+    ImageDimensions(),
+    FittingMode::SCALE_TO_FILL,
+    SamplingMode::BOX_THEN_LINEAR,
+    TextureManager::UseAtlas::NO_ATLAS,
+    observer2,
+    true,
+    TextureManager::ReloadPolicy::CACHED,
+    preMultiply);
+
+  textureId3 = textureManager.RequestLoad(
+    filename3,
+    ImageDimensions(),
+    FittingMode::SCALE_TO_FILL,
+    SamplingMode::BOX_THEN_LINEAR,
+    TextureManager::UseAtlas::NO_ATLAS,
+    &observer3,
+    true,
+    TextureManager::ReloadPolicy::CACHED,
+    preMultiply);
+
+  struct CustomData1
+  {
+    TextureManager*                  textureManagerPtr{nullptr};
+    TextureManager::TextureId        removeTextureId{TextureManager::INVALID_TEXTURE_ID};
+    TestObserverWithCustomFunction** removeTextureObserver{nullptr};
+    std::string                      resendFilename{};
+    TextureManager::TextureId        resendTextureId{TextureManager::INVALID_TEXTURE_ID};
+    TestObserver*                    resendTextureObserver{nullptr};
+    std::string                      newlyFilename{};
+    TextureManager::TextureId*       newlyTextureIdPtr{nullptr};
+  };
+  struct CustomData2
+  {
+    TextureManager* textureManagerPtr{nullptr};
+    TestObserver*   self{nullptr};
+    bool*           observerLoadedPtr{nullptr};
+    bool*           observerCalledPtr{nullptr};
+  };
+
+  bool        observer2Loaded    = false;
+  bool        observer2Called    = false;
+  bool        newObserver2Loaded = false;
+  bool        newObserver2Called = false;
+  CustomData2 newData2; // Used on observer1 function
+
+  // Connect observer1 custom function
+  CustomData1 data1;
+  data1.textureManagerPtr     = &textureManager;
+  data1.removeTextureId       = textureId2;
+  data1.removeTextureObserver = &observer2;
+  data1.resendFilename        = filename3;
+  data1.resendTextureId       = textureId3;
+  data1.resendTextureObserver = &observer3;
+  data1.newlyFilename         = filename2; // Same as observer2 filename
+  data1.newlyTextureIdPtr     = &textureId4;
+
+  observer1.mData = &data1;
+  observer1.ConnectFunction(
+    [&](void* data) {
+      DALI_TEST_CHECK(data);
+      CustomData1 data1 = *(CustomData1*)data;
+
+      DALI_TEST_CHECK(data1.textureManagerPtr);
+      DALI_TEST_CHECK(data1.removeTextureId != TextureManager::INVALID_TEXTURE_ID);
+      DALI_TEST_CHECK(data1.removeTextureObserver);
+      DALI_TEST_CHECK(*data1.removeTextureObserver);
+      DALI_TEST_CHECK(!data1.resendFilename.empty());
+      DALI_TEST_CHECK(data1.resendTextureId != TextureManager::INVALID_TEXTURE_ID);
+      DALI_TEST_CHECK(data1.resendTextureObserver);
+      DALI_TEST_CHECK(!data1.newlyFilename.empty());
+      DALI_TEST_CHECK(data1.newlyTextureIdPtr);
+      DALI_TEST_CHECK(*data1.newlyTextureIdPtr == TextureManager::INVALID_TEXTURE_ID);
+
+      // Remove textureId2.
+      data1.textureManagerPtr->RequestRemove(data1.removeTextureId, *data1.removeTextureObserver);
+
+      auto removedObserver = *data1.removeTextureObserver;
+
+      // Destroy observer2.
+      delete removedObserver;
+
+      // Create new observer. Make we use same pointer if we can.
+      uint32_t maxTryCount = 100u;
+      uint32_t tryCount    = 0u;
+
+      while(tryCount < maxTryCount)
+      {
+        *data1.removeTextureObserver = new TestObserverWithCustomFunction();
+        if(removedObserver == *data1.removeTextureObserver) break;
+        ++tryCount;
+        delete *data1.removeTextureObserver;
+      }
+
+      tet_printf("TryCount[%u] / Old observer2 : %p, newly observer2 : %p\n", tryCount, removedObserver, *data1.removeTextureObserver);
+
+      // Connect new observer2 custom function
+      newData2.textureManagerPtr = &textureManager;
+      newData2.self              = (*data1.removeTextureObserver);
+      newData2.observerLoadedPtr = &newObserver2Loaded;
+      newData2.observerCalledPtr = &newObserver2Called;
+
+      (*data1.removeTextureObserver)->mData = &newData2;
+      (*data1.removeTextureObserver)->ConnectFunction([](void* data) {
+        DALI_TEST_CHECK(data);
+        CustomData2 data2 = *(CustomData2*)data;
+
+        tet_printf("New created observer running\n");
+
+        DALI_TEST_CHECK(data2.self);
+        DALI_TEST_CHECK(data2.observerLoadedPtr);
+        DALI_TEST_CHECK(data2.observerCalledPtr);
+
+        *data2.observerLoadedPtr = data2.self->mLoaded;
+        *data2.observerCalledPtr = data2.self->mObserverCalled;
+      });
+
+      // Dummy reference value
+      auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+
+      // Resend textureId3
+      data1.textureManagerPtr->RequestRemove(data1.resendTextureId, data1.resendTextureObserver);
+
+      TextureManager::TextureId tempId;
+      tempId = data1.textureManagerPtr->RequestLoad(
+        data1.resendFilename,
+        ImageDimensions(),
+        FittingMode::SCALE_TO_FILL,
+        SamplingMode::BOX_THEN_LINEAR,
+        TextureManager::UseAtlas::NO_ATLAS,
+        data1.resendTextureObserver,
+        true,
+        TextureManager::ReloadPolicy::CACHED,
+        preMultiply);
+
+      DALI_TEST_CHECK(tempId == data1.resendTextureId);
+
+      // Request new task
+
+      tempId = data1.textureManagerPtr->RequestLoad(
+        data1.newlyFilename,
+        ImageDimensions(),
+        FittingMode::SCALE_TO_FILL,
+        SamplingMode::BOX_THEN_LINEAR,
+        TextureManager::UseAtlas::NO_ATLAS,
+        *data1.removeTextureObserver,
+        true,
+        TextureManager::ReloadPolicy::CACHED,
+        preMultiply);
+
+      DALI_TEST_CHECK(tempId != TextureManager::INVALID_TEXTURE_ID);
+      *data1.newlyTextureIdPtr = tempId;
+    });
+
+  // Connect observer2 custom function
+  CustomData2 data2;
+  data2.textureManagerPtr = &textureManager;
+  data2.self              = observer2;
+  data2.observerLoadedPtr = &observer2Loaded;
+  data2.observerCalledPtr = &observer2Called;
+
+  observer2->mData = &data2;
+  observer2->ConnectFunction(
+    [](void* data) {
+      DALI_TEST_CHECK(data);
+      CustomData2 data2 = *(CustomData2*)data;
+
+      tet_printf("Old created observer running. Something error occured!\n");
+
+      DALI_TEST_CHECK(data2.self);
+      DALI_TEST_CHECK(data2.observerLoadedPtr);
+      DALI_TEST_CHECK(data2.observerCalledPtr);
+
+      *data2.observerLoadedPtr = data2.self->mLoaded;
+      *data2.observerCalledPtr = data2.self->mObserverCalled;
+    });
+
+  application.SendNotification();
+  application.Render();
+
+  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));
+
+  DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(observer2Loaded, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(observer2Called, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(newObserver2Loaded, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(newObserver2Called, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
+
+  DALI_TEST_CHECK(textureId4 == TextureManager::INVALID_TEXTURE_ID);
+
+  // CAPTION : HARD-CODING.
+  // Run codes without exception.
+  try
+  {
+    tet_printf("Complete async load 1 first.\n");
+    std::vector<Devel::PixelBuffer> pixelBuffers;
+
+    pixelBuffers.clear();
+    pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888));
+    textureManager.AsyncLoadComplete(textureId1, pixelBuffers);
+
+    tet_printf("Now observer2 deleted, observer3 resended, observer2 re-created.\n");
+    DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer2Loaded, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer2Called, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(newObserver2Loaded, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(newObserver2Called, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
+
+    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));
+
+    DALI_TEST_CHECK(textureId4 == textureId2);
+
+    // Remove processor excute.
+    application.SendNotification();
+    application.Render();
+
+    tet_printf("Complete async load 2. Let we check old version observer2 ignored and newly observer2 loaded.\n");
+    pixelBuffers.clear();
+    pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888));
+    textureManager.AsyncLoadComplete(textureId2, pixelBuffers);
+
+    DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer2Loaded, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer2Called, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(newObserver2Loaded, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(newObserver2Called, true, TEST_LOCATION);
+    // We don't check observer3 not loaded case because SendNotification can process AsyncTask.
+    //DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
+    //DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
+
+    tet_printf("Complete async load 3.\n");
+    pixelBuffers.clear();
+    pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888));
+    textureManager.AsyncLoadComplete(textureId3, pixelBuffers);
+
+    DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer2Loaded, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer2Called, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(newObserver2Loaded, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(newObserver2Called, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer3.mLoaded, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer3.mObserverCalled, true, TEST_LOCATION);
+  }
+  catch(...)
+  {
+    DALI_TEST_CHECK(false);
+  }
+
+  END_TEST;
 }
\ No newline at end of file
index 7edefb1..73f4cf7 100644 (file)
@@ -1344,6 +1344,12 @@ int UtcDaliAnimatedImageVisualMultiImage02(void)
     dummyImpl1.UnregisterVisual(DummyControl::Property::TEST_VISUAL);
     dummyControl.Unparent();
 
+    // Ensure to remove cached texture. (Since we support lazy cache removal)
+    application.SendNotification();
+    application.Render(16);
+    application.SendNotification();
+    application.Render(16);
+
     // Batch size is 9 and cache size is 4
     propertyMap.Clear();
     propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE);
index 4dbb047..adb78aa 100644 (file)
@@ -19,9 +19,9 @@
 #include <dali-scene3d/internal/model-components/model-primitive-impl.h>
 
 // EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/image-loading.h>
 #include <dali/public-api/object/type-registry-helper.h>
 #include <dali/public-api/object/type-registry.h>
-#include <dali/devel-api/adaptor-framework/image-loading.h>
 
 // INTERNAL INCLUDES
 #include <dali-scene3d/internal/model-components/material-impl.h>
@@ -178,7 +178,7 @@ void ModelPrimitive::SetImageBasedLightScaleFactor(float iblScaleFactor)
 void ModelPrimitive::SetBlendShapeData(Scene3D::Loader::BlendShapes::BlendShapeData& data)
 {
   mBlendShapeData = std::move(data);
-  Scene3D::Loader::BlendShapes::ConfigureProperties(mBlendShapeData, mShader);
+  Scene3D::Loader::BlendShapes::ConfigureProperties(mBlendShapeData, mRenderer);
 }
 
 void ModelPrimitive::SetBlendShapeGeometry(Dali::Texture blendShapeGeometry)
@@ -246,10 +246,6 @@ void ModelPrimitive::ApplyMaterialToRenderer(MaterialModifyObserver::ModifyFlag
 
     mShader.Reset();
     mShader = Shader::New(vertexShader, fragmentShader);
-    if(mBlendShapeData.version != Scene3D::Loader::BlendShapes::Version::INVALID && mBlendShapeData.mActor.GetHandle())
-    {
-      Scene3D::Loader::BlendShapes::ConfigureProperties(mBlendShapeData, mShader);
-    }
 
     if(!mRenderer)
     {
@@ -383,7 +379,7 @@ void ModelPrimitive::UpdateImageBasedLightTexture()
 
       mRenderer.SetTextures(newTextures);
     }
-    mRenderer.RegisterProperty(GetImplementation(mMaterial).GetImageBasedLightScaleFactorName() .data(), mIblScaleFactor);
+    mRenderer.RegisterProperty(GetImplementation(mMaterial).GetImageBasedLightScaleFactorName().data(), mIblScaleFactor);
     mRenderer.RegisterProperty(GetImplementation(mMaterial).GetImageBasedLightMaxLodUniformName().data(), static_cast<float>(mSpecularMipmapLevels));
   }
 }
index 5d8d304..d35631d 100644 (file)
@@ -172,7 +172,7 @@ void AnimationDefinition::SetProperty(uint32_t index, AnimatedProperty&& propert
   mProperties[index] = std::move(property);
 }
 
-const AnimatedProperty& AnimationDefinition::GetPropertyAt(uint32_t index)
+AnimatedProperty& AnimationDefinition::GetPropertyAt(uint32_t index)
 {
   return mProperties[index];
 }
index ff72e3f..9b8393c 100644 (file)
@@ -188,7 +188,7 @@ public: // METHODS
    *
    * @param[in] index The index of property to be retrieved.
    */
-  const AnimatedProperty& GetPropertyAt(uint32_t index);
+  AnimatedProperty& GetPropertyAt(uint32_t index);
 
 private: // DATA
   std::string mName;
index 4cf288c..f854fa7 100644 (file)
@@ -36,7 +36,7 @@ const char* BlendShapes::COMPONENTS("blendShapeComponents");
 
 const char* BlendShapes::WEIGHTS_UNIFORM("uBlendShapeWeight");
 
-void BlendShapes::ConfigureProperties(const BlendShapeData& data, Shader shader)
+void BlendShapes::ConfigureProperties(const BlendShapeData& data, Renderer renderer)
 {
   unsigned int index = 0u;
 
@@ -54,28 +54,28 @@ void BlendShapes::ConfigureProperties(const BlendShapeData& data, Shader shader)
       actor.RegisterProperty(weightName, weight);
     }
 
-    if(shader && data.version == Version::VERSION_1_0)
+    if(renderer && data.version == Version::VERSION_1_0)
     {
       snprintf(pFactorName, sizeof(unnormalizeFactorNameBuffer) - (pFactorName - unnormalizeFactorNameBuffer), "[%d]", index);
       std::string factorName{unnormalizeFactorNameBuffer};
-      shader.RegisterProperty(factorName, data.unnormalizeFactors[index]);
+      renderer.RegisterProperty(factorName, data.unnormalizeFactors[index]);
     }
 
     ++index;
   }
 
-  if(shader)
+  if(renderer)
   {
     if(Version::VERSION_2_0 == data.version)
     {
-      shader.RegisterProperty(UNNORMALIZE_FACTOR, data.unnormalizeFactors[0u]);
+      renderer.RegisterProperty(UNNORMALIZE_FACTOR, data.unnormalizeFactors[0u]);
     }
 
-    shader.RegisterProperty(NUMBER_OF_BLEND_SHAPES, Property::Value(static_cast<float>(index)));
-    shader.RegisterProperty(COMPONENT_SIZE, Property::Value(static_cast<float>(data.bufferOffset)));
+    renderer.RegisterProperty(NUMBER_OF_BLEND_SHAPES, Property::Value(static_cast<float>(index)));
+    renderer.RegisterProperty(COMPONENT_SIZE, Property::Value(static_cast<float>(data.bufferOffset)));
 
     // Create a read only property to preserve the components of the blend shape.
-    shader.RegisterProperty(COMPONENTS, data.components, Property::AccessMode::READ_ONLY);
+    renderer.RegisterProperty(COMPONENTS, data.components, Property::AccessMode::READ_ONLY);
   }
 }
 
index 2b304d6..e7d2eb4 100644 (file)
@@ -74,9 +74,9 @@ struct DALI_SCENE3D_API BlendShapes
 
   /**
    * @brief Registers properties based on the mesh definition (and geometry) and identified by the above string constants,
-   *  on the given @a shader and @a actor.
+   *  on the given @a renderer and @a actor.
    */
-  static void ConfigureProperties(const BlendShapeData& data, Shader shader);
+  static void ConfigureProperties(const BlendShapeData& data, Renderer renderer);
 
   BlendShapes() = delete;
 };
index 9e8cec5..4666cc5 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali/devel-api/adaptor-framework/environment-variable.h>
 #include <dali/devel-api/adaptor-framework/image-loading.h>
 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
 #include <dali/integration-api/debug.h>
 #include <dali/public-api/rendering/geometry.h>
 
@@ -113,9 +114,10 @@ TextureManager::TextureManager()
   mAsyncLoader(std::unique_ptr<TextureAsyncLoadingHelper>(new TextureAsyncLoadingHelper(*this))),
   mLifecycleObservers(),
   mLoadQueue(),
-  mRemoveQueue(),
   mLoadingQueueTextureId(INVALID_TEXTURE_ID),
-  mLoadYuvPlanes(NeedToLoadYuvPlanes())
+  mRemoveQueue(),
+  mLoadYuvPlanes(NeedToLoadYuvPlanes()),
+  mRemoveProcessorRegistered(false)
 {
   // Initialize the AddOn
   RenderingAddOn::Get();
@@ -123,6 +125,12 @@ TextureManager::TextureManager()
 
 TextureManager::~TextureManager()
 {
+  if(mRemoveProcessorRegistered && Adaptor::IsAvailable())
+  {
+    Adaptor::Get().UnregisterProcessor(*this, true);
+    mRemoveProcessorRegistered = false;
+  }
+
   for(auto iter = mLifecycleObservers.Begin(), endIter = mLifecycleObservers.End(); iter != endIter; ++iter)
   {
     (*iter)->TextureManagerDestroyed();
@@ -298,8 +306,8 @@ TextureSet TextureManager::LoadTexture(
     std::string location = url.GetLocation();
     if(location.size() > 0u)
     {
-      TextureId id = std::stoi(location);
-      auto externalTextureInfo   = mTextureCacheManager.GetExternalTextureInfo(id);
+      TextureId id                  = std::stoi(location);
+      auto      externalTextureInfo = mTextureCacheManager.GetExternalTextureInfo(id);
       if(externalTextureInfo.textureSet)
       {
         textureId = id;
@@ -640,8 +648,8 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
 
       if(pixelBuffers.empty())
       {
-        // If pixelBuffer loading is failed in synchronously, call Remove() method.
-        Remove(textureId, nullptr);
+        // If pixelBuffer loading is failed in synchronously, call RequestRemove() method.
+        RequestRemove(textureId, nullptr);
         return INVALID_TEXTURE_ID;
       }
 
@@ -694,7 +702,34 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
   return textureId;
 }
 
-void TextureManager::Remove(const TextureManager::TextureId& textureId, TextureUploadObserver* observer)
+void TextureManager::RequestRemove(const TextureManager::TextureId& textureId, TextureUploadObserver* observer)
+{
+  DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestRemove( textureId=%d observer=%p )\n", textureId, observer);
+
+  // Queue to remove.
+  if(textureId != INVALID_TEXTURE_ID)
+  {
+    if(observer)
+    {
+      // Remove observer from cached texture info
+      TextureCacheIndex textureCacheIndex = mTextureCacheManager.GetCacheIndexFromId(textureId);
+      if(textureCacheIndex != INVALID_CACHE_INDEX)
+      {
+        TextureInfo& textureInfo(mTextureCacheManager[textureCacheIndex]);
+        RemoveTextureObserver(textureInfo, observer);
+      }
+    }
+    mRemoveQueue.PushBack(textureId);
+
+    if(!mRemoveProcessorRegistered && Adaptor::IsAvailable())
+    {
+      mRemoveProcessorRegistered = true;
+      Adaptor::Get().RegisterProcessor(*this, true);
+    }
+  }
+}
+
+void TextureManager::Remove(const TextureManager::TextureId& textureId)
 {
   if(textureId != INVALID_TEXTURE_ID)
   {
@@ -712,54 +747,48 @@ void TextureManager::Remove(const TextureManager::TextureId& textureId, TextureU
         }
       }
 
-      DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::Remove( textureId=%d observer=%p ) cacheIndex:%d removal maskTextureId=%d, loadingQueueTextureId=%d, loadState=%s\n", textureId, observer, textureCacheIndex.GetIndex(), maskTextureId, mLoadingQueueTextureId, GET_LOAD_STATE_STRING(textureInfo.loadState));
+      DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::Remove( textureId=%d ) cacheIndex:%d removal maskTextureId=%d, loadingQueueTextureId=%d, loadState=%s\n", textureId, textureCacheIndex.GetIndex(), maskTextureId, mLoadingQueueTextureId, GET_LOAD_STATE_STRING(textureInfo.loadState));
 
-      // the case that LoadingQueue is working.
-      if(mLoadingQueueTextureId != INVALID_TEXTURE_ID)
+      // Remove textureId in CacheManager. Now, textureInfo is invalidate.
+      mTextureCacheManager.RemoveCache(textureInfo);
+
+      // Remove maskTextureId in CacheManager
+      if(maskTextureId != INVALID_TEXTURE_ID)
       {
-        // If textureId is not same, this observer need to delete when ProcessRemoveQueue() is called.
-        // If textureId is same, we should not call RemoveTextureObserver.
-        // Because ObserverDestroyed signal already disconnected in NotifyObservers
-        TextureUploadObserver* queueObserver = observer;
-        if(mLoadingQueueTextureId == textureId)
+        TextureCacheIndex maskCacheIndex = mTextureCacheManager.GetCacheIndexFromId(maskTextureId);
+        if(maskCacheIndex != INVALID_CACHE_INDEX)
         {
-          queueObserver = nullptr;
+          TextureInfo& maskTextureInfo(mTextureCacheManager[maskCacheIndex]);
+          mTextureCacheManager.RemoveCache(maskTextureInfo);
         }
+      }
+    }
+  }
+}
 
-        // Remove element from the mLoadQueue
-        for(auto&& element : mLoadQueue)
-        {
-          if(element.mTextureId == textureId && element.mObserver == observer)
-          {
-            // Do not erase the item. We will clear it later in ProcessLoadQueue().
-            element.mTextureId = INVALID_TEXTURE_ID;
-            element.mObserver  = nullptr;
-            break;
-          }
-        }
+void TextureManager::ProcessRemoveQueue()
+{
+  // Note that RemoveQueue is not be changed during Remove().
+  for(auto&& textureId : mRemoveQueue)
+  {
+    if(textureId != INVALID_TEXTURE_ID)
+    {
+      Remove(textureId);
+    }
+  }
+  mRemoveQueue.Clear();
+}
 
-        mRemoveQueue.PushBack(QueueElement(textureId, queueObserver));
-      }
-      else
-      {
-        // Remove its observer
-        RemoveTextureObserver(textureInfo, observer);
+void TextureManager::Process(bool postProcessor)
+{
+  DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::Process()\n");
 
-        // Remove textureId in CacheManager. Now, textureInfo is invalidate.
-        mTextureCacheManager.RemoveCache(textureInfo);
+  ProcessRemoveQueue();
 
-        // Remove maskTextureId in CacheManager
-        if(maskTextureId != INVALID_TEXTURE_ID)
-        {
-          TextureCacheIndex maskCacheIndex = mTextureCacheManager.GetCacheIndexFromId(maskTextureId);
-          if(maskCacheIndex != INVALID_CACHE_INDEX)
-          {
-            TextureInfo& maskTextureInfo(mTextureCacheManager[maskCacheIndex]);
-            mTextureCacheManager.RemoveCache(maskTextureInfo);
-          }
-        }
-      }
-    }
+  if(Adaptor::IsAvailable())
+  {
+    Adaptor::Get().UnregisterProcessor(*this, true);
+    mRemoveProcessorRegistered = false;
   }
 }
 
@@ -931,18 +960,6 @@ void TextureManager::ProcessLoadQueue()
   mLoadQueue.Clear();
 }
 
-void TextureManager::ProcessRemoveQueue()
-{
-  for(auto&& element : mRemoveQueue)
-  {
-    if(element.mTextureId != INVALID_TEXTURE_ID)
-    {
-      Remove(element.mTextureId, element.mObserver);
-    }
-  }
-  mRemoveQueue.Clear();
-}
-
 void TextureManager::ObserveTexture(TextureManager::TextureInfo& textureInfo,
                                     TextureUploadObserver*       observer)
 {
@@ -971,7 +988,7 @@ void TextureManager::AsyncLoadComplete(const TextureManager::TextureId& textureI
     }
     else
     {
-      Remove(textureInfo.textureId, nullptr);
+      RequestRemove(textureInfo.textureId, nullptr);
     }
   }
 }
@@ -1187,7 +1204,7 @@ void TextureManager::CheckForWaitingTexture(TextureManager::TextureInfo& maskTex
   // Decrease reference count
   for(const auto textureId : notifyRequiredTextureIds)
   {
-    Remove(textureId, nullptr);
+    RequestRemove(textureId, nullptr);
   }
 }
 
@@ -1298,11 +1315,10 @@ void TextureManager::NotifyObservers(TextureManager::TextureInfo& textureInfo, c
 
   mLoadingQueueTextureId = INVALID_TEXTURE_ID;
   ProcessLoadQueue();
-  ProcessRemoveQueue();
 
   if(info->storageType == StorageType::RETURN_PIXEL_BUFFER && info->observerList.Count() == 0)
   {
-    Remove(info->textureId, nullptr);
+    RequestRemove(info->textureId, nullptr);
   }
 }
 
index d3aabb5..68bf165 100644 (file)
@@ -20,6 +20,7 @@
 // EXTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/animated-image-loading.h>
 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
+#include <dali/integration-api/processor-interface.h>
 #include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
 #include <dali/public-api/adaptor-framework/round-robin-container-view.h>
 #include <dali/public-api/common/dali-vector.h>
@@ -51,7 +52,7 @@ class TextureAsyncLoadingHelper;
  * Texture caching is provided and performed by TextureCacheManager.
  * TextureUploadObserver.LoadComplete called when async load completed.
  */
-class TextureManager : public ConnectionTracker
+class TextureManager : public ConnectionTracker, public Integration::Processor
 {
 public:
   // Copy enum and types and const values that TextureManager will use.
@@ -226,17 +227,6 @@ public:
     TextureManager::MultiplyOnLoad&     preMultiplyOnLoad);
 
   /**
-   * @brief Remove a Texture from the TextureManager.
-   *
-   * Textures are cached and therefore only the removal of the last
-   * occurrence of a Texture will cause its removal internally.
-   *
-   * @param[in] textureId The ID of the Texture to remove.
-   * @param[in] textureObserver The texture observer.
-   */
-  void Remove(const TextureManager::TextureId& textureId, TextureUploadObserver* textureObserver);
-
-  /**
    * Add an observer to the object.
    * @param[in] observer The observer to add.
    */
@@ -515,6 +505,34 @@ private:
     const bool&                      loadYuvPlanes,
     std::vector<Devel::PixelBuffer>& pixelBuffers);
 
+public: // Remove Request API
+  /**
+   * @brief Request Remove a Texture from the TextureManager.
+   *
+   * Textures are cached and therefore only the removal of the last
+   * occurrence of a Texture will cause its removal internally.
+   *
+   * @param[in] textureId The ID of the Texture to remove.
+   * @param[in] textureObserver The texture observer.
+   */
+  void RequestRemove(const TextureManager::TextureId& textureId, TextureUploadObserver* textureObserver);
+
+private:
+  /**
+   * @brief Remove a Texture from the TextureManager.
+   *
+   * Textures are cached and therefore only the removal of the last
+   * occurrence of a Texture will cause its removal internally.
+   *
+   * @param[in] textureId The ID of the Texture to remove.
+   */
+  void Remove(const TextureManager::TextureId& textureId);
+
+  /**
+   * @brief Initiate remove of texture queued.
+   */
+  void ProcessRemoveQueue();
+
 private:
   // Load and queue
 
@@ -541,7 +559,7 @@ private:
   void LoadOrQueueTexture(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer);
 
   /**
-   * @brief Queue a texture load to be subsequently handled by ProcessQueuedTextures.
+   * @brief Queue a texture load to be subsequently handled by ProcessLoadQueue.
    * @param[in] textureInfo The TextureInfo struct associated with the Texture
    * @param[in] observer The observer wishing to observe the texture upload
    */
@@ -560,11 +578,6 @@ private:
   void ProcessLoadQueue();
 
   /**
-   * @brief Initiate remove of texture queued whilst NotifyObservers invoking callbacks.
-   */
-  void ProcessRemoveQueue();
-
-  /**
    * Add the observer to the observer list
    * @param[in] textureInfo The TextureInfo struct associated with the texture
    * @param[in] observer The observer wishing to observe the texture upload
@@ -633,6 +646,12 @@ public:
    */
   void AsyncLoadComplete(const TextureManager::TextureId& textureId, std::vector<Devel::PixelBuffer>& pixelBuffers);
 
+protected: // Implementation of Processor
+  /**
+   * @copydoc Dali::Integration::Processor::Process()
+   */
+  void Process(bool postProcessor) override;
+
 private:
   /**
    * Deleted copy constructor.
@@ -651,14 +670,19 @@ private:
    */
   void ObserverDestroyed(TextureUploadObserver* observer);
 
-private:                                                             // Member Variables:
-  TextureCacheManager                        mTextureCacheManager;   ///< Manager the life-cycle and caching of Textures
-  std::unique_ptr<TextureAsyncLoadingHelper> mAsyncLoader;           ///< The Asynchronous image loader used to provide all local async loads
-  Dali::Vector<LifecycleObserver*>           mLifecycleObservers;    ///< Lifecycle observers of texture manager
-  Dali::Vector<QueueElement>                 mLoadQueue;             ///< Queue of textures to load after NotifyObservers
-  Dali::Vector<QueueElement>                 mRemoveQueue;           ///< Queue of textures to remove after NotifyObservers
-  TextureManager::TextureId                  mLoadingQueueTextureId; ///< TextureId when it is loading. it causes Load Textures to be queued.
-  bool                                       mLoadYuvPlanes;         ///< A global flag to specify if the image should be loaded as yuv planes
+private:                                    // Member Variables:
+  TextureCacheManager mTextureCacheManager; ///< Manager the life-cycle and caching of Textures
+
+  std::unique_ptr<TextureAsyncLoadingHelper> mAsyncLoader;        ///< The Asynchronous image loader used to provide all local async loads
+  Dali::Vector<LifecycleObserver*>           mLifecycleObservers; ///< Lifecycle observers of texture manager
+
+  Dali::Vector<QueueElement> mLoadQueue;             ///< Queue of textures to load after NotifyObservers
+  TextureManager::TextureId  mLoadingQueueTextureId; ///< TextureId when it is loading. it causes Load Textures to be queued.
+
+  Dali::Vector<TextureManager::TextureId> mRemoveQueue; ///< Queue of textures to remove at PostProcess. It will be cleared after PostProcess.
+
+  bool mLoadYuvPlanes;             ///< A global flag to specify if the image should be loaded as yuv planes
+  bool mRemoveProcessorRegistered; ///< Flag if remove processor registered or not.
 };
 
 } // namespace Internal
index e1ec6cf..897accc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,7 +16,7 @@
  */
 
 // CLASS HEADER
-#include "animated-image-visual.h"
+#include <dali-toolkit/internal/visuals/animated-image/animated-image-visual.h>
 
 // EXTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/image-loading.h>
index 854a7a0..dfa9f2e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -169,7 +169,7 @@ void FixedImageCache::ClearCache()
   {
     for(std::size_t i = 0; i < mImageUrls.size(); ++i)
     {
-      mTextureManager.Remove(mImageUrls[i].mTextureId, this);
+      mTextureManager.RequestRemove(mImageUrls[i].mTextureId, this);
       mImageUrls[i].mTextureId = TextureManager::INVALID_TEXTURE_ID;
     }
   }
index 7cbfa63..62cd174 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_FIXED_IMAGE_CACHE_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
index 41879c7..2fda611 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-#include "image-cache.h"
+// CLASS HEADER
+#include <dali-toolkit/internal/visuals/animated-image/image-cache.h>
 
 namespace Dali
 {
index b15101e..c40a895 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_IMAGE_CACHE_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
index b6a9ae8..abe5581 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
  */
 
 // CLASS HEADER
-#include "rolling-animated-image-cache.h"
+#include <dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.h>
 
 // INTERNAL HEADERS
 #include <dali-toolkit/devel-api/image-loader/texture-manager.h>
@@ -291,7 +291,8 @@ TextureManager::TextureId RollingAnimatedImageCache::GetCachedTextureId(int inde
 void RollingAnimatedImageCache::PopFrontCache()
 {
   ImageFrame imageFrame = mQueue.PopFront();
-  mTextureManager.Remove(mTextureIds[imageFrame.mFrameNumber], this);
+
+  mTextureManager.RequestRemove(mTextureIds[imageFrame.mFrameNumber], this);
   mTextureIds[imageFrame.mFrameNumber] = TextureManager::INVALID_TEXTURE_ID;
 
   if(mMaskingData && mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID)
index a42854b..5c63db5 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_ROLLING_ANIMATED_IMAGE_CACHE_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
index 99e12e6..0bb1629 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -205,7 +205,8 @@ TextureManager::TextureId RollingImageCache::GetCachedTextureId(int index) const
 void RollingImageCache::PopFrontCache()
 {
   ImageFrame imageFrame = mQueue.PopFront();
-  mTextureManager.Remove(mImageUrls[imageFrame.mUrlIndex].mTextureId, this);
+
+  mTextureManager.RequestRemove(mImageUrls[imageFrame.mUrlIndex].mTextureId, this);
   mImageUrls[imageFrame.mUrlIndex].mTextureId = TextureManager::INVALID_TEXTURE_ID;
 
   if(mMaskingData && mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID)
index 59fa6a7..1654d27 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_ROLLING_IMAGE_CACHE_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
index d5bc010..2f51b7a 100644 (file)
@@ -1000,7 +1000,7 @@ void ImageVisual::RemoveTexture()
 {
   if(mTextureId != TextureManager::INVALID_TEXTURE_ID)
   {
-    mFactoryCache.GetTextureManager().Remove(mTextureId, this);
+    mFactoryCache.GetTextureManager().RequestRemove(mTextureId, this);
     mTextureId = TextureManager::INVALID_TEXTURE_ID;
   }
   else
index 4712f39..f5bf6fe 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_IMAGE_VISUAL_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
index 8b44d99..172eab6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,7 +16,7 @@
  */
 
 // CLASS HEADER
-#include "npatch-visual.h"
+#include <dali-toolkit/internal/visuals/npatch/npatch-visual.h>
 
 // EXTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/image-loading.h>
@@ -246,7 +246,7 @@ void NPatchVisual::DoSetOffScene(Actor& actor)
     if(mAuxiliaryTextureId != TextureManager::INVALID_TEXTURE_ID)
     {
       TextureManager& textureManager = mFactoryCache.GetTextureManager();
-      textureManager.Remove(mAuxiliaryTextureId, this);
+      textureManager.RequestRemove(mAuxiliaryTextureId, this);
       mAuxiliaryTextureId      = TextureManager::INVALID_TEXTURE_ID;
       mAuxiliaryResourceStatus = Toolkit::Visual::ResourceStatus::PREPARING;
       mAuxiliaryTextureSet.Reset();
@@ -325,7 +325,8 @@ NPatchVisual::~NPatchVisual()
       if(mAuxiliaryTextureId != TextureManager::INVALID_TEXTURE_ID)
       {
         TextureManager& textureManager = mFactoryCache.GetTextureManager();
-        textureManager.Remove(mAuxiliaryTextureId, this);
+
+        textureManager.RequestRemove(mAuxiliaryTextureId, this);
         mAuxiliaryTextureId = TextureManager::INVALID_TEXTURE_ID;
         mAuxiliaryTextureSet.Reset();
       }
@@ -414,8 +415,8 @@ Shader NPatchVisual::CreateShader()
 
   auto fragmentShader = mAuxiliaryResourceStatus == Toolkit::Visual::ResourceStatus::READY ? SHADER_NPATCH_VISUAL_MASK_SHADER_FRAG
                                                                                            : SHADER_NPATCH_VISUAL_SHADER_FRAG;
-  auto shaderType = mAuxiliaryResourceStatus == Toolkit::Visual::ResourceStatus::READY ? VisualFactoryCache::NINE_PATCH_MASK_SHADER
-                                                                                       : VisualFactoryCache::NINE_PATCH_SHADER;
+  auto shaderType     = mAuxiliaryResourceStatus == Toolkit::Visual::ResourceStatus::READY ? VisualFactoryCache::NINE_PATCH_MASK_SHADER
+                                                                                           : VisualFactoryCache::NINE_PATCH_SHADER;
 
   // ask loader for the regions
   if(mLoader.GetNPatchData(mId, data))
index a5144f6..174e4a5 100644 (file)
@@ -29,7 +29,7 @@ namespace Toolkit
 {
 const unsigned int TOOLKIT_MAJOR_VERSION = 2;
 const unsigned int TOOLKIT_MINOR_VERSION = 2;
-const unsigned int TOOLKIT_MICRO_VERSION = 24;
+const unsigned int TOOLKIT_MICRO_VERSION = 25;
 const char* const  TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 2586547..0ba2a56 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_IMAGE_VISUAL_PROPERTIES_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -242,7 +242,7 @@ enum
   LOAD_POLICY,
 
   /**
-   * @brief The policy to determine when an image should no longer be cached.
+   * @brief The policy to determine when an image request to be released so should no longer be cached.
    * @details Name "releasePolicy", Type ReleasePolicy::Type (Property::INTEGER) or Property::STRING
    * @SINCE_1_3_5
    * @note Default ReleasePolicy::DETACHED
@@ -281,7 +281,7 @@ enum Type
 } // namespace LoadPolicy
 
 /**
- * @brief The policy determining when a image is deleted from the cache in relation to the ImageVisual lifetime.
+ * @brief The policy determining when a image is requested to be deleted from the cache in relation to the ImageVisual lifetime.
  * @SINCE_1_3_5
  * @note If the texture is being shared by another visual it persist if still required.
  */
index c466716..d115944 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    2.2.24
+Version:    2.2.25
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT