*/
// EXTERNAL INCLUDES
+#include <deque>
+#include <functional>
#include <string>
#include <dali/public-api/common/dali-vector.h>
#include <dali/public-api/object/ref-object.h>
#include <dali/public-api/rendering/texture-set.h>
#include <dali/devel-api/common/owner-container.h>
#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
-#include <deque>
// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/image-loader/async-image-loader-devel.h>
#include <dali-toolkit/devel-api/image-loader/image-atlas.h>
#include <dali-toolkit/public-api/image-loader/async-image-loader.h>
#include <dali-toolkit/internal/visuals/texture-upload-observer.h>
#include <dali-toolkit/internal/visuals/visual-url.h>
+#include <dali-toolkit/internal/helpers/round-robin-container-view.h>
+#include <dali-toolkit/internal/image-loader/async-image-loader-impl.h>
namespace Dali
* 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 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).
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 );
TextureId maskTextureId,
const VisualUrl& url,
ImageDimensions desiredSize,
+ float scaleFactor,
FittingMode::Type fittingMode,
Dali::SamplingMode::Type samplingMode,
bool loadSynchronously,
+ bool cropToMask,
UseAtlas useAtlas,
TextureManager::TextureHash hash )
: url( url ),
textureId( textureId ),
maskTextureId( maskTextureId ),
hash( hash ),
+ scaleFactor( scaleFactor ),
referenceCount( 1u ),
loadState( NOT_STARTED ),
fittingMode( fittingMode ),
samplingMode( samplingMode ),
storageType( UPLOAD_TO_TEXTURE ),
loadSynchronously( loadSynchronously ),
- useAtlas( useAtlas )
+ useAtlas( useAtlas ),
+ cropToMask( cropToMask )
{
}
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
+ float scaleFactor; ///< The scale factor to apply to the Texture when masking
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
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
+ bool cropToMask:1; ///< true if the image should be cropped to the mask size.
};
// Structs:
* Apply the mask to the pixelBuffer.
* @param[in] pixelBuffer The pixelBuffer to apply the mask to
* @param[in] maskTextureId The texture id of the mask.
+ * @param[in] contentScale The factor to scale the content
+ * @param[in] cropToMask Whether to crop the content to the mask size
*/
- void ApplyMask( Devel::PixelBuffer& pixelBuffer, TextureId maskTextureId );
+ void ApplyMask( Devel::PixelBuffer& pixelBuffer, TextureId maskTextureId,
+ float contentScale, bool cropToMask );
/**
* Upload the texture specified in pixelBuffer to the appropriate location
const FittingMode::Type fittingMode,
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.
const bool useAtlas,
TextureId maskTextureId );
+private:
+
+ /**
+ * @brief Helper class to keep the relation between AsyncImageLoader and corresponding LoadingInfo container
+ */
+ class AsyncLoadingHelper : public ConnectionTracker
+ {
+ public:
+ /**
+ * @brief Create an AsyncLoadingHelper.
+ * @param[in] textureManager Reference to the texture manager
+ */
+ AsyncLoadingHelper(TextureManager& textureManager);
+
+ /**
+ * @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] 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
+ */
+ void Load(TextureId textureId,
+ const VisualUrl& url,
+ ImageDimensions desiredSize,
+ FittingMode::Type fittingMode,
+ SamplingMode::Type samplingMode,
+ bool orientationCorrection);
+
+ public:
+ AsyncLoadingHelper(const AsyncLoadingHelper&) = delete;
+ AsyncLoadingHelper& operator=(const AsyncLoadingHelper&) = delete;
+
+ AsyncLoadingHelper(AsyncLoadingHelper&& rhs);
+ AsyncLoadingHelper& operator=(AsyncLoadingHelper&&rhs) = delete;
+
+ private:
+ /**
+ * @brief Main constructor that used by all other constructors
+ */
+ AsyncLoadingHelper(Toolkit::AsyncImageLoader loader,
+ TextureManager& textureManager,
+ AsyncLoadingInfoContainerType&& loadingInfoContainer);
+
+ /**
+ * @brief Callback to be called when texture loading is complete, it passes the pixel buffer on to texture manager.
+ * @param[in] id Loader id
+ * @param[in] pixelBuffer Image data
+ */
+ void AsyncLoadComplete(uint32_t id, Devel::PixelBuffer pixelBuffer);
+
+ private:
+ Toolkit::AsyncImageLoader mLoader;
+ TextureManager& mTextureManager;
+ AsyncLoadingInfoContainerType mLoadingInfoContainer;
+ };
private:
/**
- * Undefined copy constructor.
+ * Deleted copy constructor.
*/
- TextureManager( const TextureManager& );
+ TextureManager( const TextureManager& ) = delete;
/**
- * Undefined assignment operator.
+ * Deleted assignment operator.
*/
- TextureManager& operator=( const TextureManager& rhs );
+ TextureManager& operator=( const TextureManager& rhs ) = delete;
/**
* This is called by the TextureManagerUploadObserver when an observer is destroyed.
private: // Member Variables:
- AsyncLoadingInfoContainerType mAsyncLocalLoadingInfoContainer; ///< Used to manage Asynchronous loads in progress
- AsyncLoadingInfoContainerType mAsyncRemoteLoadingInfoContainer; ///< Used to manage Asynchronous loads in progress
- AtlasInfoContainerType mAtlasContainer; ///< Used to manage Atlas creation and destruction
- TextureInfoContainerType mTextureInfoContainer; ///< Used to manage the life-cycle and caching of Textures
- Toolkit::AsyncImageLoader mAsyncLocalLoader; ///< The Asynchronous image loader used to provide all local async loads
- Toolkit::AsyncImageLoader mAsyncRemoteLoader; ///< The Asynchronous image loader used to provide all remote async loads
- TextureId mCurrentTextureId; ///< The current value used for the unique Texture Id generation
+ AtlasInfoContainerType mAtlasContainer; ///< Used to manage Atlas creation and destruction
+ TextureInfoContainerType mTextureInfoContainer; ///< Used to manage the life-cycle and caching of Textures
+ TextureId mCurrentTextureId; ///< The current value used for the unique Texture Id generation
+ 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
};