From eeae87bdabeca966e0bc4146d9a9476ab4655dae Mon Sep 17 00:00:00 2001 From: seungho Date: Mon, 13 Dec 2021 21:57:14 +0900 Subject: [PATCH] [Tizen] CPU Alpha Masking for Animated Image Visual Change-Id: Ia8b705570b0b9e9ad792c4c4f7863261ce66a5f4 Signed-off-by: seungho --- .../animated-image/animated-image-visual.cpp | 79 +++++++++++++++++++++- .../visuals/animated-image/animated-image-visual.h | 9 ++- .../visuals/animated-image/fixed-image-cache.cpp | 19 ++++-- .../visuals/animated-image/fixed-image-cache.h | 20 +++--- .../visuals/animated-image/image-cache.cpp | 10 +-- .../internal/visuals/animated-image/image-cache.h | 32 +++++---- .../rolling-animated-image-cache.cpp | 38 ++++++++--- .../animated-image/rolling-animated-image-cache.h | 29 +++++--- .../visuals/animated-image/rolling-image-cache.cpp | 38 ++++++++--- .../visuals/animated-image/rolling-image-cache.h | 29 +++++--- .../internal/visuals/texture-manager-impl.cpp | 64 ++++++++++++++++-- .../internal/visuals/texture-manager-impl.h | 4 +- 12 files changed, 286 insertions(+), 85 deletions(-) diff --git a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp index cc90d5d..e830602 100644 --- a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp @@ -174,7 +174,7 @@ void AnimatedImageVisual::CreateImageCache() if(mAnimatedImageLoading) { - mImageCache = new RollingAnimatedImageCache(textureManager, mAnimatedImageLoading, *this, mCacheSize, mBatchSize, IsSynchronousLoadingRequired()); + mImageCache = new RollingAnimatedImageCache(textureManager, mAnimatedImageLoading, mMaskingData, *this, mCacheSize, mBatchSize, IsSynchronousLoadingRequired()); } else if(mImageUrls) { @@ -185,11 +185,11 @@ void AnimatedImageVisual::CreateImageCache() uint16_t cacheSize = std::max(std::min(std::max(batchSize, mCacheSize), numUrls), MINIMUM_CACHESIZE); if(cacheSize < numUrls) { - mImageCache = new RollingImageCache(textureManager, *mImageUrls, *this, cacheSize, batchSize, mFrameDelay); + mImageCache = new RollingImageCache(textureManager, *mImageUrls, mMaskingData, *this, cacheSize, batchSize, mFrameDelay); } else { - mImageCache = new FixedImageCache(textureManager, *mImageUrls, *this, batchSize, mFrameDelay); + mImageCache = new FixedImageCache(textureManager, *mImageUrls, mMaskingData, *this, batchSize, mFrameDelay); } } @@ -218,6 +218,7 @@ AnimatedImageVisual::AnimatedImageVisual(VisualFactoryCache& factoryCache, Image mCurrentLoopIndex(FIRST_LOOP), mLoadPolicy(Toolkit::ImageVisual::LoadPolicy::ATTACHED), mReleasePolicy(Toolkit::ImageVisual::ReleasePolicy::DETACHED), + mMaskingData(), mFrameCount(0), mImageSize(), mActionStatus(DevelAnimatedImageVisual::Action::PLAY), @@ -260,6 +261,18 @@ void AnimatedImageVisual::GetNaturalSize(Vector2& naturalSize) { mImageSize = Dali::GetClosestImageSize((*mImageUrls)[0].mUrl); } + + if(mMaskingData && mMaskingData->mAlphaMaskUrl.IsValid() && + mMaskingData->mCropToMask) + { + ImageDimensions dimensions = Dali::GetClosestImageSize(mMaskingData->mAlphaMaskUrl.GetUrl()); + if(dimensions != ImageDimensions(0, 0)) + { + naturalSize.x = dimensions.GetWidth(); + naturalSize.y = dimensions.GetHeight(); + } + return; + } } naturalSize.width = mImageSize.GetWidth(); @@ -303,6 +316,13 @@ void AnimatedImageVisual::DoCreatePropertyMap(Property::Map& map) const map.Insert(Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, mStopBehavior); + if(mMaskingData) + { + map.Insert(Toolkit::ImageVisual::Property::ALPHA_MASK_URL, mMaskingData->mAlphaMaskUrl.GetUrl()); + map.Insert(Toolkit::ImageVisual::Property::MASK_CONTENT_SCALE, mMaskingData->mContentScaleFactor); + map.Insert(Toolkit::ImageVisual::Property::CROP_TO_MASK, mMaskingData->mCropToMask); + } + map.Insert(Toolkit::ImageVisual::Property::LOAD_POLICY, mLoadPolicy); map.Insert(Toolkit::ImageVisual::Property::RELEASE_POLICY, mReleasePolicy); } @@ -418,6 +438,18 @@ void AnimatedImageVisual::DoSetProperties(const Property::Map& propertyMap) { DoSetProperty(Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, keyValue.second); } + else if(keyValue.first == ALPHA_MASK_URL) + { + DoSetProperty(Toolkit::ImageVisual::Property::ALPHA_MASK_URL, keyValue.second); + } + else if(keyValue.first == MASK_CONTENT_SCALE_NAME) + { + DoSetProperty(Toolkit::ImageVisual::Property::MASK_CONTENT_SCALE, keyValue.second); + } + else if(keyValue.first == CROP_TO_MASK_NAME) + { + DoSetProperty(Toolkit::ImageVisual::Property::CROP_TO_MASK, keyValue.second); + } else if(keyValue.first == LOAD_POLICY_NAME) { DoSetProperty(Toolkit::ImageVisual::Property::LOAD_POLICY, keyValue.second); @@ -559,6 +591,39 @@ void AnimatedImageVisual::DoSetProperty(Property::Index index, break; } + case Toolkit::ImageVisual::Property::ALPHA_MASK_URL: + { + std::string alphaUrl = ""; + if(value.Get(alphaUrl)) + { + AllocateMaskData(); + mMaskingData->mAlphaMaskUrl = alphaUrl; + } + break; + } + + case Toolkit::ImageVisual::Property::MASK_CONTENT_SCALE: + { + float scale = 1.0f; + if(value.Get(scale)) + { + AllocateMaskData(); + mMaskingData->mContentScaleFactor = scale; + } + break; + } + + case Toolkit::ImageVisual::Property::CROP_TO_MASK: + { + bool crop = false; + if(value.Get(crop)) + { + AllocateMaskData(); + mMaskingData->mCropToMask = crop; + } + break; + } + case Toolkit::ImageVisual::Property::RELEASE_POLICY: { int releasePolicy = 0; @@ -870,6 +935,14 @@ Shader AnimatedImageVisual::GenerateShader() const return shader; } +void AnimatedImageVisual::AllocateMaskData() +{ + if(!mMaskingData) + { + mMaskingData.reset(new TextureManager::MaskingData()); + } +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h index 6679ef2..210b588 100644 --- a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h +++ b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h @@ -247,6 +247,12 @@ private: */ TextureSet SetLoadingFailed(); + /** + * @brief Allocate mask data. + * This is allocated only once. + */ + void AllocateMaskData(); + // Undefined AnimatedImageVisual(const AnimatedImageVisual& animatedImageVisual); @@ -274,9 +280,10 @@ private: int16_t mLoopCount; int16_t mCurrentLoopIndex; - // Variables for image visual policy. + // Variables for image visual properties. Dali::Toolkit::ImageVisual::LoadPolicy::Type mLoadPolicy; Dali::Toolkit::ImageVisual::ReleasePolicy::Type mReleasePolicy; + TextureManager::MaskingDataPointer mMaskingData; // Shared variables uint32_t mFrameCount; // Number of frames diff --git a/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp b/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp index c90e86e..004cff3 100644 --- a/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp +++ b/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp @@ -36,9 +36,13 @@ static constexpr bool ENABLE_ORIENTATION_CORRECTION(true); static constexpr uint32_t FIRST_FRAME_INDEX = 0u; } // namespace -FixedImageCache::FixedImageCache( - TextureManager& textureManager, UrlList& urlList, ImageCache::FrameReadyObserver& observer, uint32_t batchSize, uint32_t interval) -: ImageCache(textureManager, observer, batchSize, interval), +FixedImageCache::FixedImageCache(TextureManager& textureManager, + UrlList& urlList, + TextureManager::MaskingDataPointer& maskingData, + ImageCache::FrameReadyObserver& observer, + uint32_t batchSize, + uint32_t interval) +: ImageCache(textureManager, maskingData, observer, batchSize, interval), mImageUrls(urlList), mFront(FIRST_FRAME_INDEX) { @@ -126,7 +130,6 @@ void FixedImageCache::LoadBatch() bool synchronousLoading = false; bool atlasingStatus = false; bool loadingStatus = false; - TextureManager::MaskingDataPointer maskInfo = nullptr; AtlasUploadObserver* atlasObserver = nullptr; ImageAtlasManagerPtr imageAtlasManager = nullptr; Vector4 textureRect; @@ -134,7 +137,7 @@ void FixedImageCache::LoadBatch() auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; TextureSet textureSet = mTextureManager.LoadTexture( - url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, maskInfo, synchronousLoading, mImageUrls[frameIndex].mTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply); + url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, mMaskingData, synchronousLoading, mImageUrls[frameIndex].mTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply); // If textureSet is returned but loadingState is false than load state is LOAD_FINISHED. (Notification is not comming yet.) // If textureSet is null and the request is synchronous, load state is LOAD_FAILED. @@ -198,10 +201,16 @@ void FixedImageCache::ClearCache() { mTextureManager.Remove(mImageUrls[i].mTextureId, this); mImageUrls[i].mTextureId = TextureManager::INVALID_TEXTURE_ID; + + if(mMaskingData && mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID) + { + mTextureManager.Remove(mMaskingData->mAlphaMaskId, this); + } } } mReadyFlags.clear(); mLoadStates.assign(mImageUrls.size(), TextureManager::LoadState::NOT_STARTED); + mMaskingData->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID; } void FixedImageCache::UploadComplete( diff --git a/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.h b/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.h index 93a32b6..3d80db0 100644 --- a/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.h +++ b/dali-toolkit/internal/visuals/animated-image/fixed-image-cache.h @@ -33,19 +33,21 @@ public: /** * Constructor. * @param[in] textureManager The texture manager - * @param[in] urlList List of urls to cache - * @param[in] observer FrameReady observer - * @param[in] batchSize The size of a batch to load - * @param[in] interval Time interval between each frame + * @param[in] urlList List of urls to cache + * @param[in] maskingData Masking data to be applied. + * @param[in] observer FrameReady observer + * @param[in] batchSize The size of a batch to load + * @param[in] interval Time interval between each frame * * This will start loading textures immediately, according to the * batch and cache sizes. The cache is as large as the number of urls. */ - FixedImageCache(TextureManager& textureManager, - UrlList& urlList, - ImageCache::FrameReadyObserver& observer, - uint32_t batchSize, - uint32_t interval); + FixedImageCache(TextureManager& textureManager, + UrlList& urlList, + TextureManager::MaskingDataPointer& maskingData, + ImageCache::FrameReadyObserver& observer, + uint32_t batchSize, + uint32_t interval); ~FixedImageCache() override; diff --git a/dali-toolkit/internal/visuals/animated-image/image-cache.cpp b/dali-toolkit/internal/visuals/animated-image/image-cache.cpp index dcd0d40..8f001f7 100644 --- a/dali-toolkit/internal/visuals/animated-image/image-cache.cpp +++ b/dali-toolkit/internal/visuals/animated-image/image-cache.cpp @@ -22,12 +22,14 @@ namespace Toolkit { namespace Internal { -ImageCache::ImageCache(TextureManager& textureManager, - ImageCache::FrameReadyObserver& observer, - uint32_t batchSize, - uint32_t interval) +ImageCache::ImageCache(TextureManager& textureManager, + TextureManager::MaskingDataPointer& maskingData, + ImageCache::FrameReadyObserver& observer, + uint32_t batchSize, + uint32_t interval) : mTextureManager(textureManager), mObserver(observer), + mMaskingData(maskingData), mBatchSize(batchSize), mInterval(interval), mRequestingLoad(false), diff --git a/dali-toolkit/internal/visuals/animated-image/image-cache.h b/dali-toolkit/internal/visuals/animated-image/image-cache.h index 432ad8c..dba45fa 100644 --- a/dali-toolkit/internal/visuals/animated-image/image-cache.h +++ b/dali-toolkit/internal/visuals/animated-image/image-cache.h @@ -59,18 +59,19 @@ public: /** * @brief Constructor. * @param[in] textureManager The texture manager - * @param[in] urlList List of urls to cache - * @param[in] observer FrameReady observer - * @param[in] batchSize The size of a batch to load - * @param[in] interval Time interval between each frame + * @param[in] observer FrameReady observer + * @param[in] maskingData Masking data to be applied. + * @param[in] batchSize The size of a batch to load + * @param[in] interval Time interval between each frame * * This will start loading textures immediately, according to the * batch and cache sizes. The cache is as large as the number of urls. */ - ImageCache(TextureManager& textureManager, - ImageCache::FrameReadyObserver& observer, - uint32_t batchSize, - uint32_t interval); + ImageCache(TextureManager& textureManager, + TextureManager::MaskingDataPointer& maskingData, + ImageCache::FrameReadyObserver& observer, + uint32_t batchSize, + uint32_t interval); virtual ~ImageCache(); @@ -139,13 +140,16 @@ private: */ void TextureManagerDestroyed() final; + void AllocateMaskData(); + protected: - TextureManager& mTextureManager; - FrameReadyObserver& mObserver; - uint32_t mBatchSize; - uint32_t mInterval; - bool mRequestingLoad : 1; - bool mTextureManagerAlive : 1; + TextureManager& mTextureManager; + FrameReadyObserver& mObserver; + TextureManager::MaskingDataPointer& mMaskingData; + uint32_t mBatchSize; + uint32_t mInterval; + bool mRequestingLoad : 1; + bool mTextureManagerAlive : 1; }; } //namespace Internal diff --git a/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp b/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp index f8f8310..a950ac7 100644 --- a/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp +++ b/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp @@ -59,9 +59,14 @@ static constexpr uint32_t SINGLE_IMAGE_COUNT = 1u; static constexpr uint32_t FIRST_FRAME_INDEX = 0u; } // namespace -RollingAnimatedImageCache::RollingAnimatedImageCache( - TextureManager& textureManager, AnimatedImageLoading& animatedImageLoading, ImageCache::FrameReadyObserver& observer, uint16_t cacheSize, uint16_t batchSize, bool isSynchronousLoading) -: ImageCache(textureManager, observer, batchSize, 0u), +RollingAnimatedImageCache::RollingAnimatedImageCache(TextureManager& textureManager, + AnimatedImageLoading& animatedImageLoading, + TextureManager::MaskingDataPointer& maskingData, + ImageCache::FrameReadyObserver& observer, + uint16_t cacheSize, + uint16_t batchSize, + bool isSynchronousLoading) +: ImageCache(textureManager, maskingData, observer, batchSize, 0u), mAnimatedImageLoading(animatedImageLoading), mFrameCount(SINGLE_IMAGE_COUNT), mFrameIndex(FIRST_FRAME_INDEX), @@ -85,10 +90,8 @@ TextureSet RollingAnimatedImageCache::Frame(uint32_t frameIndex) bool popExist = false; while(!mQueue.IsEmpty() && mQueue.Front().mFrameNumber != frameIndex) { - ImageFrame imageFrame = mQueue.PopFront(); - mTextureManager.Remove(mImageUrls[imageFrame.mFrameNumber].mTextureId, this); - mImageUrls[imageFrame.mFrameNumber].mTextureId = TextureManager::INVALID_TEXTURE_ID; - popExist = true; + PopFrontCache(); + popExist = true; } TextureSet textureSet; @@ -191,6 +194,7 @@ TextureSet RollingAnimatedImageCache::RequestFrameLoading(uint32_t frameIndex, b frameIndex, loadingStatus, mImageUrls[frameIndex].mTextureId, + mMaskingData, SamplingMode::BOX_THEN_LINEAR, Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT, @@ -267,13 +271,27 @@ TextureManager::TextureId RollingAnimatedImageCache::GetCachedTextureId(int inde return mImageUrls[mQueue[index].mFrameNumber].mTextureId; } +void RollingAnimatedImageCache::PopFrontCache() +{ + ImageFrame imageFrame = mQueue.PopFront(); + mTextureManager.Remove(mImageUrls[imageFrame.mFrameNumber].mTextureId, this); + mImageUrls[imageFrame.mFrameNumber].mTextureId = TextureManager::INVALID_TEXTURE_ID; + + if(mMaskingData && mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID) + { + mTextureManager.Remove(mMaskingData->mAlphaMaskId, this); + if(mQueue.IsEmpty()) + { + mMaskingData->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID; + } + } +} + void RollingAnimatedImageCache::ClearCache() { while(mTextureManagerAlive && !mQueue.IsEmpty()) { - ImageFrame imageFrame = mQueue.PopFront(); - mTextureManager.Remove(mImageUrls[imageFrame.mFrameNumber].mTextureId, this); - mImageUrls[imageFrame.mFrameNumber].mTextureId = TextureManager::INVALID_TEXTURE_ID; + PopFrontCache(); } mLoadWaitingQueue.clear(); diff --git a/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.h b/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.h index 6a06717..a35ba7c 100644 --- a/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.h +++ b/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.h @@ -41,22 +41,24 @@ class RollingAnimatedImageCache : public ImageCache, public TextureUploadObserve public: /** * @brief Constructor. - * @param[in] textureManager The texture manager - * @param[in] animatedImageLoader The loaded animated image - * @param[in] observer FrameReady observer - * @param[in] cacheSize The size of the cache - * @param[in] batchSize The size of a batch to load + * @param[in] textureManager The texture manager + * @param[in] animatedImageLoading The loaded animated image + * @param[in] maskingData Masking data to be applied. + * @param[in] observer FrameReady observer + * @param[in] cacheSize The size of the cache + * @param[in] batchSize The size of a batch to load * @param[in] isSynchronousLoading The flag to define whether to load first frame synchronously * * This will start loading textures immediately, according to the * batch and cache sizes. */ - RollingAnimatedImageCache(TextureManager& textureManager, - AnimatedImageLoading& animatedImageLoader, - ImageCache::FrameReadyObserver& observer, - uint16_t cacheSize, - uint16_t batchSize, - bool isSynchronousLoading); + RollingAnimatedImageCache(TextureManager& textureManager, + AnimatedImageLoading& animatedImageLoading, + TextureManager::MaskingDataPointer& maskingData, + ImageCache::FrameReadyObserver& observer, + uint16_t cacheSize, + uint16_t batchSize, + bool isSynchronousLoading); /** * @brief Destructor @@ -143,6 +145,11 @@ private: */ TextureManager::TextureId GetCachedTextureId(int index) const; + /** + * @brief Pop front entity of Cache. + */ + void PopFrontCache(); + protected: /** diff --git a/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp b/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp index c776605..df41982 100644 --- a/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp +++ b/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp @@ -56,9 +56,14 @@ namespace Toolkit { namespace Internal { -RollingImageCache::RollingImageCache( - TextureManager& textureManager, UrlList& urlList, ImageCache::FrameReadyObserver& observer, uint16_t cacheSize, uint16_t batchSize, uint32_t interval) -: ImageCache(textureManager, observer, batchSize, interval), +RollingImageCache::RollingImageCache(TextureManager& textureManager, + UrlList& urlList, + TextureManager::MaskingDataPointer& maskingData, + ImageCache::FrameReadyObserver& observer, + uint16_t cacheSize, + uint16_t batchSize, + uint32_t interval) +: ImageCache(textureManager, maskingData, observer, batchSize, interval), mImageUrls(urlList), mQueue(cacheSize) { @@ -76,9 +81,7 @@ TextureSet RollingImageCache::Frame(uint32_t frameIndex) bool popExist = false; while(!mQueue.IsEmpty() && mQueue.Front().mUrlIndex != frameIndex) { - ImageFrame imageFrame = mQueue.PopFront(); - mTextureManager.Remove(mImageUrls[imageFrame.mUrlIndex].mTextureId, this); - mImageUrls[imageFrame.mUrlIndex].mTextureId = TextureManager::INVALID_TEXTURE_ID; + PopFrontCache(); popExist = true; } if(popExist || mQueue.IsEmpty()) @@ -159,7 +162,6 @@ void RollingImageCache::LoadBatch(uint32_t frameIndex) bool synchronousLoading = false; bool atlasingStatus = false; bool loadingStatus = false; - TextureManager::MaskingDataPointer maskInfo = nullptr; AtlasUploadObserver* atlasObserver = nullptr; ImageAtlasManagerPtr imageAtlasManager = nullptr; Vector4 textureRect; @@ -167,7 +169,7 @@ void RollingImageCache::LoadBatch(uint32_t frameIndex) auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; TextureSet textureSet = mTextureManager.LoadTexture( - url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, maskInfo, synchronousLoading, mImageUrls[imageFrame.mUrlIndex].mTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply); + url, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, mMaskingData, synchronousLoading, mImageUrls[imageFrame.mUrlIndex].mTextureId, textureRect, textureRectSize, atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT, this, atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply); // If textureSet is returned but loadingState is false than load state is LOAD_FINISHED. (Notification is not comming yet.) // If textureSet is null and the request is synchronous, load state is LOAD_FAILED. @@ -232,13 +234,27 @@ void RollingImageCache::CheckFrontFrame(bool wasReady) } } +void RollingImageCache::PopFrontCache() +{ + ImageFrame imageFrame = mQueue.PopFront(); + mTextureManager.Remove(mImageUrls[imageFrame.mUrlIndex].mTextureId, this); + mImageUrls[imageFrame.mUrlIndex].mTextureId = TextureManager::INVALID_TEXTURE_ID; + + if(mMaskingData && mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID) + { + mTextureManager.Remove(mMaskingData->mAlphaMaskId, this); + if(mQueue.IsEmpty()) + { + mMaskingData->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID; + } + } +} + void RollingImageCache::ClearCache() { while(mTextureManagerAlive && !mQueue.IsEmpty()) { - ImageFrame imageFrame = mQueue.PopFront(); - mTextureManager.Remove(mImageUrls[imageFrame.mUrlIndex].mTextureId, this); - mImageUrls[imageFrame.mUrlIndex].mTextureId = TextureManager::INVALID_TEXTURE_ID; + PopFrontCache(); } mLoadStates.assign(mImageUrls.size(), TextureManager::LoadState::NOT_STARTED); } diff --git a/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.h b/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.h index 6f168df..0f0d883 100644 --- a/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.h +++ b/dali-toolkit/internal/visuals/animated-image/rolling-image-cache.h @@ -39,21 +39,23 @@ public: /** * Constructor. * @param[in] textureManager The texture manager - * @param[in] urlList List of urls to cache - * @param[in] observer FrameReady observer - * @param[in] cacheSize The size of the cache - * @param[in] batchSize The size of a batch to load - * @param[in] interval Time interval between each frame + * @param[in] urlList List of urls to cache + * @param[in] maskingData Masking data to be applied. + * @param[in] observer FrameReady observer + * @param[in] cacheSize The size of the cache + * @param[in] batchSize The size of a batch to load + * @param[in] interval Time interval between each frame * * This will start loading textures immediately, according to the * batch and cache sizes. */ - RollingImageCache(TextureManager& textureManager, - UrlList& urlList, - ImageCache::FrameReadyObserver& observer, - uint16_t cacheSize, - uint16_t batchSize, - uint32_t interval); + RollingImageCache(TextureManager& textureManager, + UrlList& urlList, + TextureManager::MaskingDataPointer& maskingData, + ImageCache::FrameReadyObserver& observer, + uint16_t cacheSize, + uint16_t batchSize, + uint32_t interval); /** * Destructor @@ -139,6 +141,11 @@ private: */ void CheckFrontFrame(bool wasReady); + /** + * @brief Pop front entity of Cache. + */ + void PopFrontCache(); + protected: /** diff --git a/dali-toolkit/internal/visuals/texture-manager-impl.cpp b/dali-toolkit/internal/visuals/texture-manager-impl.cpp index b1f18eb..e694c57 100644 --- a/dali-toolkit/internal/visuals/texture-manager-impl.cpp +++ b/dali-toolkit/internal/visuals/texture-manager-impl.cpp @@ -146,6 +146,7 @@ TextureSet TextureManager::LoadAnimatedImageTexture(Dali::AnimatedImageLoading a uint32_t frameIndex, bool& loadingStatus, TextureManager::TextureId& textureId, + MaskingDataPointer& maskInfo, Dali::SamplingMode::Type samplingMode, Dali::WrapMode::Type wrapModeU, Dali::WrapMode::Type wrapModeV, @@ -168,6 +169,15 @@ TextureSet TextureManager::LoadAnimatedImageTexture(Dali::AnimatedImageLoading a } else { + if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid()) + { + Devel::PixelBuffer maskPixelBuffer = LoadImageFromFile(maskInfo->mAlphaMaskUrl.GetUrl(), ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, true); + if(maskPixelBuffer) + { + pixelBuffer.ApplyMask(maskPixelBuffer, maskInfo->mContentScaleFactor, maskInfo->mCropToMask); + } + } + PixelData pixelData = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer if(!textureSet) { @@ -180,9 +190,36 @@ TextureSet TextureManager::LoadAnimatedImageTexture(Dali::AnimatedImageLoading a } else { - loadingStatus = true; - auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; - textureId = RequestLoadInternal(animatedImageLoading.GetUrl(), INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, TextureManager::NO_ATLAS, false, StorageType::UPLOAD_TO_TEXTURE, textureObserver, true, TextureManager::ReloadPolicy::CACHED, preMultiply, animatedImageLoading, frameIndex, useCache); + TextureId alphaMaskId = INVALID_TEXTURE_ID; + float contentScaleFactor = 1.0f; + bool cropToMask = false; + if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid()) + { + maskInfo->mAlphaMaskId = RequestMaskLoad(maskInfo->mAlphaMaskUrl); + alphaMaskId = maskInfo->mAlphaMaskId; + contentScaleFactor = maskInfo->mContentScaleFactor; + cropToMask = maskInfo->mCropToMask; + } + + loadingStatus = true; + auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; + textureId = RequestLoadInternal(animatedImageLoading.GetUrl(), + alphaMaskId, + contentScaleFactor, + ImageDimensions(), + FittingMode::SCALE_TO_FILL, + SamplingMode::BOX_THEN_LINEAR, + TextureManager::NO_ATLAS, + cropToMask, + StorageType::UPLOAD_TO_TEXTURE, + textureObserver, + true, + TextureManager::ReloadPolicy::CACHED, + preMultiply, + animatedImageLoading, + frameIndex, + useCache); + TextureManager::LoadState loadState = GetTextureStateInternal(textureId); if(loadState == TextureManager::LoadState::UPLOADED) { @@ -244,8 +281,25 @@ Devel::PixelBuffer TextureManager::LoadPixelBuffer( return pixelBuffer; } -TextureSet TextureManager::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, TextureManager::MultiplyOnLoad& preMultiplyOnLoad) +TextureSet TextureManager::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, + TextureManager::MultiplyOnLoad& preMultiplyOnLoad) { TextureSet textureSet; diff --git a/dali-toolkit/internal/visuals/texture-manager-impl.h b/dali-toolkit/internal/visuals/texture-manager-impl.h index 4fddf49..0da2ba2 100644 --- a/dali-toolkit/internal/visuals/texture-manager-impl.h +++ b/dali-toolkit/internal/visuals/texture-manager-impl.h @@ -59,7 +59,7 @@ class TextureManager : public ConnectionTracker { public: 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 + static constexpr int32_t 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 @@ -169,6 +169,7 @@ public: * @param[in] frameIndex The frame index to load. * @param[out] loadingStatus The loading status of the texture * @param[out] textureId The textureId of the frame + * @param[in, out] maskInfo Mask info structure * @param[in] samplingMode The SamplingMode to use * @param[in] wrapModeU Horizontal Wrap mode * @param[in] wrapModeV Vertical Wrap mode @@ -184,6 +185,7 @@ public: uint32_t frameIndex, bool& loadingStatus, TextureManager::TextureId& textureId, + MaskingDataPointer& maskInfo, Dali::SamplingMode::Type samplingMode, Dali::WrapMode::Type wrapModeU, Dali::WrapMode::Type wrapModeV, -- 2.7.4