[dali_2.1.42] Merge branch 'devel/master' 86/282386/1
authorRichard Huang <r.huang@samsung.com>
Fri, 30 Sep 2022 10:29:18 +0000 (11:29 +0100)
committerRichard Huang <r.huang@samsung.com>
Fri, 30 Sep 2022 10:29:19 +0000 (11:29 +0100)
Change-Id: I3f0b3575115588e6985702abc30290026792869d

automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
dali-toolkit/internal/text/controller/text-controller-impl.cpp
dali-toolkit/internal/text/rendering/text-typesetter.cpp
dali-toolkit/internal/texture-manager/texture-manager-impl.cpp
dali-toolkit/internal/transition/transition-base-impl.cpp
dali-toolkit/internal/transition/transition-base-impl.h
dali-toolkit/internal/transition/transition-impl.cpp
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

index 5f82a5c..c80d1b5 100644 (file)
@@ -54,8 +54,9 @@ void utc_dali_toolkit_texture_manager_cleanup(void)
 
 namespace
 {
-const char* TEST_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/gallery-small-1.jpg";
-const char* TEST_MASK_FILE_NAME  = TEST_RESOURCE_DIR "/mask.png";
+const char* TEST_IMAGE_FILE_NAME   = TEST_RESOURCE_DIR "/gallery-small-1.jpg";
+const char* TEST_IMAGE_2_FILE_NAME = TEST_RESOURCE_DIR "/icon-delete.png";
+const char* TEST_MASK_FILE_NAME    = TEST_RESOURCE_DIR "/mask.png";
 
 class TestObserver : public Dali::Toolkit::TextureUploadObserver
 {
@@ -1034,7 +1035,7 @@ int UtcTextureManagerAsyncSyncAsync(void)
   Texture asyncTexture2 = asyncTextureSet2.GetTexture(0u);
   DALI_TEST_CHECK(syncTexture);
   DALI_TEST_CHECK(asyncTexture2);
-  DALI_TEST_CHECK(asyncTexture2 == syncTexture);               // check loaded two texture is same.
+  DALI_TEST_CHECK(asyncTexture2 == syncTexture); // check loaded two texture is same.
 
   // observer is called synchronously because the texture is cached.
   DALI_TEST_EQUALS(asyncObserver2.mLoaded, true, TEST_LOCATION);
@@ -1216,3 +1217,162 @@ int UtcTextureManagerRemoveDuringApplyMasking(void)
 
   END_TEST;
 }
+
+int UtcTextureManagerMaskCacheTest(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcTextureManagerMaskCacheTest");
+
+  TextureManager textureManager; // Create new texture manager
+
+  TestObserver observer1;
+  TestObserver observer2;
+
+  std::string                        filename(TEST_IMAGE_FILE_NAME);
+  std::string                        filename2(TEST_IMAGE_2_FILE_NAME);
+  std::string                        maskname(TEST_MASK_FILE_NAME);
+  TextureManager::MaskingDataPointer maskInfo = nullptr;
+  maskInfo.reset(new TextureManager::MaskingData());
+  maskInfo->mAlphaMaskUrl       = maskname;
+  maskInfo->mAlphaMaskId        = TextureManager::INVALID_TEXTURE_ID;
+  maskInfo->mCropToMask         = true;
+  maskInfo->mContentScaleFactor = 1.0f;
+
+  TextureManager::MaskingDataPointer maskInfo2 = nullptr;
+  maskInfo2.reset(new TextureManager::MaskingData());
+  maskInfo2->mAlphaMaskUrl       = maskname;
+  maskInfo2->mAlphaMaskId        = TextureManager::INVALID_TEXTURE_ID;
+  maskInfo2->mCropToMask         = true;
+  maskInfo2->mContentScaleFactor = 1.0f;
+
+  auto                          textureId1(TextureManager::INVALID_TEXTURE_ID);
+  auto                          textureId2(TextureManager::INVALID_TEXTURE_ID);
+  Vector4                       atlasRect(0.f, 0.f, 1.f, 1.f);
+  Dali::ImageDimensions         atlasRectSize(0, 0);
+  bool                          synchronousLoading(false);
+  bool                          atlasingStatus(false);
+  bool                          loadingStatus(false);
+  auto                          preMultiply         = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+  ImageAtlasManagerPtr          atlasManager        = nullptr;
+  Toolkit::AtlasUploadObserver* atlasUploadObserver = nullptr;
+
+  textureManager.LoadTexture(
+    filename,
+    ImageDimensions(),
+    FittingMode::SCALE_TO_FILL,
+    SamplingMode::BOX_THEN_LINEAR,
+    maskInfo,
+    synchronousLoading,
+    textureId1,
+    atlasRect,
+    atlasRectSize,
+    atlasingStatus,
+    loadingStatus,
+    &observer1,
+    atlasUploadObserver,
+    atlasManager,
+    true,
+    TextureManager::ReloadPolicy::CACHED,
+    preMultiply);
+
+  DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render();
+
+  // Load image and mask image.
+  // Now, LoadState become MASK_APPLYING
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+  tet_printf("Current textureId1:%d's state become MASK_APPLYING\n", static_cast<int>(textureId1));
+
+  textureManager.LoadTexture(
+    filename2,
+    ImageDimensions(),
+    FittingMode::SCALE_TO_FILL,
+    SamplingMode::BOX_THEN_LINEAR,
+    maskInfo2,
+    synchronousLoading,
+    textureId2,
+    atlasRect,
+    atlasRectSize,
+    atlasingStatus,
+    loadingStatus,
+    &observer2,
+    atlasUploadObserver,
+    atlasManager,
+    true,
+    TextureManager::ReloadPolicy::CACHED,
+    preMultiply);
+
+  application.SendNotification();
+  application.Render();
+
+  // Load image2 + image1 apply mask + image2 apply mask = total 3 event trigger required.
+  // Note that we use cached mask image.
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
+
+  DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
+  DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
+  DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION);
+  DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION);
+
+  try
+  {
+    // Remove textureId1 first, and then remove textureId2. Check whether segfault occured.
+    textureManager.Remove(textureId1, &observer1);
+    textureManager.Remove(textureId2, &observer2);
+
+    TestObserver observer3;
+    maskInfo.reset(new TextureManager::MaskingData());
+    maskInfo->mAlphaMaskUrl       = maskname;
+    maskInfo->mAlphaMaskId        = TextureManager::INVALID_TEXTURE_ID;
+    maskInfo->mCropToMask         = true;
+    maskInfo->mContentScaleFactor = 1.0f;
+
+    textureManager.LoadTexture(
+      filename,
+      ImageDimensions(),
+      FittingMode::SCALE_TO_FILL,
+      SamplingMode::BOX_THEN_LINEAR,
+      maskInfo,
+      synchronousLoading,
+      textureId1,
+      atlasRect,
+      atlasRectSize,
+      atlasingStatus,
+      loadingStatus,
+      &observer3,
+      atlasUploadObserver,
+      atlasManager,
+      true,
+      TextureManager::ReloadPolicy::CACHED,
+      preMultiply);
+
+    DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
+
+    application.SendNotification();
+    application.Render();
+
+    // Load image and mask image.
+    DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+    DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+    DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
+
+    // Apply mask.
+    DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), 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;
+}
index 1559ae7..34aa8a3 100644 (file)
@@ -3474,7 +3474,7 @@ void OnResourceReadySignal06(Control control)
     // We hope this request result is return later than gImageView2.
 
     Property::Map map1;
