Remove cached texture at PostProcessor 56/290456/18
authorEunki Hong <eunkiki.hong@samsung.com>
Sat, 25 Mar 2023 15:02:44 +0000 (00:02 +0900)
committerEunki Hong <eunkiki.hong@samsung.com>
Fri, 28 Apr 2023 00:30:59 +0000 (09:30 +0900)
We don't need to Remove memory of texture immediately.
If we call Remove(image); Add(image); continously,
Then image will try to reload image one more time.

It might useless behaviour for real world app side.

So make we don't remove texture immediatly, and
Process remove queue at post process timing.

Change-Id: Ic0d1a1cd10c13fc8b742667a09b02552594aae70
Signed-off-by: Eunki Hong <eunkiki.hong@samsung.com>
17 files changed:
automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp
automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp
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/visuals/image-visual-properties.h

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 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 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.
  */