Support MultiSampling FrameBuffer 14/284214/18
authorEunki, Hong <eunkiki.hong@samsung.com>
Fri, 11 Nov 2022 13:51:29 +0000 (22:51 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Thu, 1 Dec 2022 09:46:04 +0000 (18:46 +0900)
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>
19 files changed:
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-gl-abstraction.cpp
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-gl-abstraction.h
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-application.h
dali/internal/graphics/common/graphics-interface.h
dali/internal/graphics/file.list
dali/internal/graphics/gles-impl/gles-graphics-framebuffer.cpp
dali/internal/graphics/gles-impl/gles-graphics-framebuffer.h
dali/internal/graphics/gles/egl-graphics.cpp
dali/internal/graphics/gles/egl-graphics.h
dali/internal/graphics/gles/gl-extensions-support.cpp [new file with mode: 0644]
dali/internal/graphics/gles/gl-extensions-support.h [new file with mode: 0644]
dali/internal/graphics/gles/gl-extensions.cpp
dali/internal/graphics/gles/gl-extensions.h
dali/internal/graphics/gles/gl-implementation.h
dali/internal/graphics/gles/gles-abstraction.h
dali/internal/graphics/gles/gles2-implementation.h
dali/internal/graphics/gles/gles3-implementation.h
dali/internal/system/common/configuration-manager.cpp
dali/internal/system/common/configuration-manager.h

index 7a31046b7b1dbf188463146ea0c46b62ac2c9ee0..6021026cf9340ad4ac48e69a52aacb480eafc3b5 100644 (file)
@@ -166,6 +166,11 @@ bool TestGlAbstraction::IsAdvancedBlendEquationSupported()
   return true;
 }
 
+bool TestGlAbstraction::IsMultisampledRenderToTextureSupported()
+{
+  return true;
+}
+
 bool TestGlAbstraction::IsBlendEquationSupported(DevelBlendEquation::Type blendEquation)
 {
   return true;
index f6878ae7ca3be575470275cc0528ba2b3ecabfdc..5e5fde3dbb57d1ec21c91da0d0933fd398f858b7 100644 (file)
@@ -72,6 +72,8 @@ public:
 
   bool IsAdvancedBlendEquationSupported() override;
 
+  bool IsMultisampledRenderToTextureSupported() override;
+
   bool IsBlendEquationSupported(DevelBlendEquation::Type blendEquation) override;
 
   std::string GetShaderVersionPrefix();
@@ -1702,6 +1704,12 @@ public:
   {
   }
 
+  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
   {
   }
index 3705eee8a7feb23b06ac5e9fd7edbdb0f0d51e49..a1f8a2e70937cb782fadb19a7ba221dd54a0f09f 100644 (file)
@@ -2,7 +2,7 @@
 #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.
@@ -147,6 +147,14 @@ public:
     return true;
   }
 
+  /**
+   * @return true if multisampled render to texture is supported
+   */
+  bool IsMultisampledRenderToTextureSupported() override
+  {
+    return true;
+  }
+
   /**
    * @return true if graphics subsystem is initialized
    */
@@ -171,6 +179,14 @@ public:
     return 32768u;
   }
 
+  /**
+   * @return the maximum texture samples when we use multisampled texture
+   */
+  uint8_t GetMaxTextureSamples() override
+  {
+    return 8u;
+  }
+
   /**
    * @return the version number of the shader language
    */
index 6575a0ced36aa3c9ebffe67a99da3fe90c349e7c..08cc77d5f3634270d00bebc5aba78d1686afdb24 100644 (file)
@@ -2,7 +2,7 @@
 #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.
@@ -146,6 +146,11 @@ public:
    */
   virtual bool IsAdvancedBlendEquationSupported() = 0;
 
+  /**
+   * @return true if multisampled render to texture is supported
+   */
+  virtual bool IsMultisampledRenderToTextureSupported() = 0;
+
   /**
    * @return true if graphics subsystem is initialized
    */
@@ -161,6 +166,11 @@ public:
    */
   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
    */
index 1aaa12fb10ee571fbcb4660e0d4fd8107d15422f..e40507adc10392ab40315c1eef99131734dc3a8c 100644 (file)
@@ -6,6 +6,7 @@ SET( adaptor_graphics_gles_src_files
     ${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
index f5f750b5ccdcf3c94e862308d8a694092400dcca..6695fbf7cfec87bc9631f7663ef9e4de438a57a0 100644 (file)
@@ -84,6 +84,12 @@ struct DEPTH_STENCIL_ATTACHMENT_TYPE
 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);
 }
@@ -137,30 +143,32 @@ bool Framebuffer::InitializeResource()
 
       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);
@@ -213,13 +221,14 @@ void Framebuffer::AttachTexture(const Graphics::Texture* texture, uint32_t attac
   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);
     }
   }
 }
