[dali_2.1.39] Merge branch 'devel/master' 92/281092/1
authorAdam Bialogonski <adam.b@samsung.com>
Fri, 9 Sep 2022 09:06:29 +0000 (10:06 +0100)
committerAdam Bialogonski <adam.b@samsung.com>
Fri, 9 Sep 2022 09:06:30 +0000 (10:06 +0100)
Change-Id: I6d5048d0466daac227df97e34f20e98d7afc7717

20 files changed:
automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-gl-abstraction.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-gl-abstraction.h
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp
dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp
dali-toolkit/internal/texture-manager/texture-cache-manager.cpp
dali-toolkit/internal/texture-manager/texture-cache-manager.h
dali-toolkit/internal/texture-manager/texture-manager-impl.cpp
dali-toolkit/internal/texture-manager/texture-manager-impl.h
dali-toolkit/internal/texture-manager/texture-manager-type.h
dali-toolkit/internal/texture-manager/texture-upload-observer.cpp
dali-toolkit/internal/texture-manager/texture-upload-observer.h
dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp
dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp
dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/npatch/npatch-visual.cpp
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

index 1c8fea2..5f82a5c 100644 (file)
@@ -599,8 +599,6 @@ int UtcTextureManagerUseInvalidMask(void)
     atlasRectSize,
     atlasingStatus,
     loadingStatus,
-    WrapMode::DEFAULT,
-    WrapMode::DEFAULT,
     &observer,
     atlasUploadObserver,
     atlasManager,
@@ -666,8 +664,6 @@ int UtcTextureManagerUseInvalidMaskAndMaskLoadedFirst(void)
     atlasRectSize,
     atlasingStatus,
     loadingStatus,
-    WrapMode::DEFAULT,
-    WrapMode::DEFAULT,
     &observer,
     atlasUploadObserver,
     atlasManager,
@@ -733,8 +729,6 @@ int UtcTextureManagerUseInvalidMaskAndMaskLoadedLater(void)
     atlasRectSize,
     atlasingStatus,
     loadingStatus,
-    WrapMode::DEFAULT,
-    WrapMode::DEFAULT,
     &observer,
     atlasUploadObserver,
     atlasManager,
@@ -820,8 +814,6 @@ int UtcTextureManagerSynchronousLoadingFail(void)
     atlasRectSize,
     atlasingStatus,
     loadingStatus,
-    WrapMode::DEFAULT,
-    WrapMode::DEFAULT,
     &observer,
     atlasUploadObserver,
     atlasManager,
@@ -876,8 +868,6 @@ int UtcTextureManagerCachingSynchronousLoading(void)
     atlasRectSize,
     atlasingStatus,
     loadingStatus,
-    WrapMode::DEFAULT,
-    WrapMode::DEFAULT,
     &observer,
     atlasUploadObserver,
     atlasManager,
@@ -908,8 +898,6 @@ int UtcTextureManagerCachingSynchronousLoading(void)
     atlasRectSize,
     atlasingStatus,
     loadingStatus,
-    WrapMode::DEFAULT,
-    WrapMode::DEFAULT,
     &asyncObserver,
     atlasUploadObserver,
     atlasManager,
@@ -968,8 +956,6 @@ int UtcTextureManagerAsyncSyncAsync(void)
     atlasRectSize,
     atlasingStatus,
     asyncLoadingStatus1,
-    WrapMode::DEFAULT,
-    WrapMode::DEFAULT,
     &asyncObserver1,
     atlasUploadObserver,
     atlasManager,
@@ -1000,8 +986,6 @@ int UtcTextureManagerAsyncSyncAsync(void)
     atlasRectSize,
     atlasingStatus,
     syncLoadingStatus,
-    WrapMode::DEFAULT,
-    WrapMode::DEFAULT,
     &syncObserver,
     atlasUploadObserver,
     atlasManager,
@@ -1037,8 +1021,6 @@ int UtcTextureManagerAsyncSyncAsync(void)
     atlasRectSize,
     atlasingStatus,
     asyncLoadingStatus2,
-    WrapMode::DEFAULT,
-    WrapMode::DEFAULT,
     &asyncObserver2,
     atlasUploadObserver,
     atlasManager,
@@ -1048,7 +1030,11 @@ int UtcTextureManagerAsyncSyncAsync(void)
 
   DALI_TEST_EQUALS(asyncLoadingStatus2, false, TEST_LOCATION); // texture is loaded by previous sync request
   DALI_TEST_CHECK(asyncTextureSet2);                           // texture is loaded
-  DALI_TEST_CHECK(asyncTextureSet2 == syncTextureSet);         // check loaded two texture is same.
+  Texture syncTexture   = syncTextureSet.GetTexture(0u);
+  Texture asyncTexture2 = asyncTextureSet2.GetTexture(0u);
+  DALI_TEST_CHECK(syncTexture);
+  DALI_TEST_CHECK(asyncTexture2);
+  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);
@@ -1064,7 +1050,10 @@ int UtcTextureManagerAsyncSyncAsync(void)
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
   DALI_TEST_EQUALS(asyncObserver1.mLoaded, true, TEST_LOCATION);
   DALI_TEST_EQUALS(asyncObserver1.mObserverCalled, true, TEST_LOCATION);
-  DALI_TEST_CHECK(asyncObserver1.mTextureSet == asyncTextureSet2); // check loaded two texture is same.
+  DALI_TEST_CHECK(asyncObserver1.mTextureSet);
+
+  Texture observerTexture = asyncObserver1.mTextureSet.GetTexture(0u);
+  DALI_TEST_CHECK(observerTexture == asyncTexture2); // check loaded two texture is same.
 
   // asyncObserver2 was already called so it isn't called here.
   DALI_TEST_EQUALS(asyncObserver2.mLoaded, false, TEST_LOCATION);
@@ -1165,8 +1154,6 @@ int UtcTextureManagerRemoveDuringApplyMasking(void)
     atlasRectSize,
     atlasingStatus,
     loadingStatus,
-    WrapMode::DEFAULT,
-    WrapMode::DEFAULT,
     &observer1,
     atlasUploadObserver,
     atlasManager,
@@ -1216,22 +1203,6 @@ int UtcTextureManagerRemoveDuringApplyMasking(void)
 
   tet_printf("textureId1:%d removed and textureId2:%d requested\n", static_cast<int>(textureId1), static_cast<int>(textureId2));
 
-  // ApplyMask event come back, and do nothing.
-  // CAPTION : HARD-CODING.
-  {
-    std::vector<Devel::PixelBuffer> pixelBuffers;
-    textureManager.AsyncLoadComplete(textureId1, pixelBuffers);
-    textureManager.Remove(maskInfo->mAlphaMaskId, nullptr);
-  }
-
-  application.SendNotification();
-  application.Render();
-
-  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);
-
   // CAPTION : HARD-CODING.
   {
     std::vector<Devel::PixelBuffer> pixelBuffers;
index e6416e3..7a31046 100644 (file)
@@ -46,28 +46,32 @@ TestGlAbstraction::~TestGlAbstraction()
 
 void TestGlAbstraction::Initialize()
 {
-  mCurrentProgram                  = 0;
-  mCompileStatus                   = GL_TRUE;
-  mLinkStatus                      = GL_TRUE;
-  mGetErrorResult                  = 0;
-  mGetStringResult                 = NULL;
-  mIsBufferResult                  = 0;
-  mIsEnabledResult                 = 0;
-  mIsFramebufferResult             = 0;
-  mIsProgramResult                 = 0;
-  mIsRenderbufferResult            = 0;
-  mIsShaderResult                  = 0;
-  mIsTextureResult                 = 0;
-  mActiveTextureUnit               = 0;
-  mCheckFramebufferStatusResult    = 0;
-  mFramebufferStatus               = 0;
-  mFramebufferDepthAttached        = 0;
-  mFramebufferStencilAttached      = 0;
-  mFramebufferColorAttachmentCount = 0;
-  mFrameBufferColorStatus          = 0;
-  mNumBinaryFormats                = 0;
-  mBinaryFormats                   = 0;
-  mProgramBinaryLength             = 0;
+  mCurrentProgram                         = 0;
+  mCompileStatus                          = GL_TRUE;
+  mLinkStatus                             = GL_TRUE;
+  mGetErrorResult                         = 0;
+  mGetStringResult                        = NULL;
+  mIsBufferResult                         = 0;
+  mIsEnabledResult                        = 0;
+  mIsFramebufferResult                    = 0;
+  mIsProgramResult                        = 0;
+  mIsRenderbufferResult                   = 0;
+  mIsShaderResult                         = 0;
+  mIsTextureResult                        = 0;
+  mActiveTextureUnit                      = 0;
+  mCheckFramebufferStatusResult           = 0;
+  mFramebufferStatus                      = 0;
+  mFramebufferDepthAttached               = 0;
+  mFramebufferStencilAttached             = 0;
+  mFramebufferDepthStencilAttached        = 0;
+  mFramebufferColorAttachmentCount        = 0;
+  mFrameBufferColorStatus                 = 0;
+  mFramebufferDepthAttachmentCount        = 0;
+  mFramebufferStencilAttachmentCount      = 0;
+  mFramebufferDepthStencilAttachmentCount = 0;
+  mNumBinaryFormats                       = 0;
+  mBinaryFormats                          = 0;
+  mProgramBinaryLength                    = 0;
 
   mVertexAttribArrayChanged = false;
   mGetProgramBinaryCalled   = false;
index a1f8405..f6878ae 100644 (file)
@@ -299,6 +299,21 @@ public:
     return mFramebufferColorAttachmentCount;
   }
 
+  inline GLuint CheckFramebufferDepthAttachmentCount()
+  {
+    return mFramebufferDepthAttachmentCount;
+  }
+
+  inline GLuint CheckFramebufferStencilAttachmentCount()
+  {
+    return mFramebufferStencilAttachmentCount;
+  }
+
+  inline GLuint CheckFramebufferDepthStencilAttachmentCount()
+  {
+    return mFramebufferDepthStencilAttachmentCount;
+  }
+
   inline GLenum CheckFramebufferDepthAttachment()
   {
     return mFramebufferDepthAttached;
@@ -309,6 +324,11 @@ public:
     return mFramebufferStencilAttached;
   }
 
+  inline GLenum CheckFramebufferDepthStencilAttachment()
+  {
+    return mFramebufferDepthStencilAttached;
+  }
+
   inline void Clear(GLbitfield mask) override
   {
     mClearCount++;
@@ -630,8 +650,9 @@ public:
     }
     else if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)
     {
-      mFramebufferStencilAttached = true;
-      mFramebufferDepthAttached   = true;
+      mFramebufferStencilAttached      = true;
+      mFramebufferDepthAttached        = true;
+      mFramebufferDepthStencilAttached = true;
     }
   }
 
@@ -650,6 +671,20 @@ public:
         ++mFramebufferColorAttachmentCount;
       }
     }
+    else if(attachment == GL_DEPTH_ATTACHMENT)
+    {
+      ++mFramebufferDepthAttachmentCount;
+    }
+    else if(attachment == GL_STENCIL_ATTACHMENT)
+    {
+      ++mFramebufferStencilAttachmentCount;
+    }
+    else if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)
+    {
+      ++mFramebufferDepthAttachmentCount;
+      ++mFramebufferStencilAttachmentCount;
+      ++mFramebufferDepthStencilAttachmentCount;
+    }
   }
 
   inline void FrontFace(GLenum mode) override
@@ -2491,8 +2526,12 @@ public:
   GLint                                 mFramebufferStatus;
   GLenum                                mFramebufferDepthAttached;
   GLenum                                mFramebufferStencilAttached;
+  GLenum                                mFramebufferDepthStencilAttached;
   GLuint                                mFramebufferColorAttachmentCount;
   GLuint                                mFrameBufferColorStatus;
+  GLuint                                mFramebufferDepthAttachmentCount;
+  GLuint                                mFramebufferStencilAttachmentCount;
+  GLuint                                mFramebufferDepthStencilAttachmentCount;
   GLint                                 mNumBinaryFormats;
   GLint                                 mBinaryFormats;
   GLint                                 mProgramBinaryLength;
index 7a7bf26..1559ae7 100644 (file)
@@ -81,6 +81,7 @@ const char* TEST_GIF_FILE_NAME = TEST_RESOURCE_DIR "/anim.gif";
 
 const char* TEST_SVG_FILE_NAME                   = TEST_RESOURCE_DIR "/svg1.svg";
 const char* TEST_ANIMATED_VECTOR_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/insta_camera.json";
+const char* TEST_WEBP_FILE_NAME                  = TEST_RESOURCE_DIR "/dali-logo.webp";
 
 void TestUrl(ImageView imageView, const std::string url)
 {
@@ -3460,6 +3461,74 @@ void OnResourceReadySignal05(Control control)
   }
 }
 
+int gResourceReadySignal06ComesOrder = 0;
+
+void OnResourceReadySignal06(Control control)
+{
+  gResourceReadySignalCounter++;
+  if(gResourceReadySignalCounter == 1)
+  {
+    auto scene = gImageView1.GetParent();
+
+    // Request load something
+    // 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::ALPHA_MASK_URL] = TEST_BROKEN_IMAGE_DEFAULT;
+
+    gImageView3 = ImageView::New();
+    gImageView3.SetProperty(Toolkit::ImageView::Property::IMAGE, map1);
+    gImageView3.ResourceReadySignal().Connect(&OnResourceReadySignal06);
+
+    Property::Map map2;
+    map2[Toolkit::ImageVisual::Property::URL] = TEST_IMAGE_2;
+    map2[Toolkit::ImageVisual::Property::ALPHA_MASK_URL] = TEST_BROKEN_IMAGE_S;
+    gImageView4 = ImageView::New();
+    gImageView4.SetProperty(Toolkit::ImageView::Property::IMAGE, map2);
+    gImageView4.ResourceReadySignal().Connect(&OnResourceReadySignal06);
+
+    if(control == gImageView1)
+    {
+      gResourceReadySignal06ComesOrder = 1;
+    }
+    else
+    {
+      gResourceReadySignal06ComesOrder = 2;
+    }
+  }
+  if(gResourceReadySignalCounter == 2)
+  {
+    if(gResourceReadySignal06ComesOrder == 1 && control == gImageView2)
+    {
+      // Scene off first one.
+      gImageView1.Unparent();
+
+      // Scene off second one.
+      gImageView2.Unparent();
+    }
+    else if(gResourceReadySignal06ComesOrder == 2 && control == gImageView1)
+    {
+      // Scene off first one.
+      gImageView2.Unparent();
+
+      // Scene off second one.
+      gImageView1.Unparent();
+    }
+    else
+    {
+      // We can't check that this utc fail case. just pass always when we come here.
+      gResourceReadySignal06ComesOrder = -1;
+    }
+
+    // If we don't seperate index of FreeList area
+    // and if we don't queue remove during obversing,
+    // cache index become something invalid data.
+    // In this case, some strange observer can be called.
+    // For example, gImageView4.LoadComplete will be called.
+  }
+}
+
 } // namespace
 
 int UtcDaliImageViewSetImageOnResourceReadySignal01(void)
@@ -3887,3 +3956,82 @@ int UtcDaliImageViewSetImageOnResourceReadySignal05(void)
 
   END_TEST;
 }
