X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fvisuals%2Ftexture-manager-impl.cpp;h=1ea95a9b6daeb695f226a55121dfd0113f44f74d;hp=c867b91d2a08b1f3e1d83f1f8cd990bafc37133e;hb=a502d6a9b7d780c2f2d71ab950a7ea13467976d7;hpb=935ef82404ba71238cfa58b8938ac325604dd7d6 diff --git a/dali-toolkit/internal/visuals/texture-manager-impl.cpp b/dali-toolkit/internal/visuals/texture-manager-impl.cpp index c867b91..1ea95a9 100644 --- a/dali-toolkit/internal/visuals/texture-manager-impl.cpp +++ b/dali-toolkit/internal/visuals/texture-manager-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,8 +49,8 @@ size_t GetNumberOfThreads(const char* environmentVariable, size_t defaultValue) auto numberString = GetEnvironmentVariable(environmentVariable); auto numberOfThreads = numberString ? std::strtoul(numberString, nullptr, 10) : 0; constexpr auto MAX_NUMBER_OF_THREADS = 100u; - DALI_ASSERT_ALWAYS( numberOfThreads < MAX_NUMBER_OF_THREADS ); - return (numberOfThreads > 0) ? numberOfThreads : defaultValue; + DALI_ASSERT_DEBUG( numberOfThreads < MAX_NUMBER_OF_THREADS ); + return ( numberOfThreads > 0 && numberOfThreads < MAX_NUMBER_OF_THREADS ) ? numberOfThreads : defaultValue; } size_t GetNumberOfLocalLoaderThreads() @@ -83,10 +83,25 @@ 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 + +void PreMultiply( Devel::PixelBuffer pixelBuffer, TextureManager::MultiplyOnLoad& preMultiplyOnLoad ) +{ + if( Pixel::HasAlpha( pixelBuffer.GetPixelFormat() ) ) + { + if( preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD ) + { + pixelBuffer.MultiplyColorByAlpha(); + } + } + else + { + preMultiplyOnLoad = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; + } +} + } // Anonymous namespace TextureManager::MaskingData::MaskingData() @@ -100,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( - 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 ) + 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; @@ -128,6 +154,8 @@ TextureSet TextureManager::LoadTexture( { if( elem.textureId == id ) { + preMultiplyOnLoad = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; + textureId = elem.textureId; return elem.textureSet; } } @@ -142,6 +170,7 @@ TextureSet TextureManager::LoadTexture( orientationCorrection ); if( pixelBuffer ) { + PreMultiply( pixelBuffer, preMultiplyOnLoad ); data = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer } } @@ -149,9 +178,10 @@ 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 ); data = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer } Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, data.GetPixelFormat(), @@ -175,6 +205,11 @@ TextureSet TextureManager::LoadTexture( textureSet = TextureSet::New(); textureSet.SetTexture( 0u, texture ); } + else + { + textureRectSize.SetWidth(data.GetWidth()); + textureRectSize.SetHeight(data.GetHeight()); + } } } else @@ -182,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 { @@ -190,7 +225,7 @@ TextureSet TextureManager::LoadTexture( if( !maskInfo ) { textureId = RequestLoad( url, desiredSize, fittingMode, samplingMode, TextureManager::NO_ATLAS, - textureObserver, orientationCorrection, reloadPolicy ); + textureObserver, orientationCorrection, reloadPolicy, preMultiplyOnLoad ); } else { @@ -203,10 +238,10 @@ TextureSet TextureManager::LoadTexture( maskInfo->mCropToMask, textureObserver, orientationCorrection, - reloadPolicy ); + reloadPolicy, preMultiplyOnLoad ); } - TextureManager::LoadState loadState = GetTextureState( textureId ); + TextureManager::LoadState loadState = GetTextureStateInternal( textureId ); loadingStatus = ( loadState == TextureManager::LOADING ); if( loadState == TextureManager::UPLOADED ) @@ -215,6 +250,10 @@ TextureSet TextureManager::LoadTexture( textureSet = GetTextureSet( textureId ); } } + else + { + textureRectSize = desiredSize; + } } if( ! atlasingStatus && textureSet ) @@ -228,46 +267,51 @@ TextureSet TextureManager::LoadTexture( } TextureManager::TextureId TextureManager::RequestLoad( - const VisualUrl& url, - const ImageDimensions desiredSize, - FittingMode::Type fittingMode, - Dali::SamplingMode::Type samplingMode, - const UseAtlas useAtlas, - TextureUploadObserver* observer, - bool orientationCorrection, - TextureManager::ReloadPolicy reloadPolicy ) + const VisualUrl& url, + const ImageDimensions desiredSize, + FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, + const UseAtlas useAtlas, + TextureUploadObserver* observer, + bool orientationCorrection, + TextureManager::ReloadPolicy reloadPolicy, + TextureManager::MultiplyOnLoad& preMultiplyOnLoad ) { return RequestLoadInternal( url, INVALID_TEXTURE_ID, 1.0f, desiredSize, fittingMode, samplingMode, useAtlas, - false, UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy ); + false, UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy, + preMultiplyOnLoad ); } TextureManager::TextureId TextureManager::RequestLoad( - const VisualUrl& url, - TextureId maskTextureId, - float contentScale, - const ImageDimensions desiredSize, - FittingMode::Type fittingMode, - Dali::SamplingMode::Type samplingMode, - const UseAtlas useAtlas, - bool cropToMask, - TextureUploadObserver* observer, - bool orientationCorrection, - TextureManager::ReloadPolicy reloadPolicy ) + const VisualUrl& url, + TextureId maskTextureId, + float contentScale, + const ImageDimensions desiredSize, + FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, + const UseAtlas useAtlas, + bool cropToMask, + TextureUploadObserver* observer, + bool orientationCorrection, + TextureManager::ReloadPolicy reloadPolicy, + TextureManager::MultiplyOnLoad& preMultiplyOnLoad ) { return RequestLoadInternal( url, maskTextureId, contentScale, desiredSize, fittingMode, samplingMode, useAtlas, - cropToMask, UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy ); + cropToMask, UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy, + preMultiplyOnLoad ); } TextureManager::TextureId TextureManager::RequestMaskLoad( const VisualUrl& maskUrl ) { // Use the normal load procedure to get the alpha mask. + auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; return RequestLoadInternal( maskUrl, INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, NO_ATLAS, false, KEEP_PIXEL_BUFFER, NULL, true, - TextureManager::ReloadPolicy::CACHED ); + TextureManager::ReloadPolicy::CACHED, preMultiply ); } TextureManager::TextureId TextureManager::RequestLoadInternal( - const VisualUrl& url, + const VisualUrl& url, TextureId maskTextureId, float contentScale, const ImageDimensions desiredSize, @@ -278,17 +322,18 @@ TextureManager::TextureId TextureManager::RequestLoadInternal( StorageType storageType, TextureUploadObserver* observer, bool orientationCorrection, - TextureManager::ReloadPolicy reloadPolicy ) + TextureManager::ReloadPolicy reloadPolicy, + TextureManager::MultiplyOnLoad& preMultiplyOnLoad) { // First check if the requested Texture is cached. const TextureHash textureHash = GenerateHash( url.GetUrl(), desiredSize, fittingMode, samplingMode, useAtlas, - maskTextureId ); + maskTextureId, preMultiplyOnLoad ); TextureManager::TextureId textureId = INVALID_TEXTURE_ID; // Look up the texture by hash. Note: The extra parameters are used in case of a hash collision. int cacheIndex = FindCachedTexture( textureHash, url.GetUrl(), desiredSize, fittingMode, samplingMode, useAtlas, - maskTextureId ); + maskTextureId, preMultiplyOnLoad ); // Check if the requested Texture exists in the cache. if( cacheIndex != INVALID_CACHE_INDEX ) @@ -308,9 +353,11 @@ TextureManager::TextureId TextureManager::RequestLoadInternal( { // We need a new Texture. textureId = GenerateUniqueTextureId(); + bool preMultiply = ( preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD ); mTextureInfoContainer.push_back( TextureInfo( textureId, maskTextureId, url.GetUrl(), desiredSize, contentScale, fittingMode, samplingMode, - false, cropToMask, useAtlas, textureHash, orientationCorrection ) ); + false, cropToMask, useAtlas, textureHash, orientationCorrection, + preMultiply ) ); cacheIndex = mTextureInfoContainer.size() - 1u; DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d\n", @@ -363,7 +410,8 @@ TextureManager::TextureId TextureManager::RequestLoadInternal( // The Texture has already loaded. The other observers have already been notified. // We need to send a "late" loaded notification for this observer. observer->UploadComplete( true, textureInfo.textureId, textureInfo.textureSet, - textureInfo.useAtlas, textureInfo.atlasRect ); + textureInfo.useAtlas, textureInfo.atlasRect, + textureInfo.preMultiplied ); } break; } @@ -437,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 ) @@ -456,6 +511,31 @@ TextureManager::LoadState TextureManager::GetTextureState( TextureId textureId ) TextureInfo& cachedTextureInfo( mTextureInfoContainer[ cacheIndex ] ); loadState = cachedTextureInfo.loadState; } + else + { + for( auto&& elem : mExternalTextures ) + { + if( elem.textureId == textureId ) + { + loadState = LoadState::UPLOADED; + break; + } + } + } + return loadState; +} + +TextureManager::LoadState TextureManager::GetTextureStateInternal( TextureId textureId ) +{ + LoadState loadState = TextureManager::NOT_STARTED; + + int cacheIndex = GetCacheIndexFromId( textureId ); + if( cacheIndex != INVALID_CACHE_INDEX ) + { + TextureInfo& cachedTextureInfo( mTextureInfoContainer[ cacheIndex ] ); + loadState = cachedTextureInfo.loadState; + } + return loadState; } @@ -469,6 +549,17 @@ TextureSet TextureManager::GetTextureSet( TextureId textureId ) TextureInfo& cachedTextureInfo( mTextureInfoContainer[ cacheIndex ] ); textureSet = cachedTextureInfo.textureSet; } + else + { + for( auto&& elem : mExternalTextures ) + { + if( elem.textureId == textureId ) + { + textureSet = elem.textureSet; + break; + } + } + } return textureSet; } @@ -509,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; @@ -590,7 +706,7 @@ void TextureManager::PostLoad( TextureInfo& textureInfo, Devel::PixelBuffer& pix // wait for the mask to finish loading. if( textureInfo.maskTextureId != INVALID_TEXTURE_ID ) { - LoadState maskLoadState = GetTextureState( textureInfo.maskTextureId ); + LoadState maskLoadState = GetTextureStateInternal( textureInfo.maskTextureId ); if( maskLoadState == LOADING ) { textureInfo.pixelBuffer = pixelBuffer; // Store the pixel buffer temporarily @@ -665,18 +781,31 @@ 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 ); + } } + void TextureManager::UploadTexture( Devel::PixelBuffer& pixelBuffer, TextureInfo& textureInfo ) { if( textureInfo.useAtlas != USE_ATLAS ) { DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, " TextureManager::UploadTexture() New Texture for textureId:%d\n", textureInfo.textureId ); + // If the texture doesn't have an alpha channel, can't pre-multiply it. + // Ensure that we don't change the load parameter (it's used for hashing), and instead set + // the status for use in the observer. + auto preMultiply = textureInfo.preMultiplyOnLoad ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD : + TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; + PreMultiply( pixelBuffer, preMultiply ); + textureInfo.preMultiplied = (preMultiply == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD ); + Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, pixelBuffer.GetPixelFormat(), pixelBuffer.GetWidth(), pixelBuffer.GetHeight() ); + PixelData pixelData = Devel::PixelBuffer::Convert( pixelBuffer ); texture.Upload( pixelData ); if ( ! textureInfo.textureSet ) @@ -717,7 +846,8 @@ void TextureManager::NotifyObservers( TextureInfo& textureInfo, bool success ) // because new load requests can modify the mTextureInfoContainer list // (e.g. if more requests are pushed back it can cause the list to be // resized invalidating the reference to the TextureInfo ). - observer->UploadComplete( success, info->textureId, info->textureSet, info->useAtlas, info->atlasRect ); + observer->UploadComplete( success, info->textureId, info->textureSet, info->useAtlas, info->atlasRect, + info->preMultiplied ); observer->DestructionSignal().Disconnect( this, &TextureManager::ObserverDestroyed ); // Get the textureInfo from the container again as it may have been @@ -764,7 +894,6 @@ int TextureManager::GetCacheIndexFromId( const TextureId textureId ) } } - DALI_LOG_WARNING( "Cannot locate TextureId: %d\n", textureId ); return INVALID_CACHE_INDEX; } @@ -774,7 +903,8 @@ TextureManager::TextureHash TextureManager::GenerateHash( const FittingMode::Type fittingMode, const Dali::SamplingMode::Type samplingMode, const UseAtlas useAtlas, - TextureId maskTextureId ) + TextureId maskTextureId, + TextureManager::MultiplyOnLoad preMultiplyOnLoad) { std::string hashTarget( url ); const size_t urlLength = hashTarget.length(); @@ -802,16 +932,30 @@ 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 ) { - hashTarget.resize( urlLength + sizeof( TextureId ) ); - TextureId* hashTargetPtr = reinterpret_cast(&( hashTarget[ urlLength ] )); + auto textureIdIndex = hashTarget.length(); + hashTarget.resize( hashTarget.length() + sizeof( TextureId ) ); + unsigned char* hashTargetPtr = reinterpret_cast(&( hashTarget[ textureIdIndex ] )); - // Append the hash target to the end of the URL byte by byte: + // Append the texture id to the end of the URL byte by byte: // (to avoid SIGBUS / alignment issues) for( size_t byteIter = 0; byteIter < sizeof( TextureId ); ++byteIter ) { @@ -820,6 +964,22 @@ TextureManager::TextureHash TextureManager::GenerateHash( } } + auto premultipliedIndex = hashTarget.length(); + hashTarget.resize( premultipliedIndex + 1 ); + switch( preMultiplyOnLoad ) + { + case TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD: + { + hashTarget[ premultipliedIndex ] = 't'; + break; + } + case TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY: + { + hashTarget[ premultipliedIndex ] = 'f'; + break; + } + } + return Dali::CalculateHash( hashTarget ); } @@ -830,7 +990,8 @@ int TextureManager::FindCachedTexture( const FittingMode::Type fittingMode, const Dali::SamplingMode::Type samplingMode, const bool useAtlas, - TextureId maskTextureId) + TextureId maskTextureId, + TextureManager::MultiplyOnLoad preMultiplyOnLoad ) { // Default to an invalid ID, in case we do not find a match. int cacheIndex = INVALID_CACHE_INDEX; @@ -843,11 +1004,14 @@ int TextureManager::FindCachedTexture( { // We have a match, now we check all the original parameters in case of a hash collision. TextureInfo& textureInfo( mTextureInfoContainer[i] ); + auto multiplyOnLoad = textureInfo.preMultiplyOnLoad ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD : + TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; if( ( url == textureInfo.url.GetUrl() ) && ( useAtlas == textureInfo.useAtlas ) && ( maskTextureId == textureInfo.maskTextureId ) && ( size == textureInfo.desiredSize ) && + ( preMultiplyOnLoad == multiplyOnLoad ) && ( ( size.GetWidth() == 0 && size.GetHeight() == 0 ) || ( fittingMode == textureInfo.fittingMode && samplingMode == textureInfo.samplingMode ) ) ) @@ -883,6 +1047,7 @@ void TextureManager::ObserverDestroyed( TextureUploadObserver* observer ) } } + TextureManager::AsyncLoadingHelper::AsyncLoadingHelper(TextureManager& textureManager) : AsyncLoadingHelper(Toolkit::AsyncImageLoader::New(), textureManager, AsyncLoadingInfoContainerType()) @@ -924,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