Supports to set/get full screen sized window
[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   mMaxCombinedTextureUnits(0),
70   mMaxTextureSamples(0),
71   mVertexShaderPrefix(""),
72   mGlesVersion(INITIAL_GLES_VERSION),
73   mShadingLanguageVersion(100),
74   mShadingLanguageVersionCached(false),
75   mIsSurfacelessContextSupported(false),
76   mIsContextCreated(false)
77 {
78   mImpl.reset(new Gles3Implementation());
79 }
80
81 void GlImplementation::ContextCreated()
82 {
83   glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
84   glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextureUnits);
85
86   // Since gles 2.0 didn't return well for GL_MAJOR_VERSION and GL_MINOR_VERSION,
87   // Only change gles version for the device that support above gles 3.0.
88   if(mGlesVersion >= INITIAL_GLES_VERSION)
89   {
90     GLint majorVersion, minorVersion;
91     glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
92     glGetIntegerv(GL_MINOR_VERSION, &minorVersion);
93     mGlesVersion = majorVersion * 10 + minorVersion;
94   }
95
96   if(mGlesVersion >= GLES_VERSION_SUPPORT_BLEND_EQUATION_ADVANCED)
97   {
98     SetIsAdvancedBlendEquationSupported(true);
99   }
100
101   if(mGlExtensionSupportedCacheList.NeedFullCheck())
102   {
103     // fully check gl extensions if we miss some extension supported
104     mGlExtensionSupportedCacheList.EnsureGlExtensionSupportedCheck();
105   }
106
107   if(IsMultisampledRenderToTextureSupported())
108   {
109     mMaxTextureSamples = 0;
110
111     if(mGlesVersion >= MINIMUM_GLES_VERSION_GET_MAXIMUM_MULTISAMPLES_TO_TEXTURE)
112     {
113       // Try to get maximum FBO MSAA sampling level from GL_RENDERBUFFER first.
114       // If false, than ask again to GL_MAX_SAMPLES_EXT.
115       GetInternalformativ(GL_RENDERBUFFER, GL_RGBA8, GL_SAMPLES, 1, &mMaxTextureSamples);
116     }
117     if(mMaxTextureSamples == 0)
118     {
119       glGetIntegerv(GL_MAX_SAMPLES_EXT, &mMaxTextureSamples);
120     }
121   }
122
123   if(!mShadingLanguageVersionCached)
124   {
125     std::istringstream shadingLanguageVersionStream(reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION)));
126     std::string        token;
127     uint32_t           tokenCount = 0;
128     while(std::getline(shadingLanguageVersionStream, token, ' '))
129     {
130       if(tokenCount == 3 && token == "ES")
131       {
132         std::getline(shadingLanguageVersionStream, token, '.');
133         mShadingLanguageVersion = std::atoi(token.c_str());
134         mShadingLanguageVersion *= 100;
135         std::getline(shadingLanguageVersionStream, token, '.');
136         mShadingLanguageVersion += std::atoi(token.c_str());
137         break;
138       }
139       tokenCount++;
140     }
141   }
142
143   mLogThreshold = GetPerformanceLogThresholdTime();
144   mLogEnabled   = mLogThreshold > 0 ? true : false;
145
146   {
147     ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
148     mIsContextCreated = true;
149     mContextCreatedWaitCondition.Notify(lock);
150   }
151 }
152
153 std::string GlImplementation::GetFragmentShaderPrefix()
154 {
155   if(mFragmentShaderPrefix == "")
156   {
157     mFragmentShaderPrefix = GetShaderVersionPrefix();
158
159     if(GetShadingLanguageVersion() < 300)
160     {
161       mFragmentShaderPrefix += "#define INPUT varying\n";
162       mFragmentShaderPrefix += "#define OUT_COLOR gl_FragColor\n";
163       mFragmentShaderPrefix += "#define TEXTURE texture2D\n";
164     }
165     else
166     {
167       mFragmentShaderPrefix += "#define INPUT in\n";
168       mFragmentShaderPrefix += "#define OUT_COLOR fragColor\n";
169       mFragmentShaderPrefix += "#define TEXTURE texture\n";
170
171       if(IsAdvancedBlendEquationSupported())
172       {
173         mFragmentShaderPrefix += FRAGMENT_SHADER_ADVANCED_BLEND_EQUATION_PREFIX;
174       }
175
176       mFragmentShaderPrefix += FRAGMENT_SHADER_OUTPUT_COLOR_STRING;
177     }
178   }
179   return mFragmentShaderPrefix;
180 }
181
182 bool GlImplementation::ApplyNativeFragmentShader(std::string& shader, const char* customSamplerType)
183 {
184   bool        modified        = false;
185   std::string versionString   = "#version";
186   size_t      versionPosition = shader.find(versionString);
187   if(versionPosition != std::string::npos)
188   {
189     std::string extensionString;
190     size_t      shadingLanguageVersionPosition = shader.find_first_not_of(" \t", versionPosition + versionString.length());
191     if(shadingLanguageVersionPosition != std::string::npos &&
192        shader.substr(shadingLanguageVersionPosition, 3) == LEGACY_SHADING_LANGUAGE_VERSION)
193     {
194       extensionString = OES_EGL_IMAGE_EXTERNAL_STRING;
195     }
196     else
197     {
198       extensionString = OES_EGL_IMAGE_EXTERNAL_STRING_ESSL3;
199     }
200
201     if(shader.find(extensionString) == std::string::npos)
202     {
203       modified                 = true;
204       size_t extensionPosition = shader.find_first_of("\n", versionPosition) + 1;
205       shader.insert(extensionPosition, extensionString);
206     }
207   }
208   else
209   {
210     if(shader.find(OES_EGL_IMAGE_EXTERNAL_STRING) == std::string::npos)
211     {
212       modified = true;
213       shader   = OES_EGL_IMAGE_EXTERNAL_STRING + shader;
214     }
215   }
216
217   if(shader.find(customSamplerType) == std::string::npos)
218   {
219     size_t pos = shader.find(DEFAULT_SAMPLER_TYPE);
220     if(pos != std::string::npos)
221     {
222       modified = true;
223       shader.replace(pos, strlen(DEFAULT_SAMPLER_TYPE), customSamplerType);
224     }
225   }
226
227   return modified;
228 }
229
230 } // namespace Adaptor
231
232 } // namespace Internal
233
234 } // namespace Dali