+int UtcDaliImageViewSetImageOnResourceReadySignal06(void)
+{
+  tet_infoline("Test texturemanager's remove image & mask queue works well within signal handler.");
+
+  ToolkitTestApplication application;
+
+  gResourceReadySignalCounter      = 0;
+  gResourceReadySignal06ComesOrder = 0;
+
+  Property::Map map;
+  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.
+  gImageView1.SetProperty(Toolkit::ImageView::Property::IMAGE, map);
+  gImageView1.ResourceReadySignal().Connect(&OnResourceReadySignal06);
+  application.GetScene().Add(gImageView1);
+
+  gImageView2 = ImageView::New(); // request invalid image, to make loading failed fast.
+  gImageView2.SetProperty(Toolkit::ImageView::Property::IMAGE, map);
+  gImageView2.ResourceReadySignal().Connect(&OnResourceReadySignal06);
+  application.GetScene().Add(gImageView2);
+
+  application.SendNotification();
+  application.Render();
+
+  tet_infoline("Try to load 2 invalid image");
+
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+  DALI_TEST_EQUALS(gResourceReadySignalCounter, 2, TEST_LOCATION);
+
+  tet_infoline("load done");
+
+  // We can test this UTC only if gImageView1 and gImageView2 loaded done.
+  if(gResourceReadySignal06ComesOrder == -1)
+  {
+    tet_infoline("Bad news.. gImageView3 or gImageView4 loaded faster than others. just skip this UTC");
+  }
+  else
+  {
+    // gImageView3 and gImageView4 load must not be successed yet.
+    DALI_TEST_EQUALS(gImageView3.GetRendererCount(), 0u, TEST_LOCATION);
+    DALI_TEST_EQUALS(gImageView4.GetRendererCount(), 0u, TEST_LOCATION);
+
+    application.GetScene().Add(gImageView3);
+    application.GetScene().Add(gImageView4);
+    application.SendNotification();
+    application.Render();
+
+    tet_infoline("Try to load 2 valid image");
+
+    DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+    DALI_TEST_EQUALS(gResourceReadySignalCounter, 2, TEST_LOCATION);
+
+    tet_infoline("load done");
+  }
+  END_TEST;
+}
+
+int UtcDaliImageViewUseSameUrlWithAnimatedImageVisual(void)
+{
+  tet_infoline("Test multiple views with same image in animated image visual");
+  ToolkitTestApplication application;
+
+  gImageView1 = ImageView::New(TEST_WEBP_FILE_NAME);
+  application.GetScene().Add(gImageView1);
+
+  tet_infoline("Remove imageView and Create new imageView with same url");
+  application.GetScene().Remove(gImageView1);
+  gImageView2 = ImageView::New(TEST_WEBP_FILE_NAME);
+  application.GetScene().Add(gImageView2);
+
+  application.SendNotification();
+  application.Render();
+
+  tet_infoline("Check the ImageView load image successfully");
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+  END_TEST;
+}
index 2bfef0a..1fcd10d 100644 (file)
@@ -2402,9 +2402,9 @@ int UtcDaliImageVisualReleasePolicy08(void)
   DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION);
   textureTrace.Reset();
 
-  // Ensure TextureSet is same after detach/attach on stage when texture used the DESTROYED release policy
-  // 1. Get TextureSet
-  TextureSet textureSetBefore = actor.GetRendererAt(0u).GetTextures();
+  // Ensure Texture is same after detach/attach on stage when texture used the DESTROYED release policy
+  // 1. Get Texture
+  Texture textureBefore = actor.GetRendererAt(0u).GetTextures().GetTexture(0u);
 
   // 2.Remove actor from stage. In this case, renderer also is deleted.
   tet_infoline("Remove actor from stage");
@@ -2427,12 +2427,12 @@ int UtcDaliImageVisualReleasePolicy08(void)
   DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 0, TEST_LOCATION);
   textureTrace.Reset();
 
-  // 4.Compare Texture with before and after. textureSet need to be same because release policy is the DESTROYED.
-  tet_infoline("Ensure a textureSet is not deleted because it is used the DESTROYED release policy");
-  TextureSet textureSetAfter = actor.GetRendererAt(0u).GetTextures();
-  DALI_TEST_CHECK(textureSetBefore == textureSetAfter);
-  textureSetBefore.Reset();
-  textureSetAfter.Reset();
+  // 4.Compare Texture with before and after. texture need to be same because release policy is the DESTROYED.
+  tet_infoline("Ensure a texture is not deleted because it is used the DESTROYED release policy");
+  Texture textureAfter = actor.GetRendererAt(0u).GetTextures().GetTexture(0u);
+  DALI_TEST_CHECK(textureBefore == textureAfter);
+  textureBefore.Reset();
+  textureAfter.Reset();
 
   dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL);
   DALI_TEST_CHECK(actor.GetRendererCount() == 0u);
index c43334e..659dd5a 100644 (file)
@@ -360,7 +360,7 @@ void SceneView::UpdateRenderTask()
 
         // create offscreen buffer of new size to render our child actors to
         mTexture      = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, unsigned(size.width), unsigned(size.height));
-        mRenderTarget = FrameBuffer::New(size.width, size.height, FrameBuffer::Attachment::DEPTH);
+        mRenderTarget = FrameBuffer::New(size.width, size.height, FrameBuffer::Attachment::DEPTH_STENCIL);
         mRenderTarget.AttachColorTexture(mTexture);
         Dali::Toolkit::ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(mRenderTarget, 0u);
 
index 24a8ea2..c0e7ac1 100644 (file)
@@ -167,22 +167,20 @@ TextureCacheManager::LoadState TextureCacheManager::GetTextureStateInternal(cons
   return loadState;
 }
 
-TextureSet TextureCacheManager::GetTextureSet(const TextureCacheManager::TextureId& textureId)
+Texture TextureCacheManager::GetTexture(const TextureCacheManager::TextureId& textureId, uint32_t textureIndex)
 {
-  TextureSet        textureSet; // empty handle
-  TextureCacheIndex cacheIndex = static_cast<TextureCacheIndex>(mTextureIdConverter[static_cast<std::uint32_t>(textureId)]);
+  Texture        texture; // empty handle
+  TextureCacheIndex cacheIndex = GetCacheIndexFromId(textureId);
 
   switch(static_cast<TextureCacheIndexType>(cacheIndex.detailValue.type))
   {
     case TextureCacheIndexType::TEXTURE_CACHE_INDEX_TYPE_LOCAL:
     {
       TextureInfo& cachedTextureInfo(mTextureInfoContainer[cacheIndex.GetIndex()]);
-      textureSet = cachedTextureInfo.textureSet;
-      break;
-    }
-    case TextureCacheIndexType::TEXTURE_CACHE_INDEX_TYPE_TEXTURE:
-    {
-      textureSet = mExternalTextures[cacheIndex.GetIndex()].textureSet;
+      if(textureIndex < static_cast<uint32_t>(cachedTextureInfo.textures.size()))
+      {
+        texture = cachedTextureInfo.textures[textureIndex];
+      }
       break;
     }
     default:
@@ -191,7 +189,7 @@ TextureSet TextureCacheManager::GetTextureSet(const TextureCacheManager::Texture
     }
   }
 
-  return textureSet;
+  return texture;
 }
 
 TextureSet TextureCacheManager::GetExternalTextureSet(const TextureCacheManager::TextureId& textureId)
@@ -645,61 +643,55 @@ TextureCacheManager::TextureCacheIndex TextureCacheManager::AppendCache(const Te
   return cacheIndex;
 }
 
