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=da12c4ff7b319cf90e43811fa91f2a1fa6115635;hp=03e0657963fa9dff9fe5905e39063a84f430285e;hb=2bba756a645043d8c1c4023a75966401d531827c;hpb=f2039d47f9bed8104575da80a2ecf0bb6e37ff8d diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index 03e0657..da12c4f 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. @@ -27,13 +27,14 @@ #include #include #include +#include #include // for strlen() // INTERNAL HEADERS #include +#include #include #include -#include #include #include #include @@ -51,6 +52,8 @@ namespace Internal { namespace { +const int CUSTOM_PROPERTY_COUNT(7); // ltr, wrap, pixel area, atlas, pixalign, crop to mask, mask texture ratio + // fitting modes DALI_ENUM_TO_STRING_TABLE_BEGIN(FITTING_MODE) DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::FittingMode, SHRINK_TO_FIT) @@ -97,6 +100,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; @@ -175,15 +180,20 @@ ImageVisual::~ImageVisual() { if(Stage::IsInstalled()) { - if(mMaskingData) + if(mImageUrl.IsValid()) { - // TextureManager could have been deleted before the actor that contains this - // ImageVisual is destroyed (e.g. due to stage shutdown). Ensure the stage - // is still valid before accessing texture manager. - if(mMaskingData->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID) + // Decrease reference count of External Resources : + // EncodedImageBuffer or ExternalTextures. + // Ensure the stage is still valid before accessing texture manager. + if(mImageUrl.GetProtocolType() == VisualUrl::TEXTURE) + { + TextureManager& textureManager = mFactoryCache.GetTextureManager(); + textureManager.RemoveExternalTexture(mImageUrl.GetUrl()); + } + else if(mImageUrl.IsBufferResource()) { TextureManager& textureManager = mFactoryCache.GetTextureManager(); - textureManager.Remove(mMaskingData->mAlphaMaskId, this); + textureManager.RemoveEncodedImageBuffer(mImageUrl.GetUrl()); } } @@ -255,6 +265,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); @@ -288,11 +302,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 @@ -407,6 +421,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; @@ -452,7 +477,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(); @@ -460,13 +485,11 @@ void ImageVisual::GetNaturalSize(Vector2& naturalSize) } auto textureSet = mImpl->mRenderer.GetTextures(); - if(textureSet) + 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; } } @@ -496,10 +519,16 @@ void ImageVisual::GetNaturalSize(Vector2& naturalSize) } else { - Texture brokenImage = mFactoryCache.GetBrokenVisualImage(); - - naturalSize.x = brokenImage.GetWidth(); - naturalSize.y = brokenImage.GetWidth(); + Actor actor = mPlacementActor.GetHandle(); + Vector2 imageSize = Vector2::ZERO; + if(actor) + { + imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); + } + mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); + Texture brokenImage = mImpl->mRenderer.GetTextures().GetTexture(0); + naturalSize.x = brokenImage.GetWidth(); + naturalSize.y = brokenImage.GetWidth(); } return; } @@ -530,15 +559,30 @@ void ImageVisual::OnInitialize() } } - Shader shader = GetShader(); + // Increase reference count of External Resources : + // EncodedImageBuffer or ExternalTextures. + // Reference count will be decreased at destructor of the visual. + if(mImageUrl.IsValid() && (mImageUrl.IsBufferResource() || mImageUrl.GetProtocolType() == VisualUrl::TEXTURE)) + { + TextureManager& textureManager = mFactoryCache.GetTextureManager(); + textureManager.UseExternalResource(mImageUrl.GetUrl()); + } + + Shader shader = GenerateShader(); // Create the renderer - mImpl->mRenderer = Renderer::New(geometry, shader); + mImpl->mRenderer = DecoratedVisualRenderer::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) @@ -562,7 +606,7 @@ void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& te bool synchronousLoading = IsSynchronousLoadingRequired(); bool loadingStatus; - textures = textureManager.LoadTexture(mImageUrl, mDesiredSize, mFittingMode, mSamplingMode, mMaskingData, synchronousLoading, mTextureId, atlasRect, mAtlasRectSize, atlasing, loadingStatus, mWrapModeU, mWrapModeV, textureObserver, atlasUploadObserver, atlasManager, mOrientationCorrection, forceReload, preMultiplyOnLoad); + textures = textureManager.LoadTexture(mImageUrl, mDesiredSize, mFittingMode, mSamplingMode, mMaskingData, synchronousLoading, mTextureId, atlasRect, mAtlasRectSize, atlasing, loadingStatus, textureObserver, atlasUploadObserver, atlasManager, mOrientationCorrection, forceReload, preMultiplyOnLoad); if(textures) { @@ -576,6 +620,12 @@ void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& te } EnablePreMultipliedAlpha(preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD); + if(!atlasing) + { + Sampler sampler = Sampler::New(); + sampler.SetWrapMode(mWrapModeU, mWrapModeV); + textures.SetSampler(0u, sampler); + } } else if(synchronousLoading) { @@ -585,17 +635,17 @@ 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; } } bool ImageVisual::AttemptAtlasing() { - return (!mImpl->mCustomShader && mImageUrl.GetProtocolType() == VisualUrl::LOCAL && mAttemptAtlasing); + return (!mImpl->mCustomShader && (mImageUrl.IsLocalResource() || mImageUrl.IsBufferResource()) && mAttemptAtlasing); } void ImageVisual::InitializeRenderer() @@ -620,12 +670,36 @@ void ImageVisual::InitializeRenderer() else { mTextures = mFactoryCache.GetTextureManager().GetTextureSet(mTextureId); + if(!(mImpl->mFlags & Visual::Base::Impl::IS_ATLASING_APPLIED) && mTextures) + { + Sampler sampler = Sampler::New(); + sampler.SetWrapMode(mWrapModeU, mWrapModeV); + mTextures.SetSampler(0u, sampler); + } } } if(mTextures) { mImpl->mRenderer.SetTextures(mTextures); + ComputeTextureSize(); + CheckMaskTexture(); + + bool needToUpdateShader = DevelTexture::IsNative(mTextures.GetTexture(0)); + + if(mTextures.GetTextureCount() == 3) + { + if(mTextures.GetTexture(0).GetPixelFormat() == Pixel::L8 && mTextures.GetTexture(1).GetPixelFormat() == Pixel::CHROMINANCE_U && mTextures.GetTexture(2).GetPixelFormat() == Pixel::CHROMINANCE_V) + { + mNeedYuvToRgb = true; + needToUpdateShader = true; + } + } + + if(needToUpdateShader) + { + UpdateShader(); + } mTextures.Reset(); // Visual should not keep a handle to the texture after this point. } @@ -680,12 +754,12 @@ void ImageVisual::DoSetOnScene(Actor& actor) } else if(mLoadState == TextureManager::LoadState::LOAD_FAILED) { - Texture brokenImage = mFactoryCache.GetBrokenVisualImage(); - - mTextures = TextureSet::New(); - mTextures.SetTexture(0u, brokenImage); - mImpl->mRenderer.SetTextures(mTextures); - + Vector2 imageSize = Vector2::ZERO; + if(actor) + { + imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); + } + mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); actor.AddRenderer(mImpl->mRenderer); mPlacementActor.Reset(); @@ -706,6 +780,7 @@ void ImageVisual::DoSetOffScene(Actor& actor) TextureSet textureSet = TextureSet::New(); mImpl->mRenderer.SetTextures(textureSet); + ComputeTextureSize(); mLoadState = TextureManager::LoadState::NOT_STARTED; } @@ -719,7 +794,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()); @@ -741,6 +816,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); @@ -759,11 +835,11 @@ void ImageVisual::DoCreateInstancePropertyMap(Property::Map& map) const } } -void ImageVisual::OnDoAction(const Dali::Property::Index actionName, const Dali::Property::Value& attributes) +void ImageVisual::OnDoAction(const Dali::Property::Index actionId, const Dali::Property::Value& attributes) { // Check if action is valid for this visual type and perform action if possible - switch(actionName) + switch(actionId) { case DevelImageVisual::Action::RELOAD: { @@ -778,21 +854,15 @@ 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) { - Shader shader = GetShader(); + Shader shader = GenerateShader(); mImpl->mRenderer.SetShader(shader); } } @@ -817,45 +887,64 @@ void ImageVisual::UploadCompleted() } // From Texture Manager -void ImageVisual::UploadComplete(bool loadingSuccess, int32_t textureId, TextureSet textureSet, bool usingAtlas, const Vector4& atlasRectangle, bool preMultiplied) +void ImageVisual::LoadComplete(bool loadingSuccess, TextureInformation textureInformation) { Toolkit::Visual::ResourceStatus resourceStatus; if(mImpl->mRenderer) { - if(usingAtlas) + if(textureInformation.useAtlasing) { mImpl->mRenderer.RegisterProperty(ATLAS_RECT_UNIFORM_NAME, mAtlasRect); } - EnablePreMultipliedAlpha(preMultiplied); + EnablePreMultipliedAlpha(textureInformation.preMultiplied); Actor actor = mPlacementActor.GetHandle(); - if(actor) + if(!loadingSuccess) { - actor.AddRenderer(mImpl->mRenderer); - // reset the weak handle so that the renderer only get added to actor once - mPlacementActor.Reset(); + Vector2 imageSize = Vector2::ZERO; + if(actor) + { + imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); + } + mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize); + textureInformation.textureSet = mImpl->mRenderer.GetTextures(); } - - if(!loadingSuccess) + else { - Texture brokenImage = mFactoryCache.GetBrokenVisualImage(); + if(!textureInformation.useAtlasing) + { + Sampler sampler = Sampler::New(); + sampler.SetWrapMode(mWrapModeU, mWrapModeV); + textureInformation.textureSet.SetSampler(0u, sampler); + } + + mImpl->mRenderer.SetTextures(textureInformation.textureSet); + ComputeTextureSize(); + CheckMaskTexture(); - textureSet = TextureSet::New(); - textureSet.SetTexture(0u, brokenImage); - mImpl->mRenderer.SetTextures(textureSet); + if(textureInformation.textureSet.GetTextureCount() == 3) + { + if(textureInformation.textureSet.GetTexture(0).GetPixelFormat() == Pixel::L8 && textureInformation.textureSet.GetTexture(1).GetPixelFormat() == Pixel::CHROMINANCE_U && textureInformation.textureSet.GetTexture(2).GetPixelFormat() == Pixel::CHROMINANCE_V) + { + mNeedYuvToRgb = true; + UpdateShader(); + } + } } - Sampler sampler = Sampler::New(); - sampler.SetWrapMode(mWrapModeU, mWrapModeV); - textureSet.SetSampler(0u, sampler); - mImpl->mRenderer.SetTextures(textureSet); + if(actor) + { + actor.AddRenderer(mImpl->mRenderer); + // reset the weak handle so that the renderer only get added to actor once + mPlacementActor.Reset(); + } } // Storing TextureSet needed when renderer staged. if(!mImpl->mRenderer) { - mTextures = textureSet; + mTextures = textureInformation.textureSet; } // Image loaded, set status regardless of staged status. @@ -930,61 +1019,128 @@ void ImageVisual::RemoveTexture() } } -Shader ImageVisual::GetShader() +void ImageVisual::ComputeTextureSize() { - Shader shader; - - std::string_view vertexShaderView; - bool usesWholeTexture = true; - if(mImpl->mCustomShader && !mImpl->mCustomShader->mVertexShader.empty()) - { - vertexShaderView = mImpl->mCustomShader->mVertexShader; - usesWholeTexture = false; // Impossible to tell. - } - else + if(mImpl->mRenderer) { - vertexShaderView = mImageVisualShaderFactory.GetVertexShaderSource(); + 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()); + } + } + } + } } +} - std::string_view fragmentShaderView; - if(mImpl->mCustomShader && !mImpl->mCustomShader->mFragmentShader.empty()) - { - fragmentShaderView = mImpl->mCustomShader->mFragmentShader; - } - else +Vector2 ImageVisual::ComputeMaskTextureRatio() +{ + Vector2 maskTextureRatio; + if(mImpl->mRenderer) { - fragmentShaderView = mImageVisualShaderFactory.GetFragmentShaderSource(); + 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; +} - // If the texture is native, we may need to change prefix and sampler in - // the fragment shader - bool modifiedFragmentShader = false; - std::string fragmentShaderString; - if(mTextures && DevelTexture::IsNative(mTextures.GetTexture(0))) - { - Texture nativeTexture = mTextures.GetTexture(0); - fragmentShaderString = std::string(fragmentShaderView); - modifiedFragmentShader = DevelTexture::ApplyNativeFragmentShader(nativeTexture, fragmentShaderString); - fragmentShaderView = fragmentShaderString; - } +Shader ImageVisual::GenerateShader() const +{ + Shader shader; + + bool usesWholeTexture = true; + const bool useStandardShader = !mImpl->mCustomShader; + const bool useNativeImage = (mTextures && DevelTexture::IsNative(mTextures.GetTexture(0))); - const bool useStandardShader = !mImpl->mCustomShader && !modifiedFragmentShader; if(useStandardShader) { + bool requiredAlphaMaskingOnRendering = (mMaskingData && !mMaskingData->mMaskImageLoadingFailed) ? !mMaskingData->mPreappliedMasking : false; // Create and cache the standard shader shader = mImageVisualShaderFactory.GetShader( mFactoryCache, - mImpl->mFlags & Impl::IS_ATLASING_APPLIED, - mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE, - IsRoundedCornerRequired()); - } - else if(mImpl->mCustomShader) - { - shader = Shader::New(vertexShaderView, fragmentShaderView, mImpl->mCustomShader->mHints); + ImageVisualShaderFeature::FeatureBuilder() + .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) + .EnableYuvToRgb(mNeedYuvToRgb)); } else { - shader = Shader::New(vertexShaderView, fragmentShaderView); + std::string_view vertexShaderView; + std::string_view fragmentShaderView; + + if(mImpl->mCustomShader && !mImpl->mCustomShader->mVertexShader.empty()) + { + vertexShaderView = mImpl->mCustomShader->mVertexShader; + usesWholeTexture = false; // Impossible to tell. + } + else + { + vertexShaderView = mImageVisualShaderFactory.GetVertexShaderSource(); + } + + if(mImpl->mCustomShader && !mImpl->mCustomShader->mFragmentShader.empty()) + { + fragmentShaderView = mImpl->mCustomShader->mFragmentShader; + } + else + { + fragmentShaderView = mImageVisualShaderFactory.GetFragmentShaderSource(); + } + + // If the texture is native, we may need to change prefix and sampler in + // the fragment shader + if(useNativeImage) + { + bool modifiedFragmentShader = false; + Texture nativeTexture = mTextures.GetTexture(0); + std::string fragmentShaderString = std::string(fragmentShaderView); + + modifiedFragmentShader = DevelTexture::ApplyNativeFragmentShader(nativeTexture, fragmentShaderString); + if(modifiedFragmentShader) + { + fragmentShaderView = fragmentShaderString; + } + + // Create shader here cause fragmentShaderString scope issue + shader = Shader::New(vertexShaderView, fragmentShaderView, mImpl->mCustomShader->mHints); + } + else + { + shader = Shader::New(vertexShaderView, fragmentShaderView, mImpl->mCustomShader->mHints); + } } if(usesWholeTexture) @@ -1000,6 +1156,29 @@ Shader ImageVisual::GetShader() 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