Add support for Imagevisual to use External Texture as input through Url 66/150466/10
authorKimmo Hoikka <kimmo.hoikka@samsung.com>
Fri, 15 Sep 2017 16:57:01 +0000 (17:57 +0100)
committerFrancisco Santos <f1.santos@samsung.com>
Wed, 27 Sep 2017 09:32:41 +0000 (10:32 +0100)
Change-Id: I36ddb93fb33569ec40f317b3c763845a59cd2c10

automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
dali-toolkit/devel-api/file.list
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/image/image-visual.h
dali-toolkit/internal/visuals/texture-manager-impl.cpp
dali-toolkit/internal/visuals/texture-manager-impl.h

index 31909d9..bac289e 100644 (file)
@@ -24,6 +24,7 @@
 #include <dali/devel-api/scripting/scripting.h>
 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali/devel-api/scripting/scripting.h>
 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/image-loader/texture-manager.h>
 #include <dali/public-api/rendering/renderer.h>
 
 #include <test-native-image.h>
 #include <dali/public-api/rendering/renderer.h>
 
 #include <test-native-image.h>
@@ -589,7 +590,6 @@ int UtcDaliImageViewSyncLoading(void)
   END_TEST;
 }
 
   END_TEST;
 }
 
-
 int UtcDaliImageViewSyncLoading02(void)
 {
   ToolkitTestApplication application;
 int UtcDaliImageViewSyncLoading02(void)
 {
   ToolkitTestApplication application;
@@ -626,6 +626,30 @@ int UtcDaliImageViewSyncLoading02(void)
   END_TEST;
 }
 
   END_TEST;
 }
 
+int UtcDaliImageViewAddedTexture(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline("ImageView Testing image view with texture provided manager url");
+
+  ImageView imageView = ImageView::New();
+
+  // empty texture is ok, though pointless from app point of view
+  TextureSet  empty;
+  std::string url = TextureManager::AddTexture(empty);
+  DALI_TEST_CHECK(url.size() > 0u);
+
+  Property::Map propertyMap;
+  propertyMap[ImageVisual::Property::URL] = url;
+  imageView.SetProperty(ImageView::Property::IMAGE, propertyMap);
+
+  Stage::GetCurrent().Add( imageView );
+  application.SendNotification();
+  application.Render();
+
+  END_TEST;
+}
+
 int UtcDaliImageViewSizeWithBackground(void)
 {
   ToolkitTestApplication application;
 int UtcDaliImageViewSizeWithBackground(void)
 {
   ToolkitTestApplication application;
index 5cf6797..85275d9 100644 (file)
@@ -117,7 +117,8 @@ devel_api_focus_manager_header_files = \
 devel_api_image_loader_header_files = \
   $(devel_api_src_dir)/image-loader/async-image-loader-devel.h \
   $(devel_api_src_dir)/image-loader/atlas-upload-observer.h \
 devel_api_image_loader_header_files = \
   $(devel_api_src_dir)/image-loader/async-image-loader-devel.h \
   $(devel_api_src_dir)/image-loader/atlas-upload-observer.h \
-  $(devel_api_src_dir)/image-loader/image-atlas.h
+  $(devel_api_src_dir)/image-loader/image-atlas.h \
+  $(devel_api_src_dir)/image-loader/texture-manager.h
 
 devel_api_scripting_header_files = \
   $(devel_api_src_dir)/scripting/script.h \
 
 devel_api_scripting_header_files = \
   $(devel_api_src_dir)/scripting/script.h \
index ab956e8..8961b4b 100644 (file)
@@ -269,7 +269,7 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache,
   mWrapModeU( WrapMode::DEFAULT ),
   mWrapModeV( WrapMode::DEFAULT ),
   mAttemptAtlasing( false ),
   mWrapModeU( WrapMode::DEFAULT ),
   mWrapModeV( WrapMode::DEFAULT ),
   mAttemptAtlasing( false ),
-  mTextureLoading( false )
+  mLoadingStatus( false )
 {
 }
 
 {
 }
 
@@ -287,12 +287,23 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, const Image& image )
   mWrapModeU( WrapMode::DEFAULT ),
   mWrapModeV( WrapMode::DEFAULT ),
   mAttemptAtlasing( false ),
   mWrapModeU( WrapMode::DEFAULT ),
   mWrapModeV( WrapMode::DEFAULT ),
   mAttemptAtlasing( false ),
-  mTextureLoading( false )
+  mLoadingStatus( false )
 {
 }
 
 ImageVisual::~ImageVisual()
 {
 {
 }
 
 ImageVisual::~ImageVisual()
 {
+  if( mMaskingData && Stage::IsInstalled() )
+  {
+    // 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 );
+    }
+  }
   delete mMaskingData;
 }
 
   delete mMaskingData;
 }
 
@@ -358,7 +369,6 @@ void ImageVisual::DoSetProperties( const Property::Map& propertyMap )
       }
     }
   }
       }
     }
   }
-
 }
 
 void ImageVisual::DoSetProperty( Property::Index index, const Property::Value& value )
 }
 
 void ImageVisual::DoSetProperty( Property::Index index, const Property::Value& value )
@@ -466,7 +476,9 @@ void ImageVisual::DoSetProperty( Property::Index index, const Property::Value& v
       {
         AllocateMaskData();
         // Immediately trigger the alpha mask loading (it may just get a cached value)
       {
         AllocateMaskData();
         // Immediately trigger the alpha mask loading (it may just get a cached value)
-        mMaskingData->SetImage( alphaUrl );
+        mMaskingData->mAlphaMaskUrl = alphaUrl;
+        TextureManager& textureManager = mFactoryCache.GetTextureManager();
+        mMaskingData->mAlphaMaskId = textureManager.RequestMaskLoad( alphaUrl );
       }
       break;
     }
       }
       break;
     }
@@ -499,8 +511,7 @@ void ImageVisual::AllocateMaskData()
 {
   if( mMaskingData == NULL )
   {
 {
   if( mMaskingData == NULL )
   {
-    TextureManager& textureManager = mFactoryCache.GetTextureManager();
-    mMaskingData = new MaskingData(textureManager);
+    mMaskingData = new TextureManager::MaskingData();
   }
 }
 
   }
 }
 
@@ -675,118 +686,42 @@ bool ImageVisual::IsSynchronousResourceLoading() const
   return mImpl->mFlags & Impl::IS_SYNCHRONOUS_RESOURCE_LOADING;
 }
 
   return mImpl->mFlags & Impl::IS_SYNCHRONOUS_RESOURCE_LOADING;
 }
 
-TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, bool synchronousLoading, bool attemptAtlasing )
-{
-  TextureSet textureSet;
-
-  mTextureLoading = false;
-  textureRect = FULL_TEXTURE_RECT;
-
-  if( synchronousLoading )
-  {
-    PixelData data;
-    if( mImageUrl.IsValid() )
-    {
-      // if sync loading is required, the loading should immediately when actor is on stage
-      Devel::PixelBuffer pixelBuffer = LoadImageFromFile( mImageUrl.GetUrl(), mDesiredSize, mFittingMode, mSamplingMode );
-
-      if( pixelBuffer )
-      {
-        data = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer
-      }
-    }
-    if( !data )
-    {
-      // use broken image
-      textureSet = TextureSet::New();
-      TextureSetImage( textureSet, 0u, VisualFactoryCache::GetBrokenVisualImage() );
-    }
-    else
-    {
-      if( attemptAtlasing )
-      {
-        textureSet = mFactoryCache.GetAtlasManager()->Add( textureRect, data );
-        mImpl->mFlags |= Impl::IS_ATLASING_APPLIED;
-      }
-      if( !textureSet ) // big image, no atlasing or atlasing failed
-      {
-        mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
-        Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, data.GetPixelFormat(),
-                                        data.GetWidth(), data.GetHeight() );
-        texture.Upload( data );
-        textureSet = TextureSet::New();
-        textureSet.SetTexture( 0u, texture );
-      }
-    }
-  }
-  else
-  {
-    mTextureLoading = true;
-    if( attemptAtlasing )
-    {
-      textureSet = mFactoryCache.GetAtlasManager()->Add( textureRect, mImageUrl.GetUrl(), mDesiredSize, mFittingMode, true, this );
-      mImpl->mFlags |= Impl::IS_ATLASING_APPLIED;
-    }
-    if( !textureSet ) // big image, no atlasing or atlasing failed
-    {
-      mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
-      TextureManager& textureManager = mFactoryCache.GetTextureManager();
-      if( mMaskingData == NULL )
-      {
-        mTextureId = textureManager.RequestLoad( mImageUrl, mDesiredSize, mFittingMode,
-                                                 mSamplingMode, TextureManager::NO_ATLAS, this );
-      }
-      else
-      {
-        mTextureId = textureManager.RequestLoad( mImageUrl,
-                                                 mMaskingData->mAlphaMaskId,
-                                                 mMaskingData->mContentScaleFactor,
-                                                 mDesiredSize,
-                                                 mFittingMode, mSamplingMode,
-                                                 TextureManager::NO_ATLAS,
-                                                 mMaskingData->mCropToMask,
-                                                 this );
-      }
-
-      TextureManager::LoadState loadState = textureManager.GetTextureState( mTextureId );
-      mTextureLoading = ( loadState == TextureManager::LOADING );
-
-      if( loadState == TextureManager::UPLOADED )
-      {
-        // UploadComplete has already been called - keep the same texture set
-        textureSet = textureManager.GetTextureSet(mTextureId);
-      }
-    }
-  }
-
-  if( ! (mImpl->mFlags & Impl::IS_ATLASING_APPLIED) && textureSet )
-  {
-    Sampler sampler = Sampler::New();
-    sampler.SetWrapMode(  mWrapModeU, mWrapModeV  );
-    textureSet.SetSampler( 0u, sampler );
-  }
-
-  return textureSet;
-}
-
+/*
+( VisualUrl& url, Dali::ImageDimensions desiredSize, Dali::FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode,
+                                        ImageVisual::MaskingData* maskInfo, bool synchronousLoading,
+                                        TextureManager::TextureId textureId, Vector4& textureRect, bool& atlasingStatus, bool& loadingStatus
+ */
 void ImageVisual::InitializeRenderer()
 {
   mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
 
 void ImageVisual::InitializeRenderer()
 {
   mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
 
+  TextureManager& textureManager = mFactoryCache.GetTextureManager();
+
   if( ! mImpl->mCustomShader && mImageUrl.GetProtocolType() == VisualUrl::LOCAL )
   {
     bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE;
 
     Vector4 atlasRect;
   if( ! mImpl->mCustomShader && mImageUrl.GetProtocolType() == VisualUrl::LOCAL )
   {
     bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE;
 
     Vector4 atlasRect;
+
+    auto attemptAtlasing = mAttemptAtlasing;
+
     // texture set has to be created first as we need to know if atlasing succeeded or not
     // when selecting the shader
     // texture set has to be created first as we need to know if atlasing succeeded or not
     // when selecting the shader
-    TextureSet textures = CreateTextureSet( atlasRect, IsSynchronousResourceLoading(), mAttemptAtlasing );
+    TextureSet textures =
+        textureManager.LoadTexture(mImageUrl, mDesiredSize, mFittingMode, mSamplingMode,
+                                   mMaskingData, IsSynchronousResourceLoading(), mTextureId,
+                                   atlasRect, attemptAtlasing, mLoadingStatus, mWrapModeU,
+                                   mWrapModeV, this, this, mFactoryCache.GetAtlasManager());
+    if(attemptAtlasing)
+    {
+      mImpl->mFlags |= Impl::IS_ATLASING_APPLIED;
+    }
     CreateRenderer( textures );
 
     if( mImpl->mFlags & Impl::IS_ATLASING_APPLIED ) // the texture is packed inside atlas
     {
       mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, atlasRect );
     CreateRenderer( textures );
 
     if( mImpl->mFlags & Impl::IS_ATLASING_APPLIED ) // the texture is packed inside atlas
     {
       mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, atlasRect );
-      if( !defaultWrapMode ) // custom wrap mode, renderer is not cached.
+      if( !defaultWrapMode ) // custom wrap mode
       {
         Vector2 wrapMode(mWrapModeU-WrapMode::CLAMP_TO_EDGE, mWrapModeV-WrapMode::CLAMP_TO_EDGE);
         wrapMode.Clamp( Vector2::ZERO, Vector2( 2.f, 2.f ) );
       {
         Vector2 wrapMode(mWrapModeU-WrapMode::CLAMP_TO_EDGE, mWrapModeV-WrapMode::CLAMP_TO_EDGE);
         wrapMode.Clamp( Vector2::ZERO, Vector2( 2.f, 2.f ) );
@@ -796,16 +731,21 @@ void ImageVisual::InitializeRenderer()
   }
   else
   {
   }
   else
   {
+    auto attemptAtlasing = false;
     // for custom shader or remote image, atlas is not applied
     Vector4 atlasRect; // ignored in this case
     // for custom shader or remote image, atlas is not applied
     Vector4 atlasRect; // ignored in this case
-    TextureSet textures = CreateTextureSet( atlasRect, IsSynchronousResourceLoading(), false );
+    TextureSet textures =
+        textureManager.LoadTexture(mImageUrl, mDesiredSize, mFittingMode, mSamplingMode,
+                                   mMaskingData, IsSynchronousResourceLoading(), mTextureId,
+                                   atlasRect, attemptAtlasing, mLoadingStatus, mWrapModeU, mWrapModeV, this,
+                                   nullptr, nullptr); // no atlasing
+    DALI_ASSERT_DEBUG(attemptAtlasing == false);
     CreateRenderer( textures );
   }
 }
 
 void ImageVisual::InitializeRenderer( const Image& image )
 {
     CreateRenderer( textures );
   }
 }
 
 void ImageVisual::InitializeRenderer( const Image& image )
 {
-  // don't reuse CreateTextureSet
   TextureSet textures = TextureSet::New();
 
   NativeImage nativeImage = NativeImage::DownCast( image );
   TextureSet textures = TextureSet::New();
 
   NativeImage nativeImage = NativeImage::DownCast( image );
@@ -853,7 +793,7 @@ void ImageVisual::DoSetOnStage( Actor& actor )
     mImpl->mRenderer.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, mPixelArea );
   }
 
     mImpl->mRenderer.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, mPixelArea );
   }
 
-  if( mTextureLoading == false )
+  if( mLoadingStatus == false )
   {
     actor.AddRenderer( mImpl->mRenderer );
     mPlacementActor.Reset();
   {
     actor.AddRenderer( mImpl->mRenderer );
     mPlacementActor.Reset();
@@ -874,7 +814,7 @@ void ImageVisual::DoSetOffStage( Actor& actor )
     RemoveTexture( mImageUrl.GetUrl() );
     mImage.Reset();
   }
     RemoveTexture( mImageUrl.GetUrl() );
     mImage.Reset();
   }
-  mTextureLoading = false;
+  mLoadingStatus = false;
   mImpl->mRenderer.Reset();
   mPlacementActor.Reset();
 }
   mImpl->mRenderer.Reset();
   mPlacementActor.Reset();
 }
@@ -1010,7 +950,7 @@ void ImageVisual::UploadCompleted()
     // reset the weak handle so that the renderer only get added to actor once
     mPlacementActor.Reset();
   }
     // reset the weak handle so that the renderer only get added to actor once
     mPlacementActor.Reset();
   }
-  mTextureLoading = false;
+  mLoadingStatus = false;
 }
 
 // From Texture Manager
 }
 
 // From Texture Manager
@@ -1045,7 +985,7 @@ void ImageVisual::UploadComplete( bool loadingSuccess, int32_t textureId, Textur
       ResourceReady();
     }
   }
       ResourceReady();
     }
   }
