[Tizen] Fix build warning
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / gles / gl-implementation.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
18 // CLASS HEADER
19 #include <dali/internal/graphics/gles/gl-implementation.h>
20
21 namespace Dali
22 {
23 namespace Internal
24 {
25 namespace Adaptor
26 {
27 namespace
28 {
29 static constexpr int32_t INITIAL_GLES_VERSION                         = 30;
30 static constexpr int32_t GLES_VERSION_SUPPORT_BLEND_EQUATION_ADVANCED = 32;
31
32 static constexpr int32_t MINIMUM_GLES_VERSION_GET_MAXIMUM_MULTISAMPLES_TO_TEXTURE = 30;
33
34 static constexpr const char* LEGACY_SHADING_LANGUAGE_VERSION = "100";
35
36 static constexpr const char* DEFAULT_SAMPLER_TYPE = "sampler2D";
37
38 static constexpr const char* FRAGMENT_SHADER_ADVANCED_BLEND_EQUATION_PREFIX =
39   "#ifdef GL_KHR_blend_equation_advanced\n"
40   "#extension GL_KHR_blend_equation_advanced : enable\n"
41   "#endif\n"
42
43   "#if defined(GL_KHR_blend_equation_advanced) || __VERSION__>=320\n"
44   "  layout(blend_support_all_equations) out;\n"
45   "#endif\n";
46
47 static constexpr const char* FRAGMENT_SHADER_OUTPUT_COLOR_STRING =
48   "out mediump vec4 fragColor;\n";
49
50 static constexpr const char* OES_EGL_IMAGE_EXTERNAL_STRING = "#extension GL_OES_EGL_image_external:require\n";
51
52 static constexpr const char* OES_EGL_IMAGE_EXTERNAL_STRING_ESSL3 = "#extension GL_OES_EGL_image_external_essl3:require\n";
53
54 // Threshold time in miliseconds
55 constexpr auto PERFORMANCE_LOG_THRESHOLD_TIME_ENV = "DALI_EGL_PERFORMANCE_LOG_THRESHOLD_TIME";
56
57 static uint32_t GetPerformanceLogThresholdTime()
58 {
59   auto     timeString = Dali::EnvironmentVariable::GetEnvironmentVariable(PERFORMANCE_LOG_THRESHOLD_TIME_ENV);
60   uint32_t time       = timeString ? static_cast<uint32_t>(std::atoi(timeString)) : 0u;
61   return time;
62 }
63 } // namespace
64
65 GlImplementation::GlImplementation()
66 : mGlExtensionSupportedCacheList(),
67   mContextCreatedWaitCondition(),
68   mMaxTextureSize(0),
69   mMaxTextureSamples(0),
70   mVertexShaderPrefix(""),
71   mGlesVersion(INITIAL_GLES_VERSION),
72   mShadingLanguageVersion(100),
73   mShadingLanguageVersionCached(false),
74   mIsSurfacelessContextSupported(false),
75   mIsContextCreated(false)
76 {
77   mImpl.reset(new Gles3Implementation());
78 }
79
80 void GlImplementation::ContextCreated()
81 {
82   glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
83
84   // Since gles 2.0 didn't return well for GL_MAJOR_VERSION and GL_MINOR_VERSION,
85   // Only change gles version for the device that support above gles 3.0.
86   if(mGlesVersion >= INITIAL_GLES_VERSION)
87   {
88     GLint majorVersion, minorVersion;
89     glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
90     glGetIntegerv(GL_MINOR_VERSION, &minorVersion);
91     mGlesVersion = majorVersion * 10 + minorVersion;
92   }
93
94   if(mGlesVersion >= GLES_VERSION_SUPPORT_BLEND_EQUATION_ADVANCED)
95   {
96     SetIsAdvancedBlendEquationSupported(true);
97   }
98
99   if(mGlExtensionSupportedCacheList.NeedFullCheck())
100   {
101     // fully check gl extensions if we miss some extension supported
102     mGlExtensionSupportedCacheList.EnsureGlExtensionSupportedCheck();
103   }
104
105   if(IsMultisampledRenderToTextureSupported())
106   {
107     mMaxTextureSamples = 0;
108
109     if(mGlesVersion >= MINIMUM_GLES_VERSION_GET_MAXIMUM_MULTISAMPLES_TO_TEXTURE)
110     {
111       // Try to get maximum FBO MSAA sampling level from GL_RENDERBUFFER first.
112       // If false, than ask again to GL_MAX_SAMPLES_EXT.
113       GetInternalformativ(GL_RENDERBUFFER, GL_RGBA8, GL_SAMPLES, 1, &mMaxTextureSamples);
114     }
115     if(mMaxTextureSamples == 0)
116     {
117       glGetIntegerv(GL_MAX_SAMPLES_EXT, &mMaxTextureSamples);
118     }
119   }
120
121   if(!mShadingLanguageVersionCached)
122   {
123     std::istringstream shadingLanguageVersionStream(reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION)));
124     std::string        token;
125     uint32_t           tokenCount = 0;
126     while(std::getline(shadingLanguageVersionStream, token, ' '))
127     {
128       if(tokenCount == 3 && token == "ES")
129       {
130         std::getline(shadingLanguageVersionStream, token, '.');
131         mShadingLanguageVersion = std::atoi(token.c_str());
132         mShadingLanguageVersion *= 100;
133         std::getline(shadingLanguageVersionStream, token, '.');
134         mShadingLanguageVersion += std::atoi(token.c_str());
135         break;
136       }
137       tokenCount++;
138     }
139   }
140
141   mLogThreshold = GetPerformanceLogThresholdTime();
142   mLogEnabled   = mLogThreshold > 0 ? true : false;
143
144   {
145     ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
146     mIsContextCreated = true;
147     mContextCreatedWaitCondition.Notify(lock);
148   }
149 }
150
151 std::string GlImplementation::GetFragmentShaderPrefix()
152 {
153   if(mFragmentShaderPrefix == "")
154   {
155     mFragmentShaderPrefix = GetShaderVersionPrefix();
156
157     if(GetShadingLanguageVersion() < 300)
158     {
159       mFragmentShaderPrefix += "#define INPUT varying\n";
160       mFragmentShaderPrefix += "#define OUT_COLOR gl_FragColor\n";
161       mFragmentShaderPrefix += "#define TEXTURE texture2D\n";
162     }
163     else
164     {
165       mFragmentShaderPrefix += "#define INPUT in\n";
166       mFragmentShaderPrefix += "#define OUT_COLOR fragColor\n";
167       mFragmentShaderPrefix += "#define TEXTURE texture\n";
168
169       if(IsAdvancedBlendEquationSupported())
170       {
171         mFragmentShaderPrefix += FRAGMENT_SHADER_ADVANCED_BLEND_EQUATION_PREFIX;
172       }
173
174       mFragmentShaderPrefix += FRAGMENT_SHADER_OUTPUT_COLOR_STRING;
175     }
176   }
177   return mFragmentShaderPrefix;
178 }
179
180 bool GlImplementation::ApplyNativeFragmentShader(std::string& shader, const char* customSamplerType)
181 {
182   bool        modified        = false;
183   std::string versionString   = "#version";
184   size_t      versionPosition = shader.find(versionString);
185   if(versionPosition != std::string::npos)
186   {
187     std::string extensionString;
188     size_t      shadingLanguageVersionPosition = shader.find_first_not_of(" \t", versionPosition + versionString.length());
189     if(shadingLanguageVersionPosition != std::string::npos &&
190        shader.substr(shadingLanguageVersionPosition, 3) == LEGACY_SHADING_LANGUAGE_VERSION)
191     {
192       extensionString = OES_EGL_IMAGE_EXTERNAL_STRING;
193     }
194     else
195     {
196       extensionString = OES_EGL_IMAGE_EXTERNAL_STRING_ESSL3;
197     }
198
199     if(shader.find(extensionString) == std::string::npos)
200     {
201       modified                 = true;
202       size_t extensionPosition = shader.find_first_of("\n", versionPosition) + 1;
203       shader.insert(extensionPosition, extensionString);
204     }
205   }
206   else
207   {
208     if(shader.find(OES_EGL_IMAGE_EXTERNAL_STRING) == std::string::npos)
209     {
210       modified = true;
211       shader   = OES_EGL_IMAGE_EXTERNAL_STRING + shader;
212     }
213   }
214
215   if(shader.find(customSamplerType) == std::string::npos)
216   {
217     size_t pos = shader.find(DEFAULT_SAMPLER_TYPE);
218     if(pos != std::string::npos)
219     {
220       modified = true;
221       shader.replace(pos, strlen(DEFAULT_SAMPLER_TYPE), customSamplerType);
222     }
223   }
224
225   return modified;
226 }
227
228 } // namespace Adaptor
229
230 } // namespace Internal
231
232 } // namespace Dali