Merge "Fix coverity issue : Adaptor available check in async task manager" into devel...
authorEunki Hong <eunkiki.hong@samsung.com>
Tue, 6 Dec 2022 02:21:22 +0000 (02:21 +0000)
committerGerrit Code Review <gerrit@review>
Tue, 6 Dec 2022 02:21:22 +0000 (02:21 +0000)
30 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/devel-api/adaptor-framework/accessibility-bridge.h
dali/devel-api/adaptor-framework/accessibility.h
dali/devel-api/atspi-interfaces/accessible.h
dali/internal/accessibility/bridge/accessible.cpp
dali/internal/accessibility/bridge/bridge-object.cpp
dali/internal/accessibility/bridge/bridge-object.h
dali/internal/accessibility/bridge/dummy/dummy-atspi.cpp
dali/internal/accessibility/bridge/dummy/dummy-atspi.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
dali/internal/window-system/common/window-impl.cpp
dali/public-api/dali-adaptor-version.cpp
packaging/dali-adaptor.spec

index 7a31046..6021026 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 f6878ae..5e5fde3 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 3705eee..a1f8a2e 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.
@@ -148,6 +148,14 @@ public:
   }
 
   /**
+   * @return true if multisampled render to texture is supported
+   */
+  bool IsMultisampledRenderToTextureSupported() override
+  {
+    return true;
+  }
+
+  /**
    * @return true if graphics subsystem is initialized
    */
   bool IsInitialized() override
@@ -172,6 +180,14 @@ public:
   }
 
   /**
+   * @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
index 798aead..0737c69 100644 (file)
@@ -290,6 +290,20 @@ struct DALI_ADAPTOR_API Bridge
   virtual void EmitSocketAvailable(Accessible* obj) = 0;
 
   /**
+   * @brief Emits ScrollStarted event on at-spi bus.
+   *
+   * @param obj Accessible Object
+   */
+  virtual void EmitScrollStarted(Accessible *obj) = 0;
+
+    /**
+   * @brief Emits ScrollFinished event on at-spi bus.
+   *
+   * @param obj Accessible Object
+   */
+  virtual void EmitScrollFinished(Accessible *obj) = 0;
+
+  /**
    * @brief Emits state-changed event on at-spi bus.
    *
    * @param[in] obj The accessible object
index a3a8df4..cf26136 100644 (file)
@@ -506,6 +506,8 @@ enum class AtspiEvent
   ATTRIBUTES_CHANGED,\r
   MOVED_OUT,\r
   WINDOW_CHANGED,\r
+  SCROLL_STARTED,\r
+  SCROLL_FINISHED,\r
   MAX_COUNT\r
 };\r
 \r
index edac6d9..0156cc9 100644 (file)
@@ -139,6 +139,18 @@ public:
   void EmitSocketAvailable();
 
   /**
+   * @brief Emits "ScrollStarted" event.
+   *
+   */
+  void EmitScrollStarted();
+
+  /**
+   * @brief Emits "ScrollFinished" event.
+   *
+   */
+  void EmitScrollFinished();
+
+  /**
    * @brief Emits "highlighted" event.
    *
    * @param[in] event The enumerated window event
index c2a62b3..d0e2700 100644 (file)
@@ -125,6 +125,22 @@ void Accessible::EmitSocketAvailable()
   }
 }
 
+void Accessible::EmitScrollStarted()
+{
+  if(auto bridgeData = GetBridgeData())
+  {
+    bridgeData->mBridge->EmitScrollStarted(this);
+  }
+}
+
+void Accessible::EmitScrollFinished()
+{
+  if(auto bridgeData = GetBridgeData())
+  {
+    bridgeData->mBridge->EmitScrollFinished(this);
+  }
+}
+
 void Accessible::Emit(WindowEvent event, unsigned int detail)
 {
   if(auto bridgeData = GetBridgeData())
index 26b697c..d9c6d84 100644 (file)
@@ -315,3 +315,31 @@ void BridgeObject::EmitSocketAvailable(Accessible* obj)
     obj->GetAddress(),
     {"", "root"});
 }
+
+void BridgeObject::EmitScrollStarted(Accessible* obj)
+{
+  if(!IsUp() || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::SCROLL_STARTED])
+  {
+    return;
+  }
+
+  mDbusServer.emit2<Address>(
+    GetAccessiblePath(obj),
+    Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
+    "ScrollStarted",
+    {"", "root"});
+}
+
+void BridgeObject::EmitScrollFinished(Accessible* obj)
+{
+  if(!IsUp() || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::SCROLL_FINISHED])
+  {
+    return;
+  }
+
+  mDbusServer.emit2<Address>(
+    GetAccessiblePath(obj),
+    Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
+    "ScrollFinished",
+    {"", "root"});
+}
\ No newline at end of file
index 9784469..1b6637d 100644 (file)
@@ -90,6 +90,16 @@ protected:
    */
   void EmitSocketAvailable(Dali::Accessibility::Accessible* obj) override;
 