-  mTextureLoading = false;
+  mLoadingStatus = false;
 }
 
 void ImageVisual::RemoveTexture(const std::string& url)
 }
 
 void ImageVisual::RemoveTexture(const std::string& url)
@@ -1075,36 +1015,6 @@ void ImageVisual::RemoveTexture(const std::string& url)
   }
 }
 
   }
 }
 
-
-ImageVisual::MaskingData::MaskingData( TextureManager& textureManager )
-: mTextureManager( textureManager ),
-  mAlphaMaskUrl(),
-  mAlphaMaskId( TextureManager::INVALID_TEXTURE_ID ),
-  mContentScaleFactor( 1.0f ),
-  mCropToMask( true )
-{
-}
-
-ImageVisual::MaskingData::~MaskingData()
-{
-  if( Stage::IsInstalled() )
-  {
-    // 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( mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID )
-    {
-      mTextureManager.Remove( mAlphaMaskId );
-    }
-  }
-}
-
-void ImageVisual::MaskingData::SetImage( const std::string& maskUrl )
-{
-  mAlphaMaskUrl = maskUrl;
-  mAlphaMaskId = mTextureManager.RequestMaskLoad( mAlphaMaskUrl );
-}
-
 } // namespace Internal
 
 } // namespace Toolkit
 } // namespace Internal
 
 } // namespace Toolkit
index 0c2f756..bee6067 100644 (file)
@@ -314,24 +314,12 @@ private:
   void DoSetProperty( Property::Index index, const Property::Value& value );
 
 private:
   void DoSetProperty( Property::Index index, const Property::Value& value );
 
 private:
-  struct MaskingData
-  {
-    MaskingData( TextureManager& textureManager );
-    ~MaskingData();
-    void SetImage( const std::string& url );
-
-    TextureManager& mTextureManager;
-    VisualUrl mAlphaMaskUrl;
-    TextureManager::TextureId mAlphaMaskId;
-    float mContentScaleFactor;
-    bool mCropToMask;
-  };
 
   Image mImage;
   Vector4 mPixelArea;
   WeakHandle<Actor> mPlacementActor;
   VisualUrl mImageUrl;
 
   Image mImage;
   Vector4 mPixelArea;
   WeakHandle<Actor> mPlacementActor;
   VisualUrl mImageUrl;
-  MaskingData* mMaskingData;
+  TextureManager::MaskingData* mMaskingData;
 
   Dali::ImageDimensions mDesiredSize;
   TextureManager::TextureId mTextureId;
 
   Dali::ImageDimensions mDesiredSize;
   TextureManager::TextureId mTextureId;
@@ -340,8 +328,8 @@ private:
   Dali::SamplingMode::Type mSamplingMode:4;
   Dali::WrapMode::Type mWrapModeU:3;
   Dali::WrapMode::Type mWrapModeV:3;
   Dali::SamplingMode::Type mSamplingMode:4;
   Dali::WrapMode::Type mWrapModeU:3;
   Dali::WrapMode::Type mWrapModeV:3;
-  bool mAttemptAtlasing:1; ///< If true will attempt atlasing, otherwise create unique texture
-  bool mTextureLoading:1;  ///< True if the texture is being loaded asynchronously, or false when it has loaded.
+  bool mAttemptAtlasing; ///< If true will attempt atlasing, otherwise create unique texture
+  bool mLoadingStatus;  ///< True if the texture is being loaded asynchronously, or false when it has loaded.
 };
 
 
 };
 
 
