X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fvisuals%2Fimage%2Fimage-visual.cpp;h=44c9fac851bc3d770aa871ee104bc344eb176d6e;hp=39b18ee886f3812c67f969bbbc0651ad5feac130;hb=ba1c6fea08ea39ca92356ae4b39a952919398e7e;hpb=441331edb2d1886e4a2ba77d702b60067908c10d diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index 39b18ee..44c9fac 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -31,9 +31,9 @@ // INTERNAL HEADERS #include +#include #include #include -#include #include #include #include @@ -51,6 +51,8 @@ namespace Internal { namespace { +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) DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::FittingMode, SHRINK_TO_FIT) @@ -97,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; @@ -200,7 +204,7 @@ ImageVisual::~ImageVisual() else if(mImageUrl.IsBufferResource()) { TextureManager& textureManager = mFactoryCache.GetTextureManager(); - textureManager.RemoveExternalEncodedImageBuffer(mImageUrl.GetUrl()); + textureManager.RemoveEncodedImageBuffer(mImageUrl.GetUrl()); } } @@ -272,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); @@ -305,11 +313,11 @@ void ImageVisual::DoSetProperty(Property::Index index, const Property::Value& va { 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; } } else @@ -424,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; @@ -469,7 +488,7 @@ void ImageVisual::GetNaturalSize(Vector2& naturalSize) } else if(mImpl->mRenderer) // Check if we have a loaded image { - if(mImpl->mFlags & Impl::IS_ATLASING_APPLIED) + if(mImpl->mFlags & Visual::Base::Impl::IS_ATLASING_APPLIED) { naturalSize.x = mAtlasRectSize.GetWidth(); naturalSize.y = mAtlasRectSize.GetHeight(); @@ -479,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; } } @@ -513,7 +530,7 @@ void ImageVisual::GetNaturalSize(Vector2& naturalSize) } else { - Actor actor = mPlacementActor.GetHandle(); + Actor actor = mPlacementActor.GetHandle(); Vector2 imageSize = Vector2::ZERO; if(actor) { @@ -521,8 +538,8 @@ void ImageVisual::GetNaturalSize(Vector2& naturalSize) } mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); Texture brokenImage = mImpl->mRenderer.GetTextures().GetTexture(0); - naturalSize.x = brokenImage.GetWidth(); - naturalSize.y = brokenImage.GetWidth(); + naturalSize.x = brokenImage.GetWidth(); + naturalSize.y = brokenImage.GetWidth(); } return; } @@ -565,12 +582,18 @@ void ImageVisual::OnInitialize() Shader shader = GenerateShader(); // Create the renderer - mImpl->mRenderer = Renderer::New(geometry, shader); + mImpl->mRenderer = VisualRenderer::New(geometry, shader); + mImpl->mRenderer.ReserveCustomProperties(CUSTOM_PROPERTY_COUNT); //Register transform properties - mImpl->mTransform.RegisterUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT); + 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) @@ -617,11 +640,11 @@ void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& te if(atlasing) // Flag needs to be set before creating renderer { - mImpl->mFlags |= Impl::IS_ATLASING_APPLIED; + mImpl->mFlags |= Visual::Base::Impl::IS_ATLASING_APPLIED; } else { - mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED; + mImpl->mFlags &= ~Visual::Base::Impl::IS_ATLASING_APPLIED; } } @@ -658,6 +681,8 @@ void ImageVisual::InitializeRenderer() if(mTextures) { mImpl->mRenderer.SetTextures(mTextures); + ComputeTextureSize(); + CheckMaskTexture(); if(DevelTexture::IsNative(mTextures.GetTexture(0))) { UpdateShader(); @@ -742,6 +767,7 @@ void ImageVisual::DoSetOffScene(Actor& actor) TextureSet textureSet = TextureSet::New(); mImpl->mRenderer.SetTextures(textureSet); + ComputeTextureSize(); mLoadState = TextureManager::LoadState::NOT_STARTED; } @@ -755,7 +781,7 @@ void ImageVisual::DoCreatePropertyMap(Property::Map& map) const map.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE); bool sync = IsSynchronousLoadingRequired(); - map.Insert(SYNCHRONOUS_LOADING, sync); + map.Insert(Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, sync); if(mImageUrl.IsValid()) { map.Insert(Toolkit::ImageVisual::Property::URL, mImageUrl.GetUrl()); @@ -777,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); @@ -814,16 +841,10 @@ void ImageVisual::OnSetTransform() { if(mImpl->mRenderer) { - mImpl->mTransform.RegisterUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT); + mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT); } } -bool ImageVisual::IsResourceReady() const -{ - return (mImpl->mResourceStatus == Toolkit::Visual::ResourceStatus::READY || - mImpl->mResourceStatus == Toolkit::Visual::ResourceStatus::FAILED); -} - void ImageVisual::UpdateShader() { if(mImpl->mRenderer) @@ -882,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) @@ -970,26 +993,81 @@ 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; - bool usesWholeTexture = true; - const bool useStandardShader = !mImpl->mCustomShader; - const bool useNativeImage = (mTextures && DevelTexture::IsNative(mTextures.GetTexture(0))); + bool usesWholeTexture = true; + const bool useStandardShader = !mImpl->mCustomShader; + const bool useNativeImage = (mTextures && DevelTexture::IsNative(mTextures.GetTexture(0))); if(useStandardShader) { + bool requiredAlphaMaskingOnRendering = (mMaskingData && !mMaskingData->mMaskImageLoadingFailed) ? !mMaskingData->mPreappliedMasking : false; // Create and cache the standard shader shader = mImageVisualShaderFactory.GetShader( mFactoryCache, ImageVisualShaderFeature::FeatureBuilder() - .EnableTextureAtlas(mImpl->mFlags & Impl::IS_ATLASING_APPLIED && !useNativeImage) - .ApplyDefaultTextureWrapMode(mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE) - .EnableRoundedCorner(IsRoundedCornerRequired()) - .EnableBorderline(IsBorderlineRequired()) - .SetTextureForFragmentShaderCheck(useNativeImage ? mTextures.GetTexture(0) : Dali::Texture()) - ); + .EnableTextureAtlas(mImpl->mFlags & Visual::Base::Impl::IS_ATLASING_APPLIED && !useNativeImage) + .ApplyDefaultTextureWrapMode(mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE) + .EnableRoundedCorner(IsRoundedCornerRequired()) + .EnableBorderline(IsBorderlineRequired()) + .SetTextureForFragmentShaderCheck(useNativeImage ? mTextures.GetTexture(0) : Dali::Texture()) + .EnableAlphaMaskingOnRendering(requiredAlphaMaskingOnRendering)); } else { @@ -1051,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