Let we check Multisampled Framebuffer system supported.
If then + If user setup specific sampling size, render to texture multisampled.
TODO : Ubuntu profile make some crash even it support this feature.
Other profiles are all works well. Until find the reason of this crash,
Just block Multisampled FBO feature in Ubuntu case.
Change-Id: I329a97e47b65479756d9e7d2c8a57660fc569fcb
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
return true;
}
+bool TestGlAbstraction::IsMultisampledRenderToTextureSupported()
+{
+ return true;
+}
+
bool TestGlAbstraction::IsBlendEquationSupported(DevelBlendEquation::Type blendEquation)
{
return true;
bool IsAdvancedBlendEquationSupported() override;
+ bool IsMultisampledRenderToTextureSupported() override;
+
bool IsBlendEquationSupported(DevelBlendEquation::Type blendEquation) override;
std::string GetShaderVersionPrefix();
{
}
+ inline void FramebufferTexture2DMultisample(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) override
+ {
+ // TODO : Check it if need
+ FramebufferTexture2D(target, attachment, textarget, texture, level);
+ }
+
inline void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) override
{
}
#define DALI_TEST_GRAPHICS_APPLICATION_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
}
/**
+ * @return true if multisampled render to texture is supported
+ */
+ bool IsMultisampledRenderToTextureSupported() override
+ {
+ return true;
+ }
+
+ /**
* @return true if graphics subsystem is initialized
*/
bool IsInitialized() override
}
/**
+ * @return the maximum texture samples when we use multisampled texture
+ */
+ uint8_t GetMaxTextureSamples() override
+ {
+ return 8u;
+ }
+
+ /**
* @return the version number of the shader language
*/
uint32_t GetShaderLanguageVersion() override
#define DALI_INTERNAL_BASE_GRAPHICS_INTERFACE_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
virtual bool IsAdvancedBlendEquationSupported() = 0;
/**
+ * @return true if multisampled render to texture is supported
+ */
+ virtual bool IsMultisampledRenderToTextureSupported() = 0;
+
+ /**
* @return true if graphics subsystem is initialized
*/
virtual bool IsInitialized() = 0;
virtual uint32_t GetMaxTextureSize() = 0;
/**
+ * @return the maximum texture samples when we use multisampled texture
+ */
+ virtual uint8_t GetMaxTextureSamples() = 0;
+
+ /**
* @return the version number of the shader language
*/
virtual uint32_t GetShaderLanguageVersion() = 0;
${adaptor_graphics_dir}/gles/egl-sync-implementation.cpp
${adaptor_graphics_dir}/gles/egl-context-helper-implementation.cpp
${adaptor_graphics_dir}/gles/gl-extensions.cpp
+ ${adaptor_graphics_dir}/gles/gl-extensions-support.cpp
${adaptor_graphics_dir}/gles/gl-proxy-implementation.cpp
${adaptor_graphics_dir}/gles/egl-graphics-factory.cpp
${adaptor_graphics_dir}/gles/egl-graphics.cpp
Framebuffer::Framebuffer(const Graphics::FramebufferCreateInfo& createInfo, Graphics::EglGraphicsController& controller)
: FramebufferResource(createInfo, controller)
{
+ // Check whether we need to consider multisampling
+ if(createInfo.multiSamplingLevel > 1u && controller.GetGraphicsInterface()->IsMultisampledRenderToTextureSupported())
+ {
+ mMultisamples = std::min(createInfo.multiSamplingLevel, controller.GetGraphicsInterface()->GetMaxTextureSamples());
+ }
+
// Add framebuffer to the Resource queue
mController.AddFramebuffer(*this);
}
AttachTexture(depthTexture, attachmentId, 0, mCreateInfo.depthStencilAttachment.depthLevel);
}
- else if(mCreateInfo.depthStencilAttachment.depthUsage == Graphics::DepthStencilAttachment::Usage::WRITE &&
- mCreateInfo.depthStencilAttachment.stencilUsage == Graphics::DepthStencilAttachment::Usage::WRITE)
- {
- // Create depth+stencil renderbuffer
- gl->GenRenderbuffers(1, &mStencilBufferId);
- gl->BindRenderbuffer(GL_RENDERBUFFER, mStencilBufferId);
- gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mCreateInfo.size.width, mCreateInfo.size.height);
- gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mStencilBufferId);
- }
- else if(mCreateInfo.depthStencilAttachment.depthUsage == Graphics::DepthStencilAttachment::Usage::WRITE)
- {
- // Create depth renderbuffer
- gl->GenRenderbuffers(1, &mDepthBufferId);
- gl->BindRenderbuffer(GL_RENDERBUFFER, mDepthBufferId);
- gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mCreateInfo.size.width, mCreateInfo.size.height);
- gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthBufferId);
- }
- else if(mCreateInfo.depthStencilAttachment.stencilUsage == Graphics::DepthStencilAttachment::Usage::WRITE)
+ else
{
- // Create stencil renderbuffer
- gl->GenRenderbuffers(1, &mStencilBufferId);
- gl->BindRenderbuffer(GL_RENDERBUFFER, mStencilBufferId);
- gl->RenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, mCreateInfo.size.width, mCreateInfo.size.height);
- gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mStencilBufferId);
+ const bool depthWrite = mCreateInfo.depthStencilAttachment.depthUsage == Graphics::DepthStencilAttachment::Usage::WRITE;
+ const bool stencilWrite = mCreateInfo.depthStencilAttachment.stencilUsage == Graphics::DepthStencilAttachment::Usage::WRITE;
+
+ // Check whether we need to use RenderBuffer
+ if(depthWrite || stencilWrite)
+ {
+ // if stencil is write, use renderbuffer as mStencilBufferId.
+ uint32_t& bufferId = stencilWrite ? mStencilBufferId : mDepthBufferId;
+ const auto internalFormat = depthWrite ? (stencilWrite ? GL_DEPTH24_STENCIL8 : GL_DEPTH_COMPONENT16) : GL_STENCIL_INDEX8;
+ const auto attachment = depthWrite ? (stencilWrite ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT) : GL_STENCIL_ATTACHMENT;
+
+ gl->GenRenderbuffers(1, &bufferId);
+ gl->BindRenderbuffer(GL_RENDERBUFFER, bufferId);
+
+ if(mMultisamples <= 1u)
+ {
+ gl->RenderbufferStorage(GL_RENDERBUFFER, internalFormat, mCreateInfo.size.width, mCreateInfo.size.height);
+ }
+ else
+ {
+ gl->RenderbufferStorageMultisample(GL_RENDERBUFFER, mMultisamples, internalFormat, mCreateInfo.size.width, mCreateInfo.size.height);
+ }
+ gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, bufferId);
+ }
}
context->BindFrameBuffer(GL_FRAMEBUFFER, 0);
if(gl)
{
auto graphicsTexture = static_cast<const GLES::Texture*>(texture);
- if(graphicsTexture->GetCreateInfo().textureType == Graphics::TextureType::TEXTURE_2D)
+ auto textarget = (graphicsTexture->GetCreateInfo().textureType == Graphics::TextureType::TEXTURE_2D) ? graphicsTexture->GetGlTarget() : GL_TEXTURE_CUBE_MAP_POSITIVE_X + layerId;
+ if(mMultisamples <= 1u)
{
- gl->FramebufferTexture2D(GL_FRAMEBUFFER, attachmentId, graphicsTexture->GetGlTarget(), graphicsTexture->GetGLTexture(), levelId);
+ gl->FramebufferTexture2D(GL_FRAMEBUFFER, attachmentId, textarget, graphicsTexture->GetGLTexture(), levelId);
}
else
{
- gl->FramebufferTexture2D(GL_FRAMEBUFFER, attachmentId, GL_TEXTURE_CUBE_MAP_POSITIVE_X + layerId, graphicsTexture->GetGLTexture(), levelId);
+ gl->FramebufferTexture2DMultisample(GL_FRAMEBUFFER, attachmentId, textarget, graphicsTexture->GetGLTexture(), levelId, mMultisamples);
}
}
}
#define DALI_GRAPHICS_GLES_FRAMEBUFFER_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
uint32_t mFramebufferId{0u};
uint32_t mDepthBufferId{0u};
uint32_t mStencilBufferId{0u};
+ uint32_t mMultisamples{1u};
bool mInitialized{false};
};
void EglGraphics::CacheConfigurations(ConfigurationManager& configurationManager)
{
mGLES->SetIsAdvancedBlendEquationSupported(configurationManager.IsAdvancedBlendEquationSupported());
+ mGLES->SetIsMultisampledRenderToTextureSupported(configurationManager.IsMultisampledRenderToTextureSupported());
mGLES->SetShadingLanguageVersion(configurationManager.GetShadingLanguageVersion());
}
#define DALI_INTERNAL_BASE_GRAPHICS_IMPLEMENTATION_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
return mGLES->IsAdvancedBlendEquationSupported();
}
+ bool IsMultisampledRenderToTextureSupported() override
+ {
+ return mGLES->IsMultisampledRenderToTextureSupported();
+ }
+
/**
* @return true if graphics subsystem is initialized
*/
return mGLES->GetMaxTextureSize();
}
+ uint8_t GetMaxTextureSamples() override
+ {
+ return mGLES->GetMaxTextureSamples();
+ }
+
uint32_t GetShaderLanguageVersion() override
{
return mGLES->GetShadingLanguageVersion();
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/graphics/gles/gl-extensions-support.h>
+
+// EXTERNAL HEADER
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <GLES3/gl3.h>
+
+#include <algorithm> // for std::find_if
+#include <sstream>
+#include <string>
+#include <string_view>
+#include <utility> // for std::pair
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Adaptor
+{
+namespace
+{
+static constexpr const char* KHR_BLEND_EQUATION_ADVANCED = "GL_KHR_blend_equation_advanced";
+static constexpr const char* EXT_MULTISAMPLED_RENDER_TO_TEXTURE = "GL_EXT_multisampled_render_to_texture";
+
+} // namespace
+
+namespace GlExtensionCache
+{
+void GlExtensionSupportedCacheList::EnsureGlExtensionSupportedCheck()
+{
+ // Note that this function calls at most one time.
+ // But the number of GL_EXTENSIONS itmes are so vairous.
+ // We need to reduce extension checkup
+
+ const char* const extensionStr = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
+ std::istringstream stream(extensionStr);
+ std::string currentExtension;
+
+ // Create expected string-to-checkertype convertor.
+ using StringTypePair = std::pair<std::string_view, GlExtensionCheckerType>;
+ // clang-format off
+ std::vector<StringTypePair> extensionStringToTypeList
+ {
+ {KHR_BLEND_EQUATION_ADVANCED, GlExtensionCheckerType::BLEND_EQUATION_ADVANCED },
+
+#ifndef DALI_PROFILE_UBUNTU
+ // @todo : Current ubuntu profile's multisamples FBO make crash when eglDestroyContext.
+ // Invalidate multisampled render to texture feature hardly.
+ {EXT_MULTISAMPLED_RENDER_TO_TEXTURE, GlExtensionCheckerType::MULTISAMPLED_RENDER_TO_TEXTURE},
+#endif //DALI_PROFILE_UBUNTU
+
+ ///< Append additional extension checker type here.
+ };
+ // clang-format on
+
+ while(!extensionStringToTypeList.empty() && std::getline(stream, currentExtension, ' '))
+ {
+ auto findResult = std::find_if(extensionStringToTypeList.begin(),
+ extensionStringToTypeList.end(),
+ [¤tExtension](const StringTypePair& value) {
+ return value.first == currentExtension;
+ });
+ if(findResult != extensionStringToTypeList.end())
+ {
+ auto type = findResult->second;
+
+ // Mark as True.
+ MarkSupported(type, true);
+
+ // Remove from list. we don't need to check this extension.
+ extensionStringToTypeList.erase(findResult);
+ }
+ }
+
+ // Set supported as false if extension keyword not exist.
+ SetAllUncachedAsNotSupported();
+}
+} // namespace GlExtensionCache
+} // namespace Adaptor
+} // namespace Internal
+} // namespace Dali
--- /dev/null
+#ifndef DALI_INTERNAL_GL_EXTENSION_SUPPORT_H
+#define DALI_INTERNAL_GL_EXTENSION_SUPPORT_H
+
+/*
+ * Copyright (c) 2022 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+#include <cstdint>
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Adaptor
+{
+/**
+ * Common extensions support checker type.
+ * Type value should be start with 0, and increase continuous.
+ */
+using ExtensionCheckerType = uint32_t;
+
+/**
+ * @brief Store the supported information cached or not.
+ */
+struct ExtensionSupportedCache
+{
+ ExtensionSupportedCache()
+ : isSupported{false},
+ cached{false}
+ {
+ }
+ bool isSupported : 1;
+ bool cached : 1;
+};
+
+/**
+ * @brief Extension Supported caching system interface.
+ *
+ * Create ExtensionSupportedCache list and Set/Get supported value.
+ * Use ExtensionCheckerType as index of container.
+ *
+ * It will help to check gl extension & egl extention support.
+ */
+struct ExtensionSupportedCacheListInterface
+{
+ ExtensionSupportedCacheListInterface(const uint32_t maxCount)
+ : mCachedItemCount(0u),
+ mMaxCount(maxCount),
+ mData{maxCount}
+ {
+ }
+
+ /**
+ * @brief Check whether we need to check some more extension types or not.
+ * @return True if some extension type to check remained. False if we checked all extension types.
+ */
+ inline bool NeedFullCheck() const
+ {
+ return mCachedItemCount < mMaxCount;
+ }
+
+ /**
+ * @brief Set extension is supported or not
+ * If we already cached the result before, just ignored.
+ *
+ * @param[in] type The index of extension type.
+ * @param[in] isSupported Whether this extension supported or not. Default as true.
+ */
+ inline void MarkSupported(ExtensionCheckerType type, bool isSupported = true)
+ {
+ auto& cache = mData[static_cast<uint32_t>(type)];
+ if(!cache.cached)
+ {
+ cache.cached = true;
+ cache.isSupported = isSupported;
+ ++mCachedItemCount;
+ }
+ }
+
+ /**
+ * @brief Get extension is supported or not.
+ *
+ * @param[in] type The index of extension type.
+ * @return True if we cached extension as supported. False otherwise.
+ */
+ inline bool IsSupported(ExtensionCheckerType type) const
+ {
+ return mData[static_cast<uint32_t>(type)].isSupported;
+ }
+
+ /**
+ * @brief Get extension is cached or not.
+ *
+ * @param[in] type The index of extension type.
+ * @return True if we cached extension. False otherwise.
+ */
+ inline bool IsCached(ExtensionCheckerType type) const
+ {
+ return mData[static_cast<uint32_t>(type)].cached;
+ }
+
+ /**
+ * @brief Mark all uncached extension type as not supported.
+ * After this API called, we can assume that every extensions are cached.
+ */
+ void SetAllUncachedAsNotSupported()
+ {
+ if(NeedFullCheck())
+ {
+ for(auto&& iter : mData)
+ {
+ if(!iter.cached)
+ {
+ iter.isSupported = false;
+ iter.cached = true;
+ }
+ }
+
+ // Mark all cached.
+ mCachedItemCount = mMaxCount;
+ }
+ }
+
+ uint32_t mCachedItemCount;
+ const uint32_t mMaxCount;
+
+ std::vector<ExtensionSupportedCache> mData;
+};
+
+/**
+ * Gl extensions support checker system.
+ */
+namespace GlExtensionCache
+{
+enum GlExtensionCheckerType
+{
+ BLEND_EQUATION_ADVANCED = 0,
+ MULTISAMPLED_RENDER_TO_TEXTURE,
+ ///< Append additional extension checker type here.
+ EXTENSION_CHECKER_TYPE_MAX,
+};
+
+/**
+ * @brief Extension Supported caching system for gl.
+ */
+struct GlExtensionSupportedCacheList : public ExtensionSupportedCacheListInterface
+{
+ GlExtensionSupportedCacheList()
+ : ExtensionSupportedCacheListInterface(static_cast<uint32_t>(GlExtensionCheckerType::EXTENSION_CHECKER_TYPE_MAX))
+ {
+ }
+
+ /**
+ * Ensure that we check all gl extension features for this system.
+ */
+ void EnsureGlExtensionSupportedCheck();
+};
+} // namespace GlExtensionCache
+
+} // namespace Adaptor
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif /* DALI_INTERNAL_GL_EXTENSION_SUPPORT_H */
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
#ifdef GL_KHR_blend_equation_advanced
mBlendBarrierKHR(nullptr),
#endif
+#ifdef GL_EXT_multisampled_render_to_texture
+ mGlRenderbufferStorageMultisampleEXT(nullptr),
+ mGlFramebufferTexture2DMultisampleEXT(nullptr),
+#endif
mInitialized(false)
{
}
{
// initialize extension on first use as on some hw platforms a context
// has to be bound for the extensions to return correct pointer
- if(!mInitialized)
+ if(DALI_UNLIKELY(!mInitialized))
{
Initialize();
}
{
// initialize extension on first use as on some hw platforms a context
// has to be bound for the extensions to return correct pointer
- if(!mInitialized)
+ if(DALI_UNLIKELY(!mInitialized))
{
Initialize();
}
{
// initialize extension on first use as on some hw platforms a context
// has to be bound for the extensions to return correct pointer
- if(!mInitialized)
+ if(DALI_UNLIKELY(!mInitialized))
{
Initialize();
}
{
// initialize extension on first use as on some hw platforms a context
// has to be bound for the extensions to return correct pointer
- if(!mInitialized)
+ if(DALI_UNLIKELY(!mInitialized))
{
Initialize();
}
return false;
}
+void GlExtensions::RenderbufferStorageMultisampleEXT(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ // initialize extension on first use as on some hw platforms a context
+ // has to be bound for the extensions to return correct pointer
+ if(DALI_UNLIKELY(!mInitialized))
+ {
+ Initialize();
+ }
+
+#ifdef GL_EXT_multisampled_render_to_texture
+ if(mGlRenderbufferStorageMultisampleEXT)
+ {
+ mGlRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
+ }
+ else
+ {
+ DALI_LOG_ERROR("Error: glRenderbufferStorageMultisampleEXT extension is not available\n");
+ DALI_ASSERT_DEBUG(0);
+ }
+#endif
+}
+
+void GlExtensions::FramebufferTexture2DMultisampleEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples)
+{
+ // initialize extension on first use as on some hw platforms a context
+ // has to be bound for the extensions to return correct pointer
+ if(DALI_UNLIKELY(!mInitialized))
+ {
+ Initialize();
+ }
+
+#ifdef GL_EXT_multisampled_render_to_texture
+ if(mGlFramebufferTexture2DMultisampleEXT)
+ {
+ mGlFramebufferTexture2DMultisampleEXT(target, attachment, textarget, texture, level, samples);
+ }
+ else
+ {
+ DALI_LOG_ERROR("Error: glFramebufferTexture2DMultisampleEXT extension is not available\n");
+ DALI_ASSERT_DEBUG(0);
+ }
+#endif
+}
+
void GlExtensions::Initialize()
{
mInitialized = true;
#ifdef GL_KHR_blend_equation_advanced
mBlendBarrierKHR = reinterpret_cast<PFNGLBLENDBARRIERKHRPROC>(eglGetProcAddress("glBlendBarrierKHR"));
#endif
+
+#ifdef GL_EXT_multisampled_render_to_texture
+ mGlRenderbufferStorageMultisampleEXT = reinterpret_cast<PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC>(eglGetProcAddress("glRenderbufferStorageMultisampleEXT"));
+ mGlFramebufferTexture2DMultisampleEXT = reinterpret_cast<PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC>(eglGetProcAddress("glFramebufferTexture2DMultisampleEXT"));
+#endif
}
} // namespace Adaptor
#define DALI_INTERNAL_GL_EXTENSION_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
*/
bool BlendBarrierKHR();
+ /**
+ * GLES extension
+ * Establish data storage, format, dimensions and sample count of a renderbuffer object's image
+ *
+ * @param[in] target Specifies a binding to which the target of the allocation and must be GL_RENDERBUFFER.
+ * @param[in] samples Specifies the number of samples to be used for the renderbuffer object's storage. Must not bigger than MAX_SAMPLES_EXT.
+ * @param[in] internalformat Specifies the internal format to use for the renderbuffer object's image.
+ * @param[in] width Specifies the width of the renderbuffer, in pixels.
+ * @param[in] height Specifies the height of the renderbuffer, in pixels.
+ */
+ void RenderbufferStorageMultisampleEXT(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+
+ /**
+ * GLES extension
+ * Enables multisampled rendering into the images of a texture object.
+ * If samples as 0, same as FramebufferTexture2D
+ *
+ * @param[in] target Specifies the framebuffer target. The symbolic constant must be GL_FRAMEBUFFER.
+ * @param[in] attachment Specifies the attachment point to which an image from texture should be attached.
+ * @param[in] textarget Specifies the texture target.
+ * @param[in] texture Specifies the texture object whose image is to be attached.
+ * @param[in] level Specifies the mipmap level of the texture image to be attached, which must be 0.
+ * @param[in] samples The number of samples to the texture. Must not bigger than MAX_SAMPLES_EXT.
+ */
+ void FramebufferTexture2DMultisampleEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+
private:
/**
* Lazy Initialize extensions on first use
PFNGLBLENDBARRIERKHRPROC mBlendBarrierKHR;
#endif
+#ifdef GL_EXT_multisampled_render_to_texture
+ PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC mGlRenderbufferStorageMultisampleEXT;
+ PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC mGlFramebufferTexture2DMultisampleEXT;
+#endif
+
bool mInitialized;
};
#define DALI_INTERNAL_GL_IMPLEMENTATION_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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/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>
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 const char* DEFAULT_SAMPLER_TYPE = "sampler2D";
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";
+
} // namespace
/**
{
public:
GlImplementation()
- : mContextCreatedWaitCondition(),
+ : mGlExtensionSupportedCacheList(),
+ mContextCreatedWaitCondition(),
mMaxTextureSize(0),
+ mMaxTextureSamples(0),
mVertexShaderPrefix(""),
mGlesVersion(INITIAL_GLES_VERSION),
mShadingLanguageVersion(100),
mShadingLanguageVersionCached(false),
mIsSurfacelessContextSupported(false),
- mIsAdvancedBlendEquationSupportedCached(false),
- mIsAdvancedBlendEquationSupported(false),
mIsContextCreated(false)
{
mImpl.reset(new Gles3Implementation());
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)
- {
- 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;
- }
- }
- }
+ // fully check gl extensions if we miss some extension supported
+ mGlExtensionSupportedCacheList.EnsureGlExtensionSupportedCheck();
+ }
+
+ if(IsMultisampledRenderToTextureSupported())
+ {
+ glGetIntegerv(GL_MAX_SAMPLES_EXT, &mMaxTextureSamples);
}
if(!mShadingLanguageVersionCached)
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 GetMaxTextureSamples()
+ {
+ ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
+ if(!mIsContextCreated)
+ {
+ mContextCreatedWaitCondition.Wait(lock);
+ }
+ return mMaxTextureSamples;
+ }
+
int GetGlesVersion()
{
ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
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)
{
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 mMaxTextureSamples;
std::string mShaderVersionPrefix;
std::string mVertexShaderPrefix;
std::string mFragmentShaderPrefix;
int32_t mShadingLanguageVersion;
bool mShadingLanguageVersionCached;
bool mIsSurfacelessContextSupported;
- bool mIsAdvancedBlendEquationSupportedCached;
- bool mIsAdvancedBlendEquationSupported;
bool mIsContextCreated;
};
#define DALI_INTERNAL_GLES_ABSTRACTION_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
virtual void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) = 0;
+ virtual void FramebufferTexture2DMultisample(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) = 0;
+
virtual void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) = 0;
virtual GLvoid* MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) = 0;
#define DALI_INTERNAL_GLES2_IMPLEMENTATION_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) override
{
- DALI_LOG_ERROR("glRenderbufferStorageMultisample is not supported in OpenGL es 2.0\n");
+ mGlExtensions.RenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
+ }
+
+ void FramebufferTexture2DMultisample(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) override
+ {
+ mGlExtensions.FramebufferTexture2DMultisampleEXT(target, attachment, textarget, texture, level, samples);
}
void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) override
#define DALI_INTERNAL_GLES3_IMPLEMENTATION_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) override
{
- glRenderbufferStorageMultisample(target, samples, internalformat, width, height);
+ // @note even gles 3.0 support glRenderbufferStorageMultisample, We cannot use that API with FramebufferTexture2DMultisampleEXT cause vendor issue.
+ // Since dali only use RenderbufferStorageMultisample API for FBO MSAA, just keep to use extension API.
+ mGlExtensions.RenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
+ }
+
+ void FramebufferTexture2DMultisample(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) override
+ {
+ mGlExtensions.FramebufferTexture2DMultisampleEXT(target, attachment, textarget, texture, level, samples);
}
void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) override
{
namespace
{
-const std::string SYSTEM_CACHE_FILE = "gpu-environment.conf";
-const std::string DALI_ENV_MULTIPLE_WINDOW_SUPPORT = "DALI_ENV_MULTIPLE_WINDOW_SUPPORT";
-const std::string DALI_BLEND_EQUATION_ADVANCED_SUPPORT = "DALI_BLEND_EQUATION_ADVANCED_SUPPORT";
-const std::string DALI_GLSL_VERSION = "DALI_GLSL_VERSION";
+const std::string SYSTEM_CACHE_FILE = "gpu-environment.conf";
+const std::string DALI_ENV_MULTIPLE_WINDOW_SUPPORT = "DALI_ENV_MULTIPLE_WINDOW_SUPPORT";
+const std::string DALI_BLEND_EQUATION_ADVANCED_SUPPORT = "DALI_BLEND_EQUATION_ADVANCED_SUPPORT";
+const std::string DALI_MULTISAMPLED_RENDER_TO_TEXTURE_SUPPORT = "DALI_MULTISAMPLED_RENDER_TO_TEXTURE_SUPPORT";
+const std::string DALI_GLSL_VERSION = "DALI_GLSL_VERSION";
} // unnamed namespace
mShaderLanguageVersion(0u),
mIsMultipleWindowSupported(true),
mIsAdvancedBlendEquationSupported(true),
+ mIsMultisampledRenderToTextureSupported(true),
mMaxTextureSizeCached(false),
mIsMultipleWindowSupportedCached(false),
mIsAdvancedBlendEquationSupportedCached(false),
+ mIsMultisampledRenderToTextureSupportedCached(false),
mShaderLanguageVersionCached(false)
{
}
mIsAdvancedBlendEquationSupported = std::atoi(value.c_str());
mIsAdvancedBlendEquationSupportedCached = true;
}
+ else if(!mIsMultisampledRenderToTextureSupportedCached && name == DALI_MULTISAMPLED_RENDER_TO_TEXTURE_SUPPORT)
+ {
+ std::getline(subStream, value);
+ mIsMultisampledRenderToTextureSupported = std::atoi(value.c_str());
+ mIsMultisampledRenderToTextureSupportedCached = true;
+ }
else if(!mShaderLanguageVersionCached && name == DALI_GLSL_VERSION)
{
std::getline(subStream, value);
return mIsAdvancedBlendEquationSupported;
}
+bool ConfigurationManager::IsMultisampledRenderToTextureSupported()
+{
+ if(!mIsMultisampledRenderToTextureSupportedCached)
+ {
+ RetrieveKeysFromConfigFile(mSystemCacheFilePath);
+
+ if(!mIsMultisampledRenderToTextureSupportedCached)
+ {
+ if(!mGraphics->IsInitialized())
+ {
+ // Wait until graphics subsystem is initialised, but this will happen once per factory reset.
+ // This method blocks until the render thread has initialised the graphics.
+ mThreadController->WaitForGraphicsInitialization();
+ }
+
+ // Query from Graphics Subsystem and save the cache
+ mIsMultisampledRenderToTextureSupported = mGraphics->IsMultisampledRenderToTextureSupported();
+ mIsMultisampledRenderToTextureSupportedCached = true;
+
+ Dali::FileStream configFile(mSystemCacheFilePath, Dali::FileStream::READ | Dali::FileStream::APPEND | Dali::FileStream::TEXT);
+ std::fstream& stream = dynamic_cast<std::fstream&>(configFile.GetStream());
+ if(stream.is_open())
+ {
+ stream << DALI_MULTISAMPLED_RENDER_TO_TEXTURE_SUPPORT << " " << mIsMultisampledRenderToTextureSupported << std::endl;
+ }
+ else
+ {
+ DALI_LOG_ERROR("Fail to open file : %s\n", mSystemCacheFilePath.c_str());
+ }
+ }
+ }
+
+ return mIsMultisampledRenderToTextureSupported;
+}
+
} // namespace Adaptor
} // namespace Internal
#define DALI_INTERNAL_ENVIRONMENT_CONFIGURATION_MANAGER_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
/**
* @brief Check whether blend equation advanced (extension) is supported
- * @return Whether blend equation advanced (extension is supported
+ * @return Whether blend equation advanced (extension) is supported
*/
bool IsAdvancedBlendEquationSupported();
+ /**
+ * @brief Check whether multisampled render to texture (extension) is supported
+ * @return Whether multisampled render to texture (extension) is supported
+ */
+ bool IsMultisampledRenderToTextureSupported();
// Deleted copy constructor.
ConfigurationManager(const ConfigurationManager&) = delete;
// Deleted move assignment operator.
ConfigurationManager& operator=(const ConfigurationManager&&) = delete;
-private: // Data
- std::string mSystemCacheFilePath; ///< The path of system cache file
- GraphicsInterface* mGraphics; ///< Graphics interface
- ThreadController* mThreadController; ///< The thread controller
- unsigned int mMaxTextureSize; ///< The largest texture that the GL can handle
- unsigned int mShaderLanguageVersion; ///< The shader language version that the system supports.
- bool mIsMultipleWindowSupported : 1; ///< Whether multiple window is supported by the GLES
- bool mIsAdvancedBlendEquationSupported : 1; ///< Whether blend equation advanced (extension) is supported by the GLES
- bool mMaxTextureSizeCached : 1; ///< Whether we have checked the maximum texture size
- bool mIsMultipleWindowSupportedCached : 1; ///< Whether we have checked the support of multiple window
- bool mIsAdvancedBlendEquationSupportedCached : 1; ///< Whether we have checked the support of blend equation advanced (extension)
- bool mShaderLanguageVersionCached : 1; ///< Whether we have checked the shader language version
+private: // Data
+ std::string mSystemCacheFilePath; ///< The path of system cache file
+ GraphicsInterface* mGraphics; ///< Graphics interface
+ ThreadController* mThreadController; ///< The thread controller
+ unsigned int mMaxTextureSize; ///< The largest texture that the GL can handle
+ unsigned int mShaderLanguageVersion; ///< The shader language version that the system supports.
+ bool mIsMultipleWindowSupported : 1; ///< Whether multiple window is supported by the GLES
+ bool mIsAdvancedBlendEquationSupported : 1; ///< Whether blend equation advanced (extension) is supported by the GLES
+ bool mIsMultisampledRenderToTextureSupported : 1; ///< Whether multisampled render to texture (extension) is supported by the GLES
+ bool mMaxTextureSizeCached : 1; ///< Whether we have checked the maximum texture size
+ bool mIsMultipleWindowSupportedCached : 1; ///< Whether we have checked the support of multiple window
+ bool mIsAdvancedBlendEquationSupportedCached : 1; ///< Whether we have checked the support of blend equation advanced (extension)
+ bool mIsMultisampledRenderToTextureSupportedCached : 1; ///< Whether we have checked the support of multisampled render to texture (extension)
+ bool mShaderLanguageVersionCached : 1; ///< Whether we have checked the shader language version
};
} // namespace Adaptor