Fix a custom shader issue
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / texture-manager-impl.cpp
index a12fae0..1ea95a9 100644 (file)
@@ -83,7 +83,6 @@ Debug::Filter* gTextureManagerLogFilter = Debug::Filter::New( Debug::NoLogging,
 
 const uint32_t      DEFAULT_ATLAS_SIZE( 1024u );                     ///< This size can fit 8 by 8 images of average size 128 * 128
 const Vector4       FULL_ATLAS_RECT( 0.0f, 0.0f, 1.0f, 1.0f );       ///< UV Rectangle that covers the full Texture
-const char * const  BROKEN_IMAGE_URL( DALI_IMAGE_DIR "broken.png" ); ///< URL For the broken image placeholder
 const int           INVALID_INDEX( -1 );                             ///< Invalid index used to represent a non-existant TextureInfo struct
 const int           INVALID_CACHE_INDEX( -1 ); ///< Invalid Cache index
 
@@ -116,18 +115,29 @@ TextureManager::MaskingData::MaskingData()
 TextureManager::TextureManager()
 : mAsyncLocalLoaders( GetNumberOfLocalLoaderThreads(), [&]() { return AsyncLoadingHelper(*this); } ),
   mAsyncRemoteLoaders( GetNumberOfRemoteLoaderThreads(), [&]() { return AsyncLoadingHelper(*this); } ),
+  mExternalTextures(),
+  mLifecycleObservers(),
+  mBrokenImageUrl(""),
   mCurrentTextureId( 0 )
 {
 }
 
+TextureManager::~TextureManager()
+{
+  for( auto iter = mLifecycleObservers.Begin(), endIter = mLifecycleObservers.End(); iter != endIter; ++iter)
+  {
+    (*iter)->TextureManagerDestroyed();
+  }
+}
+
 TextureSet TextureManager::LoadTexture(
-    const VisualUrl& url, Dali::ImageDimensions desiredSize, Dali::FittingMode::Type fittingMode,
-    Dali::SamplingMode::Type samplingMode, const MaskingDataPointer& maskInfo,
-    bool synchronousLoading, TextureManager::TextureId& textureId, Vector4& textureRect,
-    bool& atlasingStatus, bool& loadingStatus, Dali::WrapMode::Type wrapModeU,
-    Dali::WrapMode::Type wrapModeV, TextureUploadObserver* textureObserver,
-    AtlasUploadObserver* atlasObserver, ImageAtlasManagerPtr imageAtlasManager, bool orientationCorrection,
-    TextureManager::ReloadPolicy reloadPolicy, TextureManager::MultiplyOnLoad& preMultiplyOnLoad )
+  const VisualUrl& url, Dali::ImageDimensions desiredSize, Dali::FittingMode::Type fittingMode,
+  Dali::SamplingMode::Type samplingMode, const MaskingDataPointer& maskInfo,
+  bool synchronousLoading, TextureManager::TextureId& textureId, Vector4& textureRect,
+  Dali::ImageDimensions& textureRectSize, bool& atlasingStatus, bool& loadingStatus,
+  Dali::WrapMode::Type wrapModeU, Dali::WrapMode::Type wrapModeV, TextureUploadObserver* textureObserver,
+  AtlasUploadObserver* atlasObserver, ImageAtlasManagerPtr imageAtlasManager, bool orientationCorrection,
+  TextureManager::ReloadPolicy reloadPolicy, TextureManager::MultiplyOnLoad& preMultiplyOnLoad )
 {
   TextureSet textureSet;
 
@@ -168,7 +178,7 @@ TextureSet TextureManager::LoadTexture(
     {
       // use broken image
       textureSet = TextureSet::New();
-      Devel::PixelBuffer pixelBuffer = LoadImageFromFile( BROKEN_IMAGE_URL );
+      Devel::PixelBuffer pixelBuffer = LoadImageFromFile( mBrokenImageUrl );
       if( pixelBuffer )
       {
         PreMultiply( pixelBuffer, preMultiplyOnLoad );
@@ -195,6 +205,11 @@ TextureSet TextureManager::LoadTexture(
         textureSet = TextureSet::New();
         textureSet.SetTexture( 0u, texture );
       }
+      else
+      {
+        textureRectSize.SetWidth(data.GetWidth());
+        textureRectSize.SetHeight(data.GetHeight());
+      }
     }
   }
   else
@@ -202,7 +217,7 @@ TextureSet TextureManager::LoadTexture(
     loadingStatus = true;
     if( atlasingStatus )
     {
-      textureSet = imageAtlasManager->Add( textureRect, url.GetUrl(), desiredSize, fittingMode, true, atlasObserver );
+      textureSet = imageAtlasManager->Add( textureRect, url.GetUrl(), desiredSize, fittingMode, true, atlasObserver);
     }
     if( !textureSet ) // big image, no atlasing or atlasing failed
     {
@@ -235,6 +250,10 @@ TextureSet TextureManager::LoadTexture(
         textureSet = GetTextureSet( textureId );
       }
     }
+    else
+    {
+      textureRectSize = desiredSize;
+    }
   }
 
   if( ! atlasingStatus && textureSet )
@@ -466,13 +485,20 @@ void TextureManager::Remove( const TextureManager::TextureId textureId )
   }
 }
 
