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.h;h=7ca7a05f493e94e1ddf0dc8f1de595a1f73f23b5;hp=6df17c6ed134d9f2ab9681b63ece2bf43c9eae07;hb=cc7137614f4136f571ccecc22ad1b72c01f16156;hpb=5dd8d9b17470720a322865f56925acce5f25fee7 diff --git a/dali-toolkit/internal/visuals/texture-manager-impl.h b/dali-toolkit/internal/visuals/texture-manager-impl.h old mode 100755 new mode 100644 index 6df17c6..7ca7a05 --- a/dali-toolkit/internal/visuals/texture-manager-impl.h +++ b/dali-toolkit/internal/visuals/texture-manager-impl.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -18,32 +18,31 @@ */ // EXTERNAL INCLUDES -#include -#include -#include -#include +#include +#include +#include #include #include +#include #include -#include -#include +#include +#include +#include +#include // INTERNAL INCLUDES #include #include -#include -#include -#include #include #include - +#include +#include +#include namespace Dali { - namespace Toolkit { - namespace Internal { class ImageAtlasManager; @@ -59,8 +58,7 @@ typedef IntrusivePtr ImageAtlasManagerPtr; class TextureManager : public ConnectionTracker { public: - - typedef int32_t TextureId; ///< The TextureId type. This is used as a handle to refer to a particular Texture. + 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 /** @@ -73,18 +71,20 @@ public: }; /** - * Whether the pixel data should be kept in TextureManager, or uploaded for rendering + * Whether the pixel data should be kept in TextureManager, returned with pixelBuffer or uploaded for rendering */ - enum StorageType + enum class StorageType : uint8_t { - KEEP_PIXEL_BUFFER, - UPLOAD_TO_TEXTURE + KEEP_PIXEL_BUFFER, ///< Keep loaded pixel buffer inside of texture manager without making texture. This could be used for inside pixel process like mask image. + RETURN_PIXEL_BUFFER, ///< Return loaded pixel buffer without making texture. + /// Because a pixel buffer cannot be used multiple texture, this pixel buffer only cached during loading, and is removed after loading is finished. + UPLOAD_TO_TEXTURE ///< Loaded image will be uploaded to texture and the texture will be returned. }; /** * Whether the texture should be loaded synchronously or asynchronously. */ - enum LoadType + enum class LoadType : uint8_t { LOAD_ASYNCHRONOUSLY, LOAD_SYNCHRONOUSLY @@ -93,15 +93,17 @@ public: /** * @brief The LoadState Enumeration represents the current state of a particular Texture's life-cycle. */ - enum LoadState + enum class LoadState : uint8_t { - NOT_STARTED, ///< Default - LOADING, ///< Loading has been started, but not finished. - 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 + NOT_STARTED, ///< Default + LOADING, ///< Loading has been started, but not finished. + LOAD_FINISHED, ///< Loading has finished. (for CPU storage only) + WAITING_FOR_MASK, ///< Loading has finished, but waiting for mask image + MASK_APPLYING, ///< Loading has finished, Mask is applying + MASK_APPLIED, ///< Loading has finished, Mask is applyied by GPU + UPLOADED, ///< Uploaded and ready. (For GPU upload only) + CANCELLED, ///< Removed before loading completed + LOAD_FAILED ///< Async loading failed, e.g. connection problem }; /** @@ -109,8 +111,8 @@ public: */ enum class ReloadPolicy { - CACHED = 0, ///< Loads cached texture if it exists. - FORCED ///< Forces reloading of texture. + CACHED = 0, ///< Loads cached texture if it exists. + FORCED ///< Forces reloading of texture. }; /** @@ -123,20 +125,18 @@ public: }; public: - struct MaskingData { MaskingData(); ~MaskingData() = default; - VisualUrl mAlphaMaskUrl; + VisualUrl mAlphaMaskUrl; TextureManager::TextureId mAlphaMaskId; - float mContentScaleFactor; - bool mCropToMask; + float mContentScaleFactor; + bool mCropToMask; }; using MaskingDataPointer = std::unique_ptr; - /** * Class to provide lifecycle event on destruction of texture manager. */ @@ -156,15 +156,70 @@ public: /** * Destructor. */ - ~TextureManager(); + ~TextureManager() override; // TextureManager Main API: /** + * @brief Requests an frame of animated image load. + * + * The parameters are used to specify how the animated image is loaded. + * The observer has the LoadComplete method called when the load is ready. + * + * @param[in] animatedImageLoading The AnimatedImageLoading that contain the animated image information + * @param[in] frameIndex The frame index to load. + * @param[in] samplingMode The SamplingMode to use + * @param[in] synchronousLoading true if the frame should be loaded synchronously + * @param[out] textureId The textureId of the frame + * @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). + * + * @return The texture set containing the frame of animated image, or empty if still loading. + */ + TextureSet LoadAnimatedImageTexture(Dali::AnimatedImageLoading animatedImageLoading, + uint32_t frameIndex, + Dali::SamplingMode::Type samplingMode, + bool synchronousLoading, + TextureManager::TextureId& textureId, + Dali::WrapMode::Type wrapModeU, + Dali::WrapMode::Type wrapModeV, + TextureUploadObserver* textureObserver); + + /** + * @brief Requests an image load of the given URL to get PixelBuffer. + * + * The parameters are used to specify how the image is loaded. + * The observer has the LoadComplete method called when the load is ready. + * + * @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] synchronousLoading true if the URL should be loaded synchronously + * @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] orientationCorrection Whether to rotate image to match embedded orientation data + * @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 pixel buffer containing the image, or empty if still loading. + */ + Devel::PixelBuffer LoadPixelBuffer(const VisualUrl& url, + Dali::ImageDimensions desiredSize, + Dali::FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, + bool synchronousLoading, + TextureUploadObserver* textureObserver, + bool orientationCorrection, + TextureManager::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. + * The observer has the LoadComplete method called when the load is ready. * * When the client has finished with the Texture, Remove() should be called. * @@ -172,7 +227,7 @@ public: * @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, out] 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, @@ -197,32 +252,31 @@ public: * * @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, - 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, - MultiplyOnLoad& preMultiplyOnLoad ); + TextureSet LoadTexture(const VisualUrl& url, + Dali::ImageDimensions desiredSize, + Dali::FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, + 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, + 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. + * The observer has the LoadComplete method called when the load is ready. * * When the client has finished with the Texture, Remove() should be called. * @@ -237,17 +291,19 @@ public: * @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 + * @param[in] synchronousLoading true if the frame should be loaded synchronously * @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 ); + 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, + bool synchronousLoading = false); /** * @brief Requests an image load of the given URL, when the texture has @@ -255,7 +311,7 @@ public: * the blended texture. * * The parameters are used to specify how the image is loaded. - * The observer has the UploadComplete method called when the load is ready. + * The observer has the LoadComplete method called when the load is ready. * * When the client has finished with the Texture, Remove() should be called. * @@ -279,26 +335,29 @@ public: * @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 + * @param[in] synchronousLoading true if the frame should be loaded synchronously * @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 ); + 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, + bool synchronousLoading = false); /** * 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 ); + TextureId RequestMaskLoad(const VisualUrl& maskUrl, + bool synchronousLoading = false); /** * @brief Remove a Texture from the TextureManager. @@ -307,15 +366,16 @@ public: * occurrence of a Texture will cause its removal internally. * * @param[in] textureId The ID of the Texture to remove. + * @param[in] textureObserver The texture observer. */ - void Remove( const TextureManager::TextureId textureId ); + void Remove(const TextureManager::TextureId textureId, TextureUploadObserver* textureObserver); /** * @brief Get the visualUrl associated with the texture id. * @param[in] textureId The texture Id to get * @return The visual Url associated with the texture id. */ - VisualUrl GetVisualUrl( TextureId textureId ); + VisualUrl GetVisualUrl(TextureId textureId); /** * @brief Get the current state of a texture @@ -323,57 +383,93 @@ public: * @return The loading state if the texture is valid, or NOT_STARTED if the textureId * is not valid. */ - LoadState GetTextureState( TextureId textureId ); + LoadState GetTextureState(TextureId textureId); /** * @brief Get the associated texture set if the texture id is valid * @param[in] textureId The texture Id to look up * @return the associated texture set, or an empty handle if textureId is not valid */ - TextureSet GetTextureSet( TextureId textureId ); + TextureSet GetTextureSet(TextureId textureId); + + /** + * @brief Get the encoded image buffer + * @param[in] textureId The textureId to look up + * @return the encoded image buffer, or an empty handle if textureId is not valid + */ + EncodedImageBuffer GetEncodedImageBuffer(TextureId textureId); + + /** + * @brief Get the encoded image buffer by VisualUrl + * @param[in] url The url to look up + * @return the encoded image buffer, or an empty handle if url is not buffer resource or buffer is not valid + */ + EncodedImageBuffer GetEncodedImageBuffer(const std::string& url); /** * Adds an external texture to the texture manager * @param[in] texture The texture to add * @return string containing the URL for the texture */ - std::string AddExternalTexture( TextureSet& texture ); + std::string AddExternalTexture(TextureSet& texture); + + /** + * Adds an external encoded image buffer to the texture manager + * @param[in] encodedImageBuffer The image buffer to add + * @return string containing the URL for the texture + */ + std::string AddExternalEncodedImageBuffer(const EncodedImageBuffer& encodedImageBuffer); /** * Removes an external texture from texture manager * @param[in] url The string containing the texture to remove * @return handle to the texture */ - TextureSet RemoveExternalTexture( const std::string& url ); + TextureSet RemoveExternalTexture(const std::string& url); + + /** + * Removes an external encoded image buffer from texture manager + * @param[in] url The string containing the encoded image buffer to remove + * @return handle to the encoded image buffer + */ + EncodedImageBuffer RemoveExternalEncodedImageBuffer(const std::string& url); + + /** + * @brief Notify that external textures or external encoded image buffers are used. + * @param[in] url The URL of the texture to use. + */ + void UseExternalResource(const VisualUrl& url); /** * Add an observer to the object. * @param[in] observer The observer to add. */ - void AddObserver( TextureManager::LifecycleObserver& observer ); + 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 ); + void RemoveObserver(TextureManager::LifecycleObserver& observer); /** - * @brief Set an image to be used when a visual has failed to correctly render - * @param[in] brokenImageUrl The broken image url. + * @brief Returns the geometry associated with texture. + * @param[in] textureId Id of the texture + * @param[out] frontElements number of front elements + * @param[out] backElements number of back elements + * @return Returns valid geometry object */ - void SetBrokenImageUrl(const std::string& brokenImageUrl); + Geometry GetRenderGeometry(TextureId textureId, uint32_t& frontElements, uint32_t& backElements); 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. + * The observer has the LoadComplete method called when the load is ready. * * When the client has finished with the Texture, Remove() should be called. * @@ -397,22 +493,28 @@ private: * @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 + * @param[in] animatedImageLoading The AnimatedImageLoading to load animated image + * @param[in] frameIndex The frame index of a frame to be loaded frame + * @param[in] synchronousLoading true if the frame should be loaded synchronously * @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, - bool orientationCorrection, - TextureManager::ReloadPolicy reloadPolicy, - 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, + MultiplyOnLoad& preMultiplyOnLoad, + Dali::AnimatedImageLoading animatedImageLoading, + uint32_t frameIndex, + bool synchronousLoading); /** * @brief Get the current state of a texture @@ -420,82 +522,120 @@ private: * @return The loading state if the texture is valid, or NOT_STARTED if the textureId * is not valid. */ - LoadState GetTextureStateInternal( TextureId textureId ); + LoadState GetTextureStateInternal(TextureId textureId); + + /** + * @brief Load a new image synchronously. + * @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 + * @return PixelBuffer of loaded image. + */ + Devel::PixelBuffer LoadImageSynchronously(const VisualUrl& url, + const ImageDimensions desiredSize, + FittingMode::Type fittingMode, + Dali::SamplingMode::Type samplingMode, + bool orientationCorrection); typedef size_t TextureHash; ///< The type used to store the hash used for Texture caching. + // Structs: + /** * @brief This struct is used to manage the life-cycle of Texture loading and caching. */ struct TextureInfo { - TextureInfo( TextureId textureId, - 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, - bool orientationCorrection, - bool preMultiplyOnLoad ) - : url( url ), - desiredSize( desiredSize ), - useSize( desiredSize ), - atlasRect( 0.0f, 0.0f, 1.0f, 1.0f ), // Full atlas rectangle - 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 ), - cropToMask( cropToMask ), - orientationCorrection( true ), - preMultiplyOnLoad( preMultiplyOnLoad ), - preMultiplied( false ) + TextureInfo(TextureId textureId, + 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, + bool orientationCorrection, + bool preMultiplyOnLoad, + Dali::AnimatedImageLoading animatedImageLoading, + uint32_t frameIndex) + : url(url), + desiredSize(desiredSize), + useSize(desiredSize), + atlasRect(0.0f, 0.0f, 1.0f, 1.0f), // Full atlas rectangle + textureId(textureId), + maskTextureId(maskTextureId), + hash(hash), + scaleFactor(scaleFactor), + referenceCount(1u), + loadState(LoadState::NOT_STARTED), + fittingMode(fittingMode), + samplingMode(samplingMode), + storageType(StorageType::UPLOAD_TO_TEXTURE), + animatedImageLoading(animatedImageLoading), + frameIndex(frameIndex), + loadSynchronously(loadSynchronously), + useAtlas(useAtlas), + cropToMask(cropToMask), + orientationCorrection(true), + preMultiplyOnLoad(preMultiplyOnLoad), + preMultiplied(false) { } /** * Container type used to store all observer clients of this Texture */ - typedef Dali::Vector< TextureUploadObserver* > ObserverListType; - - ObserverListType observerList; ///< Container used to store all observer clients of this Texture - Toolkit::ImageAtlas atlas; ///< The atlas this Texture lays within (if any) - Devel::PixelBuffer pixelBuffer;///< The PixelBuffer holding the image data (May be empty after upload) - 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 - 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:4; ///< 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 - StorageType storageType:2; ///< CPU storage / GPU upload; - bool loadSynchronously:1; ///< True if synchronous loading was requested - UseAtlas useAtlas:2; ///< 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 + typedef Dali::Vector ObserverListType; + + ObserverListType observerList; ///< Container used to store all observer clients of this Texture + Toolkit::ImageAtlas atlas; ///< The atlas this Texture lays within (if any) + Devel::PixelBuffer pixelBuffer; ///< The PixelBuffer holding the image data (May be empty after upload) + 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 + 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; ///< The load state showing the load progress of the Texture + FittingMode::Type fittingMode : 3; ///< The requested FittingMode + Dali::SamplingMode::Type samplingMode : 3; ///< The requested SamplingMode + StorageType storageType; ///< CPU storage / GPU upload; + Dali::AnimatedImageLoading animatedImageLoading; ///< AnimatedImageLoading that contains animated image information. + uint32_t frameIndex; ///< frame index that be loaded, in case of animated image + bool loadSynchronously : 1; ///< True if synchronous loading was requested + UseAtlas useAtlas : 2; ///< 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: + /** + * Structure to hold info about a texture load queued during NotifyObservers + */ + struct LoadQueueElement + { + LoadQueueElement(TextureId textureId, TextureUploadObserver* observer) + : mTextureId(textureId), + mObserver(observer) + { + } + + TextureId mTextureId; ///< The texture id of the requested load. + TextureUploadObserver* mObserver; ///< Observer of texture load. + }; /** * Struct to hold information about a requested Async load. @@ -503,48 +643,67 @@ private: */ struct AsyncLoadingInfo { - AsyncLoadingInfo( TextureId textureId ) - : textureId( textureId ), - loadId( 0 ) + AsyncLoadingInfo(TextureId textureId) + : textureId(textureId), + loadId(0) { } - TextureId textureId; ///< The external Texture Id assigned to this load - uint32_t loadId; ///< The load Id used by the async loader to reference this load + TextureId textureId; ///< The external Texture Id assigned to this load + uint32_t loadId; ///< The load Id used by the async loader to reference this load }; // Private typedefs: - typedef std::deque AsyncLoadingInfoContainerType; ///< The container type used to manage Asynchronous loads in progress - typedef std::vector TextureInfoContainerType; ///< The container type used to manage the life-cycle and caching of Textures + typedef std::deque AsyncLoadingInfoContainerType; ///< The container type used to manage Asynchronous loads in progress + typedef std::vector TextureInfoContainerType; ///< The container type used to manage the life-cycle and caching of Textures + + /** + * @brief Initiate a load or queue load if NotifyObservers is invoking callbacks + * @param[in] textureInfo The TextureInfo struct associated with the Texture + * @param[in] observer The observer wishing to observe the texture upload + */ + void LoadOrQueueTexture(TextureInfo& textureInfo, TextureUploadObserver* observer); + + /** + * @brief Queue a texture load to be subsequently handled by ProcessQueuedTextures. + * @param[in] textureInfo The TextureInfo struct associated with the Texture + * @param[in] observer The observer wishing to observe the texture upload + */ + void QueueLoadTexture(TextureInfo& textureInfo, TextureUploadObserver* observer); /** * @brief Used internally to initiate a load. * @param[in] textureInfo The TextureInfo struct associated with the Texture - * @return True if the load was initiated + * @param[in] observer The observer wishing to observe the texture upload + */ + void LoadTexture(TextureInfo& textureInfo, TextureUploadObserver* observer); + + /** + * @brief Initiate load of textures queued whilst NotifyObservers invoking callbacks. */ - bool LoadTexture( TextureInfo& textureInfo ); + void ProcessQueuedTextures(); /** * Add the observer to the observer list * @param[in] textureInfo The TextureInfo struct associated with the texture - * observer The observer wishing to observe the texture upload + * @param[in] observer The observer wishing to observe the texture upload */ - void ObserveTexture( TextureInfo & textureInfo, TextureUploadObserver* observer ); + void ObserveTexture(TextureInfo& textureInfo, TextureUploadObserver* observer); /** * @brief This signal handler is called when the async local loader finishes loading. * @param[in] id This is the async image loaders Id * @param[in] pixelBuffer The loaded image data */ - void AsyncLocalLoadComplete( uint32_t id, Devel::PixelBuffer pixelBuffer ); + void AsyncLocalLoadComplete(uint32_t id, Devel::PixelBuffer pixelBuffer); /** * @brief This signal handler is called when the async local loader finishes loading. * @param[in] id This is the async image loaders Id * @param[in] pixelBuffer The loaded image data */ - void AsyncRemoteLoadComplete( uint32_t id, Devel::PixelBuffer pixelBuffer ); + void AsyncRemoteLoadComplete(uint32_t id, Devel::PixelBuffer pixelBuffer); /** * Common method to handle loading completion @@ -552,7 +711,7 @@ private: * @param[in] id This is the async image loaders Id * @param[in] pixelBuffer The loaded image data */ - void AsyncLoadComplete( AsyncLoadingInfoContainerType& container, uint32_t id, Devel::PixelBuffer pixelBuffer ); + void AsyncLoadComplete(AsyncLoadingInfoContainerType& container, uint32_t id, Devel::PixelBuffer pixelBuffer); /** * @brief Performs Post-Load steps including atlasing. @@ -560,24 +719,21 @@ private: * @param[in] pixelBuffer The image pixelBuffer * @return True if successful */ - void PostLoad( TextureManager::TextureInfo& textureInfo, Devel::PixelBuffer& pixelBuffer ); + void PostLoad(TextureManager::TextureInfo& textureInfo, Devel::PixelBuffer& pixelBuffer); /** * 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 ); + void CheckForWaitingTexture(TextureInfo& maskTextureInfo); /** * Apply the mask to the pixelBuffer. - * @param[in] pixelBuffer The pixelBuffer to apply the mask to + * @param[in] textureInfo The information of texture 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, - float contentScale, bool cropToMask ); + void ApplyMask(TextureInfo& textureInfo, TextureId maskTextureId); /** * Upload the texture specified in pixelBuffer to the appropriate location @@ -585,13 +741,15 @@ private: * @param[in] textureInfo The texture info containing the location to * store the data to. */ - void UploadTexture( Devel::PixelBuffer& pixelBuffer, TextureInfo& textureInfo ); + void UploadTexture(Devel::PixelBuffer& pixelBuffer, TextureInfo& textureInfo); /** - * Mark the texture as complete, and inform observers - * @param[in] textureInfo The struct associated with this Texture + * Creates tiled geometry of for the texture which separates fully-opaque + * tiles from ones which use transparency. + * @param pixelBuffer + * @param textureInfo */ - void UploadComplete( TextureInfo& textureInfo ); + bool CreateTiledGeometry(const Devel::PixelBuffer& pixelBuffer, TextureInfo& textureInfo); /** * Notify the current observers that the texture upload is complete, @@ -599,7 +757,7 @@ private: * @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 ); + void NotifyObservers(TextureInfo& textureInfo, bool success); /** * @brief Generates a new, unique TextureId @@ -612,51 +770,47 @@ private: * @param[in] textureId The TextureId to look up * @return The cache index */ - int GetCacheIndexFromId( TextureId textureId ); - + int GetCacheIndexFromId(TextureId 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, - TextureId maskTextureId, - MultiplyOnLoad preMultiplyOnLoad); + * @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, 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 - * @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. + * @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 + * @param[in] preMultiplyOnLoad if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha. + * @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, - TextureId maskTextureId, - MultiplyOnLoad preMultiplyOnLoad); + const std::string& url, + const ImageDimensions size, + const FittingMode::Type fittingMode, + const Dali::SamplingMode::Type samplingMode, + const bool useAtlas, + TextureId maskTextureId, + MultiplyOnLoad preMultiplyOnLoad); private: - /** * @brief Helper class to keep the relation between AsyncImageLoader and corresponding LoadingInfo container */ @@ -670,6 +824,16 @@ private: AsyncLoadingHelper(TextureManager& textureManager); /** + * @brief Load a new frame of animated image + * @param[in] textureId TextureId to reference the texture that will be loaded + * @param[in] animatedImageLoading The AnimatedImageLoading to load animated image + * @param[in] frameIndex The frame index of a frame to be loaded frame + */ + void LoadAnimatedImage(TextureId textureId, + Dali::AnimatedImageLoading animatedImageLoading, + uint32_t frameIndex); + + /** * @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 @@ -679,27 +843,45 @@ private: * @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] preMultiplyOnLoad if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha or if the image need to be applied alpha mask. */ - void Load(TextureId textureId, - const VisualUrl& url, - ImageDimensions desiredSize, - FittingMode::Type fittingMode, - SamplingMode::Type samplingMode, - bool orientationCorrection); + void Load(TextureId textureId, + const VisualUrl& url, + ImageDimensions desiredSize, + FittingMode::Type fittingMode, + SamplingMode::Type samplingMode, + bool orientationCorrection, + DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad); + + /** + * @brief Apply mask + * @param [in] id of the texture + * @param [in] pixelBuffer of the to be masked image + * @param [in] maskPixelBuffer of the mask image + * @param [in] contentScale The factor to scale the content + * @param [in] cropToMask Whether to crop the content to the mask size + * @param [in] preMultiplyOnLoad if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha. + */ + void ApplyMask(TextureId textureId, + Devel::PixelBuffer pixelBuffer, + Devel::PixelBuffer maskPixelBuffer, + float contentScale, + bool cropToMask, + DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad); public: AsyncLoadingHelper(const AsyncLoadingHelper&) = delete; AsyncLoadingHelper& operator=(const AsyncLoadingHelper&) = delete; AsyncLoadingHelper(AsyncLoadingHelper&& rhs); - AsyncLoadingHelper& operator=(AsyncLoadingHelper&&rhs) = delete; + AsyncLoadingHelper& operator=(AsyncLoadingHelper&& rhs) = delete; private: /** * @brief Main constructor that used by all other constructors */ - AsyncLoadingHelper(Toolkit::AsyncImageLoader loader, - TextureManager& textureManager, + AsyncLoadingHelper(Toolkit::AsyncImageLoader loader, + TextureManager& textureManager, AsyncLoadingInfoContainerType&& loadingInfoContainer); /** @@ -717,42 +899,56 @@ private: struct ExternalTextureInfo { - TextureId textureId; + TextureId textureId; TextureSet textureSet; + int16_t referenceCount{1}; }; -private: + struct EncodedBufferTextureInfo + { + EncodedBufferTextureInfo(TextureId textureId, + const EncodedImageBuffer& encodedImageBuffer) + : textureId(textureId), + encodedImageBuffer(encodedImageBuffer), + referenceCount(1u) + { + } + TextureId textureId; + EncodedImageBuffer encodedImageBuffer; + int16_t referenceCount; + }; +private: /** * Deleted copy constructor. */ - TextureManager( const TextureManager& ) = delete; + TextureManager(const TextureManager&) = delete; /** * Deleted assignment operator. */ - TextureManager& operator=( const TextureManager& rhs ) = delete; + TextureManager& operator=(const TextureManager& rhs) = delete; /** * This is called by the TextureManagerUploadObserver when an observer is destroyed. * We use the callback to know when to remove an observer from our notify list. * @param[in] observer The observer that generated the callback */ - void ObserverDestroyed( TextureUploadObserver* observer ); - -private: // Member Variables: - - 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 mLifecycleObservers; ///< Lifecycle observers of texture manager - std::string mBrokenImageUrl; ///< Broken image url - TextureId mCurrentTextureId; ///< The current value used for the unique Texture Id generation + void ObserverDestroyed(TextureUploadObserver* observer); + +private: // Member Variables: + TextureInfoContainerType mTextureInfoContainer; ///< Used to manage the life-cycle and caching of Textures + RoundRobinContainerView mAsyncLocalLoaders; ///< The Asynchronous image loaders used to provide all local async loads + RoundRobinContainerView mAsyncRemoteLoaders; ///< The Asynchronous image loaders used to provide all remote async loads + std::vector mExternalTextures; ///< Externally provided textures + std::vector mEncodedBufferTextures; ///< Externally encoded buffer textures + Dali::Vector mLifecycleObservers; ///< Lifecycle observers of texture manager + Dali::Vector mLoadQueue; ///< Queue of textures to load after NotifyObservers + TextureId mCurrentTextureId; ///< The current value used for the unique Texture Id generation + bool mQueueLoadFlag; ///< Flag that causes Load Textures to be queued. }; - -} // name Internal +} // namespace Internal } // namespace Toolkit