From c93f6281a8bafc5b7ba5f0dcdad0eb675b8e3436 Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Thu, 9 Jun 2022 22:20:36 +0900 Subject: [PATCH] Combine textvisual shader by TextShaderFactory Let TextVisual can control the shader & textures as factory. Now we don't need to create new shader file when we add more feature for text visual. Change-Id: I4615de30f39715f45678c87dd2755a8be99f861e Signed-off-by: Eunki, Hong --- dali-toolkit/internal/file.list | 1 + .../text-visual-multi-color-text-shader.frag | 11 -- ...-visual-multi-color-text-with-style-shader.frag | 16 -- .../graphics/shaders/text-visual-shader.frag | 63 ++++++++ .../graphics/shaders/text-visual-shader.vert | 4 +- .../text-visual-single-color-text-shader.frag | 13 -- ...visual-single-color-text-with-emoji-shader.frag | 21 --- ...gle-color-text-with-style-and-emoji-shader.frag | 26 ---- ...visual-single-color-text-with-style-shader.frag | 17 -- dali-toolkit/internal/text/markup-processor.cpp | 9 +- .../text/rendering/atlas/text-atlas-renderer.cpp | 11 +- .../visuals/text-visual-shader-factory.cpp | 167 ++++++++++++++++++++ .../internal/visuals/text-visual-shader-factory.h | 172 +++++++++++++++++++++ dali-toolkit/internal/visuals/text/text-visual.cpp | 126 ++++----------- dali-toolkit/internal/visuals/text/text-visual.h | 67 +++----- .../internal/visuals/visual-factory-cache.h | 10 +- .../internal/visuals/visual-factory-impl.cpp | 13 +- .../internal/visuals/visual-factory-impl.h | 9 +- 18 files changed, 504 insertions(+), 252 deletions(-) delete mode 100644 dali-toolkit/internal/graphics/shaders/text-visual-multi-color-text-shader.frag delete mode 100644 dali-toolkit/internal/graphics/shaders/text-visual-multi-color-text-with-style-shader.frag create mode 100644 dali-toolkit/internal/graphics/shaders/text-visual-shader.frag delete mode 100644 dali-toolkit/internal/graphics/shaders/text-visual-single-color-text-shader.frag delete mode 100644 dali-toolkit/internal/graphics/shaders/text-visual-single-color-text-with-emoji-shader.frag delete mode 100644 dali-toolkit/internal/graphics/shaders/text-visual-single-color-text-with-style-and-emoji-shader.frag delete mode 100644 dali-toolkit/internal/graphics/shaders/text-visual-single-color-text-with-style-shader.frag create mode 100644 dali-toolkit/internal/visuals/text-visual-shader-factory.cpp create mode 100644 dali-toolkit/internal/visuals/text-visual-shader-factory.h diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index d80bffe..6edbd75 100644 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -44,6 +44,7 @@ SET( toolkit_src_files ${toolkit_src_dir}/visuals/primitive/primitive-visual.cpp ${toolkit_src_dir}/visuals/svg/svg-rasterize-thread.cpp ${toolkit_src_dir}/visuals/svg/svg-visual.cpp + ${toolkit_src_dir}/visuals/text-visual-shader-factory.cpp ${toolkit_src_dir}/visuals/text/text-visual.cpp ${toolkit_src_dir}/visuals/transition-data-impl.cpp ${toolkit_src_dir}/visuals/image-visual-shader-factory.cpp diff --git a/dali-toolkit/internal/graphics/shaders/text-visual-multi-color-text-shader.frag b/dali-toolkit/internal/graphics/shaders/text-visual-multi-color-text-shader.frag deleted file mode 100644 index e9e1069..0000000 --- a/dali-toolkit/internal/graphics/shaders/text-visual-multi-color-text-shader.frag +++ /dev/null @@ -1,11 +0,0 @@ -varying mediump vec2 vTexCoord; -uniform sampler2D sTexture; -uniform lowp vec4 uColor; -uniform lowp vec3 mixColor; - -void main() -{ - mediump vec4 textTexture = texture2D( sTexture, vTexCoord ); - - gl_FragColor = textTexture * uColor * vec4( mixColor, 1.0 ); -} diff --git a/dali-toolkit/internal/graphics/shaders/text-visual-multi-color-text-with-style-shader.frag b/dali-toolkit/internal/graphics/shaders/text-visual-multi-color-text-with-style-shader.frag deleted file mode 100644 index ca42ca6..0000000 --- a/dali-toolkit/internal/graphics/shaders/text-visual-multi-color-text-with-style-shader.frag +++ /dev/null @@ -1,16 +0,0 @@ -varying mediump vec2 vTexCoord; -uniform sampler2D sTexture; -uniform sampler2D sStyle; -uniform sampler2D sOverlayStyle; -uniform lowp vec4 uColor; -uniform lowp vec3 mixColor; - -void main() -{ - mediump vec4 textTexture = texture2D( sTexture, vTexCoord ); - mediump vec4 styleTexture = texture2D( sStyle, vTexCoord ); - mediump vec4 overlayStyleTexture = texture2D( sOverlayStyle, vTexCoord ); - - // Draw the text as overlay above the style - gl_FragColor = ( overlayStyleTexture + textTexture * (1.0 - overlayStyleTexture.a) + styleTexture * ( 1.0 - textTexture.a ) * (1.0 - overlayStyleTexture.a) ) * uColor * vec4( mixColor, 1.0 ); -} diff --git a/dali-toolkit/internal/graphics/shaders/text-visual-shader.frag b/dali-toolkit/internal/graphics/shaders/text-visual-shader.frag new file mode 100644 index 0000000..0fc642e --- /dev/null +++ b/dali-toolkit/internal/graphics/shaders/text-visual-shader.frag @@ -0,0 +1,63 @@ +INPUT mediump vec2 vTexCoord; +uniform sampler2D sTexture; +#ifdef IS_REQUIRED_STYLE +uniform sampler2D sStyle; +#endif +#ifdef IS_REQUIRED_OVERLAY +uniform sampler2D sOverlayStyle; +#endif +#ifdef IS_REQUIRED_MULTI_COLOR +#elif defined(IS_REQUIRED_EMOJI) +// Single color with emoji. +uniform sampler2D sMask; +uniform lowp float uHasMultipleTextColors; +#endif +uniform lowp vec4 uTextColorAnimatable; +uniform lowp vec4 uColor; +uniform lowp vec3 mixColor; + +void main() +{ +#ifdef IS_REQUIRED_STYLE + mediump vec4 styleTexture = TEXTURE( sStyle, vTexCoord ); +#endif + +#ifdef IS_REQUIRED_OVERLAY + mediump vec4 overlayStyleTexture = TEXTURE( sOverlayStyle, vTexCoord ); +#endif + +#if defined(IS_REQUIRED_MULTI_COLOR) || defined(IS_REQUIRED_EMOJI) + // Multiple color or use emoji. + mediump vec4 textColor = TEXTURE(sTexture, vTexCoord); + +#ifdef IS_REQUIRED_MULTI_COLOR +#elif defined(IS_REQUIRED_EMOJI) + // Single color with emoji. + mediump float maskTexture = TEXTURE(sMask, vTexCoord).r; + + // Set the color of non-transparent pixel in text to what it is animated to. + // Markup text with multiple text colors are not animated (but can be supported later on if required). + // Emoji color are not animated. + mediump float vstep = step( 0.0001, textColor.a ); + textColor.rgb = mix(textColor.rgb, uTextColorAnimatable.rgb, vstep * maskTexture * (1.0 - uHasMultipleTextColors)); +#endif +#else + // Single color without emoji. + mediump float textTexture = TEXTURE(sTexture, vTexCoord).r; + mediump vec4 textColor = uTextColorAnimatable * textTexture; +#endif + + // Draw the text as overlay above the style + OUT_COLOR = uColor * vec4(mixColor, 1.0) * ( +#ifdef IS_REQUIRED_OVERLAY + ( +#endif + textColor +#ifdef IS_REQUIRED_STYLE + + styleTexture * (1.0 - textColor.a) +#endif +#ifdef IS_REQUIRED_OVERLAY + ) * (1.0 - overlayStyleTexture.a) + overlayStyleTexture +#endif + ); +} diff --git a/dali-toolkit/internal/graphics/shaders/text-visual-shader.vert b/dali-toolkit/internal/graphics/shaders/text-visual-shader.vert index 4cc1212..6e90fe9 100644 --- a/dali-toolkit/internal/graphics/shaders/text-visual-shader.vert +++ b/dali-toolkit/internal/graphics/shaders/text-visual-shader.vert @@ -1,9 +1,9 @@ -attribute mediump vec2 aPosition; +INPUT mediump vec2 aPosition; uniform highp mat4 uMvpMatrix; uniform highp vec3 uSize; uniform mediump vec4 pixelArea; -varying mediump vec2 vTexCoord; +OUTPUT mediump vec2 vTexCoord; //Visual size and offset uniform mediump vec2 offset; diff --git a/dali-toolkit/internal/graphics/shaders/text-visual-single-color-text-shader.frag b/dali-toolkit/internal/graphics/shaders/text-visual-single-color-text-shader.frag deleted file mode 100644 index ab44460..0000000 --- a/dali-toolkit/internal/graphics/shaders/text-visual-single-color-text-shader.frag +++ /dev/null @@ -1,13 +0,0 @@ -varying mediump vec2 vTexCoord; -uniform sampler2D sTexture; -uniform lowp vec4 uTextColorAnimatable; -uniform lowp vec4 uColor; -uniform lowp vec3 mixColor; - -void main() -{ - mediump float textTexture = texture2D( sTexture, vTexCoord ).r; - - // Set the color of the text to what it is animated to. - gl_FragColor = uTextColorAnimatable * textTexture * uColor * vec4( mixColor, 1.0 ); -} diff --git a/dali-toolkit/internal/graphics/shaders/text-visual-single-color-text-with-emoji-shader.frag b/dali-toolkit/internal/graphics/shaders/text-visual-single-color-text-with-emoji-shader.frag deleted file mode 100644 index 544f0be..0000000 --- a/dali-toolkit/internal/graphics/shaders/text-visual-single-color-text-with-emoji-shader.frag +++ /dev/null @@ -1,21 +0,0 @@ -varying mediump vec2 vTexCoord; -uniform sampler2D sTexture; -uniform sampler2D sMask; -uniform lowp vec4 uTextColorAnimatable; -uniform lowp vec4 uColor; -uniform lowp vec3 mixColor; - -void main() -{ - mediump vec4 textTexture = texture2D( sTexture, vTexCoord ); - mediump float maskTexture = texture2D( sMask, vTexCoord ).r; - - // Set the color of non-transparent pixel in text to what it is animated to. - // Markup text with multiple text colors are not animated (but can be supported later on if required). - // Emoji color are not animated. - mediump float vstep = step( 0.0001, textTexture.a ); - textTexture.rgb = mix( textTexture.rgb, uTextColorAnimatable.rgb, vstep * maskTexture ); - - // Draw the text as overlay above the style - gl_FragColor = textTexture * uColor * vec4( mixColor, 1.0 ); -} diff --git a/dali-toolkit/internal/graphics/shaders/text-visual-single-color-text-with-style-and-emoji-shader.frag b/dali-toolkit/internal/graphics/shaders/text-visual-single-color-text-with-style-and-emoji-shader.frag deleted file mode 100644 index 0d82aa7..0000000 --- a/dali-toolkit/internal/graphics/shaders/text-visual-single-color-text-with-style-and-emoji-shader.frag +++ /dev/null @@ -1,26 +0,0 @@ -varying mediump vec2 vTexCoord; -uniform sampler2D sTexture; -uniform sampler2D sStyle; -uniform sampler2D sOverlayStyle; -uniform sampler2D sMask; -uniform lowp float uHasMultipleTextColors; -uniform lowp vec4 uTextColorAnimatable; -uniform lowp vec4 uColor; -uniform lowp vec3 mixColor; - -void main() -{ - mediump vec4 textTexture = texture2D( sTexture, vTexCoord ); - mediump vec4 styleTexture = texture2D( sStyle, vTexCoord ); - mediump vec4 overlayStyleTexture = texture2D( sOverlayStyle, vTexCoord ); - mediump float maskTexture = texture2D( sMask, vTexCoord ).r; - - // Set the color of non-transparent pixel in text to what it is animated to. - // Markup text with multiple text colors are not animated (but can be supported later on if required). - // Emoji color are not animated. - mediump float vstep = step( 0.0001, textTexture.a ); - textTexture.rgb = mix( textTexture.rgb, uTextColorAnimatable.rgb, vstep * maskTexture * ( 1.0 - uHasMultipleTextColors ) ); - - // Draw the text as overlay above the style - gl_FragColor = ( overlayStyleTexture + textTexture * (1.0 - overlayStyleTexture.a) + styleTexture * ( 1.0 - textTexture.a ) * (1.0 - overlayStyleTexture.a) ) * uColor * vec4( mixColor, 1.0 ); -} diff --git a/dali-toolkit/internal/graphics/shaders/text-visual-single-color-text-with-style-shader.frag b/dali-toolkit/internal/graphics/shaders/text-visual-single-color-text-with-style-shader.frag deleted file mode 100644 index cf93f15..0000000 --- a/dali-toolkit/internal/graphics/shaders/text-visual-single-color-text-with-style-shader.frag +++ /dev/null @@ -1,17 +0,0 @@ -varying mediump vec2 vTexCoord; -uniform sampler2D sTexture; -uniform sampler2D sStyle; -uniform sampler2D sOverlayStyle; -uniform lowp vec4 uTextColorAnimatable; -uniform lowp vec4 uColor; -uniform lowp vec3 mixColor; - -void main() -{ - mediump float textTexture = texture2D( sTexture, vTexCoord ).r; - mediump vec4 styleTexture = texture2D( sStyle, vTexCoord ); - mediump vec4 overlayStyleTexture = texture2D( sOverlayStyle, vTexCoord ); - - // Draw the text as overlay above the style - gl_FragColor = ( overlayStyleTexture + uTextColorAnimatable * textTexture * (1.0 - overlayStyleTexture.a) + styleTexture * ( 1.0 - uTextColorAnimatable.a * textTexture ) * (1.0 - overlayStyleTexture.a) ) * uColor * vec4( mixColor, 1.0 ); -} \ No newline at end of file diff --git a/dali-toolkit/internal/text/markup-processor.cpp b/dali-toolkit/internal/text/markup-processor.cpp index 1047411..344cde1 100644 --- a/dali-toolkit/internal/text/markup-processor.cpp +++ b/dali-toolkit/internal/text/markup-processor.cpp @@ -941,10 +941,13 @@ void ResizeModelVectors(MarkupProcessData& markupProcessData, markupProcessData.characterSpacingCharacterRuns.Resize(characterSpacingCharacterRunIndex); #ifdef DEBUG_ENABLED - for(uint32_t i = 0; gLogFilter->IsEnabledFor(Debug::Verbose) && i < colorRunIndex; ++i) + if(gLogFilter->IsEnabledFor(Debug::Verbose)) { - ColorRun& run = markupProcessData.colorRuns[i]; - DALI_LOG_INFO(gLogFilter, Debug::Verbose, "run[%d] index: %d, length: %d, color %f,%f,%f,%f\n", i, run.characterRun.characterIndex, run.characterRun.numberOfCharacters, run.color.r, run.color.g, run.color.b, run.color.a); + for(uint32_t i = 0; i < colorRunIndex; ++i) + { + ColorRun& run = markupProcessData.colorRuns[i]; + DALI_LOG_INFO(gLogFilter, Debug::Verbose, "run[%d] index: %d, length: %d, color %f,%f,%f,%f\n", i, run.characterRun.characterIndex, run.characterRun.numberOfCharacters, run.color.r, run.color.g, run.color.b, run.color.a); + } } #endif } diff --git a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp index 1a1063c..1d8731d 100644 --- a/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp +++ b/dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp @@ -802,11 +802,14 @@ struct AtlasRenderer::Impl Toolkit::AtlasGlyphManager::Metrics metrics = mGlyphManager.GetMetrics(); DALI_LOG_INFO(gLogFilter, Debug::General, "TextAtlasRenderer::GlyphManager::GlyphCount: %i, AtlasCount: %i, TextureMemoryUse: %iK\n", metrics.mGlyphCount, metrics.mAtlasMetrics.mAtlasCount, metrics.mAtlasMetrics.mTextureMemoryUsed / 1024); - DALI_LOG_INFO(gLogFilter, Debug::Verbose, "%s\n", metrics.mVerboseGlyphCounts.c_str()); - - for(uint32_t i = 0; gLogFilter->IsEnabledFor(Debug::Verbose) && i < metrics.mAtlasMetrics.mAtlasCount; ++i) + if(gLogFilter->IsEnabledFor(Debug::Verbose)) { - DALI_LOG_INFO(gLogFilter, Debug::Verbose, " Atlas [%i] %sPixels: %s Size: %ix%i, BlockSize: %ix%i, BlocksUsed: %i/%i\n", i + 1, i > 8 ? "" : " ", metrics.mAtlasMetrics.mAtlasMetrics[i].mPixelFormat == Pixel::L8 ? "L8 " : "BGRA", metrics.mAtlasMetrics.mAtlasMetrics[i].mSize.mWidth, metrics.mAtlasMetrics.mAtlasMetrics[i].mSize.mHeight, metrics.mAtlasMetrics.mAtlasMetrics[i].mSize.mBlockWidth, metrics.mAtlasMetrics.mAtlasMetrics[i].mSize.mBlockHeight, metrics.mAtlasMetrics.mAtlasMetrics[i].mBlocksUsed, metrics.mAtlasMetrics.mAtlasMetrics[i].mTotalBlocks); + DALI_LOG_INFO(gLogFilter, Debug::Verbose, "%s\n", metrics.mVerboseGlyphCounts.c_str()); + + for(uint32_t i = 0; i < metrics.mAtlasMetrics.mAtlasCount; ++i) + { + DALI_LOG_INFO(gLogFilter, Debug::Verbose, " Atlas [%i] %sPixels: %s Size: %ix%i, BlockSize: %ix%i, BlocksUsed: %i/%i\n", i + 1, i > 8 ? "" : " ", metrics.mAtlasMetrics.mAtlasMetrics[i].mPixelFormat == Pixel::L8 ? "L8 " : "BGRA", metrics.mAtlasMetrics.mAtlasMetrics[i].mSize.mWidth, metrics.mAtlasMetrics.mAtlasMetrics[i].mSize.mHeight, metrics.mAtlasMetrics.mAtlasMetrics[i].mSize.mBlockWidth, metrics.mAtlasMetrics.mAtlasMetrics[i].mSize.mBlockHeight, metrics.mAtlasMetrics.mAtlasMetrics[i].mBlocksUsed, metrics.mAtlasMetrics.mAtlasMetrics[i].mTotalBlocks); + } } #endif } diff --git a/dali-toolkit/internal/visuals/text-visual-shader-factory.cpp b/dali-toolkit/internal/visuals/text-visual-shader-factory.cpp new file mode 100644 index 0000000..5a2eba8 --- /dev/null +++ b/dali-toolkit/internal/visuals/text-visual-shader-factory.cpp @@ -0,0 +1,167 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// CLASS HEADER +#include + +// INTERNAL INCLUDES +#include +#include +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Internal +{ +namespace +{ +// global string variable to caching complate vertex shader +static std::string gVertexShader; + +// global string variable to caching complate fragment shader (no atlas) +static std::string gFragmentShaderNoAtlas; + +// enum of required list when we select shader +enum class TextVisualRequireFlag : uint32_t +{ + DEFAULT = 0, + STYLES = 1 << 0, + OVERLAY = 1 << 1, + EMOJI = 1 << 2, + MULTI_COLOR = 1 << 3, +}; + +const VisualFactoryCache::ShaderType SHADER_TYPE_TABLE[] = + { + VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT, + VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE, + VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_OVERLAY, + VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_OVERLAY, + VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_EMOJI, + VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI, + VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_OVERLAY_AND_EMOJI, + VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_OVERLAY_AND_EMOJI, + VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT, + VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE, + VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT_WITH_OVERLAY, + VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE_AND_OVERLAY, +}; + +} // unnamed namespace + +namespace TextVisualShaderFeature +{ +FeatureBuilder& FeatureBuilder::EnableMultiColor(bool enableMultiColor) +{ + mTextMultiColor = enableMultiColor ? TextMultiColor::MULTI_COLOR_TEXT : TextMultiColor::SINGLE_COLOR_TEXT; + return *this; +} +FeatureBuilder& FeatureBuilder::EnableEmoji(bool enableEmoji) +{ + mTextEmoji = enableEmoji ? TextEmoji::HAS_EMOJI : TextEmoji::NO_EMOJI; + return *this; +} +FeatureBuilder& FeatureBuilder::EnableStyle(bool enableStyle) +{ + mTextStyle = enableStyle ? TextStyle::HAS_STYLES : TextStyle::NO_STYLES; + return *this; +} +FeatureBuilder& FeatureBuilder::EnableOverlay(bool enableOverlay) +{ + mTextOverlay = enableOverlay ? TextOverlay::HAS_OVERLAY : TextOverlay::NO_OVERLAY; + return *this; +} +} // namespace TextVisualShaderFeature + +TextVisualShaderFactory::TextVisualShaderFactory() +{ +} + +TextVisualShaderFactory::~TextVisualShaderFactory() +{ +} + +Shader TextVisualShaderFactory::GetShader(VisualFactoryCache& factoryCache, const TextVisualShaderFeature::FeatureBuilder& featureBuilder) +{ + Shader shader; + uint32_t shaderTypeFlag = static_cast(TextVisualRequireFlag::DEFAULT); + VisualFactoryCache::ShaderType shaderType = VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT; + + const auto& multiColor = featureBuilder.mTextMultiColor; + const auto& emoji = featureBuilder.mTextEmoji; + const auto& style = featureBuilder.mTextStyle; + const auto& overlay = featureBuilder.mTextOverlay; + + if(style == TextVisualShaderFeature::TextStyle::HAS_STYLES) + { + shaderTypeFlag |= static_cast(TextVisualRequireFlag::STYLES); + } + if(overlay == TextVisualShaderFeature::TextOverlay::HAS_OVERLAY) + { + shaderTypeFlag |= static_cast(TextVisualRequireFlag::OVERLAY); + } + // multi color can also render emoji. If multi color text, dont consider emoji + if(multiColor != TextVisualShaderFeature::TextMultiColor::MULTI_COLOR_TEXT && emoji == TextVisualShaderFeature::TextEmoji::HAS_EMOJI) + { + shaderTypeFlag |= static_cast(TextVisualRequireFlag::EMOJI); + } + if(multiColor == TextVisualShaderFeature::TextMultiColor::MULTI_COLOR_TEXT) + { + shaderTypeFlag |= static_cast(TextVisualRequireFlag::MULTI_COLOR); + } + + shaderType = SHADER_TYPE_TABLE[shaderTypeFlag]; + shader = factoryCache.GetShader(shaderType); + + if(!shader) + { + std::string vertexShaderPrefixList; + std::string fragmentShaderPrefixList; + + if(style == TextVisualShaderFeature::TextStyle::HAS_STYLES) + { + fragmentShaderPrefixList += "#define IS_REQUIRED_STYLE\n"; + } + if(overlay == TextVisualShaderFeature::TextOverlay::HAS_OVERLAY) + { + fragmentShaderPrefixList += "#define IS_REQUIRED_OVERLAY\n"; + } + // multi color can also render emoji. If multi color text, dont consider emoji + if(multiColor != TextVisualShaderFeature::TextMultiColor::MULTI_COLOR_TEXT && emoji == TextVisualShaderFeature::TextEmoji::HAS_EMOJI) + { + fragmentShaderPrefixList += "#define IS_REQUIRED_EMOJI\n"; + } + if(multiColor == TextVisualShaderFeature::TextMultiColor::MULTI_COLOR_TEXT) + { + fragmentShaderPrefixList += "#define IS_REQUIRED_MULTI_COLOR\n"; + } + + std::string vertexShader = std::string(Dali::Shader::GetVertexShaderPrefix() + vertexShaderPrefixList + SHADER_TEXT_VISUAL_SHADER_VERT.data()); + std::string fragmentShader = std::string(Dali::Shader::GetFragmentShaderPrefix() + fragmentShaderPrefixList + SHADER_TEXT_VISUAL_SHADER_FRAG.data()); + + shader = Shader::New(vertexShader, fragmentShader); + factoryCache.SaveShader(shaderType, shader); + } + return shader; +} + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/visuals/text-visual-shader-factory.h b/dali-toolkit/internal/visuals/text-visual-shader-factory.h new file mode 100644 index 0000000..4a9969b --- /dev/null +++ b/dali-toolkit/internal/visuals/text-visual-shader-factory.h @@ -0,0 +1,172 @@ +#ifndef DALI_TOOLKIT_TEXT_VISUAL_SHADER_FACTORY_H +#define DALI_TOOLKIT_TEXT_VISUAL_SHADER_FACTORY_H + +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// EXTERNAL INCLUDES + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ +namespace Toolkit +{ +namespace Internal +{ +/** + * TextVisualShaderFeature contains feature lists what text visual shader need to know. + */ +namespace TextVisualShaderFeature +{ +namespace TextMultiColor +{ +/** + * @brief Whether text contains single color or not. + */ +enum Type +{ + SINGLE_COLOR_TEXT = 0, ///< The text contains single color only. + MULTI_COLOR_TEXT ///< The text contains multiple colors. +}; +} // namespace TextMultiColor + +namespace TextEmoji +{ +/** + * @brief Whether text contains emoji or not. + */ +enum Type +{ + NO_EMOJI = 0, ///< The text contains no emoji. + HAS_EMOJI ///< The text contains emoji. +}; +} // namespace TextEmoji + +namespace TextStyle +{ +/** + * @brief Whether text contains styles (like shadow or background color) or not. + */ +enum Type +{ + NO_STYLES = 0, ///< The text contains contains no styles. + HAS_STYLES ///< The text contains contains styles. +}; +} // namespace TextStyle + +namespace TextOverlay +{ +/** + * @brief Whether text contains overlay styles (like markdown) or not. + */ +enum Type +{ + NO_OVERLAY = 0, ///< The text contains contains no overlay. + HAS_OVERLAY ///< The text contains contains overlay. +}; +} // namespace TextOverlay + +/** + * @brief Collection of current text visual feature. + */ +struct FeatureBuilder +{ + FeatureBuilder() + : mTextMultiColor(TextMultiColor::SINGLE_COLOR_TEXT), + mTextEmoji(TextEmoji::NO_EMOJI), + mTextStyle(TextStyle::NO_STYLES), + mTextOverlay(TextOverlay::NO_OVERLAY) + { + } + + FeatureBuilder& EnableMultiColor(bool enableMultiColor); + FeatureBuilder& EnableEmoji(bool enableEmoji); + FeatureBuilder& EnableStyle(bool enableStyle); + FeatureBuilder& EnableOverlay(bool enableOverlay); + + bool IsEnabledMultiColor() const + { + return mTextMultiColor == TextMultiColor::MULTI_COLOR_TEXT; + } + bool IsEnabledEmoji() const + { + return mTextEmoji == TextEmoji::HAS_EMOJI; + } + bool IsEnabledStyle() const + { + return mTextStyle == TextStyle::HAS_STYLES; + } + bool IsEnabledOverlay() const + { + return mTextOverlay == TextOverlay::HAS_OVERLAY; + } + + TextMultiColor::Type mTextMultiColor : 2; ///< Whether text has multiple color, or not. default as TextMultiColor::SINGLE_COLOR_TEXT + TextEmoji::Type mTextEmoji : 2; ///< Whether text has emoji, or not. default as TextEmoji::NO_EMOJI + TextStyle::Type mTextStyle : 2; ///< Whether text has style, or not. default as TextStyle::NO_STYLES + TextOverlay::Type mTextOverlay : 2; ///< Whether text has overlay style, or not. default as TextOverlay::NO_OVERLAY +}; + +} // namespace TextVisualShaderFeature + +/** + * TextVisualShaderFactory is an object that provides and shares shaders for text visuals + */ +class TextVisualShaderFactory +{ +public: + /** + * @brief Constructor + */ + TextVisualShaderFactory(); + + /** + * @brief Destructor + */ + ~TextVisualShaderFactory(); + + /** + * @brief Get the standard text rendering shader. + * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object + * @param[in] featureBuilder Collection of current text shader's features + * @return The standard text rendering shader with features. + */ + Shader GetShader(VisualFactoryCache& factoryCache, const TextVisualShaderFeature::FeatureBuilder& featureBuilder); + +protected: + /** + * Undefined copy constructor. + */ + TextVisualShaderFactory(const TextVisualShaderFactory&); + + /** + * Undefined assignment operator. + */ + TextVisualShaderFactory& operator=(const TextVisualShaderFactory& rhs); + +private: +}; + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_TEXT_VISUAL_SHADER_FACTORY_H diff --git a/dali-toolkit/internal/visuals/text/text-visual.cpp b/dali-toolkit/internal/visuals/text/text-visual.cpp index 777e48f..2106745 100644 --- a/dali-toolkit/internal/visuals/text/text-visual.cpp +++ b/dali-toolkit/internal/visuals/text/text-visual.cpp @@ -148,9 +148,9 @@ void OpacityConstraint(float& current, const PropertyInputContainer& inputs) } // unnamed namespace -TextVisualPtr TextVisual::New(VisualFactoryCache& factoryCache, const Property::Map& properties) +TextVisualPtr TextVisual::New(VisualFactoryCache& factoryCache, TextVisualShaderFactory& shaderFactory, const Property::Map& properties) { - TextVisualPtr textVisualPtr(new TextVisual(factoryCache)); + TextVisualPtr textVisualPtr(new TextVisual(factoryCache, shaderFactory)); textVisualPtr->SetProperties(properties); textVisualPtr->Initialize(); return textVisualPtr; @@ -249,10 +249,12 @@ void TextVisual::EnablePreMultipliedAlpha(bool preMultiplied) } } -TextVisual::TextVisual(VisualFactoryCache& factoryCache) +TextVisual::TextVisual(VisualFactoryCache& factoryCache, TextVisualShaderFactory& shaderFactory) : Visual::Base(factoryCache, Visual::FittingMode::FIT_KEEP_ASPECT_RATIO, Toolkit::Visual::TEXT), mController(Text::Controller::New()), mTypesetter(Text::Typesetter::New(mController->GetTextModel())), + mTextVisualShaderFactory(shaderFactory), + mTextShaderFeatureCache(), mAnimatableTextColorPropertyIndex(Property::INVALID_INDEX), mTextColorAnimatableIndex(Property::INVALID_INDEX), mRendererUpdateNeeded(false) @@ -268,7 +270,7 @@ TextVisual::~TextVisual() void TextVisual::OnInitialize() { Geometry geometry = mFactoryCache.GetGeometry(VisualFactoryCache::QUAD_GEOMETRY); - Shader shader = GetTextShader(mFactoryCache, TextType::SINGLE_COLOR_TEXT, TextType::NO_EMOJI, TextType::NO_STYLES); + Shader shader = GetTextShader(mFactoryCache, TextVisualShaderFeature::FeatureBuilder()); mImpl->mRenderer = VisualRenderer::New(geometry, shader); mImpl->mRenderer.ReserveCustomProperties(CUSTOM_PROPERTY_COUNT); @@ -604,7 +606,7 @@ PixelData TextVisual::ConvertToPixelData(unsigned char* buffer, int width, int h return pixelData; } -void TextVisual::CreateTextureSet(TilingInfo& info, VisualRenderer& renderer, Sampler& sampler, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled, bool isOverlayStyle) +void TextVisual::CreateTextureSet(TilingInfo& info, VisualRenderer& renderer, Sampler& sampler) { TextureSet textureSet = TextureSet::New(); unsigned int textureSetIndex = 0u; @@ -618,21 +620,21 @@ void TextVisual::CreateTextureSet(TilingInfo& info, VisualRenderer& renderer, Sa ++textureSetIndex; } - if(styleEnabled && info.styleBuffer && info.overlayStyleBuffer) + if(mTextShaderFeatureCache.IsEnabledStyle() && info.styleBuffer) { PixelData styleData = ConvertToPixelData(info.styleBuffer, info.width, info.height, info.offsetPosition, Pixel::RGBA8888); AddTexture(textureSet, styleData, sampler, textureSetIndex); ++textureSetIndex; + } - // TODO : We need to seperate whether use overlayStyle or not. - // Current text visual shader required both of them. - + if(mTextShaderFeatureCache.IsEnabledOverlay() && info.overlayStyleBuffer) + { PixelData overlayStyleData = ConvertToPixelData(info.overlayStyleBuffer, info.width, info.height, info.offsetPosition, Pixel::RGBA8888); AddTexture(textureSet, overlayStyleData, sampler, textureSetIndex); ++textureSetIndex; } - if(containsColorGlyph && !hasMultipleTextColors && info.maskBuffer) + if(mTextShaderFeatureCache.IsEnabledEmoji() && !mTextShaderFeatureCache.IsEnabledMultiColor() && info.maskBuffer) { PixelData maskData = ConvertToPixelData(info.maskBuffer, info.width, info.height, info.offsetPosition, Pixel::L8); AddTexture(textureSet, maskData, sampler, textureSetIndex); @@ -651,14 +653,14 @@ void TextVisual::CreateTextureSet(TilingInfo& info, VisualRenderer& renderer, Sa renderer.SetProperty(VisualRenderer::Property::TRANSFORM_SIZE, Vector2(info.width, info.height)); renderer.SetProperty(VisualRenderer::Property::TRANSFORM_OFFSET, Vector2(info.offSet.x, info.offSet.y)); renderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON); - renderer.RegisterProperty("uHasMultipleTextColors", static_cast(hasMultipleTextColors)); + renderer.RegisterProperty("uHasMultipleTextColors", static_cast(mTextShaderFeatureCache.IsEnabledMultiColor())); mRendererList.push_back(renderer); } void TextVisual::AddRenderer(Actor& actor, const Vector2& size, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled, bool isOverlayStyle) { - Shader shader = GetTextShader(mFactoryCache, hasMultipleTextColors, containsColorGlyph, styleEnabled); + Shader shader = GetTextShader(mFactoryCache, TextVisualShaderFeature::FeatureBuilder().EnableMultiColor(hasMultipleTextColors).EnableEmoji(containsColorGlyph).EnableStyle(styleEnabled).EnableOverlay(isOverlayStyle)); mImpl->mRenderer.SetShader(shader); // Get the maximum size. @@ -667,7 +669,7 @@ void TextVisual::AddRenderer(Actor& actor, const Vector2& size, bool hasMultiple // No tiling required. Use the default renderer. if(size.height < maxTextureSize) { - TextureSet textureSet = GetTextTexture(size, hasMultipleTextColors, containsColorGlyph, styleEnabled, isOverlayStyle); + TextureSet textureSet = GetTextTexture(size); mImpl->mRenderer.SetTextures(textureSet); //Register transform properties @@ -703,23 +705,23 @@ void TextVisual::AddRenderer(Actor& actor, const Vector2& size, bool hasMultiple Dali::DevelPixelData::PixelDataBuffer textPixelData = Dali::DevelPixelData::ReleasePixelDataBuffer(data); info.textBuffer = textPixelData.buffer; - if(styleEnabled) + if(mTextShaderFeatureCache.IsEnabledStyle()) { // Create RGBA texture for all the text styles (without the text itself) PixelData styleData = mTypesetter->Render(size, textDirection, Text::Typesetter::RENDER_NO_TEXT, false, Pixel::RGBA8888); Dali::DevelPixelData::PixelDataBuffer stylePixelData = Dali::DevelPixelData::ReleasePixelDataBuffer(styleData); info.styleBuffer = stylePixelData.buffer; + } - // TODO : We need to seperate whether use overlayStyle or not. - // Current text visual shader required both of them. - + if(mTextShaderFeatureCache.IsEnabledOverlay()) + { // Create RGBA texture for all the overlay styles PixelData overlayStyleData = mTypesetter->Render(size, textDirection, Text::Typesetter::RENDER_OVERLAY_STYLE, false, Pixel::RGBA8888); Dali::DevelPixelData::PixelDataBuffer overlayStylePixelData = Dali::DevelPixelData::ReleasePixelDataBuffer(overlayStyleData); info.overlayStyleBuffer = overlayStylePixelData.buffer; } - if(containsColorGlyph && !hasMultipleTextColors) + if(mTextShaderFeatureCache.IsEnabledEmoji() && !mTextShaderFeatureCache.IsEnabledMultiColor()) { // Create a L8 texture as a mask to avoid color glyphs (e.g. emojis) to be affected by text color animation PixelData maskData = mTypesetter->Render(size, textDirection, Text::Typesetter::RENDER_MASK, false, Pixel::L8); @@ -737,7 +739,7 @@ void TextVisual::AddRenderer(Actor& actor, const Vector2& size, bool hasMultiple } // Create a textureset in the default renderer. - CreateTextureSet(info, mImpl->mRenderer, sampler, hasMultipleTextColors, containsColorGlyph, styleEnabled, isOverlayStyle); + CreateTextureSet(info, mImpl->mRenderer, sampler); verifiedHeight -= maxTextureSize; @@ -756,7 +758,7 @@ void TextVisual::AddRenderer(Actor& actor, const Vector2& size, bool hasMultiple // New offset for tiling. info.offSet.y += maxTextureSize; // Create a textureset int the new tiling renderer. - CreateTextureSet(info, tilingRenderer, sampler, hasMultipleTextColors, containsColorGlyph, styleEnabled, isOverlayStyle); + CreateTextureSet(info, tilingRenderer, sampler); verifiedHeight -= maxTextureSize; } @@ -800,7 +802,7 @@ void TextVisual::AddRenderer(Actor& actor, const Vector2& size, bool hasMultiple } } -TextureSet TextVisual::GetTextTexture(const Vector2& size, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled, bool isOverlayStyle) +TextureSet TextVisual::GetTextTexture(const Vector2& size) { // Filter mode needs to be set to linear to produce better quality while scaling. Sampler sampler = Sampler::New(); @@ -809,7 +811,7 @@ TextureSet TextVisual::GetTextTexture(const Vector2& size, bool hasMultipleTextC TextureSet textureSet = TextureSet::New(); // Create RGBA texture if the text contains emojis or multiple text colors, otherwise L8 texture - Pixel::Format textPixelFormat = (containsColorGlyph || hasMultipleTextColors) ? Pixel::RGBA8888 : Pixel::L8; + Pixel::Format textPixelFormat = (mTextShaderFeatureCache.IsEnabledEmoji() || mTextShaderFeatureCache.IsEnabledMultiColor()) ? Pixel::RGBA8888 : Pixel::L8; // Check the text direction Toolkit::DevelText::TextDirection::Type textDirection = mController->GetTextDirection(); @@ -823,23 +825,23 @@ TextureSet TextVisual::GetTextTexture(const Vector2& size, bool hasMultipleTextC AddTexture(textureSet, data, sampler, textureSetIndex); ++textureSetIndex; - if(styleEnabled) + if(mTextShaderFeatureCache.IsEnabledStyle()) { // Create RGBA texture for all the text styles that render in the background (without the text itself) PixelData styleData = mTypesetter->Render(size, textDirection, Text::Typesetter::RENDER_NO_TEXT, false, Pixel::RGBA8888); AddTexture(textureSet, styleData, sampler, textureSetIndex); ++textureSetIndex; + } - // TODO : We need to seperate whether use overlayStyle or not. - // Current text visual shader required both of them. - + if(mTextShaderFeatureCache.IsEnabledOverlay()) + { // Create RGBA texture for overlay styles such as underline and strikethrough (without the text itself) PixelData overlayStyleData = mTypesetter->Render(size, textDirection, Text::Typesetter::RENDER_OVERLAY_STYLE, false, Pixel::RGBA8888); AddTexture(textureSet, overlayStyleData, sampler, textureSetIndex); ++textureSetIndex; } - if(containsColorGlyph && !hasMultipleTextColors) + if(mTextShaderFeatureCache.IsEnabledEmoji() && !mTextShaderFeatureCache.IsEnabledMultiColor()) { // Create a L8 texture as a mask to avoid color glyphs (e.g. emojis) to be affected by text color animation PixelData maskData = mTypesetter->Render(size, textDirection, Text::Typesetter::RENDER_MASK, false, Pixel::L8); @@ -850,73 +852,13 @@ TextureSet TextVisual::GetTextTexture(const Vector2& size, bool hasMultipleTextC return textureSet; } -Shader TextVisual::GetTextShader(VisualFactoryCache& factoryCache, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled) +Shader TextVisual::GetTextShader(VisualFactoryCache& factoryCache, const TextVisualShaderFeature::FeatureBuilder& featureBuilder) { - Shader shader; - - if(hasMultipleTextColors && !styleEnabled) - { - // We don't animate text color if the text contains multiple colors - shader = factoryCache.GetShader(VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT); - if(!shader) - { - shader = Shader::New(SHADER_TEXT_VISUAL_SHADER_VERT, SHADER_TEXT_VISUAL_MULTI_COLOR_TEXT_SHADER_FRAG); - shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT); - factoryCache.SaveShader(VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT, shader); - } - } - else if(hasMultipleTextColors && styleEnabled) - { - // We don't animate text color if the text contains multiple colors - shader = factoryCache.GetShader(VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE); - if(!shader) - { - shader = Shader::New(SHADER_TEXT_VISUAL_SHADER_VERT, SHADER_TEXT_VISUAL_MULTI_COLOR_TEXT_WITH_STYLE_SHADER_FRAG); - shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT); - factoryCache.SaveShader(VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE, shader); - } - } - else if(!hasMultipleTextColors && !containsColorGlyph && !styleEnabled) - { - shader = factoryCache.GetShader(VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT); - if(!shader) - { - shader = Shader::New(SHADER_TEXT_VISUAL_SHADER_VERT, SHADER_TEXT_VISUAL_SINGLE_COLOR_TEXT_SHADER_FRAG); - shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT); - factoryCache.SaveShader(VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT, shader); - } - } - else if(!hasMultipleTextColors && !containsColorGlyph && styleEnabled) - { - shader = factoryCache.GetShader(VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE); - if(!shader) - { - shader = Shader::New(SHADER_TEXT_VISUAL_SHADER_VERT, SHADER_TEXT_VISUAL_SINGLE_COLOR_TEXT_WITH_STYLE_SHADER_FRAG); - shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT); - factoryCache.SaveShader(VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE, shader); - } - } - else if(!hasMultipleTextColors && containsColorGlyph && !styleEnabled) - { - shader = factoryCache.GetShader(VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_EMOJI); - if(!shader) - { - shader = Shader::New(SHADER_TEXT_VISUAL_SHADER_VERT, SHADER_TEXT_VISUAL_SINGLE_COLOR_TEXT_WITH_EMOJI_SHADER_FRAG); - shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT); - factoryCache.SaveShader(VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_EMOJI, shader); - } - } - else // if( !hasMultipleTextColors && containsColorGlyph && styleEnabled ) - { - shader = factoryCache.GetShader(VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI); - if(!shader) - { - shader = Shader::New(SHADER_TEXT_VISUAL_SHADER_VERT, SHADER_TEXT_VISUAL_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI_SHADER_FRAG); - shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT); - factoryCache.SaveShader(VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI, shader); - } - } + // Cache feature builder informations. + mTextShaderFeatureCache = featureBuilder; + Shader shader = mTextVisualShaderFactory.GetShader(factoryCache, mTextShaderFeatureCache); + shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT); return shader; } diff --git a/dali-toolkit/internal/visuals/text/text-visual.h b/dali-toolkit/internal/visuals/text/text-visual.h index c79c254..05d1585 100644 --- a/dali-toolkit/internal/visuals/text/text-visual.h +++ b/dali-toolkit/internal/visuals/text/text-visual.h @@ -27,6 +27,7 @@ // INTERNAL INCLUDES #include #include +#include #include namespace Dali @@ -72,10 +73,11 @@ public: * @brief Create a new text visual. * * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object + * @param[in] shaderFactory The TextVisualShaderFactory object * @param[in] properties A Property::Map containing settings for this visual * @return A smart-pointer to the newly allocated visual. */ - static TextVisualPtr New(VisualFactoryCache& factoryCache, const Property::Map& properties); + static TextVisualPtr New(VisualFactoryCache& factoryCache, TextVisualShaderFactory& shaderFactory, const Property::Map& properties); /** * @brief Converts all strings keys in property map to index keys. Property Map can then be merged correctly. @@ -153,8 +155,9 @@ protected: * @brief Constructor. * * @param[in] factoryCache The VisualFactoryCache object + * @param[in] shaderFactory The TextVisualShaderFactory object */ - TextVisual(VisualFactoryCache& factoryCache); + TextVisual(VisualFactoryCache& factoryCache, TextVisualShaderFactory& shaderFactory); /** * @brief A reference counted object may only be deleted by calling Unreference(). @@ -274,16 +277,12 @@ private: PixelData ConvertToPixelData(unsigned char* buffer, int width, int height, int offsetPosition, const Pixel::Format textPixelFormat); /** - * @brief Create the text's texture. + * @brief Create the text's texture. It will use cached shader feature for text visual. * @param[in] info This is the information you need to create a Tiling. * @param[in] renderer The renderer to which the TextureSet will be added. * @param[in] sampler The sampler. - * @param[in] hasMultipleTextColors Whether the text contains multiple colors. - * @param[in] containsColorGlyph Whether the text contains color glyph. - * @param[in] styleEnabled Whether the text contains any styles (e.g. shadow, underline, etc.). - * @param[in] isOverlayStyle Whether the style needs to overlay on the text (e.g. strikethrough, underline, etc.). */ - void CreateTextureSet(TilingInfo& info, VisualRenderer& renderer, Sampler& sampler, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled, bool isOverlayStyle); + void CreateTextureSet(TilingInfo& info, VisualRenderer& renderer, Sampler& sampler); /** * Create renderer of the text for rendering. @@ -297,23 +296,17 @@ private: void AddRenderer(Actor& actor, const Vector2& size, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled, bool isOverlayStyle); /** - * Get the texture of the text for rendering. + * Get the texture of the text for rendering. It will use cached shader feature for text visual. * @param[in] size The texture size. - * @param[in] hasMultipleTextColors Whether the text contains multiple colors. - * @param[in] containsColorGlyph Whether the text contains color glyph. - * @param[in] styleEnabled Whether the text contains any styles (e.g. shadow, underline, etc.). - * @param[in] isOverlayStyle Whether the style needs to overlay on the text (e.g. strikethrough, underline, etc.). */ - TextureSet GetTextTexture(const Vector2& size, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled, bool isOverlayStyle); + TextureSet GetTextTexture(const Vector2& size); /** * Get the text rendering shader. * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object - * @param[in] hasMultipleTextColors Whether the text contains multiple colors. - * @param[in] containsColorGlyph Whether the text contains color glyph. - * @param[in] styleEnabled Whether the text contains any styles (e.g. shadow, underline, etc.). + * @param[in] featureBuilder Collection of current text shader's features. It will be cached as text visual. */ - Shader GetTextShader(VisualFactoryCache& factoryCache, bool hasMultipleTextColors, bool containsColorGlyph, bool styleEnabled); + Shader GetTextShader(VisualFactoryCache& factoryCache, const TextVisualShaderFeature::FeatureBuilder& featureBuilder); /** * @brief Retrieve the TextVisual object. @@ -328,32 +321,20 @@ private: private: typedef std::vector RendererContainer; - /** - * Used as an alternative to boolean so that it is obvious whether the text contains single or multiple text colors, and emoji and styles. - */ - struct TextType - { - enum Type - { - SINGLE_COLOR_TEXT = 0, ///< The text contains single color only. - MULTI_COLOR_TEXT = 1, ///< The text contains multiple colors. - NO_EMOJI = 0, ///< The text contains no emoji. - HAS_EMOJI = 1, ///< The text contains emoji. - NO_STYLES = 0, ///< The text contains contains no styles. - HAS_SYLES = 1 ///< The text contains contains styles. - }; - }; - private: - Text::ControllerPtr mController; ///< The text's controller. - Text::TypesetterPtr mTypesetter; ///< The text's typesetter. - WeakHandle mControl; ///< The control where the renderer is added. - Constraint mColorConstraint{}; ///< Color constraint - Constraint mOpacityConstraint{}; ///< Opacity constraint - Property::Index mAnimatableTextColorPropertyIndex; ///< The index of animatable text color property registered by the control. - Property::Index mTextColorAnimatableIndex; ///< The index of uTextColorAnimatable property. - bool mRendererUpdateNeeded : 1; ///< The flag to indicate whether the renderer needs to be updated. - RendererContainer mRendererList; + Text::ControllerPtr mController; ///< The text's controller. + Text::TypesetterPtr mTypesetter; ///< The text's typesetter. + + TextVisualShaderFactory& mTextVisualShaderFactory; ///< The shader factory for text visual. + TextVisualShaderFeature::FeatureBuilder mTextShaderFeatureCache; ///< The cached shader feature for text visual. + + WeakHandle mControl; ///< The control where the renderer is added. + Constraint mColorConstraint{}; ///< Color constraint + Constraint mOpacityConstraint{}; ///< Opacity constraint + Property::Index mAnimatableTextColorPropertyIndex; ///< The index of animatable text color property registered by the control. + Property::Index mTextColorAnimatableIndex; ///< The index of uTextColorAnimatable property. + bool mRendererUpdateNeeded : 1; ///< The flag to indicate whether the renderer needs to be updated. + RendererContainer mRendererList; }; } // namespace Internal diff --git a/dali-toolkit/internal/visuals/visual-factory-cache.h b/dali-toolkit/internal/visuals/visual-factory-cache.h index 6d9f28c..0edda01 100644 --- a/dali-toolkit/internal/visuals/visual-factory-cache.h +++ b/dali-toolkit/internal/visuals/visual-factory-cache.h @@ -104,12 +104,18 @@ public: NATIVE_IMAGE_SHADER_ROUNDED_BORDERLINE_MASKING, NINE_PATCH_SHADER, NINE_PATCH_MASK_SHADER, - TEXT_SHADER_MULTI_COLOR_TEXT, - TEXT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE, TEXT_SHADER_SINGLE_COLOR_TEXT, TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE, + TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_OVERLAY, + TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_OVERLAY, TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_EMOJI, TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI, + TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_OVERLAY_AND_EMOJI, + TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_OVERLAY_AND_EMOJI, + TEXT_SHADER_MULTI_COLOR_TEXT, + TEXT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE, + TEXT_SHADER_MULTI_COLOR_TEXT_WITH_OVERLAY, + TEXT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE_AND_OVERLAY, ANIMATED_GRADIENT_SHADER_LINEAR_BOUNDING_REFLECT, ANIMATED_GRADIENT_SHADER_LINEAR_BOUNDING_REPEAT, ANIMATED_GRADIENT_SHADER_LINEAR_BOUNDING_CLAMP, diff --git a/dali-toolkit/internal/visuals/visual-factory-impl.cpp b/dali-toolkit/internal/visuals/visual-factory-impl.cpp index a4b0a0a..57290a1 100644 --- a/dali-toolkit/internal/visuals/visual-factory-impl.cpp +++ b/dali-toolkit/internal/visuals/visual-factory-impl.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -77,6 +78,7 @@ const char* const BROKEN_IMAGE_FILE_NAME = "broken.png"; ///< The file name of t VisualFactory::VisualFactory(bool debugEnabled) : mFactoryCache(), mImageVisualShaderFactory(), + mTextVisualShaderFactory(), mSlotDelegate(this), mDebugEnabled(debugEnabled), mPreMultiplyOnLoad(true) @@ -207,7 +209,7 @@ Toolkit::Visual::Base VisualFactory::CreateVisual(const Property::Map& propertyM case Toolkit::Visual::TEXT: { - visualPtr = TextVisual::New(GetFactoryCache(), propertyMap); + visualPtr = TextVisual::New(GetFactoryCache(), GetTextVisualShaderFactory(), propertyMap); break; } @@ -426,6 +428,15 @@ ImageVisualShaderFactory& VisualFactory::GetImageVisualShaderFactory() return *mImageVisualShaderFactory; } +TextVisualShaderFactory& VisualFactory::GetTextVisualShaderFactory() +{ + if(!mTextVisualShaderFactory) + { + mTextVisualShaderFactory = std::unique_ptr(new TextVisualShaderFactory()); + } + return *mTextVisualShaderFactory; +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/visuals/visual-factory-impl.h b/dali-toolkit/internal/visuals/visual-factory-impl.h index a5ecda8..616b8d0 100644 --- a/dali-toolkit/internal/visuals/visual-factory-impl.h +++ b/dali-toolkit/internal/visuals/visual-factory-impl.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_VISUAL_FACTORY_IMPL_H /* - * 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. @@ -35,6 +35,7 @@ namespace Internal { class VisualFactoryCache; class ImageVisualShaderFactory; +class TextVisualShaderFactory; /** * @copydoc Toolkit::VisualFactory @@ -112,6 +113,11 @@ private: */ ImageVisualShaderFactory& GetImageVisualShaderFactory(); + /** + * Get the text visual shader factory, creating it if necessary. + */ + TextVisualShaderFactory& GetTextVisualShaderFactory(); + VisualFactory(const VisualFactory&) = delete; VisualFactory& operator=(const VisualFactory& rhs) = delete; @@ -119,6 +125,7 @@ private: private: std::unique_ptr mFactoryCache; std::unique_ptr mImageVisualShaderFactory; + std::unique_ptr mTextVisualShaderFactory; SlotDelegate mSlotDelegate; bool mDebugEnabled : 1; bool mPreMultiplyOnLoad : 1; ///< Local store for this flag -- 2.7.4