END_TEST;
}
-
int UtcDaliImageVisualWithNativeImage(void)
{
ToolkitTestApplication application;
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<DummyControlImpl&>(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>();
+ std::string vertexShaderSource = (*outMap)["vertex"].Get<std::string>();
+
+ // 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;
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;
}
{
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;
#include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
// EXTERNAL INCLUDES
+#include <dali/devel-api/rendering/texture-devel.h>
// INTERNAL INCLUDES
#include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
// 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)
{
}
{
}
-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;
}
}
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;
}
}
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<VisualFactoryCache::ShaderType>(static_cast<int>(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";
}
}
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<VisualFactoryCache::ShaderType>(static_cast<int>(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);
}
{
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
~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();
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
{
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)
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);
{
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
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,