-    map1[Toolkit::ImageVisual::Property::URL] = TEST_IMAGE_1;
+    map1[Toolkit::ImageVisual::Property::URL]            = TEST_IMAGE_1;
     map1[Toolkit::ImageVisual::Property::ALPHA_MASK_URL] = TEST_BROKEN_IMAGE_DEFAULT;
 
     gImageView3 = ImageView::New();
@@ -3482,9 +3482,9 @@ void OnResourceReadySignal06(Control control)
     gImageView3.ResourceReadySignal().Connect(&OnResourceReadySignal06);
 
     Property::Map map2;
-    map2[Toolkit::ImageVisual::Property::URL] = TEST_IMAGE_2;
+    map2[Toolkit::ImageVisual::Property::URL]            = TEST_IMAGE_2;
     map2[Toolkit::ImageVisual::Property::ALPHA_MASK_URL] = TEST_BROKEN_IMAGE_S;
-    gImageView4 = ImageView::New();
+    gImageView4                                          = ImageView::New();
     gImageView4.SetProperty(Toolkit::ImageView::Property::IMAGE, map2);
     gImageView4.ResourceReadySignal().Connect(&OnResourceReadySignal06);
 
@@ -3529,6 +3529,28 @@ void OnResourceReadySignal06(Control control)
   }
 }
 
+void OnResourceReadySignal07(Control control)
+{
+  gResourceReadySignalCounter++;
+  // Load masked image
+  tet_printf("rc %d %d\n", gResourceReadySignalCounter, static_cast<bool>(gImageView2));
+
+  if(!gImageView2)
+  {
+    auto scene = gImageView1.GetParent();
+
+    Property::Map map1;
+    map1[Toolkit::ImageVisual::Property::URL]            = TEST_IMAGE_1;
+    map1[Toolkit::ImageVisual::Property::ALPHA_MASK_URL] = TEST_BROKEN_IMAGE_DEFAULT;
+
+    gImageView2 = ImageView::New();
+    gImageView2.SetProperty(Toolkit::ImageView::Property::IMAGE, map1);
+    gImageView2.ResourceReadySignal().Connect(&OnResourceReadySignal07);
+
+    scene.Add(gImageView2);
+  }
+}
+
 } // namespace
 
 int UtcDaliImageViewSetImageOnResourceReadySignal01(void)
@@ -3966,7 +3988,7 @@ int UtcDaliImageViewSetImageOnResourceReadySignal06(void)
   gResourceReadySignal06ComesOrder = 0;
 
   Property::Map map;
-  map[Toolkit::ImageVisual::Property::URL] = "invalid.jpg";
+  map[Toolkit::ImageVisual::Property::URL]            = "invalid.jpg";
   map[Toolkit::ImageVisual::Property::ALPHA_MASK_URL] = "invalid.png";
 
   gImageView1 = ImageView::New(); // request invalid image, to make loading failed fast.
@@ -4015,6 +4037,57 @@ int UtcDaliImageViewSetImageOnResourceReadySignal06(void)
   END_TEST;
 }
 
+int UtcDaliImageViewSetImageOnResourceReadySignal07(void)
+{
+  tet_infoline("Test texturemanager's remove image & mask queue works well within signal handler 02.");
+
+  ToolkitTestApplication application;
+
+  gResourceReadySignalCounter = 0;
+
+  Property::Map map;
+  map[Toolkit::ImageVisual::Property::URL] = TEST_IMAGE_1;
+
+  // Clear image view for clear test
+
+  if(gImageView1)
+  {
+    gImageView1.Reset();
+  }
+  if(gImageView2)
+  {
+    gImageView2.Reset();
+  }
+
+  gImageView1 = ImageView::New();
+  gImageView1.SetProperty(Toolkit::ImageView::Property::IMAGE, map);
+  gImageView1.ResourceReadySignal().Connect(&OnResourceReadySignal07);
+  application.GetScene().Add(gImageView1);
+
+  application.SendNotification();
+  application.Render();
+
+  // Load gImageView1
+
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+  DALI_TEST_EQUALS(gResourceReadySignalCounter, 1, TEST_LOCATION);
+
+  tet_infoline("load image1 done");
+
+  // Load gImageView2 and mask
+
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+  DALI_TEST_EQUALS(gResourceReadySignalCounter, 1, TEST_LOCATION);
+
+  // gImageView2 mask apply done
+
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+  DALI_TEST_EQUALS(gResourceReadySignalCounter, 2, TEST_LOCATION);
+
+  tet_infoline("load image2 done");
+  END_TEST;
+}
+
 int UtcDaliImageViewUseSameUrlWithAnimatedImageVisual(void)
 {
   tet_infoline("Test multiple views with same image in animated image visual");
index e5086d6..8b6d8cb 100644 (file)
@@ -1917,7 +1917,6 @@ void Controller::Impl::SetDefaultColor(const Vector4& color)
   if(!IsShowingPlaceholderText())
   {
     mModel->mVisualModel->SetTextColor(color);
-    mModel->mLogicalModel->mColorRuns.Clear();
     mOperationsPending = static_cast<OperationsMask>(mOperationsPending | COLOR);
     RequestRelayout();
   }
index 5543d79..467b80e 100644 (file)
@@ -974,7 +974,8 @@ PixelData Typesetter::Render(const Vector2& size, Toolkit::DevelText::TextDirect
   {
     // Generate the outline if enabled
     const uint16_t outlineWidth = mModel->GetOutlineWidth();
-    if(outlineWidth != 0u && RENDER_OVERLAY_STYLE != behaviour)
+    const float    outlineAlpha = mModel->GetOutlineColor().a;
+    if(outlineWidth != 0u && fabsf(outlineAlpha) > Math::MACHINE_EPSILON_1 && RENDER_OVERLAY_STYLE != behaviour)
     {
       // Create the image buffer for outline
       Devel::PixelBuffer outlineImageBuffer = CreateImageBuffer(bufferWidth, bufferHeight, Typesetter::STYLE_OUTLINE, ignoreHorizontalAlignment, pixelFormat, penX, penY, startIndexOfGlyphs, endIndexOfGlyphs);
@@ -987,7 +988,8 @@ PixelData Typesetter::Render(const Vector2& size, Toolkit::DevelText::TextDirect
 
     // Generate the shadow if enabled
     const Vector2& shadowOffset = mModel->GetShadowOffset();
-    if(RENDER_OVERLAY_STYLE != behaviour && (fabsf(shadowOffset.x) > Math::MACHINE_EPSILON_1 || fabsf(shadowOffset.y) > Math::MACHINE_EPSILON_1))
+    const float    shadowAlpha  = mModel->GetShadowColor().a;
+    if(RENDER_OVERLAY_STYLE != behaviour && fabsf(shadowAlpha) > Math::MACHINE_EPSILON_1 && (fabsf(shadowOffset.x) > Math::MACHINE_EPSILON_1 || fabsf(shadowOffset.y) > Math::MACHINE_EPSILON_1))
     {
       // Create the image buffer for shadow
       Devel::PixelBuffer shadowImageBuffer = CreateImageBuffer(bufferWidth, bufferHeight, Typesetter::STYLE_SHADOW, ignoreHorizontalAlignment, pixelFormat, penX, penY, startIndexOfGlyphs, endIndexOfGlyphs);
index 0c89aad..ab237a3 100644 (file)
@@ -37,8 +37,8 @@ constexpr auto INITIAL_HASH_NUMBER                     = size_t{0u};
 constexpr auto DEFAULT_NUMBER_OF_LOCAL_LOADER_THREADS  = size_t{4u};
 constexpr auto DEFAULT_NUMBER_OF_REMOTE_LOADER_THREADS = size_t{8u};
 
-constexpr auto TEXTURE_INDEX       = 0u; ///< The Index for texture
-constexpr auto MASK_TEXTURE_INDEX  = 1u; ///< The Index for mask texture
+constexpr auto TEXTURE_INDEX      = 0u; ///< The Index for texture
+constexpr auto MASK_TEXTURE_INDEX = 1u; ///< The Index for mask texture
 
 constexpr auto NUMBER_OF_LOCAL_LOADER_THREADS_ENV  = "DALI_TEXTURE_LOCAL_THREADS";
 constexpr auto NUMBER_OF_REMOTE_LOADER_THREADS_ENV = "DALI_TEXTURE_REMOTE_THREADS";
@@ -710,30 +710,40 @@ void TextureManager::Remove(const TextureManager::TextureId& textureId, TextureU
     if(textureCacheIndex != INVALID_CACHE_INDEX)
     {
       TextureManager::TextureId maskTextureId = INVALID_TEXTURE_ID;
-      TextureInfo& textureInfo(mTextureCacheManager[textureCacheIndex]);
-      if(textureInfo.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)
       {
-        maskTextureId = textureInfo.maskTextureId;
+        if(textureInfo.maskTextureId != INVALID_TEXTURE_ID)
+        {
+          maskTextureId = textureInfo.maskTextureId;
+        }
       }
 
       // the case that LoadingQueue is working.
       if(mLoadingQueueTextureId != INVALID_TEXTURE_ID)
       {
         // If textureId is not same, this observer need to delete when ProcessRemoveQueue() is called.
-        TextureUploadObserver* queueObserver = nullptr;
-        if(mLoadingQueueTextureId != textureId)
+        // If textureId is same, we should not call RemoveTextureObserver.
+        // Because ObserverDestroyed signal already disconnected in NotifyObservers
+        TextureUploadObserver* queueObserver = observer;
+        if(mLoadingQueueTextureId == textureId)
         {
-          queueObserver = observer;
+          queueObserver = nullptr;
         }
 
-        // Remove textureId after NotifyObserver finished
-        if(maskTextureId != INVALID_TEXTURE_ID)
+        // Remove element from the mLoadQueue
+        for(auto&& element : mLoadQueue)
         {
-          if(textureInfo.loadState != LoadState::CANCELLED)
+          if(element.mTextureId == textureId && element.mObserver == observer)
           {
-            mRemoveQueue.PushBack(QueueElement(maskTextureId, nullptr));
+            // Do not erase the item. We will clear it later in ProcessLoadQueue().
+            element.mTextureId = INVALID_TEXTURE_ID;
+            element.mObserver  = nullptr;
+            break;
           }
         }
+
         mRemoveQueue.PushBack(QueueElement(textureId, queueObserver));
       }
       else
@@ -741,6 +751,9 @@ void TextureManager::Remove(const TextureManager::TextureId& textureId, TextureU
         // Remove its observer
         RemoveTextureObserver(textureInfo, observer);
 
+        // Remove textureId in CacheManager. Now, textureInfo is invalidate.
+        mTextureCacheManager.RemoveCache(textureInfo);
+
         // Remove maskTextureId in CacheManager
         if(maskTextureId != INVALID_TEXTURE_ID)
         {
@@ -748,31 +761,9 @@ void TextureManager::Remove(const TextureManager::TextureId& textureId, TextureU
           if(maskCacheIndex != INVALID_CACHE_INDEX)
           {
             TextureInfo& maskTextureInfo(mTextureCacheManager[maskCacheIndex]);
-
-            // Only Remove maskTexture when texture's loadState is not CANCELLED. because it is already deleted.
-            if(textureInfo.loadState != LoadState::CANCELLED)
-            {
-              mTextureCacheManager.RemoveCache(maskTextureInfo);
-            }
+            mTextureCacheManager.RemoveCache(maskTextureInfo);
           }
         }
-
-        // Remove textureId in CacheManager
-        mTextureCacheManager.RemoveCache(textureInfo);
-      }
-    }
-
-    if(observer)
-    {
-      // Remove element from the LoadQueue
-      for(auto&& element : mLoadQueue)
-      {
-        if(element.mObserver == observer)
-        {
-          // Do not erase the item. We will clear it later in ProcessLoadQueue().
-          element.mObserver = nullptr;
-          break;
-        }
       }
     }
   }
@@ -885,7 +876,10 @@ void TextureManager::QueueLoadTexture(const TextureManager::TextureInfo& texture
   const auto& textureId = textureInfo.textureId;
   mLoadQueue.PushBack(QueueElement(textureId, observer));
 
-  observer->DestructionSignal().Connect(this, &TextureManager::ObserverDestroyed);
+  if(observer)
+  {
+    observer->DestructionSignal().Connect(this, &TextureManager::ObserverDestroyed);
+  }
 }
 
 void TextureManager::LoadTexture(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer)
@@ -915,7 +909,7 @@ void TextureManager::ProcessLoadQueue()
 {
   for(auto&& element : mLoadQueue)
   {
-    if(!element.mObserver)
+    if(element.mTextureId == INVALID_TEXTURE_ID)
     {
       continue;
     }
@@ -926,7 +920,10 @@ void TextureManager::ProcessLoadQueue()
       TextureInfo& textureInfo(mTextureCacheManager[cacheIndex]);
       if((textureInfo.loadState == LoadState::UPLOADED) || (textureInfo.loadState == LoadState::LOAD_FINISHED && textureInfo.storageType == StorageType::RETURN_PIXEL_BUFFER))
       {
-        EmitLoadComplete(element.mObserver, textureInfo, true);
+        if(element.mObserver)
+        {
+          EmitLoadComplete(element.mObserver, textureInfo, true);
+        }
       }
       else if(textureInfo.loadState == LoadState::LOADING)
       {
@@ -945,15 +942,11 @@ void TextureManager::ProcessLoadQueue()
 
 void TextureManager::ProcessRemoveQueue()
 {
-  TextureCacheIndex textureCacheIndex = INVALID_CACHE_INDEX;
   for(auto&& element : mRemoveQueue)
   {
-    textureCacheIndex = mTextureCacheManager.GetCacheIndexFromId(element.mTextureId);
-    if(textureCacheIndex != INVALID_CACHE_INDEX)
+    if(element.mTextureId != INVALID_TEXTURE_ID)
     {
-      TextureInfo& textureInfo(mTextureCacheManager[textureCacheIndex]);
-      RemoveTextureObserver(textureInfo, element.mObserver);
-      mTextureCacheManager.RemoveCache(textureInfo);
+      Remove(element.mTextureId, element.mObserver);
     }
   }
   mRemoveQueue.Clear();
@@ -1124,10 +1117,13 @@ void TextureManager::CheckForWaitingTexture(TextureManager::TextureInfo& maskTex
     UploadTextures(pixelBuffers, maskTextureInfo);
   }
 
-  // Search the cache, checking if any texture has this texture id as a
-  // maskTextureId:
+  // Search the cache, checking if any texture has this texture id as a maskTextureId
   const std::size_t size = mTextureCacheManager.size();
 
+  // Keep notify observer required textureIds.
+  // Note : NotifyObservers can change mTextureCacheManager cache struct. We should check id's validation before notify.
+  std::vector<TextureId> notifyRequiredTextureIds;
+
   // TODO : Refactorize here to not iterate whole cached image.
   for(TextureCacheIndex cacheIndex = TextureCacheIndex(TextureManagerType::TEXTURE_CACHE_INDEX_TYPE_LOCAL, 0u); cacheIndex.GetIndex() < size; ++cacheIndex.detailValue.index)
   {
@@ -1153,8 +1149,7 @@ void TextureManager::CheckForWaitingTexture(TextureManager::TextureInfo& maskTex
           pixelBuffers.push_back(textureInfo.pixelBuffer);
           UploadTextures(pixelBuffers, textureInfo);
 
-          // notify mask texture set.
-          NotifyObservers(textureInfo, true);
+          notifyRequiredTextureIds.push_back(textureInfo.textureId);
         }
       }
       else
@@ -1164,10 +1159,22 @@ void TextureManager::CheckForWaitingTexture(TextureManager::TextureInfo& maskTex
         std::vector<Devel::PixelBuffer> pixelBuffers;
         pixelBuffers.push_back(textureInfo.pixelBuffer);
         UploadTextures(pixelBuffers, textureInfo);
-        NotifyObservers(textureInfo, true);
+
+        notifyRequiredTextureIds.push_back(textureInfo.textureId);
       }
     }
   }
+
+  // Notify textures are masked
+  for(const auto textureId : notifyRequiredTextureIds)
+  {
+    TextureCacheIndex textureCacheIndex = mTextureCacheManager.GetCacheIndexFromId(textureId);
+    if(textureCacheIndex != INVALID_CACHE_INDEX)
+    {
+      TextureInfo& textureInfo(mTextureCacheManager[textureCacheIndex]);
+      NotifyObservers(textureInfo, true);
+    }
+  }
 }
 
 void TextureManager::ApplyMask(TextureManager::TextureInfo& textureInfo, const TextureManager::TextureId& maskTextureId)
@@ -1210,7 +1217,7 @@ void TextureManager::UploadTextures(std::vector<Devel::PixelBuffer>& pixelBuffer
 
     for(auto&& pixelBuffer : pixelBuffers)
     {
-      Texture texture = Texture::New(Dali::TextureType::TEXTURE_2D, pixelBuffer.GetPixelFormat(), pixelBuffer.GetWidth(), pixelBuffer.GetHeight());
+      Texture   texture   = Texture::New(Dali::TextureType::TEXTURE_2D, pixelBuffer.GetPixelFormat(), pixelBuffer.GetWidth(), pixelBuffer.GetHeight());
       PixelData pixelData = Devel::PixelBuffer::Convert(pixelBuffer);
       texture.Upload(pixelData);
       textureInfo.textures.push_back(texture);
@@ -1314,7 +1321,8 @@ void TextureManager::ObserverDestroyed(TextureUploadObserver* observer)
   {
     if(element.mObserver == observer)
     {
-      element.mObserver = nullptr;
+      element.mTextureId = INVALID_TEXTURE_ID;
+      element.mObserver  = nullptr;
     }
   }
 }
@@ -1346,7 +1354,7 @@ void TextureManager::EmitLoadComplete(TextureUploadObserver* observer, TextureMa
 
 TextureSet TextureManager::GetTextureSet(const TextureManager::TextureId& textureId)
 {
-  TextureSet textureSet;
+  TextureSet                textureSet;
   TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId);
   if(loadState == TextureManager::LoadState::UPLOADED)
   {
@@ -1406,8 +1414,8 @@ void TextureManager::RemoveTextureObserver(TextureManager::TextureInfo& textureI
   // Remove its observer
   if(observer)
   {
-    const auto   iterEnd = textureInfo.observerList.End();
-    const auto   iter    = std::find(textureInfo.observerList.Begin(), iterEnd, observer);
+    const auto iterEnd = textureInfo.observerList.End();
+    const auto iter    = std::find(textureInfo.observerList.Begin(), iterEnd, observer);
     if(iter != iterEnd)
     {
       // Disconnect and remove the observer.
index 5ee926e..5a88901 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -70,36 +70,6 @@ Property::Map GetOriginalProperties(Dali::Toolkit::Control control)
   return propertyMap;
 }
 
-/**
- * @brief Computes and center position by using transform properties.
- * @param[in] anchorPoint anchorPoint of an actor.
- * @param[in] positionUsesAnchorPoint positionUsesAnchorPoint of an actor.
- * @param[in] size size of an actor.
- * @param[in] scale scale of an actor.
- * @param[in] orientation orientation of an actor.
- */
-Vector3 CalculateCenterPosition(
-  const Vector3&    anchorPoint,
-  const bool        positionUsesAnchorPoint,
-  const Vector3&    size,
-  const Vector3&    scale,
-  const Quaternion& orientation)
-{
-  Vector3       centerPosition;
-  const Vector3 half(0.5f, 0.5f, 0.5f);
-  const Vector3 topLeft(0.0f, 0.0f, 0.5f);
-  // Calculate the center-point by applying the scale and rotation on the anchor point.
-  centerPosition = (half - anchorPoint) * size * scale;
-  centerPosition *= orientation;
-
-  // If the position is ignoring the anchor-point, then remove the anchor-point shift from the position.
-  if(!positionUsesAnchorPoint)
-  {
-    centerPosition -= (topLeft - anchorPoint) * size;
-  }
-  return centerPosition;
-}
-
 } // anonymous namespace
 
 TransitionBasePtr TransitionBase::New()
@@ -161,7 +131,7 @@ void TransitionBase::TransitionWithChild(bool transitionWithChild)
 
 void TransitionBase::PreProcess(Dali::Animation animation)
 {
-  mAnimation           = animation;
+  mAnimation = animation;
   // Retrieve original property map of mTarget to backup and to reset after transition is finished.
   mOriginalPropertyMap = GetOriginalProperties(mTarget);
   mMoveTargetChildren  = false;
@@ -183,11 +153,11 @@ void TransitionBase::Play()
 
   // Set world transform and color to the target control to make it independent of the parent control and its transition.
   // The properties will be returned at the TransitionFinished() method.
-  Matrix     targetWorldTransform = GetWorldTransform(mTarget);
+  Matrix     targetWorldTransform = DevelActor::GetWorldTransform(mTarget);
   Vector3    targetPosition, targetScale;
   Quaternion targetOrientation;
   targetWorldTransform.GetTransformComponents(targetPosition, targetOrientation, targetScale);
-  Vector4 targetColor = GetWorldColor(mTarget);
+  Vector4 targetColor = DevelActor::GetWorldColor(mTarget);
 
   mTarget.SetProperties(PROPERTY_MAP_INDEPENDENT_CONTROL);
   mTarget[Dali::Actor::Property::POSITION]    = targetPosition;
@@ -282,141 +252,6 @@ void TransitionBase::TransitionFinished()
   mAnimation.Reset();
 }
 
-Matrix TransitionBase::GetWorldTransform(Dali::Actor actor)
-{
-  enum InheritanceMode
-  {
-    DONT_INHERIT_TRANSFORM = 0,
-    INHERIT_POSITION       = 1,
-    INHERIT_SCALE          = 2,
-    INHERIT_ORIENTATION    = 4,
-    INHERIT_ALL            = INHERIT_POSITION | INHERIT_SCALE | INHERIT_ORIENTATION,
-  };
-
-  std::vector<Dali::Actor>     descentList;
-  std::vector<InheritanceMode> inheritanceModeList;
-  Dali::Actor                  currentActor = actor;
-  int                          inheritance  = 0;
-  do
-  {
-    inheritance = (static_cast<int>(currentActor.GetProperty<bool>(Dali::Actor::Property::INHERIT_ORIENTATION)) << 2) +
-                  (static_cast<int>(currentActor.GetProperty<bool>(Dali::Actor::Property::INHERIT_SCALE)) << 1) +
-                  static_cast<int>(currentActor.GetProperty<bool>(Dali::Actor::Property::INHERIT_POSITION));
-    inheritanceModeList.push_back(static_cast<InheritanceMode>(inheritance));
-    descentList.push_back(currentActor);
-    currentActor = currentActor.GetParent();
-  } while(inheritance != DONT_INHERIT_TRANSFORM && currentActor);
-
-  Matrix  worldMatrix;
-  Vector3 localPosition;
-  for(unsigned int i(descentList.size() - 1); i < descentList.size(); --i)
-  {
-    Vector3    anchorPoint             = descentList[i].GetProperty<Vector3>(Dali::Actor::Property::ANCHOR_POINT);
-    Vector3    parentOrigin            = descentList[i].GetProperty<Vector3>(Dali::Actor::Property::PARENT_ORIGIN);
-    bool       positionUsesAnchorPoint = descentList[i].GetProperty<bool>(Dali::Actor::Property::POSITION_USES_ANCHOR_POINT);
-    Vector3    size                    = descentList[i].GetProperty<Vector3>(Dali::Actor::Property::SIZE);
-    Vector3    actorPosition           = descentList[i].GetProperty<Vector3>(Dali::Actor::Property::POSITION);
-    Quaternion localOrientation        = descentList[i].GetProperty<Quaternion>(Dali::Actor::Property::ORIENTATION);
-    Vector3    localScale              = descentList[i].GetProperty<Vector3>(Dali::Actor::Property::SCALE);
-
-    Vector3 centerPosition = CalculateCenterPosition(anchorPoint, positionUsesAnchorPoint, size, localScale, localOrientation);
-    if(inheritanceModeList[i] != DONT_INHERIT_TRANSFORM && descentList[i].GetParent())
-    {
-      Matrix  localMatrix;
-      Vector3 parentSize = descentList[i + 1].GetProperty<Vector3>(Dali::Actor::Property::SIZE);
-      if(inheritanceModeList[i] == INHERIT_ALL)
-      {
-        localPosition = actorPosition + centerPosition + (parentOrigin - Vector3(0.5f, 0.5f, 0.5f)) * parentSize;
-        localMatrix.SetTransformComponents(localScale, localOrientation, localPosition);
-
-        //Update the world matrix
-        Matrix tempMatrix;
-        Matrix::Multiply(tempMatrix, localMatrix, worldMatrix);
-        worldMatrix = tempMatrix;
-      }
-      else
-      {
-        Vector3    parentPosition, parentScale;
-        Quaternion parentOrientation;
-        worldMatrix.GetTransformComponents(parentPosition, parentOrientation, parentScale);
-
-        if((inheritanceModeList[i] & INHERIT_SCALE) == 0)
-        {
-          //Don't inherit scale
-          localScale /= parentScale;
-        }
-
-        if((inheritanceModeList[i] & INHERIT_ORIENTATION) == 0)
-        {
-          //Don't inherit orientation
-          parentOrientation.Invert();
-          localOrientation = parentOrientation * localOrientation;
-        }
-
-        if((inheritanceModeList[i] & INHERIT_POSITION) == 0)
-        {
-          localMatrix.SetTransformComponents(localScale, localOrientation, Vector3::ZERO);
-          Matrix tempMatrix;
-          Matrix::Multiply(tempMatrix, localMatrix, worldMatrix);
-          worldMatrix = tempMatrix;
-          worldMatrix.SetTranslation(actorPosition + centerPosition);
-        }
-        else
-        {
-          localPosition = actorPosition + centerPosition + (parentOrigin - Vector3(0.5f, 0.5f, 0.5f)) * parentSize;
-          localMatrix.SetTransformComponents(localScale, localOrientation, localPosition);
-          Matrix tempMatrix;
-          Matrix::Multiply(tempMatrix, localMatrix, worldMatrix);
-          worldMatrix = tempMatrix;
-        }
-      }
-    }
-    else
-    {
-      localPosition = actorPosition + centerPosition;
-      worldMatrix.SetTransformComponents(localScale, localOrientation, localPosition);
-    }
-  }
-
-  return worldMatrix;
-}
-
-Vector4 TransitionBase::GetWorldColor(Dali::Actor actor)
-{
-  std::vector<Dali::Actor>     descentList;
-  std::vector<Dali::ColorMode> inheritanceModeList;
-  Dali::Actor                  currentActor = actor;
-  Dali::ColorMode              inheritance  = Dali::ColorMode::USE_OWN_MULTIPLY_PARENT_ALPHA;
-  do
-  {
-    inheritance = currentActor.GetProperty<Dali::ColorMode>(Dali::Actor::Property::COLOR_MODE);
-    inheritanceModeList.push_back(inheritance);
-    descentList.push_back(currentActor);
-    currentActor = currentActor.GetParent();
-  } while(inheritance != Dali::ColorMode::USE_OWN_COLOR && currentActor);
-
-  Vector4 worldColor;
-  for(unsigned int i(descentList.size() - 1); i < descentList.size(); --i)
-  {
-    if(inheritanceModeList[i] == USE_OWN_COLOR || i == descentList.size() - 1)
-    {
-      worldColor = descentList[i].GetProperty<Vector4>(Dali::Actor::Property::COLOR);
-    }
-    else if(inheritanceModeList[i] == USE_OWN_MULTIPLY_PARENT_ALPHA)
-    {
-      Vector4 ownColor = descentList[i].GetProperty<Vector4>(Dali::Actor::Property::COLOR);
-      worldColor       = Vector4(ownColor.r, ownColor.g, ownColor.b, ownColor.a * worldColor.a);
-    }
-    else if(inheritanceModeList[i] == USE_OWN_MULTIPLY_PARENT_COLOR)
-    {
-      Vector4 ownColor = descentList[i].GetProperty<Vector4>(Dali::Actor::Property::COLOR);
-      worldColor *= ownColor;
-    }
-  }
-
-  return worldColor;
-}
-
 } // namespace Internal
 
 } // namespace Toolkit
index b194e52..73e30dd 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_TRANSITION_BASE_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -126,7 +126,6 @@ public:
   }
 
 protected:
-
   /**
    * @brief Set property map which will be used as a animation start properties.
    * @param[in] propertyMap propertyMap that will be used as a start value of transition.
@@ -163,18 +162,6 @@ protected:
   }
 
   /**
-   * @brief Gets world transform of input Actor.
-   * @param[in] actor actor for get world transform.
-   */
-  Matrix GetWorldTransform(Dali::Actor actor);
-
-  /**
-   * @brief Gets world color of input Actor.
-   * @param[in] actor actor for get world color.
-   */
-  Vector4 GetWorldColor(Dali::Actor actor);
-
-  /**
    * @brief Returns whether this transition will be applied to children of target or not.
    */
   bool IsTransitionWithChild() const
@@ -256,19 +243,19 @@ private:
   }
 
 private:
-  Dali::Toolkit::Control       mTarget;              ///< Target that will be animated.
-  Dali::Actor                  mCopiedActor;         ///< Copied View that will replace mTarget during transition
-  Dali::Animation              mAnimation;           ///< Property animations for the transition of mTarget
-  AlphaFunction                mAlphaFunction;       ///< Alpha function that will applied for the property animation
-  Property::Map                mStartPropertyMap;    ///< Start properties to be animated. (world transform)
-  Property::Map                mFinishPropertyMap;   ///< Finish properties to be animated. (world transform)
-  Property::Map                mOriginalPropertyMap; ///< Original properties of mTarget to be used to restore after the transition is finished.
-  Dali::TimePeriod             mTimePeriod;          ///< TimePeriod of transition
-  bool                         mTransitionWithChild; ///< True, if mTarget transition is inherit to its child Actors.
-                                                     ///< If this is false, the child Actors are moved to the child of mCopiedActor that will have original properties of target Actor during Transition.
-  bool mMoveTargetChildren;                          ///< Flag, if mTransitionWithChild is false and mTarget has children than True.
-  bool mIsAppearingTransition;                       ///< True, if this transition is appearing transition.
-  bool mIsPairTransition;                            ///< True, if this transition is started from a Control to another Control.
+  Dali::Toolkit::Control mTarget;              ///< Target that will be animated.
+  Dali::Actor            mCopiedActor;         ///< Copied View that will replace mTarget during transition
+  Dali::Animation        mAnimation;           ///< Property animations for the transition of mTarget
+  AlphaFunction          mAlphaFunction;       ///< Alpha function that will applied for the property animation
+  Property::Map          mStartPropertyMap;    ///< Start properties to be animated. (world transform)
+  Property::Map          mFinishPropertyMap;   ///< Finish properties to be animated. (world transform)
+  Property::Map          mOriginalPropertyMap; ///< Original properties of mTarget to be used to restore after the transition is finished.
+  Dali::TimePeriod       mTimePeriod;          ///< TimePeriod of transition
+  bool                   mTransitionWithChild; ///< True, if mTarget transition is inherit to its child Actors.
+                                               ///< If this is false, the child Actors are moved to the child of mCopiedActor that will have original properties of target Actor during Transition.
+  bool mMoveTargetChildren;                    ///< Flag, if mTransitionWithChild is false and mTarget has children than True.
+  bool mIsAppearingTransition;                 ///< True, if this transition is appearing transition.
+  bool mIsPairTransition;                      ///< True, if this transition is started from a Control to another Control.
 };
 
 } // namespace Internal
index 78ba8db..3f78a6f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -82,7 +82,7 @@ Transition::~Transition()
 
 void Transition::OnPlay()
 {
-  Dali::Toolkit::Control sourceControl = mSourceControl.GetHandle();
+  Dali::Toolkit::Control sourceControl      = mSourceControl.GetHandle();
   Dali::Toolkit::Control destinationControl = mDestinationControl.GetHandle();
   if(!sourceControl || !sourceControl[Dali::Actor::Property::CONNECTED_TO_SCENE] ||
      !destinationControl || !destinationControl[Dali::Actor::Property::CONNECTED_TO_SCENE])
@@ -92,12 +92,12 @@ void Transition::OnPlay()
   }
 
   //Make startPropertyMap and finishPropertyMap to use for property animation.
-  Matrix     sourceWorldTransform = GetWorldTransform(sourceControl);
+  Matrix     sourceWorldTransform = DevelActor::GetWorldTransform(sourceControl);
   Vector3    sourcePosition, sourceScale;
   Quaternion sourceOrientation;
   sourceWorldTransform.GetTransformComponents(sourcePosition, sourceOrientation, sourceScale);
 
-  Matrix     destinationWorldTransform = GetWorldTransform(destinationControl);
+  Matrix     destinationWorldTransform = DevelActor::GetWorldTransform(destinationControl);
   Vector3    destinationPosition, destinationScale;
   Quaternion destinationOrientation;
   destinationWorldTransform.GetTransformComponents(destinationPosition, destinationOrientation, destinationScale);
@@ -115,8 +115,8 @@ void Transition::OnPlay()
   startPropertyMap.Insert(Dali::Actor::Property::SCALE, sourceScale);
   finishPropertyMap.Insert(Dali::Actor::Property::SCALE, destinationScale);
 
-  Vector4 sourceColor      = GetWorldColor(sourceControl);
-  Vector4 destinationColor = GetWorldColor(destinationControl);
+  Vector4 sourceColor      = DevelActor::GetWorldColor(sourceControl);
+  Vector4 destinationColor = DevelActor::GetWorldColor(destinationControl);
   startPropertyMap.Insert(Dali::Actor::Property::COLOR, sourceColor);
   finishPropertyMap.Insert(Dali::Actor::Property::COLOR, destinationColor);
 
index 73cc003..33fb992 100644 (file)
@@ -29,7 +29,7 @@ namespace Toolkit
 {
 const unsigned int TOOLKIT_MAJOR_VERSION = 2;
 const unsigned int TOOLKIT_MINOR_VERSION = 1;
-const unsigned int TOOLKIT_MICRO_VERSION = 41;
+const unsigned int TOOLKIT_MICRO_VERSION = 42;
 const char* const  TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 18e1669..7635931 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    2.1.41
+Version:    2.1.42
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT