To prevent scaling quality issues, image visual images are pre-multiplied after loading.
By default, this is on, but it can be turned off via a new API in VisualFactory.
Conflicts:
automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dummy-visual.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp
dali-toolkit/devel-api/visual-factory/visual-factory.h
dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp
dali-toolkit/internal/visuals/animated-image/rolling-gif-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/texture-manager-impl.cpp
dali-toolkit/internal/visuals/texture-manager-impl.h
dali-toolkit/internal/visuals/visual-factory-cache.h
dali-toolkit/internal/visuals/visual-factory-impl.cpp
dali-toolkit/internal/visuals/visual-factory-impl.h
Change-Id: Id1606e156f2d31d858bb4ddc65cbf97ed3efba5c
Signed-off-by: David Steele <david.steele@samsung.com>
namespace Internal
{
-typedef IntrusivePtr<VisualFactoryCache> VisualFactoryCachePtr;
-
DummyVisualPtr DummyVisual::New( const Property::Map& properties )
{
- VisualFactoryCachePtr factoryCache = new VisualFactoryCache(false);
+ VisualFactoryCache* factoryCache = new VisualFactoryCache(false);
- DummyVisualPtr dummyVisualPtr( new DummyVisual( *( factoryCache.Get() ) ) );
+ DummyVisualPtr dummyVisualPtr( new DummyVisual( *factoryCache ) );
return dummyVisualPtr;
}
{
}
- void UploadComplete( bool loadSuccess, int32_t textureId, TextureSet textureSet, bool useAtlasing, const Vector4& atlasRect )
+ virtual void UploadComplete( bool loadSuccess, int32_t textureId, TextureSet textureSet,
+ bool useAtlasing, const Vector4& atlasRect, bool preMultiplied ) override
{
mLoaded = loadSuccess;
mObserverCalled = true;
TestObserver observer;
std::string filename("image.png");
-
+ auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
TextureManager::TextureId textureId = textureManager.RequestLoad(
filename,
ImageDimensions(),
&observer,
true,
TextureManager::ReloadPolicy::CACHED,
- TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY );
+ preMultiply);
const VisualUrl& url = textureManager.GetVisualUrl( textureId );
}
+int UtcDaliImageVisualNoPremultipliedAlpha02(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline( "Request image visual with no alpha channel" );
+
+ VisualFactory factory = VisualFactory::Get();
+ DALI_TEST_CHECK( factory );
+
+ Property::Map propertyMap;
+ propertyMap.Insert( Toolkit::Visual::Property::TYPE, Visual::IMAGE );
+ propertyMap.Insert( ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME );
+
+ Visual::Base visual = factory.CreateVisual( propertyMap );
+ DALI_TEST_CHECK( visual );
+
+ // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied.
+ // Image with a size smaller than 512*512 will be uploaded as a part of the atlas.
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ DummyControl actor = DummyControl::New();
+ DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+ dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+
+ actor.SetSize( 200.f, 200.f );
+ DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION );
+
+ Stage::GetCurrent().Add( actor );
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
+ auto renderer = actor.GetRendererAt(0);
+ auto preMultipliedIndex = renderer.GetPropertyIndex( "preMultipliedAlpha" );
+ DALI_TEST_CHECK( preMultipliedIndex != Property::INVALID_INDEX );
+ auto preMultipliedAlpha = renderer.GetProperty<bool>( preMultipliedIndex );
+ auto preMultipliedAlpha2 = renderer.GetProperty<bool>( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA );
+
+ DALI_TEST_EQUALS( preMultipliedAlpha, false, TEST_LOCATION );
+ DALI_TEST_EQUALS( preMultipliedAlpha2, false, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
+
+ Stage::GetCurrent().Remove( actor );
+ DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+
+ END_TEST;
+}
+
+
int UtcDaliImageVisualRemoteImageLoad(void)
{
ToolkitTestApplication application;
*
* The default is to enable pre-multiplication on load.
*
- * Applications that have assets with pre-multiplied alpha already applied should
- * turn this option off.
+ * Applications that have assets with pre-multiplied alpha already applied should turn this option off.
*
- * @param[in] preMultiply True if loaded images for image visuals should have
- * alpha multiplied into the color channels.
+ * @param[in] preMultiply True if loaded images for image visuals should have alpha multiplied into the color
+ * channels.
*/
void SetPreMultiplyOnLoad( bool preMultiply );
/**
- * @brief Get the setting for automatically pre-multiplying image visual images
- * on load.
+ * @brief Get the setting for automatically pre-multiplying image visual images on load.
*
- * @return True if loaded images have pre-multiplied alpha applied on load,
- * false otherwise.
+ * @return True if loaded images have pre-multiplied alpha applied on load, false otherwise.
*/
bool GetPreMultiplyOnLoad() const;
AtlasUploadObserver* atlasObserver = nullptr;
ImageAtlasManagerPtr imageAtlasManager = nullptr;
Vector4 textureRect;
+ auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
mTextureManager.LoadTexture(
url, ImageDimensions(), FittingMode::SCALE_TO_FILL,
atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT,
Dali::WrapMode::Type::DEFAULT, this,
atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED,
- TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY );
+ preMultiply );
if( loadingStatus == false ) // not loading, means it's already ready.
{
int32_t textureId,
TextureSet textureSet,
bool useAtlasing,
- const Vector4& atlasRect )
+ const Vector4& atlasRect,
+ bool preMultiplied)
{
bool frontFrameReady = IsFrontReady();
int32_t textureId,
TextureSet textureSet,
bool useAtlasing,
- const Vector4& atlasRect );
+ const Vector4& atlasRect,
+ bool premultiplied) override;
private:
std::vector<UrlStore>& mImageUrls;
AtlasUploadObserver* atlasObserver = nullptr;
ImageAtlasManagerPtr imageAtlasManager = nullptr;
Vector4 textureRect;
+ auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
mTextureManager.LoadTexture(
mImageUrls[ imageFrame.mFrameNumber ].mUrl, ImageDimensions(), FittingMode::SCALE_TO_FILL,
synchronousLoading, mImageUrls[ imageFrame.mFrameNumber ].mTextureId, textureRect,
atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT,
Dali::WrapMode::Type::DEFAULT, NULL,
- atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY );
+ atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply );
}
mFrameIndex += batchSize;
AtlasUploadObserver* atlasObserver = nullptr;
ImageAtlasManagerPtr imageAtlasManager = nullptr;
Vector4 textureRect;
+ auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
mTextureManager.LoadTexture(
url, ImageDimensions(), FittingMode::SCALE_TO_FILL,
atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT,
Dali::WrapMode::Type::DEFAULT, this,
atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED,
- TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY );
+ preMultiply );
mRequestingLoad = false;
}
int32_t textureId,
TextureSet textureSet,
bool useAtlasing,
- const Vector4& atlasRect )
+ const Vector4& atlasRect,
+ bool preMultiplied )
{
DALI_LOG_INFO(gAnimImgLogFilter,Debug::Concise,"AnimatedImageVisual::UploadComplete(textureId:%d) start\n", textureId);
LOG_CACHE;
int32_t textureId,
TextureSet textureSet,
bool useAtlasing,
- const Vector4& atlasRect );
+ const Vector4& atlasRect,
+ bool preMultiplied ) override;
private:
/**
mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
}
-
bool ImageVisual::IsSynchronousResourceLoading() const
{
return mImpl->mFlags & Impl::IS_SYNCHRONOUS_RESOURCE_LOADING;
mWrapModeV, textureObserver, atlasUploadObserver, atlasManager,
mOrientationCorrection, forceReload, preMultiplyOnLoad);
- if( preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD)
+ if( textures && preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD)
{
EnablePreMultipliedAlpha( true );
}
// From Texture Manager
void ImageVisual::UploadComplete( bool loadingSuccess, int32_t textureId, TextureSet textureSet, bool usingAtlas,
- const Vector4& atlasRectangle )
+ const Vector4& atlasRectangle, bool preMultiplied )
{
Toolkit::Visual::ResourceStatus resourceStatus;
Actor actor = mPlacementActor.GetHandle();
{
mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, mAtlasRect );
}
+ else if( preMultiplied )
+ {
+ EnablePreMultipliedAlpha( true );
+ }
actor.AddRenderer( mImpl->mRenderer );
// reset the weak handle so that the renderer only get added to actor once
* To avoid rendering garbage pixels, renderer should be added to actor after the resources are ready.
* This callback is the place to add the renderer as it would be called once the loading is finished.
*/
- virtual void UploadCompleted();
+ virtual void UploadCompleted() override;
/**
* @copydoc TextureUploadObserver::UploadCompleted
* To avoid rendering garbage pixels, renderer should be added to actor after the resources are ready.
* This callback is the place to add the renderer as it would be called once the loading is finished.
*/
- virtual void UploadComplete( bool success, int32_t textureId, TextureSet textureSet, bool usingAtlas, const Vector4& atlasRectangle );
+ virtual void UploadComplete( bool success, int32_t textureId, TextureSet textureSet,
+ bool usingAtlas, const Vector4& atlasRectangle, bool preMultiplied ) override;
private:
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()
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 )
+ TextureManager::ReloadPolicy reloadPolicy, TextureManager::MultiplyOnLoad& preMultiplyOnLoad )
{
TextureSet textureSet;
orientationCorrection );
if( pixelBuffer )
{
- if( preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD )
- {
- pixelBuffer.MultiplyColorByAlpha();
- }
-
+ PreMultiply( pixelBuffer, preMultiplyOnLoad );
data = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer
}
}
Devel::PixelBuffer pixelBuffer = LoadImageFromFile( BROKEN_IMAGE_URL );
if( pixelBuffer )
{
- if( preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD)
- {
- pixelBuffer.MultiplyColorByAlpha();
- }
+ PreMultiply( pixelBuffer, preMultiplyOnLoad );
data = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer
}
Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, data.GetPixelFormat(),
}
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,
- TextureManager::MultiplyOnLoad preMultiplyOnLoad )
+ 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, preMultiplyOnLoad );
+ 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,
- TextureManager::MultiplyOnLoad preMultiplyOnLoad )
+ 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, preMultiplyOnLoad );
+ 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::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY);
+ TextureManager::ReloadPolicy::CACHED, preMultiply );
}
TextureManager::TextureId TextureManager::RequestLoadInternal(
- const VisualUrl& url,
- TextureId maskTextureId,
- float contentScale,
- const ImageDimensions desiredSize,
- FittingMode::Type fittingMode,
- Dali::SamplingMode::Type samplingMode,
- UseAtlas useAtlas,
- bool cropToMask,
- StorageType storageType,
- TextureUploadObserver* observer,
- bool orientationCorrection,
- TextureManager::ReloadPolicy reloadPolicy,
- TextureManager::MultiplyOnLoad preMultiplyOnLoad)
+ const VisualUrl& url,
+ TextureId maskTextureId,
+ float contentScale,
+ const ImageDimensions desiredSize,
+ FittingMode::Type fittingMode,
+ Dali::SamplingMode::Type samplingMode,
+ UseAtlas useAtlas,
+ bool cropToMask,
+ StorageType storageType,
+ TextureUploadObserver* observer,
+ bool orientationCorrection,
+ TextureManager::ReloadPolicy reloadPolicy,
+ TextureManager::MultiplyOnLoad& preMultiplyOnLoad)
{
// First check if the requested Texture is cached.
const TextureHash textureHash = GenerateHash( url.GetUrl(), desiredSize, fittingMode, samplingMode, useAtlas,
{
// 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, preMultiplyOnLoad ) );
+ 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",
// 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;
}
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() );
- if( textureInfo.preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD )
- {
- pixelBuffer.MultiplyColorByAlpha();
- }
PixelData pixelData = Devel::PixelBuffer::Convert( pixelBuffer );
texture.Upload( pixelData );
// 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
auto premultipliedIndex = hashTarget.length();
hashTarget.resize( premultipliedIndex + 1 );
- char* preMultPtr = &( hashTarget[ premultipliedIndex ] );
- *preMultPtr = (preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD) ? 't':'f';
+ 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 );
}
{
// 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 == textureInfo.preMultiplyOnLoad ) &&
+ ( preMultiplyOnLoad == multiplyOnLoad ) &&
( ( size.GetWidth() == 0 && size.GetHeight() == 0 ) ||
( fittingMode == textureInfo.fittingMode &&
samplingMode == textureInfo.samplingMode ) ) )
// TextureManager Main API:
- TextureSet 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,
- MultiplyOnLoad preMultiplyOnLoad );
+ /**
+ * @brief Requests an image load of the given URL.
+ *
+ * The parameters are used to specify how the image is loaded.
+ * The observer has the UploadComplete method called when the load is ready.
+ *
+ * When the client has finished with the Texture, Remove() should be called.
+ *
+ * @param[in] url The URL of the image to load
+ * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
+ * @param[in] fittingMode The FittingMode to use
+ * @param[in] samplingMode The SamplingMode to use
+ * @param[in] maskInfo Mask info structure
+ * @param[in] synchronousLoading true if the URL should be loaded synchronously
+ * @param[out] textureId, The textureId of the URL
+ * @param[out] textureRect The rectangle within the texture atlas that this URL occupies
+ * @param[in,out] atlasingStatus Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still
+ * 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 "UploadCompleted" 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
+ * textureObserver.UploadCompleted
+ * @param[in] imageAtlasManager The atlas manager to use for atlasing textures
+ * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
+ * @param[in] reloadPolicy Forces a reload of the texture even if already cached
+ * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
+ * image has no alpha channel
+ *
+ * @return The texture set containing the image, or empty if still loading.
+ */
+
+ TextureSet 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,
+ MultiplyOnLoad& preMultiplyOnLoad );
/**
* @brief Requests an image load of the given URL.
* This is called when an image load completes (or fails).
* @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
* @param[in] reloadPolicy Forces a reload of the texture even if already cached
- * @param[in] preMultiplyOnLoad True if the image color should be multiplied by it's alpha
+ * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the image has no alpha channel
* @return A TextureId to use as a handle to reference this Texture
*/
TextureId RequestLoad( const VisualUrl& url,
TextureUploadObserver* observer,
bool orientationCorrection,
TextureManager::ReloadPolicy reloadPolicy,
- MultiplyOnLoad preMultiplyOnLoad );
+ MultiplyOnLoad& preMultiplyOnLoad );
/**
* @brief Requests an image load of the given URL, when the texture has
* This is called when an image load completes (or fails).
* @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
* @param[in] reloadPolicy Forces a reload of the texture even if already cached
- * @param[in] preMultiplyOnLoad True if the image color should be multiplied by it's alpha
+ * @param[in] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
+ * image has no alpha channel
* @return A TextureId to use as a handle to reference this Texture
*/
TextureId RequestLoad( const VisualUrl& url,
TextureUploadObserver* observer,
bool orientationCorrection,
TextureManager::ReloadPolicy reloadPolicy,
- MultiplyOnLoad preMultiplyOnLoad );
+ MultiplyOnLoad& preMultiplyOnLoad );
/**
* Requests a masking image to be loaded. This mask is not uploaded to GL,
* This is called when an image load completes (or fails).
* @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
* @param[in] reloadPolicy Forces a reload of the texture even if already cached
- * @param[in] preMultiplyOnLoad True if the image color should be multiplied by it's alpha
+ * @param[in] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if
+ * there is no alpha
* @return A TextureId to use as a handle to reference this Texture
*/
TextureId RequestLoadInternal(
TextureUploadObserver* observer,
bool orientationCorrection,
TextureManager::ReloadPolicy reloadPolicy,
- MultiplyOnLoad preMultiplyOnLoad );
+ MultiplyOnLoad& preMultiplyOnLoad );
/**
* @brief Get the current state of a texture
UseAtlas useAtlas,
TextureManager::TextureHash hash,
bool orientationCorrection,
- MultiplyOnLoad preMultiplyOnLoad )
+ bool preMultiplyOnLoad )
: url( url ),
desiredSize( desiredSize ),
useSize( desiredSize ),
useAtlas( useAtlas ),
cropToMask( cropToMask ),
orientationCorrection( true ),
- preMultiplyOnLoad( preMultiplyOnLoad )
+ preMultiplyOnLoad( preMultiplyOnLoad ),
+ preMultiplied( false )
{
}
///< This is updated to false if atlas is not used
bool cropToMask:1; ///< true if the image should be cropped to the mask size.
bool orientationCorrection:1; ///< true if the image should be rotated to match exif orientation data
- MultiplyOnLoad preMultiplyOnLoad; ///< true if the image's color should be multiplied by it's alpha
+ bool preMultiplyOnLoad:1; ///< true if the image's color should be multiplied by it's alpha
+ bool preMultiplied:1; ///< true if the image's color was multiplied by it's alpha
};
// Structs:
* @param[in] textureSet The TextureSet containing the Texture
* @param[in] useAtlasing True if atlasing was used (note: this may be different to what was requested)
* @param[in] atlasRect If using atlasing, this is the rectangle within the atlas to use.
+ * @param[in] preMultiplied True if the image had pre-multiplied alpha applied
*/
- virtual void UploadComplete( bool loadSuccess, int32_t textureId, TextureSet textureSet, bool useAtlasing, const Vector4& atlasRect ) = 0;
+ virtual void UploadComplete( bool loadSuccess, int32_t textureId, TextureSet textureSet, bool useAtlasing,
+ const Vector4& atlasRect, bool preMultiplied ) = 0;
/**
* @brief Returns the destruction signal.
/**
* Caches shaders and geometries. Owned by VisualFactory.
*/
-class VisualFactoryCache : public RefObject
+class VisualFactoryCache
{
public:
VisualFactoryCache( bool preMultiplyOnLoad );
/**
+ * @brief Destructor
+ */
+ ~VisualFactoryCache();
+
+ /**
* Request geometry of the given type.
* @return The geometry of the required type if it exist in the cache. Otherwise, an empty handle is returned.
*/
protected:
/**
- * A reference counted object may only be deleted by calling Unreference()
- */
- virtual ~VisualFactoryCache();
-
- /**
* Undefined copy constructor.
*/
VisualFactoryCache(const VisualFactoryCache&);
{
if( !mFactoryCache )
{
- mFactoryCache = new VisualFactoryCache( mPreMultiplyOnLoad );
+ mFactoryCache = std::unique_ptr<VisualFactoryCache>( new VisualFactoryCache( mPreMultiplyOnLoad ) );
}
- return *(mFactoryCache.Get());
+ return *mFactoryCache;
}
} // namespace Internal
{
class VisualFactoryCache;
-typedef IntrusivePtr<VisualFactoryCache> VisualFactoryCachePtr;
/**
* @copydoc Toolkit::VisualFactory
VisualFactory& operator=(const VisualFactory& rhs) = delete;
private:
-
- VisualFactoryCachePtr mFactoryCache;
- bool mDebugEnabled:1;
- bool mPreMultiplyOnLoad:1; ///< Local store for this flag ( as mFactoryCache is lazy laoded )
+ std::unique_ptr<VisualFactoryCache> mFactoryCache;
+ bool mDebugEnabled:1;
+ bool mPreMultiplyOnLoad:1; ///< Local store for this flag
};
/**