+  /**
+   * @copydoc Dali::Accessibility::Bridge::EmitScrollStarted()
+   */
+  void EmitScrollStarted(Dali::Accessibility::Accessible* obj) override;
+
+  /**
+   * @copydoc Dali::Accessibility::Bridge::EmitScrollFinished()
+   */
+  void EmitScrollFinished(Dali::Accessibility::Accessible* obj) override;
+
 protected:
   DBus::DBusInterfaceDescription::SignalId mStateChanged;
 };
index 713dd3c..b5e253b 100644 (file)
@@ -141,6 +141,14 @@ void Accessibility::Accessible::EmitSocketAvailable()
 {
 }
 
+void Accessibility::Accessible::EmitScrollStarted()
+{
+}
+
+void Accessibility::Accessible::EmitScrollFinished()
+{
+}
+
 void Accessibility::Accessible::NotifyAccessibilityStateChange(Accessibility::States states, bool isRecursive)
 {
 }
index 12c817b..0bbaccd 100644 (file)
@@ -142,6 +142,14 @@ struct DummyBridge : Dali::Accessibility::Bridge
   {
   }
 
+  void EmitScrollStarted(Accessibility::Accessible* obj) override
+  {
+  }
+
+  void EmitScrollFinished(Accessibility::Accessible* obj) override
+  {
+  }
+
   void EmitStateChanged(Accessibility::Accessible* obj, Accessibility::State state, int newValue, int reserved) override
   {
   }
index 6575a0c..08cc77d 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.
@@ -147,6 +147,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
    */
   virtual bool IsInitialized() = 0;
@@ -162,6 +167,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
    */
   virtual uint32_t GetShaderLanguageVersion() = 0;
index 1aaa12f..e40507a 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 f5f750b..6695fbf 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 b48af2c..430b395 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 a963e28..15e17f1 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 399ff1a..48dd0b7 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 1790fe5..062af6b 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.
@@ -42,6 +42,10 @@ GlExtensions::GlExtensions()
 #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 fe457e2..859f450 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 b7551a4..61c2c08 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 80e0c6e..f3cb780 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 4ca86b3..527cebf 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 dbdeddf..178443b 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 12c1c9a..0515b46 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 148b928..7fc767e 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
index 9581f2e..673f0bd 100644 (file)
@@ -208,6 +208,10 @@ void Window::OnAdaptorSet(Dali::Adaptor& adaptor)
     auto rootLayer  = mScene.GetRootLayer();
     auto accessible = Accessibility::Accessible::Get(rootLayer);
     bridge->AddTopLevelWindow(accessible);
+
+    // Emit Window create event
+    // Create and Destory signal only emit in multi-window environment, so it does not emit on default layer.
+    bridge->Emit(accessible, Accessibility::WindowEvent::CREATE);
   }
 
   bridge->EnabledSignal().Connect(this, &Window::OnAccessibilityEnabled);
index 307cecd..e98c02f 100644 (file)
@@ -27,7 +27,7 @@ namespace Dali
 {
 const unsigned int ADAPTOR_MAJOR_VERSION = 2;
 const unsigned int ADAPTOR_MINOR_VERSION = 2;
-const unsigned int ADAPTOR_MICRO_VERSION = 3;
+const unsigned int ADAPTOR_MICRO_VERSION = 4;
 const char* const  ADAPTOR_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index d5a7016..ebe6a75 100644 (file)
@@ -17,7 +17,7 @@
 
 Name:       dali2-adaptor
 Summary:    The DALi Tizen Adaptor
-Version:    2.2.3
+Version:    2.2.4
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT