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>
32 static constexpr int32_t INITIAL_GLES_VERSION = 30;
33 static constexpr int32_t GLES_VERSION_SUPPORT_BLEND_EQUATION_ADVANCED = 32;
35 static constexpr int32_t MINIMUM_GLES_VERSION_GET_MAXIMUM_MULTISAMPLES_TO_TEXTURE = 30;
37 static constexpr const char* LEGACY_SHADING_LANGUAGE_VERSION = "100";
39 static constexpr const char* DEFAULT_SAMPLER_TYPE = "sampler2D";
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"
46 "#if defined(GL_KHR_blend_equation_advanced) || __VERSION__>=320\n"
47 " layout(blend_support_all_equations) out;\n"
50 static constexpr const char* FRAGMENT_SHADER_OUTPUT_COLOR_STRING =
51 "out mediump vec4 fragColor;\n";
53 static constexpr const char* OES_EGL_IMAGE_EXTERNAL_STRING = "#extension GL_OES_EGL_image_external:require\n";
55 static constexpr const char* OES_EGL_IMAGE_EXTERNAL_STRING_ESSL3 = "#extension GL_OES_EGL_image_external_essl3:require\n";
57 // Threshold time in miliseconds
58 constexpr auto PERFORMANCE_LOG_THRESHOLD_TIME_ENV = "DALI_EGL_PERFORMANCE_LOG_THRESHOLD_TIME";
60 static uint32_t GetPerformanceLogThresholdTime()
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();
68 GlImplementation::GlImplementation()
69 : mGlExtensionSupportedCacheList(),
70 mContextCreatedWaitCondition(),
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)
81 mImpl.reset(new Gles3Implementation());
84 void GlImplementation::ContextCreated()
86 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
87 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextureUnits);
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)
93 GLint majorVersion, minorVersion;
94 glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
95 glGetIntegerv(GL_MINOR_VERSION, &minorVersion);
96 mGlesVersion = majorVersion * 10 + minorVersion;
99 if(mGlesVersion >= GLES_VERSION_SUPPORT_BLEND_EQUATION_ADVANCED)
101 SetIsAdvancedBlendEquationSupported(true);
104 if(mGlExtensionSupportedCacheList.NeedFullCheck())
106 // fully check gl extensions if we miss some extension supported
107 mGlExtensionSupportedCacheList.EnsureGlExtensionSupportedCheck();
110 if(IsMultisampledRenderToTextureSupported())
112 mMaxTextureSamples = 0;
114 if(mGlesVersion >= MINIMUM_GLES_VERSION_GET_MAXIMUM_MULTISAMPLES_TO_TEXTURE)
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);
120 if(mMaxTextureSamples == 0)
122 glGetIntegerv(GL_MAX_SAMPLES_EXT, &mMaxTextureSamples);
126 if(!mShadingLanguageVersionCached)
128 std::istringstream shadingLanguageVersionStream(reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION)));
130 uint32_t tokenCount = 0;
131 while(std::getline(shadingLanguageVersionStream, token, ' '))
133 if(tokenCount == 3 && token == "ES")
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());
146 mLogThreshold = GetPerformanceLogThresholdTime();
147 mLogEnabled = mLogThreshold < std::numeric_limits<uint32_t>::max() ? true : false;
150 ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
151 mIsContextCreated = true;
152 mContextCreatedWaitCondition.Notify(lock);
156 std::string GlImplementation::GetFragmentShaderPrefix()
158 if(mFragmentShaderPrefix == "")
160 mFragmentShaderPrefix = GetShaderVersionPrefix();
162 if(GetShadingLanguageVersion() < 300)
164 mFragmentShaderPrefix += "#define INPUT varying\n";
165 mFragmentShaderPrefix += "#define OUT_COLOR gl_FragColor\n";
166 mFragmentShaderPrefix += "#define TEXTURE texture2D\n";
170 mFragmentShaderPrefix += "#define INPUT in\n";
171 mFragmentShaderPrefix += "#define OUT_COLOR fragColor\n";
172 mFragmentShaderPrefix += "#define TEXTURE texture\n";
174 if(IsAdvancedBlendEquationSupported())
176 mFragmentShaderPrefix += FRAGMENT_SHADER_ADVANCED_BLEND_EQUATION_PREFIX;
179 mFragmentShaderPrefix += FRAGMENT_SHADER_OUTPUT_COLOR_STRING;
182 return mFragmentShaderPrefix;
185 bool GlImplementation::ApplyNativeFragmentShader(std::string& shader, const char* customSamplerType)
187 bool modified = false;
188 std::string versionString = "#version";
189 size_t versionPosition = shader.find(versionString);
190 if(versionPosition != std::string::npos)
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)
197 extensionString = OES_EGL_IMAGE_EXTERNAL_STRING;
201 extensionString = OES_EGL_IMAGE_EXTERNAL_STRING_ESSL3;
204 if(shader.find(extensionString) == std::string::npos)
207 size_t extensionPosition = shader.find_first_of("\n", versionPosition) + 1;
208 shader.insert(extensionPosition, extensionString);
213 if(shader.find(OES_EGL_IMAGE_EXTERNAL_STRING) == std::string::npos)
216 shader = OES_EGL_IMAGE_EXTERNAL_STRING + shader;
220 if(shader.find(customSamplerType) == std::string::npos)
222 size_t pos = shader.find(DEFAULT_SAMPLER_TYPE);
223 if(pos != std::string::npos)
226 shader.replace(pos, strlen(DEFAULT_SAMPLER_TYPE), customSamplerType);
233 } // namespace Adaptor
235 } // namespace Internal