2 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/graphics/gles/gl-implementation.h>
29 static constexpr int32_t INITIAL_GLES_VERSION = 30;
30 static constexpr int32_t GLES_VERSION_SUPPORT_BLEND_EQUATION_ADVANCED = 32;
32 static constexpr int32_t MINIMUM_GLES_VERSION_GET_MAXIMUM_MULTISAMPLES_TO_TEXTURE = 30;
34 static constexpr const char* LEGACY_SHADING_LANGUAGE_VERSION = "100";
36 static constexpr const char* DEFAULT_SAMPLER_TYPE = "sampler2D";
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"
43 "#if defined(GL_KHR_blend_equation_advanced) || __VERSION__>=320\n"
44 " layout(blend_support_all_equations) out;\n"
47 static constexpr const char* FRAGMENT_SHADER_OUTPUT_COLOR_STRING =
48 "out mediump vec4 fragColor;\n";
50 static constexpr const char* OES_EGL_IMAGE_EXTERNAL_STRING = "#extension GL_OES_EGL_image_external:require\n";
52 static constexpr const char* OES_EGL_IMAGE_EXTERNAL_STRING_ESSL3 = "#extension GL_OES_EGL_image_external_essl3:require\n";
54 // Threshold time in miliseconds
55 constexpr auto PERFORMANCE_LOG_THRESHOLD_TIME_ENV = "DALI_EGL_PERFORMANCE_LOG_THRESHOLD_TIME";
57 static uint32_t GetPerformanceLogThresholdTime()
59 auto timeString = Dali::EnvironmentVariable::GetEnvironmentVariable(PERFORMANCE_LOG_THRESHOLD_TIME_ENV);
60 uint32_t time = timeString ? static_cast<uint32_t>(std::atoi(timeString)) : 0u;
65 GlImplementation::GlImplementation()
66 : mGlExtensionSupportedCacheList(),
67 mContextCreatedWaitCondition(),
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)
78 mImpl.reset(new Gles3Implementation());
81 void GlImplementation::ContextCreated()
83 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
84 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextureUnits);
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)
90 GLint majorVersion, minorVersion;
91 glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
92 glGetIntegerv(GL_MINOR_VERSION, &minorVersion);
93 mGlesVersion = majorVersion * 10 + minorVersion;
96 if(mGlesVersion >= GLES_VERSION_SUPPORT_BLEND_EQUATION_ADVANCED)
98 SetIsAdvancedBlendEquationSupported(true);
101 if(mGlExtensionSupportedCacheList.NeedFullCheck())
103 // fully check gl extensions if we miss some extension supported
104 mGlExtensionSupportedCacheList.EnsureGlExtensionSupportedCheck();
107 if(IsMultisampledRenderToTextureSupported())
109 mMaxTextureSamples = 0;
111 if(mGlesVersion >= MINIMUM_GLES_VERSION_GET_MAXIMUM_MULTISAMPLES_TO_TEXTURE)
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);
117 if(mMaxTextureSamples == 0)
119 glGetIntegerv(GL_MAX_SAMPLES_EXT, &mMaxTextureSamples);
123 if(!mShadingLanguageVersionCached)
125 std::istringstream shadingLanguageVersionStream(reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION)));
127 uint32_t tokenCount = 0;
128 while(std::getline(shadingLanguageVersionStream, token, ' '))
130 if(tokenCount == 3 && token == "ES")
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());
143 mLogThreshold = GetPerformanceLogThresholdTime();
144 mLogEnabled = mLogThreshold > 0 ? true : false;
147 ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
148 mIsContextCreated = true;
149 mContextCreatedWaitCondition.Notify(lock);
153 std::string GlImplementation::GetFragmentShaderPrefix()
155 if(mFragmentShaderPrefix == "")
157 mFragmentShaderPrefix = GetShaderVersionPrefix();
159 if(GetShadingLanguageVersion() < 300)
161 mFragmentShaderPrefix += "#define INPUT varying\n";
162 mFragmentShaderPrefix += "#define OUT_COLOR gl_FragColor\n";
163 mFragmentShaderPrefix += "#define TEXTURE texture2D\n";
167 mFragmentShaderPrefix += "#define INPUT in\n";
168 mFragmentShaderPrefix += "#define OUT_COLOR fragColor\n";
169 mFragmentShaderPrefix += "#define TEXTURE texture\n";
171 if(IsAdvancedBlendEquationSupported())
173 mFragmentShaderPrefix += FRAGMENT_SHADER_ADVANCED_BLEND_EQUATION_PREFIX;
176 mFragmentShaderPrefix += FRAGMENT_SHADER_OUTPUT_COLOR_STRING;
179 return mFragmentShaderPrefix;
182 bool GlImplementation::ApplyNativeFragmentShader(std::string& shader, const char* customSamplerType)
184 bool modified = false;
185 std::string versionString = "#version";
186 size_t versionPosition = shader.find(versionString);
187 if(versionPosition != std::string::npos)
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)
194 extensionString = OES_EGL_IMAGE_EXTERNAL_STRING;
198 extensionString = OES_EGL_IMAGE_EXTERNAL_STRING_ESSL3;
201 if(shader.find(extensionString) == std::string::npos)
204 size_t extensionPosition = shader.find_first_of("\n", versionPosition) + 1;
205 shader.insert(extensionPosition, extensionString);
210 if(shader.find(OES_EGL_IMAGE_EXTERNAL_STRING) == std::string::npos)
213 shader = OES_EGL_IMAGE_EXTERNAL_STRING + shader;
217 if(shader.find(customSamplerType) == std::string::npos)
219 size_t pos = shader.find(DEFAULT_SAMPLER_TYPE);
220 if(pos != std::string::npos)
223 shader.replace(pos, strlen(DEFAULT_SAMPLER_TYPE), customSamplerType);
230 } // namespace Adaptor
232 } // namespace Internal