index b48af2cce1baee84654301ad521c9df66cef149d..430b395f53c8990aaea2b18f20392522841fcaf3 100644 (file)
@@ -2,7 +2,7 @@
 #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.
@@ -86,6 +86,7 @@ private:
   uint32_t mFramebufferId{0u};
   uint32_t mDepthBufferId{0u};
   uint32_t mStencilBufferId{0u};
+  uint32_t mMultisamples{1u};
   bool     mInitialized{false};
 };
 
index a963e28f6c32e93e643b87da1ae469f1eef4b20a..15e17f1935abdfa8c5cd8d9fddd5fe33d229fd33 100644 (file)
@@ -247,6 +247,7 @@ Graphics::Controller& EglGraphics::GetController()
 void EglGraphics::CacheConfigurations(ConfigurationManager& configurationManager)
 {
   mGLES->SetIsAdvancedBlendEquationSupported(configurationManager.IsAdvancedBlendEquationSupported());
+  mGLES->SetIsMultisampledRenderToTextureSupported(configurationManager.IsMultisampledRenderToTextureSupported());
   mGLES->SetShadingLanguageVersion(configurationManager.GetShadingLanguageVersion());
 }
 
index 399ff1acb96f0e751bd291fd705f0de525c47389..48dd0b7e2b409e7e0d8ef71bb741a9237adc25b6 100644 (file)
@@ -2,7 +2,7 @@
 #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.
@@ -171,6 +171,11 @@ public:
     return mGLES->IsAdvancedBlendEquationSupported();
   }
 
+  bool IsMultisampledRenderToTextureSupported() override
+  {
+    return mGLES->IsMultisampledRenderToTextureSupported();
+  }
+
   /**
    * @return true if graphics subsystem is initialized
    */
@@ -189,6 +194,11 @@ public:
     return mGLES->GetMaxTextureSize();
   }
 