-void TextureCacheManager::RemoveCache(const TextureCacheManager::TextureId& textureId)
+void TextureCacheManager::RemoveCache(TextureCacheManager::TextureInfo& textureInfo)
 {
-  TextureCacheIndex textureInfoIndex = GetCacheIndexFromId(textureId);
-
+  TextureCacheIndex textureInfoIndex = GetCacheIndexFromId(textureInfo.textureId);
   bool removeTextureInfo = false;
 
-  if(textureInfoIndex != INVALID_CACHE_INDEX)
-  {
-    TextureInfo& textureInfo(mTextureInfoContainer[textureInfoIndex.GetIndex()]);
+  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);
 
-    DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureCacheManager::Remove(textureId:%d) url:%s\n  cacheIdx:%d loadState:%s reference count = %d\n", textureId, textureInfo.url.GetUrl().c_str(), textureInfoIndex.GetIndex(), GET_LOAD_STATE_STRING(textureInfo.loadState), textureInfo.referenceCount);
+  // Decrement the reference count and check if this is the last user of this Texture.
+  if(--textureInfo.referenceCount <= 0)
+  {
+    // This is the last remove for this Texture.
+    textureInfo.referenceCount = 0;
 
-    // Decrement the reference count and check if this is the last user of this Texture.
-    if(--textureInfo.referenceCount <= 0)
+    // If loaded, we can remove the TextureInfo and the Atlas (if atlased).
+    if(textureInfo.loadState == LoadState::UPLOADED)
     {
-      // This is the last remove for this Texture.
-      textureInfo.referenceCount = 0;
-
-      // If loaded, we can remove the TextureInfo and the Atlas (if atlased).
-      if(textureInfo.loadState == LoadState::UPLOADED)
-      {
-        if(textureInfo.atlas)
-        {
-          textureInfo.atlas.Remove(textureInfo.atlasRect);
-        }
-        removeTextureInfo = true;
-      }
-      else if(textureInfo.loadState == LoadState::LOADING || 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::CANCELLED;
-      }
-      else
+      if(textureInfo.atlas)
       {
-        // In other states, we are not waiting for a load so we are safe to remove the TextureInfo data.
-        removeTextureInfo = true;
+        textureInfo.atlas.Remove(textureInfo.atlasRect);
       }
+      removeTextureInfo = true;
+    }
+    else if(textureInfo.loadState == LoadState::LOADING || 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::CANCELLED;
+    }
+    else
+    {
+      // In other states, we are not waiting for a load so we are safe to remove the TextureInfo data.
+      removeTextureInfo = true;
+    }
 
-      // If the state allows us to remove the TextureInfo data, we do so.
-      if(removeTextureInfo)
+    // If the state allows us to remove the TextureInfo data, we do so.
+    if(removeTextureInfo)
+    {
+      // If url location is BUFFER, decrease reference count of EncodedImageBuffer.
+      if(textureInfo.url.IsBufferResource())
       {
-        // If url location is BUFFER, decrease reference count of EncodedImageBuffer.
-        if(textureInfo.url.IsBufferResource())
-        {
-          RemoveEncodedImageBuffer(textureInfo.url.GetUrl());
-        }
+        RemoveEncodedImageBuffer(textureInfo.url.GetUrl());
+      }
 
-        // Permanently remove the textureInfo struct.
+      // Permanently remove the textureInfo struct.
 
-        // Step 1. remove current textureId information in mTextureHashContainer.
-        RemoveHashId(textureInfo.hash, textureId);
-        // Step 2. make textureId is not using anymore. After this job, we can reuse textureId.
-        mTextureIdConverter.Remove(textureId);
-      }
+      // Step 1. remove current textureId information in mTextureHashContainer.
+      RemoveHashId(textureInfo.hash, textureInfo.textureId);
+      // Step 2. make textureId is not using anymore. After this job, we can reuse textureId.
+      mTextureIdConverter.Remove(textureInfo.textureId);
     }
   }
 
index fb7dfd7..c1f1355 100644 (file)
@@ -102,7 +102,7 @@ public:
   /**
    * @brief Get the current state of a texture
    * @note This API doesn't consider encodedimagebuffer.
-   * @param[in] textureId The texture id to query
+   * @param[in] textureId The texture id to query.defaul value is 0.
    * @return The loading state if the texture is valid, or NOT_STARTED if the textureId
    * is not valid.
    */
@@ -120,9 +120,10 @@ public:
   /**
    * @brief Get the associated texture set if the texture id is valid
    * @param[in] textureId The texture Id to look up
-   * @return the associated texture set, or an empty handle if textureId is not valid
+   * @param[in] textureIndex The texture index to query
+   * @return the associated texture, or an empty handle if textureId is not valid
    */
-  TextureSet GetTextureSet(const TextureCacheManager::TextureId& textureId);
+  Texture GetTexture(const TextureCacheManager::TextureId& textureId, uint32_t textureIndex = 0);
 
   /**
    * @brief Get the external texture set if the texture id is valid
@@ -269,9 +270,9 @@ public:
    * 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 at Cache.
+   * @param[in] textureInfo TextureInfo that want to cache in container.
    */