-const VisualUrl& TextureManager::GetVisualUrl( TextureId textureId )
+VisualUrl TextureManager::GetVisualUrl( TextureId textureId )
 {
+  VisualUrl visualUrl("");
   int cacheIndex = GetCacheIndexFromId( textureId );
-  DALI_ASSERT_DEBUG( cacheIndex != INVALID_CACHE_INDEX && "TextureId out of range");
 
-  TextureInfo& cachedTextureInfo( mTextureInfoContainer[ cacheIndex ] );
-  return cachedTextureInfo.url;
+  if( cacheIndex != INVALID_CACHE_INDEX )
+  {
+    DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "TextureManager::GetVisualUrl. Using cached texture id=%d, textureId=%d\n",
+                   cacheIndex, textureId );
+
+    TextureInfo& cachedTextureInfo( mTextureInfoContainer[ cacheIndex ] );
+    visualUrl = cachedTextureInfo.url;
+  }
+  return visualUrl;
 }
 
 TextureManager::LoadState TextureManager::GetTextureState( TextureId textureId )
@@ -574,6 +600,31 @@ TextureSet TextureManager::RemoveExternalTexture( const std::string& url )
   return TextureSet();
 }
 
+
+void TextureManager::AddObserver( TextureManager::LifecycleObserver& observer )
+{
+  // make sure an observer doesn't observe the same object twice
+  // otherwise it will get multiple calls to ObjectDestroyed()
+  DALI_ASSERT_DEBUG( mLifecycleObservers.End() == std::find( mLifecycleObservers.Begin(), mLifecycleObservers.End(), &observer));
+  mLifecycleObservers.PushBack( &observer );
+}
+
+void TextureManager::RemoveObserver( TextureManager::LifecycleObserver& observer)
+{
+  // Find the observer...
+  auto endIter =  mLifecycleObservers.End();
+  for( auto iter = mLifecycleObservers.Begin(); iter != endIter; ++iter)
+  {
+    if( (*iter) == &observer)
+    {
+      mLifecycleObservers.Erase( iter );
+      break;
+    }
+  }
+  DALI_ASSERT_DEBUG(endIter != mLifecycleObservers.End());
+}
+
+
 bool TextureManager::LoadTexture( TextureInfo& textureInfo )
 {
   bool success = true;
@@ -730,8 +781,11 @@ void TextureManager::ApplyMask(
   float contentScale, bool cropToMask )
 {
   int maskCacheIndex = GetCacheIndexFromId( maskTextureId );
-  Devel::PixelBuffer maskPixelBuffer = mTextureInfoContainer[maskCacheIndex].pixelBuffer;
-  pixelBuffer.ApplyMask( maskPixelBuffer, contentScale, cropToMask );
+  if( maskCacheIndex != INVALID_CACHE_INDEX )
+  {
+    Devel::PixelBuffer maskPixelBuffer = mTextureInfoContainer[maskCacheIndex].pixelBuffer;
+    pixelBuffer.ApplyMask( maskPixelBuffer, contentScale, cropToMask );
+  }
 }
 
 
@@ -878,8 +932,21 @@ TextureManager::TextureHash TextureManager::GenerateHash(
   {
     // We are not including sizing information, but we still need an extra byte for atlasing.
     hashTarget.resize( urlLength + 1u );
+
     // Add the atlasing to the hash input.
-    hashTarget[ urlLength ] = useAtlas;
+    switch( useAtlas )
+    {
+      case UseAtlas::NO_ATLAS:
+      {
+        hashTarget[ urlLength ] = 'f';
+        break;
+      }
+      case UseAtlas::USE_ATLAS:
+      {
+        hashTarget[ urlLength ] = 't';
+        break;
+      }
+    }
   }
 
   if( maskTextureId != INVALID_TEXTURE_ID )
@@ -1022,6 +1089,11 @@ void TextureManager::AsyncLoadingHelper::AsyncLoadComplete(uint32_t           id
   mTextureManager.AsyncLoadComplete(mLoadingInfoContainer, id, pixelBuffer);
 }
 
+void TextureManager::SetBrokenImageUrl(const std::string& brokenImageUrl)
+{
+  mBrokenImageUrl = brokenImageUrl;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit