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 mMaxTextureSamples(0),
70 mVertexShaderPrefix(""),
71 mGlesVersion(INITIAL_GLES_VERSION),
72 mShadingLanguageVersion(100),
73 mShadingLanguageVersionCached(false),
74 mIsSurfacelessContextSupported(false),
75 mIsContextCreated(false)
77 mImpl.reset(new Gles3Implementation());
80 void GlImplementation::ContextCreated()
82 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
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)
88 GLint majorVersion, minorVersion;
89 glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
90 glGetIntegerv(GL_MINOR_VERSION, &minorVersion);
91 mGlesVersion = majorVersion * 10 + minorVersion;
94 if(mGlesVersion >= GLES_VERSION_SUPPORT_BLEND_EQUATION_ADVANCED)
96 SetIsAdvancedBlendEquationSupported(true);
99 if(mGlExtensionSupportedCacheList.NeedFullCheck())
101 // fully check gl extensions if we miss some extension supported
102 mGlExtensionSupportedCacheList.EnsureGlExtensionSupportedCheck();
105 if(IsMultisampledRenderToTextureSupported())
107 mMaxTextureSamples = 0;
109 if(mGlesVersion >= MINIMUM_GLES_VERSION_GET_MAXIMUM_MULTISAMPLES_TO_TEXTURE)
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);
115 if(mMaxTextureSamples == 0)
117 glGetIntegerv(GL_MAX_SAMPLES_EXT, &mMaxTextureSamples);
121 if(!mShadingLanguageVersionCached)
123 std::istringstream shadingLanguageVersionStream(reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION)));
125 uint32_t tokenCount = 0;
126 while(std::getline(shadingLanguageVersionStream, token, ' '))
128 if(tokenCount == 3 && token == "ES")
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());
141 mLogThreshold = GetPerformanceLogThresholdTime();
142 mLogEnabled = mLogThreshold > 0 ? true : false;
145 ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
146 mIsContextCreated = true;
147 mContextCreatedWaitCondition.Notify(lock);
151 std::string GlImplementation::GetFragmentShaderPrefix()
153 if(mFragmentShaderPrefix == "")
155 mFragmentShaderPrefix = GetShaderVersionPrefix();
157 if(GetShadingLanguageVersion() < 300)
159 mFragmentShaderPrefix += "#define INPUT varying\n";
160 mFragmentShaderPrefix += "#define OUT_COLOR gl_FragColor\n";
161 mFragmentShaderPrefix += "#define TEXTURE texture2D\n";
165 mFragmentShaderPrefix += "#define INPUT in\n";
166 mFragmentShaderPrefix += "#define OUT_COLOR fragColor\n";
167 mFragmentShaderPrefix += "#define TEXTURE texture\n";
169 if(IsAdvancedBlendEquationSupported())
171 mFragmentShaderPrefix += FRAGMENT_SHADER_ADVANCED_BLEND_EQUATION_PREFIX;
174 mFragmentShaderPrefix += FRAGMENT_SHADER_OUTPUT_COLOR_STRING;
177 return mFragmentShaderPrefix;
180 bool GlImplementation::ApplyNativeFragmentShader(std::string& shader, const char* customSamplerType)
182 bool modified = false;
183 std::string versionString = "#version";
184 size_t versionPosition = shader.find(versionString);
185 if(versionPosition != std::string::npos)
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)
192 extensionString = OES_EGL_IMAGE_EXTERNAL_STRING;
196 extensionString = OES_EGL_IMAGE_EXTERNAL_STRING_ESSL3;
199 if(shader.find(extensionString) == std::string::npos)
202 size_t extensionPosition = shader.find_first_of("\n", versionPosition) + 1;
203 shader.insert(extensionPosition, extensionString);
208 if(shader.find(OES_EGL_IMAGE_EXTERNAL_STRING) == std::string::npos)
211 shader = OES_EGL_IMAGE_EXTERNAL_STRING + shader;
215 if(shader.find(customSamplerType) == std::string::npos)
217 size_t pos = shader.find(DEFAULT_SAMPLER_TYPE);
218 if(pos != std::string::npos)
221 shader.replace(pos, strlen(DEFAULT_SAMPLER_TYPE), customSamplerType);
228 } // namespace Adaptor
230 } // namespace Internal