+  uint8_t GetMaxTextureSamples() override
+  {
+    return mGLES->GetMaxTextureSamples();
+  }
+
   uint32_t GetShaderLanguageVersion() override
   {
     return mGLES->GetShadingLanguageVersion();
diff --git a/dali/internal/graphics/gles/gl-extensions-support.cpp b/dali/internal/graphics/gles/gl-extensions-support.cpp
new file mode 100644 (file)
index 0000000..b5e04d4
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * 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(),
+                                   [&currentExtension](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
diff --git a/dali/internal/graphics/gles/gl-extensions-support.h b/dali/internal/graphics/gles/gl-extensions-support.h
new file mode 100644 (file)
index 0000000..6caa497
--- /dev/null
@@ -0,0 +1,181 @@
+#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 */
index 1790fe5fa975882bb426be539bc7f7eacfaecc3b..062af6b62837a701ffdb29ec8b1ab2a989bcde5f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -41,6 +41,10 @@ GlExtensions::GlExtensions()
 #endif
 #ifdef GL_KHR_blend_equation_advanced
   mBlendBarrierKHR(nullptr),
+#endif
+#ifdef GL_EXT_multisampled_render_to_texture
+  mGlRenderbufferStorageMultisampleEXT(nullptr),
+  mGlFramebufferTexture2DMultisampleEXT(nullptr),
 #endif
   mInitialized(false)
 {
@@ -54,7 +58,7 @@ void GlExtensions::DiscardFrameBuffer(GLenum target, GLsizei numAttachments, con
 {
   // 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();
   }
@@ -75,7 +79,7 @@ void GlExtensions::GetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei*
 {
   // 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();
   }
@@ -97,7 +101,7 @@ void GlExtensions::ProgramBinaryOES(GLuint program, GLenum binaryFormat, const G
 {
   // 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();
   }
@@ -119,7 +123,7 @@ bool GlExtensions::BlendBarrierKHR()
 {
   // 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();
   }
@@ -136,6 +140,50 @@ bool GlExtensions::BlendBarrierKHR()
   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;
@@ -152,6 +200,11 @@ void GlExtensions::Initialize()
 #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
index fe457e2bfaecb94e0f24f1b2cf112f4046255405..859f4502bb0866907f1560e904be7ecc846519fb 100644 (file)
@@ -2,7 +2,7 @@
 #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.
@@ -87,6 +87,32 @@ public:
    */
   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
@@ -106,6 +132,11 @@ private:
   PFNGLBLENDBARRIERKHRPROC mBlendBarrierKHR;
 #endif
 
+#ifdef GL_EXT_multisampled_render_to_texture
+  PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC  mGlRenderbufferStorageMultisampleEXT;
+  PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC mGlFramebufferTexture2DMultisampleEXT;
+#endif
+
   bool mInitialized;
 };
 
index b7551a45148c1fba47186bf7fdf50a5ac86b07a7..61c2c08638411a50365681e6d324f7d30fdcffa2 100644 (file)
@@ -2,7 +2,7 @@
 #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>
@@ -44,7 +46,6 @@ 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 const char* DEFAULT_SAMPLER_TYPE = "sampler2D";
 
@@ -63,6 +64,7 @@ static constexpr const char* FRAGMENT_SHADER_OUTPUT_COLOR_STRING =
 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
 
 /**
@@ -74,15 +76,15 @@ class GlImplementation : public Dali::Integration::GlAbstraction
 {
 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());
@@ -117,25 +119,18 @@ public:
 
     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)
@@ -193,18 +188,36 @@ public:
 
   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)
@@ -337,6 +350,16 @@ public:
     return mMaxTextureSize;
   }
 
+  int GetMaxTextureSamples()
+  {
+    ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
+    if(!mIsContextCreated)
+    {
+      mContextCreatedWaitCondition.Wait(lock);
+    }
+    return mMaxTextureSamples;
+  }
+
   int GetGlesVersion()
   {
     ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
@@ -371,7 +394,7 @@ public:
     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)
       {
@@ -1250,6 +1273,11 @@ public:
     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);
@@ -1647,7 +1675,7 @@ public:
 
   void BlendBarrier(void)
   {
-    if(mIsAdvancedBlendEquationSupported)
+    if(mGlExtensionSupportedCacheList.IsSupported(GlExtensionCache::GlExtensionCheckerType::BLEND_EQUATION_ADVANCED))
     {
       mImpl->BlendBarrier();
     }
@@ -1656,8 +1684,11 @@ public:
 private:
   std::unique_ptr<GlesAbstraction> mImpl;
 
+  GlExtensionCache::GlExtensionSupportedCacheList mGlExtensionSupportedCacheList;
+
   ConditionalWait mContextCreatedWaitCondition;
   GLint           mMaxTextureSize;
+  GLint           mMaxTextureSamples;
   std::string     mShaderVersionPrefix;
   std::string     mVertexShaderPrefix;
   std::string     mFragmentShaderPrefix;
@@ -1665,8 +1696,6 @@ private:
   int32_t         mShadingLanguageVersion;
   bool            mShadingLanguageVersionCached;
   bool            mIsSurfacelessContextSupported;
-  bool            mIsAdvancedBlendEquationSupportedCached;
-  bool            mIsAdvancedBlendEquationSupported;
   bool            mIsContextCreated;
 };
 
index 80e0c6e115f19f4ad7018b5a4edd0862fb93c628..f3cb780c4ba2b5a372307f91fb7fcaf3547a5832 100644 (file)
@@ -2,7 +2,7 @@
 #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.
@@ -82,6 +82,8 @@ public:
 
   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;
index 4ca86b3c4788d6d59f9ac29c39e3e79bf81d8f8b..527cebfff5976cf2f80d68316aa5fee0d740adda 100644 (file)
@@ -2,7 +2,7 @@
 #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.
@@ -166,7 +166,12 @@ public:
 
   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
index dbdeddf722761666e32022c35e860186ef061ba1..178443be88a90713f3ef34afa34fb11ba4d774bd 100644 (file)
@@ -2,7 +2,7 @@
 #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.
@@ -164,7 +164,14 @@ public:
 
   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
index 12c1c9a406378890d442376f37435a94e6408112..0515b46a4013e2e7a668dd07ccf1bf9433d495b1 100644 (file)
@@ -37,10 +37,11 @@ namespace Adaptor
 {
 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
 
@@ -52,9 +53,11 @@ ConfigurationManager::ConfigurationManager(std::string systemCachePath, Graphics
   mShaderLanguageVersion(0u),
   mIsMultipleWindowSupported(true),
   mIsAdvancedBlendEquationSupported(true),
+  mIsMultisampledRenderToTextureSupported(true),
   mMaxTextureSizeCached(false),
   mIsMultipleWindowSupportedCached(false),
   mIsAdvancedBlendEquationSupportedCached(false),
+  mIsMultisampledRenderToTextureSupportedCached(false),
   mShaderLanguageVersionCached(false)
 {
 }
@@ -95,6 +98,12 @@ void ConfigurationManager::RetrieveKeysFromConfigFile(const std::string& configF
         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);
@@ -250,6 +259,41 @@ bool ConfigurationManager::IsAdvancedBlendEquationSupported()
   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
index 148b9287a158e0f41d048edb8927aa8dbce954a3..7fc767e523a3aee1fbb7bce96142363aae2d91dd 100644 (file)
@@ -2,7 +2,7 @@
 #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.
@@ -76,9 +76,14 @@ public:
 
   /**
    * @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;
@@ -92,18 +97,20 @@ public:
   // 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