index f074087..66f6a81 100644 (file)
@@ -21,7 +21,9 @@
 // EXTERNAL HEADERS
 #include <cstdlib>
 #include <string>
 // EXTERNAL HEADERS
 #include <cstdlib>
 #include <string>
+#include <dali/public-api/math/vector4.h>
 #include <dali/devel-api/adaptor-framework/environment-variable.h>
 #include <dali/devel-api/adaptor-framework/environment-variable.h>
+#include <dali/devel-api/adaptor-framework/image-loading.h>
 #include <dali/devel-api/common/hash.h>
 #include <dali/devel-api/images/texture-set-image.h>
 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
 #include <dali/devel-api/common/hash.h>
 #include <dali/devel-api/images/texture-set-image.h>
 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
@@ -30,6 +32,7 @@
 // INTERNAL HEADERS
 #include <dali-toolkit/internal/image-loader/image-atlas-impl.h>
 #include <dali-toolkit/public-api/image-loader/sync-image-loader.h>
 // INTERNAL HEADERS
 #include <dali-toolkit/internal/image-loader/image-atlas-impl.h>
 #include <dali-toolkit/public-api/image-loader/sync-image-loader.h>
+#include <dali-toolkit/internal/visuals/image-atlas-manager.h>
 
 namespace
 {
 
 namespace
 {
@@ -84,6 +87,13 @@ const int           INVALID_CACHE_INDEX( -1 ); ///< Invalid Cache index
 
 } // Anonymous namespace
 
 
 } // Anonymous namespace
 
+TextureManager::MaskingData::MaskingData()
+: mAlphaMaskUrl(),
+  mAlphaMaskId( INVALID_TEXTURE_ID ),
+  mContentScaleFactor( 1.0f ),
+  mCropToMask( true )
+{
+}
 
 TextureManager::TextureManager()
 : mAsyncLocalLoaders( GetNumberOfLocalLoaderThreads(), [&]() { return AsyncLoadingHelper(*this); } ),
 
 TextureManager::TextureManager()
 : mAsyncLocalLoaders( GetNumberOfLocalLoaderThreads(), [&]() { return AsyncLoadingHelper(*this); } ),
@@ -92,6 +102,125 @@ TextureManager::TextureManager()
 {
 }
 
 {
 }
 
