X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fvisuals%2Fanimated-image%2Fanimated-image-visual.cpp;h=a334e2f83bc4a0dff18822f7cbb0ecb9a6d92177;hp=be73cca489486dcf3c219c91daad978177dc08db;hb=ba1c6fea08ea39ca92356ae4b39a952919398e7e;hpb=3194e652e08af630b8996c88b0d0f09e3e78b568 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 be73cca..a334e2f 100644 --- a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp @@ -46,7 +46,7 @@ namespace Internal { namespace { -const int CUSTOM_PROPERTY_COUNT(3); // ltr, wrap, pixel area, +const int CUSTOM_PROPERTY_COUNT(10); // ltr, wrap, pixel area, crop to mask, mask texture ratio + border/corner // stop behavior DALI_ENUM_TO_STRING_TABLE_BEGIN(STOP_BEHAVIOR) @@ -83,6 +83,8 @@ static constexpr Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f); static constexpr auto LOOP_FOREVER = -1; static constexpr auto FIRST_LOOP = 0u; +constexpr uint32_t TEXTURE_COUNT_FOR_GPU_ALPHA_MASK = 2u; + #if defined(DEBUG_ENABLED) Debug::Filter* gAnimImgLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_ANIMATED_IMAGE"); #endif @@ -163,7 +165,7 @@ AnimatedImageVisualPtr AnimatedImageVisual::New(VisualFactoryCache& factoryCache void AnimatedImageVisual::InitializeAnimatedImage(const VisualUrl& imageUrl) { - mImageUrl = imageUrl; + mImageUrl = imageUrl; mAnimatedImageLoading = AnimatedImageLoading::New(imageUrl.GetUrl(), imageUrl.IsLocalResource()); } @@ -175,7 +177,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(),mFactoryCache.GetPreMultiplyOnLoad()); } else if(mImageUrls) { @@ -186,11 +188,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); } } @@ -219,6 +221,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), @@ -228,6 +231,7 @@ AnimatedImageVisual::AnimatedImageVisual(VisualFactoryCache& factoryCache, Image mStartFirstFrame(false), mIsJumpTo(false) { + EnablePreMultipliedAlpha(mFactoryCache.GetPreMultiplyOnLoad()); } AnimatedImageVisual::~AnimatedImageVisual() @@ -246,13 +250,26 @@ void AnimatedImageVisual::GetNaturalSize(Vector2& naturalSize) { if(mImageSize.GetWidth() == 0 && mImageSize.GetHeight() == 0) { + if(mMaskingData && mMaskingData->mAlphaMaskUrl.IsValid() && + mMaskingData->mCropToMask) + { + ImageDimensions dimensions = Dali::GetClosestImageSize(mMaskingData->mAlphaMaskUrl.GetUrl()); + if(dimensions != ImageDimensions(0, 0)) + { + mImageSize = dimensions; + naturalSize.x = dimensions.GetWidth(); + naturalSize.y = dimensions.GetHeight(); + return; + } + } + if(mImageUrl.IsValid()) { mImageSize = mAnimatedImageLoading.GetImageSize(); } else if(mImageUrls && mImageUrls->size() > 0) { - mImageSize = Dali::GetClosestImageSize((*mImageUrls)[0].mUrl); + mImageSize = Dali::GetClosestImageSize((*mImageUrls)[0].mUrl.GetUrl()); } } @@ -278,7 +295,7 @@ void AnimatedImageVisual::DoCreatePropertyMap(Property::Map& map) const Property::Array urls; for(unsigned int i = 0; i < mImageUrls->size(); ++i) { - urls.Add((*mImageUrls)[i].mUrl); + urls.Add((*mImageUrls)[i].mUrl.GetUrl()); } Property::Value value(const_cast(urls)); map.Insert(Toolkit::ImageVisual::Property::URL, value); @@ -293,11 +310,18 @@ void AnimatedImageVisual::DoCreatePropertyMap(Property::Map& map) const map.Insert(Toolkit::ImageVisual::Property::FRAME_DELAY, static_cast(mFrameDelay)); map.Insert(Toolkit::DevelImageVisual::Property::LOOP_COUNT, static_cast(mLoopCount)); map.Insert(Toolkit::DevelImageVisual::Property::CURRENT_FRAME_NUMBER, (mImageCache) ? static_cast(mImageCache->GetCurrentFrameIndex()) : -1); - map.Insert(Toolkit::DevelImageVisual::Property::TOTAL_FRAME_NUMBER, (mImageCache) ? static_cast((mAnimatedImageLoading) ? mAnimatedImageLoading.GetImageCount() : - mImageCache->GetTotalFrameCount()) : -1); + map.Insert(Toolkit::DevelImageVisual::Property::TOTAL_FRAME_NUMBER, (mImageCache) ? static_cast((mAnimatedImageLoading) ? mAnimatedImageLoading.GetImageCount() : mImageCache->GetTotalFrameCount()) : -1); map.Insert(Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, mStopBehavior); + if(mMaskingData != nullptr) + { + 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::DevelImageVisual::Property::MASKING_TYPE, mMaskingData->mPreappliedMasking ? DevelImageVisual::MaskingType::MASKING_ON_LOADING : DevelImageVisual::MaskingType::MASKING_ON_RENDERING); + } + map.Insert(Toolkit::ImageVisual::Property::LOAD_POLICY, mLoadPolicy); map.Insert(Toolkit::ImageVisual::Property::RELEASE_POLICY, mReleasePolicy); } @@ -337,7 +361,7 @@ void AnimatedImageVisual::OnDoAction(const Dali::Property::Index actionId, const { // STOP reset functionality will actually be done in a future change // Stop will be executed on next timer tick - mActionStatus = DevelAnimatedImageVisual::Action::STOP; + mActionStatus = DevelAnimatedImageVisual::Action::STOP; mCurrentLoopIndex = FIRST_LOOP; if(IsOnScene()) { @@ -413,6 +437,22 @@ 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 == MASKING_TYPE_NAME) + { + DoSetProperty(Toolkit::DevelImageVisual::Property::MASKING_TYPE, keyValue.second); + } else if(keyValue.first == LOAD_POLICY_NAME) { DoSetProperty(Toolkit::ImageVisual::Property::LOAD_POLICY, keyValue.second); @@ -545,11 +585,55 @@ void AnimatedImageVisual::DoSetProperty(Property::Index index, value.Get(sync); if(sync) { - mImpl->mFlags |= Impl::IS_SYNCHRONOUS_RESOURCE_LOADING; + mImpl->mFlags |= Visual::Base::Impl::IS_SYNCHRONOUS_RESOURCE_LOADING; } else { - mImpl->mFlags &= ~Impl::IS_SYNCHRONOUS_RESOURCE_LOADING; + mImpl->mFlags &= ~Visual::Base::Impl::IS_SYNCHRONOUS_RESOURCE_LOADING; + } + 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::DevelImageVisual::Property::MASKING_TYPE: + { + int maskingType = 0; + if(value.Get(maskingType)) + { + AllocateMaskData(); + mMaskingData->mPreappliedMasking = Toolkit::DevelImageVisual::MaskingType::Type(maskingType) == Toolkit::DevelImageVisual::MaskingType::MASKING_ON_LOADING ? true : false; } break; } @@ -574,8 +658,8 @@ void AnimatedImageVisual::DoSetProperty(Property::Index index, void AnimatedImageVisual::DoSetOnScene(Actor& actor) { - mStartFirstFrame = true; - mPlacementActor = actor; + mStartFirstFrame = true; + mPlacementActor = actor; PrepareTextureSet(); } @@ -600,9 +684,9 @@ void AnimatedImageVisual::DoSetOffScene(Actor& actor) } mPlacementActor.Reset(); - mStartFirstFrame = false; + mStartFirstFrame = false; mCurrentFrameIndex = FIRST_FRAME_INDEX; - mCurrentLoopIndex = FIRST_LOOP; + mCurrentLoopIndex = FIRST_LOOP; } void AnimatedImageVisual::OnSetTransform() @@ -624,14 +708,16 @@ void AnimatedImageVisual::UpdateShader() Shader AnimatedImageVisual::GenerateShader() const { - bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE; + bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE; + bool requiredAlphaMaskingOnRendering = (mMaskingData && !mMaskingData->mMaskImageLoadingFailed) ? !mMaskingData->mPreappliedMasking : false; Shader shader; shader = mImageVisualShaderFactory.GetShader( mFactoryCache, ImageVisualShaderFeature::FeatureBuilder() .ApplyDefaultTextureWrapMode(defaultWrapMode) .EnableRoundedCorner(IsRoundedCornerRequired()) - .EnableBorderline(IsBorderlineRequired())); + .EnableBorderline(IsBorderlineRequired()) + .EnableAlphaMaskingOnRendering(requiredAlphaMaskingOnRendering)); return shader; } @@ -661,6 +747,17 @@ void AnimatedImageVisual::OnInitialize() { mImpl->mRenderer.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, mPixelArea); } + + if(mMaskingData) + { + mImpl->mRenderer.RegisterProperty(CROP_TO_MASK_NAME, static_cast(mMaskingData->mCropToMask)); + } + + // Enable PreMultipliedAlpha if it need premultiplied + auto preMultiplyOnLoad = IsPreMultipliedAlphaEnabled() && !mImpl->mCustomShader + ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD + : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY; + EnablePreMultipliedAlpha(preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD); } void AnimatedImageVisual::StartFirstFrame(TextureSet& textureSet, uint32_t firstInterval) @@ -671,6 +768,7 @@ void AnimatedImageVisual::StartFirstFrame(TextureSet& textureSet, uint32_t first if(mImpl->mRenderer) { mImpl->mRenderer.SetTextures(textureSet); + CheckMaskTexture(); Actor actor = mPlacementActor.GetHandle(); if(actor) @@ -721,6 +819,22 @@ void AnimatedImageVisual::SetImageSize(TextureSet& textureSet) mImageSize.SetWidth(texture.GetWidth()); mImageSize.SetHeight(texture.GetHeight()); } + + if(textureSet.GetTextureCount() > 1u && mMaskingData && mMaskingData->mCropToMask) + { + Texture maskTexture = textureSet.GetTexture(1); + if(maskTexture) + { + mImageSize.SetWidth(std::min(static_cast(mImageSize.GetWidth() * mMaskingData->mContentScaleFactor), maskTexture.GetWidth())); + mImageSize.SetHeight(std::min(static_cast(mImageSize.GetHeight() * mMaskingData->mContentScaleFactor), maskTexture.GetHeight())); + + float textureWidth = std::max(static_cast(texture.GetWidth() * mMaskingData->mContentScaleFactor), Dali::Math::MACHINE_EPSILON_1); + float textureHeight = std::max(static_cast(texture.GetHeight() * mMaskingData->mContentScaleFactor), Dali::Math::MACHINE_EPSILON_1); + Vector2 textureRatio(std::min(static_cast(maskTexture.GetWidth()), textureWidth) / textureWidth, + std::min(static_cast(maskTexture.GetHeight()), textureHeight) / textureHeight); + mImpl->mRenderer.RegisterProperty(MASK_TEXTURE_RATIO_NAME, textureRatio); + } + } } } @@ -747,6 +861,7 @@ void AnimatedImageVisual::FrameReady(TextureSet textureSet, uint32_t interval) mFrameDelayTimer.SetInterval(interval); } mImpl->mRenderer.SetTextures(textureSet); + CheckMaskTexture(); } } } @@ -815,6 +930,7 @@ bool AnimatedImageVisual::DisplayNextFrame() if(mImpl->mRenderer) { mImpl->mRenderer.SetTextures(textureSet); + CheckMaskTexture(); } mFrameDelayTimer.SetInterval(mImageCache->GetFrameInterval(frameIndex)); } @@ -851,6 +967,32 @@ TextureSet AnimatedImageVisual::SetLoadingFailed() return textureSet; } +void AnimatedImageVisual::AllocateMaskData() +{ + if(!mMaskingData) + { + mMaskingData.reset(new TextureManager::MaskingData()); + } +} + +void AnimatedImageVisual::CheckMaskTexture() +{ + if(mMaskingData && !mMaskingData->mPreappliedMasking) + { + bool maskLoadFailed = true; + TextureSet textures = mImpl->mRenderer.GetTextures(); + if(textures && textures.GetTextureCount() >= TEXTURE_COUNT_FOR_GPU_ALPHA_MASK) + { + maskLoadFailed = false; + } + if(mMaskingData->mMaskImageLoadingFailed != maskLoadFailed) + { + mMaskingData->mMaskImageLoadingFailed = maskLoadFailed; + UpdateShader(); + } + } +} + } // namespace Internal } // namespace Toolkit