From e0c063be9e7ecde0e5665079289489d456828abf Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Wed, 3 Nov 2021 22:02:00 +0900 Subject: [PATCH] Refactoring ImageVisualShaderFactory::GetShader There are two Intention this patch 1. Clean up GetShader params 2. Allow that native image also use visual features (a.k.a. RoundedCorner + Borderline) Change-Id: I8b0cbd0a4c7c622268c90d3cbbbd345ae83dfa07 Signed-off-by: Eunki, Hong --- .../src/dali-toolkit/utc-Dali-ImageVisual.cpp | 66 ++++++++++- .../animated-image/animated-image-visual.cpp | 9 +- .../animated-vector-image-visual.cpp | 7 +- .../visuals/image-visual-shader-factory.cpp | 123 +++++++++++++++++++-- .../internal/visuals/image-visual-shader-factory.h | 107 +++++++++++++++--- .../internal/visuals/image/image-visual.cpp | 95 +++++++++------- .../internal/visuals/npatch/npatch-visual.cpp | 5 +- dali-toolkit/internal/visuals/svg/svg-visual.cpp | 8 +- .../internal/visuals/visual-factory-cache.h | 8 +- 9 files changed, 336 insertions(+), 92 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp index cd834df..51b9923 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp @@ -422,7 +422,6 @@ int UtcDaliImageVisualRemoteImageLoad(void) END_TEST; } - int UtcDaliImageVisualWithNativeImage(void) { ToolkitTestApplication application; @@ -468,6 +467,71 @@ int UtcDaliImageVisualWithNativeImage(void) END_TEST; } +int UtcDaliImageVisualWithNativeImageCustomShader(void) +{ + ToolkitTestApplication application; + tet_infoline( "Use Native Image as url and Use custom shader" ); + + NativeImageSourcePtr nativeImageSource = NativeImageSource::New(500, 500, NativeImageSource::COLOR_DEPTH_DEFAULT); + ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(nativeImageSource); + std::string url = imageUrl.GetUrl(); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK( factory ); + + Property::Map propertyMap; + Property::Map shaderMap; + const std::string customVertexShaderSource = "Foobar"; + const std::string customFragmentShaderSource = "Foobar"; + shaderMap[Toolkit::Visual::Shader::Property::FRAGMENT_SHADER] = customFragmentShaderSource; + shaderMap[Toolkit::Visual::Shader::Property::VERTEX_SHADER] = customVertexShaderSource; + + propertyMap.Insert( Toolkit::Visual::Property::TYPE, Visual::IMAGE ); + propertyMap.Insert( Toolkit::Visual::Property::SHADER, shaderMap ); + propertyMap.Insert( ImageVisual::Property::URL, url ); + + Visual::Base visual = factory.CreateVisual( propertyMap ); + DALI_TEST_CHECK( visual ); + + 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 ) ); + actor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER ); + + DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION ); + + application.GetScene().Add( actor ); + + DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION ); + + application.SendNotification(); + application.Render(16); + + Renderer renderer = actor.GetRendererAt(0); + Shader shader = renderer.GetShader(); + + Property::Value value = shader.GetProperty(Shader::Property::PROGRAM); + DALI_TEST_CHECK(value.GetType() == Property::MAP); + const Property::Map* outMap = value.GetMap(); + std::string fragmentShaderSource = (*outMap)["fragment"].Get(); + std::string vertexShaderSource = (*outMap)["vertex"].Get(); + + // Compare vertex shader is equal + DALI_TEST_EQUALS( customVertexShaderSource, vertexShaderSource, TEST_LOCATION ); + + // Check fragment shader changed + const char* fragmentPrefix = Dali::NativeImageSourceTest::GetCustomFragmentPrefix(); + size_t pos = fragmentShaderSource.find(fragmentPrefix); + + DALI_TEST_EQUALS( pos != std::string::npos, true, TEST_LOCATION ); + + DALI_TEST_EQUALS( std::string(fragmentPrefix) + customFragmentShaderSource, fragmentShaderSource, TEST_LOCATION ); + + END_TEST; +} + int UtcDaliImageVisualWithNativeImageRemoved(void) { ToolkitTestApplication application; 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 d8d61d3..da7fb09 100644 --- a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp @@ -833,10 +833,11 @@ Shader AnimatedImageVisual::GenerateShader() const Shader shader; shader = mImageVisualShaderFactory.GetShader( mFactoryCache, - TextureAtlas::DISABLED, - defaultWrapMode ? DefaultTextureWrapMode::APPLY : DefaultTextureWrapMode::DO_NOT_APPLY, - IsRoundedCornerRequired() ? RoundedCorner::ENABLED : RoundedCorner::DISABLED, - IsBorderlineRequired() ? Borderline::ENABLED : Borderline::DISABLED); + ImageVisualShaderFeature::FeatureBuilder() + .ApplyDefaultTextureWrapMode(defaultWrapMode) + .EnableRoundedCorner(IsRoundedCornerRequired()) + .EnableBorderline(IsBorderlineRequired()) + ); return shader; } diff --git a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp index 26495bf..75b71f2 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp @@ -626,10 +626,9 @@ Shader AnimatedVectorImageVisual::GenerateShader() const { shader = mImageVisualShaderFactory.GetShader( mFactoryCache, - TextureAtlas::DISABLED, - DefaultTextureWrapMode::APPLY, - IsRoundedCornerRequired() ? RoundedCorner::ENABLED : RoundedCorner::DISABLED, - IsBorderlineRequired() ? Borderline::ENABLED : Borderline::DISABLED + ImageVisualShaderFeature::FeatureBuilder() + .EnableRoundedCorner(IsRoundedCornerRequired()) + .EnableBorderline(IsBorderlineRequired()) ); } return shader; diff --git a/dali-toolkit/internal/visuals/image-visual-shader-factory.cpp b/dali-toolkit/internal/visuals/image-visual-shader-factory.cpp index 7f2cac7..f5753fa 100644 --- a/dali-toolkit/internal/visuals/image-visual-shader-factory.cpp +++ b/dali-toolkit/internal/visuals/image-visual-shader-factory.cpp @@ -18,6 +18,7 @@ #include // EXTERNAL INCLUDES +#include // INTERNAL INCLUDES #include @@ -40,9 +41,41 @@ static std::string gVertexShader; // global string variable to caching complate fragment shader (no atlas) static std::string gFragmentShaderNoAtlas; +const int NATIVE_SHADER_TYPE_OFFSET = VisualFactoryCache::ShaderType::NATIVE_IMAGE_SHADER - VisualFactoryCache::ShaderType::IMAGE_SHADER; + } // unnamed namespace +namespace ImageVisualShaderFeature +{ +FeatureBuilder& FeatureBuilder::EnableTextureAtlas(bool enableAtlas) +{ + mTextureAtlas = (enableAtlas ? TextureAtlas::ENABLED : TextureAtlas::DISABLED); + return *this; +} +FeatureBuilder& FeatureBuilder::ApplyDefaultTextureWrapMode(bool applyDefaultTextureWrapMode) +{ + mDefaultTextureWrapMode = (applyDefaultTextureWrapMode ? DefaultTextureWrapMode::APPLY : DefaultTextureWrapMode::DO_NOT_APPLY); + return *this; +} +FeatureBuilder& FeatureBuilder::EnableRoundedCorner(bool enableRoundedCorner) +{ + mRoundedCorner = (enableRoundedCorner ? RoundedCorner::ENABLED : RoundedCorner::DISABLED); + return *this; +} +FeatureBuilder& FeatureBuilder::EnableBorderline(bool enableBorderline) +{ + mBorderline = (enableBorderline ? Borderline::ENABLED : Borderline::DISABLED); + return *this; +} +FeatureBuilder& FeatureBuilder::SetTextureForFragmentShaderCheck(const Dali::Texture& texture) +{ + mTexture = texture; + return *this; +} +} // namespace ImageVisualShaderFeature + ImageVisualShaderFactory::ImageVisualShaderFactory() +: mFragmentShaderNeedChange(ImageVisualShaderFeature::ChangeFragmentShader::UNDECIDED) { } @@ -50,13 +83,22 @@ ImageVisualShaderFactory::~ImageVisualShaderFactory() { } -Shader ImageVisualShaderFactory::GetShader(VisualFactoryCache& factoryCache, TextureAtlas atlasing, DefaultTextureWrapMode defaultTextureWrapping, RoundedCorner roundedCorner, Borderline borderline) +Shader ImageVisualShaderFactory::GetShader(VisualFactoryCache& factoryCache, const ImageVisualShaderFeature::FeatureBuilder& featureBuilder) { Shader shader; VisualFactoryCache::ShaderType shaderType = VisualFactoryCache::IMAGE_SHADER; - if(atlasing == TextureAtlas::ENABLED) + + const auto& atlasing = featureBuilder.mTextureAtlas; + const auto& defaultTextureWrapping = featureBuilder.mDefaultTextureWrapMode; + const auto& roundedCorner = featureBuilder.mRoundedCorner; + const auto& borderline = featureBuilder.mBorderline; + const auto& changeFragmentShader = (featureBuilder.mTexture && DevelTexture::IsNative(featureBuilder.mTexture)) + ? ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE + : ImageVisualShaderFeature::ChangeFragmentShader::DONT_CHANGE; + + if(atlasing == ImageVisualShaderFeature::TextureAtlas::ENABLED) { - if(defaultTextureWrapping == DefaultTextureWrapMode::APPLY) + if(defaultTextureWrapping == ImageVisualShaderFeature::DefaultTextureWrapMode::APPLY) { shaderType = VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP; } @@ -67,9 +109,9 @@ Shader ImageVisualShaderFactory::GetShader(VisualFactoryCache& factoryCache, Tex } else { - if(roundedCorner == RoundedCorner::ENABLED) + if(roundedCorner == ImageVisualShaderFeature::RoundedCorner::ENABLED) { - if(borderline == Borderline::ENABLED) + if(borderline == ImageVisualShaderFeature::Borderline::ENABLED) { shaderType = VisualFactoryCache::IMAGE_SHADER_ROUNDED_BORDERLINE; } @@ -80,21 +122,28 @@ Shader ImageVisualShaderFactory::GetShader(VisualFactoryCache& factoryCache, Tex } else { - if(borderline == Borderline::ENABLED) + if(borderline == ImageVisualShaderFeature::Borderline::ENABLED) { shaderType = VisualFactoryCache::IMAGE_SHADER_BORDERLINE; } } } + if(changeFragmentShader == ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE && + (mFragmentShaderNeedChange == ImageVisualShaderFeature::ChangeFragmentShader::UNDECIDED || + mFragmentShaderNeedChange == ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE)) + { + shaderType = static_cast(static_cast(shaderType) + NATIVE_SHADER_TYPE_OFFSET); + } + shader = factoryCache.GetShader(shaderType); if(!shader) { std::string vertexShaderPrefixList; std::string fragmentShaderPrefixList; - if(atlasing == TextureAtlas::ENABLED) + if(atlasing == ImageVisualShaderFeature::TextureAtlas::ENABLED) { - if(defaultTextureWrapping == DefaultTextureWrapMode::APPLY) + if(defaultTextureWrapping == ImageVisualShaderFeature::DefaultTextureWrapMode::APPLY) { fragmentShaderPrefixList += "#define ATLAS_DEFAULT_WARP 1\n"; } @@ -105,20 +154,70 @@ Shader ImageVisualShaderFactory::GetShader(VisualFactoryCache& factoryCache, Tex } else { - if(roundedCorner == RoundedCorner::ENABLED) + if(roundedCorner == ImageVisualShaderFeature::RoundedCorner::ENABLED) { vertexShaderPrefixList += "#define IS_REQUIRED_ROUNDED_CORNER 1\n"; fragmentShaderPrefixList += "#define IS_REQUIRED_ROUNDED_CORNER 1\n"; } - if(borderline == Borderline::ENABLED) + if(borderline == ImageVisualShaderFeature::Borderline::ENABLED) { vertexShaderPrefixList += "#define IS_REQUIRED_BORDERLINE 1\n"; fragmentShaderPrefixList += "#define IS_REQUIRED_BORDERLINE 1\n"; } } - shader = Shader::New(Dali::Shader::GetVertexShaderPrefix() + vertexShaderPrefixList + SHADER_IMAGE_VISUAL_SHADER_VERT.data(), - Dali::Shader::GetFragmentShaderPrefix() + fragmentShaderPrefixList + SHADER_IMAGE_VISUAL_SHADER_FRAG.data()); + std::string vertexShader = std::string(Dali::Shader::GetVertexShaderPrefix() + vertexShaderPrefixList + SHADER_IMAGE_VISUAL_SHADER_VERT.data()); + std::string fragmentShader = std::string(Dali::Shader::GetFragmentShaderPrefix() + fragmentShaderPrefixList + SHADER_IMAGE_VISUAL_SHADER_FRAG.data()); + + if(changeFragmentShader == ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE) + { + if(DALI_UNLIKELY(mFragmentShaderNeedChange == ImageVisualShaderFeature::ChangeFragmentShader::UNDECIDED)) + { + // NOTE : This routine will run exist one times. + // + // First, we will run ApplyNativeFragmentShader + // - If fragment shader is modified, then current platform allow to change fragment shader. + // We cache this result mFragmentShaderNeedChange = ChangeFragmentShader::NEED_CHANGE. + // - If fragment shader is not modified, then current platform will always don't change fragment shader. + // We cache this result mFragmentShaderNeedChange = ChangeFragmentShader::DONT_CHANGE. + // And change current shaderType into normal image range. + // After cached the result, shaderType never become NATIVE_IMAGE_SHADER anymore. + // Second, save shader result. + + // Try to apply fragmentShader + bool modified = DevelTexture::ApplyNativeFragmentShader(featureBuilder.mTexture, fragmentShader); + if(modified) + { + // Now we know that fragment shader need to change. + mFragmentShaderNeedChange = ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE; + } + else + { + // Now we know that fragment shader even don't need to change. + // We can skip ApplyNativeFragmentShader routine after now. + mFragmentShaderNeedChange = ImageVisualShaderFeature::ChangeFragmentShader::DONT_CHANGE; + + // Now we need normal shader type + // So decrease NATIVE_SHADER_TYPE_OFFSET. + shaderType = static_cast(static_cast(shaderType) - NATIVE_SHADER_TYPE_OFFSET); + + // If we already compiled this type already, just use that cached shader. + // Else, just go forward. + shader = factoryCache.GetShader(shaderType); + if(shader) + { + return shader; + } + } + } + else if(mFragmentShaderNeedChange == ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE) + { + // Always need to apply fragmentShader + bool modified = DevelTexture::ApplyNativeFragmentShader(featureBuilder.mTexture, fragmentShader); + DALI_ASSERT_ALWAYS(modified && "NativeImageTexture need to change fragment shader. But DALI default image shader doesn't changed!"); + } + } + shader = Shader::New(vertexShader, fragmentShader); shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT); factoryCache.SaveShader(shaderType, shader); } diff --git a/dali-toolkit/internal/visuals/image-visual-shader-factory.h b/dali-toolkit/internal/visuals/image-visual-shader-factory.h index 604b49b..1459614 100644 --- a/dali-toolkit/internal/visuals/image-visual-shader-factory.h +++ b/dali-toolkit/internal/visuals/image-visual-shader-factory.h @@ -29,41 +29,101 @@ namespace Toolkit { namespace Internal { + +/** + * ImageVisualShaderFeature contains feature lists what image visual shader need to know. + */ +namespace ImageVisualShaderFeature +{ +namespace TextureAtlas +{ /** * @brief Whether use texture with atlas, or not */ -enum class TextureAtlas +enum Type { - DISABLED = 0, ///< Image visual use ATLAS - ENABLED ///< Image visual doesn't use ATLAS + DISABLED = 0, ///< Image visual doesn't use ATLAS + ENABLED ///< Image visual uses ATLAS }; +} // namespace TextureAtlas +namespace DefaultTextureWrapMode +{ /** * @brief Whether apply to texture wraping in default, or not */ -enum class DefaultTextureWrapMode +enum Type { - DO_NOT_APPLY = 0, ///< Image visual doesn't apply to wraping texture in default - APPLY ///< Image visual apply to wraping texture in default + APPLY = 0, ///< Image visual applies to wraping texture in default + DO_NOT_APPLY ///< Image visual doesn't apply to wraping texture in default }; +} // namespace DefaultTextureWrapMode +namespace RoundedCorner +{ /** * @brief Whether use rounded corner, or not */ -enum class RoundedCorner +enum Type { DISABLED = 0, ///< Image visual doesn't use rounded corner - ENABLED ///< Image visual use rounded corner + ENABLED ///< Image visual uses rounded corner }; +} // namespace RoundedCorner +namespace Borderline +{ /** * @brief Whether use borderline, or not */ -enum class Borderline +enum Type { DISABLED = 0, ///< Image visual doesn't use borderline - ENABLED ///< Image visual use borderline + ENABLED ///< Image visual uses borderline }; +} // namespace Borderline + +namespace ChangeFragmentShader +{ +/** + * @brief Whether native image change the default fragment shader, or not + */ +enum Type +{ + DONT_CHANGE = 0, ///< Native image doesn't change default fragment shader. + NEED_CHANGE, ///< Native image changes default fragment shader. We need another shader cache. + UNDECIDED, ///< Undecided. +}; +} // namespace ChangeFragmentShader + +/** + * @brief Collection of current image visual feature. Only use for ImageVisualShaderFactory::GetShader() + */ +struct FeatureBuilder +{ + FeatureBuilder() + : mTextureAtlas(TextureAtlas::DISABLED), + mDefaultTextureWrapMode(DefaultTextureWrapMode::APPLY), + mRoundedCorner(RoundedCorner::DISABLED), + mBorderline(Borderline::DISABLED), + mTexture() + { + } + + FeatureBuilder& EnableTextureAtlas(bool enableTextureAtlas); + FeatureBuilder& ApplyDefaultTextureWrapMode(bool applyDefaultTextureWrapMode); + FeatureBuilder& EnableRoundedCorner(bool enableRoundedCorner); + FeatureBuilder& EnableBorderline(bool enableBorderline); + FeatureBuilder& SetTextureForFragmentShaderCheck(const Dali::Texture& texture); + + TextureAtlas::Type mTextureAtlas : 2; ///< Whether use texture with atlas, or not. default as TextureAtlas::DISABLED + DefaultTextureWrapMode::Type mDefaultTextureWrapMode : 2; ///< Whether apply to texture wraping in default, or not. default as DefaultTextureWrapMode::APPLY + RoundedCorner::Type mRoundedCorner : 2; ///< Whether use rounded corner, or not. default as RoundedCorner::DISABLED + Borderline::Type mBorderline : 2; ///< Whether use borderline, or not. default as Borderline::DISABLED + Dali::Texture mTexture; ///< Texture to check whether we need to change fragment shader or not +}; + +} // namespace ImageVisualShaderFactoryFeature /** * ImageVisualShaderFactory is an object that provides and shares shaders between image visuals @@ -83,23 +143,21 @@ public: ~ImageVisualShaderFactory(); /** - * Get the standard image rendering shader. + * @brief Get the standard image rendering shader. * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object - * @param[in] atlasing Whether texture atlasing is applied. - * @param[in] defaultTextureWrapping Whether the default texture wrap mode is applied. - * @param[in] roundedCorner Whether the rounded corder is applied. - * @param[in] borderline Whether the borderline of visual is applied. + * @param[in] featureBuilder Collection of current image shader's features + * @return The standard image rendering shader with features. */ - Shader GetShader(VisualFactoryCache& factoryCache, TextureAtlas atlasing, DefaultTextureWrapMode defaultTextureWrapping, RoundedCorner roundedCorner, Borderline borderline); + Shader GetShader(VisualFactoryCache& factoryCache, const ImageVisualShaderFeature::FeatureBuilder& featureBuilder); /** - * Request the default vertex shader source. + * @brief Request the default vertex shader source. * @return The default vertex shader source. */ std::string_view GetVertexShaderSource(); /** - * Request the default fragment shader source. + * @brief Request the default fragment shader source. * @return The default fragment shader source. */ std::string_view GetFragmentShaderSource(); @@ -116,6 +174,19 @@ protected: ImageVisualShaderFactory& operator=(const ImageVisualShaderFactory& rhs); private: + + /** + * @brief Cached information whether native image should change fragment shader. + * Default it is ChangeFragmentShader::UNDECIDED. + * If we have any chance to check native image source apply fragment shader, + * this vaule will be changed one of these : ChangeFragmentShader::DONT_CHANGE or ChangeFragmentShader::NEED_CHANGE + * + * After result cached, this value will not be changed. + * + * If value is DONT_CHANGE, ImageVisualShaderFactory::GetShader never call ApplyNativeFragmentShader. + * Else, ImageVisualShaderFactory::GetShader will call ApplyNativeFragmentShader if native image source texture come. + */ + ImageVisualShaderFeature::ChangeFragmentShader::Type mFragmentShaderNeedChange : 3; }; } // namespace Internal diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index 7e404ca..650c508 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual.cpp @@ -974,59 +974,68 @@ Shader ImageVisual::GenerateShader() const { 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 - { - vertexShaderView = mImageVisualShaderFactory.GetVertexShaderSource(); - } + bool usesWholeTexture = true; + const bool useStandardShader = !mImpl->mCustomShader; + const bool useNativeImage = (mTextures && DevelTexture::IsNative(mTextures.GetTexture(0))); - std::string_view fragmentShaderView; - 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 - 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; - } - - const bool useStandardShader = !mImpl->mCustomShader && !modifiedFragmentShader; if(useStandardShader) { // Create and cache the standard shader shader = mImageVisualShaderFactory.GetShader( mFactoryCache, - mImpl->mFlags & Impl::IS_ATLASING_APPLIED ? TextureAtlas::ENABLED : TextureAtlas::DISABLED, - mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE ? DefaultTextureWrapMode::APPLY : DefaultTextureWrapMode::DO_NOT_APPLY, - IsRoundedCornerRequired() ? RoundedCorner::ENABLED : RoundedCorner::DISABLED, - IsBorderlineRequired() ? Borderline::ENABLED : Borderline::DISABLED + 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()) ); } - else if(mImpl->mCustomShader) - { - shader = Shader::New(vertexShaderView, fragmentShaderView, mImpl->mCustomShader->mHints); - } 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) diff --git a/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp b/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp index e87e244..1f48eca 100644 --- a/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp +++ b/dali-toolkit/internal/visuals/npatch/npatch-visual.cpp @@ -378,10 +378,7 @@ void NPatchVisual::OnInitialize() Geometry geometry = mFactoryCache.GetGeometry(VisualFactoryCache::QUAD_GEOMETRY); Shader shader = mImageVisualShaderFactory.GetShader( mFactoryCache, - TextureAtlas::DISABLED, - DefaultTextureWrapMode::APPLY, - RoundedCorner::DISABLED, - Borderline::DISABLED + ImageVisualShaderFeature::FeatureBuilder() ); mImpl->mRenderer = Renderer::New(geometry, shader); diff --git a/dali-toolkit/internal/visuals/svg/svg-visual.cpp b/dali-toolkit/internal/visuals/svg/svg-visual.cpp index 5d1fff1..25e84fd 100644 --- a/dali-toolkit/internal/visuals/svg/svg-visual.cpp +++ b/dali-toolkit/internal/visuals/svg/svg-visual.cpp @@ -378,10 +378,10 @@ Shader SvgVisual::GenerateShader() const { shader = mImageVisualShaderFactory.GetShader( mFactoryCache, - mAttemptAtlasing ? TextureAtlas::ENABLED : TextureAtlas::DISABLED, - DefaultTextureWrapMode::APPLY, - IsRoundedCornerRequired() ? RoundedCorner::ENABLED : RoundedCorner::DISABLED, - IsBorderlineRequired() ? Borderline::ENABLED : Borderline::DISABLED + ImageVisualShaderFeature::FeatureBuilder() + .EnableTextureAtlas(mAttemptAtlasing) + .EnableRoundedCorner(IsRoundedCornerRequired()) + .EnableBorderline(IsBorderlineRequired()) ); } else diff --git a/dali-toolkit/internal/visuals/visual-factory-cache.h b/dali-toolkit/internal/visuals/visual-factory-cache.h index b23c010..deae0b0 100644 --- a/dali-toolkit/internal/visuals/visual-factory-cache.h +++ b/dali-toolkit/internal/visuals/visual-factory-cache.h @@ -81,11 +81,15 @@ public: GRADIENT_SHADER_RADIAL_USER_SPACE_BORDERLINE, GRADIENT_SHADER_RADIAL_USER_SPACE_ROUNDED_BORDERLINE, IMAGE_SHADER, - IMAGE_SHADER_ATLAS_DEFAULT_WRAP, - IMAGE_SHADER_ATLAS_CUSTOM_WRAP, IMAGE_SHADER_ROUNDED_CORNER, IMAGE_SHADER_BORDERLINE, IMAGE_SHADER_ROUNDED_BORDERLINE, + IMAGE_SHADER_ATLAS_DEFAULT_WRAP, + IMAGE_SHADER_ATLAS_CUSTOM_WRAP, + NATIVE_IMAGE_SHADER, + NATIVE_IMAGE_SHADER_ROUNDED_CORNER, + NATIVE_IMAGE_SHADER_BORDERLINE, + NATIVE_IMAGE_SHADER_ROUNDED_BORDERLINE, NINE_PATCH_SHADER, NINE_PATCH_MASK_SHADER, TEXT_SHADER_MULTI_COLOR_TEXT, -- 2.7.4