+TextureSet TextureManager::LoadTexture(
+    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)
+{
+  TextureSet textureSet;
+
+  loadingStatus = false;
+  textureRect = FULL_ATLAS_RECT;
+
+  if( VisualUrl::TEXTURE == url.GetProtocolType())
+  {
+    std::string location = url.GetLocation();
+    if( location.size() > 0u )
+    {
+      TextureId id = std::stoi( location );
+      for( auto&& elem : mExternalTextures )
+      {
+        if( elem.textureId == id )
+        {
+          return elem.textureSet;
+        }
+      }
+    }
+  }
+  else if( synchronousLoading )
+  {
+    PixelData data;
+    if( url.IsValid() )
+    {
+      // if sync loading is required, the loading should immediately when actor is on stage
+      Devel::PixelBuffer pixelBuffer = LoadImageFromFile( url.GetUrl(), desiredSize, fittingMode, samplingMode );
+      if( pixelBuffer )
+      {
+        data = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer
+      }
+    }
+    if( !data )
+    {
+      // use broken image
+      textureSet = TextureSet::New();
+      Devel::PixelBuffer pixelBuffer = LoadImageFromFile( BROKEN_IMAGE_URL );
+      if( pixelBuffer )
+      {
+        data = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer
+      }
+      Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, data.GetPixelFormat(),
+                                      data.GetWidth(), data.GetHeight() );
+      texture.Upload( data );
+      textureSet = TextureSet::New();
+      textureSet.SetTexture( 0u, texture );
+    }
+    else
+    {
+      if( atlasingStatus ) // attempt atlasing
+      {
+        textureSet = imageAtlasManager->Add( textureRect, data );
+      }
+      if( !textureSet ) // big image, no atlasing or atlasing failed
+      {
+        atlasingStatus = false;
+        Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, data.GetPixelFormat(),
+                                        data.GetWidth(), data.GetHeight() );
+        texture.Upload( data );
+        textureSet = TextureSet::New();
+        textureSet.SetTexture( 0u, texture );
+      }
+    }
+  }
+  else
+  {
+    loadingStatus = true;
+    if( atlasingStatus )
+    {
+      textureSet = imageAtlasManager->Add( textureRect, url.GetUrl(), desiredSize, fittingMode, true, atlasObserver );
+    }
+    if( !textureSet ) // big image, no atlasing or atlasing failed
+    {
+      atlasingStatus = false;
+      if( !maskInfo )
+      {
+        textureId = RequestLoad( url, desiredSize, fittingMode, samplingMode, TextureManager::NO_ATLAS, textureObserver );
+      }
+      else
+      {
+        textureId = RequestLoad( url,
+                                 maskInfo->mAlphaMaskId,
+                                 maskInfo->mContentScaleFactor,
+                                 desiredSize,
+                                 fittingMode, samplingMode,
+                                 TextureManager::NO_ATLAS,
+                                 maskInfo->mCropToMask,
+                                 textureObserver );
+      }
+
+      TextureManager::LoadState loadState = GetTextureState( textureId );
+      loadingStatus = ( loadState == TextureManager::LOADING );
+
+      if( loadState == TextureManager::UPLOADED )
+      {
+        // UploadComplete has already been called - keep the same texture set
+        textureSet = GetTextureSet( textureId );
+      }
+    }
+  }
+
+  if( ! atlasingStatus && textureSet )
+  {
+    Sampler sampler = Sampler::New();
+    sampler.SetWrapMode(  wrapModeU, wrapModeV  );
+    textureSet.SetSampler( 0u, sampler );
+  }
+
+  return textureSet;
+}
+
 TextureManager::TextureId TextureManager::RequestLoad(
   const VisualUrl&         url,
   const ImageDimensions    desiredSize,
 TextureManager::TextureId TextureManager::RequestLoad(
   const VisualUrl&         url,
   const ImageDimensions    desiredSize,
@@ -123,7 +252,6 @@ TextureManager::TextureId TextureManager::RequestMaskLoad( const VisualUrl& mask
   return RequestLoadInternal( maskUrl, INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, NO_ATLAS, false, KEEP_PIXEL_BUFFER, NULL );
 }
 
   return RequestLoadInternal( maskUrl, INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, NO_ATLAS, false, KEEP_PIXEL_BUFFER, NULL );
 }
 
-
 TextureManager::TextureId TextureManager::RequestLoadInternal(
   const VisualUrl&         url,
   TextureId                maskTextureId,
 TextureManager::TextureId TextureManager::RequestLoadInternal(
   const VisualUrl&         url,
   TextureId                maskTextureId,
@@ -715,10 +843,6 @@ void TextureManager::ObserverDestroyed( TextureUploadObserver* observer )
   }
 }
 
   }
 }
 
-TextureManager::~TextureManager()
-{
-}
-
 TextureManager::AsyncLoadingHelper::AsyncLoadingHelper(TextureManager& textureManager)
 : AsyncLoadingHelper(Toolkit::AsyncImageLoader::New(), textureManager,
                      AsyncLoadingInfoContainerType())
 TextureManager::AsyncLoadingHelper::AsyncLoadingHelper(TextureManager& textureManager)
 : AsyncLoadingHelper(Toolkit::AsyncImageLoader::New(), textureManager,
                      AsyncLoadingInfoContainerType())
