Make MASK_CANCELLED loadstate + minor log info 45/282345/2
authorEunki, Hong <eunkiki.hong@samsung.com>
Fri, 30 Sep 2022 04:41:51 +0000 (13:41 +0900)
committerEunki Hong <eunkiki.hong@samsung.com>
Fri, 30 Sep 2022 13:22:55 +0000 (13:22 +0000)
When we remove the image during ApplyMask job,
the loadstate become "CANCELLED".
And, if we re-load the same image,
the loadstate revived as "LOADING".

Without MASK_CANCELLED state, that image will send
ApplyMask one more times.
That mean, alpha mask applied double times.

This patch seperate the cancelled situation
so we can revive the loadstate well.

+

Add some more informations for log

Change-Id: I055bb9807d2c1afe7192daa29aca08cd47910968
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
dali-toolkit/internal/texture-manager/texture-cache-manager.cpp
dali-toolkit/internal/texture-manager/texture-manager-impl.cpp
dali-toolkit/internal/texture-manager/texture-manager-type.h

index 34aa8a3..dbd84e6 100644 (file)
@@ -1274,6 +1274,74 @@ int UtcDaliImageViewReplaceImage(void)
   END_TEST;
 }
 
+int UtcDaliImageViewReloadAlphaMaskImage(void)
+{
+  ToolkitTestApplication application;
+
+  gResourceReadySignalFired = false;
+
+  ImageView     dummy     = ImageView::New();
+  ImageView     imageView = ImageView::New();
+  Property::Map propertyMap;
+
+  // To keep alpha mask cached, scene on some dummy image.
+  // Note : If we don't cache alpha mask image, the reference count of mask image become zero.
+  // In this case, we might need to wait mask image loading, which is not neccesary & can be changed behavior.
+  propertyMap[ImageVisual::Property::URL]            = gImage_600_RGB;
+  propertyMap[ImageVisual::Property::ALPHA_MASK_URL] = TEST_BROKEN_IMAGE_DEFAULT;
+  dummy.SetProperty(ImageView::Property::IMAGE, propertyMap);
+
+  application.GetScene().Add(dummy);
+
+  application.SendNotification();
+  application.Render(16);
+
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render(16);
+
+  propertyMap.Clear();
+  propertyMap[ImageVisual::Property::URL]            = gImage_34_RGBA;
+  propertyMap[ImageVisual::Property::ALPHA_MASK_URL] = TEST_BROKEN_IMAGE_DEFAULT;
+  imageView.SetProperty(ImageView::Property::IMAGE, propertyMap);
+
+  DALI_TEST_EQUALS(imageView.IsResourceReady(), false, TEST_LOCATION);
+
+  imageView.ResourceReadySignal().Connect(&ResourceReadySignal);
+
+  application.GetScene().Add(imageView);
+
+  application.SendNotification();
+  application.Render(16);
+
+  // Load image and use cached mask. Now we try to apply masking.
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  DALI_TEST_EQUALS(gResourceReadySignalFired, false, TEST_LOCATION);
+
+  // Cancel apply masking.
+  imageView.Unparent();
+
+  application.SendNotification();
+  application.Render(16);
+
+  // Reload same image again.
+  application.GetScene().Add(imageView);
+
+  application.SendNotification();
+  application.Render(16);
+
+  // Finish apply masking.
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  DALI_TEST_EQUALS(imageView.GetRendererCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(imageView.IsResourceReady(), true, TEST_LOCATION);
+  DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION);
+
+  END_TEST;
+}
+
 void OnRelayoutOverride(Size size)
 {
   gNaturalSize = size; // Size Relayout is using
index c0e7ac1..fc3ffde 100644 (file)
@@ -43,6 +43,7 @@ extern Debug::Filter* gTextureManagerLogFilter; ///< Define at texture-manager-i
   loadState == TextureManagerType::LoadState::MASK_APPLIED     ? "MASK_APPLIED"     : \
   loadState == TextureManagerType::LoadState::UPLOADED         ? "UPLOADED"         : \
   loadState == TextureManagerType::LoadState::CANCELLED        ? "CANCELLED"        : \
+  loadState == TextureManagerType::LoadState::MASK_CANCELLED   ? "MASK_CANCELLED"   : \
   loadState == TextureManagerType::LoadState::LOAD_FAILED      ? "LOAD_FAILED"      : \
                                                                  "Unknown"
 // clang-format on
@@ -169,7 +170,7 @@ TextureCacheManager::LoadState TextureCacheManager::GetTextureStateInternal(cons
 
 Texture TextureCacheManager::GetTexture(const TextureCacheManager::TextureId& textureId, uint32_t textureIndex)
 {
-  Texture        texture; // empty handle
+  Texture           texture; // empty handle
   TextureCacheIndex cacheIndex = GetCacheIndexFromId(textureId);
 
   switch(static_cast<TextureCacheIndexType>(cacheIndex.detailValue.type))
@@ -645,8 +646,8 @@ TextureCacheManager::TextureCacheIndex TextureCacheManager::AppendCache(const Te
 
 void TextureCacheManager::RemoveCache(TextureCacheManager::TextureInfo& textureInfo)
 {
-  TextureCacheIndex textureInfoIndex = GetCacheIndexFromId(textureInfo.textureId);
-  bool removeTextureInfo = false;
+  TextureCacheIndex textureInfoIndex  = GetCacheIndexFromId(textureInfo.textureId);
+  bool              removeTextureInfo = false;
 
   DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureCacheManager::Remove(textureId:%d) url:%s\n  cacheIdx:%d loadState:%s reference count = %d\n", textureInfo.textureId, textureInfo.url.GetUrl().c_str(), textureInfoIndex.GetIndex(), GET_LOAD_STATE_STRING(textureInfo.loadState), textureInfo.referenceCount);
 
@@ -665,12 +666,18 @@ void TextureCacheManager::RemoveCache(TextureCacheManager::TextureInfo& textureI
       }
       removeTextureInfo = true;
     }
-    else if(textureInfo.loadState == LoadState::LOADING || textureInfo.loadState == LoadState::MASK_APPLYING)
+    else if(textureInfo.loadState == LoadState::LOADING)
     {
       // We mark the textureInfo for removal.
       // Once the load has completed, this method will be called again.
       textureInfo.loadState = LoadState::CANCELLED;
     }
+    else if(textureInfo.loadState == LoadState::MASK_APPLYING)
+    {
+      // We mark the textureInfo for removal.
+      // Once the load has completed, this method will be called again.
+      textureInfo.loadState = LoadState::MASK_CANCELLED;
+    }
     else
     {
       // In other states, we are not waiting for a load so we are safe to remove the TextureInfo data.
index 33405be..643fced 100644 (file)
@@ -92,6 +92,7 @@ Debug::Filter* gTextureManagerLogFilter = Debug::Filter::New(Debug::NoLogging, f
   loadState == TextureManagerType::LoadState::MASK_APPLIED     ? "MASK_APPLIED"     : \
   loadState == TextureManagerType::LoadState::UPLOADED         ? "UPLOADED"         : \
   loadState == TextureManagerType::LoadState::CANCELLED        ? "CANCELLED"        : \
+  loadState == TextureManagerType::LoadState::MASK_CANCELLED   ? "MASK_CANCELLED"   : \
   loadState == TextureManagerType::LoadState::LOAD_FAILED      ? "LOAD_FAILED"      : \
                                                                  "Unknown"
 // clang-format on
@@ -551,7 +552,7 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
     // Update preMultiplyOnLoad value. It should be changed according to preMultiplied value of the cached info.
     preMultiplyOnLoad = mTextureCacheManager[cacheIndex].preMultiplied ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
 
-    DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) Using cached texture id@%d, textureId=%d, frameindex=%d, premultiplied=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, frameIndex, mTextureCacheManager[cacheIndex].preMultiplied ? 1 : 0);
+    DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) Using cached texture id@%d, textureId=%d, maskTextureId=%d, frameindex=%d, premultiplied=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, maskTextureId, frameIndex, mTextureCacheManager[cacheIndex].preMultiplied ? 1 : 0);
   }
 
   if(textureId == INVALID_TEXTURE_ID) // There was no caching, or caching not required
@@ -563,7 +564,7 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
     // Cache new texutre, and get cacheIndex.
     cacheIndex = mTextureCacheManager.AppendCache(TextureInfo(textureId, maskTextureId, url, desiredSize, contentScale, fittingMode, samplingMode, false, cropToMask, useAtlas, textureHash, orientationCorrection, preMultiply, animatedImageLoading, frameIndex, loadYuvPlanes));
 
-    DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d, frameindex=%d premultiply=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, frameIndex, preMultiply);
+    DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d, maskTextureId=%d, frameindex=%d premultiply=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, maskTextureId, frameIndex, preMultiply);
   }
 
   // The below code path is common whether we are using the cache or not.
