[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / text-visual-shader-factory.cpp
1 /*
2  * Copyright (c) 2024 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 // CLASS HEADER
18 #include <dali-toolkit/internal/visuals/text-visual-shader-factory.h>
19
20 // INTERNAL INCLUDES
21 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
22 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
23 #include <dali/integration-api/debug.h>
24
25 namespace Dali
26 {
27 namespace Toolkit
28 {
29 namespace Internal
30 {
31 namespace
32 {
33 // enum of required list when we select shader
34 enum class TextVisualRequireFlag : uint32_t
35 {
36   DEFAULT     = 0,
37   STYLES      = 1 << 0,
38   OVERLAY     = 1 << 1,
39   EMOJI       = 1 << 2,
40   MULTI_COLOR = 1 << 3,
41 };
42
43 const VisualFactoryCache::ShaderType SHADER_TYPE_TABLE[] =
44   {
45     VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT,
46     VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE,
47     VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_OVERLAY,
48     VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_OVERLAY,
49     VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_EMOJI,
50     VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI,
51     VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_OVERLAY_AND_EMOJI,
52     VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_OVERLAY_AND_EMOJI,
53     VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT,
54     VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE,
55     VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT_WITH_OVERLAY,
56     VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE_AND_OVERLAY,
57 };
58
59 static constexpr auto      SHADER_TYPE_COUNT = 1u;
60 constexpr std::string_view VertexPredefines[SHADER_TYPE_COUNT]{
61   "", // VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT
62 };
63 constexpr std::string_view FragmentPredefines[SHADER_TYPE_COUNT]{
64   "", // VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT
65 };
66 constexpr VisualFactoryCache::ShaderType ShaderTypePredefines[SHADER_TYPE_COUNT]{
67   VisualFactoryCache::ShaderType::TEXT_SHADER_SINGLE_COLOR_TEXT,
68 };
69
70 } // unnamed namespace
71
72 namespace TextVisualShaderFeature
73 {
74 FeatureBuilder& FeatureBuilder::EnableMultiColor(bool enableMultiColor)
75 {
76   mTextMultiColor = enableMultiColor ? TextMultiColor::MULTI_COLOR_TEXT : TextMultiColor::SINGLE_COLOR_TEXT;
77   return *this;
78 }
79 FeatureBuilder& FeatureBuilder::EnableEmoji(bool enableEmoji)
80 {
81   mTextEmoji = enableEmoji ? TextEmoji::HAS_EMOJI : TextEmoji::NO_EMOJI;
82   return *this;
83 }
84 FeatureBuilder& FeatureBuilder::EnableStyle(bool enableStyle)
85 {
86   mTextStyle = enableStyle ? TextStyle::HAS_STYLES : TextStyle::NO_STYLES;
87   return *this;
88 }
89 FeatureBuilder& FeatureBuilder::EnableOverlay(bool enableOverlay)
90 {
91   mTextOverlay = enableOverlay ? TextOverlay::HAS_OVERLAY : TextOverlay::NO_OVERLAY;
92   return *this;
93 }
94 } // namespace TextVisualShaderFeature
95
96 TextVisualShaderFactory::TextVisualShaderFactory()
97 {
98 }
99
100 TextVisualShaderFactory::~TextVisualShaderFactory()
101 {
102 }
103
104 Shader TextVisualShaderFactory::GetShader(VisualFactoryCache& factoryCache, const TextVisualShaderFeature::FeatureBuilder& featureBuilder)
105 {
106   Shader                         shader;
107   uint32_t                       shaderTypeFlag = static_cast<uint32_t>(TextVisualRequireFlag::DEFAULT);
108   VisualFactoryCache::ShaderType shaderType     = VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT;
109
110   const auto& multiColor = featureBuilder.mTextMultiColor;
111   const auto& emoji      = featureBuilder.mTextEmoji;
112   const auto& style      = featureBuilder.mTextStyle;
113   const auto& overlay    = featureBuilder.mTextOverlay;
114
115   if(style == TextVisualShaderFeature::TextStyle::HAS_STYLES)
116   {
117     shaderTypeFlag |= static_cast<uint32_t>(TextVisualRequireFlag::STYLES);
118   }
119   if(overlay == TextVisualShaderFeature::TextOverlay::HAS_OVERLAY)
120   {
121     shaderTypeFlag |= static_cast<uint32_t>(TextVisualRequireFlag::OVERLAY);
122   }
123   // multi color can also render emoji. If multi color text, dont consider emoji
124   if(multiColor != TextVisualShaderFeature::TextMultiColor::MULTI_COLOR_TEXT && emoji == TextVisualShaderFeature::TextEmoji::HAS_EMOJI)
125   {
126     shaderTypeFlag |= static_cast<uint32_t>(TextVisualRequireFlag::EMOJI);
127   }
128   if(multiColor == TextVisualShaderFeature::TextMultiColor::MULTI_COLOR_TEXT)
129   {
130     shaderTypeFlag |= static_cast<uint32_t>(TextVisualRequireFlag::MULTI_COLOR);
131   }
132
133   shaderType = SHADER_TYPE_TABLE[shaderTypeFlag];
134   shader     = factoryCache.GetShader(shaderType);
135
136   if(!shader)
137   {
138     std::string vertexShaderPrefixList;
139     std::string fragmentShaderPrefixList;
140
141     if(style == TextVisualShaderFeature::TextStyle::HAS_STYLES)
142     {
143       fragmentShaderPrefixList += "#define IS_REQUIRED_STYLE\n";
144     }
145     if(overlay == TextVisualShaderFeature::TextOverlay::HAS_OVERLAY)
146     {
147       fragmentShaderPrefixList += "#define IS_REQUIRED_OVERLAY\n";
148     }
149     // multi color can also render emoji. If multi color text, dont consider emoji
150     if(multiColor != TextVisualShaderFeature::TextMultiColor::MULTI_COLOR_TEXT && emoji == TextVisualShaderFeature::TextEmoji::HAS_EMOJI)
151     {
152       fragmentShaderPrefixList += "#define IS_REQUIRED_EMOJI\n";
153     }
154     if(multiColor == TextVisualShaderFeature::TextMultiColor::MULTI_COLOR_TEXT)
155     {
156       fragmentShaderPrefixList += "#define IS_REQUIRED_MULTI_COLOR\n";
157     }
158
159     std::string vertexShader   = std::string(Dali::Shader::GetVertexShaderPrefix() + vertexShaderPrefixList + SHADER_TEXT_VISUAL_SHADER_VERT.data());
160     std::string fragmentShader = std::string(Dali::Shader::GetFragmentShaderPrefix() + fragmentShaderPrefixList + SHADER_TEXT_VISUAL_SHADER_FRAG.data());
161
162     shader = factoryCache.GenerateAndSaveShader(shaderType, vertexShader, fragmentShader);
163   }
164   return shader;
165 }
166
167 void TextVisualShaderFactory::GetPreCompiledShader(RawShaderData& shaders)
168 {
169   std::vector<std::string_view> vertexPrefix;
170   std::vector<std::string_view> fragmentPrefix;
171   std::vector<std::string_view> shaderName;
172   int                           shaderCount = 0;
173   for(uint32_t i = 0; i < SHADER_TYPE_COUNT; ++i)
174   {
175     vertexPrefix.push_back(VertexPredefines[i]);
176     fragmentPrefix.push_back(FragmentPredefines[i]);
177     shaderName.push_back(Scripting::GetLinearEnumerationName<VisualFactoryCache::ShaderType>(ShaderTypePredefines[i], VISUAL_SHADER_TYPE_TABLE, VISUAL_SHADER_TYPE_TABLE_COUNT));
178     shaderCount++;
179   }
180
181   shaders.vertexPrefix   = vertexPrefix;
182   shaders.fragmentPrefix = fragmentPrefix;
183   shaders.shaderName     = shaderName;
184   shaders.vertexShader   = SHADER_TEXT_VISUAL_SHADER_VERT;
185   shaders.fragmentShader = SHADER_TEXT_VISUAL_SHADER_FRAG;
186   shaders.shaderCount    = shaderCount;
187 }
188
189 } // namespace Internal
190
191 } // namespace Toolkit
192
193 } // namespace Dali