From ba1c6fea08ea39ca92356ae4b39a952919398e7e Mon Sep 17 00:00:00 2001 From: seungho Date: Wed, 18 May 2022 21:08:22 +0900 Subject: [PATCH] Enable to use GPU masking in image visual Change-Id: I37673b02dfa6764a1ebf87a68193c839a6b6212d Signed-off-by: seungho --- .../src/dali-toolkit/utc-Dali-ImageVisual.cpp | 183 ++++++++++++++++++++- .../texture-manager/texture-manager-impl.cpp | 81 +++++---- .../animated-image/animated-image-visual.cpp | 1 - .../internal/visuals/image/image-visual.cpp | 117 ++++++++++++- dali-toolkit/internal/visuals/image/image-visual.h | 18 ++ .../internal/visuals/visual-string-constants.cpp | 1 + .../internal/visuals/visual-string-constants.h | 1 + .../public-api/visuals/image-visual-properties.h | 2 +- 8 files changed, 360 insertions(+), 44 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp index b36457f..3f4fdba 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp @@ -1593,7 +1593,7 @@ int UtcDaliImageVisualSetInvalidRemoteImage(void) END_TEST; } -int UtcDaliImageVisualAlphaMask(void) +int UtcDaliImageVisualAlphaMask01(void) { ToolkitTestApplication application; tet_infoline("Request image visual with a Property::Map containing an Alpha mask"); @@ -1647,7 +1647,127 @@ int UtcDaliImageVisualAlphaMask(void) END_TEST; } -int UtcDaliImageVisualSynchronousLoadAlphaMask(void) +int UtcDaliImageVisualAlphaMask02(void) +{ + ToolkitTestApplication application; + tet_infoline("Request image visual with a Property::Map containing an Alpha mask for GPU"); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME); + propertyMap.Insert(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + Property::Map testMap; + visual.CreatePropertyMap(testMap); + DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION); + DALI_TEST_EQUALS(*testMap.Find(DevelImageVisual::Property::MASKING_TYPE), Property::Value(DevelImageVisual::MaskingType::MASKING_ON_RENDERING), TEST_LOCATION); + + // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied. + // Image with a size smaller than 512*512 will be uploaded as a part of the atlas. + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION); + + application.GetScene().Add(actor); + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + Renderer renderer = actor.GetRendererAt(0u); + TextureSet textures = renderer.GetTextures(); + DALI_TEST_CHECK(textures); + DALI_TEST_EQUALS(textures.GetTextureCount(), 2u, TEST_LOCATION); + + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + + dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualAlphaMask03(void) +{ + ToolkitTestApplication application; + tet_infoline("Request image visual with a Property::Map containing an Alpha mask for GPU with fail case"); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, "dummy_path"); + propertyMap.Insert(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + Property::Map testMap; + visual.CreatePropertyMap(testMap); + + // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied. + // Image with a size smaller than 512*512 will be uploaded as a part of the atlas. + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION); + + application.GetScene().Add(actor); + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + Renderer renderer = actor.GetRendererAt(0u); + TextureSet textures = renderer.GetTextures(); + DALI_TEST_CHECK(textures); + DALI_TEST_EQUALS(textures.GetTextureCount(), 1u, TEST_LOCATION); + + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + + dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualSynchronousLoadAlphaMask01(void) { ToolkitTestApplication application; tet_infoline("Request image visual with a Property::Map containing an Alpha mask with synchronous loading"); @@ -1700,6 +1820,65 @@ int UtcDaliImageVisualSynchronousLoadAlphaMask(void) END_TEST; } +int UtcDaliImageVisualSynchronousLoadAlphaMask02(void) +{ + ToolkitTestApplication application; + tet_infoline("Request image visual with a Property::Map containing an Alpha mask for GPU with synchronous loading"); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); + propertyMap.Insert(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + Property::Map testMap; + visual.CreatePropertyMap(testMap); + DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION); + + // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied. + // Image with a size smaller than 512*512 will be uploaded as a part of the atlas. + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION); + + application.GetScene().Add(actor); + + // Do not wait for any EventThreadTrigger in synchronous alpha mask. + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + Renderer renderer = actor.GetRendererAt(0u); + TextureSet textures = renderer.GetTextures(); + DALI_TEST_CHECK(textures); + DALI_TEST_EQUALS(textures.GetTextureCount(), 2u, TEST_LOCATION); + + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + + dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + + END_TEST; +} + int UtcDaliImageVisualRemoteAlphaMask(void) { ToolkitTestApplication application; diff --git a/dali-toolkit/internal/texture-manager/texture-manager-impl.cpp b/dali-toolkit/internal/texture-manager/texture-manager-impl.cpp index cac3b47..445ad65 100644 --- a/dali-toolkit/internal/texture-manager/texture-manager-impl.cpp +++ b/dali-toolkit/internal/texture-manager/texture-manager-impl.cpp @@ -402,39 +402,36 @@ TextureSet TextureManager::LoadTexture( if(!textureSet) // big image, no atlasing or atlasing failed { atlasingStatus = false; - if(!maskInfo || !maskInfo->mAlphaMaskUrl.IsValid()) - { - textureId = RequestLoad( - url, - desiredSize, - fittingMode, - samplingMode, - UseAtlas::NO_ATLAS, - textureObserver, - orientationCorrection, - reloadPolicy, - preMultiplyOnLoad, - synchronousLoading); - } - else + + TextureId alphaMaskId = INVALID_TEXTURE_ID; + float contentScaleFactor = 1.0f; + bool cropToMask = false; + if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid()) { maskInfo->mAlphaMaskId = RequestMaskLoad(maskInfo->mAlphaMaskUrl, maskInfo->mPreappliedMasking ? StorageType::KEEP_PIXEL_BUFFER : StorageType::KEEP_TEXTURE, synchronousLoading); - textureId = RequestLoad( - url, - maskInfo->mAlphaMaskId, - maskInfo->mContentScaleFactor, - desiredSize, - fittingMode, - samplingMode, - UseAtlas::NO_ATLAS, - maskInfo->mCropToMask, - textureObserver, - orientationCorrection, - reloadPolicy, - preMultiplyOnLoad, - synchronousLoading); + alphaMaskId = maskInfo->mAlphaMaskId; + if(maskInfo && maskInfo->mPreappliedMasking) + { + contentScaleFactor = maskInfo->mContentScaleFactor; + cropToMask = maskInfo->mCropToMask; + } } + textureId = RequestLoad( + url, + alphaMaskId, + contentScaleFactor, + desiredSize, + fittingMode, + samplingMode, + UseAtlas::NO_ATLAS, + cropToMask, + textureObserver, + orientationCorrection, + reloadPolicy, + preMultiplyOnLoad, + synchronousLoading); + TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId); if(loadState == TextureManager::LoadState::UPLOADED) { @@ -667,19 +664,31 @@ TextureManager::TextureId TextureManager::RequestLoadInternal( } else // For the image loading. { + Texture maskTexture; if(maskTextureId != INVALID_TEXTURE_ID) { TextureCacheIndex maskCacheIndex = mTextureCacheManager.GetCacheIndexFromId(maskTextureId); if(maskCacheIndex != INVALID_CACHE_INDEX) { - Devel::PixelBuffer maskPixelBuffer = mTextureCacheManager[maskCacheIndex].pixelBuffer; - if(maskPixelBuffer) + if(mTextureCacheManager[maskCacheIndex].storageType == StorageType::KEEP_TEXTURE) { - pixelBuffer.ApplyMask(maskPixelBuffer, contentScale, cropToMask); + TextureSet maskTextures = mTextureCacheManager[maskCacheIndex].textureSet; + if(maskTextures && maskTextures.GetTextureCount()) + { + maskTexture = maskTextures.GetTexture(0u); + } } - else + else if(mTextureCacheManager[maskCacheIndex].storageType == StorageType::KEEP_PIXEL_BUFFER) { - DALI_LOG_ERROR("Mask image cached invalid pixel buffer!\n"); + Devel::PixelBuffer maskPixelBuffer = mTextureCacheManager[maskCacheIndex].pixelBuffer; + if(maskPixelBuffer) + { + pixelBuffer.ApplyMask(maskPixelBuffer, contentScale, cropToMask); + } + else + { + DALI_LOG_ERROR("Mask image cached invalid pixel buffer!\n"); + } } } else @@ -691,6 +700,10 @@ TextureManager::TextureId TextureManager::RequestLoadInternal( // Upload texture UploadTexture(pixelBuffer, textureInfo); + if(maskTexture && textureInfo.textureSet) + { + textureInfo.textureSet.SetTexture(1u, maskTexture); + } } } } 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 72f44cf..a334e2f 100644 --- a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp @@ -83,7 +83,6 @@ 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; -const char* const MASK_TEXTURE_RATIO_NAME("maskTextureRatio"); constexpr uint32_t TEXTURE_COUNT_FOR_GPU_ALPHA_MASK = 2u; #if defined(DEBUG_ENABLED) diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index e3aa797..44c9fac 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual.cpp @@ -51,7 +51,7 @@ namespace Internal { namespace { -const int CUSTOM_PROPERTY_COUNT(9); // wrap, pixel area, atlas, pixalign, + border/corner +const int CUSTOM_PROPERTY_COUNT(12); // ltr, wrap, pixel area, atlas, pixalign, crop to mask, mask texture ratio + border/corner // fitting modes DALI_ENUM_TO_STRING_TABLE_BEGIN(FITTING_MODE) @@ -99,6 +99,8 @@ const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f); const float PIXEL_ALIGN_ON = 1.0f; const float PIXEL_ALIGN_OFF = 0.0f; +constexpr uint32_t TEXTURE_COUNT_FOR_GPU_ALPHA_MASK = 2u; + Geometry CreateGeometry(VisualFactoryCache& factoryCache, ImageDimensions gridSize) { Geometry geometry; @@ -274,6 +276,10 @@ void ImageVisual::DoSetProperties(const Property::Map& propertyMap) { 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); @@ -426,6 +432,17 @@ void ImageVisual::DoSetProperty(Property::Index index, const Property::Value& va 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; + } + case Toolkit::ImageVisual::Property::RELEASE_POLICY: { int releasePolicy = 0; @@ -481,11 +498,9 @@ void ImageVisual::GetNaturalSize(Vector2& naturalSize) auto textureSet = mImpl->mRenderer.GetTextures(); if(textureSet && textureSet.GetTextureCount()) { - auto texture = textureSet.GetTexture(0); - if(texture) + if(mTextureSize != Vector2::ZERO) { - naturalSize.x = texture.GetWidth(); - naturalSize.y = texture.GetHeight(); + naturalSize = mTextureSize; return; } } @@ -574,6 +589,11 @@ void ImageVisual::OnInitialize() mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT); EnablePreMultipliedAlpha(IsPreMultipliedAlphaEnabled()); + + if(mMaskingData) + { + mImpl->mRenderer.RegisterProperty(CROP_TO_MASK_NAME, static_cast(mMaskingData->mCropToMask)); + } } void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& textures, bool orientationCorrection, TextureManager::ReloadPolicy forceReload) @@ -661,6 +681,8 @@ void ImageVisual::InitializeRenderer() if(mTextures) { mImpl->mRenderer.SetTextures(mTextures); + ComputeTextureSize(); + CheckMaskTexture(); if(DevelTexture::IsNative(mTextures.GetTexture(0))) { UpdateShader(); @@ -745,6 +767,7 @@ void ImageVisual::DoSetOffScene(Actor& actor) TextureSet textureSet = TextureSet::New(); mImpl->mRenderer.SetTextures(textureSet); + ComputeTextureSize(); mLoadState = TextureManager::LoadState::NOT_STARTED; } @@ -780,6 +803,7 @@ void ImageVisual::DoCreatePropertyMap(Property::Map& map) const 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); @@ -879,6 +903,8 @@ void ImageVisual::LoadComplete(bool loadingSuccess, TextureInformation textureIn sampler.SetWrapMode(mWrapModeU, mWrapModeV); textureInformation.textureSet.SetSampler(0u, sampler); mImpl->mRenderer.SetTextures(textureInformation.textureSet); + ComputeTextureSize(); + CheckMaskTexture(); } if(actor) @@ -967,6 +993,60 @@ void ImageVisual::RemoveTexture() } } +void ImageVisual::ComputeTextureSize() +{ + if(mImpl->mRenderer) + { + auto textureSet = mImpl->mRenderer.GetTextures(); + if(textureSet && textureSet.GetTextureCount()) + { + auto texture = textureSet.GetTexture(0); + if(texture) + { + mTextureSize.x = texture.GetWidth(); + mTextureSize.y = texture.GetHeight(); + if(textureSet.GetTextureCount() > 1u && mMaskingData && !mMaskingData->mPreappliedMasking && mMaskingData->mCropToMask) + { + Texture maskTexture = textureSet.GetTexture(1); + if(maskTexture) + { + mTextureSize.x = std::min(static_cast(mTextureSize.x * mMaskingData->mContentScaleFactor), maskTexture.GetWidth()); + mTextureSize.y = std::min(static_cast(mTextureSize.y * mMaskingData->mContentScaleFactor), maskTexture.GetHeight()); + } + } + } + } + } +} + +Vector2 ImageVisual::ComputeMaskTextureRatio() +{ + Vector2 maskTextureRatio; + if(mImpl->mRenderer) + { + auto textureSet = mImpl->mRenderer.GetTextures(); + if(textureSet && textureSet.GetTextureCount()) + { + auto texture = textureSet.GetTexture(0); + if(texture) + { + if(textureSet.GetTextureCount() > 1u && mMaskingData && !mMaskingData->mPreappliedMasking && mMaskingData->mCropToMask) + { + Texture maskTexture = textureSet.GetTexture(1); + if(maskTexture) + { + 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); + maskTextureRatio = Vector2(std::min(static_cast(maskTexture.GetWidth()), textureWidth) / textureWidth, + std::min(static_cast(maskTexture.GetHeight()), textureHeight) / textureHeight); + } + } + } + } + } + return maskTextureRatio; +} + Shader ImageVisual::GenerateShader() const { Shader shader; @@ -977,6 +1057,7 @@ Shader ImageVisual::GenerateShader() const if(useStandardShader) { + bool requiredAlphaMaskingOnRendering = (mMaskingData && !mMaskingData->mMaskImageLoadingFailed) ? !mMaskingData->mPreappliedMasking : false; // Create and cache the standard shader shader = mImageVisualShaderFactory.GetShader( mFactoryCache, @@ -985,7 +1066,8 @@ Shader ImageVisual::GenerateShader() const .ApplyDefaultTextureWrapMode(mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE) .EnableRoundedCorner(IsRoundedCornerRequired()) .EnableBorderline(IsBorderlineRequired()) - .SetTextureForFragmentShaderCheck(useNativeImage ? mTextures.GetTexture(0) : Dali::Texture())); + .SetTextureForFragmentShaderCheck(useNativeImage ? mTextures.GetTexture(0) : Dali::Texture()) + .EnableAlphaMaskingOnRendering(requiredAlphaMaskingOnRendering)); } else { @@ -1047,6 +1129,29 @@ Shader ImageVisual::GenerateShader() const return shader; } +void ImageVisual::CheckMaskTexture() +{ + if(mMaskingData && !mMaskingData->mPreappliedMasking) + { + bool maskLoadFailed = true; + TextureSet textures = mImpl->mRenderer.GetTextures(); + if(textures && textures.GetTextureCount() >= TEXTURE_COUNT_FOR_GPU_ALPHA_MASK) + { + if(mMaskingData->mCropToMask) + { + mImpl->mRenderer.RegisterProperty(MASK_TEXTURE_RATIO_NAME, ComputeMaskTextureRatio()); + } + maskLoadFailed = false; + } + + if(mMaskingData->mMaskImageLoadingFailed != maskLoadFailed) + { + mMaskingData->mMaskImageLoadingFailed = maskLoadFailed; + UpdateShader(); + } + } +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/visuals/image/image-visual.h b/dali-toolkit/internal/visuals/image/image-visual.h index 0cbc3ba..17d5a6e 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.h +++ b/dali-toolkit/internal/visuals/image/image-visual.h @@ -299,12 +299,29 @@ private: void RemoveTexture(); /** + * @brief Compute texture size + */ + void ComputeTextureSize(); + + /** + * @brief Compute mask texture ratio + * @return The Mask Texture Ratio + */ + Vector2 ComputeMaskTextureRatio(); + + /** * Helper method to set individual values by index key. * @param[in] index The index key of the value * @param[in] value The value */ void DoSetProperty(Property::Index index, const Property::Value& value); + /** + * @brief Check whether the mask texture is loaded or not. + * If MaskingType is MASKING_ON_LOADING and mask texture is failed to load, update shader. + */ + void CheckMaskTexture(); + private: Vector4 mPixelArea; WeakHandle mPlacementActor; @@ -314,6 +331,7 @@ private: Dali::ImageDimensions mDesiredSize; TextureManager::TextureId mTextureId; TextureSet mTextures; + Vector2 mTextureSize; ImageVisualShaderFactory& mImageVisualShaderFactory; diff --git a/dali-toolkit/internal/visuals/visual-string-constants.cpp b/dali-toolkit/internal/visuals/visual-string-constants.cpp index 6b48a2d..c79c9a6 100644 --- a/dali-toolkit/internal/visuals/visual-string-constants.cpp +++ b/dali-toolkit/internal/visuals/visual-string-constants.cpp @@ -123,6 +123,7 @@ const char* const IMAGE_DESIRED_HEIGHT("desiredHeight"); const char* const ALPHA_MASK_URL("alphaMaskUrl"); const char* const REDRAW_IN_SCALING_DOWN_NAME("redrawInScalingDown"); const char* const MASKING_TYPE_NAME("maskingType"); +const char* const MASK_TEXTURE_RATIO_NAME("maskTextureRatio"); // Text visual const char* const TEXT_PROPERTY("text"); diff --git a/dali-toolkit/internal/visuals/visual-string-constants.h b/dali-toolkit/internal/visuals/visual-string-constants.h index e736132..b65292f 100644 --- a/dali-toolkit/internal/visuals/visual-string-constants.h +++ b/dali-toolkit/internal/visuals/visual-string-constants.h @@ -107,6 +107,7 @@ extern const char* const IMAGE_DESIRED_HEIGHT; extern const char* const ALPHA_MASK_URL; extern const char* const REDRAW_IN_SCALING_DOWN_NAME; extern const char* const MASKING_TYPE_NAME; +extern const char* const MASK_TEXTURE_RATIO_NAME; // Text visual extern const char* const TEXT_PROPERTY; diff --git a/dali-toolkit/public-api/visuals/image-visual-properties.h b/dali-toolkit/public-api/visuals/image-visual-properties.h index b0b28d4..29b9409 100644 --- a/dali-toolkit/public-api/visuals/image-visual-properties.h +++ b/dali-toolkit/public-api/visuals/image-visual-properties.h @@ -226,7 +226,7 @@ enum * @details Name "cropToMask", type Property::BOOLEAN, True if the image should * be cropped to match the mask size, or false if the image should remain the same size. * @SINCE_1_2.60 - * @note Optional. + * @note Optional, Default true * @note If this is false, then the mask is scaled to fit the image before being applied. */ CROP_TO_MASK, -- 2.7.4