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