[Tizen] Change precompile shader list for performance
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / text-visual-shader-factory.cpp
1 /*
2  * Copyright (c) 2023 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 const std::string_view VertexPredefines[SHADER_TYPE_COUNT]{
61   "", // VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT
62 };
63 const std::string_view FragmentPredefines[SHADER_TYPE_COUNT]{
64   "", // VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT
65 };
66
67 } // unnamed namespace
68
69 namespace TextVisualShaderFeature
70 {
71 FeatureBuilder& FeatureBuilder::EnableMultiColor(bool enableMultiColor)
72 {
73   mTextMultiColor = enableMultiColor ? TextMultiColor::MULTI_COLOR_TEXT : TextMultiColor::SINGLE_COLOR_TEXT;
74   return *this;
75 }
76 FeatureBuilder& FeatureBuilder::EnableEmoji(bool enableEmoji)
77 {
78   mTextEmoji = enableEmoji ? TextEmoji::HAS_EMOJI : TextEmoji::NO_EMOJI;
79   return *this;
80 }
81 FeatureBuilder& FeatureBuilder::EnableStyle(bool enableStyle)
82 {
83   mTextStyle = enableStyle ? TextStyle::HAS_STYLES : TextStyle::NO_STYLES;
84   return *this;
85 }
86 FeatureBuilder& FeatureBuilder::EnableOverlay(bool enableOverlay)
87 {
88   mTextOverlay = enableOverlay ? TextOverlay::HAS_OVERLAY : TextOverlay::NO_OVERLAY;
89   return *this;
90 }
91 } // namespace TextVisualShaderFeature
92
93 TextVisualShaderFactory::TextVisualShaderFactory()
94 {
95 }
96
97 TextVisualShaderFactory::~TextVisualShaderFactory()
98 {
99 }
100
101 Shader TextVisualShaderFactory::GetShader(VisualFactoryCache& factoryCache, const TextVisualShaderFeature::FeatureBuilder& featureBuilder)
102 {
103   Shader                         shader;
104   uint32_t                       shaderTypeFlag = static_cast<uint32_t>(TextVisualRequireFlag::DEFAULT);
105   VisualFactoryCache::ShaderType shaderType     = VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT;
106
107   const auto& multiColor = featureBuilder.mTextMultiColor;
108   const auto& emoji      = featureBuilder.mTextEmoji;
109   const auto& style      = featureBuilder.mTextStyle;
110   const auto& overlay    = featureBuilder.mTextOverlay;
111
112   if(style == TextVisualShaderFeature::TextStyle::HAS_STYLES)
113   {
114     shaderTypeFlag |= static_cast<uint32_t>(TextVisualRequireFlag::STYLES);
115   }
116   if(overlay == TextVisualShaderFeature::TextOverlay::HAS_OVERLAY)
117   {
118     shaderTypeFlag |= static_cast<uint32_t>(TextVisualRequireFlag::OVERLAY);
119   }
120   // multi color can also render emoji. If multi color text, dont consider emoji
121   if(multiColor != TextVisualShaderFeature::TextMultiColor::MULTI_COLOR_TEXT && emoji == TextVisualShaderFeature::TextEmoji::HAS_EMOJI)
122   {
123     shaderTypeFlag |= static_cast<uint32_t>(TextVisualRequireFlag::EMOJI);
124   }
125   if(multiColor == TextVisualShaderFeature::TextMultiColor::MULTI_COLOR_TEXT)
126   {
127     shaderTypeFlag |= static_cast<uint32_t>(TextVisualRequireFlag::MULTI_COLOR);
128   }
129
130   shaderType = SHADER_TYPE_TABLE[shaderTypeFlag];
131   shader     = factoryCache.GetShader(shaderType);
132
133   if(!shader)
134   {
135     std::string vertexShaderPrefixList;
136     std::string fragmentShaderPrefixList;
137
138     if(style == TextVisualShaderFeature::TextStyle::HAS_STYLES)
139     {
140       fragmentShaderPrefixList += "#define IS_REQUIRED_STYLE\n";
141     }
142     if(overlay == TextVisualShaderFeature::TextOverlay::HAS_OVERLAY)
143     {
144       fragmentShaderPrefixList += "#define IS_REQUIRED_OVERLAY\n";
145     }
146     // multi color can also render emoji. If multi color text, dont consider emoji
147     if(multiColor != TextVisualShaderFeature::TextMultiColor::MULTI_COLOR_TEXT && emoji == TextVisualShaderFeature::TextEmoji::HAS_EMOJI)
148     {
149       fragmentShaderPrefixList += "#define IS_REQUIRED_EMOJI\n";
150     }
151     if(multiColor == TextVisualShaderFeature::TextMultiColor::MULTI_COLOR_TEXT)
152     {
153       fragmentShaderPrefixList += "#define IS_REQUIRED_MULTI_COLOR\n";
154     }
155
156     std::string vertexShader   = std::string(Dali::Shader::GetVertexShaderPrefix() + vertexShaderPrefixList + SHADER_TEXT_VISUAL_SHADER_VERT.data());
157     std::string fragmentShader = std::string(Dali::Shader::GetFragmentShaderPrefix() + fragmentShaderPrefixList + SHADER_TEXT_VISUAL_SHADER_FRAG.data());
158
159     shader = Shader::New(vertexShader, fragmentShader);
160     factoryCache.SaveShader(shaderType, shader);
161   }
162   return shader;
163 }
164
165 void TextVisualShaderFactory::GetPrecompiledShader(RawShaderData& shaders)
166 {
167   std::vector<std::string_view> vertexPrefix;
168   std::vector<std::string_view> fragmentPrefix;
169   int                           shaderCount = 0;
170   for(int i = 0; i < SHADER_TYPE_COUNT; ++i)
171   {
172     vertexPrefix.push_back(VertexPredefines[i]);
173     fragmentPrefix.push_back(FragmentPredefines[i]);
174     shaderCount++;
175   }
176
177   shaders.vertexPrefix   = vertexPrefix;
178   shaders.fragmentPrefix = fragmentPrefix;
179   shaders.vertexShader   = SHADER_TEXT_VISUAL_SHADER_VERT;
180   shaders.fragmentShader = SHADER_TEXT_VISUAL_SHADER_FRAG;
181   shaders.shaderCount    = shaderCount;
182 }
183
184 } // namespace Internal
185
186 } // namespace Toolkit
187
188 } // namespace Dali