@@ -582,9 +583,10 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
      TextureManager::LoadState::WAITING_FOR_MASK != textureInfo.loadState &&
      TextureManager::LoadState::MASK_APPLYING != textureInfo.loadState &&
      TextureManager::LoadState::MASK_APPLIED != textureInfo.loadState &&
-     TextureManager::LoadState::CANCELLED != textureInfo.loadState)
+     TextureManager::LoadState::CANCELLED != textureInfo.loadState &&
+     TextureManager::LoadState::MASK_CANCELLED != textureInfo.loadState)
   {
-    DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, "TextureManager::RequestLoad( url=%s observer=%p ) ForcedReload cacheIndex:%d, textureId=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId);
+    DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, "TextureManager::RequestLoad( url=%s observer=%p ) ForcedReload cacheIndex:%d, textureId=%d, maskTextureId=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, maskTextureId);
 
     textureInfo.loadState = TextureManager::LoadState::NOT_STARTED;
   }
@@ -625,6 +627,14 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
         ObserveTexture(textureInfo, observer);
         break;
       }
+      case TextureManager::LoadState::MASK_CANCELLED:
+      {
+        // A cancelled texture hasn't finished mask applying yet. Treat as a mask applying texture
+        // (it's ref count has already been incremented, above)
+        textureInfo.loadState = TextureManager::LoadState::MASK_APPLYING;
+        ObserveTexture(textureInfo, observer);
+        break;
+      }
       case TextureManager::LoadState::LOAD_FINISHED:
       {
         // Loading has already completed.
@@ -711,8 +721,8 @@ void TextureManager::Remove(const TextureManager::TextureId& textureId, TextureU
     {
       TextureManager::TextureId maskTextureId = INVALID_TEXTURE_ID;
       TextureInfo&              textureInfo(mTextureCacheManager[textureCacheIndex]);
-      // We only need to consider maskTextureId when texture's loadState is not CANCELLED. Because it is already deleted.
-      if(textureInfo.loadState != LoadState::CANCELLED)
+      // We only need to consider maskTextureId when texture's loadState is not cancelled. Because it is already deleted.
+      if(textureInfo.loadState != LoadState::CANCELLED && textureInfo.loadState != LoadState::MASK_CANCELLED)
       {
         if(textureInfo.maskTextureId != INVALID_TEXTURE_ID)
         {
@@ -720,6 +730,8 @@ 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));
+
       // the case that LoadingQueue is working.
       if(mLoadingQueueTextureId != INVALID_TEXTURE_ID)
       {
@@ -861,6 +873,7 @@ void TextureManager::LoadOrQueueTexture(TextureManager::TextureInfo& textureInfo
     }
     case LoadState::LOADING:
     case LoadState::CANCELLED:
+    case LoadState::MASK_CANCELLED:
     case LoadState::LOAD_FINISHED:
     case LoadState::WAITING_FOR_MASK:
     case LoadState::MASK_APPLYING:
@@ -974,7 +987,7 @@ void TextureManager::AsyncLoadComplete(const TextureManager::TextureId& textureI
 
     DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "  textureId:%d Url:%s CacheIndex:%d LoadState: %s\n", textureInfo.textureId, textureInfo.url.GetUrl().c_str(), cacheIndex.GetIndex(), GET_LOAD_STATE_STRING(textureInfo.loadState));
 
-    if(textureInfo.loadState != LoadState::CANCELLED)
+    if(textureInfo.loadState != LoadState::CANCELLED && textureInfo.loadState != LoadState::MASK_CANCELLED)
     {
       // textureInfo can be invalidated after this call (as the mTextureInfoContainer may be modified)
       PostLoad(textureInfo, pixelBuffers);
@@ -1117,6 +1130,8 @@ void TextureManager::CheckForWaitingTexture(TextureManager::TextureInfo& maskTex
     UploadTextures(pixelBuffers, maskTextureInfo);
   }
 
+  DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::CheckForWaitingTexture(): maskTextureId=%d, maskTextureUrl=%s\n", maskTextureInfo.textureId, maskTextureInfo.url.GetUrl().c_str());
+
   // Search the cache, checking if any texture has this texture id as a maskTextureId
   const std::size_t size = mTextureCacheManager.size();
 
@@ -1155,10 +1170,12 @@ void TextureManager::CheckForWaitingTexture(TextureManager::TextureInfo& maskTex
           maskTextureInfo.referenceCount++;
           textureInfo.referenceCount++;
 
+          DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::CheckForWaitingTexture(): Ready to notify textureId=%d\n", textureInfo.textureId);
+
           notifyRequiredTextureIds.push_back(textureInfo.textureId);
         }
       }
-      else
+      else // maskTextureInfo.loadState == LoadState::LOAD_FAILED
       {
         // Url texture load success, But alpha mask texture load failed. Run as normal image upload.
         DALI_LOG_ERROR("Alpha mask image loading failed! Image will not be masked\n");
@@ -1172,6 +1189,8 @@ void TextureManager::CheckForWaitingTexture(TextureManager::TextureInfo& maskTex
         maskTextureInfo.referenceCount++;
         textureInfo.referenceCount++;
 
+        DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::CheckForWaitingTexture(): Ready to notify textureId=%d\n", textureInfo.textureId);
+
         notifyRequiredTextureIds.push_back(textureInfo.textureId);
       }
     }
index adffcf9..74057fc 100644 (file)
@@ -201,6 +201,7 @@ enum class LoadState
   MASK_APPLIED,     ///< Loading has finished, Mask is applyied by GPU
   UPLOADED,         ///< Uploaded and ready. (For GPU upload only)
   CANCELLED,        ///< Removed before loading completed
+  MASK_CANCELLED,   ///< Removed before mask applying completed
   LOAD_FAILED       ///< Async loading failed, e.g. connection problem
 };