namespace Internal
{
+class MaskTextureObserver;
+
/**
* The TextureManager provides a common Image loading API for Visuals.
*
typedef int32_t TextureId; ///< The TextureId type. This is used as a handle to refer to a particular Texture.
static const int INVALID_TEXTURE_ID = -1; ///< Used to represent a null TextureId or error
+ /**
+ * Whether the texture should be atlased or uploaded into it's own GPU texture
+ */
enum UseAtlas
{
NO_ATLAS,
USE_ATLAS
};
+ /**
+ * Whether the texture should be stored in CPU memory, or uploaded to a GPU texture
+ */
+ enum StorageType
+ {
+ CPU,
+ GPU_UPLOAD
+ };
+
+ /**
+ * Whether the texture should be loaded synchronously or asynchronously.
+ */
enum LoadType
{
LOAD_ASYNCHRONOUSLY,
};
/**
- * @brief The LoadState Enumeration represents the current state of a particular Textures life-cycle.
+ * @brief The LoadState Enumeration represents the current state of a particular Texture's life-cycle.
*/
enum LoadState
{
NOT_STARTED, ///< Default
LOADING, ///< Loading has been started, but not finished.
- UPLOADED, ///< Loaded (and ready).
+ LOAD_FINISHED, ///< Loading has finished. (for CPU storage only)
+ WAITING_FOR_MASK,///< Loading has finished, but waiting for mask image
+ UPLOADED, ///< Uploaded and ready. (For GPU upload only)
CANCELLED, ///< Removed before loading completed
+ LOAD_FAILED ///< Async loading failed, e.g. connection problem
};
public:
~TextureManager();
-// TextureManager Main API:
+ // TextureManager Main API:
/**
* @brief Requests an image load of the given URL.
TextureUploadObserver* observer );
/**
+ * @brief Requests an image load of the given URL, when the texture has
+ * have loaded, it will perform a CPU blend with the image mask, and upload
+ * the blend texture.
+ *
+ * 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).
+ * @return A TextureId to use as a handle to reference this Texture
+ */
+ TextureId RequestLoad( const VisualUrl& url,
+ TextureId maskTextureId,
+ const ImageDimensions desiredSize,
+ FittingMode::Type fittingMode,
+ Dali::SamplingMode::Type samplingMode,
+ const UseAtlas useAtlasing,
+ TextureUploadObserver* observer );
+
+ /**
+ * Requests a masking image to be loaded. This mask is not uploaded to GL,
+ * instead, it is stored in CPU memory, and can be used for CPU blending.
+ */
+ TextureId RequestMaskLoad( const VisualUrl& maskUrl );
+
+ /**
* @brief Remove a Texture from the TextureManager.
*
* Textures are cached and therefore only the removal of the last
private:
+ /**
+ * @brief Requests an image load of the given URL, when the texture has
+ * have loaded, if there is a valid maskTextureId, it will perform a
+ * CPU blend with the mask, and upload the blend texture.
+ *
+ * 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] 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] 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] 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
+ */
+ TextureId RequestInternalLoad(
+ const VisualUrl& url,
+ TextureId maskTextureId,
+ const ImageDimensions desiredSize,
+ FittingMode::Type fittingMode,
+ Dali::SamplingMode::Type samplingMode,
+ UseAtlas useAtlas,
+ StorageType storageType,
+ TextureUploadObserver* observer );
+
typedef size_t TextureHash; ///< The type used to store the hash used for Texture caching.
/**
* @brief This struct is used to manage the life-cycle of Texture loading and caching.
- * TODO-TX: pimpl this
*/
struct TextureInfo
{
TextureInfo( TextureId textureId,
+ TextureId maskTextureId,
const VisualUrl& url,
ImageDimensions desiredSize,
FittingMode::Type fittingMode,
useSize( desiredSize ),
atlasRect( 0.0f, 0.0f, 1.0f, 1.0f ), // Full atlas rectangle
textureId( textureId ),
+ maskTextureId( maskTextureId ),
hash( hash ),
referenceCount( 1u ),
loadState( NOT_STARTED ),
fittingMode( fittingMode ),
samplingMode( samplingMode ),
+ storageType( GPU_UPLOAD ),
loadSynchronously( loadSynchronously ),
- useAtlas( useAtlas ),
- loadingSucceeded( false )
+ useAtlas( useAtlas )
{
}
ObserverListType observerList; ///< Container used to store all observer clients of this Texture
Toolkit::ImageAtlas atlas; ///< The atlas this Texture lays within (if any)
- PixelData pixelData; ///< The PixelData holding the image data (this is used if atlasing is deferred)
+ PixelData pixelData; ///< The PixelData holding the image data (this is used if atlasing is deferred or CPU storage is required)
TextureSet textureSet; ///< The TextureSet holding the Texture
VisualUrl url; ///< The URL of the image
ImageDimensions desiredSize; ///< The size requested
ImageDimensions useSize; ///< The size used
Vector4 atlasRect; ///< The atlas rect used if atlased
TextureId textureId; ///< The TextureId associated with this Texture
+ TextureId maskTextureId; ///< The mask TextureId to be applied on load
TextureManager::TextureHash hash; ///< The hash used to cache this Texture
int16_t referenceCount; ///< The reference count of clients using this Texture
LoadState loadState:3; ///< The load state showing the load progress of the Texture
FittingMode::Type fittingMode:2; ///< The requested FittingMode
Dali::SamplingMode::Type samplingMode:3; ///< The requested SamplingMode
- bool loadSynchronously; ///< True if synchronous loading was requested
- UseAtlas useAtlas; ///< USE_ATLAS if an atlas was requested. This is updated to false if atlas is not used
- bool loadingSucceeded; ///< True if the image was loaded successfully
+ 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
};
// Structs:
/**
* @brief Performs Post-Load steps including atlasing.
- * @param[in] textureInfo The struct associated with this Texture
- * @param[in] pixelData The image pixelData
- * @return True if successful
+ * @param[in] textureInfo The struct associated with this Texture
+ * @param[in] pixelData The image pixelData
+ * @return True if successful
*/
- bool PostLoad( TextureManager::TextureInfo& textureInfo, PixelData pixelData );
+ void PostLoad( TextureManager::TextureInfo& textureInfo, PixelData pixelData );
+
+ /**
+ * Check if there is a texture waiting to be masked. If there
+ * is then apply this mask and upload it.
+ * @param[in] maskTextureInfo The texture info of the mask that has just loaded.
+ */
+ void CheckForWaitingTexture( TextureInfo& maskTextureInfo );
+
+ /**
+ * Apply the mask texture to the image texture.
+ * @param[in] pixelData The image pixelData to apply the mask to
+ * @param[in] maskTextureId The texture id of the mask.
+ */
+ void ApplyMask( PixelData pixelData, TextureId maskTextureId );
+
+ /**
+ * Upload the texture specified in pixelData to the appropriate location
+ * @param[in] pixelData The image data to upload
+ * @param[in] textureInfo The texture info containing the location to
+ * store the data to.
+ */
+ void UploadTexture( PixelData pixelData, TextureInfo& textureInfo );
+
+ /**
+ * Mark the texture as complete, and inform observers
+ * @param[in] textureInfo The struct associated with this Texture
+ */
+ void UploadComplete( TextureInfo& textureInfo );
+
+ /**
+ * Notify the current observers that the texture upload is complete,
+ * then remove the observers from the list.
+ * @param[in] textureInfo The struct associated with this Texture
+ * @param[in] success If the pixel data was retrieved successfully and uploaded to GPU
+ */
+ void NotifyObservers( TextureInfo& textureInfo, bool success );
/**
* @brief Generates a new, unique TextureId
/**
* @brief Generates a hash for caching based on the input parameters.
+ * Only applies size, fitting mode andsampling mode if the size is specified.
+ * Only applies maskTextureId if it isn't INVALID_TEXTURE_ID
+ * Always applies useAtlas.
* @param[in] url The URL of the image to load
* @param[in] size The image size
* @param[in] fittingMode The FittingMode to use
* @param[in] samplingMode The SamplingMode to use
* @param[in] useAtlas True if atlased
+ * @param[in] maskTextureId The masking texture id (or INVALID_TEXTURE_ID)
* @return A hash of the provided data for caching.
*/
TextureHash GenerateHash( const std::string& url, const ImageDimensions size,
const FittingMode::Type fittingMode,
- const Dali::SamplingMode::Type samplingMode, const UseAtlas useAtlas );
+ const Dali::SamplingMode::Type samplingMode, const UseAtlas useAtlas,
+ TextureId maskTextureId );
/**
* @brief Looks up a cached texture by its hash.
* If found, the given parameters are used to check there is no hash-collision.
- * @param[in] hash The hash to look up
- * @param[in] url The URL of the image to load
- * @param[in] size The image size
- * @param[in] fittingMode The FittingMode to use
- * @param[in] samplingMode The SamplingMode to use
- * @param[in] useAtlas True if atlased
- * @return A TextureId of a cached Texture if found. Or INVALID_TEXTURE_ID if not found.
+ * @param[in] hash The hash to look up
+ * @param[in] url The URL of the image to load
+ * @param[in] size The image size
+ * @param[in] fittingMode The FittingMode to use
+ * @param[in] samplingMode The SamplingMode to use
+ * @param[in] useAtlas True if atlased
+ * @param[in] maskTextureId Optional texture ID to use to mask this image
+ * @return A TextureId of a cached Texture if found. Or INVALID_TEXTURE_ID if not found.
*/
- TextureManager::TextureId FindCachedTexture( const TextureManager::TextureHash hash, const std::string& url, const ImageDimensions size,
- const FittingMode::Type fittingMode, const Dali::SamplingMode::Type samplingMode, const bool useAtlas );
+ TextureManager::TextureId FindCachedTexture(
+ const TextureManager::TextureHash hash,
+ const std::string& url,
+ const ImageDimensions size,
+ const FittingMode::Type fittingMode,
+ const Dali::SamplingMode::Type samplingMode,
+ const bool useAtlas,
+ TextureId maskTextureId );
private: