#define DALI_INTERNAL_GL_IMPLEMENTATION_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali/devel-api/threading/conditional-wait.h>
#include <dali/integration-api/gl-abstraction.h>
#include <dali/internal/graphics/common/egl-include.h>
+#include <dali/public-api/common/vector-wrapper.h>
#include <cstdlib>
#include <cstring>
#include <memory>
// INTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/environment-variable.h>
+#include <dali/internal/graphics/gles/gl-extensions-support.h>
#include <dali/internal/graphics/gles/gles-abstraction.h>
#include <dali/internal/graphics/gles/gles2-implementation.h>
#include <dali/internal/graphics/gles/gles3-implementation.h>
+#include <dali/internal/system/common/time-service.h>
namespace Dali
{
{
namespace
{
-static constexpr int32_t INITIAL_GLES_VERSION = 30;
-static constexpr int32_t GLES_VERSION_SUPPORT_BLEND_EQUATION_ADVANCED = 32;
-static constexpr const char* LEGACY_SHADING_LANGUAGE_VERSION = "100";
-static constexpr const char* KHR_BLEND_EQUATION_ADVANCED = "GL_KHR_blend_equation_advanced";
+static constexpr int32_t INITIAL_GLES_VERSION = 30;
+static constexpr int32_t GLES_VERSION_SUPPORT_BLEND_EQUATION_ADVANCED = 32;
+
+static constexpr int32_t MINIMUM_GLES_VERSION_GET_MAXIMUM_MULTISAMPLES_TO_TEXTURE = 30;
+
+static constexpr const char* LEGACY_SHADING_LANGUAGE_VERSION = "100";
static constexpr const char* DEFAULT_SAMPLER_TYPE = "sampler2D";
static constexpr const char* FRAGMENT_SHADER_ADVANCED_BLEND_EQUATION_PREFIX =
+ "#ifdef GL_KHR_blend_equation_advanced\n"
"#extension GL_KHR_blend_equation_advanced : enable\n"
+ "#endif\n"
- "#if GL_KHR_blend_equation_advanced==1 || __VERSION__>=320\n"
+ "#if defined(GL_KHR_blend_equation_advanced) || __VERSION__>=320\n"
" layout(blend_support_all_equations) out;\n"
"#endif\n";
static constexpr const char* OES_EGL_IMAGE_EXTERNAL_STRING = "#extension GL_OES_EGL_image_external:require\n";
static constexpr const char* OES_EGL_IMAGE_EXTERNAL_STRING_ESSL3 = "#extension GL_OES_EGL_image_external_essl3:require\n";
+
+// Threshold time in miliseconds
+constexpr auto PERFORMANCE_LOG_THRESHOLD_TIME_ENV = "DALI_EGL_PERFORMANCE_LOG_THRESHOLD_TIME";
+
+uint32_t GetPerformanceLogThresholdTime()
+{
+ auto timeString = Dali::EnvironmentVariable::GetEnvironmentVariable(PERFORMANCE_LOG_THRESHOLD_TIME_ENV);
+ uint32_t time = timeString ? static_cast<uint32_t>(std::atoi(timeString)) : 0u;
+ return time;
+}
+
} // namespace
/**
{
public:
GlImplementation()
- : mContextCreatedWaitCondition(),
+ : mGlExtensionSupportedCacheList(),
+ mContextCreatedWaitCondition(),
mMaxTextureSize(0),
+ mMaxCombinedTextureUnits(0),
+ mMaxTextureSamples(0),
mVertexShaderPrefix(""),
mGlesVersion(INITIAL_GLES_VERSION),
mShadingLanguageVersion(100),
mShadingLanguageVersionCached(false),
mIsSurfacelessContextSupported(false),
- mIsAdvancedBlendEquationSupportedCached(false),
- mIsAdvancedBlendEquationSupported(false),
mIsContextCreated(false)
{
mImpl.reset(new Gles3Implementation());
void ContextCreated()
{
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
+ glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextureUnits);
+ // Since gles 2.0 didn't return well for GL_MAJOR_VERSION and GL_MINOR_VERSION,
// Only change gles version for the device that support above gles 3.0.
if(mGlesVersion >= INITIAL_GLES_VERSION)
{
if(mGlesVersion >= GLES_VERSION_SUPPORT_BLEND_EQUATION_ADVANCED)
{
- mIsAdvancedBlendEquationSupported = true;
+ SetIsAdvancedBlendEquationSupported(true);
}
- else
+
+ if(mGlExtensionSupportedCacheList.NeedFullCheck())
{
- // when mIsAdvancedBlendEquationSupported is cached, we don't need to check all the extensions.
- if(!mIsAdvancedBlendEquationSupportedCached)
+ // fully check gl extensions if we miss some extension supported
+ mGlExtensionSupportedCacheList.EnsureGlExtensionSupportedCheck();
+ }
+
+ if(IsMultisampledRenderToTextureSupported())
+ {
+ mMaxTextureSamples = 0;
+
+ if(mGlesVersion >= MINIMUM_GLES_VERSION_GET_MAXIMUM_MULTISAMPLES_TO_TEXTURE)
{
- const char* const extensionStr = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
- std::istringstream stream(extensionStr);
- std::string currentExtension;
- while(std::getline(stream, currentExtension, ' '))
- {
- if(currentExtension == KHR_BLEND_EQUATION_ADVANCED)
- {
- mIsAdvancedBlendEquationSupported = true;
- break;
- }
- }
+ // Try to get maximum FBO MSAA sampling level from GL_RENDERBUFFER first.
+ // If false, than ask again to GL_MAX_SAMPLES_EXT.
+ GetInternalformativ(GL_RENDERBUFFER, GL_RGBA8, GL_SAMPLES, 1, &mMaxTextureSamples);
+ }
+ if(mMaxTextureSamples == 0)
+ {
+ glGetIntegerv(GL_MAX_SAMPLES_EXT, &mMaxTextureSamples);
}
}
}
}
+ mLogThreshold = GetPerformanceLogThresholdTime();
+ mLogEnabled = mLogThreshold > 0 ? true : false;
+
{
ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
mIsContextCreated = true;
void SetIsAdvancedBlendEquationSupported(const bool isSupported)
{
- mIsAdvancedBlendEquationSupported = isSupported;
- mIsAdvancedBlendEquationSupportedCached = true;
+ mGlExtensionSupportedCacheList.MarkSupported(GlExtensionCache::GlExtensionCheckerType::BLEND_EQUATION_ADVANCED, isSupported);
}
bool IsAdvancedBlendEquationSupported()
{
ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
- if(!mIsContextCreated && !mIsAdvancedBlendEquationSupportedCached)
+
+ const auto type = GlExtensionCache::GlExtensionCheckerType::BLEND_EQUATION_ADVANCED;
+ if(!mIsContextCreated && !mGlExtensionSupportedCacheList.IsCached(type))
+ {
+ mContextCreatedWaitCondition.Wait(lock);
+ }
+ return mGlExtensionSupportedCacheList.IsSupported(type);
+ }
+
+ void SetIsMultisampledRenderToTextureSupported(const bool isSupported)
+ {
+ mGlExtensionSupportedCacheList.MarkSupported(GlExtensionCache::GlExtensionCheckerType::MULTISAMPLED_RENDER_TO_TEXTURE, isSupported);
+ }
+
+ bool IsMultisampledRenderToTextureSupported()
+ {
+ ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
+
+ const auto type = GlExtensionCache::GlExtensionCheckerType::MULTISAMPLED_RENDER_TO_TEXTURE;
+ if(!mIsContextCreated && !mGlExtensionSupportedCacheList.IsCached(type))
{
mContextCreatedWaitCondition.Wait(lock);
}
- return mIsAdvancedBlendEquationSupported;
+ return mGlExtensionSupportedCacheList.IsSupported(type);
}
bool IsBlendEquationSupported(DevelBlendEquation::Type blendEquation)
return mMaxTextureSize;
}
- int GetGlesVersion()
+ int GetMaxCombinedTextureUnits()
+ {
+ ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
+ if(!mIsContextCreated)
+ {
+ mContextCreatedWaitCondition.Wait(lock);
+ }
+ return mMaxCombinedTextureUnits;
+ }
+
+ int GetMaxTextureSamples()
+ {
+ ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
+ if(!mIsContextCreated)
+ {
+ mContextCreatedWaitCondition.Wait(lock);
+ }
+ return mMaxTextureSamples;
+ }
+
+ int32_t GetGlesVersion()
{
ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
if(!mIsContextCreated)
if(versionPosition != std::string::npos)
{
std::string extensionString;
- size_t shadingLanguageVersionPosition = shader.find_first_not_of(" \t", versionPosition + versionString.length());
+ size_t shadingLanguageVersionPosition = shader.find_first_not_of(" \t", versionPosition + versionString.length());
if(shadingLanguageVersionPosition != std::string::npos &&
shader.substr(shadingLanguageVersionPosition, 3) == LEGACY_SHADING_LANGUAGE_VERSION)
{
void Clear(GLbitfield mask) override
{
+ uint32_t startTime = 0, endTime = 0;
+ if(mLogEnabled)
+ {
+ startTime = TimeService::GetMilliSeconds();
+ }
+
glClear(mask);
+
+ if(mLogEnabled)
+ {
+ endTime = TimeService::GetMilliSeconds();
+ if(endTime - startTime > mLogThreshold)
+ {
+ DALI_LOG_DEBUG_INFO("glClear takes long time! [%u ms]\n", endTime - startTime);
+ }
+ }
}
void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) override
mImpl->RenderbufferStorageMultisample(target, samples, internalformat, width, height);
}
+ void FramebufferTexture2DMultisample(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) override
+ {
+ mImpl->FramebufferTexture2DMultisample(target, attachment, textarget, texture, level, samples);
+ }
+
void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) override
{
mImpl->FramebufferTextureLayer(target, attachment, texture, level, layer);
void BlendBarrier(void)
{
- if(mIsAdvancedBlendEquationSupported)
+ if(mGlExtensionSupportedCacheList.IsSupported(GlExtensionCache::GlExtensionCheckerType::BLEND_EQUATION_ADVANCED))
{
mImpl->BlendBarrier();
}
private:
std::unique_ptr<GlesAbstraction> mImpl;
+ GlExtensionCache::GlExtensionSupportedCacheList mGlExtensionSupportedCacheList;
+
ConditionalWait mContextCreatedWaitCondition;
GLint mMaxTextureSize;
+ GLint mMaxCombinedTextureUnits;
+ GLint mMaxTextureSamples;
std::string mShaderVersionPrefix;
std::string mVertexShaderPrefix;
std::string mFragmentShaderPrefix;
int32_t mGlesVersion;
int32_t mShadingLanguageVersion;
+ uint32_t mLogThreshold{0};
bool mShadingLanguageVersionCached;
bool mIsSurfacelessContextSupported;
- bool mIsAdvancedBlendEquationSupportedCached;
- bool mIsAdvancedBlendEquationSupported;
bool mIsContextCreated;
+ bool mLogEnabled{false};
};
} // namespace Adaptor