namespace NPatchBuffer
{
-void SetLoadedNPatchData( NPatchLoader::Data* data, Devel::PixelBuffer& pixelBuffer )
+void SetLoadedNPatchData( NPatchLoader::Data* data, Devel::PixelBuffer& pixelBuffer, bool preMultiplied )
{
if( data->border == Rect< int >( 0, 0, 0, 0 ) )
{
data->textureSet = TextureSet::New();
data->textureSet.SetTexture( 0u, texture );
+ data->preMultiplyOnLoad = preMultiplied;
+
data->loadCompleted = true;
}
{
}
-std::size_t NPatchLoader::Load( TextureManager& textureManager, TextureUploadObserver* textureObserver, const std::string& url, const Rect< int >& border, bool& preMultiplyOnLoad, bool synchronousLoading )
+std::size_t NPatchLoader::Load( TextureManager& textureManager, NPatchLoadObserver* nPatchObserver, const std::string& url, const Rect< int >& border, bool& preMultiplyOnLoad, bool synchronousLoading )
{
std::size_t hash = CalculateHash( url );
OwnerContainer< Data* >::SizeType index = UNINITIALIZED_ID;
const OwnerContainer< Data* >::SizeType count = mCache.Count();
- int cachedIndex = -1;
- Data* data;
for( ; index < count; ++index )
{
if( mCache[ index ]->hash == hash )
{
- // hash match, check url as well in case of hash collision
- if( mCache[ index ]->url == url )
+ // hash match, check url and preMultiplyOnLoading as well in case of hash collision
+ if( mCache[ index ]->url == url && mCache[ index ]->preMultiplyOnLoad == preMultiplyOnLoad )
{
// Use cached data
if( mCache[ index ]->border == border )
{
- if( mCache[ index ]->loadCompleted )
+ if( !mCache[ index ]->loadCompleted )
{
- return index + 1u; // valid indices are from 1 onwards
+ mCache[ index ]->observerList.PushBack( nPatchObserver );
}
- mCache[ index ]->observerList.PushBack( textureObserver );
- data = mCache[ index ];
return index + 1u; // valid indices are from 1 onwards
}
else
if( mCache[ index ]->loadCompleted )
{
// Same url but border is different - use the existing texture
- Data* data = new Data();
- data->hash = hash;
- data->url = url;
- data->croppedWidth = mCache[ index ]->croppedWidth;
- data->croppedHeight = mCache[ index ]->croppedHeight;
+ Data* newData = new Data();
+ newData->hash = hash;
+ newData->url = url;
+ newData->croppedWidth = mCache[ index ]->croppedWidth;
+ newData->croppedHeight = mCache[ index ]->croppedHeight;
- data->textureSet = mCache[ index ]->textureSet;
+ newData->textureSet = mCache[ index ]->textureSet;
NPatchUtility::StretchRanges stretchRangesX;
- stretchRangesX.PushBack( Uint16Pair( border.left, ( (data->croppedWidth >= static_cast< unsigned int >( border.right )) ? data->croppedWidth - border.right : 0 ) ) );
+ stretchRangesX.PushBack( Uint16Pair( border.left, ( (newData->croppedWidth >= static_cast< unsigned int >( border.right )) ? newData->croppedWidth - border.right : 0 ) ) );
NPatchUtility::StretchRanges stretchRangesY;
- stretchRangesY.PushBack( Uint16Pair( border.top, ( (data->croppedHeight >= static_cast< unsigned int >( border.bottom )) ? data->croppedHeight - border.bottom : 0 ) ) );
+ stretchRangesY.PushBack( Uint16Pair( border.top, ( (newData->croppedHeight >= static_cast< unsigned int >( border.bottom )) ? newData->croppedHeight - border.bottom : 0 ) ) );
- data->stretchPixelsX = stretchRangesX;
- data->stretchPixelsY = stretchRangesY;
- data->border = border;
+ newData->stretchPixelsX = stretchRangesX;
+ newData->stretchPixelsY = stretchRangesY;
+ newData->border = border;
- data->loadCompleted = mCache[ index ]->loadCompleted;
+ newData->preMultiplyOnLoad = preMultiplyOnLoad;
- mCache.PushBack( data );
+ newData->loadCompleted = mCache[ index ]->loadCompleted;
+
+ mCache.PushBack( newData );
return mCache.Count(); // valid ids start from 1u
}
}
}
- if( cachedIndex == -1 )
- {
- data = new Data();
- data->loadCompleted = false;
- data->hash = hash;
- data->url = url;
- data->border = border;
-
- mCache.PushBack( data );
-
- cachedIndex = mCache.Count();
- }
+ // If this is new image loading, make new cache data
+ Data* data;
+ data = new Data();
+ data->loadCompleted = false;
+ data->hash = hash;
+ data->url = url;
+ data->border = border;
+ data->preMultiplyOnLoad = preMultiplyOnLoad;
+ data->observerList.PushBack( nPatchObserver );
+ data->textureObserver = nPatchObserver;
+ mCache.PushBack(data);
auto preMultiplyOnLoading = preMultiplyOnLoad ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD
: TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+
Devel::PixelBuffer pixelBuffer = textureManager.LoadPixelBuffer( url, Dali::ImageDimensions(), FittingMode::DEFAULT,
SamplingMode::BOX_THEN_LINEAR, synchronousLoading,
- textureObserver, true, preMultiplyOnLoading );
+ nPatchObserver, true, preMultiplyOnLoading );
if( pixelBuffer )
{
- NPatchBuffer::SetLoadedNPatchData( data, pixelBuffer );
preMultiplyOnLoad = ( preMultiplyOnLoading == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD ) ? true : false;
+ NPatchBuffer::SetLoadedNPatchData( data, pixelBuffer, preMultiplyOnLoad );
}
- return cachedIndex;
+ return mCache.Count();
}
-void NPatchLoader::SetNPatchData( bool loadSuccess, std::size_t id, Devel::PixelBuffer& pixelBuffer, const Internal::VisualUrl& url, bool preMultiplied )
+void NPatchLoader::SetNPatchData( std::size_t id, Devel::PixelBuffer& pixelBuffer, bool preMultiplied )
{
Data* data;
data = mCache[ id - 1u ];
- // To prevent recursion.
- // data->loadCompleted will be set true in the NPatchBuffer::SetLoadedNPatchData when the first observer called this method.
- if( data->loadCompleted )
- {
- return;
- }
+ NPatchBuffer::SetLoadedNPatchData( data, pixelBuffer, preMultiplied );
- NPatchBuffer::SetLoadedNPatchData( data, pixelBuffer );
-
- while( data->observerList.Count() )
+ for(uint32_t index = 0; index < data->observerList.Count(); ++index )
{
- TextureUploadObserver* observer = data->observerList[0];
- observer->LoadComplete( loadSuccess, Devel::PixelBuffer(), url, preMultiplied );
- data->observerList.Erase( data->observerList.begin() );
+ NPatchLoadObserver* observer = data->observerList[index];
+ observer->NPatchLoadComplete( preMultiplied );
}
}
return false;
}
+void NPatchLoader::Remove( std::size_t id, TextureManager& textureManager, NPatchLoadObserver* nPatchObserver, bool synchronousLoading )
+{
+ Data* data;
+ data = mCache[ id - 1u ];
+
+ for(uint32_t index = 0; index < data->observerList.Count(); ++index )
+ {
+ if(nPatchObserver == data->observerList[index])
+ {
+ data->observerList.Erase( data->observerList.begin() + index );
+ break;
+ }
+ }
+
+ if(data->observerList.Empty())
+ {
+ data->loadCompleted = false;
+ data->hash = 0u;
+ data->url.clear();
+ data->textureObserver = nullptr;
+ data->textureSet.Reset();
+ }
+ else
+ {
+ if(!data->loadCompleted && data->textureObserver == nPatchObserver)
+ {
+ data->textureObserver = nPatchObserver;
+ auto preMultiplyOnLoading = data->preMultiplyOnLoad ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD
+ : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+
+ Devel::PixelBuffer pixelBuffer = textureManager.LoadPixelBuffer(data->url, Dali::ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, synchronousLoading, nPatchObserver, true, preMultiplyOnLoading);
+
+ if(pixelBuffer)
+ {
+ NPatchBuffer::SetLoadedNPatchData(data, pixelBuffer, (preMultiplyOnLoading == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD) ? true : false);
+ }
+ }
+ }
+}
+
} // namespace Internal
} // namespace Toolkit
class NPatchLoader
{
public:
+ /**
+ * Observer class to inform the npatch image is loaded.
+ */
+ class NPatchLoadObserver: public Dali::Toolkit::TextureUploadObserver
+ {
+ public:
+ /**
+ * Informs observer when the npatch image is loaded.
+ * @param[in] preMultiplied True if the image had pre-multiplied alpha applied
+ */
+ virtual void NPatchLoadComplete ( bool preMultiplied ) = 0;
+ };
enum
{
~Data();
- using ObserverListType = Dali::Vector< TextureUploadObserver* >;
-
- ObserverListType observerList; ///< Container used to store all observer clients of this Texture
- std::string url; ///< Url of the N-Patch
- TextureSet textureSet; ///< Texture containing the cropped image
- NPatchUtility::StretchRanges stretchPixelsX; ///< X stretch pixels
- NPatchUtility::StretchRanges stretchPixelsY; ///< Y stretch pixels
- std::size_t hash; ///< Hash code for the Url
- uint32_t croppedWidth; ///< Width of the cropped middle part of N-patch
- uint32_t croppedHeight; ///< Height of the cropped middle part of N-patch
- Rect< int > border; ///< The size of the border
- bool loadCompleted; ///< True if the data loading is completed
- void* renderingMap; ///< NPatch rendering data
+ using ObserverListType = Dali::Vector< NPatchLoadObserver* >;
+
+ TextureUploadObserver* textureObserver; ///< TextureUploadObserver that requests to load texture.
+ ObserverListType observerList; ///< Container used to store all observer clients of this Texture
+ std::string url; ///< Url of the N-Patch
+ TextureSet textureSet; ///< Texture containing the cropped image
+ NPatchUtility::StretchRanges stretchPixelsX; ///< X stretch pixels
+ NPatchUtility::StretchRanges stretchPixelsY; ///< Y stretch pixels
+ std::size_t hash; ///< Hash code for the Url
+ uint32_t croppedWidth; ///< Width of the cropped middle part of N-patch
+ uint32_t croppedHeight; ///< Height of the cropped middle part of N-patch
+ Rect< int > border; ///< The size of the border
+ bool preMultiplyOnLoad; ///< Whether to multiply alpha into color channels on load
+ bool loadCompleted; ///< True if the data loading is completed
+ void* renderingMap; ///< NPatch rendering data
};
public:
* @brief Retrieve a texture matching the n-patch url.
*
* @param [in] textureManager that will be used to loading image
- * @param [in] textureObserver The NPatchVisual that requested loading.
+ * @param [in] nPatchObserver The NPatchVisual that requested loading.
* @param [in] url to retrieve
* @param [in] border The border size of the image
* @param [in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
* @param [in] synchronousLoading True if the image will be loaded in synchronous time.
* @return id of the texture.
*/
- std::size_t Load( TextureManager& textureManager, TextureUploadObserver* textureObserver, const std::string& url, const Rect< int >& border, bool& preMultiplyOnLoad, bool synchronousLoading );
+ std::size_t Load( TextureManager& textureManager, NPatchLoadObserver* nPatchObserver, const std::string& url, const Rect< int >& border, bool& preMultiplyOnLoad, bool synchronousLoading );
/**
* @brief Set loaded PixelBuffer and its information
*
- * @param [in] loadSuccess True if the texture load was successful (i.e. the resource is available). If false, then the resource failed to load.
* @param [in] id cache data id
* @param [in] pixelBuffer of loaded image
- * @param [in] url The url address of the loaded image.
* @param [in] preMultiplied True if the image had pre-multiplied alpha applied
*/
- void SetNPatchData( bool loadSuccess, std::size_t id, Devel::PixelBuffer& pixelBuffer, const Internal::VisualUrl& url, bool preMultiplied );
+ void SetNPatchData( std::size_t id, Devel::PixelBuffer& pixelBuffer, bool preMultiplied );
/**
* @brief Retrieve N patch data matching to an id
*/
bool GetNPatchData( std::size_t id, const Data*& data );
+ void Remove( std::size_t id, TextureManager& textureManager, NPatchLoadObserver* nPatchObserver, bool synchronousLoading );
+
protected:
/**