index 117bd1f..868afdc 100644 (file)
@@ -45,6 +45,8 @@ namespace Toolkit
 
 namespace Internal
 {
 
 namespace Internal
 {
+class ImageAtlasManager;
+typedef IntrusivePtr<ImageAtlasManager> ImageAtlasManagerPtr;
 
 /**
  * The TextureManager provides a common Image loading API for Visuals.
 
 /**
  * The TextureManager provides a common Image loading API for Visuals.
@@ -103,6 +105,17 @@ public:
 
 public:
 
 
 public:
 
+  struct MaskingData
+  {
+    MaskingData();
+    ~MaskingData() = default;
+
+    VisualUrl mAlphaMaskUrl;
+    TextureManager::TextureId mAlphaMaskId;
+    float mContentScaleFactor;
+    bool mCropToMask;
+  };
+
   /**
    * Constructor.
    */
   /**
    * Constructor.
    */
@@ -111,11 +124,20 @@ public:
   /**
    * Destructor.
    */
   /**
    * Destructor.
    */
-  ~TextureManager();
+  ~TextureManager() = default;
 
 
   // TextureManager Main API:
 
 
 
   // TextureManager Main API:
 
+  TextureSet LoadTexture(VisualUrl& url, Dali::ImageDimensions desiredSize,
+                         Dali::FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode,
+                         MaskingData* 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);
+
   /**
    * @brief Requests an image load of the given URL.
    *
   /**
    * @brief Requests an image load of the given URL.
    *
@@ -345,25 +367,9 @@ private:
     unsigned short      loadId;      ///< The load Id used by the async loader to reference this load
   };
 
     unsigned short      loadId;      ///< The load Id used by the async loader to reference this load
   };
 
-  /**
-   * @brief This struct is used within a container to manage atlas creation and destruction.
-   */
-  struct AtlasInfo
-  {
-    AtlasInfo( Toolkit::ImageAtlas atlas, TextureSet textureSet )
-    : atlas( atlas ),
-      textureSet( textureSet )
-    {
-    }
-
-    Toolkit::ImageAtlas                 atlas;                          ///< The ImageAtlas object
-    TextureSet                          textureSet;                     ///< The TextureSet is kept in the struct to allow fast lookup of TextureSet to Atlas
-  };
-
   // Private typedefs:
 
   typedef std::deque<AsyncLoadingInfo>  AsyncLoadingInfoContainerType;  ///< The container type used to manage Asynchronous loads in progress
   // Private typedefs:
 
   typedef std::deque<AsyncLoadingInfo>  AsyncLoadingInfoContainerType;  ///< The container type used to manage Asynchronous loads in progress
-  typedef std::vector<AtlasInfo>        AtlasInfoContainerType;         ///< The container type used to manage Atlas creation and destruction
   typedef std::vector<TextureInfo>      TextureInfoContainerType;       ///< The container type used to manage the life-cycle and caching of Textures
 
   /**
   typedef std::vector<TextureInfo>      TextureInfoContainerType;       ///< The container type used to manage the life-cycle and caching of Textures
 
   /**
@@ -586,7 +592,6 @@ private:
 
 private:  // Member Variables:
 
 
 private:  // Member Variables:
 
-  AtlasInfoContainerType                        mAtlasContainer;       ///< Used to manage Atlas creation and destruction
   TextureInfoContainerType                      mTextureInfoContainer; ///< Used to manage the life-cycle and caching of Textures
   RoundRobinContainerView< AsyncLoadingHelper > mAsyncLocalLoaders;    ///< The Asynchronous image loaders used to provide all local async loads
   RoundRobinContainerView< AsyncLoadingHelper > mAsyncRemoteLoaders;   ///< The Asynchronous image loaders used to provide all remote async loads
   TextureInfoContainerType                      mTextureInfoContainer; ///< Used to manage the life-cycle and caching of Textures
   RoundRobinContainerView< AsyncLoadingHelper > mAsyncLocalLoaders;    ///< The Asynchronous image loaders used to provide all local async loads
   RoundRobinContainerView< AsyncLoadingHelper > mAsyncRemoteLoaders;   ///< The Asynchronous image loaders used to provide all remote async loads