-  void RemoveCache(const TextureCacheManager::TextureId& textureId);
+  void RemoveCache(TextureCacheManager::TextureInfo& textureInfo);
 
 public:
   /**
index e23ee49..0c89aad 100644 (file)
@@ -37,6 +37,9 @@ 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 NUMBER_OF_LOCAL_LOADER_THREADS_ENV  = "DALI_TEXTURE_LOCAL_THREADS";
 constexpr auto NUMBER_OF_REMOTE_LOADER_THREADS_ENV = "DALI_TEXTURE_REMOTE_THREADS";
 constexpr auto LOAD_IMAGE_YUV_PLANES_ENV           = "DALI_LOAD_IMAGE_YUV_PLANES";
@@ -133,7 +136,7 @@ TextureManager::TextureManager()
   mLifecycleObservers(),
   mLoadQueue(),
   mRemoveQueue(),
-  mQueueLoadFlag(false),
+  mLoadingQueueTextureId(INVALID_TEXTURE_ID),
   mLoadYuvPlanes(NeedToLoadYuvPlanes())
 {
   // Initialize the AddOn
@@ -155,8 +158,6 @@ TextureSet TextureManager::LoadAnimatedImageTexture(
   TextureManager::TextureId&      textureId,
   MaskingDataPointer&             maskInfo,
   const Dali::SamplingMode::Type& samplingMode,
-  const Dali::WrapMode::Type&     wrapModeU,
-  const Dali::WrapMode::Type&     wrapModeV,
   const bool&                     synchronousLoading,
   TextureUploadObserver*          textureObserver,
   TextureManager::MultiplyOnLoad& preMultiplyOnLoad)
@@ -210,10 +211,10 @@ TextureSet TextureManager::LoadAnimatedImageTexture(
         Texture texture = Texture::New(Dali::TextureType::TEXTURE_2D, pixelData.GetPixelFormat(), pixelData.GetWidth(), pixelData.GetHeight());
         texture.Upload(pixelData);
         textureSet = TextureSet::New();
-        textureSet.SetTexture(0u, texture);
+        textureSet.SetTexture(TEXTURE_INDEX, texture);
         if(maskTexture)
         {
-          textureSet.SetTexture(1u, maskTexture);
+          textureSet.SetTexture(MASK_TEXTURE_INDEX, maskTexture);
         }
       }
     }
@@ -244,13 +245,6 @@ TextureSet TextureManager::LoadAnimatedImageTexture(
     }
   }
 
-  if(textureSet)
-  {
-    Sampler sampler = Sampler::New();
-    sampler.SetWrapMode(wrapModeU, wrapModeV);
-    textureSet.SetSampler(0u, sampler);
-  }
-
   return textureSet;
 }
 
@@ -307,8 +301,6 @@ TextureSet TextureManager::LoadTexture(
   Dali::ImageDimensions&              textureRectSize,
   bool&                               atlasingStatus,
   bool&                               loadingStatus,
-  const Dali::WrapMode::Type&         wrapModeU,
-  const Dali::WrapMode::Type&         wrapModeV,
   TextureUploadObserver*              textureObserver,
   AtlasUploadObserver*                atlasObserver,
   ImageAtlasManagerPtr                imageAtlasManager,
@@ -444,7 +436,7 @@ TextureSet TextureManager::LoadTexture(
         if(loadState == TextureManager::LoadState::UPLOADED)
         {
           // LoadComplete has already been called - keep the same texture set
-          textureSet = mTextureCacheManager.GetTextureSet(textureId);
+          textureSet = GetTextureSet(textureId);
         }
 
         // If we are loading the texture, or waiting for the ready signal handler to complete, inform
@@ -454,7 +446,7 @@ TextureSet TextureManager::LoadTexture(
                          loadState == TextureManager::LoadState::MASK_APPLYING ||
                          loadState == TextureManager::LoadState::MASK_APPLIED ||
                          loadState == TextureManager::LoadState::NOT_STARTED ||
-                         mQueueLoadFlag);
+                         mLoadingQueueTextureId != INVALID_TEXTURE_ID);
       }
       else
       {
@@ -463,13 +455,6 @@ TextureSet TextureManager::LoadTexture(
     }
   }
 
-  if(!atlasingStatus && textureSet)
-  {
-    Sampler sampler = Sampler::New();
-    sampler.SetWrapMode(wrapModeU, wrapModeV);
-    textureSet.SetSampler(0u, sampler);
-  }
-
   if(synchronousLoading)
   {
     loadingStatus = false;
@@ -683,10 +668,9 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
           {
             if(mTextureCacheManager[maskCacheIndex].storageType == StorageType::KEEP_TEXTURE)
             {
-              TextureSet maskTextures = mTextureCacheManager[maskCacheIndex].textureSet;
-              if(maskTextures && maskTextures.GetTextureCount())
+              if(!mTextureCacheManager[maskCacheIndex].textures.empty())
               {
-                maskTexture = maskTextures.GetTexture(0u);
+                maskTexture = mTextureCacheManager[maskCacheIndex].textures[0];
               }
             }
             else if(mTextureCacheManager[maskCacheIndex].storageType == StorageType::KEEP_PIXEL_BUFFER)
@@ -711,13 +695,10 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
 
         // Upload texture
         UploadTextures(pixelBuffers, textureInfo);
-        if(maskTexture && textureInfo.textureSet)
-        {
-          textureInfo.textureSet.SetTexture(1u, maskTexture);
-        }
       }
     }
   }
+
   return textureId;
 }
 
@@ -725,15 +706,60 @@ void TextureManager::Remove(const TextureManager::TextureId& textureId, TextureU
 {
   if(textureId != INVALID_TEXTURE_ID)
   {
-    if(mQueueLoadFlag)
-    {
-      // Remove textureId after NotifyObserver finished
-      mRemoveQueue.PushBack(textureId);
-    }
-    else
+    TextureCacheIndex textureCacheIndex = mTextureCacheManager.GetCacheIndexFromId(textureId);
+    if(textureCacheIndex != INVALID_CACHE_INDEX)
     {
-      // Remove textureId in CacheManager.
-      mTextureCacheManager.RemoveCache(textureId);
+      TextureManager::TextureId maskTextureId = INVALID_TEXTURE_ID;
+      TextureInfo& textureInfo(mTextureCacheManager[textureCacheIndex]);
+      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)
+        {
+          queueObserver = observer;
+        }
+
+        // Remove textureId after NotifyObserver finished
+        if(maskTextureId != INVALID_TEXTURE_ID)
+        {
+          if(textureInfo.loadState != LoadState::CANCELLED)
+          {
+            mRemoveQueue.PushBack(QueueElement(maskTextureId, nullptr));
+          }
+        }
+        mRemoveQueue.PushBack(QueueElement(textureId, queueObserver));
+      }
+      else
+      {
+        // Remove its observer
+        RemoveTextureObserver(textureInfo, observer);
+
+        // Remove maskTextureId in CacheManager
+        if(maskTextureId != INVALID_TEXTURE_ID)
+        {
+          TextureCacheIndex maskCacheIndex = mTextureCacheManager.GetCacheIndexFromId(maskTextureId);
+          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);
+            }
+          }
+        }
+
+        // Remove textureId in CacheManager
+        mTextureCacheManager.RemoveCache(textureInfo);
+      }
     }
 
     if(observer)
@@ -818,7 +844,7 @@ void TextureManager::LoadOrQueueTexture(TextureManager::TextureInfo& textureInfo
     case LoadState::NOT_STARTED:
     case LoadState::LOAD_FAILED:
     {
-      if(mQueueLoadFlag)
+      if(mLoadingQueueTextureId != INVALID_TEXTURE_ID)
       {
         QueueLoadTexture(textureInfo, observer);
       }
@@ -830,7 +856,7 @@ void TextureManager::LoadOrQueueTexture(TextureManager::TextureInfo& textureInfo
     }
     case LoadState::UPLOADED:
     {
-      if(mQueueLoadFlag)
+      if(mLoadingQueueTextureId != INVALID_TEXTURE_ID)
       {
         QueueLoadTexture(textureInfo, observer);
       }
@@ -857,7 +883,7 @@ void TextureManager::LoadOrQueueTexture(TextureManager::TextureInfo& textureInfo
 void TextureManager::QueueLoadTexture(const TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer)
 {
   const auto& textureId = textureInfo.textureId;
-  mLoadQueue.PushBack(LoadQueueElement(textureId, observer));
+  mLoadQueue.PushBack(QueueElement(textureId, observer));
 
   observer->DestructionSignal().Connect(this, &TextureManager::ObserverDestroyed);
 }
@@ -919,9 +945,16 @@ void TextureManager::ProcessLoadQueue()
 
 void TextureManager::ProcessRemoveQueue()
 {
-  for(const auto& textureId : mRemoveQueue)
+  TextureCacheIndex textureCacheIndex = INVALID_CACHE_INDEX;
+  for(auto&& element : mRemoveQueue)
   {
-    mTextureCacheManager.RemoveCache(textureId);
+    textureCacheIndex = mTextureCacheManager.GetCacheIndexFromId(element.mTextureId);
+    if(textureCacheIndex != INVALID_CACHE_INDEX)
+    {
+      TextureInfo& textureInfo(mTextureCacheManager[textureCacheIndex]);
+      RemoveTextureObserver(textureInfo, element.mObserver);
+      mTextureCacheManager.RemoveCache(textureInfo);
+    }
   }
   mRemoveQueue.Clear();
 }
@@ -1014,11 +1047,7 @@ void TextureManager::PostLoad(TextureManager::TextureInfo& textureInfo, std::vec
                   {
                     // Upload image texture. textureInfo.loadState will be UPLOADED.
                     UploadTextures(pixelBuffers, textureInfo);
-                    if(maskTextureInfo.textureSet.GetTextureCount() > 0u)
-                    {
-                      Texture maskTexture = maskTextureInfo.textureSet.GetTexture(0u);
-                      textureInfo.textureSet.SetTexture(1u, maskTexture);
-                    }
+
                     // notify mask texture set.
                     NotifyObservers(textureInfo, true);
                   }
@@ -1123,11 +1152,7 @@ void TextureManager::CheckForWaitingTexture(TextureManager::TextureInfo& maskTex
           std::vector<Devel::PixelBuffer> pixelBuffers;
           pixelBuffers.push_back(textureInfo.pixelBuffer);
           UploadTextures(pixelBuffers, textureInfo);
-          if(maskTextureInfo.textureSet.GetTextureCount() > 0u)
-          {
-            Texture maskTexture = maskTextureInfo.textureSet.GetTexture(0u);
-            textureInfo.textureSet.SetTexture(1u, maskTexture);
-          }
+
           // notify mask texture set.
           NotifyObservers(textureInfo, true);
         }
@@ -1180,19 +1205,15 @@ void TextureManager::UploadTextures(std::vector<Devel::PixelBuffer>& pixelBuffer
       renderingAddOn.CreateGeometry(textureInfo.textureId, pixelBuffers[0]);
     }
 
-    if(!textureInfo.textureSet)
-    {
-      textureInfo.textureSet = TextureSet::New();
-    }
+    // Remove previous textures and insert new textures
+    textureInfo.textures.clear();
 
-    uint32_t index = 0;
     for(auto&& pixelBuffer : pixelBuffers)
     {
       Texture texture = Texture::New(Dali::TextureType::TEXTURE_2D, pixelBuffer.GetPixelFormat(), pixelBuffer.GetWidth(), pixelBuffer.GetHeight());
-
       PixelData pixelData = Devel::PixelBuffer::Convert(pixelBuffer);
       texture.Upload(pixelData);
-      textureInfo.textureSet.SetTexture(index++, texture);
+      textureInfo.textures.push_back(texture);
     }
   }
 
@@ -1222,7 +1243,7 @@ void TextureManager::NotifyObservers(TextureManager::TextureInfo& textureInfo, c
     info->animatedImageLoading.Reset();
   }
 
-  mQueueLoadFlag = true;
+  mLoadingQueueTextureId = textureId;
 
   // Reverse observer list that we can pop_back the observer.
   std::reverse(info->observerList.Begin(), info->observerList.End());
@@ -1258,7 +1279,7 @@ void TextureManager::NotifyObservers(TextureManager::TextureInfo& textureInfo, c
     info = &mTextureCacheManager[textureInfoIndex];
   }
 
-  mQueueLoadFlag = false;
+  mLoadingQueueTextureId = INVALID_TEXTURE_ID;
   ProcessLoadQueue();
   ProcessRemoveQueue();
 
@@ -1309,13 +1330,90 @@ void TextureManager::EmitLoadComplete(TextureUploadObserver* observer, TextureMa
   {
     observer->LoadComplete(success, TextureUploadObserver::TextureInformation(TextureUploadObserver::ReturnType::PIXEL_BUFFER, textureInfo.pixelBuffer, textureInfo.url.GetUrl(), textureInfo.preMultiplied));
   }
-  else if(textureInfo.isAnimatedImageFormat)
+  else
+  {
+    TextureSet textureSet = GetTextureSet(textureInfo);
+    if(textureInfo.isAnimatedImageFormat)
+    {
+      observer->LoadComplete(success, TextureUploadObserver::TextureInformation(TextureUploadObserver::ReturnType::ANIMATED_IMAGE_TEXTURE, textureInfo.textureId, textureSet, textureInfo.frameCount, textureInfo.frameInterval));
+    }
+    else
+    {
+      observer->LoadComplete(success, TextureUploadObserver::TextureInformation(TextureUploadObserver::ReturnType::TEXTURE, textureInfo.textureId, textureSet, (textureInfo.useAtlas == UseAtlas::USE_ATLAS) ? true : false, textureInfo.atlasRect, textureInfo.preMultiplied));
+    }
+  }
+}
+
+TextureSet TextureManager::GetTextureSet(const TextureManager::TextureId& textureId)
+{
+  TextureSet textureSet;
+  TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId);
+  if(loadState == TextureManager::LoadState::UPLOADED)
   {
-    observer->LoadComplete(success, TextureUploadObserver::TextureInformation(TextureUploadObserver::ReturnType::ANIMATED_IMAGE_TEXTURE, textureInfo.textureId, textureInfo.frameCount, textureInfo.frameInterval));
+    // LoadComplete has already been called - keep the same texture set
+    TextureCacheIndex textureCacheIndex = mTextureCacheManager.GetCacheIndexFromId(textureId);
+    if(textureCacheIndex != INVALID_CACHE_INDEX)
+    {
+      TextureInfo& textureInfo(mTextureCacheManager[textureCacheIndex]);
+      textureSet = GetTextureSet(textureInfo);
+    }
   }
   else
   {
-    observer->LoadComplete(success, TextureUploadObserver::TextureInformation(TextureUploadObserver::ReturnType::TEXTURE, textureInfo.textureId, textureInfo.textureSet, (textureInfo.useAtlas == UseAtlas::USE_ATLAS) ? true : false, textureInfo.atlasRect, textureInfo.preMultiplied));
+    DALI_LOG_ERROR("GetTextureSet is failed. texture is not uploaded \n");
+  }
+  return textureSet;
+}
+
+TextureSet TextureManager::GetTextureSet(const TextureManager::TextureInfo& textureInfo)
+{
+  TextureSet textureSet;
+
+  // LoadComplete has already been called - keep the same texture set
+  textureSet = TextureSet::New();
+  if(!textureInfo.textures.empty())
+  {
+    if(textureInfo.textures.size() > 1) // For YUV case
+    {
+      uint32_t index = 0u;
+      for(auto&& texture : textureInfo.textures)
+      {
+        textureSet.SetTexture(index++, texture);
+      }
+    }
+    else
+    {
+      textureSet.SetTexture(TEXTURE_INDEX, textureInfo.textures[0]);
+      TextureCacheIndex maskCacheIndex = mTextureCacheManager.GetCacheIndexFromId(textureInfo.maskTextureId);
+      if(maskCacheIndex != INVALID_CACHE_INDEX)
+      {
+        TextureInfo& maskTextureInfo(mTextureCacheManager[maskCacheIndex]);
+        if(maskTextureInfo.storageType == StorageType::UPLOAD_TO_TEXTURE || maskTextureInfo.storageType == StorageType::KEEP_TEXTURE)
+        {
+          if(!maskTextureInfo.textures.empty())
+          {
+            textureSet.SetTexture(MASK_TEXTURE_INDEX, maskTextureInfo.textures[0]);
+          }
+        }
+      }
+    }
+  }
+  return textureSet;
+}
+
+void TextureManager::RemoveTextureObserver(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer)
+{
+  // Remove its observer
+  if(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.
+      observer->DestructionSignal().Disconnect(this, &TextureManager::ObserverDestroyed);
+      textureInfo.observerList.Erase(iter);
+    }
   }
 }
 
index 5601052..6b3f1a7 100644 (file)
@@ -120,8 +120,6 @@ public:
    * @param[out] textureId             The textureId of the frame
    * @param[in, out] maskInfo          Mask info structure
    * @param[in]  samplingMode          The SamplingMode to use
-   * @param[in]  wrapModeU             Horizontal Wrap mode
-   * @param[in]  wrapModeV             Vertical Wrap mode
    * @param[in]  synchronousLoading    true if the frame should be loaded synchronously
    * @param[in]  textureObserver       The client object should inherit from this and provide the "LoadCompleted" virtual.
    *                                   This is called when an image load completes (or fails).
@@ -136,8 +134,6 @@ public:
                                       TextureManager::TextureId&      textureId,
                                       MaskingDataPointer&             maskInfo,
                                       const Dali::SamplingMode::Type& samplingMode,
-                                      const Dali::WrapMode::Type&     wrapModeU,
-                                      const Dali::WrapMode::Type&     wrapModeV,
                                       const bool&                     synchronousLoading,
                                       TextureUploadObserver*          textureObserver,
                                       TextureManager::MultiplyOnLoad& preMultiplyOnLoad);
@@ -194,8 +190,6 @@ public:
    *                                  be loaded, and marked successful, but this will be set to false.
    *                                  If atlasing succeeds, this will be set to true.
    * @param[out] loadingStatus        The loading status of the texture
-   * @param[in] wrapModeU             Horizontal Wrap mode
-   * @param[in] wrapModeV             Vertical Wrap mode
    * @param[in] textureObserver       The client object should inherit from this and provide the "LoadCompleted" virtual.
    *                                  This is called when an image load completes (or fails).
    * @param[in] atlasObserver         This is used if the texture is atlased, and will be called instead of
@@ -220,8 +214,6 @@ public:
     Dali::ImageDimensions&              textureRectSize,
     bool&                               atlasingStatus,
     bool&                               loadingStatus,
-    const Dali::WrapMode::Type&         wrapModeU,
-    const Dali::WrapMode::Type&         wrapModeV,
     TextureUploadObserver*              textureObserver,
     AtlasUploadObserver*                atlasObserver,
     ImageAtlasManagerPtr                imageAtlasManager,
@@ -262,6 +254,20 @@ public:
    */
   Geometry GetRenderGeometry(const TextureManager::TextureId& textureId, std::uint32_t& frontElements, std::uint32_t& backElements);
 
+  /**
+   * @brief Returns the textureSet in texture manager.
+   * @param[in] textureId Id of the texture
+   * @return The textureSet in texture manager. These textures include YUV textures or images and masks.
+   */
+  TextureSet GetTextureSet(const TextureManager::TextureId& textureId);
+
+  /**
+   * @brief Returns the textureSet in texture manager.
+   * @param[in] textureInfo the information of the texture
+   * @return The textureSet in texture manager. These textures include YUV textures or images and masks.
+   */
+  TextureSet GetTextureSet(const TextureManager::TextureInfo& textureInfo);
+
 public:
   // API list that need to access TextureCacheManager.
 
@@ -274,11 +280,11 @@ public:
   }
 
   /**
-   * @copydoc TextureCacheManager::GetTextureSet
+   * @copydoc TextureCacheManager::GetTexture
    */
-  inline TextureSet GetTextureSet(const TextureManager::TextureId& textureId)
+  inline Texture GetTexture(const TextureManager::TextureId& textureId)
   {
-    return mTextureCacheManager.GetTextureSet(textureId);
+    return mTextureCacheManager.GetTexture(textureId);
   }
 
   /**
@@ -511,9 +517,9 @@ private:
   /**
    * Structure to hold info about a texture load queued during NotifyObservers
    */
