#include <deque>
#include <functional>
#include <string>
+#include <memory>
#include <dali/public-api/common/dali-vector.h>
#include <dali/public-api/object/ref-object.h>
#include <dali/public-api/rendering/texture-set.h>
namespace Internal
{
+class ImageAtlasManager;
+typedef IntrusivePtr<ImageAtlasManager> ImageAtlasManagerPtr;
/**
* The TextureManager provides a common Image loading API for Visuals.
LOAD_FAILED ///< Async loading failed, e.g. connection problem
};
+ /**
+ * @brief Types of reloading policies
+ */
+ enum class ReloadPolicy
+ {
+ CACHED = 0, ///< Loads cached texture if it exists.
+ FORCED ///< Forces reloading of texture.
+ };
+
+ /**
+ * @brief Whether to multiply alpha into color channels on load
+ */
+ enum class MultiplyOnLoad
+ {
+ LOAD_WITHOUT_MULTIPLY = 0, ///< Don't modify the image
+ MULTIPLY_ON_LOAD ///< Multiply alpha into color channels on load
+ };
+
public:
+ struct MaskingData
+ {
+ MaskingData();
+ ~MaskingData() = default;
+
+ VisualUrl mAlphaMaskUrl;
+ TextureManager::TextureId mAlphaMaskId;
+ float mContentScaleFactor;
+ bool mCropToMask;
+ };
+ using MaskingDataPointer = std::unique_ptr<MaskingData>;
+
+
+ /**
+ * Class to provide lifecycle event on destruction of texture manager.
+ */
+ struct LifecycleObserver
+ {
+ /**
+ * Called shortly before the texture manager is destroyed.
+ */
+ virtual void TextureManagerDestroyed() = 0;
+ };
+
/**
* Constructor.
*/
*/
~TextureManager();
-
// TextureManager Main API:
/**
*
* 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] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful,
- * but "useAtlasing" will be set to false in the "UploadCompleted" callback from the TextureManagerUploadObserver.
- * @param[in] observer The client object should inherit from this and provide the "UploadCompleted" virtual.
- * This is called when an image load completes (or fails).
- * @return A TextureId to use as a handle to reference this Texture
- */
- TextureId RequestLoad( const VisualUrl& url,
- const ImageDimensions desiredSize,
- FittingMode::Type fittingMode,
- Dali::SamplingMode::Type samplingMode,
- const UseAtlas useAtlasing,
- TextureUploadObserver* observer );
+ * @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.
+ *
+ * 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] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful,
+ * but "useAtlasing" will be set to false in the "UploadCompleted" callback from the TextureManagerUploadObserver.
+ * @param[in] observer The client object should inherit from this and provide the "UploadCompleted" virtual.
+ * 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,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,
+ const ImageDimensions desiredSize,
+ FittingMode::Type fittingMode,
+ Dali::SamplingMode::Type samplingMode,
+ const UseAtlas useAtlasing,
+ TextureUploadObserver* observer,
+ bool orientationCorrection,
+ TextureManager::ReloadPolicy reloadPolicy,
+ MultiplyOnLoad& preMultiplyOnLoad );
/**
* @brief Requests an image load of the given URL, when the texture has
*
* When the client has finished with the Texture, Remove() should be called.
*
- * @param[in] url The URL of the image to load
- * @param[in] maskTextureId The texture id of an image to mask this with (can be INVALID if no masking required)
- * @param[in] contentScale The scale factor to apply to the image before masking
- * @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] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful,
- * but "useAtlasing" will be set to false in the "UploadCompleted" callback from the TextureManagerUploadObserver.
- * @param[in] cropToMask Only used with masking, this will crop the scaled image to the mask size. If false, then the mask will be scaled to fit the image before being applied.
- * @param[in] observer The client object should inherit from this and provide the "UploadCompleted" virtual.
- * This is called when an image load completes (or fails).
- * @return A TextureId to use as a handle to reference this Texture
- */
- TextureId RequestLoad( const VisualUrl& url,
- TextureId maskTextureId,
- float contentScale,
- const ImageDimensions desiredSize,
- FittingMode::Type fittingMode,
- Dali::SamplingMode::Type samplingMode,
- const UseAtlas useAtlasing,
- bool cropToMask,
- TextureUploadObserver* observer );
+ * @param[in] url The URL of the image to load
+ * @param[in] maskTextureId The texture id of an image to mask this with
+ * (can be INVALID if no masking required)
+ * @param[in] contentScale The scale factor to apply to the image before masking
+ * @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] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still
+ * be loaded, and marked successful,
+ * but "useAtlasing" will be set to false in the "UploadCompleted" callback from
+ * the TextureManagerUploadObserver.
+ * @param[in] cropToMask Only used with masking, this will crop the scaled image to the mask size.
+ * If false, then the mask will be scaled to fit the image before being applied.
+ * @param[in] observer The client object should inherit from this and provide the "UploadCompleted"
+ * virtual.
+ * 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. 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,
+ TextureId maskTextureId,
+ float contentScale,
+ const ImageDimensions desiredSize,
+ FittingMode::Type fittingMode,
+ Dali::SamplingMode::Type samplingMode,
+ const UseAtlas useAtlasing,
+ bool cropToMask,
+ TextureUploadObserver* observer,
+ bool orientationCorrection,
+ TextureManager::ReloadPolicy reloadPolicy,
+ MultiplyOnLoad& preMultiplyOnLoad );
/**
* Requests a masking image to be loaded. This mask is not uploaded to GL,
*/
TextureSet RemoveExternalTexture( const std::string& url );
+ /**
+ * Add an observer to the object.
+ * @param[in] observer The observer to add.
+ */
+ void AddObserver( TextureManager::LifecycleObserver& observer );
+
+ /**
+ * Remove an observer from the object
+ * @pre The observer has already been added.
+ * @param[in] observer The observer to remove.
+ */
+ void RemoveObserver( TextureManager::LifecycleObserver& observer );
+
private:
/**
*
* When the client has finished with the Texture, Remove() should be called.
*
- * @param[in] url The URL of the image to load
- * @param[in] maskTextureId The texture id of an image to use as a mask. If no mask is required, then set to INVALID_TEXTURE_ID
- * @param[in] contentScale The scaling factor to apply to the content when masking
- * @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] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful,
- * but "useAtlasing" will be set to false in the "UploadCompleted" callback from the TextureManagerUploadObserver.
- * @param[in] cropToMask Whether to crop the target after masking, or scale the mask to the image before masking.
- * @param[in] storageType, Whether the pixel data is stored in the cache or uploaded to the GPU
- * @param[in] observer The client object should inherit from this and provide the "UploadCompleted" virtual.
- * This is called when an image load completes (or fails).
- * @return A TextureId to use as a handle to reference this Texture
+ * @param[in] url The URL of the image to load
+ * @param[in] maskTextureId The texture id of an image to use as a mask. If no mask is required, then set
+ * to INVALID_TEXTURE_ID
+ * @param[in] contentScale The scaling factor to apply to the content when masking
+ * @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] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be
+ * loaded, and marked successful, but "useAtlasing" will be set to false in the
+ * "UploadCompleted" callback from the TextureManagerUploadObserver.
+ * @param[in] cropToMask Whether to crop the target after masking, or scale the mask to the image before
+ * masking.
+ * @param[in] storageType, Whether the pixel data is stored in the cache or uploaded to the GPU
+ * @param[in] observer The client object should inherit from this and provide the "UploadCompleted"
+ * virtual.
+ * 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. Set to false if
+ * there is no alpha
+ * @return A TextureId to use as a handle to reference this Texture
*/
TextureId 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 );
+ 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,
+ MultiplyOnLoad& preMultiplyOnLoad );
+ /**
+ * @brief Get the current state of a texture
+ * @param[in] textureId The texture id to query
+ * @return The loading state if the texture is valid, or NOT_STARTED if the textureId
+ * is not valid.
+ */
+ LoadState GetTextureStateInternal( TextureId textureId );
typedef size_t TextureHash; ///< The type used to store the hash used for Texture caching.
bool loadSynchronously,
bool cropToMask,
UseAtlas useAtlas,
- TextureManager::TextureHash hash )
+ TextureManager::TextureHash hash,
+ bool orientationCorrection,
+ bool preMultiplyOnLoad )
: url( url ),
desiredSize( desiredSize ),
useSize( desiredSize ),
storageType( UPLOAD_TO_TEXTURE ),
loadSynchronously( loadSynchronously ),
useAtlas( useAtlas ),
- cropToMask( cropToMask )
+ cropToMask( cropToMask ),
+ orientationCorrection( true ),
+ preMultiplyOnLoad( preMultiplyOnLoad ),
+ preMultiplied( false )
{
}
Dali::SamplingMode::Type samplingMode:3; ///< The requested SamplingMode
StorageType storageType:1; ///< CPU storage / GPU upload;
bool loadSynchronously:1; ///< True if synchronous loading was requested
- UseAtlas useAtlas:1; ///< USE_ATLAS if an atlas was requested. This is updated to false if atlas is not used
+ UseAtlas useAtlas:1; ///< USE_ATLAS if an atlas was requested.
+ ///< 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
+ 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:
}
TextureId textureId; ///< The external Texture Id assigned to 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
+ uint32_t loadId; ///< The load Id used by the async loader to reference this load
};
// 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
/**
TextureHash GenerateHash( const std::string& url, const ImageDimensions size,
const FittingMode::Type fittingMode,
const Dali::SamplingMode::Type samplingMode, const UseAtlas useAtlas,
- TextureId maskTextureId );
+ TextureId maskTextureId,
+ MultiplyOnLoad preMultiplyOnLoad);
/**
* @brief Looks up a cached texture by its hash.
* If found, the given parameters are used to check there is no hash-collision.
const FittingMode::Type fittingMode,
const Dali::SamplingMode::Type samplingMode,
const bool useAtlas,
- TextureId maskTextureId );
+ TextureId maskTextureId,
+ MultiplyOnLoad preMultiplyOnLoad);
private:
* @brief Load a new texture.
* @param[in] textureId TextureId to reference the texture that will be loaded
* @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] 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] orientationCorrection Whether to use image metadata to rotate or flip the image, e.g., from portrait to landscape
+ * @param[in] orientationCorrection Whether to use image metadata to rotate or flip the image,
+ * e.g., from portrait to landscape
*/
void Load(TextureId textureId,
const VisualUrl& url,
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
std::vector< ExternalTextureInfo > mExternalTextures; ///< Externally provided textures
+ Dali::Vector<LifecycleObserver*> mLifecycleObservers; ///< Lifecycle observers of texture manager
TextureId mCurrentTextureId; ///< The current value used for the unique Texture Id generation
-
};