Previously, DevelRenderer always merged into uColor.a value.
This situation usally have no problem.
But when we want to use both MIX_COLOR and BORDERLINE_COLOR
there was no way to split Actor's opacity and MIX_COLOR's opacity.
So BORDERLINE_COLOR.a is always pre-multiplired by MIX_COLOR.a.
And also, when MIX_COLOR.a is zero, There is no way to render BORDERLINE only.
This patch try to fix this issue.
First, Add logic to keep-rendering logic. (BlendMode::ON_WITHOUT_CULL)
Second, Turn on that flag only if borderline required.
Third, Modify shader s.t. use default uniform : uActorColor.
Change-Id: I033fa6accebe5ae59aedc1e0b68ee4b8d0df7098
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
{"sTextureRect", GL_SAMPLER_2D, 1},
{"sGloss", GL_SAMPLER_2D, 1},
{"uColor", GL_FLOAT_VEC4, 1},
+ {"uActorColor", GL_FLOAT_VEC4, 1},
{"uModelMatrix", GL_FLOAT_MAT4, 1},
{"uModelView", GL_FLOAT_MAT4, 1},
{"uMvpMatrix", GL_FLOAT_MAT4, 1},
UniformData("sTextureRect", Property::Type::FLOAT),
UniformData("sGloss", Property::Type::FLOAT),
UniformData("uColor", Property::Type::VECTOR4),
+ UniformData("uActorColor", Property::Type::VECTOR4),
UniformData("uModelMatrix", Property::Type::MATRIX),
UniformData("uModelView", Property::Type::MATRIX),
UniformData("uMvpMatrix", Property::Type::MATRIX),
uniform mediump float borderlineWidth;
uniform mediump float borderlineOffset;
uniform lowp vec4 borderlineColor;
+uniform lowp vec4 uActorColor;
#endif
#if IS_REQUIRED_BLUR
uniform mediump float blurRadius;
borderlineOpacity = smoothstep(gMinInlinePotential, gMaxInlinePotential, potential);
}
+ lowp vec3 BorderlineColorRGB = borderlineColor.rgb * uActorColor.rgb;
+ lowp float BorderlineColorAlpha = borderlineColor.a * uActorColor.a;
+
//calculate inside of borderline when outilneColor.a < 1.0
if(borderlineColor.a < 1.0)
{
if(potential > MaxTexturelinePotential)
{
// potential is out of texture range. use borderline color instead of texture
- textureColor = vec4(borderlineColor.xyz, 0.0);
+ textureColor = vec4(BorderlineColorRGB, 0.0);
}
else if(potential > MinTexturelinePotential)
{
// potential is in texture range
- textureColor = mix(textureColor, vec4(borderlineColor.xyz, 0.0), smoothstep(MinTexturelinePotential, MaxTexturelinePotential, potential));
+ textureColor = mix(textureColor, vec4(BorderlineColorRGB, 0.0), smoothstep(MinTexturelinePotential, MaxTexturelinePotential, potential));
}
+ // TODO : need to fix here when uColor.a = 0.0 and uActorColor.a != 0
borderlineOpacity *= borderlineColor.a;
- return mix(textureColor, vec4(borderlineColor.xyz, 1.0), borderlineOpacity);
+ return mix(textureColor, vec4(BorderlineColorRGB, 1.0), borderlineOpacity);
}
- return mix(textureColor, borderlineColor, borderlineOpacity);
+ return mix(textureColor, vec4(BorderlineColorRGB, BorderlineColorAlpha), borderlineOpacity);
}
#endif
void main()
{
- lowp vec4 targetColor = vec4(mixColor, 1.0);
+ lowp vec4 targetColor = vec4(mixColor, 1.0) * uColor;
#if IS_REQUIRED_BLUR || IS_REQUIRED_ROUNDED_CORNER || IS_REQUIRED_BORDERLINE
// skip most potential calculate for performance
if(abs(vPosition.x) < vOptRectSize.x && abs(vPosition.y) < vOptRectSize.y)
{
- OUT_COLOR = targetColor * uColor;
+ OUT_COLOR = targetColor;
return;
}
PreprocessPotential();
#if !IS_REQUIRED_BLUR && IS_REQUIRED_BORDERLINE
targetColor = convertBorderlineColor(targetColor);
#endif
- OUT_COLOR = targetColor * uColor;
+ OUT_COLOR = targetColor;
#if IS_REQUIRED_BLUR
mediump float opacity = calculateBlurOpacity();
uniform mediump float borderlineWidth;
uniform mediump float borderlineOffset;
uniform lowp vec4 borderlineColor;
+uniform lowp vec4 uActorColor;
#endif
#if IS_REQUIRED_ROUNDED_CORNER || IS_REQUIRED_BORDERLINE
borderlineOpacity = smoothstep(gMinInlinePotential, gMaxInlinePotential, potential);
}
+ lowp vec3 BorderlineColorRGB = borderlineColor.rgb * uActorColor.rgb;
+ lowp float BorderlineColorAlpha = borderlineColor.a * uActorColor.a;
+ // Gradient is always preMultiplied.
+ BorderlineColorRGB *= BorderlineColorAlpha;
+
//calculate inside of borderline when outilneColor.a < 1.0
if(borderlineColor.a < 1.0)
{
// potential is in texture range
textureColor = mix(textureColor, vec4(BorderlineColorRGB, 0.0), smoothstep(MinTexturelinePotential, MaxTexturelinePotential, potential));
}
+ // TODO : need to fix here when uColor.a = 0.0 and uActorColor.a != 0
borderlineOpacity *= borderlineColor.a;
return mix(textureColor, vec4(BorderlineColorRGB, 1.0), borderlineOpacity);
}
- return mix(textureColor, borderlineColor, borderlineOpacity);
+ return mix(textureColor, vec4(BorderlineColorRGB, BorderlineColorAlpha), borderlineOpacity);
}
#endif
void main()
{
#if RADIAL
- lowp vec4 textureColor = TEXTURE(sTexture, vec2(length(vTexCoord), 0.5)) * vec4(mixColor, 1.0);
+ lowp vec4 textureColor = TEXTURE(sTexture, vec2(length(vTexCoord), 0.5)) * vec4(mixColor, 1.0) * uColor;
#else
- lowp vec4 textureColor = TEXTURE(sTexture, vec2(vTexCoord.y, 0.5)) * vec4(mixColor, 1.0);
+ lowp vec4 textureColor = TEXTURE(sTexture, vec2(vTexCoord.y, 0.5)) * vec4(mixColor, 1.0) * uColor;
#endif
#if IS_REQUIRED_ROUNDED_CORNER || IS_REQUIRED_BORDERLINE
// skip most potential calculate for performance
if(abs(vPosition.x) < vOptRectSize.x && abs(vPosition.y) < vOptRectSize.y)
{
- OUT_COLOR = textureColor * uColor;
+ OUT_COLOR = textureColor;
return;
}
PreprocessPotential();
#if IS_REQUIRED_BORDERLINE
textureColor = convertBorderlineColor(textureColor);
#endif
- OUT_COLOR = textureColor * uColor;
+ OUT_COLOR = textureColor;
#if IS_REQUIRED_ROUNDED_CORNER
mediump float opacity = calculateCornerOpacity();
uniform mediump float borderlineWidth;
uniform mediump float borderlineOffset;
uniform lowp vec4 borderlineColor;
+uniform lowp vec4 uActorColor;
#endif
#if ATLAS_CUSTOM_WARP
borderlineOpacity = smoothstep(gMinInlinePotential, gMaxInlinePotential, potential);
}
+ lowp vec3 BorderlineColorRGB = borderlineColor.rgb * uActorColor.rgb;
+ lowp float BorderlineColorAlpha = borderlineColor.a * uActorColor.a;
+ BorderlineColorRGB *= mix(1.0, BorderlineColorAlpha, preMultipliedAlpha);
+
//calculate inside of borderline when outilneColor.a < 1.0
if(borderlineColor.a < 1.0)
{
mediump float tCornerRadius = -gCenterPosition;
mediump float MaxTexturelinePotential = tCornerRadius + gPotentialRange;
mediump float MinTexturelinePotential = tCornerRadius - gPotentialRange;
- lowp vec3 BorderlineColorRGB = borderlineColor.xyz;
- BorderlineColorRGB *= mix(1.0, borderlineColor.a, preMultipliedAlpha);
if(potential > MaxTexturelinePotential)
{
// potential is out of texture range. use borderline color instead of texture
// potential is in texture range
textureColor = mix(textureColor, vec4(BorderlineColorRGB, 0.0), smoothstep(MinTexturelinePotential, MaxTexturelinePotential, potential));
}
+ // TODO : need to fix here when uColor.a = 0.0 and uActorColor.a != 0
borderlineOpacity *= borderlineColor.a;
return mix(textureColor, vec4(BorderlineColorRGB, 1.0), borderlineOpacity);
}
- return mix(textureColor, borderlineColor, borderlineOpacity);
+ return mix(textureColor, vec4(BorderlineColorRGB, BorderlineColorAlpha), borderlineOpacity);
}
#endif
mediump vec2 texCoord = vTexCoord;
#endif
- lowp vec4 textureColor = TEXTURE( sTexture, texCoord ) * vec4( mixColor, 1.0 );
+ lowp vec4 textureColor = TEXTURE( sTexture, texCoord ) * vec4( mixColor, 1.0 ) * uColor;
#if IS_REQUIRED_ROUNDED_CORNER || IS_REQUIRED_BORDERLINE
// skip most potential calculate for performance
if(abs(vPosition.x) < vOptRectSize.x && abs(vPosition.y) < vOptRectSize.y)
{
- OUT_COLOR = textureColor * uColor;
+ OUT_COLOR = textureColor;
return;
}
PreprocessPotential();
#if IS_REQUIRED_BORDERLINE
textureColor = convertBorderlineColor(textureColor);
#endif
- OUT_COLOR = textureColor * uColor;
+ OUT_COLOR = textureColor;
#if IS_REQUIRED_ROUNDED_CORNER
mediump float opacity = calculateCornerOpacity();
DALI_ENUM_TO_STRING_WITH_SCOPE(Visual::FittingMode, FIT_HEIGHT)
DALI_ENUM_TO_STRING_TABLE_END(VISUAL_FITTING_MODE)
+/**
+ * @brief Check whether this visual type can use corner radius feature or not.
+ * @param type VisualType that want to checkup
+ * @return true if type can use corner radius feature.
+ */
+static bool IsTypeAvailableForCornerRadius(Toolkit::Visual::Type type)
+{
+ switch(static_cast<Toolkit::DevelVisual::Type>(type))
+ {
+ case Toolkit::Visual::Type::COLOR:
+ case Toolkit::Visual::Type::GRADIENT:
+ case Toolkit::Visual::Type::IMAGE:
+ case Toolkit::Visual::Type::SVG:
+ case Toolkit::Visual::Type::ANIMATED_IMAGE:
+ case Toolkit::DevelVisual::Type::ANIMATED_VECTOR_IMAGE:
+ {
+ return true;
+ }
+ default:
+ {
+ return false;
+ }
+ }
+}
+
+/**
+ * @brief Check whether this visual type can use borderline feature or not.
+ * @param type VisualType that want to checkup
+ * @return true if type can use borderline feature.
+ */
+static bool IsTypeAvailableForBorderline(Toolkit::Visual::Type type)
+{
+ switch(static_cast<Toolkit::DevelVisual::Type>(type))
+ {
+ case Toolkit::Visual::Type::COLOR:
+ case Toolkit::Visual::Type::GRADIENT:
+ case Toolkit::Visual::Type::IMAGE:
+ case Toolkit::Visual::Type::SVG:
+ case Toolkit::Visual::Type::ANIMATED_IMAGE:
+ case Toolkit::DevelVisual::Type::ANIMATED_VECTOR_IMAGE:
+ {
+ return true;
+ }
+ default:
+ {
+ return false;
+ }
+ }
+}
+
} // namespace
Visual::Base::Base(VisualFactoryCache& factoryCache, FittingMode fittingMode, Toolkit::Visual::Type type)
mImpl->mBorderlineColorIndex = mImpl->mRenderer.RegisterProperty(DevelVisual::Property::BORDERLINE_COLOR, BORDERLINE_COLOR, mImpl->mBorderlineColor);
mImpl->mBorderlineOffsetIndex = mImpl->mRenderer.RegisterProperty(DevelVisual::Property::BORDERLINE_OFFSET, BORDERLINE_OFFSET, mImpl->mBorderlineOffset);
- mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON);
+ mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON_WITHOUT_CULL);
}
}
}
bool Visual::Base::IsRoundedCornerRequired() const
{
- if(mImpl->mRenderer && mImpl->mCornerRadiusIndex != Property::INVALID_INDEX)
+ // If VisualType doesn't support rounded corner, always return false.
+ if(IsTypeAvailableForCornerRadius(mImpl->mType))
{
- // Update values from Renderer
- mImpl->mCornerRadius = mImpl->mRenderer.GetProperty<Vector4>(mImpl->mCornerRadiusIndex);
+ if(mImpl->mRenderer && mImpl->mCornerRadiusIndex != Property::INVALID_INDEX)
+ {
+ // Update values from Renderer
+ mImpl->mCornerRadius = mImpl->mRenderer.GetProperty<Vector4>(mImpl->mCornerRadiusIndex);
+ }
+ return !(mImpl->mCornerRadius == Vector4::ZERO) || mImpl->mNeedCornerRadius;
}
- return !(mImpl->mCornerRadius == Vector4::ZERO) || mImpl->mNeedCornerRadius;
+ return false;
}
bool Visual::Base::IsBorderlineRequired() const
{
- if(mImpl->mRenderer && mImpl->mBorderlineWidthIndex != Property::INVALID_INDEX)
+ // If VisualType doesn't support borderline, always return false.
+ if(IsTypeAvailableForBorderline(mImpl->mType))
{
- // Update values from Renderer
- mImpl->mBorderlineWidth = mImpl->mRenderer.GetProperty<float>(mImpl->mBorderlineWidthIndex);
+ if(mImpl->mRenderer && mImpl->mBorderlineWidthIndex != Property::INVALID_INDEX)
+ {
+ // Update values from Renderer
+ mImpl->mBorderlineWidth = mImpl->mRenderer.GetProperty<float>(mImpl->mBorderlineWidthIndex);
+ }
+ return !EqualsZero(mImpl->mBorderlineWidth) || mImpl->mNeedBorderline;
}
- return !EqualsZero(mImpl->mBorderlineWidth) || mImpl->mNeedBorderline;
+ return false;
}
void Visual::Base::OnDoAction(const Property::Index actionId, const Property::Value& attributes)
Property::Index index = GetPropertyIndex(key);
if(index == Property::INVALID_INDEX)
{
- if((key.type == Property::Key::INDEX && key.indexKey == DevelVisual::Property::BORDERLINE_WIDTH) || (key.type == Property::Key::STRING && key.stringKey == BORDERLINE_WIDTH) ||
- (key.type == Property::Key::INDEX && key.indexKey == DevelVisual::Property::BORDERLINE_COLOR) || (key.type == Property::Key::STRING && key.stringKey == BORDERLINE_COLOR) ||
- (key.type == Property::Key::INDEX && key.indexKey == DevelVisual::Property::BORDERLINE_OFFSET) || (key.type == Property::Key::STRING && key.stringKey == BORDERLINE_OFFSET))
+ if(IsTypeAvailableForBorderline(mImpl->mType) &&
+ ((key.type == Property::Key::INDEX && key.indexKey == DevelVisual::Property::BORDERLINE_WIDTH) || (key.type == Property::Key::STRING && key.stringKey == BORDERLINE_WIDTH) ||
+ (key.type == Property::Key::INDEX && key.indexKey == DevelVisual::Property::BORDERLINE_COLOR) || (key.type == Property::Key::STRING && key.stringKey == BORDERLINE_COLOR) ||
+ (key.type == Property::Key::INDEX && key.indexKey == DevelVisual::Property::BORDERLINE_OFFSET) || (key.type == Property::Key::STRING && key.stringKey == BORDERLINE_OFFSET)))
{
- mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON);
+ mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON_WITHOUT_CULL);
// Register borderline properties
mImpl->mBorderlineWidthIndex = mImpl->mRenderer.RegisterProperty(DevelVisual::Property::BORDERLINE_WIDTH, BORDERLINE_WIDTH, mImpl->mBorderlineWidth);
// Change shader
UpdateShader();
}
- else if((key.type == Property::Key::INDEX && key.indexKey == DevelVisual::Property::CORNER_RADIUS) || (key.type == Property::Key::STRING && key.stringKey == CORNER_RADIUS))
+ else if(IsTypeAvailableForCornerRadius(mImpl->mType) && ((key.type == Property::Key::INDEX && key.indexKey == DevelVisual::Property::CORNER_RADIUS) || (key.type == Property::Key::STRING && key.stringKey == CORNER_RADIUS)))
{
// Register CORNER_RADIUS property
mImpl->mCornerRadiusIndex = mImpl->mRenderer.RegisterProperty(DevelVisual::Property::CORNER_RADIUS, CORNER_RADIUS, mImpl->mCornerRadius);
mImpl->mRenderer.RegisterProperty(CORNER_RADIUS_POLICY, mImpl->mCornerRadiusPolicy);
- mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON);
+ if(!mImpl->mNeedBorderline)
+ {
+ // If mNeedBorderline is true, BLEND_MODE is already BlendMode::ON_WITHOUT_CULL. So we don't overwrite it.
+ mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON);
+ }
index = mImpl->mCornerRadiusIndex;
mImpl->mNeedCornerRadius = true;