-  struct LoadQueueElement
+  struct QueueElement
   {
-    LoadQueueElement(TextureManager::TextureId textureId, TextureUploadObserver* observer)
+    QueueElement(TextureManager::TextureId textureId, TextureUploadObserver* observer)
     : mTextureId(textureId),
       mObserver(observer)
     {
@@ -606,6 +612,15 @@ private:
    */
   void EmitLoadComplete(TextureUploadObserver* observer, TextureManager::TextureInfo& textureInfo, const bool& success);
 
+
+  /**
+   * @brief Remove observer in textureInfo
+   *
+   * @param textureInfo The struct associated with this Texture.
+   * @param observer The observer wishing to remove.
+   */
+  void RemoveTextureObserver(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer);
+
 public:
   /**
    * @brief Common method to handle loading completion.
@@ -639,11 +654,11 @@ private:                                    // Member Variables:
   RoundRobinContainerView<TextureAsyncLoadingHelper> mAsyncLocalLoaders;  ///< The Asynchronous image loaders used to provide all local async loads
   RoundRobinContainerView<TextureAsyncLoadingHelper> mAsyncRemoteLoaders; ///< The Asynchronous image loaders used to provide all remote async loads
 
-  Dali::Vector<LifecycleObserver*>        mLifecycleObservers; ///< Lifecycle observers of texture manager
-  Dali::Vector<LoadQueueElement>          mLoadQueue;          ///< Queue of textures to load after NotifyObservers
-  Dali::Vector<TextureManager::TextureId> mRemoveQueue;        ///< Queue of textures to remove after NotifyObservers
-  bool                                    mQueueLoadFlag;      ///< Flag that causes Load Textures to be queued.
-  bool                                    mLoadYuvPlanes;      ///< A global flag to specify if the image should be loaded as yuv planes
+  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
 };
 
 } // namespace Internal
index 98c5baa..adffcf9 100644 (file)
@@ -281,7 +281,7 @@ struct TextureInfo
   ObserverListType           observerList;         ///< Container used to store all observer clients of this Texture
   Dali::Toolkit::ImageAtlas  atlas;                ///< The atlas this Texture lays within (if any)
   Dali::Devel::PixelBuffer   pixelBuffer;          ///< The PixelBuffer holding the image data (May be empty after upload)
-  Dali::TextureSet           textureSet;           ///< The TextureSet holding the Texture
+  std::vector<Dali::Texture> textures;             ///< The Textures
   VisualUrl                  url;                  ///< The URL of the image
   Dali::ImageDimensions      desiredSize;          ///< The size requested
   Dali::ImageDimensions      useSize;              ///< The size used
index 1e59c2d..ee8ff1c 100644 (file)
@@ -61,10 +61,10 @@ TextureUploadObserver::TextureInformation::TextureInformation(ReturnType returnT
 {
 }
 
-TextureUploadObserver::TextureInformation::TextureInformation(ReturnType returnType, int32_t textureId, uint32_t frameCount, uint32_t interval)
+TextureUploadObserver::TextureInformation::TextureInformation(ReturnType returnType, int32_t textureId, TextureSet textureSet, uint32_t frameCount, uint32_t interval)
 : returnType(returnType),
   textureId(textureId),
-  textureSet(),
+  textureSet(textureSet),
   useAtlasing(false),
   atlasRect(Vector4::ZERO),
   preMultiplied(false),
index 4180d20..82b6691 100644 (file)
@@ -54,7 +54,7 @@ public:
     TextureInformation(ReturnType returnType, int32_t textureId, TextureSet textureSet, bool useAtlasing, const Vector4& atlasRect, bool preMultiplied);
     TextureInformation(ReturnType returnType, int32_t textureId, TextureSet textureSet, const std::string& url, bool preMultiplied);
     TextureInformation(ReturnType returnType, Devel::PixelBuffer pixelBuffer, const std::string& url, bool preMultiplied);
-    TextureInformation(ReturnType returnType, int32_t textureId, uint32_t frameCount, uint32_t interval);
+    TextureInformation(ReturnType returnType, int32_t textureId, TextureSet textureSet, uint32_t frameCount, uint32_t interval);
 
     TextureInformation();
 
index 97b8d35..7cb6ce3 100644 (file)
@@ -132,16 +132,21 @@ void FixedImageCache::LoadBatch()
     Dali::ImageDimensions textureRectSize;
     auto                  preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
 
-    mTextureManager.LoadTexture(
-      url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, mMaskingData, synchronousLoading, mImageUrls[frameIndex].mTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply);
-
+    mTextureManager.LoadTexture(url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, mMaskingData, synchronousLoading, mImageUrls[frameIndex].mTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply);
     mRequestingLoad = false;
   }
 }
 
 TextureSet FixedImageCache::GetFrontTextureSet() const
 {
-  return mTextureManager.GetTextureSet(mImageUrls[mFront].mTextureId);
+  TextureSet textureSet = mTextureManager.GetTextureSet(mImageUrls[mFront].mTextureId);
+  if(textureSet)
+  {
+    Sampler sampler = Sampler::New();
+    sampler.SetWrapMode(Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT);
+    textureSet.SetSampler(0u, sampler);
+  }
+  return textureSet;
 }
 
 void FixedImageCache::CheckFrontFrame(bool wasReady)
@@ -160,13 +165,6 @@ void FixedImageCache::ClearCache()
     {
       mTextureManager.Remove(mImageUrls[i].mTextureId, this);
       mImageUrls[i].mTextureId = TextureManager::INVALID_TEXTURE_ID;
-
-      if(mMaskingData && mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID)
-      {
-        // In the CPU alpha masking, each frame increases reference count of masking texture.
-        // We should call TextureManager::Remove to decrease reference count when each frame is removed.
-        mTextureManager.Remove(mMaskingData->mAlphaMaskId, this);
-      }
     }
   }
   mReadyFlags.clear();
index b8a6961..bd6c5a7 100644 (file)
@@ -208,11 +208,15 @@ TextureSet RollingAnimatedImageCache::RequestFrameLoading(uint32_t frameIndex, b
                                                                    loadTextureId,
                                                                    mMaskingData,
                                                                    SamplingMode::BOX_THEN_LINEAR,
-                                                                   mWrapModeU,
-                                                                   mWrapModeV,
                                                                    synchronousLoading,
                                                                    this,
                                                                    preMultiplyOnLoading);
+  if(textureSet)
+  {
+    Sampler sampler = Sampler::New();
+    sampler.SetWrapMode(mWrapModeU, mWrapModeV);
+    textureSet.SetSampler(0u, sampler);
+  }
 
   mTextureIds[frameIndex] = loadTextureId;
 
@@ -260,7 +264,14 @@ TextureSet RollingAnimatedImageCache::GetFrontTextureSet() const
   DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "RollingAnimatedImageCache::GetFrontTextureSet() FrameNumber:%d\n", mQueue[0].mFrameNumber);
 
   TextureManager::TextureId textureId = GetCachedTextureId(0);
-  return mTextureManager.GetTextureSet(textureId);
+  TextureSet textureSet = mTextureManager.GetTextureSet(textureId);
+  if(textureSet)
+  {
+    Sampler sampler = Sampler::New();
+    sampler.SetWrapMode(mWrapModeU, mWrapModeV);
+    textureSet.SetSampler(0u, sampler);
+  }
+  return textureSet;
 }
 
 TextureManager::TextureId RollingAnimatedImageCache::GetCachedTextureId(int index) const
@@ -276,7 +287,6 @@ void RollingAnimatedImageCache::PopFrontCache()
 
   if(mMaskingData && mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID)
   {
-    mTextureManager.Remove(mMaskingData->mAlphaMaskId, this);
     if(mQueue.IsEmpty())
     {
       mMaskingData->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID;
@@ -332,15 +342,14 @@ void RollingAnimatedImageCache::LoadComplete(bool loadSuccess, TextureInformatio
   DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "AnimatedImageVisual::LoadComplete(textureId:%d) start\n", textureInformation.textureId);
   LOG_CACHE;
 
-  TextureSet textureSet = mTextureManager.GetTextureSet(textureInformation.textureId);
-  if(textureSet)
+  if(textureInformation.textureSet)
   {
     Sampler sampler = Sampler::New();
     sampler.SetWrapMode(mWrapModeU, mWrapModeV);
-    textureSet.SetSampler(0u, sampler);
+    textureInformation.textureSet.SetSampler(0u, sampler);
   }
 
-  MakeFrameReady(loadSuccess, textureSet, textureInformation.interval);
+  MakeFrameReady(loadSuccess, textureInformation.textureSet, textureInformation.interval);
 
   if(loadSuccess)
   {
index 7a84f5b..390af53 100644 (file)
@@ -168,7 +168,7 @@ void RollingImageCache::LoadBatch(uint32_t frameIndex)
 
     TextureManager::TextureId loadTextureId = TextureManager::INVALID_TEXTURE_ID;
     TextureSet                textureSet    = mTextureManager.LoadTexture(
-      url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, mMaskingData, synchronousLoading, loadTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply);
+      url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, mMaskingData, synchronousLoading, loadTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply);
     mImageUrls[imageFrame.mUrlIndex].mTextureId = loadTextureId;
 
     mRequestingLoad = false;
@@ -181,7 +181,14 @@ void RollingImageCache::LoadBatch(uint32_t frameIndex)
 TextureSet RollingImageCache::GetFrontTextureSet() const
 {
   TextureManager::TextureId textureId = GetCachedTextureId(0);
-  return mTextureManager.GetTextureSet(textureId);
+  TextureSet textureSet = mTextureManager.GetTextureSet(textureId);
+  if(textureSet)
+  {
+    Sampler sampler = Sampler::New();
+    sampler.SetWrapMode(Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT);
+    textureSet.SetSampler(0u, sampler);
+  }
+  return textureSet;
 }
 
 TextureManager::TextureId RollingImageCache::GetCachedTextureId(int index) const
@@ -197,7 +204,6 @@ void RollingImageCache::PopFrontCache()
 
   if(mMaskingData && mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID)
   {
-    mTextureManager.Remove(mMaskingData->mAlphaMaskId, this);
     if(mQueue.IsEmpty())
     {
       mMaskingData->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID;
@@ -244,7 +250,13 @@ void RollingImageCache::LoadComplete(bool loadSuccess, TextureInformation textur
 
     if(!frontFrameReady && IsFrontReady())
     {
-      mObserver.FrameReady(mTextureManager.GetTextureSet(textureInformation.textureId), mInterval);
+      if(textureInformation.textureSet)
+      {
+        Sampler sampler = Sampler::New();
+        sampler.SetWrapMode(Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT);
+        textureInformation.textureSet.SetSampler(0u, sampler);
+      }
+      mObserver.FrameReady(textureInformation.textureSet, mInterval);
     }
   }
   else
index 87d6ea6..da12c4f 100644 (file)
@@ -180,18 +180,6 @@ ImageVisual::~ImageVisual()
 {
   if(Stage::IsInstalled())
   {
-    if(mMaskingData)
-    {
-      // TextureManager could have been deleted before the actor that contains this
-      // ImageVisual is destroyed (e.g. due to stage shutdown). Ensure the stage
-      // is still valid before accessing texture manager.
-      if(mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID)
-      {
-        TextureManager& textureManager = mFactoryCache.GetTextureManager();
-        textureManager.Remove(mMaskingData->mAlphaMaskId, this);
-      }
-    }
-
     if(mImageUrl.IsValid())
     {
       // Decrease reference count of External Resources :
@@ -618,7 +606,7 @@ void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& te
   bool synchronousLoading = IsSynchronousLoadingRequired();
   bool loadingStatus;
 
-  textures = textureManager.LoadTexture(mImageUrl, mDesiredSize, mFittingMode, mSamplingMode, mMaskingData, synchronousLoading, mTextureId, atlasRect, mAtlasRectSize, atlasing, loadingStatus, mWrapModeU, mWrapModeV, textureObserver, atlasUploadObserver, atlasManager, mOrientationCorrection, forceReload, preMultiplyOnLoad);
+  textures = textureManager.LoadTexture(mImageUrl, mDesiredSize, mFittingMode, mSamplingMode, mMaskingData, synchronousLoading, mTextureId, atlasRect, mAtlasRectSize, atlasing, loadingStatus, textureObserver, atlasUploadObserver, atlasManager, mOrientationCorrection, forceReload, preMultiplyOnLoad);
 
   if(textures)
   {
@@ -632,6 +620,12 @@ void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& te
     }
 
     EnablePreMultipliedAlpha(preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD);
+    if(!atlasing)
+    {
+      Sampler sampler = Sampler::New();
+      sampler.SetWrapMode(mWrapModeU, mWrapModeV);
+      textures.SetSampler(0u, sampler);
+    }
   }
   else if(synchronousLoading)
   {
@@ -676,6 +670,12 @@ void ImageVisual::InitializeRenderer()
     else
     {
       mTextures = mFactoryCache.GetTextureManager().GetTextureSet(mTextureId);
+      if(!(mImpl->mFlags & Visual::Base::Impl::IS_ATLASING_APPLIED) && mTextures)
+      {
+        Sampler sampler = Sampler::New();
+        sampler.SetWrapMode(mWrapModeU, mWrapModeV);
+        mTextures.SetSampler(0u, sampler);
+      }
     }
   }
 
@@ -912,9 +912,13 @@ void ImageVisual::LoadComplete(bool loadingSuccess, TextureInformation textureIn
     }
     else
     {
-      Sampler sampler = Sampler::New();
-      sampler.SetWrapMode(mWrapModeU, mWrapModeV);
-      textureInformation.textureSet.SetSampler(0u, sampler);
+      if(!textureInformation.useAtlasing)
+      {
+        Sampler sampler = Sampler::New();
+        sampler.SetWrapMode(mWrapModeU, mWrapModeV);
+        textureInformation.textureSet.SetSampler(0u, sampler);
+      }
+
       mImpl->mRenderer.SetTextures(textureInformation.textureSet);
       ComputeTextureSize();
       CheckMaskTexture();
index f95a796..8b44d99 100644 (file)
@@ -102,7 +102,14 @@ void NPatchVisual::LoadImages()
     bool loadingStatus = false;
 
     // Load the auxiliary image
-    mAuxiliaryTextureSet = textureManager.LoadTexture(mAuxiliaryUrl, Dali::ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, maskingDataPtr, synchronousLoading, mAuxiliaryTextureId, atlasRect, atlasRectSize, atlasing, loadingStatus, WrapMode::DEFAULT, WrapMode::DEFAULT, this, nullptr, imageAtlasManagerPtr, true, TextureManager::ReloadPolicy::CACHED, preMultiplyOnLoad);
+    mAuxiliaryTextureSet = textureManager.LoadTexture(mAuxiliaryUrl, Dali::ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, maskingDataPtr, synchronousLoading, mAuxiliaryTextureId, atlasRect, atlasRectSize, atlasing, loadingStatus, this, nullptr, imageAtlasManagerPtr, true, TextureManager::ReloadPolicy::CACHED, preMultiplyOnLoad);
+
+    if(mAuxiliaryTextureSet)
+    {
+      Sampler sampler = Sampler::New();
+      sampler.SetWrapMode(WrapMode::DEFAULT, WrapMode::DEFAULT);
+      mAuxiliaryTextureSet.SetSampler(0u, sampler);
+    }
 
     // If synchronousLoading is true, we can check the auxiliaryResource's status now.
     if(synchronousLoading)
@@ -599,7 +606,14 @@ void NPatchVisual::LoadComplete(bool loadSuccess, TextureInformation textureInfo
     }
     if(loadSuccess)
     {
-      mAuxiliaryTextureSet     = textureInformation.textureSet;
+      mAuxiliaryTextureSet = textureInformation.textureSet;
+      if(mAuxiliaryTextureSet)
+      {
+        Sampler sampler = Sampler::New();
+        sampler.SetWrapMode(WrapMode::DEFAULT, WrapMode::DEFAULT);
+        mAuxiliaryTextureSet.SetSampler(0u, sampler);
+      }
+
       mAuxiliaryResourceStatus = Toolkit::Visual::ResourceStatus::READY;
     }
     else
index 7639b88..0b2f47d 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 = 38;
+const unsigned int TOOLKIT_MICRO_VERSION = 39;
 const char* const  TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 954e171..753dce7 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    2.1.38
+Version:    2.1.39
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT