Revert "[Tizen] Reset To 2.3.41"
authorEunki, Hong <eunkiki.hong@samsung.com>
Wed, 16 Oct 2024 06:50:14 +0000 (15:50 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Wed, 16 Oct 2024 06:50:14 +0000 (15:50 +0900)
This reverts commit 02d480ee28b80ab0df126a6efa2d4ef77197eac8.

124 files changed:
.gitignore
automated-tests/src/dali-adaptor-internal/utc-Dali-ImageOperations.cpp
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-controller.cpp
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-controller.h
build/tizen/deps-check.cmake
dali/devel-api/adaptor-framework/accessibility.cpp
dali/devel-api/adaptor-framework/atspi-accessibility.cpp
dali/devel-api/adaptor-framework/atspi-accessibility.h
dali/devel-api/adaptor-framework/key-devel.h
dali/devel-api/adaptor-framework/web-engine/web-engine-plugin.h
dali/devel-api/adaptor-framework/web-engine/web-engine-user-media-permission-request.h [new file with mode: 0755]
dali/devel-api/adaptor-framework/web-engine/web-engine.cpp
dali/devel-api/adaptor-framework/web-engine/web-engine.h
dali/devel-api/adaptor-framework/window-blur-info.cpp
dali/devel-api/adaptor-framework/window-blur-info.h
dali/devel-api/adaptor-framework/window-devel.cpp
dali/devel-api/adaptor-framework/window-devel.h
dali/devel-api/atspi-interfaces/collection.h
dali/devel-api/file.list
dali/integration-api/adaptor-framework/shader-precompiler.cpp
dali/integration-api/adaptor-framework/shader-precompiler.h
dali/internal/accessibility/bridge/bridge-base.cpp
dali/internal/accessibility/bridge/bridge-collection.cpp
dali/internal/accessibility/bridge/bridge-collection.h
dali/internal/accessibility/bridge/collection.cpp [new file with mode: 0644]
dali/internal/accessibility/file.list
dali/internal/adaptor/common/combined-update-render-controller.cpp
dali/internal/drag-and-drop/tizen-wayland/drag-and-drop-impl-ecore-wl2.cpp
dali/internal/graphics/common/shader-parser.cpp
dali/internal/graphics/gles-impl/egl-graphics-controller.cpp
dali/internal/graphics/gles-impl/egl-graphics-controller.h
dali/internal/graphics/gles-impl/egl-sync-object.cpp
dali/internal/graphics/gles-impl/gles-graphics-buffer.cpp
dali/internal/graphics/gles-impl/gles-graphics-framebuffer.cpp
dali/internal/graphics/gles-impl/gles-graphics-pipeline-cache.cpp
dali/internal/graphics/gles-impl/gles-graphics-pipeline.cpp
dali/internal/graphics/gles-impl/gles-graphics-program.cpp
dali/internal/graphics/gles-impl/gles-graphics-shader.cpp
dali/internal/graphics/gles-impl/gles-graphics-shader.h
dali/internal/graphics/gles-impl/gles-graphics-texture.cpp
dali/internal/graphics/gles-impl/gles-sync-object.cpp
dali/internal/graphics/gles-impl/gles-sync-pool.cpp
dali/internal/graphics/gles-impl/gles2-graphics-memory.cpp
dali/internal/graphics/gles-impl/gles3-graphics-memory.cpp
dali/internal/graphics/tizen/egl-sync-implementation-tizen.cpp
dali/internal/graphics/vulkan-impl/vulkan-buffer-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-buffer-impl.h
dali/internal/graphics/vulkan-impl/vulkan-buffer.cpp
dali/internal/graphics/vulkan-impl/vulkan-buffer.h
dali/internal/graphics/vulkan-impl/vulkan-command-buffer-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-command-buffer-impl.h
dali/internal/graphics/vulkan-impl/vulkan-command-buffer.cpp
dali/internal/graphics/vulkan-impl/vulkan-command-buffer.h
dali/internal/graphics/vulkan-impl/vulkan-command-pool-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-command-pool-impl.h
dali/internal/graphics/vulkan-impl/vulkan-fence-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-fence-impl.h
dali/internal/graphics/vulkan-impl/vulkan-framebuffer-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-framebuffer-impl.h
dali/internal/graphics/vulkan-impl/vulkan-framebuffer.cpp
dali/internal/graphics/vulkan-impl/vulkan-framebuffer.h
dali/internal/graphics/vulkan-impl/vulkan-graphics-controller.cpp
dali/internal/graphics/vulkan-impl/vulkan-graphics-controller.h
dali/internal/graphics/vulkan-impl/vulkan-graphics-resource.h
dali/internal/graphics/vulkan-impl/vulkan-handle.h [new file with mode: 0644]
dali/internal/graphics/vulkan-impl/vulkan-image-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-image-impl.h
dali/internal/graphics/vulkan-impl/vulkan-image-view-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-image-view-impl.h
dali/internal/graphics/vulkan-impl/vulkan-memory-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-memory-impl.h
dali/internal/graphics/vulkan-impl/vulkan-pipeline-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-pipeline-impl.h
dali/internal/graphics/vulkan-impl/vulkan-pipeline.cpp
dali/internal/graphics/vulkan-impl/vulkan-pipeline.h
dali/internal/graphics/vulkan-impl/vulkan-program-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-program-impl.h
dali/internal/graphics/vulkan-impl/vulkan-program.cpp
dali/internal/graphics/vulkan-impl/vulkan-program.h
dali/internal/graphics/vulkan-impl/vulkan-reflection.cpp
dali/internal/graphics/vulkan-impl/vulkan-reflection.h
dali/internal/graphics/vulkan-impl/vulkan-render-pass-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-render-pass-impl.h
dali/internal/graphics/vulkan-impl/vulkan-render-target.cpp
dali/internal/graphics/vulkan-impl/vulkan-render-target.h
dali/internal/graphics/vulkan-impl/vulkan-resource-transfer-request.h
dali/internal/graphics/vulkan-impl/vulkan-sampler-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-sampler-impl.h
dali/internal/graphics/vulkan-impl/vulkan-sampler.cpp
dali/internal/graphics/vulkan-impl/vulkan-sampler.h
dali/internal/graphics/vulkan-impl/vulkan-shader-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-shader-impl.h
dali/internal/graphics/vulkan-impl/vulkan-surface-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-surface-impl.h
dali/internal/graphics/vulkan-impl/vulkan-swapchain-impl.cpp
dali/internal/graphics/vulkan-impl/vulkan-swapchain-impl.h
dali/internal/graphics/vulkan-impl/vulkan-texture.cpp
dali/internal/graphics/vulkan-impl/vulkan-texture.h
dali/internal/graphics/vulkan-impl/vulkan-types.h
dali/internal/graphics/vulkan/vulkan-device.cpp
dali/internal/graphics/vulkan/vulkan-device.h
dali/internal/graphics/vulkan/vulkan-graphics-impl.cpp
dali/internal/imaging/common/image-operations.cpp
dali/internal/imaging/common/loader-jpeg-turbo.cpp
dali/internal/web-engine/common/web-engine-impl.cpp
dali/internal/web-engine/common/web-engine-impl.h
dali/internal/window-system/android/window-base-android.cpp
dali/internal/window-system/android/window-base-android.h
dali/internal/window-system/common/window-base.h
dali/internal/window-system/common/window-impl.cpp
dali/internal/window-system/common/window-impl.h
dali/internal/window-system/macos/window-base-mac.h
dali/internal/window-system/macos/window-base-mac.mm
dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp
dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.h
dali/internal/window-system/ubuntu-x11/window-base-ecore-x.cpp
dali/internal/window-system/ubuntu-x11/window-base-ecore-x.h
dali/internal/window-system/windows/window-base-win.cpp
dali/internal/window-system/windows/window-base-win.h
dali/internal/window-system/x11/window-base-x.cpp
dali/internal/window-system/x11/window-base-x.h
dali/public-api/adaptor-framework/window-enumerations.h
dali/public-api/dali-adaptor-version.cpp
packaging/dali-adaptor.spec

index 104aa334fcf8550d7a8713ebd048615e679b2b0d..5e20af5346eed0d8476955862d529739b8e85036 100644 (file)
@@ -42,6 +42,7 @@ install_manifest.txt
 /build/tizen/.cov
 /build/tizen/.ninja_deps
 /build/tizen/.ninja_log
+/build/tizen/clion/
 /build/tizen/build.ninja
 /build/tizen/rules.ninja
 /build/desktop
index 6c54a622e46e56b0116b009a97282a2e04d8be39..93e39bca5f4764cb4a895726b0b3c6e7bd1a578c 100644 (file)
@@ -342,6 +342,8 @@ int UtcDaliImageOperationsAveragePixelRGB565(void)
   END_TEST;
 }
 
+namespace
+{
 /**
  * @brief Build a square bitmap, downscale it and assert the resulting bitmap has the right dimensions.
  */
@@ -365,6 +367,99 @@ void TestDownscaledBitmapHasRightDimensionsAndFormat(
   DALI_TEST_EQUALS(downScaled.GetPixelFormat(), format, location);
 }
 
+/**
+ * @brief Test that resizing RGBA8888 images as raw pixel arrays produces a result of the correct dimensions.
+ */
+void TestDownscaleOutputsExpectedDimensionsRGBA8888(uint32_t pixels[], unsigned inputWidth, unsigned inputHeight, unsigned int desiredWidth, unsigned int desiredHeight, unsigned int expectedWidth, unsigned int expectedHeight, const char* const location)
+{
+  unsigned int resultingWidth = -1, resultingHeight = -1, resultingStride = -1;
+  Dali::Internal::Platform::DownscaleInPlacePow2RGBA8888(
+    reinterpret_cast<unsigned char*>(pixels),
+    inputWidth,
+    inputHeight,
+    inputWidth,
+    desiredWidth,
+    desiredHeight,
+    BoxDimensionTestBoth,
+    resultingWidth,
+    resultingHeight,
+    resultingStride);
+
+  DALI_TEST_EQUALS(resultingWidth, expectedWidth, location);
+  DALI_TEST_EQUALS(resultingHeight, expectedHeight, location);
+  DALI_TEST_EQUALS(resultingStride, expectedWidth, location);
+}
+
+/**
+ * @brief Test that resizing RGB565 images as raw pixel arrays produces a result of the correct dimensions.
+ */
+void TestDownscaleOutputsExpectedDimensionsRGB565(uint16_t pixels[], unsigned inputWidth, unsigned inputHeight, unsigned int desiredWidth, unsigned int desiredHeight, unsigned int expectedWidth, unsigned int expectedHeight, const char* const location)
+{
+  unsigned int resultingWidth = -1, resultingHeight = -1, resultingStride = -1;
+  Dali::Internal::Platform::DownscaleInPlacePow2RGB565(
+    reinterpret_cast<unsigned char*>(pixels),
+    inputWidth,
+    inputHeight,
+    inputWidth,
+    desiredWidth,
+    desiredHeight,
+    BoxDimensionTestBoth,
+    resultingWidth,
+    resultingHeight,
+    resultingStride);
+
+  DALI_TEST_EQUALS(resultingWidth, expectedWidth, location);
+  DALI_TEST_EQUALS(resultingHeight, expectedHeight, location);
+  DALI_TEST_EQUALS(resultingStride, expectedWidth, location);
+}
+
+/**
+ * @brief Test that resizing 2-byte-per-pixel images as raw pixel arrays produces a result of the correct dimensions.
+ */
+void TestDownscaleOutputsExpectedDimensions2ComponentPair(uint8_t pixels[], unsigned inputWidth, unsigned inputHeight, unsigned int desiredWidth, unsigned int desiredHeight, unsigned int expectedWidth, unsigned int expectedHeight, const char* const location)
+{
+  unsigned int resultingWidth = -1, resultingHeight = -1, resultingStride = -1;
+  Dali::Internal::Platform::DownscaleInPlacePow2ComponentPair(
+    pixels,
+    inputWidth,
+    inputHeight,
+    inputWidth,
+    desiredWidth,
+    desiredHeight,
+    BoxDimensionTestBoth,
+    resultingWidth,
+    resultingHeight,
+    resultingStride);
+
+  DALI_TEST_EQUALS(resultingWidth, expectedWidth, location);
+  DALI_TEST_EQUALS(resultingHeight, expectedHeight, location);
+  DALI_TEST_EQUALS(resultingStride, expectedWidth, location);
+}
+
+/**
+ * @brief Test that resizing single-byte-per-pixel images as raw pixel arrays produces a result of the correct dimensions.
+ */
+void TestDownscaleOutputsExpectedDimensionsSingleComponent(uint8_t pixels[], unsigned inputWidth, unsigned inputHeight, unsigned int desiredWidth, unsigned int desiredHeight, unsigned int expectedWidth, unsigned int expectedHeight, const char* const location)
+{
+  unsigned int resultingWidth = -1, resultingHeight = -1, resultingStride = -1;
+  Dali::Internal::Platform::DownscaleInPlacePow2SingleBytePerPixel(
+    pixels,
+    inputWidth,
+    inputHeight,
+    inputWidth,
+    desiredWidth,
+    desiredHeight,
+    BoxDimensionTestBoth,
+    resultingWidth,
+    resultingHeight,
+    resultingStride);
+
+  DALI_TEST_EQUALS(resultingWidth, expectedWidth, location);
+  DALI_TEST_EQUALS(resultingHeight, expectedHeight, location);
+  DALI_TEST_EQUALS(resultingStride, expectedWidth, location);
+}
+} // namespace
+
 /**
  * @brief Test the top-level function for reducing the dimension of a bitmap,
  * feeding it each of the five pixel formats that are output by image loaders.
@@ -502,98 +597,6 @@ int UtcDaliImageOperationsDownscaleInPlacePow2RGB888(void)
   END_TEST;
 }
 
-/**
- * @brief Test that resizing RGBA8888 images as raw pixel arrays produces a result of the correct dimensions.
- */
-void TestDownscaleOutputsExpectedDimensionsRGBA8888(uint32_t pixels[], unsigned inputWidth, unsigned inputHeight, unsigned int desiredWidth, unsigned int desiredHeight, unsigned int expectedWidth, unsigned int expectedHeight, const char* const location)
-{
-  unsigned int resultingWidth = -1, resultingHeight = -1, resultingStride = -1;
-  Dali::Internal::Platform::DownscaleInPlacePow2RGBA8888(
-    reinterpret_cast<unsigned char*>(pixels),
-    inputWidth,
-    inputHeight,
-    inputWidth,
-    desiredWidth,
-    desiredHeight,
-    BoxDimensionTestBoth,
-    resultingWidth,
-    resultingHeight,
-    resultingStride);
-
-  DALI_TEST_EQUALS(resultingWidth, expectedWidth, location);
-  DALI_TEST_EQUALS(resultingHeight, expectedHeight, location);
-  DALI_TEST_EQUALS(resultingStride, expectedWidth, location);
-}
-
-/**
- * @brief Test that resizing RGB565 images as raw pixel arrays produces a result of the correct dimensions.
- */
-void TestDownscaleOutputsExpectedDimensionsRGB565(uint16_t pixels[], unsigned inputWidth, unsigned inputHeight, unsigned int desiredWidth, unsigned int desiredHeight, unsigned int expectedWidth, unsigned int expectedHeight, const char* const location)
-{
-  unsigned int resultingWidth = -1, resultingHeight = -1, resultingStride = -1;
-  Dali::Internal::Platform::DownscaleInPlacePow2RGB565(
-    reinterpret_cast<unsigned char*>(pixels),
-    inputWidth,
-    inputHeight,
-    inputWidth,
-    desiredWidth,
-    desiredHeight,
-    BoxDimensionTestBoth,
-    resultingWidth,
-    resultingHeight,
-    resultingStride);
-
-  DALI_TEST_EQUALS(resultingWidth, expectedWidth, location);
-  DALI_TEST_EQUALS(resultingHeight, expectedHeight, location);
-  DALI_TEST_EQUALS(resultingStride, expectedWidth, location);
-}
-
-/**
- * @brief Test that resizing 2-byte-per-pixel images as raw pixel arrays produces a result of the correct dimensions.
- */
-void TestDownscaleOutputsExpectedDimensions2ComponentPair(uint8_t pixels[], unsigned inputWidth, unsigned inputHeight, unsigned int desiredWidth, unsigned int desiredHeight, unsigned int expectedWidth, unsigned int expectedHeight, const char* const location)
-{
-  unsigned int resultingWidth = -1, resultingHeight = -1, resultingStride = -1;
-  Dali::Internal::Platform::DownscaleInPlacePow2ComponentPair(
-    pixels,
-    inputWidth,
-    inputHeight,
-    inputWidth,
-    desiredWidth,
-    desiredHeight,
-    BoxDimensionTestBoth,
-    resultingWidth,
-    resultingHeight,
-    resultingStride);
-
-  DALI_TEST_EQUALS(resultingWidth, expectedWidth, location);
-  DALI_TEST_EQUALS(resultingHeight, expectedHeight, location);
-  DALI_TEST_EQUALS(resultingStride, expectedWidth, location);
-}
-
-/**
- * @brief Test that resizing single-byte-per-pixel images as raw pixel arrays produces a result of the correct dimensions.
- */
-void TestDownscaleOutputsExpectedDimensionsSingleComponent(uint8_t pixels[], unsigned inputWidth, unsigned inputHeight, unsigned int desiredWidth, unsigned int desiredHeight, unsigned int expectedWidth, unsigned int expectedHeight, const char* const location)
-{
-  unsigned int resultingWidth = -1, resultingHeight = -1, resultingStride = -1;
-  Dali::Internal::Platform::DownscaleInPlacePow2SingleBytePerPixel(
-    pixels,
-    inputWidth,
-    inputHeight,
-    inputWidth,
-    desiredWidth,
-    desiredHeight,
-    BoxDimensionTestBoth,
-    resultingWidth,
-    resultingHeight,
-    resultingStride);
-
-  DALI_TEST_EQUALS(resultingWidth, expectedWidth, location);
-  DALI_TEST_EQUALS(resultingHeight, expectedHeight, location);
-  DALI_TEST_EQUALS(resultingStride, expectedWidth, location);
-}
-
 /**
  * @brief Test downscaling of RGBA8888 images in raw image arrays.
  */
index f0bc4d6d5dde5f659628ac54300d245fe7d59403..114879fb4faa9ec6e36cc41e6f9dba7419e38aef 100644 (file)
@@ -1505,4 +1505,22 @@ Graphics::UniquePtr<Graphics::Texture> TestGraphicsController::ReleaseTextureFro
   return texture;
 }
 
+bool TestGraphicsController::HasClipMatrix() const
+{
+  return true;
+}
+
+const Matrix& TestGraphicsController::GetClipMatrix() const
+{
+  // This matrix transforms from GL -> Vulkan clip space
+  constexpr float VULKAN_CLIP_MATRIX_DATA[] = {
+    1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 1.0f};
+  static const Matrix VULKAN_CLIP_MATRIX(VULKAN_CLIP_MATRIX_DATA);
+  static const Matrix IDENTITY = Matrix::IDENTITY;
+
+  // For now, return IDENTITY to stay in GL clip space.
+  // @todo Add test toggle
+  return IDENTITY;
+}
+
 } // namespace Dali
index e21c30400f009814a08b0683288f1a7d6f5b05f3..2b0a9b97aaedb4ab9ee2facf08ba104f15b74ca6 100644 (file)
@@ -422,6 +422,9 @@ public: // ResourceId relative API.
    */
   Graphics::UniquePtr<Graphics::Texture> ReleaseTextureFromResourceId(uint32_t resourceId) override;
 
+  bool          HasClipMatrix() const override;
+  const Matrix& GetClipMatrix() const override;
+
 public: // Test Functions
   void SetAutoAttrCreation(bool v)
   {
@@ -499,14 +502,14 @@ public: // Test Functions
                                uint32_t                                      elementStrideInBytes)
   {
     TestGraphicsReflection::TestUniformInfo info;
-    info.name          = std::move(name);
-    info.type          = type;
-    info.uniformClass  = Graphics::UniformClass::UNIFORM;
-    info.numElements   = elementCount;
-    info.locations     = {0};
-    info.bufferIndex   = 0;                    // this will update when AddCustomUniformBlock called
-
-    auto retval= GetUniformBufferArrayStrideAndTypeSize(info, elementStrideInBytes);
+    info.name         = std::move(name);
+    info.type         = type;
+    info.uniformClass = Graphics::UniformClass::UNIFORM;
+    info.numElements  = elementCount;
+    info.locations    = {0};
+    info.bufferIndex  = 0; // this will update when AddCustomUniformBlock called
+
+    auto retval        = GetUniformBufferArrayStrideAndTypeSize(info, elementStrideInBytes);
     info.elementStride = std::max(retval.first, retval.second);
     info.offsets       = {blockInfo.size};
     blockInfo.size += (elementCount == 0 ? 1 : elementCount) * std::max(retval.first, retval.second);
@@ -567,4 +570,4 @@ public:
 
 } // namespace Dali
 
-#endif //TEST_GRAPHICS_CONTROLLER_H
+#endif // TEST_GRAPHICS_CONTROLLER_H
index e350c04fb8d53b6ea6bfd2a68b67a116d9a3e347..e3a8e4c68fd83879aa68cd8df14eaf6c4998da82 100644 (file)
@@ -119,16 +119,11 @@ CHECK_MODULE_AND_SET( ECORE_IMF ecore-imf [] )
 CHECK_MODULE_AND_SET( ELDBUS eldbus>=${ELDBUS_REQUIRED} eldbus_available )
 CHECK_MODULE_AND_SET( TPKP_CURL tpkp-curl tpkp_curl_available )
 CHECK_MODULE_AND_SET( UTILX utilX utilx_available )
-CHECK_MODULE_AND_SET( OPENGLES20 glesv2 [] )
-CHECK_MODULE_AND_SET( EGL egl [] )
 CHECK_MODULE_AND_SET( DLOG dlog [] )
 CHECK_MODULE_AND_SET( TTS tts [] )
 CHECK_MODULE_AND_SET( VCONF vconf [] )
 CHECK_MODULE_AND_SET( LIBUV libuv [] )
 CHECK_MODULE_AND_SET( GLIB glib-2.0 [] )
-CHECK_MODULE_AND_SET( VULKAN vulkan [] )
-CHECK_MODULE_AND_SET( GLSLANG glslang [] )
-CHECK_MODULE_AND_SET( SPIRVTOOLS SPIRV-Tools [] )
 CHECK_MODULE_AND_SET( X11 x11 [] )
 CHECK_MODULE_AND_SET( XCB x11-xcb [] )
 CHECK_MODULE_AND_SET( XDAMAGE xdamage [] )
@@ -157,6 +152,15 @@ CHECK_MODULE_AND_SET( DALICORE dali2-core [] )
 
 CHECK_MODULE_AND_SET( THORVG thorvg thorvg_support )
 
+IF( ENABLE_VULKAN )
+  CHECK_MODULE_AND_SET( VULKAN vulkan [] )
+  CHECK_MODULE_AND_SET( GLSLANG glslang [] )
+  CHECK_MODULE_AND_SET( SPIRVTOOLS SPIRV-Tools [] )
+ELSE()
+  CHECK_MODULE_AND_SET( OPENGLES20 glesv2 [] )
+  CHECK_MODULE_AND_SET( EGL egl [] )
+ENDIF()
+
 IF( thorvg_support )
   ADD_DEFINITIONS( -DTHORVG_SUPPORT )
 ENDIF()
@@ -542,6 +546,7 @@ IF(enable_glslang)
     SET(DALI_LDFLAGS ${DALI_LDFLAGS} ${GLSLANG_LDFLAGS} -lSPIRV ${SPIRVTOOLS_LDFLAGS} -lglslang-default-resource-limits)
   ENDIF()
 
+  SET(DALI_CFLAGS ${DALI_CFLAGS} ${GLSLANG_CFLAGS} )
 ENDIF()
 
 IF(LIBUV_X11_PROFILE)
@@ -645,3 +650,6 @@ ADD_DEFINITIONS(  -DDALI_DATA_RW_DIR="${daliReadWriteDir}"
                   -DFONT_CONFIGURATION_FILE="${fontConfigurationFile}"
                   -DTIZEN_PLATFORM_CONFIG_SUPPORTED=${tizenPlatformConfigSupported}
 )
+
+
+MESSAGE(STATUS "DALI_CFLAGS: ${DALI_CFLAGS}")
index fe0b3a51778bb29b91292034bed0f87dd061470e..f6e1702eaf7f29fb6686d240b5f0942bd12bee18 100644 (file)
@@ -359,6 +359,17 @@ public:
   {
   }
 
+  ~AdaptorAccessible() override
+  {
+    if(mRoot)
+    {
+      if(auto bridge = Accessibility::Bridge::GetCurrentBridge())
+      {
+        bridge->RemoveTopLevelWindow(this);
+      }
+    }
+  }
+
   bool GrabFocus() override
   {
     return false;
index 1adebe75636d291bbad92e32b9b9ce54649152ef..c5d33a1547b04d47effcb25d8c040f6fc1f96384 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -61,59 +61,6 @@ void Dali::AtspiAccessibility::Say(const std::string& text, bool discardable, st
   }
 }
 
-int Dali::AtspiAccessibility::SetForcefully(bool turnOn)
-{
-  if(turnOn)
-  {
-    if(auto bridge = Dali::Accessibility::Bridge::GetCurrentBridge())
-    {
-      bridge->Initialize();
-      auto ret = bridge->ForceUp();
-      return (int)ret;
-    }
-  }
-  else
-  {
-    if(auto bridge = Dali::Accessibility::Bridge::GetCurrentBridge())
-    {
-      bridge->ForceDown();
-      return 0;
-    }
-  }
-  return -1;
-}
-
-int Dali::AtspiAccessibility::GetStatus()
-{
-  //0(ATSPI OFF, ScreenReader OFF), 1(ATSPI ON, ScreenReader OFF), 2 (ATSPI OFF, ScreenReader ON), 3(ATSPI ON, ScreenReader ON)
-  if(auto bridge = Dali::Accessibility::Bridge::GetCurrentBridge())
-  {
-    if(bridge->GetScreenReaderEnabled())
-    {
-      if(bridge->IsEnabled())
-      {
-        return 3;
-      }
-      else
-      {
-        return 2;
-      }
-    }
-    else
-    {
-      if(bridge->IsEnabled())
-      {
-        return 1;
-      }
-      else
-      {
-        return 0;
-      }
-    }
-  }
-  return -1;
-}
-
 bool Dali::AtspiAccessibility::IsEnabled()
 {
   return Dali::Accessibility::IsUp();
index 3ee0674ea5d6deae1aa3b5001b09f22c5c4cc1ea..26ca5f2dc32c0889d14eec7f5adb61258bdc37e4 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_DEVEL_ATSPI_ACCESSIBILITY_H
 #define DALI_DEVEL_ATSPI_ACCESSIBILITY_H
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -64,22 +64,6 @@ DALI_ADAPTOR_API void StopReading(bool alsoNonDiscardable = false);
  */
 DALI_ADAPTOR_API bool SuppressScreenReader(bool suppress);
 
-/**
- * @brief Sets ATSPI to be turned On or Off forcibly.
- *
- * @param[in] turnOn true to turn on, false to turn off.
- * @return The status of ATSPI : 0(ATSPI OFF, ScreenReader OFF), 1(ATSPI ON, ScreenReader OFF),
- * 2 (ATSPI OFF, ScreenReader ON), 3(ATSPI ON, ScreenReader ON)
- */
-DALI_ADAPTOR_API int SetForcefully(bool turnOn);
-
-/**
- * @brief Gets ATSPI status.
- * @return Status of ATSPI : 0(ATSPI OFF, ScreenReader OFF), 1(ATSPI ON, ScreenReader OFF),
- * 2 (ATSPI OFF, ScreenReader ON), 3(ATSPI ON, ScreenReader ON)
- */
-DALI_ADAPTOR_API int GetStatus();
-
 /**
  * @brief Returns whether the state of Accessibility is enabled or not.
  *
index 60de30b99adcd7903233fc20fef7acb8d9ffc1d0..8a939e9ade8b1678a761cc7e7ab61d2ade1370ea 100644 (file)
@@ -86,10 +86,14 @@ enum Key
   DALI_KEY_CONTROL_RIGHT = 105,
 
   /**
-   * @brief Control Return key.
+   * @brief Return key.
    */
-  DALI_KEY_RETURN = 36
+  DALI_KEY_RETURN = 36,
 
+  /**
+   * @brief Keypad Enter key.
+   */
+  DALI_KEY_KP_ENTER = 104
 };
 
 /**
index 8dbd584bd575cbf7606a79d6a89911ce15f2dcb3..a105b64344674e92013e211478fc8605ceb28986 100755 (executable)
@@ -47,6 +47,7 @@ class WebEnginePolicyDecision;
 class WebEngineSettings;
 class HoverEvent;
 class WheelEvent;
+class WebEngineUserMediaPermissionRequest;
 
 /**
  * @brief WebEnginePlugin is an abstract interface, used by dali-adaptor to access WebEngine plugin.
@@ -205,6 +206,21 @@ public:
    */
   using PlainTextReceivedCallback = std::function<void(const std::string&)>;
 
+  /**
+   * @brief WebView callback informs browser app to display QB code popup for passkey scenario.
+   */
+  using WebEngineWebAuthDisplayQRCallback = std::function<void(const std::string&)>;
+
+  /**
+   * @brief WebView callback informs browser app that the passkey registration and authentication has been successful and app can close QR popup.
+   */
+  using WebEngineWebAuthResponseCallback = std::function<void(void)>;
+
+  /**
+   * @brief The callback to be called when the web engine received a user media permission reqeust from user application.
+   */
+  using WebEngineUserMediaPermissionRequestCallback = std::function<void(std::unique_ptr<Dali::WebEngineUserMediaPermissionRequest>, const std::string&)>;
+
   /**
    * @brief Enumeration for the scroll edge.
    */
@@ -952,6 +968,33 @@ public:
    * @param[in] callback The callback function called asynchronously.
    */
   virtual void GetPlainTextAsynchronously(PlainTextReceivedCallback callback) = 0;
+
+  /**
+   * @brief Cancel WebAuthentication(cancel in progress passkey operation).
+   */
+  virtual void WebAuthenticationCancel() = 0;
+
+  /**
+   * @brief Register WebAuthDisplayQR callback.
+   *
+   * @param[in] callback The callback informs browser app to display QR code popup for passkey scenario.
+   */
+  virtual void RegisterWebAuthDisplayQRCallback(WebEngineWebAuthDisplayQRCallback callback) = 0;
+
+  /**
+   * @brief Register WebAuthResponse callback.
+   *
+   * @param[in] callback The callback informs browser app that the passkey registration and authentication has been successful and app can close QR popup.
+   */
+  virtual void RegisterWebAuthResponseCallback(WebEngineWebAuthResponseCallback callback) = 0;
+
+  /**
+   * @brief Register UserMediaPermissionRequest callback.
+   *
+   * @param[in] callback The callback to be called for handling user media permission.
+   */
+  virtual void RegisterUserMediaPermissionRequestCallback(WebEngineUserMediaPermissionRequestCallback callback) = 0;
+
 };
 
 // specialization has to be done in the same namespace
diff --git a/dali/devel-api/adaptor-framework/web-engine/web-engine-user-media-permission-request.h b/dali/devel-api/adaptor-framework/web-engine/web-engine-user-media-permission-request.h
new file mode 100755 (executable)
index 0000000..88e6ea9
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef DALI_WEB_ENGINE_USER_MEDIA_PERMISSION_REQUEST_H
+#define DALI_WEB_ENGINE_USER_MEDIA_PERMISSION_REQUEST_H
+
+/*
+ * Copyright (c) 2024 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
+
+namespace Dali
+{
+/**
+ * @brief A class WebEngineUserMediaPermissionRequest for handling user's media permission of web engine.
+ */
+class WebEngineUserMediaPermissionRequest
+{
+public:
+  /**
+   * @brief Constructor.
+   */
+  WebEngineUserMediaPermissionRequest() = default;
+
+  /**
+   * @brief Destructor.
+   */
+  virtual ~WebEngineUserMediaPermissionRequest() = default;
+
+  /**
+   * @brief Request to set user media permission of web engine.
+   *
+   * @param[in] allowed if true, allow to set, false, not allow to set.
+   */
+  virtual void Set(bool allowed) const = 0;
+
+  /**
+   * @brief Suspend user media permission request process of web engine.
+   * @return true if the suspension was successful, false otherwise.
+   */
+  virtual bool Suspend() const = 0;
+};
+} // namespace Dali
+
+#endif // DALI_WEB_ENGINE_USER_MEDIA_PERMISSION_REQUEST_H
index 3549b507a699d4d93930b2ef3370ea17ce656e9e..045fbb7789fead5626f64191c16915fe1691d548 100755 (executable)
@@ -52,7 +52,14 @@ WebEngine::~WebEngine()
 
 WebEngine WebEngine::New()
 {
-  Internal::Adaptor::WebEnginePtr engine = Internal::Adaptor::WebEngine::New();
+  Internal::Adaptor::WebEnginePtr engine = Internal::Adaptor::WebEngine::New(-1);
+
+  return WebEngine(engine.Get());
+}
+
+WebEngine WebEngine::New(int32_t type)
+{
+  Internal::Adaptor::WebEnginePtr engine = Internal::Adaptor::WebEngine::New(type);
 
   return WebEngine(engine.Get());
 }
@@ -605,4 +612,24 @@ void WebEngine::GetPlainTextAsynchronously(Dali::WebEnginePlugin::PlainTextRecei
   GetImplementation(*this).GetPlainTextAsynchronously(callback);
 }
 
+void WebEngine::WebAuthenticationCancel()
+{
+  GetImplementation(*this).WebAuthenticationCancel();
+}
+
+void WebEngine::RegisterWebAuthDisplayQRCallback(Dali::WebEnginePlugin::WebEngineWebAuthDisplayQRCallback callback)
+{
+  GetImplementation(*this).RegisterWebAuthDisplayQRCallback(callback);
+}
+
+void WebEngine::RegisterWebAuthResponseCallback(Dali::WebEnginePlugin::WebEngineWebAuthResponseCallback callback)
+{
+  GetImplementation(*this).RegisterWebAuthResponseCallback(callback);
+}
+
+void WebEngine::RegisterUserMediaPermissionRequestCallback(Dali::WebEnginePlugin::WebEngineUserMediaPermissionRequestCallback callback)
+{
+  GetImplementation(*this).RegisterUserMediaPermissionRequestCallback(callback);
+}
+
 } // namespace Dali
index 8f8a8fb351cce2b2944ca267d5146e59430708a0..b5ee7a8c0c6b3059ecf59a0cde2db5074c0c49bd 100755 (executable)
@@ -64,6 +64,12 @@ public:
    */
   static WebEngine New();
 
+  /**
+   * @brief Create a new instance of a WebEngine with type (0: Chromium, 1: LWE, otherwise: depend on system environment).
+   * @param[in] type The WebEngine type (0: Chromium, 1: LWE, otherwise: depend on system environment).
+   */
+  static WebEngine New(int type);
+
   /**
    * @brief Get context of WebEngine.
    */
@@ -833,6 +839,35 @@ public:
    */
   void GetPlainTextAsynchronously(Dali::WebEnginePlugin::PlainTextReceivedCallback callback);
 
+  /**
+   * @brief Cancel WebAuthentication(cancel in progress passkey operation).
+   */
+  void WebAuthenticationCancel();
+
+  /**
+   * @brief Get a plain text of current web page asynchronously.
+   *
+   * @param[in] callback The callback function called asynchronously.
+
+   */
+  void RegisterWebAuthDisplayQRCallback(Dali::WebEnginePlugin::WebEngineWebAuthDisplayQRCallback callback);
+
+  /**
+   * @brief Get a plain text of current web page asynchronously.
+   *
+   * @param[in] callback The callback function called asynchronously.
+
+   */
+  void RegisterWebAuthResponseCallback(Dali::WebEnginePlugin::WebEngineWebAuthResponseCallback callback);
+
+  /**
+   * @brief Register UserMediaPermissionRequest callback.
+   *
+   * @param[in] callback The callback to be called for handling user media permission.
+   */
+  void RegisterUserMediaPermissionRequestCallback(Dali::WebEnginePlugin::WebEngineUserMediaPermissionRequestCallback callback);
+
+
 private: // Not intended for application developers
   /**
    * @brief Internal constructor
index 7ae13b0dbb71e8056323c2e1097e7f29c3aa76da..3db2c845d16858ce2ea011c3cf6409f053686a39 100644 (file)
@@ -31,7 +31,7 @@ bool WindowBlurInfo::operator==(const WindowBlurInfo& blurInfo) const
   {
     return false;
   }
-  if(backgroundBlurRadius != blurInfo.backgroundBlurRadius)
+  if(backgroundCornerRadius != blurInfo.backgroundCornerRadius)
   {
     return false;
   }
@@ -61,12 +61,12 @@ int WindowBlurInfo::GetBlurRadius() const
 
 void WindowBlurInfo::SetCornerRadiusForBackground(int cornerRadius)
 {
-  backgroundBlurRadius = cornerRadius;
+  backgroundCornerRadius = cornerRadius;
 }
 
 int WindowBlurInfo::GetCornerRadiusForBackground() const
 {
-  return backgroundBlurRadius;
+  return backgroundCornerRadius;
 }
 
 } // namespace Dali
index 8a8f9147959d3ada2671dddaec2ca7bf21d64eb5..0e3685e16e3d78a05544b61f29d3904b9bd44f54 100644 (file)
@@ -46,7 +46,7 @@ public:
   WindowBlurInfo()
   : windowBlurType(WindowBlurType::NONE),
     windowBlurRadius(0),
-    backgroundBlurRadius(0)
+    backgroundCornerRadius(0)
   {
   }
 
@@ -61,7 +61,7 @@ public:
   explicit constexpr WindowBlurInfo(WindowBlurType type, int blurRadius, int cornerRadius)
   : windowBlurType(type),
     windowBlurRadius(blurRadius),
-    backgroundBlurRadius(cornerRadius)
+    backgroundCornerRadius(cornerRadius)
   {
   }
 
@@ -76,7 +76,7 @@ public:
   explicit constexpr WindowBlurInfo(WindowBlurType type, int blurRadius)
   : windowBlurType(type),
     windowBlurRadius(blurRadius),
-    backgroundBlurRadius(0)
+    backgroundCornerRadius(0)
   {
   }
 
@@ -149,7 +149,7 @@ public:
 public:
   WindowBlurType windowBlurType;
   int windowBlurRadius;
-  int backgroundBlurRadius;
+  int backgroundCornerRadius;
 };
 
 } // namespace Dali
index 243c8c5bb16499688fe6ec370f1e00de179758c4..8f3456d68b5d4cc8fce921936766f942dec43f70 100644 (file)
@@ -389,6 +389,16 @@ bool IsAlwaysOnTop(Window window)
   return GetImplementation(window).IsAlwaysOnTop();
 }
 
+void SetBottom(Window window, bool enable)
+{
+  GetImplementation(window).SetBottom(enable);
+}
+
+bool IsBottom(Window window)
+{
+  return GetImplementation(window).IsBottom();
+}
+
 Any GetNativeBuffer(Window window)
 {
   return GetImplementation(window).GetNativeBuffer();
index 481aa8d7ec6d010381712611e38a68b89bc5db53..e2ab62566653fef8503b483d44beb66acc0161d1 100644 (file)
@@ -686,6 +686,9 @@ DALI_ADAPTOR_API bool IsModal(Window window);
 /**
  * @brief Enables or disables the window always is on top.
  *
+ * This is valid between windows that have no notification level or a notification level of 'none'.
+ * If it has a notification level, this will not do anything.
+ *
  * @param[in] window The window instance.
  * @param[in] alwaysOnTop true to enable the window always is on top, false to disable.
  */
@@ -699,6 +702,25 @@ DALI_ADAPTOR_API void SetAlwaysOnTop(Window window, bool alwaysOnTop);
  */
 DALI_ADAPTOR_API bool IsAlwaysOnTop(Window window);
 
+/**
+ * @brief Enables or disables the window's layer is changed to bottom.
+ *
+ * If the enable flag is true, this window will be placed below other windows.
+ * Otherwise, if it's called with a false value, it will be located above other windows.
+ *
+ * @param[in] window The window instance.
+ * @param[in] enable true to change the window layer to the bottom.
+ */
+DALI_ADAPTOR_API void SetBottom(Window window, bool enable);
+
+/**
+ * @brief Returns whether the window layer is the bottom or not.
+ *
+ * @param[in] window The window instance.
+ * @return True if the window layer is the bottom, false otherwise.
+ */
+DALI_ADAPTOR_API bool IsBottom(Window window);
+
 /**
  * @brief Gets the native buffer of the window.
  *
index 7a8407957941494207824715ac327bebc4974e2d..369eae1482ea08c632259f317f4b84b78c10b14e 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_ADAPTOR_ATSPI_COLLECTION_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -30,6 +30,21 @@ namespace Dali::Accessibility
  */
 class DALI_ADAPTOR_API Collection : public virtual Accessible
 {
+public:
+  /**
+   * MatchRule type is a tuple that only carries data of de-serialized parameter from BridgeCollection::GetMatches dbus method.
+   */
+  using MatchRule = std::tuple<
+    std::array<int32_t, 2>,
+    int32_t,
+    std::unordered_map<std::string, std::string>,
+    int32_t,
+    std::array<int32_t, 4>,
+    int32_t,
+    std::vector<std::string>,
+    int32_t,
+    bool>;
+
   /**
    * @brief Downcasts an Accessible to a Collection.
    *
@@ -39,6 +54,28 @@ class DALI_ADAPTOR_API Collection : public virtual Accessible
    * @see Dali::Accessibility::Accessible::DownCast()
    */
   static inline Collection* DownCast(Accessible* obj);
+
+  /**
+   * @brief Gets the matching Accessible objects with MatchRule.
+   *
+   * @param[in] rule Collection::MatchRule
+   * @param[in] sortBy SortOrder::CANONICAL or SortOrder::REVERSE_CANONICAL
+   * @param[in] maxCount The maximum number of objects; returns all matches if 0
+   * @return The matching Accessible objects
+   */
+  std::vector<Accessible*> GetMatches(MatchRule rule, uint32_t sortBy, size_t maxCount);
+
+  /**
+   * @brief Gets the matching Accessible objects with two MatchRules.
+   *
+   * @param[in] firstRule The initial Collection::MatchRule.
+   * @param[in] secondRule An secondary Collection::MatchRule.
+   * @param[in] sortBy SortOrder::CANONICAL or SortOrder::REVERSE_CANONICAL
+   * @param[in] firstCount The maximum number of objects to return for the initial match.; returns all matches if 0
+   * @param[in] secondCount The maximum number of objects to return for the secondary match.; returns all matches if 0
+   * @return The matching Accessible objects
+   */
+  std::vector<Accessible*> GetMatchesInMatches(MatchRule firstRule, MatchRule secondRule, uint32_t sortBy, int32_t firstCount, int32_t secondCount);
 };
 
 namespace Internal
index 94ded8bd5b7a01a94db345cfc900101018f0bc89..fff4c81b98a46a48261203d82f9240114b38a68a 100755 (executable)
@@ -158,6 +158,7 @@ SET( devel_api_adaptor_framework_web_engine_header_files
   ${adaptor_devel_api_dir}/adaptor-framework/web-engine/web-engine-request-interceptor.h
   ${adaptor_devel_api_dir}/adaptor-framework/web-engine/web-engine-security-origin.h
   ${adaptor_devel_api_dir}/adaptor-framework/web-engine/web-engine-settings.h
+  ${adaptor_devel_api_dir}/adaptor-framework/web-engine/web-engine-user-media-permission-request.h  
 )
 
 
index 1323ff48ae7acb1b99910095557a4ce7fa902ff5..e28ea966637db00f9d68f4d8e655380739db7864 100644 (file)
@@ -33,8 +33,8 @@ std::once_flag                     ShaderPreCompiler::mOnceFlag;
 
 ShaderPreCompiler::ShaderPreCompiler()
 : mRawShaderList(),
-  mPrecompiled(false),
-  mEnabled(false)
+  mEnabled(false),
+  mNeedsSleep(true)
 {
 }
 
@@ -45,36 +45,33 @@ ShaderPreCompiler& ShaderPreCompiler::Get()
   return *(mInstance.get());
 }
 
-void ShaderPreCompiler::AddPreCompiledProgram(Graphics::UniquePtr<Dali::Graphics::Program> program)
+void ShaderPreCompiler::AddPreCompiledProgram(ShaderPreCompiler::CompiledProgram program)
 {
   mProgram.push_back(move(program));
 }
 
-void ShaderPreCompiler::GetPreCompileShaderList(std::vector<RawShaderData>& shaderList)
+void ShaderPreCompiler::GetPreCompileShaderList(ShaderPreCompiler::RawShaderDataList& shaderList)
 {
   // move shader list
-  shaderList = mRawShaderList;
+  shaderList = std::move(mRawShaderList);
+
+  // Call clear, to avoid SVACE false alarm.
+  mRawShaderList.clear();
 }
 
-void ShaderPreCompiler::SavePreCompileShaderList(std::vector<RawShaderData>& shaderList)
+void ShaderPreCompiler::SavePreCompileShaderList(ShaderPreCompiler::RawShaderDataList&& shaderList)
 {
-  mRawShaderList = shaderList;
-  mPrecompiled   = true;
+  mRawShaderList = std::move(shaderList);
   DALI_LOG_RELEASE_INFO("Precompile shader list is saved! Precompile available now\n");
   Awake();
 }
 
-bool ShaderPreCompiler::IsReady() const
-{
-  return mPrecompiled;
-}
-
-void ShaderPreCompiler::Enable()
+void ShaderPreCompiler::Enable(bool enable)
 {
-  mEnabled = true;
+  mEnabled = enable;
 }
 
-bool ShaderPreCompiler::IsEnable()
+bool ShaderPreCompiler::IsEnable() const
 {
   return mEnabled;
 }
@@ -102,4 +99,10 @@ void ShaderPreCompiler::Awake()
   mNeedsSleep = false;
   mConditionalWait.Notify(lock);
 }
+
+void ShaderPreCompiler::ClearPreCompiledPrograms()
+{
+  mProgram.clear();
+}
+
 } // namespace Dali
index 4272b5f0ad60129a19a3e79a51c81e464974991e..ff20f27f9c1ab030a685a745f761d23c7aaf46bd 100644 (file)
 
 namespace Dali
 {
-struct RawShaderData
-{
-  int                           shaderCount;
-  std::vector<std::string_view> vertexPrefix;
-  std::vector<std::string_view> fragmentPrefix;
-  std::vector<std::string_view> shaderName;
-  std::string_view              vertexShader;
-  std::string_view              fragmentShader;
-  bool custom;
-};
-
 /**
  * ShaderPreCompiler  is used to precompile shaders.
  * The precompiled shaders are stored in a file.
@@ -52,6 +41,21 @@ struct RawShaderData
  */
 class DALI_CORE_API ShaderPreCompiler : public BaseHandle
 {
+public:
+  struct RawShaderData
+  {
+    uint32_t                 shaderCount;
+    std::vector<std::string> vertexPrefix;
+    std::vector<std::string> fragmentPrefix;
+    std::vector<std::string> shaderName;
+    std::string_view         vertexShader;
+    std::string_view         fragmentShader;
+    bool                     custom;
+  };
+
+  using RawShaderDataList = std::vector<RawShaderData>;
+  using CompiledProgram   = Dali::Graphics::UniquePtr<Dali::Graphics::Program>;
+
 public:
   /**
    * @brief Gets the singleton of ShaderPreCompiler object.
@@ -65,41 +69,36 @@ public:
    *
    * @param[in] program precompiled program
    */
-  void AddPreCompiledProgram(Graphics::UniquePtr<Dali::Graphics::Program> program);
+  void AddPreCompiledProgram(CompiledProgram program);
 
   /**
-   * @brief Gets the shader list to be precompiled
+   * @brief Gets the shader list to be precompiled.
+   * @note Stored shader list will be cleared after calling this function.
    *
-   *  @param[in] shaders shader data for precompile
+   * @param[out] shaders shader data for precompile
    */
-  void GetPreCompileShaderList(std::vector<RawShaderData>& shaders);
+  void GetPreCompileShaderList(RawShaderDataList& shaders);
 
   /**
    * @brief Save the shader list to be precompiled
    *
    * @param[in] shaders shader data for precompile
    */
-  void SavePreCompileShaderList(std::vector<RawShaderData>& shaders);
-
-  /**
-   * @brief Checks whether the precompiled list is ready or not
-   *
-   * @return true if precompile list is ready
-   */
-  bool IsReady() const;
+  void SavePreCompileShaderList(RawShaderDataList&& shaders);
 
   /**
    * @brief Enable the feature of precompile
    *
+   * @param[in] enable True if we need to enable precompile. False if we need to disable precompile.
    */
-  void Enable();
+  void Enable(bool enable);
 
   /**
    * @brief Check the feature of precompile is enabled or not
    *
    * @return true if the feature of precompile is enabled
   */
-  bool IsEnable();
+  bool IsEnable() const;
 
   /**
    * @brief Waiting for a list of shaders to be precompiled
@@ -113,6 +112,12 @@ public:
    */
   void Awake();
 
+  /**
+   * @brief Remove all pre-compiled programs from cache.
+   * @note It must be called before graphics shutdown.
+   */
+  void ClearPreCompiledPrograms();
+
 private:
   /**
    * Construct a new ShaderPreCompiler.
@@ -126,15 +131,18 @@ private:
   ShaderPreCompiler& operator=(const ShaderPreCompiler& rhs) = delete;
 
 private:
-  std::vector<Graphics::UniquePtr<Dali::Graphics::Program>> mProgram;
-  static std::unique_ptr<ShaderPreCompiler>                 mInstance;
-  static std::once_flag                                     mOnceFlag;
-  std::vector<RawShaderData>                                mRawShaderList;
-  ConditionalWait                                           mConditionalWait;
-  Dali::Mutex                                               mMutex;
-  bool                                                      mPrecompiled;
-  bool                                                      mEnabled;
-  bool                                                      mNeedsSleep{true};
+  static std::unique_ptr<ShaderPreCompiler> mInstance;
+  static std::once_flag                     mOnceFlag;
+
+private:
+  std::vector<CompiledProgram> mProgram; ///< Keep compiled programs so we can use cached program.
+
+  RawShaderDataList mRawShaderList;
+  ConditionalWait   mConditionalWait;
+  Dali::Mutex       mMutex;
+
+  bool mEnabled : 1;
+  bool mNeedsSleep : 1;
 };
 
 } // namespace Dali
index 0e3269c37e6ff067cc23afcbb188ef6291d0dc2c..3179368beb985009496a8c9eb9b5588d28275d84 100644 (file)
@@ -38,7 +38,6 @@ BridgeBase::BridgeBase()
 
 BridgeBase::~BridgeBase()
 {
-  mApplication.mChildren.clear();
 }
 
 void BridgeBase::AddCoalescableMessage(CoalescableMessages kind, Dali::Accessibility::Accessible* obj, float delay, std::function<void()> functor)
@@ -225,6 +224,7 @@ void BridgeBase::RemoveTopLevelWindow(Accessible* windowAccessible)
     if(mApplication.mChildren[i] == windowAccessible)
     {
       mApplication.mChildren.erase(mApplication.mChildren.begin() + i);
+      Emit(windowAccessible, WindowEvent::DESTROY);
       break;
     }
   }
index 20111301dbf2d4cff647cbe525d5fcdfc25ea242..c7aaa1cfddf0d93dca6927775396253f10bc8508 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
 
 using namespace Dali::Accessibility;
 
-namespace
-{
-/**
- * @brief Enumeration used for quering Accessibility objects.
- *
- * Refer to MatchType enumeration.
- */
-enum class AtspiCollection
-{
-  MATCH_INVALID,
-  MATCH_ALL,
-  MATCH_ANY,
-  MATCH_NONE,
-  MATCH_EMPTY,
-  MATCH_LAST_DEFINED,
-};
-} // anonymous namespace
-
 void BridgeCollection::RegisterInterfaces()
 {
   DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::COLLECTION)};
@@ -57,513 +39,22 @@ Collection* BridgeCollection::FindSelf() const
   return FindCurrentObjectWithInterface<Dali::Accessibility::AtspiInterface::COLLECTION>();
 }
 
-/**
- * @brief The BridgeCollection::Comparer structure.
- *
- * Once the data is de-serialized by DBusWrapper, the data of match rule is passed
- * to Comparer type which do the comparison against a single accessible object.
- */
-struct BridgeCollection::Comparer
+DBus::ValueOrError<std::vector<Accessible*> > BridgeCollection::GetMatches(Collection::MatchRule rule, uint32_t sortBy, int32_t count, bool traverse)
 {
-  using Mode = MatchType;
-
-  /**
-   * @brief Enumeration to check the object is found first.
-   */
-  enum class CompareFuncExit
+  if(auto collection = FindSelf())
   {
-    FIRST_FOUND,
-    FIRST_NOT_FOUND
-  };
-
-  static Mode ConvertToMatchType(int32_t mode)
-  {
-    switch(mode)
-    {
-      case static_cast<int32_t>(AtspiCollection::MATCH_INVALID):
-      {
-        return Mode::INVALID;
-      }
-      case static_cast<int32_t>(AtspiCollection::MATCH_ALL):
-      {
-        return Mode::ALL;
-      }
-      case static_cast<int32_t>(AtspiCollection::MATCH_ANY):
-      {
-        return Mode::ANY;
-      }
-      case static_cast<int32_t>(AtspiCollection::MATCH_NONE):
-      {
-        return Mode::NONE;
-      }
-      case static_cast<int32_t>(AtspiCollection::MATCH_EMPTY):
-      {
-        return Mode::EMPTY;
-      }
-    }
-    return Mode::INVALID;
+    return collection->GetMatches(std::move(rule), sortBy, count);
   }
 
-  /**
-   * @brief The ComparerInterfaces structure
-   */
-  struct ComparerInterfaces
-  {
-    std::unordered_set<std::string> mObject;
-    std::vector<std::string>        mRequested;
-    Mode                            mMode = Mode::INVALID;
-
-    ComparerInterfaces(MatchRule* rule)
-    : mMode(ConvertToMatchType(std::get<static_cast<std::size_t>(Index::INTERFACES_MATCH_TYPE)>(*rule)))
-    {
-      mRequested = {std::get<static_cast<std::size_t>(Index::INTERFACES)>(*rule).begin(), std::get<static_cast<std::size_t>(Index::INTERFACES)>(*rule).end()};
-    }
-
-    void Update(Accessible* obj)
-    {
-      mObject.clear();
-      for(auto& interface : obj->GetInterfacesAsStrings())
-      {
-        mObject.insert(std::move(interface));
-      }
-    }
-
-    bool IsRequestEmpty() const
-    {
-      return mRequested.empty();
-    }
-
-    bool IsObjectEmpty() const
-    {
-      return mObject.empty();
-    }
-
-    bool Compare(CompareFuncExit exit)
-    {
-      bool foundAny = false;
-      for(auto& iname : mRequested)
-      {
-        bool found = (mObject.find(iname) != mObject.end());
-        if(found)
-        {
-          foundAny = true;
-        }
-
-        if(found == (exit == CompareFuncExit::FIRST_FOUND))
-        {
-          return found;
-        }
-      }
-      return foundAny;
-    }
-  }; // ComparerInterfaces struct
-
-  /**
-   * @brief The ComparerAttributes structure
-   */
-  struct ComparerAttributes
-  {
-    std::unordered_map<std::string, std::string> mRequested;
-    std::unordered_map<std::string, std::string> mObject;
-    Mode                                         mMode = Mode::INVALID;
-
-    ComparerAttributes(MatchRule* rule)
-    : mMode(ConvertToMatchType(std::get<static_cast<std::size_t>(Index::ATTRIBUTES_MATCH_TYPE)>(*rule)))
-    {
-      mRequested = std::get<static_cast<std::size_t>(Index::ATTRIBUTES)>(*rule);
-    }
-
-    void Update(Accessible* obj)
-    {
-      mObject = obj->GetAttributes();
-    }
-
-    bool IsRequestEmpty() const
-    {
-      return mRequested.empty();
-    }
-
-    bool IsObjectEmpty() const
-    {
-      return mObject.empty();
-    }
-
-    bool Compare(CompareFuncExit exit)
-    {
-      bool foundAny = false;
-      for(auto& iname : mRequested)
-      {
-        auto it    = mObject.find(iname.first);
-        bool found = it != mObject.end() && iname.second == it->second;
-        if(found)
-        {
-          foundAny = true;
-        }
-
-        if(found == (exit == CompareFuncExit::FIRST_FOUND))
-        {
-          return found;
-        }
-      }
-      return foundAny;
-    }
-  }; // ComparerAttributes struct
-
-  /**
-   * @brief The ComparerRoles structure
-   */
-  struct ComparerRoles
-  {
-    using Roles = EnumBitSet<Role, Role::MAX_COUNT>;
-
-    Roles mRequested;
-    Roles mObject;
-    Mode  mMode = Mode::INVALID;
-
-    ComparerRoles(MatchRule* rule)
-    : mMode(ConvertToMatchType(std::get<static_cast<std::size_t>(Index::ROLES_MATCH_TYPE)>(*rule)))
-    {
-      mRequested = Roles{std::get<static_cast<std::size_t>(Index::ROLES)>(*rule)};
-    }
-
-    void Update(Accessible* obj)
-    {
-      mObject                 = {};
-      mObject[obj->GetRole()] = true;
-      assert(mObject);
-    }
-
-    bool IsRequestEmpty() const
-    {
-      return !mRequested;
-    }
-
-    bool IsObjectEmpty() const
-    {
-      return !mObject;
-    }
-
-    bool Compare(CompareFuncExit exit)
-    {
-      switch(mMode)
-      {
-        case Mode::INVALID:
-        {
-          return true;
-        }
-        case Mode::EMPTY:
-        case Mode::ALL:
-        {
-          return mRequested == (mObject & mRequested);
-        }
-        case Mode::ANY:
-        {
-          return bool(mObject & mRequested);
-        }
-        case Mode::NONE:
-        {
-          return bool(mObject & mRequested);
-        }
-      }
-      return false;
-    }
-  }; // ComparerRoles struct
-
-  /**
-   * @brief The ComparerStates structure
-   */
-  struct ComparerStates
-  {
-    States mRequested;
-    States mObject;
-    Mode   mMode = Mode::INVALID;
-
-    ComparerStates(MatchRule* rule)
-    : mMode(ConvertToMatchType(std::get<static_cast<std::size_t>(Index::STATES_MATCH_TYPE)>(*rule)))
-    {
-      mRequested = States{std::get<static_cast<std::size_t>(Index::STATES)>(*rule)};
-    }
-
-    void Update(Accessible* obj)
-    {
-      mObject = obj->GetStates();
-    }
-
-    bool IsRequestEmpty() const
-    {
-      return !mRequested;
-    }
-
-    bool IsObjectEmpty() const
-    {
-      return !mObject;
-    }
-
-    bool Compare(CompareFuncExit exit)
-    {
-      switch(mMode)
-      {
-        case Mode::INVALID:
-        {
-          return true;
-        }
-        case Mode::EMPTY:
-        case Mode::ALL:
-        {
-          return mRequested == (mObject & mRequested);
-        }
-        case Mode::ANY:
-        {
-          return bool(mObject & mRequested);
-        }
-        case Mode::NONE:
-        {
-          return bool(mObject & mRequested);
-        }
-      }
-      return false;
-    }
-  }; // ComparerStates struct
-
-  template<typename T>
-  bool CompareFunc(T& cmp, Accessible* obj)
-  {
-    if(cmp.mMode == Mode::INVALID)
-    {
-      return true;
-    }
-
-    cmp.Update(obj);
-    switch(cmp.mMode)
-    {
-      case Mode::ANY:
-      {
-        if(cmp.IsRequestEmpty() || cmp.IsObjectEmpty())
-        {
-          return false;
-        }
-        break;
-      }
-      case Mode::ALL:
-      {
-        if(cmp.IsRequestEmpty())
-        {
-          return true;
-        }
-        if(cmp.IsObjectEmpty())
-        {
-          return false;
-        }
-        break;
-      }
-      case Mode::NONE:
-      {
-        if(cmp.IsRequestEmpty() || cmp.IsObjectEmpty())
-        {
-          return true;
-        }
-        break;
-      }
-      case Mode::EMPTY:
-      {
-        if(cmp.IsRequestEmpty() && cmp.IsObjectEmpty())
-        {
-          return true;
-        }
-        if(cmp.IsRequestEmpty() || cmp.IsObjectEmpty())
-        {
-          return false;
-        }
-        break;
-      }
-      case Mode::INVALID:
-      {
-        return true;
-      }
-    }
-
-    switch(cmp.mMode)
-    {
-      case Mode::EMPTY:
-      case Mode::ALL:
-      {
-        if(!cmp.Compare(CompareFuncExit::FIRST_NOT_FOUND))
-        {
-          return false;
-        }
-        break;
-      }
-      case Mode::ANY:
-      {
-        if(cmp.Compare(CompareFuncExit::FIRST_FOUND))
-        {
-          return true;
-        }
-        break;
-      }
-      case Mode::NONE:
-      {
-        if(cmp.Compare(CompareFuncExit::FIRST_FOUND))
-        {
-          return false;
-        }
-        break;
-      }
-      case Mode::INVALID:
-      {
-        return true;
-      }
-    }
-
-    switch(cmp.mMode)
-    {
-      case Mode::EMPTY:
-      case Mode::ALL:
-      case Mode::NONE:
-      {
-        return true;
-      }
-      case Mode::ANY:
-      {
-        return false;
-      }
-      case Mode::INVALID:
-      {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  Comparer(MatchRule* rule)
-  : mInterface(rule),
-    mAttribute(rule),
-    mRole(rule),
-    mState(rule)
-  {
-  }
-
-  bool operator()(Accessible* obj)
-  {
-    return CompareFunc(mInterface, obj) &&
-           CompareFunc(mAttribute, obj) &&
-           CompareFunc(mRole, obj) &&
-           CompareFunc(mState, obj);
-  }
-
-  bool IsShowing(Accessible* obj)
-  {
-    if (mState.mMode == Mode::NONE) return true;
-    mState.Update(obj);
-    if (mState.IsRequestEmpty() || mState.IsObjectEmpty()) return true;
-    if (!mState.mRequested[State::SHOWING] ) return true;
-    if (mState.mObject[State::SHOWING]) return true;
-
-    return false;
-  }
-
-  ComparerInterfaces mInterface;
-  ComparerAttributes mAttribute;
-  ComparerRoles      mRole;
-  ComparerStates     mState;
-}; // BridgeCollection::Comparer struct
-
-
-void BridgeCollection::VisitNodes(Accessible* obj, std::vector<Accessible*>& result, Comparer& comparer, size_t maxCount)
-{
-  if(maxCount > 0 && result.size() >= maxCount)
-  {
-    return;
-  }
-
-  if(comparer(obj))
-  {
-    result.emplace_back(obj);
-    // the code below will never return for maxCount equal 0
-    if(result.size() == maxCount)
-    {
-      return;
-    }
-  }
-
-  if (!comparer.IsShowing(obj))
-  {
-    return;
-  }
-
-  for(auto i = 0u; i < obj->GetChildCount(); ++i)
-  {
-    VisitNodes(obj->GetChildAtIndex(i), result, comparer, maxCount);
-  }
+  return {};
 }
 
-DBus::ValueOrError<std::vector<Accessible*> > BridgeCollection::GetMatches(MatchRule rule, uint32_t sortBy, int32_t count, bool traverse)
+DBus::ValueOrError<std::vector<Accessible*> > BridgeCollection::GetMatchesInMatches(Collection::MatchRule firstRule, Collection::MatchRule secondRule, uint32_t sortBy, int32_t firstCount, int32_t secondCount, bool traverse)
 {
-  std::vector<Accessible*> res;
-  auto                     self    = BridgeBase::FindCurrentObject();
-  auto                     matcher = Comparer{&rule};
-  VisitNodes(self, res, matcher, count);
-
-  switch(static_cast<SortOrder>(sortBy))
+  if(auto collection = FindSelf())
   {
-    case SortOrder::CANONICAL:
-    {
-      break;
-    }
-
-    case SortOrder::REVERSE_CANONICAL:
-    {
-      std::reverse(res.begin(), res.end());
-      break;
-    }
-
-    default:
-    {
-      throw std::domain_error{"unsupported sorting order"};
-    }
-      //TODO: other cases
-  }
-
-  return res;
-}
-
-DBus::ValueOrError<std::vector<Accessible*> > BridgeCollection::GetMatchesInMatches(MatchRule firstRule, MatchRule secondRule, uint32_t sortBy, int32_t firstCount, int32_t secondCount, bool traverse)
-{
-  std::vector<Accessible*> res;
-  std::vector<Accessible*> firstRes;
-  std::vector<Accessible*> secondRes;
-  auto                     self          = BridgeBase::FindCurrentObject();
-  auto                     firstMatcher  = Comparer{&firstRule};
-  auto                     secondMatcher = Comparer{&secondRule};
-  VisitNodes(self, firstRes, firstMatcher, firstCount);
-
-  for (auto &obj : firstRes)
-  {
-    VisitNodes(obj, secondRes, secondMatcher, secondCount);
-
-    res.insert(res.end(), secondRes.begin(), secondRes.end());
-    secondRes.clear();
-  }
-
-  switch(static_cast<SortOrder>(sortBy))
-  {
-    case SortOrder::CANONICAL:
-    {
-      break;
-    }
-
-    case SortOrder::REVERSE_CANONICAL:
-    {
-      std::reverse(res.begin(), res.end());
-      break;
-    }
-
-    default:
-    {
-      throw std::domain_error{"unsupported sorting order"};
-    }
-      //TODO: other cases
+    return collection->GetMatchesInMatches(std::move(firstRule), std::move(secondRule), sortBy, firstCount, secondCount);
   }
 
-  return res;
+  return {};
 }
index 32ea9c15461106c0b57fb86ff13be4755389fdfe..234d7d3f4a4996dbbf333594cdca81e3dd347416 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_COLLECTION_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
  */
 class BridgeCollection : public virtual BridgeBase
 {
-private:
-  struct Comparer;
-
-  /**
-   * @brief Visits all nodes of Accessible object and pushes the object to 'result' container.
-   *
-   * To query the entire tree, the BridgeCollection::Comparer is used inside this method,
-   * which traverse the tree using GetChildAtIndex().
-   * @param[in] obj The Accessible object to search
-   * @param[out] result The vector container for result
-   * @param[in] comparer BridgeCollection::Comparer which do the comparison against a single accessible object
-   * @param[in] maxCount The maximum count of containing Accessible object
-   */
-  static void VisitNodes(Dali::Accessibility::Accessible* obj, std::vector<Dali::Accessibility::Accessible*>& result, Comparer& comparer, size_t maxCount);
-
 protected:
   BridgeCollection() = default;
 
@@ -74,57 +59,14 @@ protected:
 
 public:
   /**
-   * MatchRule type is a tuple that only carries data of de-serialized parameter from BridgeCollection::GetMatches dbus method.
+   * @copydoc Dali::Accessibility::Collection::GetMatches()
    */
-  using MatchRule = std::tuple<
-    std::array<int32_t, 2>,
-    int32_t,
-    std::unordered_map<std::string, std::string>,
-    int32_t,
-    std::array<int32_t, 4>,
-    int32_t,
-    std::vector<std::string>,
-    int32_t,
-    bool>;
+  DBus::ValueOrError<std::vector<Dali::Accessibility::Accessible*> > GetMatches(Dali::Accessibility::Collection::MatchRule rule, uint32_t sortBy, int32_t count, bool traverse);
 
   /**
-   * @brief Enumeration for Collection Index.
-   */
-  enum class Index
-  {
-    STATES,
-    STATES_MATCH_TYPE,
-    ATTRIBUTES,
-    ATTRIBUTES_MATCH_TYPE,
-    ROLES,
-    ROLES_MATCH_TYPE,
-    INTERFACES,
-    INTERFACES_MATCH_TYPE,
-  };
-
-  /**
-   * @brief Gets the matching Accessible objects with MatchRule.
-   *
-   * @param[in] rule BridgeCollection::MatchRule
-   * @param[in] sortBy SortOrder::CANONICAL or SortOrder::REVERSE_CANONICAL
-   * @param[in] count The maximum number of objects
-   * @param[in] traverse True if it is traverse, otherwise false.
-   * @return The matching Accessible objects
-   */
-  DBus::ValueOrError<std::vector<Dali::Accessibility::Accessible*> > GetMatches(MatchRule rule, uint32_t sortBy, int32_t count, bool traverse);
-
-  /**
-   * @brief Gets the matching Accessible objects with two MatchRules.
-   *
-   * @param[in] firstRule The initial BridgeCollection::MatchRule.
-   * @param[in] secondRule An secondary BridgeCollection::MatchRule.
-   * @param[in] sortBy SortOrder::CANONICAL or SortOrder::REVERSE_CANONICAL
-   * @param[in] firstCount The maximum number of objects to return for the initial match.
-   * @param[in] secondCount The maximum number of objects to return for the secondary match.
-   * @param[in] traverse True if it is traverse, otherwise false.
-   * @return The matching Accessible objects
+   * @copydoc Dali::Accessibility::Collection::GetMatchesInMatches()
    */
-  DBus::ValueOrError<std::vector<Dali::Accessibility::Accessible*> > GetMatchesInMatches(MatchRule firstRule, MatchRule secondRule, uint32_t sortBy, int32_t firstCount, int32_t secondCount,  bool traverse);
+  DBus::ValueOrError<std::vector<Dali::Accessibility::Accessible*> > GetMatchesInMatches(Dali::Accessibility::Collection::MatchRule firstRule, Dali::Accessibility::Collection::MatchRule secondRule, uint32_t sortBy, int32_t firstCount, int32_t secondCount, bool traverse);
 };
 
 #endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_COLLECTION_H
diff --git a/dali/internal/accessibility/bridge/collection.cpp b/dali/internal/accessibility/bridge/collection.cpp
new file mode 100644 (file)
index 0000000..5835733
--- /dev/null
@@ -0,0 +1,582 @@
+/*
+ * Copyright (c) 2024 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
+
+// EXTERNAL INCLUDES
+#include <iostream>
+#include <set>
+
+// INTERNAL INCLUDES
+#include <dali/devel-api/atspi-interfaces/collection.h>
+#include <dali/internal/accessibility/bridge/accessibility-common.h>
+
+using namespace Dali::Accessibility;
+
+namespace
+{
+using MatchRule = Collection::MatchRule;
+
+/**
+   * @brief Enumeration for Collection Index.
+   */
+enum class Index
+{
+  STATES,
+  STATES_MATCH_TYPE,
+  ATTRIBUTES,
+  ATTRIBUTES_MATCH_TYPE,
+  ROLES,
+  ROLES_MATCH_TYPE,
+  INTERFACES,
+  INTERFACES_MATCH_TYPE,
+};
+
+/**
+ * @brief Enumeration used for quering Accessibility objects.
+ *
+ * Refer to MatchType enumeration.
+ */
+enum class AtspiCollection
+{
+  MATCH_INVALID,
+  MATCH_ALL,
+  MATCH_ANY,
+  MATCH_NONE,
+  MATCH_EMPTY,
+  MATCH_LAST_DEFINED,
+};
+
+/**
+ * @brief The Comparer structure.
+ *
+ * Once the data is de-serialized by DBusWrapper, the data of match rule is passed
+ * to Comparer type which do the comparison against a single accessible object.
+ */
+struct Comparer
+{
+  using Mode = MatchType;
+
+  /**
+   * @brief Enumeration to check the object is found first.
+   */
+  enum class CompareFuncExit
+  {
+    FIRST_FOUND,
+    FIRST_NOT_FOUND
+  };
+
+  static Mode ConvertToMatchType(int32_t mode)
+  {
+    switch(mode)
+    {
+      case static_cast<int32_t>(AtspiCollection::MATCH_INVALID):
+      {
+        return Mode::INVALID;
+      }
+      case static_cast<int32_t>(AtspiCollection::MATCH_ALL):
+      {
+        return Mode::ALL;
+      }
+      case static_cast<int32_t>(AtspiCollection::MATCH_ANY):
+      {
+        return Mode::ANY;
+      }
+      case static_cast<int32_t>(AtspiCollection::MATCH_NONE):
+      {
+        return Mode::NONE;
+      }
+      case static_cast<int32_t>(AtspiCollection::MATCH_EMPTY):
+      {
+        return Mode::EMPTY;
+      }
+    }
+    return Mode::INVALID;
+  }
+
+  /**
+   * @brief The ComparerInterfaces structure
+   */
+  struct ComparerInterfaces
+  {
+    std::unordered_set<std::string> mObject;
+    std::vector<std::string>        mRequested;
+    Mode                            mMode = Mode::INVALID;
+
+    ComparerInterfaces(MatchRule* rule)
+    : mMode(ConvertToMatchType(std::get<static_cast<std::size_t>(Index::INTERFACES_MATCH_TYPE)>(*rule)))
+    {
+      mRequested = {std::get<static_cast<std::size_t>(Index::INTERFACES)>(*rule).begin(), std::get<static_cast<std::size_t>(Index::INTERFACES)>(*rule).end()};
+    }
+
+    void Update(Accessible* obj)
+    {
+      mObject.clear();
+      for(auto& interface : obj->GetInterfacesAsStrings())
+      {
+        mObject.insert(std::move(interface));
+      }
+    }
+
+    bool IsRequestEmpty() const
+    {
+      return mRequested.empty();
+    }
+
+    bool IsObjectEmpty() const
+    {
+      return mObject.empty();
+    }
+
+    bool Compare(CompareFuncExit exit)
+    {
+      bool foundAny = false;
+      for(auto& iname : mRequested)
+      {
+        bool found = (mObject.find(iname) != mObject.end());
+        if(found)
+        {
+          foundAny = true;
+        }
+
+        if(found == (exit == CompareFuncExit::FIRST_FOUND))
+        {
+          return found;
+        }
+      }
+      return foundAny;
+    }
+  }; // ComparerInterfaces struct
+
+  /**
+   * @brief The ComparerAttributes structure
+   */
+  struct ComparerAttributes
+  {
+    std::unordered_map<std::string, std::string> mRequested;
+    std::unordered_map<std::string, std::string> mObject;
+    Mode                                         mMode = Mode::INVALID;
+
+    ComparerAttributes(MatchRule* rule)
+    : mMode(ConvertToMatchType(std::get<static_cast<std::size_t>(Index::ATTRIBUTES_MATCH_TYPE)>(*rule)))
+    {
+      mRequested = std::get<static_cast<std::size_t>(Index::ATTRIBUTES)>(*rule);
+    }
+
+    void Update(Accessible* obj)
+    {
+      mObject = obj->GetAttributes();
+    }
+
+    bool IsRequestEmpty() const
+    {
+      return mRequested.empty();
+    }
+
+    bool IsObjectEmpty() const
+    {
+      return mObject.empty();
+    }
+
+    bool Compare(CompareFuncExit exit)
+    {
+      bool foundAny = false;
+      for(auto& iname : mRequested)
+      {
+        auto it    = mObject.find(iname.first);
+        bool found = it != mObject.end() && iname.second == it->second;
+        if(found)
+        {
+          foundAny = true;
+        }
+
+        if(found == (exit == CompareFuncExit::FIRST_FOUND))
+        {
+          return found;
+        }
+      }
+      return foundAny;
+    }
+  }; // ComparerAttributes struct
+
+  /**
+   * @brief The ComparerRoles structure
+   */
+  struct ComparerRoles
+  {
+    using Roles = EnumBitSet<Role, Role::MAX_COUNT>;
+
+    Roles mRequested;
+    Roles mObject;
+    Mode  mMode = Mode::INVALID;
+
+    ComparerRoles(MatchRule* rule)
+    : mMode(ConvertToMatchType(std::get<static_cast<std::size_t>(Index::ROLES_MATCH_TYPE)>(*rule)))
+    {
+      mRequested = Roles{std::get<static_cast<std::size_t>(Index::ROLES)>(*rule)};
+    }
+
+    void Update(Accessible* obj)
+    {
+      mObject                 = {};
+      mObject[obj->GetRole()] = true;
+      assert(mObject);
+    }
+
+    bool IsRequestEmpty() const
+    {
+      return !mRequested;
+    }
+
+    bool IsObjectEmpty() const
+    {
+      return !mObject;
+    }
+
+    bool Compare(CompareFuncExit exit)
+    {
+      switch(mMode)
+      {
+        case Mode::INVALID:
+        {
+          return true;
+        }
+        case Mode::EMPTY:
+        case Mode::ALL:
+        {
+          return mRequested == (mObject & mRequested);
+        }
+        case Mode::ANY:
+        {
+          return bool(mObject & mRequested);
+        }
+        case Mode::NONE:
+        {
+          return bool(mObject & mRequested);
+        }
+      }
+      return false;
+    }
+  }; // ComparerRoles struct
+
+  /**
+   * @brief The ComparerStates structure
+   */
+  struct ComparerStates
+  {
+    States mRequested;
+    States mObject;
+    Mode   mMode = Mode::INVALID;
+
+    ComparerStates(MatchRule* rule)
+    : mMode(ConvertToMatchType(std::get<static_cast<std::size_t>(Index::STATES_MATCH_TYPE)>(*rule)))
+    {
+      mRequested = States{std::get<static_cast<std::size_t>(Index::STATES)>(*rule)};
+    }
+
+    void Update(Accessible* obj)
+    {
+      mObject = obj->GetStates();
+    }
+
+    bool IsRequestEmpty() const
+    {
+      return !mRequested;
+    }
+
+    bool IsObjectEmpty() const
+    {
+      return !mObject;
+    }
+
+    bool Compare(CompareFuncExit exit)
+    {
+      switch(mMode)
+      {
+        case Mode::INVALID:
+        {
+          return true;
+        }
+        case Mode::EMPTY:
+        case Mode::ALL:
+        {
+          return mRequested == (mObject & mRequested);
+        }
+        case Mode::ANY:
+        {
+          return bool(mObject & mRequested);
+        }
+        case Mode::NONE:
+        {
+          return bool(mObject & mRequested);
+        }
+      }
+      return false;
+    }
+  }; // ComparerStates struct
+
+  template<typename T>
+  bool CompareFunc(T& cmp, Accessible* obj)
+  {
+    if(cmp.mMode == Mode::INVALID)
+    {
+      return true;
+    }
+
+    cmp.Update(obj);
+    switch(cmp.mMode)
+    {
+      case Mode::ANY:
+      {
+        if(cmp.IsRequestEmpty() || cmp.IsObjectEmpty())
+        {
+          return false;
+        }
+        break;
+      }
+      case Mode::ALL:
+      {
+        if(cmp.IsRequestEmpty())
+        {
+          return true;
+        }
+        if(cmp.IsObjectEmpty())
+        {
+          return false;
+        }
+        break;
+      }
+      case Mode::NONE:
+      {
+        if(cmp.IsRequestEmpty() || cmp.IsObjectEmpty())
+        {
+          return true;
+        }
+        break;
+      }
+      case Mode::EMPTY:
+      {
+        if(cmp.IsRequestEmpty() && cmp.IsObjectEmpty())
+        {
+          return true;
+        }
+        if(cmp.IsRequestEmpty() || cmp.IsObjectEmpty())
+        {
+          return false;
+        }
+        break;
+      }
+      case Mode::INVALID:
+      {
+        return true;
+      }
+    }
+
+    switch(cmp.mMode)
+    {
+      case Mode::EMPTY:
+      case Mode::ALL:
+      {
+        if(!cmp.Compare(CompareFuncExit::FIRST_NOT_FOUND))
+        {
+          return false;
+        }
+        break;
+      }
+      case Mode::ANY:
+      {
+        if(cmp.Compare(CompareFuncExit::FIRST_FOUND))
+        {
+          return true;
+        }
+        break;
+      }
+      case Mode::NONE:
+      {
+        if(cmp.Compare(CompareFuncExit::FIRST_FOUND))
+        {
+          return false;
+        }
+        break;
+      }
+      case Mode::INVALID:
+      {
+        return true;
+      }
+    }
+
+    switch(cmp.mMode)
+    {
+      case Mode::EMPTY:
+      case Mode::ALL:
+      case Mode::NONE:
+      {
+        return true;
+      }
+      case Mode::ANY:
+      {
+        return false;
+      }
+      case Mode::INVALID:
+      {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  Comparer(MatchRule* rule)
+  : mInterface(rule),
+    mAttribute(rule),
+    mRole(rule),
+    mState(rule)
+  {
+  }
+
+  bool operator()(Accessible* obj)
+  {
+    return CompareFunc(mInterface, obj) &&
+           CompareFunc(mAttribute, obj) &&
+           CompareFunc(mRole, obj) &&
+           CompareFunc(mState, obj);
+  }
+
+  bool IsShowing(Accessible* obj)
+  {
+    if(mState.mMode == Mode::NONE) return true;
+    mState.Update(obj);
+    if(mState.IsRequestEmpty() || mState.IsObjectEmpty()) return true;
+    if(!mState.mRequested[State::SHOWING]) return true;
+    if(mState.mObject[State::SHOWING]) return true;
+
+    return false;
+  }
+
+  ComparerInterfaces mInterface;
+  ComparerAttributes mAttribute;
+  ComparerRoles      mRole;
+  ComparerStates     mState;
+}; // BridgeCollection::Comparer struct
+
+/**
+ * @brief Visits all nodes of Accessible object and pushes the object to 'result' container.
+ *
+ * To query the entire tree, the BridgeCollection::Comparer is used inside this method,
+ * which traverse the tree using GetChildAtIndex().
+ * @param[in] obj The Accessible object to search
+ * @param[out] result The vector container for result
+ * @param[in] comparer BridgeCollection::Comparer which do the comparison against a single accessible object
+ * @param[in] maxCount The maximum count of containing Accessible object
+ */
+void VisitNodes(Accessible* obj, std::vector<Accessible*>& result, Comparer& comparer, size_t maxCount, std::set<Accessible*>& visitedNodes)
+{
+  if(visitedNodes.count(obj) > 0)
+  {
+    return;
+  }
+
+  visitedNodes.insert(obj);
+
+  if(maxCount > 0 && result.size() >= maxCount)
+  {
+    return;
+  }
+
+  if(comparer(obj))
+  {
+    result.emplace_back(obj);
+    // the code below will never return for maxCount equal 0
+    if(result.size() == maxCount)
+    {
+      return;
+    }
+  }
+
+  if(!comparer.IsShowing(obj))
+  {
+    return;
+  }
+
+  for(auto i = 0u; i < obj->GetChildCount(); ++i)
+  {
+    VisitNodes(obj->GetChildAtIndex(i), result, comparer, maxCount, visitedNodes);
+  }
+}
+
+void SortMatchedResult(std::vector<Accessible*>& result, SortOrder sortBy)
+{
+  switch(sortBy)
+  {
+    case SortOrder::CANONICAL:
+    {
+      break;
+    }
+
+    case SortOrder::REVERSE_CANONICAL:
+    {
+      std::reverse(result.begin(), result.end());
+      break;
+    }
+
+    default:
+    {
+      throw std::domain_error{"unsupported sorting order"};
+    }
+      //TODO: other cases
+  }
+}
+
+} // namespace
+
+std::vector<Accessible*> Collection::GetMatches(MatchRule rule, uint32_t sortBy, size_t maxCount)
+{
+  std::vector<Accessible*> res;
+  auto                     matcher = Comparer{&rule};
+  std::set<Accessible*>    visitedNodes;
+  VisitNodes(this, res, matcher, maxCount, visitedNodes);
+  SortMatchedResult(res, static_cast<SortOrder>(sortBy));
+  return res;
+}
+
+std::vector<Accessible*> Collection::GetMatchesInMatches(MatchRule firstRule, MatchRule secondRule, uint32_t sortBy, int32_t firstCount, int32_t secondCount)
+{
+  std::vector<Accessible*> res;
+  std::vector<Accessible*> firstRes;
+  auto                     firstMatcher = Comparer{&firstRule};
+  std::set<Accessible*>    visitedNodes;
+  VisitNodes(this, firstRes, firstMatcher, firstCount, visitedNodes);
+
+  if(!firstRes.empty())
+  {
+    visitedNodes.clear();
+    auto secondMatcher = Comparer{&secondRule};
+    for(auto* obj : firstRes)
+    {
+      std::vector<Accessible*> secondRes;
+      VisitNodes(obj, secondRes, secondMatcher, secondCount, visitedNodes);
+
+      if(!secondRes.empty())
+      {
+        res.insert(res.end(), secondRes.begin(), secondRes.end());
+      }
+    }
+
+    SortMatchedResult(res, static_cast<SortOrder>(sortBy));
+  }
+
+  return res;
+}
index eccf2934828a175b8078f72ee4bfacb7bb3adce0..5aefe309f28cca19c68881daa12c6f28fa87945c 100644 (file)
@@ -78,6 +78,7 @@ SET( adaptor_accessibility_atspi_bridge_src_files
     ${adaptor_accessibility_dir}/bridge/bridge-table-cell.cpp
     ${adaptor_accessibility_dir}/bridge/bridge-text.cpp
     ${adaptor_accessibility_dir}/bridge/bridge-value.cpp
+    ${adaptor_accessibility_dir}/bridge/collection.cpp
     ${adaptor_accessibility_dir}/bridge/component.cpp
     ${adaptor_accessibility_dir}/bridge/dbus/dbus-tizen.cpp
 )
index c94bffb8d52f4bad61350478e1d46d3ed7410bc8..4234080c5f9e517477e6c0e49b0d38f10bb2a8b8 100644 (file)
 
 // EXTERNAL INCLUDES
 #include <dali/integration-api/platform-abstraction.h>
+#include <dali/integration-api/shader-integ.h>
+#include <dali/public-api/common/dali-common.h>
 #include <errno.h>
 #include <unistd.h>
-#include "dali/public-api/common/dali-common.h"
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/adaptor-framework/shader-precompiler.h>
@@ -591,10 +592,10 @@ void CombinedUpdateRenderController::UpdateRenderThread()
     if(ShaderPreCompiler::Get().IsEnable())
     {
       TRACE_UPDATE_RENDER_BEGIN("DALI_PRECOMPILE_SHADER");
-      std::vector<RawShaderData> precompiledShaderList;
+      ShaderPreCompiler::RawShaderDataList precompiledShaderList;
       ShaderPreCompiler::Get().GetPreCompileShaderList(precompiledShaderList);
-      DALI_LOG_RELEASE_INFO("ShaderPreCompiler[ENABLE], list size:%d \n", precompiledShaderList.size());
-      for(auto precompiledShader = precompiledShaderList.begin(); precompiledShader != precompiledShaderList.end(); ++precompiledShader)
+
+      while(!precompiledShaderList.empty())
       {
         if(mIsPreCompileCancelled == TRUE)
         {
@@ -603,26 +604,34 @@ void CombinedUpdateRenderController::UpdateRenderThread()
           break;
         }
 
-        auto numberOfPrecompiledShader = precompiledShader->shaderCount;
-        DALI_LOG_RELEASE_INFO("ShaderPreCompiler[ENABLE], shader count :%d \n", numberOfPrecompiledShader);
-        for(int i = 0; i < numberOfPrecompiledShader; ++i)
+        DALI_LOG_RELEASE_INFO("ShaderPreCompiler[ENABLE], Remained shader list : %zu \n", precompiledShaderList.size());
+
+        // We can assume that last element exist.
+        const auto& shaderRawData = precompiledShaderList.back();
+
+        auto numberOfPrecompiledShader = shaderRawData.shaderCount;
+        DALI_LOG_RELEASE_INFO("ShaderPreCompiler[ENABLE], shader count : %u \n", numberOfPrecompiledShader);
+        for(auto i = 0u; i < numberOfPrecompiledShader; ++i)
         {
           std::string vertexShader;
           std::string fragmentShader;
-          if(precompiledShader->custom)
+          if(shaderRawData.custom)
           {
-            vertexShader = precompiledShader->vertexPrefix[i].data();
-            fragmentShader = precompiledShader->fragmentPrefix[i].data();
+            vertexShader   = shaderRawData.vertexPrefix[i];
+            fragmentShader = shaderRawData.fragmentPrefix[i];
           }
           else
           {
-            vertexShader   = graphics.GetController().GetGraphicsConfig().GetVertexShaderPrefix() + std::string(precompiledShader->vertexPrefix[i].data()) + std::string(precompiledShader->vertexShader.data());
-            fragmentShader = graphics.GetController().GetGraphicsConfig().GetFragmentShaderPrefix() + std::string(precompiledShader->fragmentPrefix[i].data()) + std::string(precompiledShader->fragmentShader.data());
+            vertexShader   = Dali::Integration::GenerateTaggedShaderPrefix(graphics.GetController().GetGraphicsConfig().GetVertexShaderPrefix()) + shaderRawData.vertexPrefix[i] + std::string(shaderRawData.vertexShader);
+            fragmentShader = Dali::Integration::GenerateTaggedShaderPrefix(graphics.GetController().GetGraphicsConfig().GetFragmentShaderPrefix()) + shaderRawData.fragmentPrefix[i] + std::string(shaderRawData.fragmentShader);
           }
 
-          PreCompileShader(std::move(vertexShader), std::move(fragmentShader), static_cast<uint32_t>(i) < precompiledShader->shaderName.size() ? std::string(precompiledShader->shaderName[i]) : "");
-          DALI_LOG_RELEASE_INFO("ShaderPreCompiler[ENABLE], precompile shader >> %s \n", precompiledShader->shaderName.size() ? std::string(precompiledShader->shaderName[i]).c_str() : "");
+          PreCompileShader(std::move(vertexShader), std::move(fragmentShader), static_cast<uint32_t>(i) < shaderRawData.shaderName.size() ? shaderRawData.shaderName[i] : "");
+          DALI_LOG_RELEASE_INFO("ShaderPreCompiler[ENABLE], precompile shader [%u/%u] >> %s \n", i + 1u, numberOfPrecompiledShader, shaderRawData.shaderName.size() ? shaderRawData.shaderName[i].c_str() : "");
         }
+
+        // Pop last one.
+        precompiledShaderList.pop_back();
       }
       TRACE_UPDATE_RENDER_END("DALI_PRECOMPILE_SHADER");
     }
@@ -937,6 +946,10 @@ void CombinedUpdateRenderController::UpdateRenderThread()
   }
   TRACE_UPDATE_RENDER_BEGIN("DALI_RENDER_THREAD_FINISH");
 
+  // Remove pre-compiled program before context destroyed
+  ShaderPreCompiler::Get().ClearPreCompiledPrograms();
+  ShaderPreCompiler::Get().Enable(false);
+
   // Inform core of context destruction
   mCore.ContextDestroyed();
 
index e7fd680edad441b4b15cc3601f99156c4b957876..28eeac79b95c680bcb5f3527d301df89a70cc0bb 100644 (file)
@@ -589,32 +589,32 @@ void DragAndDropEcoreWl::TriggerDragEventForWindowTarget(int targetIndex, Ecore_
   bool currentInside = IsIntersection(cursor.x + position.GetX(), cursor.y + position.GetY(), position.GetX(), position.GetY(), size.GetWidth(), size.GetHeight());
 
   // Calculate Drag Enter, Leave, Move Event
-  if(currentInside && !mDropTargets[targetIndex].inside)
+  if(currentInside && !mDropWindowTargets[targetIndex].inside)
   {
-    mDropTargets[targetIndex].inside = true;
+    mDropWindowTargets[targetIndex].inside = true;
     // Call Enter Event
     dragEvent.SetAction(Dali::DragAndDrop::DragType::ENTER);
     dragEvent.SetPosition(cursor);
-    mDropTargets[targetIndex].callback(dragEvent);
+    mDropWindowTargets[targetIndex].callback(dragEvent);
     // Accept Offer
     ecore_wl2_offer_mimes_set(event->offer, mimes);
   }
-  else if(!currentInside && mDropTargets[targetIndex].inside)
+  else if(!currentInside && mDropWindowTargets[targetIndex].inside)
   {
-    mDropTargets[targetIndex].inside = false;
+    mDropWindowTargets[targetIndex].inside = false;
     // Call Leave Event
     dragEvent.SetAction(Dali::DragAndDrop::DragType::LEAVE);
     dragEvent.SetPosition(cursor);
-    mDropTargets[targetIndex].callback(dragEvent);
+    mDropWindowTargets[targetIndex].callback(dragEvent);
     // Reject Offer
     ecore_wl2_offer_accept(event->offer, nullptr);
   }
-  else if(currentInside && mDropTargets[targetIndex].inside)
+  else if(currentInside && mDropWindowTargets[targetIndex].inside)
   {
     // Call Move Event
     dragEvent.SetAction(Dali::DragAndDrop::DragType::MOVE);
     dragEvent.SetPosition(cursor);
-    mDropTargets[targetIndex].callback(dragEvent);
+    mDropWindowTargets[targetIndex].callback(dragEvent);
   }
 }
 
index 1cb10c07e2182c04575011a848bcb911166be9d8..8bc27399fb7b83331d1cc93fb45ffc8400ed2f0c 100644 (file)
@@ -1,19 +1,19 @@
 /*
-* Copyright (c) 2024 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.
-*
-*/
+ * Copyright (c) 2024 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.
+ *
+ */
 
 #include <dali/integration-api/debug.h>
 #include <dali/internal/graphics/common/shader-parser.h>
@@ -575,4 +575,4 @@ void Parse(const ShaderParserInfo& parseInfo, std::vector<std::string>& output)
   }
 }
 
-} // namespace Dali::Internal::ShaderParser
\ No newline at end of file
+} // namespace Dali::Internal::ShaderParser
index 3478d680eed475066a153b1b0d04f7b0bf2e6828..8a63e50f7762ec6eb30fb6585e0571298684b208 100644 (file)
@@ -70,8 +70,21 @@ struct GLESDeleter
 
   void operator()(T* object)
   {
-    // Discard resource (add it to discard queue)
-    object->DiscardResource();
+    // GLES object deleter should skip discard queue if controller shutting down
+    if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
+    {
+      // Discard resource (add it to discard queue)
+      object->DiscardResource();
+    }
+    else
+    {
+      // Destroy and delete object otherwise
+      if(DALI_LIKELY(object))
+      {
+        object->DestroyResource();
+      }
+      delete object;
+    }
   }
 };
 
@@ -130,8 +143,15 @@ T0* CastObject(T1* apiObject)
 const uint32_t TEXTURE_UPLOAD_MAX_BUFER_SIZE_MB = 1;
 
 DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_EGL, false);
+
+bool gIsShuttingDown = true; ///< Global static flag to ensure that we have single graphics controller instance per each UpdateRender thread loop.
 } // namespace
 
+bool EglGraphicsController::IsShuttingDown()
+{
+  return gIsShuttingDown;
+}
+
 EglGraphicsController::EglGraphicsController()
 : mTextureDependencyChecker(*this),
   mSyncPool(*this)
@@ -151,6 +171,7 @@ EglGraphicsController::~EglGraphicsController()
 void EglGraphicsController::InitializeGLES(Integration::GlAbstraction& glAbstraction)
 {
   DALI_LOG_RELEASE_INFO("Initializing Graphics Controller Phase 1\n");
+
   mGlAbstraction  = &glAbstraction;
   mContext        = std::make_unique<GLES::Context>(*this, mGlAbstraction);
   mCurrentContext = mContext.get();
@@ -162,6 +183,9 @@ void EglGraphicsController::Initialize(Integration::GraphicsSyncAbstraction& syn
   DALI_LOG_RELEASE_INFO("Initializing Graphics Controller Phase 2\n");
   auto* syncImplPtr = static_cast<Internal::Adaptor::EglSyncImplementation*>(&syncImplementation);
 
+  DALI_ASSERT_ALWAYS(gIsShuttingDown && "Don't initialize Phase 2 EglGraphicsController twice");
+  gIsShuttingDown = false;
+
   mEglSyncImplementation = syncImplPtr;
   mGraphics              = &graphicsInterface;
 }
@@ -193,6 +217,28 @@ void EglGraphicsController::WaitIdle()
   Flush();
 }
 
+void EglGraphicsController::Shutdown()
+{
+  DALI_ASSERT_ALWAYS(!gIsShuttingDown && "Don't call EglGraphicsController::Shutdown twice");
+  gIsShuttingDown = true;
+
+  // Final flush
+  Flush();
+
+  if(mContext)
+  {
+    mContext->GlContextDestroyed();
+  }
+
+  for(auto&& context : mSurfaceContexts)
+  {
+    if(context.second)
+    {
+      context.second->GlContextDestroyed();
+    }
+  }
+}
+
 void EglGraphicsController::PresentRenderTarget(RenderTarget* renderTarget)
 {
   GLES::CommandBuffer* presentCommandBuffer{nullptr};
@@ -1082,4 +1128,14 @@ Graphics::UniquePtr<Graphics::Texture> EglGraphicsController::ReleaseTextureFrom
   return texture;
 }
 
+bool EglGraphicsController::HasClipMatrix() const
+{
+  return false;
+}
+
+const Matrix& EglGraphicsController::GetClipMatrix() const
+{
+  return Matrix::IDENTITY;
+}
+
 } // namespace Dali::Graphics
index 54a4e8e89615cd9d4258888bd1b18e9f41e778c9..b14a5aa229843ed73a419f1d2e15edd824372ced 100644 (file)
@@ -68,6 +68,11 @@ class TextureDependencyChecker;
 class EglGraphicsController : public Graphics::Controller
 {
 public:
+  /**
+   * @brief Get whether is graphics controller shutting down or not.
+   */
+  static bool IsShuttingDown();
+
   /**
    * @brief Constructor
    */
@@ -142,26 +147,7 @@ public:
   /**
    * @copydoc Dali::Graphics::Shutdown()
    */
-  void Shutdown() override
-  {
-    mIsShuttingDown = true;
-
-    // Final flush
-    Flush();
-
-    if(mContext)
-    {
-      mContext->GlContextDestroyed();
-    }
-
-    for(auto&& context : mSurfaceContexts)
-    {
-      if(context.second)
-      {
-        context.second->GlContextDestroyed();
-      }
-    }
-  }
+  void Shutdown() override;
 
   /**
    * @copydoc Dali::Graphics::Destroy()
@@ -350,7 +336,7 @@ public: // ResourceId relative API.
 public:
   [[nodiscard]] Integration::GlAbstraction* GetGL() const
   {
-    if(mIsShuttingDown)
+    if(DALI_UNLIKELY(IsShuttingDown()))
     {
       return nullptr;
     }
@@ -740,11 +726,6 @@ public:
     mGLESVersion = glesVersion;
   }
 
-  bool IsShuttingDown() const
-  {
-    return mIsShuttingDown;
-  }
-
   /**
    * @brief Reset texture cache in the contexts
    */
@@ -849,6 +830,9 @@ public:
     return mCapacity;
   }
 
+  bool          HasClipMatrix() const override;
+  const Matrix& GetClipMatrix() const override;
+
 private:
   Integration::GlAbstraction*              mGlAbstraction{nullptr};
   Integration::GlContextHelperAbstraction* mGlContextHelperAbstraction{nullptr};
@@ -891,8 +875,6 @@ private:
   GLES::GLESVersion mGLESVersion{GLES::GLESVersion::GLES_20}; ///< Runtime supported GLES version
   uint32_t          mTextureUploadTotalCPUMemoryUsed{0u};
 
-  bool mIsShuttingDown{false}; ///< Indicates whether the controller is shutting down
-
   std::queue<const GLES::CommandBuffer*> mPresentationCommandBuffers{}; ///< Queue of reusable command buffers used by presentation engine
 
   void* mSharedContext{nullptr}; ///< Shared EGL context
index 44dd8f41444bf5494bceb2eb12c5a0197b0f44ac..bfcccd6a10db0ffbccd66fc9dec9f544cf1c8968 100644 (file)
@@ -38,6 +38,12 @@ SyncObject::~SyncObject()
 
 void SyncObject::DestroyResource()
 {
+  if(DALI_UNLIKELY(EglGraphicsController::IsShuttingDown()))
+  {
+    return;
+  }
+  mEglSyncImplementation.DestroySyncObject(mEglSyncObject);
+  mEglSyncObject = nullptr;
 }
 
 bool SyncObject::InitializeResource()
@@ -51,8 +57,7 @@ void SyncObject::DiscardResource()
 {
   // Called from custom deleter.
   // Don't use discard queue, drop immediately.
-  mEglSyncImplementation.DestroySyncObject(mEglSyncObject);
-  mEglSyncObject = nullptr;
+  DestroyResource();
 }
 
 bool SyncObject::IsSynced()
index d2fbaaf32823e12114c4a7e2afccffbde481f950..107e4212b69dedd0e04d4da0ddf8aa5048098001 100644 (file)
@@ -125,6 +125,11 @@ void Buffer::InitializeCPUBuffer()
 
 void Buffer::InitializeGPUBuffer()
 {
+  if(DALI_UNLIKELY(EglGraphicsController::IsShuttingDown()))
+  {
+    return;
+  }
+
   auto context = mController.GetCurrentContext();
   auto gl      = mController.GetGL();
   if(!gl || !context)
@@ -160,10 +165,13 @@ void Buffer::DestroyResource()
   // Deestroy GPU allocation
   else
   {
-    auto gl = mController.GetGL();
-    if(gl)
+    if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
     {
-      gl->DeleteBuffers(1, &mBufferId);
+      auto gl = mController.GetGL();
+      if(gl)
+      {
+        gl->DeleteBuffers(1, &mBufferId);
+      }
     }
   }
 }
index 6695fbf7cfec87bc9631f7663ef9e4de438a57a0..e7b83313887947eba79987c03b1d7f9fc1d78e96 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -179,23 +179,26 @@ bool Framebuffer::InitializeResource()
 
 void Framebuffer::DestroyResource()
 {
-  auto context = mController.GetCurrentContext();
-  auto gl      = mController.GetGL();
-  if(gl && context && mInitialized)
+  if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
   {
-    if(mDepthBufferId)
+    auto context = mController.GetCurrentContext();
+    auto gl      = mController.GetGL();
+    if(gl && context && mInitialized)
     {
-      gl->DeleteRenderbuffers(1, &mDepthBufferId);
-    }
-    if(mStencilBufferId)
-    {
-      gl->DeleteRenderbuffers(1, &mStencilBufferId);
-    }
+      if(mDepthBufferId)
+      {
+        gl->DeleteRenderbuffers(1, &mDepthBufferId);
+      }
+      if(mStencilBufferId)
+      {
+        gl->DeleteRenderbuffers(1, &mStencilBufferId);
+      }
 
-    context->DeleteFramebuffers(1, &mFramebufferId);
+      context->DeleteFramebuffers(1, &mFramebufferId);
 
-    mFramebufferId = 0u;
-    mInitialized   = false;
+      mFramebufferId = 0u;
+      mInitialized   = false;
+    }
   }
 }
 
index 183efb6e02e1222fc82c6abdbd92d7312e13ce9c..3f2fe69ba0940bec06fa7f3046283b338f13a7af 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
@@ -39,26 +39,18 @@ struct CachedObjectDeleter
 
   void operator()(T* object)
   {
-    // Discard resource (add it to discard queue)
-    object->DiscardResource();
-  }
-};
-
-template<>
-struct CachedObjectDeleter<GLES::Program>
-{
-  CachedObjectDeleter() = default;
-
-  void operator()(GLES::Program* object)
-  {
-    // Program deleter should skip discard queue if controller shutting down
-    if(!object->GetController().IsShuttingDown())
+    // Discard resource (add it to discard queue) if controller is not shutting down
+    if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
     {
       object->DiscardResource();
     }
     else
     {
-      // delete object otherwise
+      // Destroy and delete object otherwise
+      if(DALI_LIKELY(object))
+      {
+        object->DestroyResource();
+      }
       delete object;
     }
   }
@@ -502,15 +494,24 @@ ShaderImpl* PipelineCache::FindShaderImpl(const ShaderCreateInfo& shaderCreateIn
     for(auto& item : mImpl->shaderEntries)
     {
       auto& itemInfo = item.shaderImpl->GetCreateInfo();
+
+      // Check metadata
       if(itemInfo.pipelineStage != shaderCreateInfo.pipelineStage ||
          itemInfo.shaderlanguage != shaderCreateInfo.shaderlanguage ||
-         itemInfo.sourceMode != shaderCreateInfo.sourceMode ||
-         itemInfo.sourceSize != shaderCreateInfo.sourceSize)
+         itemInfo.sourceMode != shaderCreateInfo.sourceMode)
+      {
+        continue;
+      }
+
+      // Get offset of source. Since prefix might be removed after ShaderImpl created,
+      // we should compare only after the offset.
+      auto sourceOffset = item.shaderImpl->GetSourceOffset();
+      if(itemInfo.sourceSize + sourceOffset != shaderCreateInfo.sourceSize)
       {
         continue;
       }
 
-      if(memcmp(itemInfo.sourceData, shaderCreateInfo.sourceData, itemInfo.sourceSize) == 0)
+      if(memcmp(itemInfo.sourceData, reinterpret_cast<const uint8_t*>(shaderCreateInfo.sourceData) + sourceOffset, itemInfo.sourceSize) == 0)
       {
         return item.shaderImpl.get();
       }
index a927fadc81123c830f7c3842fcbf9018a070d41e..19d9a7dca3467659d0fd280f24bf2186ae86cfe7 100644 (file)
@@ -91,6 +91,11 @@ auto& PipelineImpl::GetController() const
 
 void PipelineImpl::Bind(const uint32_t glProgram) const
 {
+  if(DALI_UNLIKELY(EglGraphicsController::IsShuttingDown()))
+  {
+    return; // Early out if shutting down
+  }
+
   if(auto gl = GetController().GetGL())
   {
     gl->UseProgram(glProgram);
index 0da8eb0d0d0f6087e54125b0819b3238b305e609..ec3f3afdb7eca500d718ba56799879c4529e9a6a 100644 (file)
@@ -122,6 +122,11 @@ ProgramImpl::~ProgramImpl() = default;
 
 bool ProgramImpl::Destroy()
 {
+  if(DALI_UNLIKELY(EglGraphicsController::IsShuttingDown()))
+  {
+    return false; // Early out if shutting down
+  }
+
   if(mImpl->glProgram)
   {
     auto gl = mImpl->controller.GetGL();
@@ -352,6 +357,11 @@ void ProgramImpl::UpdateStandaloneUniformBlock(const char* ptr)
 
   const auto& extraInfos = reflection.GetStandaloneUniformExtraInfo();
 
+  if(DALI_UNLIKELY(EglGraphicsController::IsShuttingDown()))
+  {
+    return; // Early out if shutting down
+  }
+
   auto* gl = GetController().GetGL();
   if(!gl)
   {
index 2ee3020fd36a31ebe3ccfec2d2512ab9323f64d4..94e6191b9ed2b155e744f45a5c9dc91b68db68e1 100644 (file)
@@ -36,14 +36,13 @@ struct ShaderImpl::Impl
 
     // Make a copy of source code. if code is meant to be used
     // by modern parser, skip the prefix part
-    size_t dataStartIndex = 0;
     size_t dataSize;
 
-    ShaderImpl::StripLegacyCodeIfNeeded(_createInfo, dataStartIndex, glslVersion, dataSize);
+    ShaderImpl::StripLegacyCodeIfNeeded(_createInfo, sourceOffset, glslVersion, dataSize);
 
     source.resize(dataSize);
-    std::copy(reinterpret_cast<const uint8_t*>(_createInfo.sourceData) + dataStartIndex,
-              reinterpret_cast<const uint8_t*>(_createInfo.sourceData) + dataStartIndex + dataSize,
+    std::copy(reinterpret_cast<const uint8_t*>(_createInfo.sourceData) + sourceOffset,
+              reinterpret_cast<const uint8_t*>(_createInfo.sourceData) + sourceOffset + dataSize,
               source.data());
 
     // Substitute pointer
@@ -155,6 +154,10 @@ struct ShaderImpl::Impl
   std::vector<uint8_t>   source{};
   std::vector<uint8_t>   sourcePreprocessed{};
 
+  size_t sourceOffset{0u}; /// byte offset of source data from original CreateInfo.
+                           /// It will be changed after call StripLegacyCodeIfNeeded
+                           /// More detail, createInfo.sourceData[0] == source[0] == (original CreateInfo).sourceData[sourceOffset];
+
   uint32_t glShader{};
   uint32_t refCount{0u};
   uint32_t flushCount{0u};  ///< Number of frames at refCount=0
@@ -168,7 +171,7 @@ ShaderImpl::ShaderImpl(const Graphics::ShaderCreateInfo& createInfo, Graphics::E
 
 ShaderImpl::~ShaderImpl()
 {
-  if(!mImpl->controller.IsShuttingDown())
+  if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
   {
     mImpl->Destroy();
   }
@@ -207,6 +210,11 @@ uint32_t ShaderImpl::Release()
   return mImpl->glslVersion;
 }
 
+[[nodiscard]] size_t ShaderImpl::GetSourceOffset() const
+{
+  return mImpl->sourceOffset;
+}
+
 /**
  * @brief Compiles shader
  *
@@ -234,6 +242,16 @@ const ShaderCreateInfo& ShaderImpl::GetCreateInfo() const
 
 void ShaderImpl::StripLegacyCodeIfNeeded(const ShaderCreateInfo& info, size_t& startIndex, uint32_t& glslVersion, size_t& finalDataSize)
 {
+  startIndex = 0u;
+
+  // Fast-out if shader is not a text.
+  if(info.sourceMode != ShaderSourceMode::TEXT)
+  {
+    glslVersion   = info.shaderVersion;
+    finalDataSize = info.sourceSize;
+    return;
+  }
+
   // Make a copy of source code. if code is meant to be used
   // by modern parser, skip the prefix part
   auto text   = reinterpret_cast<const char*>(info.sourceData);
@@ -248,7 +266,8 @@ void ShaderImpl::StripLegacyCodeIfNeeded(const ShaderCreateInfo& info, size_t& s
     else if(result == 0)
     {
       char* end;
-      startIndex = std::strtoul(reinterpret_cast<const char*>(info.sourceData) + 21, &end, 10);
+      startIndex  = std::strtoul(reinterpret_cast<const char*>(info.sourceData) + 21, &end, 10);
+      glslVersion = info.shaderVersion;
     }
   }
   else
@@ -283,6 +302,11 @@ Shader::~Shader()
 {
   if(!mShader->Release())
   {
+    if(DALI_UNLIKELY(EglGraphicsController::IsShuttingDown()))
+    {
+      return; // Early out if shutting down
+    }
+
     GetImplementation()->GetController().GetPipelineCache().MarkShaderCacheFlushRequired();
   }
 }
@@ -294,11 +318,7 @@ Shader::~Shader()
 
 void Shader::DiscardResource()
 {
-  auto& controller = GetImplementation()->GetController();
-  if(!controller.IsShuttingDown())
-  {
-    controller.DiscardResource(this);
-  }
+  GetImplementation()->GetController().DiscardResource(this);
 }
 
 uint32_t Shader::GetGLSLVersion() const
index ac85822e0c908c557e1370e2bca5c8120585fbda..077fcbd3a591cd9d9851629501b55eefe2377c4e 100644 (file)
@@ -126,6 +126,12 @@ public:
    */
   [[nodiscard]] uint32_t GetGLSLVersion() const;
 
+  /**
+   * @brief Returns source prefix offset infomation.
+   * @return Returns source prefix offset value
+   */
+  [[nodiscard]] size_t GetSourceOffset() const;
+
 private:
   friend class Shader;
   struct Impl;
index cd4b66d0c8226f7658e0342093e2d8aba325281b..7471f5c6c6888fd95283c07b062fa2cb23c72b51 100644 (file)
@@ -310,20 +310,26 @@ bool Texture::InitializeTexture()
 
 void Texture::DestroyResource()
 {
-  auto gl = mController.GetGL();
-  if(!gl)
+  if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
   {
-    return;
-  }
+    auto gl = mController.GetGL();
+    if(!gl)
+    {
+      return;
+    }
 
-  // This is a proper destructor
-  if(mTextureId)
-  {
-    gl->DeleteTextures(1, &mTextureId);
-  }
-  if(mCreateInfo.nativeImagePtr)
-  {
-    mCreateInfo.nativeImagePtr->DestroyResource();
+    // This is a proper destructor
+    if(mTextureId)
+    {
+      gl->DeleteTextures(1, &mTextureId);
+    }
+
+    // TODO : Shouldn't we call DestroyResource even if shutting down?
+    // For now, we use EglExtensions API at DestroyResource. So just block for now.
+    if(mCreateInfo.nativeImagePtr)
+    {
+      mCreateInfo.nativeImagePtr->DestroyResource();
+    }
   }
 }
 
index 1d1bc1197d43c8adfd3e987c27de0fbc3e4113a8..bfaccecf43cf18ea35756d89ee87c08d675c409e 100644 (file)
@@ -36,6 +36,15 @@ SyncObject::~SyncObject()
 
 void SyncObject::DestroyResource()
 {
+  if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
+  {
+    auto gl = mController.GetGL();
+    if(gl)
+    {
+      gl->DeleteSync(mGlSyncObject);
+    }
+    mGlSyncObject = 0;
+  }
 }
 
 bool SyncObject::InitializeResource()
@@ -53,12 +62,7 @@ void SyncObject::DiscardResource()
 {
   // Called from custom deleter.
   // Don't use discard queue, drop immediately.
-  auto gl = mController.GetGL();
-  if(gl)
-  {
-    gl->DeleteSync(mGlSyncObject);
-  }
-  mGlSyncObject = 0;
+  DestroyResource();
 }
 
 bool SyncObject::IsSynced()
index c4cd3991697fadc14fee037395b80660b8c03fc1..6077414f47cc86cf88636c74df336922ede1f578 100644 (file)
@@ -52,7 +52,7 @@ AgingSyncObject::AgingSyncObject(Graphics::EglGraphicsController& controller, co
 
 AgingSyncObject::~AgingSyncObject()
 {
-  if(!controller.IsShuttingDown())
+  if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
   {
     if(egl)
     {
index 6ad22f8c47d06af32bf59e0986272bcec640a9c2..6d3f1492b766780fdd3ebec4b0149c63aa719053 100644 (file)
@@ -78,28 +78,31 @@ void* Memory2::LockRegion(uint32_t offset, uint32_t size)
 
 void Memory2::Unlock(bool flush)
 {
-  if(auto gl = mController.GetGL())
+  if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
   {
-    // for buffer...
-    if(mMapObjectType == MapObjectType::BUFFER && mMappedPointer)
+    if(auto gl = mController.GetGL())
     {
-      auto buffer = static_cast<GLES::Buffer*>(mMapBufferInfo.buffer);
-      if(!buffer->IsCPUAllocated())
+      // for buffer...
+      if(mMapObjectType == MapObjectType::BUFFER && mMappedPointer)
       {
-        buffer->Bind(BufferUsage::VERTEX_BUFFER);
-        gl->BufferSubData(GL_ARRAY_BUFFER, GLintptr(mMapBufferInfo.offset), GLsizeiptr(mMapBufferInfo.size), mMappedPointer);
+        auto buffer = static_cast<GLES::Buffer*>(mMapBufferInfo.buffer);
+        if(!buffer->IsCPUAllocated())
+        {
+          buffer->Bind(BufferUsage::VERTEX_BUFFER);
+          gl->BufferSubData(GL_ARRAY_BUFFER, GLintptr(mMapBufferInfo.offset), GLsizeiptr(mMapBufferInfo.size), mMappedPointer);
+        }
       }
-    }
 
-    if(mIsAllocatedLocally)
-    {
-      free(mMappedPointer);
-      mMappedPointer = nullptr;
-    }
+      if(mIsAllocatedLocally)
+      {
+        free(mMappedPointer);
+        mMappedPointer = nullptr;
+      }
 
-    if(flush)
-    {
-      Flush();
+      if(flush)
+      {
+        Flush();
+      }
     }
   }
 }
index 18e78616a7f19669b3ff21f32746ecc7d4295ba2..c0aec279bbc3707dd7674216ddbe250c0812f093 100644 (file)
@@ -49,25 +49,28 @@ Memory3::~Memory3()
 
 void* Memory3::LockRegion(uint32_t offset, uint32_t size)
 {
-  if(auto gl = mController.GetGL())
+  if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
   {
-    if(mMapObjectType == MapObjectType::BUFFER)
+    if(auto gl = mController.GetGL())
     {
-      auto buffer = static_cast<GLES::Buffer*>(mMapBufferInfo.buffer);
-
-      if(buffer->IsCPUAllocated())
-      {
-        using Ptr      = char*;
-        mMappedPointer = Ptr(buffer->GetCPUAllocatedAddress()) + offset;
-      }
-      else
+      if(mMapObjectType == MapObjectType::BUFFER)
       {
-        gl->BindBuffer(GL_COPY_WRITE_BUFFER, buffer->GetGLBuffer());
-        void* ptr      = nullptr;
-        ptr            = gl->MapBufferRange(GL_COPY_WRITE_BUFFER, GLintptr(mMapBufferInfo.offset), GLsizeiptr(mMapBufferInfo.size), GL_MAP_WRITE_BIT);
-        mMappedPointer = ptr;
+        auto buffer = static_cast<GLES::Buffer*>(mMapBufferInfo.buffer);
+
+        if(buffer->IsCPUAllocated())
+        {
+          using Ptr      = char*;
+          mMappedPointer = Ptr(buffer->GetCPUAllocatedAddress()) + offset;
+        }
+        else
+        {
+          gl->BindBuffer(GL_COPY_WRITE_BUFFER, buffer->GetGLBuffer());
+          void* ptr      = nullptr;
+          ptr            = gl->MapBufferRange(GL_COPY_WRITE_BUFFER, GLintptr(mMapBufferInfo.offset), GLsizeiptr(mMapBufferInfo.size), GL_MAP_WRITE_BIT);
+          mMappedPointer = ptr;
+        }
+        return mMappedPointer;
       }
-      return mMappedPointer;
     }
   }
   return nullptr;
@@ -75,21 +78,24 @@ void* Memory3::LockRegion(uint32_t offset, uint32_t size)
 
 void Memory3::Unlock(bool flush)
 {
-  if(auto gl = mController.GetGL())
+  if(DALI_LIKELY(!EglGraphicsController::IsShuttingDown()))
   {
-    if(mMapObjectType == MapObjectType::BUFFER && mMappedPointer)
+    if(auto gl = mController.GetGL())
     {
-      auto buffer = static_cast<GLES::Buffer*>(mMapBufferInfo.buffer);
-      if(!buffer->IsCPUAllocated())
+      if(mMapObjectType == MapObjectType::BUFFER && mMappedPointer)
       {
-        gl->BindBuffer(GL_COPY_WRITE_BUFFER, buffer->GetGLBuffer());
-        gl->UnmapBuffer(GL_COPY_WRITE_BUFFER);
+        auto buffer = static_cast<GLES::Buffer*>(mMapBufferInfo.buffer);
+        if(!buffer->IsCPUAllocated())
+        {
+          gl->BindBuffer(GL_COPY_WRITE_BUFFER, buffer->GetGLBuffer());
+          gl->UnmapBuffer(GL_COPY_WRITE_BUFFER);
+        }
       }
-    }
 
-    if(flush)
-    {
-      Flush();
+      if(flush)
+      {
+        Flush();
+      }
     }
 
     mMappedPointer = nullptr;
index 41c771a3ced6c4ce19521a639129148cc550911a..a334a91d94318bc3922a0b39235eb975f8d69267 100644 (file)
@@ -158,6 +158,11 @@ EglSyncImplementation::EglSyncImplementation()
 
 EglSyncImplementation::~EglSyncImplementation()
 {
+  for(auto& syncObject : mSyncObjects)
+  {
+    delete static_cast<EglSyncObject*>(syncObject);
+  }
+  mSyncObjects.Clear();
 }
 
 void EglSyncImplementation::Initialize(EglImplementation* eglImpl)
index 9e70eb6be806413de4bcf8c7b299efb86f31e852..1ffcbf6723e62e47b5d00640734caab70ee904dd 100644 (file)
@@ -28,7 +28,7 @@ namespace Dali::Graphics::Vulkan
 {
 BufferImpl* BufferImpl::New(Device& device, size_t size, vk::BufferUsageFlags usageFlags)
 {
-  return New(device, size, vk::SharingMode(vk::SharingMode::eExclusive), usageFlags, vk::MemoryPropertyFlags(vk::MemoryPropertyFlagBits::eHostVisible));
+  return New(device, size, vk::SharingMode(vk::SharingMode::eExclusive), usageFlags, vk::MemoryPropertyFlags(vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent));
 }
 
 BufferImpl* BufferImpl::New(Device& device, size_t size, vk::SharingMode sharingMode, vk::BufferUsageFlags usageFlags, vk::MemoryPropertyFlags memoryProperties)
@@ -54,6 +54,11 @@ BufferImpl::BufferImpl(Device& device, const vk::BufferCreateInfo& createInfo)
 {
 }
 
+BufferImpl::~BufferImpl()
+{
+  Destroy();
+}
+
 void BufferImpl::Initialize(vk::MemoryPropertyFlags memoryProperties)
 {
   // Allocate
@@ -62,7 +67,7 @@ void BufferImpl::Initialize(vk::MemoryPropertyFlags memoryProperties)
                                                 requirements.memoryTypeBits,
                                                 memoryProperties);
 
-  mMemory = std::make_unique<MemoryImpl>(mDevice, size_t(requirements.size), size_t(requirements.alignment), ((memoryProperties & vk::MemoryPropertyFlagBits::eHostVisible) == vk::MemoryPropertyFlagBits::eHostVisible));
+  mMemory = std::make_unique<MemoryImpl>(mDevice, size_t(requirements.size), size_t(requirements.alignment), memoryProperties);
 
   auto allocateInfo = vk::MemoryAllocateInfo{}
                         .setMemoryTypeIndex(memoryTypeIndex)
@@ -84,19 +89,16 @@ void BufferImpl::Initialize(vk::MemoryPropertyFlags memoryProperties)
   }
 }
 
-void BufferImpl::DestroyNow()
+void BufferImpl::Destroy()
 {
-  DestroyVulkanResources(mDevice.GetLogicalDevice(), mBuffer, mMemory->ReleaseVkObject(), &mDevice.GetAllocator());
-  mBuffer = nullptr;
-  mMemory = nullptr;
-}
+  DALI_LOG_INFO(gVulkanFilter, Debug::General, "Destroying buffer: %p\n", static_cast<VkBuffer>(mBuffer));
 
-void BufferImpl::DestroyVulkanResources(vk::Device device, vk::Buffer buffer, vk::DeviceMemory memory, const vk::AllocationCallbacks* allocator)
-{
-  DALI_LOG_INFO(gVulkanFilter, Debug::General, "Invoking deleter function: buffer->%p\n", static_cast<VkBuffer>(buffer));
+  auto device = mDevice.GetLogicalDevice();
+  device.destroyBuffer(mBuffer, mDevice.GetAllocator());
 
-  device.destroyBuffer(buffer, allocator);
-  device.freeMemory(memory, allocator);
+  mMemory.reset();
+  mBuffer = nullptr;
+  mMemory = nullptr;
 }
 
 Graphics::MemoryRequirements BufferImpl::GetMemoryRequirements()
index 9e59418d911008f0f30e8254b412c0e4b7ffc311..0a09ef9c0e9da02f72d914c42e64613e055d2351 100644 (file)
 
 #include <dali/graphics-api/graphics-types.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-memory-impl.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-types.h>
 #include <dali/internal/graphics/vulkan/vulkan-device.h>
 
 #include <cstdint>
 
 namespace Dali::Graphics::Vulkan
 {
-class BufferImpl // : public VkManaged
+class BufferImpl
 {
 public:
   static BufferImpl* New(Vulkan::Device& device, size_t size, vk::BufferUsageFlags usageFlags);
 
   static BufferImpl* New(Vulkan::Device& device, size_t size, vk::SharingMode sharingMode, vk::BufferUsageFlags usageFlags, vk::MemoryPropertyFlags memoryProperties);
 
+  /** Destructor */
+  ~BufferImpl();
+
   /**
    * Returns buffer usage flags
    * @return
@@ -75,7 +79,7 @@ public:
    * @note Calling this function is unsafe and makes any further use of
    * buffer invalid.
    */
-  void DestroyNow();
+  void Destroy();
 
   BufferImpl(const Buffer&)            = delete;
   BufferImpl& operator=(const Buffer&) = delete;
index e725d77d32eb3094f09c966d2ca9037910b7fa68..075f7b700baba7bd42ec9d376a5c69e5d6f2a54d 100644 (file)
 #include <dali/public-api/common/dali-common.h>
 
 // EXTERNAL INCLUDES
-#include <cstdint>
 
 namespace Dali::Graphics::Vulkan
 {
-
 Buffer::Buffer(const Graphics::BufferCreateInfo& createInfo, VulkanGraphicsController& controller)
 : BufferResource(createInfo, controller)
 {
@@ -121,8 +119,7 @@ void Buffer::DestroyResource()
     }
     mBufferPtr = nullptr;
   }
-  // Deestroy GPU allocation
-  else
+  else // Destroy GPU allocation
   {
     delete(mBufferImpl);
     mBufferImpl = nullptr;
index 72caa86415463b8e4463e1bc43451d197f34002c..a6fb0ebb01adbf11c7cd9a69a5e875903e4f7418 100644 (file)
@@ -45,8 +45,6 @@ public:
    * @copydoc Graphics::Vulkan::Resource::InitializeResource();
    */
   bool InitializeResource() override;
-  void InitializeCPUBuffer();
-  void InitializeGPUBuffer();
 
   /**
    * @return false - Vulkan should always allocate GPU buffers
@@ -59,6 +57,23 @@ public:
    */
   void DiscardResource() override;
 
+  /**
+   * @copydoc Graphics::Vulkan::Resource::GetAllocationCallbacks()
+   */
+  [[nodiscard]] const Graphics::AllocationCallbacks* GetAllocationCallbacks() const override
+  {
+    return mCreateInfo.allocationCallbacks;
+  }
+
+  /**
+   * @copydoc Graphics::Vulkan::Resource::InvokeDeleter()
+   * Only intended for use by discard queue.
+   */
+  void InvokeDeleter() override
+  {
+    this->~Buffer();
+  }
+
   void Bind(Graphics::BufferUsage bindingTarget) const;
 
   BufferImpl* GetImpl()
@@ -70,6 +85,10 @@ public:
     return nullptr;
   }
 
+private:
+  void InitializeCPUBuffer();
+  void InitializeGPUBuffer();
+
 private:
   union
   {
index c1b931aff1bdf4fa4deb37ba17e8a897fc08e522..200f3f829ba04578d1dd9ea5e377f18b99db7ade 100644 (file)
@@ -15,6 +15,7 @@
  *
  */
 
+// CLASS HEADER
 #include <dali/internal/graphics/vulkan-impl/vulkan-command-buffer-impl.h>
 
 // INTERNAL INCLUDES
 #include <dali/internal/graphics/vulkan-impl/vulkan-command-pool-impl.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-framebuffer-impl.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-image-impl.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-image-view-impl.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-pipeline-impl.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-sampler-impl.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-sampler.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-swapchain-impl.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-texture.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-types.h>
 #include <dali/internal/graphics/vulkan/vulkan-device.h>
 
+#include <dali/integration-api/debug.h>
+
+#if defined(DEBUG_ENABLED)
+extern Debug::Filter* gLogCmdBufferFilter;
+#endif
+
 namespace Dali
 {
 namespace Graphics
@@ -47,7 +58,15 @@ CommandBufferImpl::CommandBufferImpl(CommandPool&                         comman
 {
 }
 
-CommandBufferImpl::~CommandBufferImpl() = default;
+CommandBufferImpl::~CommandBufferImpl()
+{
+  Destroy();
+}
+
+void CommandBufferImpl::Destroy()
+{
+  // Command buffer Pool cleanup will remove the vulkan command buffer
+}
 
 /** Begin recording */
 void CommandBufferImpl::Begin(vk::CommandBufferUsageFlags       usageFlags,
@@ -57,7 +76,6 @@ void CommandBufferImpl::Begin(vk::CommandBufferUsageFlags       usageFlags,
   auto info = vk::CommandBufferBeginInfo{};
 
   vk::CommandBufferInheritanceInfo defaultInheritanceInfo{};
-  defaultInheritanceInfo.sType                = vk::StructureType::eCommandBufferInheritanceInfo;
   defaultInheritanceInfo.pNext                = nullptr;
   defaultInheritanceInfo.subpass              = 0;
   defaultInheritanceInfo.occlusionQueryEnable = false;
@@ -109,10 +127,117 @@ void CommandBufferImpl::BindPipeline(const Graphics::Pipeline* pipeline)
 
   // Bind if pipeline is ready (if nullptr, pipeline isn't ready).
   // If pipeline is valid, bind it early
+
   if(pipelineImpl.GetVkPipeline())
   {
     mCommandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipelineImpl.GetVkPipeline());
+
+    mCurrentProgram = pipelineImpl.GetProgram()->GetImplementation();
+  }
+  else
+  {
+    mCurrentProgram = nullptr;
+  }
+}
+
+void CommandBufferImpl::BindVertexBuffers(
+  uint32_t                        firstBinding,
+  const std::vector<BufferImpl*>& buffers,
+  const std::vector<uint32_t>&    offsets)
+{
+  // update list of used resources and create an array of VkBuffers
+  std::vector<vk::Buffer> vkBuffers;
+  vkBuffers.reserve(buffers.size());
+  for(auto&& buffer : buffers)
+  {
+    vkBuffers.emplace_back(buffer->GetVkHandle());
+  }
+  std::vector<vk::DeviceSize> vkOffsets;
+  vkOffsets.reserve(offsets.size());
+  for(auto&& offset : offsets)
+  {
+    vkOffsets.emplace_back(static_cast<vk::DeviceSize>(offset));
   }
+  mCommandBuffer.bindVertexBuffers(firstBinding, vkBuffers.size(), vkBuffers.data(), vkOffsets.data());
+}
+
+void CommandBufferImpl::BindIndexBuffer(
+  BufferImpl& buffer,
+  uint32_t    offset,
+  Format      format)
+{
+  if(format == Graphics::Format::R16_UINT)
+  {
+    mCommandBuffer.bindIndexBuffer(buffer.GetVkHandle(), offset, vk::IndexType::eUint16);
+  }
+  else if(format == Graphics::Format::R32_UINT)
+  {
+    mCommandBuffer.bindIndexBuffer(buffer.GetVkHandle(), offset, vk::IndexType::eUint32);
+  }
+}
+
+void CommandBufferImpl::BindUniformBuffers(const std::vector<UniformBufferBinding>& bindings)
+{
+  // Needs descriptor set pools.
+  bool standalone = true;
+  for(const auto& uniformBinding : bindings)
+  {
+    if(standalone)
+    {
+      // First buffer is not used in Vulkan (it's a fake buffer in GLES)
+      standalone = false;
+      continue;
+    }
+
+    auto buffer = const_cast<Vulkan::Buffer*>(static_cast<const Vulkan::Buffer*>(uniformBinding.buffer));
+
+    CommandBufferImpl::DeferredUniformBinding deferredUniformBinding{};
+    deferredUniformBinding.buffer  = buffer->GetImpl()->GetVkHandle();
+    deferredUniformBinding.offset  = uniformBinding.offset;
+    deferredUniformBinding.range   = uniformBinding.dataSize;
+    deferredUniformBinding.binding = uniformBinding.binding;
+
+    mDeferredUniformBindings.push_back(deferredUniformBinding);
+  }
+}
+
+void CommandBufferImpl::BindTextures(const std::vector<TextureBinding>& textureBindings)
+{
+  for(const auto& textureBinding : textureBindings)
+  {
+    auto texture     = static_cast<const Vulkan::Texture*>(textureBinding.texture);
+    auto sampler     = const_cast<Vulkan::Sampler*>(static_cast<const Vulkan::Sampler*>(textureBinding.sampler));
+    auto samplerImpl = sampler ? sampler->GetImpl() : texture->GetSampler();
+    auto vkSampler   = samplerImpl ? samplerImpl->GetVkHandle() : nullptr;
+    // @todo If there is still no sampler, fall back to default?
+    if(!vkSampler)
+    {
+      DALI_LOG_INFO(gLogCmdBufferFilter, Debug::Concise, "No sampler for texture binding\n");
+    }
+
+    auto image     = texture->GetImage();
+    auto imageView = texture->GetImageView();
+
+    // test if image is valid, skip invalid image
+    if(!image || !image->GetVkHandle())
+    {
+      continue;
+    }
+
+    // Store: imageView, sampler & texture.binding for later use
+    // We don't know at this point what pipeline is bound (As dali-core
+    // binds the pipeline after calling this API)
+
+    mDeferredTextureBindings.emplace_back();
+    mDeferredTextureBindings.back().imageView = imageView->GetVkHandle();
+    mDeferredTextureBindings.back().sampler   = vkSampler;
+    mDeferredTextureBindings.back().binding   = textureBinding.binding; // zero indexed
+  }
+}
+
+void CommandBufferImpl::BindSamplers(const std::vector<SamplerBinding>& samplerBindings)
+{
+  // Unused in core
 }
 
 vk::CommandBuffer CommandBufferImpl::GetVkHandle() const
@@ -171,17 +296,25 @@ uint32_t CommandBufferImpl::GetPoolAllocationIndex() const
   return mPoolAllocationIndex;
 }
 
-bool CommandBufferImpl::OnDestroy()
-{
-  mOwnerCommandPool->ReleaseCommandBuffer(*this);
-  return true;
-}
-
 void CommandBufferImpl::Draw(uint32_t vertexCount,
                              uint32_t instanceCount,
                              uint32_t firstVertex,
                              uint32_t firstInstance)
 {
+  // Example of deferred binding descriptors
+  if(mCurrentProgram)
+  {
+    auto set = mCurrentProgram->AllocateDescriptorSet(-1); // allocate from recent pool
+    if(set)
+    {
+      BindResources(set);
+    }
+  }
+  if(instanceCount == 0)
+  {
+    instanceCount = 1;
+  }
+  mCommandBuffer.draw(vertexCount, instanceCount, firstVertex, firstInstance);
 }
 
 void CommandBufferImpl::DrawIndexed(uint32_t indexCount,
@@ -190,17 +323,119 @@ void CommandBufferImpl::DrawIndexed(uint32_t indexCount,
                                     int32_t  vertexOffset,
                                     uint32_t firstInstance)
 {
+  // Example of deferred binding descriptors
+  if(mCurrentProgram)
+  {
+    auto set = mCurrentProgram->AllocateDescriptorSet(-1); // allocate from recent pool
+    if(set)
+    {
+      BindResources(set);
+    }
+  }
+  // draw here
+  if(instanceCount == 0)
+  {
+    instanceCount = 1;
+  }
+  mCommandBuffer.drawIndexed(indexCount,
+                             instanceCount,
+                             firstIndex,
+                             static_cast<int32_t>(vertexOffset),
+                             firstInstance);
+}
+
+void CommandBufferImpl::DrawIndexedIndirect(BufferImpl& buffer,
+                                            uint32_t    offset,
+                                            uint32_t    drawCount,
+                                            uint32_t    stride)
+{
+  mCommandBuffer.drawIndexedIndirect(buffer.GetVkHandle(), static_cast<vk::DeviceSize>(offset), drawCount, stride);
+}
+
+void CommandBufferImpl::ExecuteCommandBuffers(std::vector<vk::CommandBuffer>& commandBuffers)
+{
+  mCommandBuffer.executeCommands(commandBuffers);
+}
+
+void CommandBufferImpl::SetScissor(Rect2D value)
+{
+  mCommandBuffer.setScissor(0, 1, reinterpret_cast<vk::Rect2D*>(&value));
 }
 
-void CommandBufferImpl::DrawIndexedIndirect(Graphics::Buffer& buffer,
-                                            uint32_t          offset,
-                                            uint32_t          drawCount,
-                                            uint32_t          stride)
+void CommandBufferImpl::SetViewport(Viewport value)
 {
+  mCommandBuffer.setViewport(0, 1, reinterpret_cast<vk::Viewport*>(&value));
 }
 
-void CommandBufferImpl::ExecuteCommandBuffers(std::vector<const Graphics::CommandBuffer*>&& commandBuffers)
+void CommandBufferImpl::BindResources(vk::DescriptorSet descriptorSet)
 {
+  std::vector<vk::DescriptorImageInfo>  imageInfos;
+  std::vector<vk::DescriptorBufferInfo> bufferInfos;
+  std::vector<vk::WriteDescriptorSet>   descriptorWrites;
+
+  // Deferred uniform buffer bindings:
+  for(auto& uniformBinding : mDeferredUniformBindings)
+  {
+    bufferInfos.emplace_back();
+    bufferInfos.back()
+      .setOffset(uniformBinding.offset)
+      .setRange(uniformBinding.range)
+      .setBuffer(uniformBinding.buffer);
+
+    descriptorWrites.emplace_back();
+    descriptorWrites.back()
+      .setPBufferInfo(&bufferInfos.back())
+      .setDescriptorType(vk::DescriptorType::eUniformBuffer)
+      .setDescriptorCount(1)
+      .setDstSet(descriptorSet)
+      .setDstBinding(uniformBinding.binding)
+      .setDstArrayElement(0);
+  }
+
+  auto& reflection = mCurrentProgram->GetReflection();
+  auto& samplers   = reflection.GetSamplers();
+
+  // Deferred texture bindings:
+  uint32_t binding = 1;
+  for(auto& textureBinding : mDeferredTextureBindings)
+  {
+    imageInfos.emplace_back();
+    imageInfos.back()
+      .setImageLayout(vk::ImageLayout::eShaderReadOnlyOptimal)
+      .setImageView(textureBinding.imageView)
+      .setSampler(textureBinding.sampler);
+
+    descriptorWrites.emplace_back();
+    for(auto& info : samplers)
+    {
+      if(info.location == textureBinding.binding)
+      {
+        binding = info.binding;
+        break;
+      }
+    }
+
+    descriptorWrites.back()
+      .setPImageInfo(&imageInfos.back())
+      .setDescriptorType(vk::DescriptorType::eCombinedImageSampler)
+      .setDescriptorCount(1)
+      .setDstSet(descriptorSet)
+      .setDstBinding(binding)
+      .setDstArrayElement(0);
+  }
+  mGraphicsDevice->GetLogicalDevice().updateDescriptorSets(uint32_t(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr);
+
+  auto pipelineLayout = reflection.GetVkPipelineLayout();
+
+  mCommandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics,
+                                    pipelineLayout,
+                                    0,
+                                    1,
+                                    &descriptorSet, // @note - old impl could use multiple sets (possibly)
+                                    0,
+                                    nullptr);
+  mDeferredTextureBindings.clear();
+  mDeferredUniformBindings.clear();
 }
 
 } // namespace Vulkan
index 6f9cda2f873113eb56daf4b7e9a7c7ea994aaac4..73c0323abf14664250948c2a5a7aabe3a91e0622 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali/graphics-api/graphics-types.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-buffer-impl.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-image-impl.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-program-impl.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-types.h>
 
 namespace Dali::Graphics::Vulkan
@@ -31,7 +32,7 @@ class Device;
 class CommandPool;
 class PipelineImpl;
 
-class CommandBufferImpl : public VkManaged
+class CommandBufferImpl
 {
   friend class CommandPool;
 
@@ -40,7 +41,9 @@ class CommandBufferImpl : public VkManaged
 public:
   CommandBufferImpl() = delete;
 
-  ~CommandBufferImpl() override;
+  ~CommandBufferImpl();
+
+  void Destroy();
 
   /** Begin recording */
   void Begin(vk::CommandBufferUsageFlags usageFlags, vk::CommandBufferInheritanceInfo* inheritanceInfo);
@@ -60,6 +63,15 @@ public:
   /** Final validation of the pipeline */
   void ValidatePipeline();
 
+  void BindVertexBuffers(
+    uint32_t                                firstBinding,
+    const std::vector<Vulkan::BufferImpl*>& buffers,
+    const std::vector<uint32_t>&            offsets);
+  void BindIndexBuffer(Vulkan::BufferImpl& buffer, uint32_t offset, Format format);
+  void BindUniformBuffers(const std::vector<UniformBufferBinding>& bindings);
+  void BindTextures(const std::vector<TextureBinding>& textureBindings);
+  void BindSamplers(const std::vector<SamplerBinding>& samplerBindings);
+
   /** Returns Vulkan object associated with the buffer */
   [[nodiscard]] vk::CommandBuffer GetVkHandle() const;
 
@@ -68,7 +80,6 @@ public:
    * @return Returns true if the command buffer is primary
    */
   [[nodiscard]] bool IsPrimary() const;
-
   /**
    * Allows to issue custom VkRenderPassBeginInfo structure
    * @param renderPassBeginInfo
@@ -92,11 +103,8 @@ public:
 
   void CopyImage(Vulkan::Image* srcImage, vk::ImageLayout srcLayout, Image* dstImage, vk::ImageLayout dstLayout, const std::vector<vk::ImageCopy>& regions);
 
-  /**
-   * Implements VkManaged::OnDestroy
-   * @return
-   */
-  bool OnDestroy() override;
+  void SetScissor(Rect2D value);
+  void SetViewport(Viewport value);
 
   void Draw(
     uint32_t vertexCount,
@@ -112,12 +120,12 @@ public:
     uint32_t firstInstance);
 
   void DrawIndexedIndirect(
-    Graphics::Buffer& buffer,
-    uint32_t          offset,
-    uint32_t          drawCount,
-    uint32_t          stride);
+    BufferImpl& buffer,
+    uint32_t    offset,
+    uint32_t    drawCount,
+    uint32_t    stride);
 
-  void ExecuteCommandBuffers(std::vector<const Graphics::CommandBuffer*>&& commandBuffers);
+  void ExecuteCommandBuffers(std::vector<vk::CommandBuffer>& commandBuffers);
 
 private:
   /**
@@ -126,6 +134,11 @@ private:
    */
   [[nodiscard]] uint32_t GetPoolAllocationIndex() const;
 
+  /**
+   * Bind all deferred resources before drawing
+   */
+  void BindResources(vk::DescriptorSet set);
+
 private:
   // Constructor called by the CommandPool only
   CommandBufferImpl(
@@ -134,14 +147,33 @@ private:
     const vk::CommandBufferAllocateInfo& allocateInfo,
     vk::CommandBuffer                    vulkanHandle);
 
+private: // Struct for deferring texture binding
+  struct DeferredTextureBinding
+  {
+    vk::ImageView imageView;
+    vk::Sampler   sampler;
+    uint32_t      binding;
+  };
+  struct DeferredUniformBinding
+  {
+    vk::Buffer buffer;
+    uint32_t   offset;
+    uint32_t   range;
+    uint32_t   binding;
+  };
+
 private:
-  CommandPool*                  mOwnerCommandPool;
-  Device*                       mGraphicsDevice;
-  uint32_t                      mPoolAllocationIndex;
-  vk::CommandBufferAllocateInfo mAllocateInfo{};
+  CommandPool*                        mOwnerCommandPool;
+  Device*                             mGraphicsDevice;
+  uint32_t                            mPoolAllocationIndex;
+  vk::CommandBufferAllocateInfo       mAllocateInfo{};
+  std::vector<DeferredTextureBinding> mDeferredTextureBindings;
+  std::vector<DeferredUniformBinding> mDeferredUniformBindings;
 
   vk::CommandBuffer mCommandBuffer{};
 
+  Vulkan::ProgramImpl* mCurrentProgram{nullptr}; /// To test descriptor sets, will collide with other work
+
   bool mRecording{false};
 };
 
index 89043db2afb1745a68dd3f08261aa6214fbcfaff..922bb391ad372ab9ab606d09d19e3d871e7dcb13 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
+// CLASS HEADER
 #include <dali/internal/graphics/vulkan-impl/vulkan-command-buffer.h>
+
+// INTERNAL HEADERS
+#include <dali/internal/graphics/vulkan-impl/vulkan-buffer-impl.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-buffer.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-command-buffer-impl.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-command-pool-impl.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-framebuffer-impl.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-graphics-controller.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-program-impl.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-render-pass-impl.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-render-pass.h>
 #include <dali/internal/graphics/vulkan/vulkan-device.h>
+
+#include <dali/integration-api/debug.h>
 #include <dali/internal/window-system/common/window-render-surface.h>
 
-#include <dali/internal/graphics/vulkan-impl/vulkan-command-buffer-impl.h>
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogCmdBufferFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_VK_COMMAND_BUFFER");
+#endif
 
 namespace Dali::Graphics::Vulkan
 {
+template<typename VT, typename GT>
+VT* ConstGraphicsCast(const GT* object)
+{
+  return const_cast<VT*>(static_cast<const VT*>(object));
+}
+
 CommandBuffer::CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, VulkanGraphicsController& controller)
 : CommandBufferResource(createInfo, controller),
   mCommandBufferImpl(nullptr)
@@ -45,6 +61,9 @@ CommandBuffer::~CommandBuffer() = default;
 
 void CommandBuffer::DestroyResource()
 {
+  // Don't delete the impl, it's pool allocated and should have been
+  // returned to the command pool for re-use.
+  mCommandBufferImpl = nullptr;
 }
 
 bool CommandBuffer::InitializeResource()
@@ -54,13 +73,41 @@ bool CommandBuffer::InitializeResource()
 
 void CommandBuffer::DiscardResource()
 {
+  mController.DiscardResource(this);
 }
 
 void CommandBuffer::Begin(const Graphics::CommandBufferBeginInfo& info)
 {
   if(mCommandBufferImpl)
   {
-    mCommandBufferImpl->Begin(static_cast<vk::CommandBufferUsageFlags>(info.usage), nullptr);
+    // Check if there is some extra information about used resources
+    // if so then apply optimizations
+    if(info.resourceBindings)
+    {
+      // update programs with descriptor pools
+      for(auto& binding : *info.resourceBindings)
+      {
+        if(binding.type == ResourceType::PROGRAM)
+        {
+          auto programImpl = static_cast<Vulkan::Program*>(binding.programBinding->program)->GetImplementation();
+
+          // Pool index is returned and we may do something with it later (storing it per cmdbuf?)
+          [[maybe_unused]] auto poolIndex = programImpl->AddDescriptorPool(binding.programBinding->count, 3); // add new pool, limit pools to 3 per program
+        }
+      }
+    }
+
+    vk::CommandBufferInheritanceInfo inheritanceInfo{};
+    if(info.renderPass)
+    {
+      auto renderTarget                  = ConstGraphicsCast<Vulkan::RenderTarget, Graphics::RenderTarget>(info.renderTarget);
+      inheritanceInfo.renderPass         = renderTarget->GetRenderPass(info.renderPass)->GetVkHandle();
+      inheritanceInfo.subpass            = 0;
+      inheritanceInfo.framebuffer        = renderTarget->GetCurrentFramebufferImpl()->GetVkHandle();
+      inheritanceInfo.queryFlags         = static_cast<vk::QueryControlFlags>(0);
+      inheritanceInfo.pipelineStatistics = static_cast<vk::QueryPipelineStatisticFlags>(0);
+    }
+    mCommandBufferImpl->Begin(static_cast<vk::CommandBufferUsageFlags>(info.usage), &inheritanceInfo);
   }
 }
 
@@ -82,13 +129,30 @@ void CommandBuffer::Reset()
 }
 
 void CommandBuffer::BindVertexBuffers(uint32_t                                    firstBinding,
-                                      const std::vector<const Graphics::Buffer*>& buffers,
+                                      const std::vector<const Graphics::Buffer*>& gfxBuffers,
                                       const std::vector<uint32_t>&                offsets)
 {
+  std::vector<BufferImpl*> buffers;
+  buffers.reserve(gfxBuffers.size());
+  for(auto& gfxBuffer : gfxBuffers)
+  {
+    buffers.push_back(ConstGraphicsCast<Buffer, Graphics::Buffer>(gfxBuffer)->GetImpl());
+  }
+  mCommandBufferImpl->BindVertexBuffers(firstBinding, buffers, offsets);
+}
+
+void CommandBuffer::BindIndexBuffer(const Graphics::Buffer& gfxBuffer,
+                                    uint32_t                offset,
+                                    Format                  format)
+{
+  auto indexBuffer = ConstGraphicsCast<Buffer, Graphics::Buffer>(&gfxBuffer);
+  DALI_ASSERT_DEBUG(indexBuffer && indexBuffer->GetImpl());
+  mCommandBufferImpl->BindIndexBuffer(*indexBuffer->GetImpl(), offset, format);
 }
 
 void CommandBuffer::BindUniformBuffers(const std::vector<UniformBufferBinding>& bindings)
 {
+  mCommandBufferImpl->BindUniformBuffers(bindings);
 }
 
 void CommandBuffer::BindPipeline(const Graphics::Pipeline& pipeline)
@@ -98,10 +162,12 @@ void CommandBuffer::BindPipeline(const Graphics::Pipeline& pipeline)
 
 void CommandBuffer::BindTextures(const std::vector<TextureBinding>& textureBindings)
 {
+  mCommandBufferImpl->BindTextures(textureBindings);
 }
 
 void CommandBuffer::BindSamplers(const std::vector<SamplerBinding>& samplerBindings)
 {
+  mCommandBufferImpl->BindSamplers(samplerBindings);
 }
 
 void CommandBuffer::BindPushConstants(void*    data,
@@ -110,12 +176,6 @@ void CommandBuffer::BindPushConstants(void*    data,
 {
 }
 
-void CommandBuffer::BindIndexBuffer(const Graphics::Buffer& buffer,
-                                    uint32_t                offset,
-                                    Format                  format)
-{
-}
-
 void CommandBuffer::BeginRenderPass(Graphics::RenderPass*          gfxRenderPass,
                                     Graphics::RenderTarget*        gfxRenderTarget,
                                     Rect2D                         renderArea,
@@ -126,7 +186,7 @@ void CommandBuffer::BeginRenderPass(Graphics::RenderPass*          gfxRenderPass
   auto             surface      = renderTarget->GetSurface();
   auto&            device       = mController.GetGraphicsDevice();
   FramebufferImpl* framebuffer;
-  RenderPassImpl*  renderPassImpl;
+  RenderPassHandle renderPassImpl;
   if(surface)
   {
     auto window    = static_cast<Internal::Adaptor::WindowRenderSurface*>(surface);
@@ -134,13 +194,13 @@ void CommandBuffer::BeginRenderPass(Graphics::RenderPass*          gfxRenderPass
     auto swapchain = device.GetSwapchainForSurfaceId(surfaceId);
     mLastSwapchain = swapchain;
     framebuffer    = swapchain->GetCurrentFramebuffer();
-    renderPassImpl = framebuffer->GetRenderPass(renderPass);
+    renderPassImpl = framebuffer->GetImplFromRenderPass(renderPass);
   }
   else
   {
     auto coreFramebuffer = renderTarget->GetFramebuffer();
     framebuffer          = coreFramebuffer->GetImpl();
-    renderPassImpl       = framebuffer->GetRenderPass(renderPass);
+    renderPassImpl       = framebuffer->GetImplFromRenderPass(renderPass);
   }
 
   std::vector<vk::ClearValue> vkClearValues;
@@ -167,7 +227,7 @@ void CommandBuffer::BeginRenderPass(Graphics::RenderPass*          gfxRenderPass
                                         .setRenderArea({{0, 0}, {renderArea.width, renderArea.height}})
                                         .setPClearValues(vkClearValues.data())
                                         .setClearValueCount(uint32_t(framebuffer->GetClearValues().size())),
-                                      vk::SubpassContents::eInline);
+                                      vk::SubpassContents::eSecondaryCommandBuffers);
 }
 
 void CommandBuffer::EndRenderPass(Graphics::SyncObject* syncObject)
@@ -175,8 +235,15 @@ void CommandBuffer::EndRenderPass(Graphics::SyncObject* syncObject)
   mCommandBufferImpl->EndRenderPass();
 }
 
-void CommandBuffer::ExecuteCommandBuffers(std::vector<const Graphics::CommandBuffer*>&& commandBuffers)
+void CommandBuffer::ExecuteCommandBuffers(std::vector<const Graphics::CommandBuffer*>&& gfxCommandBuffers)
 {
+  std::vector<vk::CommandBuffer> vkCommandBuffers;
+  vkCommandBuffers.reserve(gfxCommandBuffers.size());
+  for(auto& gfxCmdBuf : gfxCommandBuffers)
+  {
+    vkCommandBuffers.push_back(ConstGraphicsCast<CommandBuffer, Graphics::CommandBuffer>(gfxCmdBuf)->GetImpl()->GetVkHandle());
+  }
+  mCommandBufferImpl->ExecuteCommandBuffers(vkCommandBuffers);
 }
 
 void CommandBuffer::Draw(uint32_t vertexCount,
@@ -196,12 +263,14 @@ void CommandBuffer::DrawIndexed(uint32_t indexCount,
   mCommandBufferImpl->DrawIndexed(indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
 }
 
-void CommandBuffer::DrawIndexedIndirect(Graphics::Buffer& buffer,
+void CommandBuffer::DrawIndexedIndirect(Graphics::Buffer& gfxBuffer,
                                         uint32_t          offset,
                                         uint32_t          drawCount,
                                         uint32_t          stride)
 {
-  mCommandBufferImpl->DrawIndexedIndirect(buffer, offset, drawCount, stride);
+  auto buffer = ConstGraphicsCast<Buffer, Graphics::Buffer>(&gfxBuffer)->GetImpl();
+
+  mCommandBufferImpl->DrawIndexedIndirect(*buffer, offset, drawCount, stride);
 }
 
 void CommandBuffer::DrawNative(const DrawNativeInfo* drawInfo)
@@ -210,18 +279,25 @@ void CommandBuffer::DrawNative(const DrawNativeInfo* drawInfo)
 
 void CommandBuffer::SetScissor(Rect2D value)
 {
+  // @todo Vulkan accepts array of scissors... add to API
+  mCommandBufferImpl->SetScissor(value);
 }
 
 void CommandBuffer::SetScissorTestEnable(bool value)
 {
+  // Enabled by default. What does disabling test do?!
+  // Probably should force pipeline to not use dynamic scissor state
 }
 
 void CommandBuffer::SetViewport(Viewport value)
 {
+  mCommandBufferImpl->SetViewport(value);
 }
 
 void CommandBuffer::SetViewportEnable(bool value)
 {
+  // Enabled by default. What does disabling test do?!
+  // Probably should force pipeline to not use dynamic viewport state
 }
 
 void CommandBuffer::SetColorMask(bool enabled)
index 5bad086886548728a064dd151ec85635b156cfa6..fe6f42510035fb745abccf68d11116e8a6840cf8 100644 (file)
@@ -33,22 +33,6 @@ class CommandBuffer : public CommandBufferResource
 public:
   CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, VulkanGraphicsController& controller);
   ~CommandBuffer() override;
-  /**
-   * @brief Called when GL resources are destroyed
-   */
-  void DestroyResource() override;
-
-  /**
-   * @brief Called when initializing the resource
-   *
-   * @return True on success
-   */
-  bool InitializeResource() override;
-
-  /**
-   * @brief Called when UniquePtr<> on client-side dies
-   */
-  void DiscardResource() override;
 
   void Begin(const Graphics::CommandBufferBeginInfo& info) override;
 
@@ -338,7 +322,42 @@ public:
    */
   void SetDepthWriteEnable(bool depthWriteEnable) override;
 
-public: //API
+public: // VulkanResource API
+  /**
+   * @brief Called when GL resources are destroyed
+   */
+  void DestroyResource() override;
+
+  /**
+   * @brief Called when initializing the resource
+   *
+   * @return True on success
+   */
+  bool InitializeResource() override;
+
+  /**
+   * @brief Called when UniquePtr<> on client-side dies
+   */
+  void DiscardResource() override;
+
+  /**
+   * @copydoc Graphics::Vulkan::Resource::GetAllocationCallbacks()
+   */
+  [[nodiscard]] const Graphics::AllocationCallbacks* GetAllocationCallbacks() const override
+  {
+    return mCreateInfo.allocationCallbacks;
+  }
+
+  /**
+   * @copydoc Graphics::Vulkan::Resource::InvokeDeleter()
+   * Only intended for use by discard queue.
+   */
+  void InvokeDeleter() override
+  {
+    this->~CommandBuffer();
+  }
+
+public: // API
   /**
    * Get the last swapchain referenced by a BeginRenderPass command in this command buffer.
    *
index ddc6d04b1be3c29b46800234b4cbea3993e27fdf..8bc279e16a0f5721d427ef1673cff9917e60fa3b 100644 (file)
@@ -19,8 +19,8 @@
 #include <dali/internal/graphics/vulkan-impl/vulkan-command-pool-impl.h>
 
 // INTERNAL INCLUDES
-#include <dali/internal/graphics/vulkan/vulkan-device.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-command-buffer-impl.h>
+#include <dali/internal/graphics/vulkan/vulkan-device.h>
 
 #include <dali/integration-api/debug.h>
 
@@ -34,47 +34,46 @@ namespace Dali::Graphics::Vulkan
  *
  * Struct: InternalPool
  */
-CommandPool::InternalPool::Node::Node( uint32_t _nextFreeIndex, CommandBufferImpl* _commandBuffer )
-: nextFreeIndex( _nextFreeIndex ),
-  commandBuffer( _commandBuffer )
+CommandPool::InternalPool::Node::Node(uint32_t _nextFreeIndex, CommandBufferImpl* _commandBuffer)
+: nextFreeIndex(_nextFreeIndex),
+  commandBuffer(_commandBuffer)
 {
 }
 
-CommandPool::InternalPool::InternalPool( CommandPool& owner, Vulkan::Device* graphics,
-                                         uint32_t initialCapacity, bool isPrimary )
-: mOwner( owner ),
-  mGraphicsDevice( graphics ),
+CommandPool::InternalPool::InternalPool(CommandPool& owner, Vulkan::Device* graphics, uint32_t initialCapacity, bool isPrimary)
+: mOwner(owner),
+  mGraphicsDevice(graphics),
   mPoolData{},
-  mFirstFree( INVALID_NODE_INDEX ),
-  mCapacity( initialCapacity ),
-  mAllocationCount( 0u ),
-  mIsPrimary( isPrimary )
+  mFirstFree(INVALID_NODE_INDEX),
+  mCapacity(initialCapacity),
+  mAllocationCount(0u),
+  mIsPrimary(isPrimary)
 {
   // don't allocate anything if initial capacity is 0
-  if( initialCapacity )
+  if(initialCapacity)
   {
-    Resize( initialCapacity );
+    Resize(initialCapacity);
   }
 }
 
 CommandPool::InternalPool::~InternalPool()
 {
   // free all buffers here
-  for( auto&& cmd : mPoolData )
+  for(auto&& cmd : mPoolData)
   {
     delete cmd.commandBuffer;
   }
 }
 
-std::vector< vk::CommandBuffer >
-CommandPool::InternalPool::AllocateVkCommandBuffers( vk::CommandBufferAllocateInfo allocateInfo )
+std::vector<vk::CommandBuffer>
+CommandPool::InternalPool::AllocateVkCommandBuffers(vk::CommandBufferAllocateInfo allocateInfo)
 {
-  return VkAssert( mGraphicsDevice->GetLogicalDevice().allocateCommandBuffers( allocateInfo ) );
+  return VkAssert(mGraphicsDevice->GetLogicalDevice().allocateCommandBuffers(allocateInfo));
 }
 
-void CommandPool::InternalPool::Resize( uint32_t newCapacity )
+void CommandPool::InternalPool::Resize(uint32_t newCapacity)
 {
-  if( newCapacity <= mPoolData.size() )
+  if(newCapacity <= mPoolData.size())
   {
     return;
   }
@@ -82,42 +81,42 @@ void CommandPool::InternalPool::Resize( uint32_t newCapacity )
   auto diff = newCapacity - mPoolData.size();
 
   auto allocateInfo = vk::CommandBufferAllocateInfo{}
-          .setCommandBufferCount( U32( diff ) )
-          .setCommandPool( mOwner.GetVkHandle() )
-          .setLevel( mIsPrimary ? vk::CommandBufferLevel::ePrimary : vk::CommandBufferLevel::eSecondary );
-  auto newBuffers = AllocateVkCommandBuffers( allocateInfo );
+                        .setCommandBufferCount(U32(diff))
+                        .setCommandPool(mOwner.GetVkHandle())
+                        .setLevel(mIsPrimary ? vk::CommandBufferLevel::ePrimary : vk::CommandBufferLevel::eSecondary);
+  auto newBuffers = AllocateVkCommandBuffers(allocateInfo);
 
-  uint32_t i = U32( mPoolData.size() + 1 );
+  uint32_t i = U32(mPoolData.size() + 1);
 
-  mFirstFree = U32( mPoolData.size() );
-  if( !mPoolData.empty() )
+  mFirstFree = U32(mPoolData.size());
+  if(!mPoolData.empty())
   {
     mPoolData.back()
-             .nextFreeIndex = U32( mPoolData.size() );
+      .nextFreeIndex = U32(mPoolData.size());
   }
-  for( auto&& cmdbuf : newBuffers )
+  for(auto&& cmdbuf : newBuffers)
   {
-    auto commandBuffer = new CommandBufferImpl( mOwner, i - 1, allocateInfo, cmdbuf );
-    mPoolData.emplace_back( i, commandBuffer );
+    auto commandBuffer = new CommandBufferImpl(mOwner, i - 1, allocateInfo, cmdbuf);
+    mPoolData.emplace_back(i, commandBuffer);
     ++i;
   }
   mPoolData.back().nextFreeIndex = INVALID_NODE_INDEX;
-  mCapacity = U32( mPoolData.size() );
+  mCapacity                      = U32(mPoolData.size());
 }
 
-CommandBufferImpl* CommandPool::InternalPool::AllocateCommandBuffer( bool reset )
+CommandBufferImpl* CommandPool::InternalPool::AllocateCommandBuffer(bool reset)
 {
   // resize if no more nodes
-  if( mFirstFree == INVALID_NODE_INDEX )
+  if(mFirstFree == INVALID_NODE_INDEX)
   {
     auto newSize = static_cast<uint32_t>(mPoolData.empty() ? 1 : 2 * mPoolData.size());
-    Resize( U32( newSize ) );
+    Resize(U32(newSize));
   }
 
   auto& node = mPoolData[mFirstFree];
   mFirstFree = node.nextFreeIndex;
 
-  if( reset )
+  if(reset)
   {
     node.commandBuffer->Reset();
   }
@@ -126,13 +125,13 @@ CommandBufferImpl* CommandPool::InternalPool::AllocateCommandBuffer( bool reset
   return node.commandBuffer;
 }
 
-void CommandPool::InternalPool::ReleaseCommandBuffer(CommandBufferImpl& buffer, bool reset )
+void CommandPool::InternalPool::ReleaseCommandBuffer(CommandBufferImpl& buffer, bool reset)
 {
-  auto indexInPool = buffer.GetPoolAllocationIndex();
+  auto indexInPool                     = buffer.GetPoolAllocationIndex();
   mPoolData[indexInPool].nextFreeIndex = mFirstFree;
-  mFirstFree = indexInPool;
+  mFirstFree                           = indexInPool;
 
-  if( reset )
+  if(reset)
   {
     buffer.Reset();
   }
@@ -149,9 +148,9 @@ uint32_t CommandPool::InternalPool::GetAllocationCount() const
   return mAllocationCount;
 }
 
-CommandPool* CommandPool::New( Device& graphics, const vk::CommandPoolCreateInfo& createInfo )
+CommandPool* CommandPool::New(Device& graphics, const vk::CommandPoolCreateInfo& createInfo)
 {
-  auto pool = new CommandPool( graphics, createInfo );
+  auto pool = new CommandPool(graphics, createInfo);
 
   if(pool)
   {
@@ -161,27 +160,30 @@ CommandPool* CommandPool::New( Device& graphics, const vk::CommandPoolCreateInfo
   return pool;
 }
 
-CommandPool* CommandPool::New( Device& graphics )
+CommandPool* CommandPool::New(Device& graphics)
 {
-  return New( graphics, vk::CommandPoolCreateInfo{} );
+  return New(graphics, vk::CommandPoolCreateInfo{});
 }
 
 bool CommandPool::Initialize()
 {
-  mCreateInfo.setFlags( vk::CommandPoolCreateFlagBits::eResetCommandBuffer );
-  mCommandPool = VkAssert( mGraphicsDevice->GetLogicalDevice().createCommandPool( mCreateInfo, mGraphicsDevice->GetAllocator() ) );
-  mInternalPoolPrimary = std::make_unique< InternalPool >( *this, mGraphicsDevice, 0, true );
-  mInternalPoolSecondary = std::make_unique< InternalPool >( *this, mGraphicsDevice, 0, false );
+  mCreateInfo.setFlags(vk::CommandPoolCreateFlagBits::eResetCommandBuffer);
+  mCommandPool           = VkAssert(mGraphicsDevice->GetLogicalDevice().createCommandPool(mCreateInfo, mGraphicsDevice->GetAllocator()));
+  mInternalPoolPrimary   = std::make_unique<InternalPool>(*this, mGraphicsDevice, 0, true);
+  mInternalPoolSecondary = std::make_unique<InternalPool>(*this, mGraphicsDevice, 0, false);
   return true;
 }
 
-CommandPool::CommandPool( Device& graphics, const vk::CommandPoolCreateInfo& createInfo )
-: mGraphicsDevice( &graphics ),
-  mCreateInfo( createInfo )
+CommandPool::CommandPool(Device& graphics, const vk::CommandPoolCreateInfo& createInfo)
+: mGraphicsDevice(&graphics),
+  mCreateInfo(createInfo)
 {
 }
 
-CommandPool::~CommandPool() = default;
+CommandPool::~CommandPool()
+{
+  Destroy();
+}
 
 vk::CommandPool CommandPool::GetVkHandle() const
 {
@@ -193,34 +195,34 @@ Device& CommandPool::GetGraphicsDevice() const
   return *mGraphicsDevice;
 }
 
-CommandBufferImpl* CommandPool::NewCommandBuffer( const vk::CommandBufferAllocateInfo& allocateInfo )
+CommandBufferImpl* CommandPool::NewCommandBuffer(const vk::CommandBufferAllocateInfo& allocateInfo)
 {
-  return NewCommandBuffer( allocateInfo.level == vk::CommandBufferLevel::ePrimary );
+  return NewCommandBuffer(allocateInfo.level == vk::CommandBufferLevel::ePrimary);
 }
 
-CommandBufferImpl* CommandPool::NewCommandBuffer( bool isPrimary )
+CommandBufferImpl* CommandPool::NewCommandBuffer(bool isPrimary)
 {
   auto& usedPool = isPrimary ? *mInternalPoolPrimary : *mInternalPoolSecondary;
-  return usedPool.AllocateCommandBuffer( false );
+  return usedPool.AllocateCommandBuffer(false);
 }
 
-void CommandPool::Reset( bool releaseResources )
+void CommandPool::Reset(bool releaseResources)
 {
   mGraphicsDevice->GetLogicalDevice()
-           .resetCommandPool( mCommandPool,
-                              releaseResources ? vk::CommandPoolResetFlagBits::eReleaseResources
-                                               : vk::CommandPoolResetFlags{} );
+    .resetCommandPool(mCommandPool,
+                      releaseResources ? vk::CommandPoolResetFlagBits::eReleaseResources
+                                       : vk::CommandPoolResetFlags{});
 }
 
-bool CommandPool::ReleaseCommandBuffer(CommandBufferImpl& buffer )
+bool CommandPool::ReleaseCommandBuffer(CommandBufferImpl& buffer)
 {
-  if( buffer.IsPrimary() )
+  if(buffer.IsPrimary() && mInternalPoolPrimary)
   {
-    mInternalPoolPrimary->ReleaseCommandBuffer( buffer );
+    mInternalPoolPrimary->ReleaseCommandBuffer(buffer);
   }
-  else
+  else if(mInternalPoolSecondary)
   {
-    mInternalPoolSecondary->ReleaseCommandBuffer( buffer );
+    mInternalPoolSecondary->ReleaseCommandBuffer(buffer);
   }
   return false;
 }
@@ -237,26 +239,23 @@ uint32_t CommandPool::GetAllocationCount() const
          mInternalPoolSecondary->GetAllocationCount();
 }
 
-uint32_t CommandPool::GetAllocationCount( vk::CommandBufferLevel level ) const
+uint32_t CommandPool::GetAllocationCount(vk::CommandBufferLevel level) const
 {
-  return level == vk::CommandBufferLevel::ePrimary ?
-         mInternalPoolPrimary->GetAllocationCount() :
-         mInternalPoolSecondary->GetAllocationCount();
+  return level == vk::CommandBufferLevel::ePrimary ? mInternalPoolPrimary->GetAllocationCount() : mInternalPoolSecondary->GetAllocationCount();
 }
 
-bool CommandPool::OnDestroy()
+void CommandPool::Destroy()
 {
-  auto device = mGraphicsDevice->GetLogicalDevice();
-  auto commandPool = mCommandPool;
+  auto device    = mGraphicsDevice->GetLogicalDevice();
   auto allocator = &mGraphicsDevice->GetAllocator();
 
-  mGraphicsDevice->DiscardResource( [ device, commandPool, allocator ]() {
-    DALI_LOG_INFO( gVulkanFilter, Debug::General, "Invoking deleter function: command pool->%p\n",
-                   static_cast< VkCommandPool >( commandPool ) )
-    device.destroyCommandPool( commandPool, allocator );
-  } );
+  if(mCommandPool)
+  {
+    DALI_LOG_INFO(gVulkanFilter, Debug::General, "Destroying command pool: %p\n", static_cast<VkCommandPool>(mCommandPool));
+    device.destroyCommandPool(mCommandPool, allocator);
 
-  return false;
+    mCommandPool = nullptr;
+  }
 }
 
 } // namespace Dali::Graphics::Vulkan
index 497991e7e0966881a48d619145068dacc5e1982a..dcf17b598824e222e007858435d05df1f645f45e 100644 (file)
@@ -24,7 +24,7 @@ namespace Dali::Graphics::Vulkan
 class Device;
 class CommandBufferImpl;
 
-class CommandPool : public VkManaged
+class CommandPool
 {
 public: // Construction, destruction
   /**
@@ -46,7 +46,7 @@ public: // Construction, destruction
 
   CommandPool(Device& graphicsDevice, const vk::CommandPoolCreateInfo& createInfo);
 
-  ~CommandPool() override;
+  ~CommandPool();
 
   vk::CommandPool GetVkHandle() const;
 
@@ -54,7 +54,7 @@ public: // Construction, destruction
 
   bool Initialize();
 
-  bool OnDestroy() override; // TODO: Queue deleter for destruction
+  void Destroy();
 
   /**
    * Resets command pool
index 38c15ef5557bead8e3e76565d14c0a2131b0a329..a65735fe0f1d01fcc88d1e92dc4de6c1655c2227 100644 (file)
@@ -27,10 +27,9 @@ extern Debug::Filter* gVulkanFilter;
 
 namespace Dali::Graphics::Vulkan
 {
-
-FenceImpl* FenceImpl::New(Device& graphicsDevice, const vk::FenceCreateInfo& fenceCreateInfo)
+std::unique_ptr<FenceImpl> FenceImpl::New(Device& graphicsDevice, const vk::FenceCreateInfo& fenceCreateInfo)
 {
-  auto fence = new FenceImpl(graphicsDevice);
+  auto fence = std::unique_ptr<FenceImpl>(new FenceImpl(graphicsDevice));
   fence->Initialize(fenceCreateInfo);
   return fence;
 }
index 4866d4829af02d3defe150697475a0c02017dc65..fed81c6b1cdc3449bd2e460310bcd38c82a51858 100644 (file)
@@ -23,6 +23,7 @@
 
 // EXTERNAL INCLUDES
 #include <limits>
+#include <memory>
 
 namespace Dali::Graphics::Vulkan
 {
@@ -34,7 +35,7 @@ class Device;
 class FenceImpl
 {
 public:
-  static FenceImpl* New(Device& graphicsDevice, const vk::FenceCreateInfo& fenceCreateInfo);
+  static std::unique_ptr<FenceImpl> New(Device& graphicsDevice, const vk::FenceCreateInfo& fenceCreateInfo);
 
   FenceImpl(Device& graphicsDevice);
 
index 92f6c845ddc03947c472a97fdd40f0e3aeec6e57..4e5d556f5ee9fc68c65220c3b5ac31da47afb052 100644 (file)
@@ -32,9 +32,9 @@ extern Debug::Filter* gVulkanFilter;
 
 namespace Dali::Graphics::Vulkan
 {
-FramebufferAttachment* FramebufferAttachment::NewColorAttachment(ImageView*          imageView,
-                                                                 vk::ClearColorValue clearColorValue,
-                                                                 bool                presentable)
+FramebufferAttachment* FramebufferAttachment::NewColorAttachment(std::unique_ptr<ImageView>& imageView,
+                                                                 vk::ClearColorValue         clearColorValue,
+                                                                 bool                        presentable)
 {
   assert(imageView->GetImage()->GetUsageFlags() & vk::ImageUsageFlagBits::eColorAttachment);
 
@@ -46,8 +46,8 @@ FramebufferAttachment* FramebufferAttachment::NewColorAttachment(ImageView*
 }
 
 FramebufferAttachment* FramebufferAttachment::NewDepthAttachment(
-  ImageView*                 imageView,
-  vk::ClearDepthStencilValue clearDepthStencilValue)
+  std::unique_ptr<ImageView>& imageView,
+  vk::ClearDepthStencilValue  clearDepthStencilValue)
 {
   assert(imageView->GetImage()->GetUsageFlags() & vk::ImageUsageFlagBits::eDepthStencilAttachment);
 
@@ -59,15 +59,15 @@ FramebufferAttachment* FramebufferAttachment::NewDepthAttachment(
   return attachment;
 }
 
-FramebufferAttachment::FramebufferAttachment(ImageView*     imageView,
-                                             vk::ClearValue clearColor,
-                                             AttachmentType type,
-                                             bool           presentable)
-: mImageView(imageView),
-  mClearValue(clearColor),
+FramebufferAttachment::FramebufferAttachment(std::unique_ptr<ImageView>& imageView,
+                                             vk::ClearValue              clearColor,
+                                             AttachmentType              type,
+                                             bool                        presentable)
+: mClearValue(clearColor),
   mType(type)
 {
-  auto image = imageView->GetImage();
+  mImageView.swap(imageView);
+  auto image = mImageView->GetImage();
 
   auto sampleCountFlags = image->GetSampleCount();
 
@@ -92,7 +92,7 @@ FramebufferAttachment::FramebufferAttachment(ImageView*     imageView,
 
 ImageView* FramebufferAttachment::GetImageView() const
 {
-  return mImageView;
+  return mImageView.get();
 }
 
 const vk::AttachmentDescription& FramebufferAttachment::GetDescription() const
@@ -112,56 +112,61 @@ AttachmentType FramebufferAttachment::GetType() const
 
 bool FramebufferAttachment::IsValid() const
 {
-  return mImageView;
+  return mImageView != nullptr;
 }
 
 // FramebufferImpl -------------------------------
 
 FramebufferImpl* FramebufferImpl::New(
-  Vulkan::Device&                      device,
-  RenderPassImpl*                      renderPass,
-  std::vector<FramebufferAttachment*>& attachments,
-  uint32_t                             width,
-  uint32_t                             height,
-  bool                                 hasDepthAttachments)
+  Vulkan::Device&   device,
+  RenderPassHandle  renderPass,
+  OwnedAttachments& attachments,
+  uint32_t          width,
+  uint32_t          height,
+  bool              hasDepthAttachments)
 {
-  std::vector<vk::ImageView> imageViewAttachments;
-
-  DALI_ASSERT_ALWAYS(renderPass != nullptr && "You require more render passes!");
+  DALI_ASSERT_ALWAYS(renderPass && "You require more render passes!");
 
-  std::transform(attachments.cbegin(),
-                 attachments.cend(),
-                 std::back_inserter(imageViewAttachments),
-                 [&](FramebufferAttachment* entry) {
-                   return entry->GetImageView()->GetVkHandle();
-                 });
+  std::vector<vk::ImageView> imageViewAttachments;
+  for(auto& attachment : attachments)
+  {
+    imageViewAttachments.emplace_back(attachment->GetImageView()->GetVkHandle());
+  }
 
-  auto framebufferCreateInfo = vk::FramebufferCreateInfo{}.setRenderPass(renderPass->GetVkHandle()).setPAttachments(imageViewAttachments.data()).setLayers(1).setWidth(width).setHeight(height).setAttachmentCount(U32(attachments.size()));
+  auto framebufferCreateInfo = vk::FramebufferCreateInfo{}
+                                 .setRenderPass(renderPass->GetVkHandle())
+                                 .setPAttachments(imageViewAttachments.data())
+                                 .setLayers(1)
+                                 .setWidth(width)
+                                 .setHeight(height)
+                                 .setAttachmentCount(U32(attachments.size()));
 
   auto vkFramebuffer = VkAssert(device.GetLogicalDevice().createFramebuffer(framebufferCreateInfo, device.GetAllocator()));
 
   return new FramebufferImpl(device,
                              attachments,
                              vkFramebuffer,
-                             *renderPass,
+                             renderPass,
                              width,
                              height,
                              hasDepthAttachments);
 }
 
 FramebufferImpl* FramebufferImpl::New(
-  Vulkan::Device&                            device,
-  RenderPassImpl*                            renderPass,
-  const std::vector<FramebufferAttachment*>& colorAttachments,
-  FramebufferAttachment*                     depthAttachment,
-  uint32_t                                   width,
-  uint32_t                                   height)
+  Vulkan::Device&                         device,
+  RenderPassHandle                        renderPass,
+  OwnedAttachments&                       colorAttachments,
+  std::unique_ptr<FramebufferAttachment>& depthAttachment,
+  uint32_t                                width,
+  uint32_t                                height)
 {
   assert((!colorAttachments.empty() || depthAttachment) && "Cannot create framebuffer. Please provide at least one attachment");
 
-  auto colorAttachmentsValid = true;
+  auto                                colorAttachmentsValid = true;
+  std::vector<FramebufferAttachment*> attachments;
   for(auto& attachment : colorAttachments)
   {
+    attachments.emplace_back(attachment.get());
     if(!attachment->IsValid())
     {
       colorAttachmentsValid = false;
@@ -180,38 +185,54 @@ FramebufferImpl* FramebufferImpl::New(
   }
 
   // This vector stores the attachments (vk::ImageViews)
-  auto attachments = std::vector<FramebufferAttachment*>{};
 
   // Flag that indicates if the render pass is externally provided
-  if(renderPass == nullptr)
+  if(!renderPass)
   {
-    // Create compatible render pass
-    renderPass = RenderPassImpl::New(device, colorAttachments, depthAttachment);
+    // Create compatible vulkan render pass
+    renderPass = RenderPassImpl::New(device, attachments, depthAttachment.get());
   }
-  attachments.reserve(colorAttachments.size());
-  attachments.insert(attachments.begin(), colorAttachments.begin(), colorAttachments.end());
+
+  OwnedAttachments ownedAttachments(std::move(colorAttachments));
   if(hasDepth)
   {
-    attachments.push_back(depthAttachment);
+    ownedAttachments.emplace_back(std::move(depthAttachment));
   }
-  return FramebufferImpl::New(device, renderPass, attachments, width, height, hasDepth);
+  return FramebufferImpl::New(device, renderPass, ownedAttachments, width, height, hasDepth);
 }
 
-FramebufferImpl::FramebufferImpl(Device&                                    graphicsDevice,
-                                 const std::vector<FramebufferAttachment*>& attachments,
-                                 vk::Framebuffer                            vkHandle,
-                                 const RenderPassImpl&                      renderPassImpl,
-                                 uint32_t                                   width,
-                                 uint32_t                                   height,
-                                 bool                                       hasDepthAttachment)
+FramebufferImpl::FramebufferImpl(Device&           graphicsDevice,
+                                 OwnedAttachments& attachments,
+                                 vk::Framebuffer   vkHandle,
+                                 RenderPassHandle  renderPassImpl,
+                                 uint32_t          width,
+                                 uint32_t          height,
+                                 bool              hasDepthAttachment)
 : mGraphicsDevice(&graphicsDevice),
   mWidth(width),
   mHeight(height),
-  mAttachments(attachments),
+  mAttachments(std::move(attachments)),
   mFramebuffer(vkHandle),
   mHasDepthAttachment(hasDepthAttachment)
 {
-  mRenderPasses.push_back(RenderPassMapElement{nullptr, const_cast<RenderPassImpl*>(&renderPassImpl)});
+  mRenderPasses.emplace_back(RenderPassMapElement{nullptr, renderPassImpl});
+}
+
+void FramebufferImpl::Destroy()
+{
+  auto device = mGraphicsDevice->GetLogicalDevice();
+
+  mRenderPasses.clear();
+  mAttachments.clear();
+
+  if(mFramebuffer)
+  {
+    auto allocator = &mGraphicsDevice->GetAllocator();
+
+    DALI_LOG_INFO(gVulkanFilter, Debug::General, "Destroying Framebuffer: %p\n", static_cast<VkFramebuffer>(mFramebuffer));
+    device.destroyFramebuffer(mFramebuffer, allocator);
+  }
+  mFramebuffer = nullptr;
 }
 
 uint32_t FramebufferImpl::GetWidth() const
@@ -230,12 +251,14 @@ FramebufferAttachment* FramebufferImpl::GetAttachment(AttachmentType type, uint3
   {
     case AttachmentType::COLOR:
     {
-      return mAttachments[index];
+      return mAttachments[index].get();
     }
     case AttachmentType::DEPTH_STENCIL:
     {
       if(mHasDepthAttachment)
-        return mAttachments.back();
+      {
+        return mAttachments.back().get();
+      }
     }
     case AttachmentType::INPUT:
     case AttachmentType::RESOLVE:
@@ -256,7 +279,10 @@ std::vector<FramebufferAttachment*> FramebufferImpl::GetAttachments(AttachmentTy
     {
       auto numColorAttachments = mHasDepthAttachment ? mAttachments.size() - 1 : mAttachments.size();
       retval.reserve(numColorAttachments);
-      retval.insert(retval.end(), mAttachments.begin(), mAttachments.begin() + numColorAttachments);
+      for(size_t i = 0; i < numColorAttachments; ++i)
+      {
+        retval.emplace_back(mAttachments[i].get());
+      }
       break;
     }
     case AttachmentType::DEPTH_STENCIL:
@@ -264,7 +290,7 @@ std::vector<FramebufferAttachment*> FramebufferImpl::GetAttachments(AttachmentTy
       if(mHasDepthAttachment)
       {
         retval.reserve(1);
-        retval.push_back(mAttachments.back());
+        retval.emplace_back(mAttachments.back().get());
       }
       break;
     }
@@ -305,16 +331,16 @@ uint32_t FramebufferImpl::GetRenderPassCount() const
   return uint32_t(mRenderPasses.size());
 }
 
-RenderPassImpl* FramebufferImpl::GetRenderPass(uint32_t index) const
+RenderPassHandle FramebufferImpl::GetRenderPass(uint32_t index) const
 {
   if(index < mRenderPasses.size())
   {
     return mRenderPasses[index].renderPassImpl;
   }
-  return nullptr;
+  return RenderPassHandle{};
 }
 
-RenderPassImpl* FramebufferImpl::GetRenderPass(RenderPass* renderPass)
+RenderPassHandle FramebufferImpl::GetImplFromRenderPass(RenderPass* renderPass)
 {
   auto attachments  = renderPass->GetCreateInfo().attachments;
   auto matchLoadOp  = attachments->front().loadOp;
@@ -334,7 +360,7 @@ RenderPassImpl* FramebufferImpl::GetRenderPass(RenderPass* renderPass)
     }
     else
     {
-      DALI_ASSERT_DEBUG(element.renderPassImpl != nullptr && "Render pass list doesn't contain impl");
+      DALI_ASSERT_DEBUG(element.renderPassImpl && "Render pass list doesn't contain impl");
       auto createInfo = element.renderPassImpl->GetCreateInfo();
 
       if(createInfo.attachmentDescriptions[0].loadOp == VkLoadOpType(matchLoadOp).loadOp &&
@@ -348,7 +374,15 @@ RenderPassImpl* FramebufferImpl::GetRenderPass(RenderPass* renderPass)
   }
 
   // @todo create new render pass from existing + load/store op, add it to mRenderPasses, and return it.
-
+  // @todo Need to reconsider swapchain/fbo/renderpass creation model.
+  // This framebuffer may belong to a swapchain, in which case, there are multiple framebuffers
+  // that could share render passes.
+  // A) Need to detect this situation - keep owner info?
+  // B) Sharing render passes means we
+  //    1) need to ref-count to ensure safe ownership, or
+  //    2) move ownership of renderpass to swapchain.
+  //       Onus is on client to determine which interface to use, if it's a surface, use swapchain;
+  //       if it's an offscreen, use framebuffer. (Kinda need a core interface to wrap surface/offscreen)
   return mRenderPasses[0].renderPassImpl;
 }
 
@@ -361,39 +395,15 @@ std::vector<vk::ClearValue> FramebufferImpl::GetClearValues() const
 {
   auto result = std::vector<vk::ClearValue>{};
 
-  std::transform(mAttachments.begin(), // @todo & color clear enabled / depth clear enabled
-                 mAttachments.end(),
-                 std::back_inserter(result),
-                 [](FramebufferAttachment* attachment) {
-                   return attachment->GetClearValue();
-                 });
+  // @todo & color clear enabled / depth clear enabled
+  for(auto& attachment : mAttachments)
+  {
+    result.emplace_back(attachment->GetClearValue());
+  }
 
   return result;
 }
 
-bool FramebufferImpl::OnDestroy()
-{
-  auto device      = mGraphicsDevice->GetLogicalDevice();
-  auto frameBuffer = mFramebuffer;
-
-  ///@todo Destroy all render passes.
-  vk::RenderPass renderPass = mRenderPasses[0].renderPassImpl->GetVkHandle();
-
-  auto allocator = &mGraphicsDevice->GetAllocator();
-
-  mGraphicsDevice->DiscardResource([device, frameBuffer, renderPass, allocator]() {
-                                     DALI_LOG_INFO(gVulkanFilter, Debug::General, "Invoking deleter function: framebuffer->%p\n", static_cast<VkFramebuffer>(frameBuffer))
-                                     device.destroyFramebuffer(frameBuffer, allocator);
-
-                                     if(renderPass)
-                                     {
-                                       DALI_LOG_INFO(gVulkanFilter, Debug::General, "Invoking deleter function: render pass->%p\n", static_cast<VkRenderPass>(renderPass))
-                                       device.destroyRenderPass(renderPass, allocator);
-                                     } });
-
-  return false;
-}
-
 } // namespace Dali::Graphics::Vulkan
 
 // Namespace Graphics
index defb3f4618049e2032d445b723271bd26aa832ca..16e4ea66b9e2cae50cfaba3a3014d6a19b63140e 100644 (file)
 
 #include <dali/internal/graphics/vulkan-impl/vulkan-types.h>
 
+#include <dali/internal/graphics/vulkan-impl/vulkan-image-view-impl.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-render-pass-impl.h>
+
 namespace Dali::Graphics::Vulkan
 {
 class RenderPass;
-class RenderPassImpl;
 
 enum class AttachmentType
 {
@@ -37,20 +39,41 @@ enum class AttachmentType
 
 class Device;
 
-class FramebufferAttachment : public VkManaged
+class FramebufferAttachment
 {
 public:
-  FramebufferAttachment(ImageView*     imageView,
-                        vk::ClearValue clearColor,
-                        AttachmentType type,
-                        bool           presentable);
+  /**
+   * Constructor
+   *
+   * @param[in] imageView The imageview of the attachment
+   * @param[in] clearColor The color used to clear this attachment during CLEAR_OP
+   * @param[in] type The attachment type (usually COLOR or DEPTH_STENCIL)
+   * @param[in] presentable Whether the attachment is presentable (changes final layout)
+   */
+  FramebufferAttachment(std::unique_ptr<ImageView>& imageView,
+                        vk::ClearValue              clearColor,
+                        AttachmentType              type,
+                        bool                        presentable);
 
-  static FramebufferAttachment* NewColorAttachment(ImageView*          imageView,
-                                                   vk::ClearColorValue clearColorValue,
-                                                   bool                presentable);
+  /**
+   * Creates a new color attachment.
+   *
+   * @param[in] imageView The imageview of the attachment
+   * @param[in] clearColorValue The color used to clear this attachment during CLEAR_OP
+   * @param[in] presentable Whether the attachment is presentable (changes final layout)
+   */
+  static FramebufferAttachment* NewColorAttachment(std::unique_ptr<ImageView>& imageView,
+                                                   vk::ClearColorValue         clearColorValue,
+                                                   bool                        presentable);
 
-  static FramebufferAttachment* NewDepthAttachment(ImageView*                 imageView,
-                                                   vk::ClearDepthStencilValue clearDepthStencilValue);
+  /**
+   * Creates a new depth attachment.
+   *
+   * @param[in] imageView The imageview of the attachment
+   * @param[in] clearDepthStencilValue The value used to clear this attachment during CLEAR_OP
+   */
+  static FramebufferAttachment* NewDepthAttachment(std::unique_ptr<ImageView>& imageView,
+                                                   vk::ClearDepthStencilValue  clearDepthStencilValue);
 
   [[nodiscard]] ImageView* GetImageView() const;
 
@@ -65,44 +88,84 @@ public:
 private:
   FramebufferAttachment() = default;
 
-  ImageView*                mImageView{nullptr};
-  vk::AttachmentDescription mDescription;
-  vk::ClearValue            mClearValue;
-  AttachmentType            mType{AttachmentType::UNDEFINED};
+  std::unique_ptr<ImageView> mImageView;
+  vk::AttachmentDescription  mDescription;
+  vk::ClearValue             mClearValue;
+  AttachmentType             mType{AttachmentType::UNDEFINED};
 };
 
+using OwnedAttachments = std::vector<std::unique_ptr<FramebufferAttachment>>;
+
 /**
  * FramebufferImpl encapsulates following objects:
  * - Images ( attachments )
  * - FramebufferImpl
  * - ImageViews
+ * - RenderPasses
  */
-class FramebufferImpl : public VkManaged
+class FramebufferImpl
 {
 public:
+  /**
+   * @brief Create a new Framebuffer
+   *
+   * @param[in] device The vulkan device
+   * @param[in] renderPass A shared handle to a compatible render pass.
+   * @param[in] attachments The attachments. Framebuffer takes ownership of these
+   * @param[in] width Width of the framebuffer
+   * @param[in] height Height of the framebuffer
+   * @param[in] hasDepthAttachment True if the last attachment is a depth buffer
+   *
+   * @return A new framebuffer object
+   */
   static FramebufferImpl* New(
-    Vulkan::Device&                      device,
-    RenderPassImpl*                      renderPass,
-    std::vector<FramebufferAttachment*>& attachments,
-    uint32_t                             width,
-    uint32_t                             height,
-    bool                                 hasDepthAttachment);
+    Vulkan::Device&   device,
+    RenderPassHandle  renderPass,
+    OwnedAttachments& attachments,
+    uint32_t          width,
+    uint32_t          height,
+    bool              hasDepthAttachment);
 
+  /**
+   * @brief Create a new Framebuffer
+   *
+   * @param[in] device The vulkan device
+   * @param[in] renderPass A shared handle to a compatible render pass.
+   * @param[in] attachments The attachments. Framebuffer takes ownership of these
+   * @param[in] width Width of the framebuffer
+   * @param[in] height Height of the framebuffer
+   * @param[in] hasDepthAttachment True if the last attachment is a depth buffer
+   *
+   * @return A new framebuffer object
+   */
   static FramebufferImpl* New(
-    Vulkan::Device&                            device,
-    RenderPassImpl*                            renderPass,
-    const std::vector<FramebufferAttachment*>& colorAttachments,
-    FramebufferAttachment*                     depthAttachment,
-    uint32_t                                   width,
-    uint32_t                                   height);
-
-  FramebufferImpl(Device&                                    graphicsDevice,
-                  const std::vector<FramebufferAttachment*>& attachments,
-                  vk::Framebuffer                            vkHandle,
-                  const RenderPassImpl&                      renderPass,
-                  uint32_t                                   width,
-                  uint32_t                                   height,
-                  bool                                       hasDepthAttachment);
+    Vulkan::Device&                         device,
+    RenderPassHandle                        renderPass,
+    OwnedAttachments&                       colorAttachments,
+    std::unique_ptr<FramebufferAttachment>& depthAttachment,
+    uint32_t                                width,
+    uint32_t                                height);
+
+  /**
+   * @brief Constructor
+   *
+   * @param[in] graphicsDevice The vulkan device
+   * @param[in] attachments The attachments - framebuffer takes ownership
+   * @param[in] vkHandle a handle to a created framebuffer
+   * @param[in] renderPass a handle to a compatible render pass
+   * @param[in] width Width of the framebuffer
+   * @param[in] height Height of the framebuffer
+   * @param[in] hasDepthAttachment True if the last attachment is a depth buffer
+   */
+  FramebufferImpl(Device&           graphicsDevice,
+                  OwnedAttachments& attachments,
+                  vk::Framebuffer   vkHandle,
+                  RenderPassHandle  renderPass,
+                  uint32_t          width,
+                  uint32_t          height,
+                  bool              hasDepthAttachment);
+
+  void Destroy();
 
   [[nodiscard]] uint32_t GetWidth() const;
 
@@ -114,9 +177,9 @@ public:
 
   [[nodiscard]] uint32_t GetAttachmentCount(AttachmentType type) const;
 
-  [[nodiscard]] RenderPassImpl* GetRenderPass(RenderPass* renderPass); // May mutate mRenderPasses
+  [[nodiscard]] RenderPassHandle GetImplFromRenderPass(RenderPass* renderPass); // May mutate mRenderPasses
 
-  [[nodiscard]] RenderPassImpl* GetRenderPass(uint32_t index) const;
+  [[nodiscard]] RenderPassHandle GetRenderPass(uint32_t index) const;
 
   [[nodiscard]] uint32_t GetRenderPassCount() const;
 
@@ -124,8 +187,6 @@ public:
 
   [[nodiscard]] std::vector<vk::ClearValue> GetClearValues() const;
 
-  bool OnDestroy() override;
-
 private:
   Device* mGraphicsDevice;
 
@@ -137,15 +198,15 @@ private:
    */
   struct RenderPassMapElement
   {
-    RenderPass*     renderPass{nullptr};
-    RenderPassImpl* renderPassImpl{nullptr};
+    RenderPass*      renderPass{nullptr};
+    RenderPassHandle renderPassImpl{nullptr};
   };
   using RenderPasses = std::vector<RenderPassMapElement>;
 
-  std::vector<FramebufferAttachment*> mAttachments;
-  vk::Framebuffer                     mFramebuffer;
-  RenderPasses                        mRenderPasses;
-  bool                                mHasDepthAttachment{false};
+  OwnedAttachments mAttachments;
+  vk::Framebuffer  mFramebuffer;
+  RenderPasses     mRenderPasses;
+  bool             mHasDepthAttachment{false};
 };
 
 } // Namespace Dali::Graphics::Vulkan
index 70f1817a5e916f08b83aeba200471c12fb93caf0..7209950b877c0be61ca848e1d19746fac9ac5d5d 100644 (file)
 #include <dali/internal/graphics/vulkan-impl/vulkan-render-pass-impl.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-render-pass.h>
 
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
+namespace Dali::Graphics::Vulkan
 {
 Framebuffer::Framebuffer(const FramebufferCreateInfo& createInfo, VulkanGraphicsController& controller)
 : Resource(createInfo, controller),
@@ -39,25 +35,20 @@ Framebuffer::~Framebuffer() = default;
 bool Framebuffer::InitializeResource()
 {
   // Create attachments
-  std::vector<FramebufferAttachment*> colorAttachments;
+  OwnedAttachments colorAttachments;
   // for(auto& attachment : mCreateInfo.colorAttachments)
   {
     // auto graphicsTexture = static_cast<const Vulkan::Texture*>(attachment.texture);
     // colorAttachments.push_back(FramebufferAttachment::NewColorAttachment(attachment.texture->GetVkHandle(), clearColor, AttachmentType::COLOR, false);
   }
-  FramebufferAttachment* depthStencilAttachment{nullptr};
+  std::unique_ptr<FramebufferAttachment> depthStencilAttachment;
   if(mCreateInfo.depthStencilAttachment.depthTexture || mCreateInfo.depthStencilAttachment.stencilTexture)
   {
     // depthStencilAttachment = FramebufferAttachment::NewDepthAttachment();
   }
 
-  // Create initial render pass.
-  auto renderPassImpl = RenderPassImpl::New(mController.GetGraphicsDevice(),
-                                            colorAttachments,
-                                            depthStencilAttachment);
-
   auto& device     = mController.GetGraphicsDevice();
-  mFramebufferImpl = FramebufferImpl::New(device, renderPassImpl, colorAttachments, depthStencilAttachment, mCreateInfo.size.width, mCreateInfo.size.height);
+  mFramebufferImpl = FramebufferImpl::New(device, RenderPassHandle{}, colorAttachments, depthStencilAttachment, mCreateInfo.size.width, mCreateInfo.size.height);
 
   return true;
 }
@@ -70,6 +61,4 @@ void Framebuffer::DiscardResource()
 {
 }
 
-} // namespace Vulkan
-} // namespace Graphics
-} // namespace Dali
+} // namespace Dali::Graphics::Vulkan
index 11b86e5ea0ff0ab4bcd3ad8f8ed186c6a2156fdf..447422ad7eb8594a9ab39e3d9cfef7669cd5a312 100644 (file)
@@ -20,8 +20,8 @@
 
 #include <dali/internal/graphics/vulkan-impl/vulkan-graphics-resource.h>
 
-#include <dali/graphics-api/graphics-framebuffer.h>
 #include <dali/graphics-api/graphics-framebuffer-create-info.h>
+#include <dali/graphics-api/graphics-framebuffer.h>
 
 namespace Dali
 {
@@ -32,6 +32,7 @@ namespace Vulkan
 class FramebufferImpl;
 
 using FramebufferResource = Resource<Graphics::Framebuffer, Graphics::FramebufferCreateInfo>;
+
 class Framebuffer : public FramebufferResource
 {
 public:
@@ -40,7 +41,7 @@ public:
   ~Framebuffer() override;
 
   /**
-   * @brief Called when GL resources are destroyed
+   * @brief Called when resources are destroyed
    */
   void DestroyResource() override;
 
@@ -56,10 +57,28 @@ public:
    */
   void DiscardResource() override;
 
+  /**
+   * @copydoc Graphics::Vulkan::ResourceBase::GetAllocationCallbacks()
+   */
+  [[nodiscard]] const Graphics::AllocationCallbacks* GetAllocationCallbacks() const override
+  {
+    return mCreateInfo.allocationCallbacks;
+  }
+
+  /**
+   * @copydoc Graphics::Vulkan::ResourceBase::InvokeDeleter()
+   * Only intended for use by discard queue.
+   */
+  void InvokeDeleter() override
+  {
+    this->~Framebuffer();
+  }
+
   FramebufferImpl* GetImpl()
   {
     return mFramebufferImpl;
   }
+
 private:
   FramebufferImpl* mFramebufferImpl;
 };
index b04cbd58572dd6e6cd2a5a208e5c74105208aeca..e125df43d3501b8f38643313c2003d5d84b13e3a 100644 (file)
@@ -71,13 +71,13 @@ static bool TestCopyRectIntersection(const ResourceTransferRequest* srcRequest,
  *
  * When Graphics object dies the unique pointer (Graphics::UniquePtr)
  * doesn't destroy it directly but passes the ownership back
- * to the Controller. The VKDeleter is responsible for passing
- * the object to the discard queue (by calling Resource::DiscardResource()).
+ * to the Controller. The GraphicsDeleter is responsible for passing
+ * the graphics object to the discard queue (by calling Resource::DiscardResource()).
  */
 template<typename T>
-struct VKDeleter
+struct GraphicsDeleter
 {
-  VKDeleter() = default;
+  GraphicsDeleter() = default;
 
   void operator()(T* object)
   {
@@ -94,7 +94,7 @@ struct VKDeleter
  * @param[out] out Unique pointer to the return object
  */
 template<class VKType, class GfxCreateInfo, class T>
-auto NewObject(const GfxCreateInfo& info, VulkanGraphicsController& controller, T&& oldObject)
+auto NewGraphicsObject(const GfxCreateInfo& info, VulkanGraphicsController& controller, T&& oldObject)
 {
   // Use allocator
   using Type = typename T::element_type;
@@ -105,7 +105,7 @@ auto NewObject(const GfxCreateInfo& info, VulkanGraphicsController& controller,
       sizeof(VKType),
       0,
       info.allocationCallbacks->userData);
-    return UPtr(new(memory) VKType(info, controller), VKDeleter<VKType>());
+    return UPtr(new(memory) VKType(info, controller), GraphicsDeleter<VKType>());
   }
   else // Use standard allocator
   {
@@ -116,7 +116,7 @@ auto NewObject(const GfxCreateInfo& info, VulkanGraphicsController& controller,
       // If succeeded, attach the object to the unique_ptr and return it back
       if(static_cast<VKType*>(reusedObject)->TryRecycle(info, controller))
       {
-        return UPtr(reusedObject, VKDeleter<VKType>());
+        return UPtr(reusedObject, GraphicsDeleter<VKType>());
       }
       else
       {
@@ -126,8 +126,8 @@ auto NewObject(const GfxCreateInfo& info, VulkanGraphicsController& controller,
       }
     }
 
-    // Create brand new object
-    UPtr gfxObject(new VKType(info, controller), VKDeleter<VKType>());
+    // Create brand-new object
+    UPtr gfxObject(new VKType(info, controller), GraphicsDeleter<VKType>());
     static_cast<VKType*>(gfxObject.get())->InitializeResource(); // @todo Consider using create queues?
     return gfxObject;
   }
@@ -192,7 +192,8 @@ struct VulkanGraphicsController::Impl
     if(!mTextureStagingBuffer ||
        mTextureStagingBuffer->GetImpl()->GetSize() < size)
     {
-      auto workerFunc = [&, size](auto workerIndex) {
+      auto workerFunc = [&, size](auto workerIndex)
+      {
         Graphics::BufferCreateInfo createInfo{};
         createInfo.SetSize(size)
           .SetUsage(0u | Dali::Graphics::BufferUsage::TRANSFER_SRC);
@@ -282,7 +283,8 @@ struct VulkanGraphicsController::Impl
         }
         assert(image);
 
-        auto predicate = [&](auto& item) -> bool {
+        auto predicate = [&](auto& item) -> bool
+        {
           return image->GetVkHandle() == item.image.GetVkHandle();
         };
         auto it = std::find_if(requestMap.begin(), requestMap.end(), predicate);
@@ -394,7 +396,7 @@ struct VulkanGraphicsController::Impl
         commandBuffer->End();
 
         // submit to the queue
-        mGraphicsDevice->Submit(mGraphicsDevice->GetTransferQueue(0u), {Vulkan::SubmissionData{{}, {}, {commandBuffer->GetImpl()}, {}}}, fence);
+        mGraphicsDevice->Submit(mGraphicsDevice->GetTransferQueue(0u), {Vulkan::SubmissionData{{}, {}, {commandBuffer->GetImpl()}, {}}}, fence.get());
         fence->Wait();
         fence->Reset();
       }
@@ -408,7 +410,7 @@ struct VulkanGraphicsController::Impl
           // Do not destroy
           if(buffer != mTextureStagingBuffer->GetImpl())
           {
-            buffer->DestroyNow();
+            buffer->Destroy();
           }
         }
         else if(request.requestType == TransferRequestType::IMAGE_TO_IMAGE)
@@ -416,7 +418,7 @@ struct VulkanGraphicsController::Impl
           auto& image = request.imageToImageInfo.srcImage;
           if(image->GetVkHandle())
           {
-            image->DestroyNow();
+            image->Destroy();
           }
         }
       }
@@ -426,12 +428,74 @@ struct VulkanGraphicsController::Impl
     }
   }
 
+  /**
+   * @brief Processes a discard queue for objects created with NewObject
+   *
+   * @param[in,out] queue Reference to the queue
+   */
+  template<class ResourceType>
+  void ProcessResourceDiscardQueue(std::queue<ResourceType*>& queue)
+  {
+    while(!queue.empty())
+    {
+      auto* object = const_cast<ResourceType*>(queue.front());
+
+      // Destroy
+      object->DestroyResource();
+
+      auto* allocationCallbacks = object->GetAllocationCallbacks();
+      if(allocationCallbacks)
+      {
+        object->InvokeDeleter();
+        allocationCallbacks->freeCallback(object, allocationCallbacks->userData);
+      }
+      else
+      {
+        delete object;
+      }
+      queue.pop();
+    }
+  }
+
+  /**
+   * Processes a discard queue for direct instantiated objects
+   */
+  template<class ResourceType>
+  void ProcessDiscardQueue(std::queue<ResourceType*>& queue)
+  {
+    while(!queue.empty())
+    {
+      auto* object = queue.front();
+
+      // Destroy
+      object->DestroyResource();
+      delete object;
+
+      queue.pop();
+    }
+  }
+
+  void GarbageCollect()
+  {
+    ProcessResourceDiscardQueue<ResourceWithDeleter>(mResourceDiscardQueue);
+    ProcessDiscardQueue<ResourceBase>(mDiscardQueue);
+  }
+
+  void Flush()
+  {
+    // Flush any outstanding queues.
+
+    GarbageCollect();
+  }
+
   VulkanGraphicsController& mGraphicsController;
   Vulkan::Device*           mGraphicsDevice{nullptr};
 
   // used for texture<->buffer<->memory transfers
-  std::vector<ResourceTransferRequest> mResourceTransferRequests;
-  std::recursive_mutex                 mResourceTransferMutex{};
+  std::vector<ResourceTransferRequest>     mResourceTransferRequests;
+  std::recursive_mutex                     mResourceTransferMutex{};
+  std::queue<Vulkan::ResourceBase*>        mDiscardQueue;
+  std::queue<Vulkan::ResourceWithDeleter*> mResourceDiscardQueue;
 
   std::unique_ptr<Vulkan::Buffer>       mTextureStagingBuffer{};
   Dali::SharedFuture                    mTextureStagingBufferFuture{};
@@ -451,7 +515,10 @@ VulkanGraphicsController::VulkanGraphicsController()
 {
 }
 
-VulkanGraphicsController::~VulkanGraphicsController() = default;
+VulkanGraphicsController::~VulkanGraphicsController()
+{
+  mImpl->GarbageCollect();
+}
 
 void VulkanGraphicsController::Initialize(Dali::Graphics::VulkanGraphics& graphicsImplementation,
                                           Vulkan::Device&                 graphicsDevice)
@@ -482,6 +549,12 @@ void VulkanGraphicsController::SubmitCommandBuffers(const SubmitInfo& submitInfo
       swapchain->Submit(cmdBuffer->GetImpl());
     }
   }
+
+  // If flush bit set, flush all pending tasks
+  if(submitInfo.flags & (0 | SubmitFlagBits::FLUSH))
+  {
+    Flush();
+  }
 }
 
 void VulkanGraphicsController::PresentRenderTarget(Graphics::RenderTarget* renderTarget)
@@ -597,7 +670,8 @@ void VulkanGraphicsController::UpdateTextures(
 
         if(destTexture->GetProperties().directWriteAccessEnabled)
         {
-          auto taskLambda = [pInfo, sourcePtr, sourceInfoPtr, texture](auto workerIndex) {
+          auto taskLambda = [pInfo, sourcePtr, sourceInfoPtr, texture](auto workerIndex)
+          {
             const auto& properties = texture->GetProperties();
 
             if(properties.emulated)
@@ -632,7 +706,8 @@ void VulkanGraphicsController::UpdateTextures(
           // The staging buffer is not allocated yet. The task knows pointer to the pointer which will point
           // at staging buffer right before executing tasks. The function will either perform direct copy
           // or will do suitable conversion if source format isn't supported and emulation is available.
-          auto taskLambda = [ppStagingMemory, currentOffset, pInfo, sourcePtr, texture](auto workerThread) {
+          auto taskLambda = [ppStagingMemory, currentOffset, pInfo, sourcePtr, texture](auto workerThread)
+          {
             char* pStagingMemory = reinterpret_cast<char*>(*ppStagingMemory);
 
             // Try to initialise` texture resources explicitly if they are not yet initialised
@@ -670,7 +745,8 @@ void VulkanGraphicsController::UpdateTextures(
   for(auto& item : updateMap)
   {
     auto pUpdates = &item.second;
-    auto task     = [pUpdates](auto workerIndex) {
+    auto task     = [pUpdates](auto workerIndex)
+    {
       for(auto& update : *pUpdates)
       {
         update.copyTask(workerIndex);
@@ -787,6 +863,7 @@ bool VulkanGraphicsController::EnableDepthStencilBuffer(bool enableDepth, bool e
 
 void VulkanGraphicsController::RunGarbageCollector(size_t numberOfDiscardedRenderers)
 {
+  mImpl->GarbageCollect();
 }
 
 void VulkanGraphicsController::DiscardUnusedResources()
@@ -805,12 +882,12 @@ bool VulkanGraphicsController::IsDrawOnResumeRequired()
 
 UniquePtr<Graphics::RenderTarget> VulkanGraphicsController::CreateRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo, UniquePtr<Graphics::RenderTarget>&& oldRenderTarget)
 {
-  return NewObject<Vulkan::RenderTarget>(renderTargetCreateInfo, *this, std::move(oldRenderTarget));
+  return NewGraphicsObject<Vulkan::RenderTarget>(renderTargetCreateInfo, *this, std::move(oldRenderTarget));
 }
 
 UniquePtr<Graphics::CommandBuffer> VulkanGraphicsController::CreateCommandBuffer(const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo, UniquePtr<Graphics::CommandBuffer>&& oldCommandBuffer)
 {
-  return NewObject<Vulkan::CommandBuffer>(commandBufferCreateInfo, *this, std::move(oldCommandBuffer));
+  return NewGraphicsObject<Vulkan::CommandBuffer>(commandBufferCreateInfo, *this, std::move(oldCommandBuffer));
 }
 
 UniquePtr<Graphics::RenderPass> VulkanGraphicsController::CreateRenderPass(const Graphics::RenderPassCreateInfo& renderPassCreateInfo, UniquePtr<Graphics::RenderPass>&& oldRenderPass)
@@ -823,12 +900,12 @@ UniquePtr<Graphics::RenderPass> VulkanGraphicsController::CreateRenderPass(const
 
 UniquePtr<Graphics::Buffer> VulkanGraphicsController::CreateBuffer(const Graphics::BufferCreateInfo& bufferCreateInfo, UniquePtr<Graphics::Buffer>&& oldBuffer)
 {
-  return NewObject<Vulkan::Buffer>(bufferCreateInfo, *this, std::move(oldBuffer));
+  return NewGraphicsObject<Vulkan::Buffer>(bufferCreateInfo, *this, std::move(oldBuffer));
 }
 
 UniquePtr<Graphics::Texture> VulkanGraphicsController::CreateTexture(const Graphics::TextureCreateInfo& textureCreateInfo, UniquePtr<Graphics::Texture>&& oldTexture)
 {
-  return NewObject<Vulkan::Texture>(textureCreateInfo, *this, std::move(oldTexture));
+  return NewGraphicsObject<Vulkan::Texture>(textureCreateInfo, *this, std::move(oldTexture));
 }
 
 UniquePtr<Graphics::Framebuffer> VulkanGraphicsController::CreateFramebuffer(const Graphics::FramebufferCreateInfo& framebufferCreateInfo, UniquePtr<Graphics::Framebuffer>&& oldFramebuffer)
@@ -853,7 +930,7 @@ UniquePtr<Graphics::Shader> VulkanGraphicsController::CreateShader(const Graphic
 
 UniquePtr<Graphics::Sampler> VulkanGraphicsController::CreateSampler(const Graphics::SamplerCreateInfo& samplerCreateInfo, UniquePtr<Graphics::Sampler>&& oldSampler)
 {
-  return NewObject<Vulkan::Sampler>(samplerCreateInfo, *this, std::move(oldSampler));
+  return NewGraphicsObject<Vulkan::Sampler>(samplerCreateInfo, *this, std::move(oldSampler));
 }
 
 UniquePtr<Graphics::SyncObject> VulkanGraphicsController::CreateSyncObject(const Graphics::SyncObjectCreateInfo& syncObjectCreateInfo,
@@ -862,6 +939,16 @@ UniquePtr<Graphics::SyncObject> VulkanGraphicsController::CreateSyncObject(const
   return UniquePtr<Graphics::SyncObject>{};
 }
 
+void VulkanGraphicsController::DiscardResource(Vulkan::ResourceBase* resource)
+{
+  mImpl->mDiscardQueue.push(resource);
+}
+
+void VulkanGraphicsController::DiscardResource(Vulkan::ResourceWithDeleter* resource)
+{
+  mImpl->mResourceDiscardQueue.push(resource);
+}
+
 UniquePtr<Graphics::Memory> VulkanGraphicsController::MapBufferRange(const MapBufferInfo& mapInfo)
 {
   // @todo: Process create queues
@@ -904,7 +991,7 @@ MemoryRequirements VulkanGraphicsController::GetTextureMemoryRequirements(Graphi
 
 TextureProperties VulkanGraphicsController::GetTextureProperties(const Graphics::Texture& gfxTexture)
 {
-  Vulkan::Texture* texture = const_cast<Vulkan::Texture*>(static_cast<const Vulkan::Texture*>(&gfxTexture));
+  auto* texture = const_cast<Vulkan::Texture*>(static_cast<const Vulkan::Texture*>(&gfxTexture));
   return texture->GetProperties();
 }
 
@@ -987,40 +1074,6 @@ std::string VulkanGraphicsController::GetFragmentShaderPrefix()
   return "";
 }
 
-void VulkanGraphicsController::Add(Vulkan::RenderTarget* renderTarget)
-{
-  // @todo Add create resource queues?
-  renderTarget->InitializeResource();
-}
-
-void VulkanGraphicsController::DiscardResource(Vulkan::RenderTarget* renderTarget)
-{
-  // @todo Add discard queues
-}
-
-void VulkanGraphicsController::DiscardResource(Vulkan::Buffer* buffer)
-{
-  // @todo Add discard queues
-}
-
-void VulkanGraphicsController::DiscardResource(Vulkan::Pipeline* buffer)
-{
-  // @todo Add discard queues
-}
-
-void VulkanGraphicsController::DiscardResource(Vulkan::Program* program)
-{
-  // @todo Add discard queues
-}
-
-void VulkanGraphicsController::DiscardResource(Vulkan::Sampler* sampler)
-{
-}
-
-void VulkanGraphicsController::DiscardResource(Vulkan::Texture* texture)
-{
-}
-
 Vulkan::Device& VulkanGraphicsController::GetGraphicsDevice()
 {
   return *mImpl->mGraphicsDevice;
@@ -1078,9 +1131,27 @@ Graphics::UniquePtr<Graphics::Texture> VulkanGraphicsController::ReleaseTextureF
   return gfxTexture;
 }
 
+void VulkanGraphicsController::Flush()
+{
+  mImpl->Flush();
+}
+
 std::size_t VulkanGraphicsController::GetCapacity() const
 {
   return mImpl->mCapacity;
 }
 
+bool VulkanGraphicsController::HasClipMatrix() const
+{
+  return true;
+}
+
+const Matrix& VulkanGraphicsController::GetClipMatrix() const
+{
+  constexpr float CLIP_MATRIX_DATA[] = {
+    1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 1.0f};
+  static const Matrix CLIP_MATRIX(CLIP_MATRIX_DATA);
+  return CLIP_MATRIX;
+}
+
 } // namespace Dali::Graphics::Vulkan
index 2c76e20b0240d9baacfbcbbb033ff320409dd34d..0e10695eb306e68e3ab21827f59d045b26cd0e12 100644 (file)
@@ -269,6 +269,14 @@ public:
   UniquePtr<Graphics::SyncObject> CreateSyncObject(const Graphics::SyncObjectCreateInfo& syncObjectCreateInfo,
                                                    UniquePtr<Graphics::SyncObject>&&     oldSyncObject) override;
 
+  /**
+   * Add the graphics resource to a discard queue for later destruction
+   * @param[in] resource The graphics resource to discard.
+   */
+  void DiscardResource(Vulkan::ResourceBase* resource);
+
+  void DiscardResource(Vulkan::ResourceWithDeleter* program);
+
   /**
    * @brief Maps memory associated with Buffer object
    *
@@ -365,14 +373,6 @@ public:
    */
   bool GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData) override;
 
-  void Add(Vulkan::RenderTarget* renderTarget);
-  void DiscardResource(Vulkan::RenderTarget* renderTarget);
-  void DiscardResource(Vulkan::Buffer* buffer);
-  void DiscardResource(Vulkan::Pipeline* buffer);
-  void DiscardResource(Vulkan::Program* renderProgram);
-  void DiscardResource(Vulkan::Sampler* sampler);
-  void DiscardResource(Vulkan::Texture* texture);
-
 public: // Integration::GraphicsConfig
   bool        IsBlendEquationSupported(DevelBlendEquation::Type blendEquation) override;
   uint32_t    GetShaderLanguageVersion() override;
@@ -417,12 +417,27 @@ public: // ResourceId relative API.
    */
   UniquePtr<Graphics::Texture> ReleaseTextureFromResourceId(uint32_t resourceId) override;
 
+  /**
+   * @return true if there is a clip space transform matrix
+   */
+  bool HasClipMatrix() const override;
+
+  /**
+   * @return the clip space transform matrix
+   */
+  const Matrix& GetClipMatrix() const override;
+
 public: // For debug
   void FrameStart();
 
   std::size_t GetCapacity() const;
 
 private:
+  /**
+   * Flush all outstanding queues.
+   */
+  void Flush();
+
   bool IsAdvancedBlendEquationSupported();
 
   struct Impl;
index e1d0f11bb2a1fceceed49b48f7196172c6635fd2..4d145c9b0a2073e8e750803ca26dc470d0f339e2 100644 (file)
  *
  */
 
+#include <dali/graphics-api/graphics-types.h>
+
 namespace Dali::Graphics::Vulkan
 {
 class VulkanGraphicsController;
 
+/**
+ * Interface class for graphics resources
+ */
+class ResourceBase
+{
+public:
+  /**
+   * @brief Destroys resource
+   *
+   * This function must be implemented by the derived class.
+   * It should perform final destruction of used GL resources.
+   */
+  virtual void DestroyResource() = 0;
+
+  /**
+   * @brief Initializes resource
+   *
+   * This function must be implemented by the derived class.
+   * It should initialize all necessary GL resources.
+   *
+   * @return True on success
+   */
+  virtual bool InitializeResource() = 0;
+
+  /**
+   * @brief Discards resource by adding it to the discard queue
+   */
+  virtual void DiscardResource() = 0;
+
+  virtual ~ResourceBase() = default;
+};
+
+class ResourceWithDeleter : public ResourceBase
+{
+public:
+  /**
+   * @brief Get the allocation callbacks for this object
+   */
+  [[nodiscard]] virtual const Graphics::AllocationCallbacks* GetAllocationCallbacks() const = 0;
+
+  /**
+   * @brief Invoke the deleter of the derived type.
+   */
+  virtual void InvokeDeleter() = 0;
+
+  ~ResourceWithDeleter() override = default;
+};
+
 /**
  * @brief Base class for the Graphics resource.
+ * A graphics resource is any Graphics API object created by the controller that
+ * requires lifecycle management.
+ * It explicitly does not include Vulkan Impl objects that wrap a vkHandle.
  */
-template<class BASE, class CreateInfo>
-class Resource : public BASE
+template<class GraphicsType, class CreateInfo>
+class Resource : public GraphicsType, public ResourceWithDeleter
 {
 public:
   /**
@@ -79,34 +132,11 @@ public:
     return mController;
   }
 
-  /**
-   * @brief Destroys resource
-   *
-   * This function must be implemented by the derived class.
-   * It should perform final destruction of used GL resources.
-   */
-  virtual void DestroyResource() = 0;
-
-  /**
-   * @brief Initializes resource
-   *
-   * This function must be implemented by the derived class.
-   * It should initialize all necessary GL resources.
-   *
-   * @return True on success
-   */
-  virtual bool InitializeResource() = 0;
-
-  /**
-   * @brief Discards resource by adding it to the discard queue
-   */
-  virtual void DiscardResource() = 0;
-
   /**
    * @brief returns pointer to base
    * @return
    */
-  BASE* GetBase()
+  GraphicsType* GetBase()
   {
     return this;
   }
diff --git a/dali/internal/graphics/vulkan-impl/vulkan-handle.h b/dali/internal/graphics/vulkan-impl/vulkan-handle.h
new file mode 100644 (file)
index 0000000..53d8302
--- /dev/null
@@ -0,0 +1,245 @@
+#pragma once
+
+/*
+ * Copyright (c) 2024 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.
+ */
+
+namespace Dali::Graphics::Vulkan
+{
+
+template<class T>
+class Handle
+{
+public:
+  Handle();
+
+  explicit Handle(T* object);
+
+  Handle(const Handle& handle);
+
+  Handle& operator=(const Handle& handle);
+
+  Handle& operator=(Handle&& handle);
+
+  Handle(Handle&& handle) noexcept;
+
+  ~Handle();
+
+  operator bool() const;
+
+  T* operator->() const
+  {
+    return mObject;
+  }
+
+  uint32_t GetRefCount() const
+  {
+    return mObject->GetRefCount();
+  }
+
+  T& operator*() const
+  {
+    return *mObject;
+  }
+
+  template<class K>
+  Handle<K> StaticCast()
+  {
+    return Handle<K>(static_cast<K*>(mObject));
+  }
+
+  template<class K>
+  bool operator==(const Handle<K>& object) const
+  {
+    return mObject == &*object;
+  }
+
+  template<class K>
+  bool operator!=(const Handle<K>& object) const
+  {
+    return !(mObject == &*object);
+  }
+
+  template<class K>
+  Handle<K> DynamicCast();
+
+  void Reset()
+  {
+    if(mObject)
+    {
+      mObject->Release();
+      mObject = nullptr;
+    }
+  }
+
+private:
+  T* mObject{nullptr};
+};
+
+template<class K, class T>
+static Handle<K> VkTypeCast(const Handle<T>& inval)
+{
+  return Handle<K>(static_cast<K*>(&*inval));
+}
+
+template<class T>
+Handle<T>::Handle(T* object)
+: mObject(object)
+{
+  if(mObject)
+  {
+    mObject->Retain();
+  }
+}
+
+template<class T>
+Handle<T>::Handle()
+: mObject(nullptr)
+{
+}
+
+template<class T>
+Handle<T>::Handle(const Handle& handle)
+{
+  mObject = handle.mObject;
+  if(mObject)
+  {
+    mObject->Retain();
+  }
+}
+
+template<class T>
+Handle<T>::Handle(Handle&& handle) noexcept
+{
+  mObject        = handle.mObject;
+  handle.mObject = nullptr;
+}
+
+template<class T>
+Handle<T>::operator bool() const
+{
+  return mObject != nullptr;
+}
+
+template<class T>
+Handle<T>& Handle<T>::operator=(Handle&& handle)
+{
+  if(mObject)
+  {
+    mObject->Release();
+  }
+  mObject        = handle.mObject;
+  handle.mObject = nullptr;
+  return *this;
+}
+
+template<class T>
+Handle<T>& Handle<T>::operator=(const Handle<T>& handle)
+{
+  mObject = handle.mObject;
+  if(mObject)
+  {
+    mObject->Retain();
+  }
+  return *this;
+}
+
+template<class T>
+Handle<T>::~Handle()
+{
+  if(mObject)
+  {
+    mObject->Release();
+  }
+}
+
+template<class T>
+template<class K>
+Handle<K> Handle<T>::DynamicCast()
+{
+  auto val = dynamic_cast<K*>(mObject);
+  if(val)
+  {
+    return Handle<K>(val);
+  }
+  return Handle<K>();
+}
+
+template<typename T, typename... Args>
+Handle<T> MakeRef(Args&&... args)
+{
+  return Handle<T>(new T(std::forward<Args>(args)...));
+}
+
+template<typename T, typename... Args>
+Handle<T> NewRef(Args&&... args)
+{
+  return Handle<T>(T::New(std::forward<Args>(args)...));
+}
+
+class VkSharedResource // E.g. render pass
+{
+public:
+  VkSharedResource() = default;
+
+  virtual ~VkSharedResource() = default;
+
+  void Release()
+  {
+    OnRelease(--mRefCount);
+
+    if(mRefCount == 0)
+    {
+      // orphaned
+      if(!Destroy())
+      {
+        delete this;
+      }
+    }
+  }
+
+  void Retain()
+  {
+    OnRetain(++mRefCount);
+  }
+
+  uint32_t GetRefCount()
+  {
+    return mRefCount;
+  }
+
+  virtual bool Destroy()
+  {
+    return OnDestroy();
+  }
+
+  virtual void OnRetain(uint32_t refcount)
+  {
+  }
+
+  virtual void OnRelease(uint32_t refcount)
+  {
+  }
+
+  virtual bool OnDestroy()
+  {
+    return false;
+  }
+
+private:
+  std::atomic_uint mRefCount{0u};
+};
+
+} // namespace Dali::Graphics::Vulkan
index 9d0dbe6626c76dd131c852a7b5006417e0039c2e..470d1bd919aada7159cac0f85a2a0d2294000046 100644 (file)
@@ -30,7 +30,6 @@ namespace Graphics
 {
 namespace Vulkan
 {
-
 Image* Image::New(Device& graphicsDevice, const vk::ImageCreateInfo& createInfo)
 {
   auto image = new Image(graphicsDevice, createInfo, nullptr);
@@ -84,6 +83,18 @@ void Image::Initialize()
   VkAssert(mDevice.GetLogicalDevice().createImage(&mCreateInfo, &mDevice.GetAllocator("IMAGE"), &mImage));
 }
 
+void Image::Destroy()
+{
+  DALI_LOG_INFO(gVulkanFilter, Debug::General, "Destroying image: %p\n", static_cast<VkImage>(mImage));
+  auto device = mDevice.GetLogicalDevice();
+  if(mImage)
+  {
+    device.destroyImage(mImage, mDevice.GetAllocator());
+  }
+  mImage = nullptr;
+  mMemory.reset();
+}
+
 void Image::AllocateAndBind(vk::MemoryPropertyFlags memoryProperties)
 {
   auto requirements    = mDevice.GetLogicalDevice().getImageMemoryRequirements(mImage);
@@ -94,7 +105,7 @@ void Image::AllocateAndBind(vk::MemoryPropertyFlags memoryProperties)
   mMemory = std::make_unique<MemoryImpl>(mDevice,
                                          size_t(requirements.size),
                                          size_t(requirements.alignment),
-                                         (memoryProperties & vk::MemoryPropertyFlagBits::eHostVisible) == vk::MemoryPropertyFlagBits::eHostVisible);
+                                         memoryProperties);
 
   auto allocateInfo = vk::MemoryAllocateInfo{}
                         .setMemoryTypeIndex(memoryTypeIndex)
@@ -256,39 +267,6 @@ vk::SampleCountFlagBits Image::GetSampleCount() const
   return mCreateInfo.samples;
 }
 
-void Image::DestroyNow()
-{
-  DestroyVulkanResources(mDevice.GetLogicalDevice(), mImage, mMemory->ReleaseVkObject(), &mDevice.GetAllocator());
-  mImage  = nullptr;
-  mMemory = nullptr;
-}
-
-bool Image::OnDestroy()
-{
-  if(!mIsExternal)
-  {
-    if(mImage)
-    {
-      auto device    = mDevice.GetLogicalDevice();
-      auto image     = mImage;
-      auto allocator = &mDevice.GetAllocator();
-      auto memory    = mMemory->ReleaseVkObject();
-
-      mDevice.DiscardResource([device, image, memory, allocator]()
-                              { DestroyVulkanResources(device, image, memory, allocator); });
-    }
-  }
-
-  return false;
-}
-
-void Image::DestroyVulkanResources(vk::Device device, vk::Image image, vk::DeviceMemory memory, const vk::AllocationCallbacks* allocator)
-{
-  DALI_LOG_INFO(gVulkanFilter, Debug::General, "Invoking deleter function: image->%p\n", static_cast<VkImage>(image))
-  device.destroyImage(image, allocator);
-  device.freeMemory(memory, allocator);
-}
-
 } // namespace Vulkan
 
 } // namespace Graphics
index 8454583f2d62799e30ad9804a42f010808b0a79c..dc9ea516fb32777bc377e349ad2c652248ce536d 100644 (file)
@@ -53,6 +53,14 @@ public:
    */
   void Initialize();
 
+  /**
+   * Destroys underlying Vulkan resources on the caller thread.
+   *
+   * @note Calling this function is unsafe and makes any further use of
+   * image invalid.
+   */
+  void Destroy();
+
   /**
    * Allocate memory for the image and bind it.
    * Kept separate from Initialize because reasons. ?!?!
@@ -149,32 +157,12 @@ public:
     return mMemory.get();
   }
 
-  bool OnDestroy();
-
-  /**
-   * Destroys underlying Vulkan resources on the caller thread.
-   *
-   * @note Calling this function is unsafe and makes any further use of
-   * image invalid.
-   */
-  void DestroyNow();
-
-  /**
-   * Destroys used Vulkan resource objects
-   * @param device Vulkan device
-   * @param image Vulkan image
-   * @param memory Vulkan device memory
-   * @param allocator Pointer to the Vulkan allocator callbacks
-   */
-  static void DestroyVulkanResources(vk::Device device, vk::Image image, vk::DeviceMemory memory, const vk::AllocationCallbacks* allocator);
-
 private:
-  Device&              mDevice;
-  vk::ImageCreateInfo  mCreateInfo;
-  vk::Image            mImage;
-  vk::ImageLayout      mImageLayout;
-  vk::ImageAspectFlags mAspectFlags;
-
+  Device&                     mDevice;
+  vk::ImageCreateInfo         mCreateInfo;
+  vk::Image                   mImage;
+  vk::ImageLayout             mImageLayout;
+  vk::ImageAspectFlags        mAspectFlags;
   std::unique_ptr<MemoryImpl> mMemory;
   bool                        mIsExternal;
 };
index 15fb6fda0282b705aaea9054728f5100616ac45d..9d921c00c4edbb5f8d4cd99472ff6b74b1e29a4c 100644 (file)
@@ -110,6 +110,13 @@ ImageView::~ImageView()
   Destroy();
 }
 
+void ImageView::Destroy()
+{
+  DALI_LOG_INFO(gVulkanFilter, Debug::General, "Destroying ImageView: %p\n", static_cast<VkImageView>(mImageView));
+  auto device = mDevice.GetLogicalDevice();
+  device.destroyImageView(mImageView, mDevice.GetAllocator());
+}
+
 vk::ImageView ImageView::GetVkHandle() const
 {
   return mImageView;
@@ -135,12 +142,6 @@ vk::ImageAspectFlags ImageView::GetImageAspectMask() const
   return vk::ImageAspectFlags();
 }
 
-void ImageView::Destroy()
-{
-  auto device = mDevice.GetLogicalDevice();
-  device.destroyImageView(mImageView, mDevice.GetAllocator());
-}
-
 } // namespace Vulkan
 } // namespace Graphics
 } // namespace Dali
index b7454ad4c8d9319e1971e397e84cc94215a0110f..28830291b368695ba93859126b05ef1cd055d114 100644 (file)
@@ -52,6 +52,8 @@ public:
 
   ~ImageView();
 
+  void Destroy();
+
   /**
    *
    * @return
@@ -79,8 +81,6 @@ public:
    */
   [[nodiscard]] vk::ImageAspectFlags GetImageAspectMask() const;
 
-  void Destroy();
-
 private:
   Device&                 mDevice;
   const Image&            mImage;
index fc1b3dfd500fb7cdfafae1e2d4778db7d713640e..ce333d4c0b10f14e5d45f8bbdbe324a83d3baa5a 100644 (file)
 
 namespace Dali::Graphics::Vulkan
 {
-
-MemoryImpl::MemoryImpl(Device& device, size_t memSize, size_t memAlign, bool isHostVisible)
+MemoryImpl::MemoryImpl(Device& device, size_t memSize, size_t memAlign, vk::MemoryPropertyFlags memoryProperties)
 : mDevice(device),
   deviceMemory(nullptr),
   size(memSize),
   alignment(memAlign),
   mappedPtr(nullptr),
   mappedSize(0u),
-  hostVisible(isHostVisible)
+  mMemoryProperties(memoryProperties)
 {
 }
 
@@ -78,20 +77,18 @@ void MemoryImpl::Unmap()
   }
 }
 
-vk::DeviceMemory MemoryImpl::ReleaseVkObject()
-{
-  auto retval  = deviceMemory;
-  deviceMemory = nullptr;
-  return retval;
-}
-
 void MemoryImpl::Flush()
 {
-  vk::Result result = mDevice.GetLogicalDevice().flushMappedMemoryRanges({vk::MappedMemoryRange{}
-                                                                            .setSize(mappedSize)
-                                                                            .setMemory(deviceMemory)
-                                                                            .setOffset(0u)});
-  DALI_ASSERT_ALWAYS(result == vk::Result::eSuccess); // If it's out of memory, may as well crash.
+  // Don't flush if we are using host coherent memory - it's un-necessary
+  if((mMemoryProperties & vk::MemoryPropertyFlagBits::eHostCoherent) != vk::MemoryPropertyFlagBits::eHostCoherent)
+  {
+    vk::Result result = mDevice.GetLogicalDevice().flushMappedMemoryRanges({vk::MappedMemoryRange{}
+                                                                              .setSize(mappedSize ? mappedSize : VK_WHOLE_SIZE)
+                                                                              .setMemory(deviceMemory)
+                                                                              .setOffset(0u)});
+
+    DALI_ASSERT_ALWAYS(result == vk::Result::eSuccess); // If it's out of memory, may as well crash.
+  }
 }
 
 vk::DeviceMemory MemoryImpl::GetVkHandle() const
index 73e5f52bdc1c767cbe368f8a09c3110966816038..40a2fb72f6add92c059b8e72f571af3512fbfb64 100644 (file)
 
 namespace Dali::Graphics::Vulkan
 {
-
 class MemoryImpl
 {
 public:
-  MemoryImpl(Device& device, size_t memSize, size_t memAlign, bool hostVisible);
+  MemoryImpl(Device& device, size_t memSize, size_t memAlign, vk::MemoryPropertyFlags memoryProperties);
 
   ~MemoryImpl();
 
@@ -50,23 +49,16 @@ public:
 
   void Flush();
 
-  /**
-   * Releases vk::DeviceMemory object so it can be deleted
-   * externally
-   * @return
-   */
-  vk::DeviceMemory ReleaseVkObject();
-
   [[nodiscard]] vk::DeviceMemory GetVkHandle() const;
 
 private:
-  Device&          mDevice;
-  vk::DeviceMemory deviceMemory;
-  size_t           size;
-  size_t           alignment;
-  void*            mappedPtr;
-  size_t           mappedSize;
-  bool             hostVisible;
+  Device&                 mDevice;
+  vk::DeviceMemory        deviceMemory;
+  size_t                  size;
+  size_t                  alignment;
+  void*                   mappedPtr;
+  size_t                  mappedSize;
+  vk::MemoryPropertyFlags mMemoryProperties;
 };
 
 } // namespace Dali::Graphics::Vulkan
index 8bb63caadd6a36d547bbf6a62ec03c193fd76385..03d928098d8f5b46bbad02f15f17430578f9231f 100644 (file)
@@ -261,10 +261,12 @@ void PipelineImpl::InitializePipeline()
   dynInfo.setDynamicStates(mDynamicStates);
   gfxPipelineInfo.setPDynamicState(&dynInfo);
 
-  auto& allocator   = mController.GetGraphicsDevice().GetAllocator();
-  auto  rtImpl      = static_cast<Vulkan::RenderTarget*>(mCreateInfo.renderTarget);
-  auto  framebuffer = rtImpl->GetFramebuffer();
-  auto  surface     = rtImpl->GetSurface();
+  auto& allocator = mController.GetGraphicsDevice().GetAllocator();
+
+  auto rtImpl = static_cast<Vulkan::RenderTarget*>(mCreateInfo.renderTarget);
+
+  auto framebuffer = rtImpl->GetFramebuffer();
+  auto surface     = rtImpl->GetSurface();
 
   FramebufferImpl* fbImpl = nullptr;
   if(surface)
@@ -282,7 +284,7 @@ void PipelineImpl::InitializePipeline()
   auto renderPassCount = fbImpl->GetRenderPassCount();
   for(auto i = 0u; i < renderPassCount; ++i)
   {
-    RenderPassImpl* impl       = fbImpl->GetRenderPass(i);
+    RenderPassHandle impl      = fbImpl->GetRenderPass(i);
     gfxPipelineInfo.renderPass = impl->GetVkHandle();
     gfxPipelineInfo.subpass    = 0;
 
@@ -319,6 +321,11 @@ void PipelineImpl::InitializePipeline()
   }
 }
 
+const Vulkan::Program* PipelineImpl::GetProgram() const
+{
+  return static_cast<const Vulkan::Program*>(mCreateInfo.programState->program);
+}
+
 void PipelineImpl::InitializeVertexInputState(vk::PipelineVertexInputStateCreateInfo& out)
 {
   std::vector<vk::VertexInputBindingDescription> bindings;
@@ -824,8 +831,11 @@ void PipelineImpl::InitializeColorBlendState(vk::PipelineColorBlendStateCreateIn
 
   att.setAlphaBlendOp(ConvBlendOp(in->alphaBlendOp));
   att.setBlendEnable(in->blendEnable);
+  //att.setColorWriteMask()
   att.setColorBlendOp(ConvBlendOp(in->colorBlendOp));
   att.setColorWriteMask(vk::ColorComponentFlags(in->colorComponentWriteBits));
+  att.setColorWriteMask(vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG |
+                        vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA);
   att.setDstAlphaBlendFactor(ConvBlendFactor(in->dstAlphaBlendFactor));
   att.setDstColorBlendFactor(ConvBlendFactor(in->dstColorBlendFactor));
   att.setSrcAlphaBlendFactor(ConvBlendFactor(in->srcAlphaBlendFactor));
index 61d9731312b4961149f1ea20b2902b8224e0542b..1a978ade127814fe997813f96971b6f33e796066 100644 (file)
@@ -96,6 +96,8 @@ public:
 
   void InitializePipeline();
 
+  const Vulkan::Program* GetProgram() const;
+
 private:
   void InitializeVertexInputState(vk::PipelineVertexInputStateCreateInfo& out);
   void InitializeInputAssemblyState(vk::PipelineInputAssemblyStateCreateInfo& out) const;
index 6cf4fc4bae1d84a9827ca7634c0ca22165a0caec..95a4b03d48d07c29d4d5647a829f1c63f0fd6b9f 100644 (file)
@@ -56,6 +56,11 @@ Pipeline::Pipeline(const Graphics::PipelineCreateInfo& createInfo, VulkanGraphic
   mPipeline = std::make_unique<PipelineImpl>(createInfo, controller, pipelineCache);
 }
 
+bool Pipeline::InitializeResource()
+{
+  return true;
+}
+
 void Pipeline::DiscardResource()
 {
   // Send pipeline to discard queue if refcount is 0
index 2e92309d240c51e96cea64da7f7f2915f9af3c15..8f3d16b6c397177b1e079f40fe9bce1e79734a74 100644 (file)
@@ -35,7 +35,7 @@ class PipelineCache;
 /**
  * @brief Pipeline class wraps the PipelineImpl
  */
-class Pipeline : public Graphics::Pipeline
+class Pipeline : public Graphics::Pipeline, public Vulkan::ResourceBase
 {
 public:
   Pipeline() = delete;
@@ -82,22 +82,23 @@ public:
   bool operator==(const PipelineImpl* impl) const;
 
   /**
-   * @brief Run by UniquePtr to discard resource
+   * @brief Initialize the resource
    */
-  void DiscardResource();
+  bool InitializeResource() override;
+
+  /**
+   * @brief trigger discard
+   */
+  void DiscardResource() override;
 
   /**
    * @brief Destroy resource
-   *
-   * Despite this class doesn't inherit Resource it must provide
-   * (so it won't duplicate same data) same set of functions
-   * so it can work with resource management functions of Controller.
    */
-  void DestroyResource();
+  void DestroyResource() override;
 
 private:
   std::unique_ptr<PipelineImpl> mPipeline; // TODO: it may need to be changed when we have caching
 };
 
 } // namespace Dali::Graphics::Vulkan
-#endif
\ No newline at end of file
+#endif
index 0a6d8a67dfd903c6693573763f1bea481f7bf793..4269dbfbc6813d50a450165eaecd3abf72ef682c 100644 (file)
@@ -24,6 +24,7 @@
 #include <dali/internal/graphics/vulkan-impl/vulkan-reflection.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-shader-impl.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-shader.h>
+#include <dali/internal/graphics/vulkan/vulkan-device.h>
 
 // EXTERNAL HEADERS
 #include <iostream>
@@ -63,6 +64,15 @@ struct ProgramImpl::Impl
   std::unique_ptr<Vulkan::Reflection> reflection{nullptr};
 
   std::vector<vk::PipelineShaderStageCreateInfo> mPipelineShaderStageCreateInfoList;
+
+  struct DescriptorPool
+  {
+    vk::DescriptorPoolCreateInfo createInfo;
+    vk::DescriptorPool           vkPool;
+  };
+
+  std::vector<DescriptorPool> poolList;
+  int32_t                     currentPoolIndex{-1};
 };
 
 ProgramImpl::ProgramImpl(const Graphics::ProgramCreateInfo& createInfo, VulkanGraphicsController& controller)
@@ -249,4 +259,95 @@ const ProgramCreateInfo& ProgramImpl::GetCreateInfo() const
   return mImpl->mPipelineShaderStageCreateInfoList;
 }
 
+[[nodiscard]] int ProgramImpl::AddDescriptorPool(uint32_t poolCapacity, uint32_t maxPoolCounts)
+{
+  auto& poolList  = mImpl->poolList;
+  auto& poolIndex = mImpl->currentPoolIndex;
+  poolIndex %= maxPoolCounts;
+
+  auto& gfxDevice = mImpl->controller.GetGraphicsDevice();
+  auto& allocator = gfxDevice.GetAllocator();
+  auto  vkDevice  = gfxDevice.GetLogicalDevice();
+
+  if(poolCapacity != poolList.size())
+  {
+    poolList.resize(poolCapacity);
+    // should error if pool index exceeds pool capacity
+  }
+
+  // round-robin the pool index
+  Impl::DescriptorPool& descriptorPool = mImpl->poolList[poolIndex];
+
+  // if pool exists at index...
+  if(descriptorPool.vkPool)
+  {
+    // ...try to reuse the pool
+    if(descriptorPool.createInfo.maxSets >= poolCapacity)
+    {
+      vkDevice.resetDescriptorPool(descriptorPool.vkPool, vk::DescriptorPoolResetFlags{});
+      return poolIndex;
+    }
+
+    // ... else, destroy vulkan object
+    vkDevice.destroyDescriptorPool(descriptorPool.vkPool, &allocator);
+  }
+
+  descriptorPool.createInfo.setMaxSets(poolCapacity);
+  std::vector<vk::DescriptorPoolSize> poolSizes;
+
+  // Note, first block is for gles emulation, so ignore it.
+  auto uniformBlockCount = GetReflection().GetUniformBlockCount() - 1;
+  auto samplersCount     = GetReflection().GetSamplers().size();
+
+  if(uniformBlockCount)
+  {
+    vk::DescriptorPoolSize item;
+    item.setType(vk::DescriptorType::eUniformBuffer);
+    item.setDescriptorCount(uniformBlockCount * poolCapacity);
+    poolSizes.emplace_back(item);
+  }
+  if(samplersCount) // For now, we use only combined image sampler type as 'sampler'
+  {
+    vk::DescriptorPoolSize item;
+    item.setType(vk::DescriptorType::eCombinedImageSampler);
+    item.setDescriptorCount(samplersCount * poolCapacity);
+    poolSizes.emplace_back(item);
+  }
+
+  // set sizes
+  descriptorPool.createInfo.setPoolSizes(poolSizes);
+
+  // create pool
+  VkAssert(vkDevice.createDescriptorPool(&descriptorPool.createInfo, &allocator, &descriptorPool.vkPool));
+
+  return poolIndex;
+}
+
+[[nodiscard]] vk::DescriptorSet ProgramImpl::AllocateDescriptorSet(int poolIndex)
+{
+  // if pool index isn't specified, last added pool will be used
+  if(poolIndex < 0)
+  {
+    poolIndex = mImpl->currentPoolIndex;
+  }
+
+  auto& poolList  = mImpl->poolList;
+  auto& gfxDevice = mImpl->controller.GetGraphicsDevice();
+  auto  vkDevice  = gfxDevice.GetLogicalDevice();
+
+  vk::DescriptorSetAllocateInfo allocateInfo;
+  allocateInfo.setDescriptorPool(poolList[poolIndex].vkPool);
+
+  auto& layouts = GetReflection().GetVkDescriptorSetLayouts();
+  allocateInfo.setSetLayouts(layouts);
+  // TODO: making sure only first layout will be use.
+  // Reflection supports multiple sets but current architecture of Vulkan backend
+  // uses single set only per pipeline/program
+  allocateInfo.setDescriptorSetCount(1);
+
+  vk::DescriptorSet set;
+  VkAssert(vkDevice.allocateDescriptorSets(&allocateInfo, &set));
+  return set;
+}
+
 }; // namespace Dali::Graphics::Vulkan
index cf59bf2828d70f33c32d285c2a28c178be0c8e7e..be7b09c8d5d2fa301688f09ffbc988d8b5ec8b1b 100644 (file)
@@ -142,6 +142,16 @@ public:
    */
   bool GetParameter(uint32_t parameterId, void* out);
 
+  /**
+   *
+   * @param[in] poolCapacity the capacity of pool
+   * @param maxPoolCounts number of pools, last added pool will be removed
+   * @return index of descriptor pool or -1 if unable to create pool
+   */
+  [[nodiscard]] int AddDescriptorPool(uint32_t poolCapacity, uint32_t maxPoolCounts);
+
+  [[nodiscard]] vk::DescriptorSet AllocateDescriptorSet(int poolIndex);
+
 private:
   friend class Program;
 
index 0f50162c774c795d0bf3274aae254f9ee7afd140..d5eda21ea2de1c737498bad52ceccea8ab5f57bd 100644 (file)
@@ -64,9 +64,19 @@ const ProgramCreateInfo& Program::GetCreateInfo() const
   return GetImplementation()->GetCreateInfo();
 }
 
+bool Program::InitializeResource()
+{
+  return true;
+}
+
 void Program::DiscardResource()
 {
   GetController().DiscardResource(this);
 }
 
+void Program::DestroyResource()
+{
+  // nothing to do here
+}
+
 }; // namespace Dali::Graphics::Vulkan
index 041bbe0e38eb22a049cd954dd80251149b794d57..bc19a4264a2eaefd8a6bbbfa9eb22f4eb21bf219 100644 (file)
@@ -28,6 +28,7 @@ namespace Dali::Graphics::Vulkan
 {
 class Reflection;
 class ProgramImpl;
+
 /**
  * @brief Wrapper for the program implementation
  *
@@ -37,7 +38,7 @@ class ProgramImpl;
  * within Graphics API is a set of shader stages linked together
  * so the reflection can do its work on it.
  */
-class Program : public Graphics::Program
+class Program : public Graphics::Program, public Vulkan::ResourceBase
 {
 public:
   /**
@@ -59,7 +60,6 @@ public:
 
   /**
    * @brief Returns reference to the Reflection object
-
    * @return Reflection
    */
   [[nodiscard]] const Vulkan::Reflection& GetReflection() const;
@@ -103,10 +103,15 @@ public:
     return (program.mProgram != mProgram);
   }
 
+  /**
+   * @brief Initialize the resource
+   */
+  bool InitializeResource() override;
+
   /**
    * @brief Run by UniquePtr to discard resource
    */
-  void DiscardResource();
+  void DiscardResource() override;
 
   /**
    * @brief Destroying resources
@@ -114,10 +119,7 @@ public:
    * This function is kept for compatibility with Resource<> class
    * so can the object can be use with templated functions.
    */
-  void DestroyResource()
-  {
-    // nothing to do here
-  }
+  void DestroyResource() override;
 
   bool TryRecycle(const Graphics::ProgramCreateInfo& createInfo, VulkanGraphicsController& controller)
   {
@@ -129,4 +131,4 @@ private:
 };
 } // namespace Dali::Graphics::Vulkan
 
-#endif //DALI_GRAPHICS_VULKAN_PROGRAM_H
+#endif // DALI_GRAPHICS_VULKAN_PROGRAM_H
index 799d7dc44a65ff15de3bfdec3a1a176b32ab0455..57bdd248cf384ad2306cf772ed281f33e9cde7a6 100644 (file)
@@ -53,19 +53,19 @@ inline VertexInputAttributeFormat ToVertexInputAttributeFormat(SpvReflectFormat
     {
       return VertexInputAttributeFormat::FLOAT;
     }
-    //case SPV_REFLECT_FORMAT_R32G32_SINT:{
-    //  return VertexInputAttributeFormat::VEC2
-    //}
+    // case SPV_REFLECT_FORMAT_R32G32_SINT:{
+    //   return VertexInputAttributeFormat::VEC2
+    // }
     case SPV_REFLECT_FORMAT_R32G32_SFLOAT:
     {
       return VertexInputAttributeFormat::VEC2;
     }
-    //case SPV_REFLECT_FORMAT_R32G32B32_SINT:{}
+    // case SPV_REFLECT_FORMAT_R32G32B32_SINT:{}
     case SPV_REFLECT_FORMAT_R32G32B32_SFLOAT:
     {
       return VertexInputAttributeFormat::VEC3;
     }
-    //case SPV_REFLECT_FORMAT_R32G32B32A32_SINT:{};
+    // case SPV_REFLECT_FORMAT_R32G32B32A32_SINT:{};
     case SPV_REFLECT_FORMAT_R32G32B32A32_SFLOAT:
     {
       return VertexInputAttributeFormat::VEC4;
@@ -147,7 +147,8 @@ void Reflection::BuildReflection()
     }
 
     // helper lambda if we need to check more types of pipeline stages in the future
-    auto CheckStageIfDone = [stage](auto expectedStage, auto& variable, const char* stageName) -> StageCheckResult {
+    auto CheckStageIfDone = [stage](auto expectedStage, auto& variable, const char* stageName) -> StageCheckResult
+    {
       if(stage == expectedStage)
       {
         if(!variable)
@@ -270,7 +271,8 @@ void Reflection::BuildReflection()
     {
       mUniformOpaques.insert(mUniformOpaques.end(), samplers.begin(), samplers.end());
       // sort samplers by bindings
-      std::sort(mUniformOpaques.begin(), mUniformOpaques.end(), [](auto& lhs, auto& rhs) { return lhs.binding < rhs.binding; });
+      std::sort(mUniformOpaques.begin(), mUniformOpaques.end(), [](auto& lhs, auto& rhs)
+                { return lhs.binding < rhs.binding; });
       for(auto i = 0u; i < mUniformOpaques.size(); ++i)
       {
         mUniformOpaques[i].location = i;
@@ -309,6 +311,11 @@ vk::PipelineLayout Reflection::GetVkPipelineLayout() const
   return mVkPipelineLayout;
 }
 
+const std::vector<vk::DescriptorSetLayout>& Reflection::GetVkDescriptorSetLayouts() const
+{
+  return mVkDescriptorSetLayoutList;
+}
+
 void Reflection::BuildVertexAttributeReflection(SpvReflectShaderModule* spvModule)
 {
   std::vector<SpvReflectInterfaceVariable*> attrs;
index 4a45aff8e6f09defc22a298231f4a2f6859215b8..b0a194b0b84f88497e066d235fa31afe9be0de12 100644 (file)
@@ -94,7 +94,9 @@ public:
 
   /**
    * @brief Gets the number of uniform blocks in the shader
-   *
+   * Note: GLES implementation generates an emulated block at index 0, so we have
+   * to handle that here. Reduce the count by 1 to get the number of actual uniform
+   * buffers.
    * @return The number of uniform blocks
    */
   [[nodiscard]] uint32_t GetUniformBlockCount() const override;
@@ -206,6 +208,8 @@ public:
 
   vk::PipelineLayout GetVkPipelineLayout() const;
 
+  const std::vector<vk::DescriptorSetLayout>& GetVkDescriptorSetLayouts() const;
+
 protected:
   Reflection(Reflection&&) = default;
   Reflection& operator=(Reflection&&) = default;
@@ -229,7 +233,8 @@ private:
   std::vector<vk::DescriptorSetLayoutCreateInfo>           mVkDescriptorSetLayoutCreateInfoList; ///< List of DSlayout create structures
   std::vector<std::vector<vk::DescriptorSetLayoutBinding>> mVkDescriptorSetLayoutBindingList;
   std::vector<vk::DescriptorSetLayout>                     mVkDescriptorSetLayoutList;
-  vk::PipelineLayout                                       mVkPipelineLayout;
+
+  vk::PipelineLayout mVkPipelineLayout;
 };
 
 } // namespace Vulkan
index 67a6f1f3e6d18cee2847419481f2d65ceab1fd6b..9c5d9a3c3209b6dfa29e18804478c6e76933d44d 100644 (file)
@@ -29,14 +29,13 @@ extern Debug::Filter* gVulkanFilter;
 
 namespace Dali::Graphics::Vulkan
 {
-
-RenderPassImpl* RenderPassImpl::New(
+RenderPassHandle RenderPassImpl::New(
   Vulkan::Device&                            device,
   const std::vector<FramebufferAttachment*>& colorAttachments,
   FramebufferAttachment*                     depthAttachment)
 {
   auto renderPass = new RenderPassImpl(device, colorAttachments, depthAttachment);
-  return renderPass;
+  return RenderPassHandle(renderPass);
 }
 
 RenderPassImpl::RenderPassImpl(Vulkan::Device&                            device,
@@ -50,11 +49,6 @@ RenderPassImpl::RenderPassImpl(Vulkan::Device&                            device
 
 RenderPassImpl::~RenderPassImpl() = default;
 
-vk::RenderPass RenderPassImpl::GetVkHandle()
-{
-  return mVkRenderPass;
-}
-
 bool RenderPassImpl::OnDestroy()
 {
   if(mVkRenderPass)
@@ -62,14 +56,18 @@ bool RenderPassImpl::OnDestroy()
     auto device     = mGraphicsDevice->GetLogicalDevice();
     auto allocator  = &mGraphicsDevice->GetAllocator();
     auto renderPass = mVkRenderPass;
-    mGraphicsDevice->DiscardResource([device, renderPass, allocator]()
-                                     {
-      DALI_LOG_INFO(gVulkanFilter, Debug::General, "Invoking deleter function: swap chain->%p\n", static_cast<VkRenderPass>(renderPass))
-      device.destroyRenderPass(renderPass, allocator); });
+
+    DALI_LOG_INFO(gVulkanFilter, Debug::General, "Destroying render pass: %p\n", static_cast<VkRenderPass>(renderPass));
+    device.destroyRenderPass(renderPass, allocator);
 
     mVkRenderPass = nullptr;
   }
-  return false;
+  return true;
+}
+
+vk::RenderPass RenderPassImpl::GetVkHandle()
+{
+  return mVkRenderPass;
 }
 
 std::vector<vk::ImageView>& RenderPassImpl::GetAttachments()
@@ -173,10 +171,12 @@ void RenderPassImpl::CreateCompatibleCreateInfo(
       .setDstAccessMask(vk::AccessFlagBits::eMemoryRead)
       .setDependencyFlags(vk::DependencyFlagBits::eByRegion)};
 
-  mCreateInfo.createInfo.setAttachmentCount(U32(mCreateInfo.attachmentDescriptions.size()))
+  mCreateInfo.createInfo
+    .setAttachmentCount(U32(mCreateInfo.attachmentDescriptions.size()))
     .setPAttachments(mCreateInfo.attachmentDescriptions.data())
     .setPSubpasses(&mCreateInfo.subpassDesc)
     .setSubpassCount(1)
+    .setDependencyCount(2)
     .setPDependencies(mCreateInfo.subpassDependencies.data());
 }
 
index 612263476dabcfc460b15521cd391b0c5dfb0902..571cffc0a7cbd4764053b816d6857e8b9bd8750b 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include <dali/graphics-api/graphics-render-pass-create-info.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-handle.h>
 #include <dali/internal/graphics/vulkan-impl/vulkan-types.h>
 #include <dali/public-api/common/vector-wrapper.h>
 
@@ -26,6 +27,9 @@ namespace Dali::Graphics::Vulkan
 class Device;
 class VulkanGraphicsController;
 class RenderTarget;
+class RenderPassImpl;
+
+using RenderPassHandle = Handle<class RenderPassImpl>;
 
 /**
  * Holder class for Vulkan RenderPass object.
@@ -41,7 +45,7 @@ class RenderTarget;
  * FramebufferImpl will create a separate compatible RenderPassImpl if a matching
  * render pass is NOT found.
  */
-class RenderPassImpl final : public Dali::Graphics::Vulkan::VkManaged
+class RenderPassImpl : public VkSharedResource
 {
 public:
   struct CreateInfo
@@ -54,19 +58,18 @@ public:
     vk::RenderPassCreateInfo               createInfo;
   };
 
-  static RenderPassImpl* New(
-    Vulkan::Device&                            device,
-    const std::vector<FramebufferAttachment*>& colorAttachments,
-    FramebufferAttachment*                     depthAttachment);
+  static RenderPassHandle New(Vulkan::Device&                            device,
+                              const std::vector<FramebufferAttachment*>& colorAttachments,
+                              FramebufferAttachment*                     depthAttachment);
 
   RenderPassImpl(Vulkan::Device& device, const std::vector<FramebufferAttachment*>& colorAttachments, FramebufferAttachment* depthAttachment);
 
-  ~RenderPassImpl() override;
-
-  vk::RenderPass GetVkHandle();
+  ~RenderPassImpl();
 
   bool OnDestroy() override;
 
+  vk::RenderPass GetVkHandle();
+
   std::vector<vk::ImageView>& GetAttachments();
 
   CreateInfo& GetCreateInfo()
@@ -87,6 +90,7 @@ private:
   vk::RenderPass             mVkRenderPass;
   std::vector<vk::ImageView> mAttachments{};
 };
+
 } // namespace Dali::Graphics::Vulkan
 
 #endif // DALI_INTERNAL_GRAPHICS_VULKAN_RENDER_PASS_IMPL_H
index 822c44dbf9787d64e48fb29ea67728e196c7cf1a..b69c3c4755e715cce38ec903ef1e90347df41539 100644 (file)
  */
 
 // CLASS HEADER
-#include "vulkan-render-target.h"
+#include <dali/internal/graphics/vulkan-impl/vulkan-render-target.h>
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/adaptor-framework/render-surface-interface.h>
-#include "vulkan-framebuffer.h"
-#include "vulkan-graphics-controller.h"
+#include <dali/internal/graphics/vulkan-impl/vulkan-framebuffer-impl.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-framebuffer.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-graphics-controller.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-render-pass.h>
+#include <dali/internal/graphics/vulkan/vulkan-device.h>
+#include <dali/internal/window-system/common/window-render-surface.h>
 
 namespace Dali::Graphics::Vulkan
 {
@@ -63,4 +67,31 @@ Integration::RenderSurfaceInterface* RenderTarget::GetSurface() const
   return mCreateInfo.surface;
 }
 
+Vulkan::FramebufferImpl* RenderTarget::GetCurrentFramebufferImpl() const
+{
+  auto framebuffer = GetFramebuffer();
+  auto surface     = GetSurface();
+
+  FramebufferImpl* fbImpl = nullptr;
+  if(surface)
+  {
+    auto& gfxDevice = mController.GetGraphicsDevice();
+    auto  surfaceId = static_cast<Internal::Adaptor::WindowRenderSurface*>(surface)->GetSurfaceId();
+    auto  swapchain = gfxDevice.GetSwapchainForSurfaceId(surfaceId);
+    fbImpl          = swapchain->GetCurrentFramebuffer();
+  }
+  else if(framebuffer)
+  {
+    fbImpl = framebuffer->GetImpl();
+  }
+  return fbImpl;
+}
+
+Vulkan::RenderPassHandle RenderTarget::GetRenderPass(const Graphics::RenderPass* gfxRenderPass) const
+{
+  auto renderPass      = const_cast<Vulkan::RenderPass*>(static_cast<const Vulkan::RenderPass*>(gfxRenderPass));
+  auto framebufferImpl = GetCurrentFramebufferImpl();
+  return framebufferImpl->GetImplFromRenderPass(renderPass);
+}
+
 } // namespace Dali::Graphics::Vulkan
index 72392b7d8ce0f5a5895c13607687f72c928235a9..f08983e8b5e0993476873b07fed19c5554bfe567 100644 (file)
@@ -23,6 +23,7 @@
 #include <dali/graphics-api/graphics-render-target-create-info.h>
 #include <dali/graphics-api/graphics-render-target.h>
 #include <dali/integration-api/adaptor-framework/render-surface-interface.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-render-pass-impl.h>
 
 namespace Dali::Graphics::Vulkan
 {
@@ -59,6 +60,23 @@ public:
    */
   void DiscardResource() override;
 
+  /**
+   * @copydoc Graphics::Vulkan::Resource::GetAllocationCallbacks()
+   */
+  [[nodiscard]] const Graphics::AllocationCallbacks* GetAllocationCallbacks() const override
+  {
+    return mCreateInfo.allocationCallbacks;
+  }
+
+  /**
+   * @copydoc Graphics::Vulkan::Resource::InvokeDeleter()
+   * Only intended for use by discard queue.
+   */
+  void InvokeDeleter() override
+  {
+    this->~RenderTarget();
+  }
+
   /**
    * @brief Returns framebuffer associated with the render target
    */
@@ -69,12 +87,21 @@ public:
    */
   [[nodiscard]] Integration::RenderSurfaceInterface* GetSurface() const;
 
-  // Get Swapchain?
+  /**
+   * @brief Returns the current framebuffer impl for this frame.
+   * (May be either the swapchain's current fb, or the offscreen's fb).
+   * @return the current framebuffer
+   */
+  [[nodiscard]] Vulkan::FramebufferImpl* GetCurrentFramebufferImpl() const;
 
-private:
-  //  UniquePtr<Swapchain> mSwapchain;
+  /**
+   * Find a matching render pass for this render target
+   * @param[in] renderPass A render pass to search for
+   * @return a matching render pass implementation from the current framebuffer
+   */
+  [[nodiscard]] Vulkan::RenderPassHandle GetRenderPass(const Graphics::RenderPass* renderPass) const;
 };
 
 } // namespace Dali::Graphics::Vulkan
 
-#endif //DALI_INTERNAL_GRAPHICS_VULKAN_RENDER_TARGET_H
+#endif // DALI_INTERNAL_GRAPHICS_VULKAN_RENDER_TARGET_H
index ec81a09e8265f1487fe7e0d739afc961e48c0d36..1d5d30d38ea603b8cb43b96e9faa755424b9f60e 100644 (file)
@@ -76,9 +76,9 @@ struct ResourceTransferRequest
   bool deferredTransferMode{true}; // Vulkan implementation prefers deferred mode
 
   // delete copy
-  ResourceTransferRequest(const ResourceTransferRequest&)            = delete;
+  ResourceTransferRequest(const ResourceTransferRequest&) = delete;
   ResourceTransferRequest& operator=(const ResourceTransferRequest&) = delete;
-  ResourceTransferRequest& operator=(ResourceTransferRequest&& obj)  = delete;
+  ResourceTransferRequest& operator=(ResourceTransferRequest&& obj) = delete;
 
   ResourceTransferRequest(ResourceTransferRequest&& obj)
   {
@@ -97,6 +97,13 @@ struct ResourceTransferRequest
       imageToImageInfo.dstImage = obj.imageToImageInfo.dstImage;
       imageToImageInfo.copyInfo = obj.imageToImageInfo.copyInfo;
     }
+    else if(requestType == TransferRequestType::LAYOUT_TRANSITION_ONLY)
+    {
+      imageLayoutTransitionInfo.image     = obj.imageLayoutTransitionInfo.image;
+      imageLayoutTransitionInfo.srcLayout = obj.imageLayoutTransitionInfo.srcLayout;
+      imageLayoutTransitionInfo.dstLayout = obj.imageLayoutTransitionInfo.dstLayout;
+      deferredTransferMode                = false;
+    }
   }
 };
 
index f35d10048a45fe0a736214a9d964b34544c3f059..b950c3d3e8bab48d9d112a41c316379d1d6e242d 100644 (file)
@@ -39,13 +39,25 @@ SamplerImpl::SamplerImpl(Device& device, const vk::SamplerCreateInfo& samplerCre
 {
 }
 
-SamplerImpl::~SamplerImpl() = default;
+SamplerImpl::~SamplerImpl()
+{
+  Destroy();
+}
 
 void SamplerImpl::Initialize()
 {
   VkAssert(mDevice.GetLogicalDevice().createSampler(&mCreateInfo, &mDevice.GetAllocator("SAMPLER"), &mSampler));
 }
 
+void SamplerImpl::Destroy()
+{
+  if(mSampler)
+  {
+    mDevice.GetLogicalDevice().destroySampler(mSampler);
+    mSampler = nullptr;
+  }
+}
+
 vk::Sampler SamplerImpl::GetVkHandle() const
 {
   return mSampler;
index e8f040e1e2c147d76d5bcad627e51f9387c78831..7028627b0e6d21dd90dc605f7e8a9f848aa17741 100644 (file)
@@ -36,6 +36,8 @@ public:
 
   void Initialize();
 
+  void Destroy();
+
   /**
    * Returns VkSampler object
    * @return
index bf881da610c263b1b77986960de3482971d5bb31..4ad402bb55f00b87d03e7c03e6fcc21e5c53e83d 100644 (file)
 
 // INTERNAL INCLUDES
 #include <dali/internal/graphics/vulkan-impl/vulkan-graphics-controller.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-sampler-impl.h>
 
 namespace Dali::Graphics::Vulkan
 {
+namespace
+{
+constexpr vk::Filter ConvertFilter(Dali::Graphics::SamplerFilter filter)
+{
+  switch(filter)
+  {
+    case Dali::Graphics::SamplerFilter::LINEAR:
+      return vk::Filter::eLinear;
+    case Dali::Graphics::SamplerFilter::NEAREST:
+      return vk::Filter::eNearest;
+  }
+  return vk::Filter{};
+}
+
+constexpr vk::SamplerAddressMode ConvertAddressMode(Dali::Graphics::SamplerAddressMode mode)
+{
+  switch(mode)
+  {
+    case Dali::Graphics::SamplerAddressMode::CLAMP_TO_EDGE:
+      return vk::SamplerAddressMode::eClampToEdge;
+    case Dali::Graphics::SamplerAddressMode::CLAMP_TO_BORDER:
+      return vk::SamplerAddressMode::eClampToBorder;
+    case Dali::Graphics::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE:
+      return vk::SamplerAddressMode::eMirrorClampToEdge;
+    case Dali::Graphics::SamplerAddressMode::MIRRORED_REPEAT:
+      return vk::SamplerAddressMode::eMirroredRepeat;
+    case Dali::Graphics::SamplerAddressMode::REPEAT:
+      return vk::SamplerAddressMode::eRepeat;
+  }
+  return vk::SamplerAddressMode{};
+}
+
+constexpr vk::SamplerMipmapMode ConvertMipmapMode(Dali::Graphics::SamplerMipmapMode mode)
+{
+  switch(mode)
+  {
+    case Dali::Graphics::SamplerMipmapMode::NONE:
+      return vk::SamplerMipmapMode::eNearest;
+    case Dali::Graphics::SamplerMipmapMode::LINEAR:
+      return vk::SamplerMipmapMode::eLinear;
+    case Dali::Graphics::SamplerMipmapMode::NEAREST:
+      return vk::SamplerMipmapMode::eNearest;
+  }
+  return vk::SamplerMipmapMode{};
+}
+
+} // namespace
+
 Sampler::Sampler(const Graphics::SamplerCreateInfo& createInfo, VulkanGraphicsController& controller)
 : SamplerResource(createInfo, controller)
 {
@@ -32,11 +81,32 @@ Sampler::~Sampler() = default;
 
 void Sampler::DestroyResource()
 {
-  // For now, no GPU resources are initialized so nothing to destroy
+  if(mSamplerImpl)
+  {
+    mSamplerImpl->Destroy();
+    mSamplerImpl = nullptr;
+  }
 }
 
 bool Sampler::InitializeResource()
 {
+  vk::SamplerCreateInfo createInfo{};
+  createInfo.setMinFilter(ConvertFilter(mCreateInfo.minFilter))
+    .setMagFilter(ConvertFilter(mCreateInfo.magFilter))
+    .setAddressModeU(ConvertAddressMode(mCreateInfo.addressModeU))
+    .setAddressModeV(ConvertAddressMode(mCreateInfo.addressModeV))
+    .setAddressModeW(ConvertAddressMode(mCreateInfo.addressModeW))
+    .setMipmapMode(ConvertMipmapMode(mCreateInfo.mipMapMode))
+    .setCompareEnable(vk::Bool32(mCreateInfo.compareEnable))
+    .setUnnormalizedCoordinates(vk::Bool32(mCreateInfo.unnormalizeCoordinates))
+    .setBorderColor(vk::BorderColor::eFloatOpaqueBlack)
+    .setAnisotropyEnable(vk::Bool32(mCreateInfo.anisotropyEnable))
+    .setMaxAnisotropy(mCreateInfo.maxAnisotropy)
+    .setMinLod(mCreateInfo.minLod)
+    .setMaxLod(mCreateInfo.maxLod);
+
+  mSamplerImpl = SamplerImpl::New(mController.GetGraphicsDevice(), createInfo);
+
   return true;
 }
 
index d575b050379e9e800e8162e9a07c29662d335fb7..715a66eab4f54fa8a8e388b5790a3dd17cf31d80 100644 (file)
@@ -28,6 +28,7 @@
 namespace Dali::Graphics::Vulkan
 {
 using SamplerResource = Resource<Graphics::Sampler, Graphics::SamplerCreateInfo>;
+class SamplerImpl;
 
 class Sampler : public SamplerResource
 {
@@ -47,7 +48,7 @@ public:
   /**
    * @brief Called when GPU resources are destroyed
    */
-  void DestroyResource();
+  void DestroyResource() override;
 
   /**
    * @brief Called when initializing the resource
@@ -60,6 +61,31 @@ public:
    * @brief Called when UniquePtr<> on client-side dies
    */
   void DiscardResource() override;
+
+  SamplerImpl* GetImpl()
+  {
+    return mSamplerImpl;
+  }
+
+  /**
+   * @copydoc Graphics::Vulkan::Resource::GetAllocationCallbacks()
+   */
+  [[nodiscard]] const Graphics::AllocationCallbacks* GetAllocationCallbacks() const override
+  {
+    return mCreateInfo.allocationCallbacks;
+  }
+
+  /**
+   * @copydoc Graphics::Vulkan::Resource::InvokeDeleter()
+   * Only intended for use by discard queue.
+   */
+  void InvokeDeleter() override
+  {
+    this->~Sampler();
+  }
+
+private:
+  SamplerImpl* mSamplerImpl;
 };
 
 } // namespace Dali::Graphics::Vulkan
index 3ecc55acba45b5fb28ccfa2ccbc815ee34bb5afc..fe89ecdcb62638983881072f21328e876fa626d2 100644 (file)
@@ -163,6 +163,12 @@ uint32_t ShaderImpl::Release()
   return mImpl->refCount;
 }
 
+void ShaderImpl::Destroy()
+{
+  mImpl->Destroy();
+  mImpl.reset();
+}
+
 [[nodiscard]] uint32_t ShaderImpl::IncreaseFlushCount()
 {
   return ++mImpl->flushCount;
index 288dac426bb59b7d7677a147324d1a0f884adc23..06e90c39e0407da69bd24dc201451d927bf50ee7 100644 (file)
@@ -21,7 +21,9 @@
 // INTERNAL INCLUDES
 #include <dali/graphics-api/graphics-shader-create-info.h>
 #include <dali/graphics-api/graphics-shader.h>
-#include <dali/internal/graphics/vulkan-impl/vulkan-graphics-resource.h>
+
+#include <dali/internal/graphics/vulkan-impl/vulkan-graphics-controller.h>
+#include <dali/internal/graphics/vulkan-impl/vulkan-types.h>
 
 // EXTERNAL INCLUDES
 #include <vulkan/vulkan.hpp>
@@ -36,7 +38,7 @@ public:
    * @param[in] createInfo Valid createInfo structure
    * @param[in] controller Reference to the controller
    */
-  ShaderImpl(const Graphics::ShaderCreateInfo& createInfo, Graphics::Vulkan::VulkanGraphicsController& controller);
+  ShaderImpl(const Graphics::ShaderCreateInfo& createInfo, VulkanGraphicsController& controller);
 
   /**
    * @brief destructor
@@ -61,6 +63,11 @@ public:
    */
   [[nodiscard]] uint32_t GetRefCount() const;
 
+  /**
+   * @brief Destroys Vulkan shader module
+   */
+  void Destroy();
+
   /**
    * Whilst unreferenced, increase the flush count and return it
    *
@@ -82,11 +89,6 @@ public:
    */
   [[nodiscard]] bool Compile() const;
 
-  /**
-   * @brief Destroys Vulkan shader module
-   */
-  void Destroy();
-
   /**
    * @brief Returns Vulkan resource
    * @return Valid Vulkan shader resource
index ba41033ad2e138969da75acf452826320090bd52..f98bf8a9896bf5bde40e87ae9bb8d8e516861f37 100644 (file)
@@ -19,8 +19,8 @@
 #include <dali/internal/graphics/vulkan-impl/vulkan-surface-impl.h>
 
 // INTERNAL INCLUDES
-#include <dali/internal/graphics/vulkan/vulkan-device.h>
 #include <dali/integration-api/debug.h>
+#include <dali/internal/graphics/vulkan/vulkan-device.h>
 
 #if defined(DEBUG_ENABLED)
 extern Debug::Filter* gVulkanFilter;
@@ -29,13 +29,30 @@ extern Debug::Filter* gVulkanFilter;
 namespace Dali::Graphics::Vulkan
 {
 
-SurfaceImpl::SurfaceImpl( Device& device, vk::SurfaceKHR surfaceKhr)
-: mGraphicsDevice( device ),
+SurfaceImpl::SurfaceImpl(Device& device, vk::SurfaceKHR surfaceKhr)
+: mGraphicsDevice(device),
   mSurface(surfaceKhr)
 {
 }
 
-SurfaceImpl::~SurfaceImpl() = default;
+SurfaceImpl::~SurfaceImpl()
+{
+  Destroy();
+};
+
+void SurfaceImpl::Destroy()
+{
+  if(mSurface)
+  {
+    auto instance  = mGraphicsDevice.GetInstance();
+    auto surface   = mSurface;
+    auto allocator = &mGraphicsDevice.GetAllocator();
+
+    DALI_LOG_INFO(gVulkanFilter, Debug::General, "Destroying surface: %p\n", static_cast<VkSurfaceKHR>(surface));
+    instance.destroySurfaceKHR(surface, allocator);
+    mSurface = nullptr;
+  }
+}
 
 vk::SurfaceKHR SurfaceImpl::GetVkHandle() const
 {
@@ -54,42 +71,43 @@ vk::SurfaceCapabilitiesKHR& SurfaceImpl::GetCapabilities()
 
 bool SurfaceImpl::GetSupportedFormats(
   vk::SurfaceFormatKHR requestedFormat,
-  vk::Format& swapchainImageFormat,
-  vk::ColorSpaceKHR& swapchainColorSpace)
+  vk::Format&          swapchainImageFormat,
+  vk::ColorSpaceKHR&   swapchainColorSpace)
 {
-  bool found=false;
-  auto supportedFormats = VkAssert( mGraphicsDevice.GetPhysicalDevice().getSurfaceFormatsKHR( mSurface ) );
+  bool found            = false;
+  auto supportedFormats = VkAssert(mGraphicsDevice.GetPhysicalDevice().getSurfaceFormatsKHR(mSurface));
 
   // If the surface format list only includes one entry with VK_FORMAT_UNDEFINED,
   // there is no preferred format, so we assume vk::Format::eB8G8R8A8Unorm
-  if( supportedFormats.size() == 1 && supportedFormats[0].format == vk::Format::eUndefined )
+  if(supportedFormats.size() == 1 && supportedFormats[0].format == vk::Format::eUndefined)
   {
-    swapchainColorSpace = supportedFormats[0].colorSpace;
+    swapchainColorSpace  = supportedFormats[0].colorSpace;
     swapchainImageFormat = vk::Format::eB8G8R8A8Unorm;
   }
   else // Try to find the requested format in the list
   {
     auto iter = std::find_if(supportedFormats.begin(),
                              supportedFormats.end(),
-                             [ & ]( vk::SurfaceFormatKHR supportedFormat ) {
+                             [&](vk::SurfaceFormatKHR supportedFormat)
+                             {
                                return requestedFormat == supportedFormat.format;
-                             } );
+                             });
     // If found assign it.
-    if( iter != supportedFormats.end() )
+    if(iter != supportedFormats.end())
     {
-      found = true;
-      auto surfaceFormat = *iter;
-      swapchainColorSpace = surfaceFormat.colorSpace;
+      found                = true;
+      auto surfaceFormat   = *iter;
+      swapchainColorSpace  = surfaceFormat.colorSpace;
       swapchainImageFormat = surfaceFormat.format;
     }
     else // Requested format not found...attempt to use the first one on the list
     {
-      auto surfaceFormat = supportedFormats[0];
-      swapchainColorSpace = surfaceFormat.colorSpace;
+      auto surfaceFormat   = supportedFormats[0];
+      swapchainColorSpace  = surfaceFormat.colorSpace;
       swapchainImageFormat = surfaceFormat.format;
     }
   }
-  assert( swapchainImageFormat != vk::Format::eUndefined && "Could not find a supported swap chain image format." );
+  assert(swapchainImageFormat != vk::Format::eUndefined && "Could not find a supported swap chain image format.");
   return found;
 }
 
@@ -99,29 +117,10 @@ std::vector<vk::PresentModeKHR> SurfaceImpl::GetSurfacePresentModes()
   return presentModes;
 }
 
-void SurfaceImpl::UpdateSize( unsigned int width, unsigned int height )
+void SurfaceImpl::UpdateSize(unsigned int width, unsigned int height)
 {
-  mCapabilities.currentExtent.width = width;
+  mCapabilities.currentExtent.width  = width;
   mCapabilities.currentExtent.height = height;
 }
 
-bool SurfaceImpl::OnDestroy()
-{
-  if( mSurface )
-  {
-    auto instance = mGraphicsDevice.GetInstance();
-    auto surface = mSurface;
-    auto allocator = &mGraphicsDevice.GetAllocator();
-
-    mGraphicsDevice.DiscardResource( [ instance, surface, allocator ]() {
-      DALI_LOG_INFO( gVulkanFilter, Debug::General, "Invoking deleter function: surface->%p\n",
-                     static_cast< VkSurfaceKHR >( surface ) )
-      instance.destroySurfaceKHR( surface, allocator );
-    } );
-
-    mSurface = nullptr;
-  }
-  return false;
-}
-
 } // namespace Dali::Graphics::Vulkan
index 0542131abbf29a634665a846dd21651bd6ab4652..73744657b025c195ea8e6739c7041a42c20d9602 100644 (file)
@@ -25,12 +25,14 @@ namespace Dali::Graphics::Vulkan
 {
 class Device;
 
-class SurfaceImpl final : public Dali::Graphics::Vulkan::VkManaged
+class SurfaceImpl
 {
 public:
   explicit SurfaceImpl(Device& device, vk::SurfaceKHR surfaceKhr);
 
-  ~SurfaceImpl() final;
+  ~SurfaceImpl();
+
+  void Destroy();
 
   /**
    * @return the handle to this surface
@@ -57,16 +59,14 @@ public:
    */
   bool GetSupportedFormats(
     vk::SurfaceFormatKHR requestedFormat,
-    vk::Format& swapchainImageFormat,
-    vk::ColorSpaceKHR& swapchainColorSpace);
+    vk::Format&          swapchainImageFormat,
+    vk::ColorSpaceKHR&   swapchainColorSpace);
 
   /**
    * Update size of surface
    */
   void UpdateSize(unsigned int width, unsigned int height);
 
-  bool OnDestroy() override;
-
 private:
   Device&                    mGraphicsDevice;
   vk::SurfaceKHR             mSurface;
index 5d72ade4938c9ebab11217a8a1558a04115a1189..42a36deb0d3df7610a9306ff8ba525d95269c364 100644 (file)
@@ -66,7 +66,7 @@ SwapchainBuffer::SwapchainBuffer(Device& graphicsDevice_)
   acquireNextImageSemaphore = graphicsDevice.GetLogicalDevice().createSemaphore({}, graphicsDevice.GetAllocator()).value;
   submitSemaphore           = graphicsDevice.GetLogicalDevice().createSemaphore({}, graphicsDevice.GetAllocator()).value;
 
-  endOfFrameFence.reset(FenceImpl::New(graphicsDevice, {}));
+  endOfFrameFence = FenceImpl::New(graphicsDevice, {});
 }
 
 SwapchainBuffer::~SwapchainBuffer()
@@ -100,7 +100,9 @@ Swapchain::Swapchain(Device& graphicsDevice, Queue& presentationQueue)
 {
 }
 
-Swapchain::~Swapchain() = default;
+Swapchain::~Swapchain()
+{
+}
 
 void Swapchain::CreateVkSwapchain(
   vk::SwapchainKHR   oldSwapchain,
@@ -194,6 +196,22 @@ void Swapchain::CreateVkSwapchain(
   mSwapchainKHR = VkAssert(mGraphicsDevice.GetLogicalDevice().createSwapchainKHR(mSwapchainCreateInfoKHR, mGraphicsDevice.GetAllocator()));
 }
 
+void Swapchain::Destroy()
+{
+  if(mSwapchainKHR)
+  {
+    auto device    = mGraphicsDevice.GetLogicalDevice();
+    auto swapchain = mSwapchainKHR;
+    auto allocator = &mGraphicsDevice.GetAllocator();
+    mFramebuffers.clear();
+    mSwapchainBuffers.clear();
+
+    DALI_LOG_INFO(gVulkanFilter, Debug::General, "Destroying SwapChain: %p\n", static_cast<VkSwapchainKHR>(swapchain));
+    device.destroySwapchainKHR(swapchain, allocator);
+    mSwapchainKHR = nullptr;
+  }
+}
+
 void Swapchain::CreateFramebuffers()
 {
   assert(mSwapchainKHR && "Needs a swapchain before creating framebuffers");
@@ -221,25 +239,41 @@ void Swapchain::CreateFramebuffers()
   //
   // CREATE FRAMEBUFFERS
   //
+  RenderPassHandle compatibleRenderPass{};
   for(auto&& image : images)
   {
     auto colorImage = mGraphicsDevice.CreateImageFromExternal(image,
                                                               mSwapchainCreateInfoKHR.imageFormat,
                                                               mSwapchainCreateInfoKHR.imageExtent);
 
-    auto colorImageView = ImageView::NewFromImage(mGraphicsDevice, *colorImage);
+    std::unique_ptr<ImageView> colorImageView;
+    colorImageView.reset(ImageView::NewFromImage(mGraphicsDevice, *colorImage));
 
     // A new color attachment for each framebuffer
-    auto colorAttachment = FramebufferAttachment::NewColorAttachment(colorImageView,
-                                                                     clearColor,
-                                                                     true); // presentable
-
-    mFramebuffers.push_back(FramebufferImpl::New(mGraphicsDevice,
-                                                 nullptr,
-                                                 {colorAttachment},
-                                                 nullptr,
-                                                 mSwapchainCreateInfoKHR.imageExtent.width,
-                                                 mSwapchainCreateInfoKHR.imageExtent.height));
+    OwnedAttachments attachments;
+    attachments.emplace_back(FramebufferAttachment::NewColorAttachment(colorImageView,
+                                                                       clearColor,
+                                                                       true));
+    std::unique_ptr<FramebufferAttachment>                       depthAttachment;
+    std::unique_ptr<FramebufferImpl, void (*)(FramebufferImpl*)> framebuffer(
+      FramebufferImpl::New(mGraphicsDevice,
+                           compatibleRenderPass,
+                           attachments,
+                           depthAttachment,
+                           mSwapchainCreateInfoKHR.imageExtent.width,
+                           mSwapchainCreateInfoKHR.imageExtent.height),
+      [](FramebufferImpl* framebuffer1)
+      {
+        framebuffer1->Destroy();
+        delete framebuffer1;
+      });
+    mFramebuffers.push_back(std::move(framebuffer));
+
+    if(!compatibleRenderPass)
+    {
+      // use common renderpass for all framebuffers.
+      compatibleRenderPass = mFramebuffers.back()->GetRenderPass(0);
+    }
   }
   mIsValid = true;
 }
@@ -256,7 +290,7 @@ FramebufferImpl* Swapchain::GetCurrentFramebuffer() const
 
 FramebufferImpl* Swapchain::GetFramebuffer(uint32_t index) const
 {
-  return mFramebuffers[index];
+  return mFramebuffers[index].get();
 }
 
 FramebufferImpl* Swapchain::AcquireNextFramebuffer(bool shouldCollectGarbageNow)
@@ -311,8 +345,8 @@ FramebufferImpl* Swapchain::AcquireNextFramebuffer(bool shouldCollectGarbageNow)
   // cause a stall ( nvidia, ubuntu )
   if(mFrameCounter >= mSwapchainBuffers.size())
   {
-    vk::Result result = swapchainBuffer->endOfFrameFence->GetStatus();
-    if(result == vk::Result::eNotReady)
+    vk::Result status = swapchainBuffer->endOfFrameFence->GetStatus();
+    if(status == vk::Result::eNotReady)
     {
       swapchainBuffer->endOfFrameFence->Wait();
       swapchainBuffer->endOfFrameFence->Reset();
@@ -324,7 +358,7 @@ FramebufferImpl* Swapchain::AcquireNextFramebuffer(bool shouldCollectGarbageNow)
   }
   // mGraphicsDevice.CollectGarbage();
 
-  return mFramebuffers[mSwapchainImageIndex];
+  return mFramebuffers[mSwapchainImageIndex].get();
 }
 
 void Swapchain::Submit(CommandBufferImpl* commandBuffer)
@@ -339,7 +373,7 @@ void Swapchain::Submit(CommandBufferImpl* commandBuffer)
   mGraphicsDevice.Submit(*mQueue,
                          {Vulkan::SubmissionData{
                            {swapchainBuffer->acquireNextImageSemaphore},
-                           {},
+                           {vk::PipelineStageFlagBits::eFragmentShader},
                            {commandBuffer},
                            {swapchainBuffer->submitSemaphore}}},
                          swapchainBuffer->endOfFrameFence.get());
@@ -383,24 +417,6 @@ void Swapchain::Present()
   mFrameCounter++;
 }
 
-bool Swapchain::OnDestroy()
-{
-  if(mSwapchainKHR)
-  {
-    auto device    = mGraphicsDevice.GetLogicalDevice();
-    auto swapchain = mSwapchainKHR;
-    auto allocator = &mGraphicsDevice.GetAllocator();
-
-    mGraphicsDevice.DiscardResource([device, swapchain, allocator]()
-                                    {
-      DALI_LOG_INFO(gVulkanFilter, Debug::General, "Invoking deleter function: swap chain->%p\n", static_cast<VkSwapchainKHR>(swapchain))
-      device.destroySwapchainKHR(swapchain, allocator); });
-
-    mSwapchainKHR = nullptr;
-  }
-  return false;
-}
-
 bool Swapchain::IsValid() const
 {
   return mIsValid;
index aacaa7327b28464a1dfc595382780606e16668d9..92380475f2c581cf6111dada6126880de50ceaf5 100644 (file)
@@ -33,7 +33,7 @@ class SwapchainBuffer;
 /**
  * Creates swapchain for given surface and queue
  */
-class Swapchain : public VkManaged
+class Swapchain
 {
 public:
   static Swapchain* NewSwapchain(
@@ -47,11 +47,13 @@ public:
 
   Swapchain(Device& graphicsDevice, Queue& presentationQueue);
 
-  ~Swapchain() override;
+  ~Swapchain();
 
   Swapchain(const Swapchain&)            = delete;
   Swapchain& operator=(const Swapchain&) = delete;
 
+  void Destroy();
+
   /**
    * Automatically create framebuffers (generating compatible render passes)
    */
@@ -94,8 +96,6 @@ public:
    */
   void Present();
 
-  bool OnDestroy() override;
-
   /**
    * Returns true when swapchain expired
    * @return
@@ -143,16 +143,14 @@ private:
   /**
    * FramebufferImpl object associated with the buffer
    */
-  std::vector<FramebufferImpl*> mFramebuffers;
+  using OwnedFramebuffer = std::unique_ptr<FramebufferImpl, void (*)(FramebufferImpl*)>;
+  std::vector<OwnedFramebuffer> mFramebuffers;
 
   /**
    * Array of swapchain buffers
    */
   std::vector<std::unique_ptr<SwapchainBuffer>> mSwapchainBuffers;
-
-  FenceImpl* mBetweenRenderPassFence{};
-
-  uint32_t mFrameCounter{0u}; ///< Current frame number
+  uint32_t                                      mFrameCounter{0u}; ///< Current frame number
 
   bool mIsValid; // indicates whether the swapchain is still valid or requires to be recreated
 };
index f912f9537f59b062e9234a0ef3618a76141ccb83..2121f0b6868cb4119bcc9e9c63400417c92ae5f5 100644 (file)
@@ -1080,6 +1080,15 @@ void Texture::CopyMemoryDirect(
     // ...and flush
     memory->Flush();
   }
+
+  ResourceTransferRequest transferRequest(TransferRequestType::LAYOUT_TRANSITION_ONLY);
+  transferRequest.imageLayoutTransitionInfo.image     = mImage;
+  transferRequest.imageLayoutTransitionInfo.srcLayout = mImage->GetImageLayout();
+  transferRequest.imageLayoutTransitionInfo.dstLayout = vk::ImageLayout::eShaderReadOnlyOptimal;
+  transferRequest.deferredTransferMode                = false;
+
+  // schedule transfer
+  mController.ScheduleResourceTransfer(std::move(transferRequest));
 }
 
 vk::Format Texture::ValidateFormat(vk::Format sourceFormat)
@@ -1154,10 +1163,26 @@ bool Texture::InitializeResource()
 
 void Texture::DestroyResource()
 {
+  if(mImageView)
+  {
+    mImageView->Destroy();
+    mImageView = nullptr;
+  }
+  if(mImage)
+  {
+    mImage->Destroy();
+    mImage = nullptr;
+  }
+  if(mSampler)
+  {
+    mSampler->Destroy();
+    mSampler = nullptr;
+  }
 }
 
 void Texture::DiscardResource()
 {
+  mController.DiscardResource(this);
 }
 
 void Texture::SetFormatAndUsage()
index b64f977554fd0baa56ab6e23c9bcc1d343bdfcb5..d3d16beace846098cacd5b3db435ada5db91b804 100644 (file)
@@ -42,11 +42,36 @@ public:
   Texture(const Graphics::TextureCreateInfo& createInfo, VulkanGraphicsController& controller);
   ~Texture();
 
+  /**
+   * @copydoc Graphics::Vulkan::Resource::InitializeResource();
+   */
   bool InitializeResource() override;
 
+  /**
+   * @copydoc Graphics::Vulkan::Resource::DiscardResource();
+   */
+  void DiscardResource() override;
+  /**
+   * @copydoc Graphics::Vulkan::Resource::DestroyResource();
+   */
   void DestroyResource() override;
 
-  void DiscardResource() override;
+  /**
+   * @copydoc Graphics::Vulkan::Resource::GetAllocationCallbacks()
+   */
+  [[nodiscard]] const Graphics::AllocationCallbacks* GetAllocationCallbacks() const override
+  {
+    return mCreateInfo.allocationCallbacks;
+  }
+
+  /**
+   * @copydoc Graphics::Vulkan::Resource::InvokeDeleter()
+   * Only intended for use by discard queue.
+   */
+  void InvokeDeleter() override
+  {
+    this->~Texture();
+  }
 
   bool IsSamplerImmutable() const;
 
index 5d9b1e0b7273efd83ae88596ff673f1d72d0492c..c4dd38219f1ae2ce404a9a4a934f28c08b298b10 100644 (file)
@@ -35,7 +35,6 @@
 
 namespace Dali::Graphics
 {
-
 namespace
 {
 // Default value use to clear the stencil buffer
@@ -50,7 +49,6 @@ std::unique_ptr<T> MakeUnique(Args&&... args)
 
 namespace Vulkan
 {
-
 /**
  * Forward class declarations
  */
@@ -194,59 +192,6 @@ struct VkStoreOpType
   vk::AttachmentStoreOp storeOp{vk::AttachmentStoreOp::eDontCare};
 };
 
-class VkManaged
-{
-public:
-  VkManaged() = default;
-
-  virtual ~VkManaged() = default;
-
-  void Release()
-  {
-    OnRelease(--mRefCount);
-
-    if(mRefCount == 0)
-    {
-      // orphaned
-      if(!Destroy())
-      {
-        delete this;
-      }
-    }
-  }
-
-  void Retain()
-  {
-    OnRetain(++mRefCount);
-  }
-
-  uint32_t GetRefCount()
-  {
-    return mRefCount;
-  }
-
-  virtual bool Destroy()
-  {
-    return OnDestroy();
-  }
-
-  virtual void OnRetain(uint32_t refcount)
-  {
-  }
-
-  virtual void OnRelease(uint32_t refcount)
-  {
-  }
-
-  virtual bool OnDestroy()
-  {
-    return false;
-  }
-
-private:
-  std::atomic_uint mRefCount{0u};
-};
-
 } // namespace Vulkan
 } // namespace Dali::Graphics
 
index 68e9f89ee3dd7160bfcdf67c73fe9b6f60887692..5065b96687118a1941fc40128714b3afbe038b72 100644 (file)
@@ -95,6 +95,7 @@ Device::~Device()
   DALI_LOG_STREAM(gVulkanFilter, Debug::General, "DESTROYING GRAPHICS CONTEXT--------------------------------\n");
 
   SwapBuffers();
+  ReleaseCommandPools();
 
   // We are done with all resources (technically... . If not we will get a ton of validation layer errors)
   // Kill the Vulkan logical device
@@ -107,18 +108,21 @@ Device::~Device()
 // Create methods -----------------------------------------------------------------------------------------------
 void Device::Create()
 {
-  auto extensions = PrepareDefaultInstanceExtensions();
-  auto layers     = vk::enumerateInstanceLayerProperties();
+  auto extensions     = PrepareDefaultInstanceExtensions();
+  auto instanceLayers = vk::enumerateInstanceLayerProperties();
 
   std::vector<const char*> validationLayers;
-  for(auto&& reqLayer : reqLayers)
+  if(!instanceLayers.value.empty())
   {
-    for(auto&& prop : layers.value)
+    for(auto&& prop : instanceLayers.value)
     {
       DALI_LOG_STREAM(gVulkanFilter, Debug::General, prop.layerName);
-      if(std::string(prop.layerName) == reqLayer)
+      for(auto&& reqLayer : reqLayers)
       {
-        validationLayers.push_back(reqLayer);
+        if(std::string(prop.layerName) == reqLayer)
+        {
+          validationLayers.push_back(reqLayer);
+        }
       }
     }
   }
@@ -376,7 +380,8 @@ Swapchain* Device::CreateSwapchain(SurfaceImpl*       surface,
     // during replacing the swapchain
     auto khr = oldSwapchain->GetVkHandle();
     oldSwapchain->SetVkHandle(nullptr);
-    oldSwapchain->Release();
+    oldSwapchain->Destroy();
+    delete oldSwapchain;
 
     mLogicalDevice.destroySwapchainKHR(khr, *mAllocator);
   }
@@ -434,8 +439,8 @@ Queue& Device::GetPresentQueue() const
 
 void Device::DiscardResource(std::function<void()> deleter)
 {
-  // std::lock_guard< std::mutex > lock( mMutex );
-  // mDiscardQueue[mCurrentBufferIndex].push_back( std::move( deleter ) );
+  // For now, just call immediately.
+  deleter();
 }
 
 Image* Device::CreateImageFromExternal(vk::Image externalImage, vk::Format imageFormat, vk::Extent2D extent)
@@ -540,6 +545,15 @@ CommandPool* Device::GetCommandPool(std::thread::id threadId)
   return commandPool;
 }
 
+void Device::ReleaseCommandPools()
+{
+  for(auto& commandPool : mCommandPools)
+  {
+    commandPool.second->Reset(true);
+    delete commandPool.second;
+  }
+}
+
 void Device::SurfaceResized(unsigned int width, unsigned int height)
 {
   // Get main window's surface
@@ -561,6 +575,7 @@ void Device::SurfaceResized(unsigned int width, unsigned int height)
 
 uint32_t Device::SwapBuffers()
 {
+  DeviceWaitIdle();
   mCurrentBufferIndex = (mCurrentBufferIndex + 1) & 1;
   return mCurrentBufferIndex;
 }
index 3742807fd8f1bd185c40dc6ca1673374feb5d38b..e40de4b167594800420faee06884ba3b6dcf5918 100644 (file)
@@ -153,6 +153,8 @@ private: // Methods
 
   std::vector<const char*> PrepareDefaultInstanceExtensions();
 
+  void ReleaseCommandPools();
+
 private: // Members
   vk::PhysicalDevice mPhysicalDevice;
   vk::Device         mLogicalDevice;
@@ -166,10 +168,10 @@ private: // Members
   std::vector<vk::QueueFamilyProperties> mQueueFamilyProperties;
 
   // Sets of queues
-  std::vector<std::unique_ptr<Queue> > mAllQueues;
-  std::vector<Queue*>                  mGraphicsQueues;
-  std::vector<Queue*>                  mTransferQueues;
-  std::vector<Queue*>                  mComputeQueues;
+  std::vector<std::unique_ptr<Queue>> mAllQueues;
+  std::vector<Queue*>                 mGraphicsQueues;
+  std::vector<Queue*>                 mTransferQueues;
+  std::vector<Queue*>                 mComputeQueues;
 
   CommandPoolMap mCommandPools;
 
index 8784003d8117324354f6b5d27b1e4cf63c925771..e9680d745ce033bb9bfa51f7bfefec13df6f69b1 100644 (file)
@@ -98,9 +98,9 @@ Graphics::SurfaceId VulkanGraphics::CreateSurface(
   return surfaceId;
 }
 
-void VulkanGraphics::DestroySurface(Graphics::SurfaceId)
+void VulkanGraphics::DestroySurface(Graphics::SurfaceId surfaceId)
 {
-  // @todo Destroy swapchain.
+  mGraphicsDevice.DestroySurface(surfaceId);
 }
 
 bool VulkanGraphics::ReplaceSurface(Graphics::SurfaceId surface, int width, int height)
@@ -123,6 +123,7 @@ void VulkanGraphics::MakeContextCurrent(Graphics::SurfaceId surfaceId)
 
 void VulkanGraphics::PostRender()
 {
+  mGraphicsDevice.SwapBuffers();
 }
 
 void VulkanGraphics::Shutdown()
@@ -131,6 +132,7 @@ void VulkanGraphics::Shutdown()
 
 void VulkanGraphics::Destroy()
 {
+  mGraphicsController.RunGarbageCollector(0);
 }
 
 void VulkanGraphics::Pause()
index d33b48b6217746835488a87beda3f8d4e9d6c70b..35208cc2913f4f542aa22b1076d5fa7a0d0b25ed 100644 (file)
@@ -466,25 +466,25 @@ ImageDimensions CalculateDesiredDimensions(uint32_t bitmapWidth, uint32_t bitmap
   // If both dimensions have values requested, use them both:
   if(requestedWidth != 0 && requestedHeight != 0)
   {
-    DALI_ASSERT_DEBUG( (bitmapWidth > 0 && bitmapHeight > 0) && "Bitmap dimensions are zero");
+    DALI_ASSERT_DEBUG((bitmapWidth > 0 && bitmapHeight > 0) && "Bitmap dimensions are zero");
 
     if(fittingMode == FittingMode::VISUAL_FITTING)
     {
       uint32_t adjustedDesiredWidth, adjustedDesiredHeight;
-      float aspectOfDesiredSize = (float)requestedHeight / (float)requestedWidth;
-      float aspectOfImageSize = (float)bitmapHeight / (float)bitmapWidth;
-      if (aspectOfImageSize > aspectOfDesiredSize)
+      float    aspectOfDesiredSize = (float)requestedHeight / (float)requestedWidth;
+      float    aspectOfImageSize   = (float)bitmapHeight / (float)bitmapWidth;
+      if(aspectOfImageSize > aspectOfDesiredSize)
       {
-        adjustedDesiredWidth = requestedWidth;
-        adjustedDesiredHeight = static_cast<uint64_t>(bitmapHeight) * requestedWidth / bitmapWidth;
+        adjustedDesiredWidth  = requestedWidth;
+        adjustedDesiredHeight = (static_cast<uint64_t>(bitmapHeight) * requestedWidth + bitmapWidth / 2) / bitmapWidth; ///< round up
       }
       else
       {
-        adjustedDesiredWidth = static_cast<uint64_t>(bitmapWidth) * requestedHeight / bitmapHeight;
+        adjustedDesiredWidth  = (static_cast<uint64_t>(bitmapWidth) * requestedHeight + bitmapHeight / 2) / bitmapHeight; ///< round up
         adjustedDesiredHeight = requestedHeight;
       }
 
-      requestedWidth = adjustedDesiredWidth;
+      requestedWidth  = adjustedDesiredWidth;
       requestedHeight = adjustedDesiredHeight;
     }
 
@@ -1173,6 +1173,7 @@ Dali::Devel::PixelBuffer DownscaleBitmap(Dali::Devel::PixelBuffer bitmap,
     if(filteredWidth < shrunkWidth || filteredHeight < shrunkHeight)
     {
       if(samplingMode == SamplingMode::LINEAR || samplingMode == SamplingMode::BOX_THEN_LINEAR ||
+         samplingMode == SamplingMode::LANCZOS || samplingMode == SamplingMode::BOX_THEN_LANCZOS ||
          samplingMode == SamplingMode::NEAREST || samplingMode == SamplingMode::BOX_THEN_NEAREST)
       {
         outputBitmap = Dali::Devel::PixelBuffer::New(filteredWidth, filteredHeight, pixelFormat);
@@ -1183,6 +1184,10 @@ Dali::Devel::PixelBuffer DownscaleBitmap(Dali::Devel::PixelBuffer bitmap,
           {
             LinearSample(bitmap.GetBuffer(), ImageDimensions(shrunkWidth, shrunkHeight), outStride, pixelFormat, outputBitmap.GetBuffer(), filteredDimensions);
           }
+          else if(samplingMode == SamplingMode::LANCZOS || samplingMode == SamplingMode::BOX_THEN_LANCZOS)
+          {
+            LanczosSample(bitmap.GetBuffer(), ImageDimensions(shrunkWidth, shrunkHeight), outStride, pixelFormat, outputBitmap.GetBuffer(), filteredDimensions);
+          }
           else
           {
             PointSample(bitmap.GetBuffer(), shrunkWidth, shrunkHeight, outStride, pixelFormat, outputBitmap.GetBuffer(), filteredWidth, filteredHeight);
@@ -1660,7 +1665,7 @@ void DownscaleInPlacePow2(uint8_t* const     pixels,
   outHeight = inputHeight;
   outStride = inputStride;
   // Perform power of 2 iterated 4:1 box filtering if the requested filter mode requires it:
-  if(samplingMode == SamplingMode::BOX || samplingMode == SamplingMode::BOX_THEN_NEAREST || samplingMode == SamplingMode::BOX_THEN_LINEAR)
+  if(samplingMode == SamplingMode::BOX || samplingMode == SamplingMode::BOX_THEN_NEAREST || samplingMode == SamplingMode::BOX_THEN_LINEAR || samplingMode == SamplingMode::BOX_THEN_LANCZOS)
   {
     // Check the pixel format is one that is supported:
     if(pixelFormat == Pixel::RGBA8888 || pixelFormat == Pixel::RGB888 || pixelFormat == Pixel::RGB565 || pixelFormat == Pixel::LA88 || pixelFormat == Pixel::L8 || pixelFormat == Pixel::A8 || pixelFormat == Pixel::CHROMINANCE_U || pixelFormat == Pixel::CHROMINANCE_V)
@@ -2411,6 +2416,15 @@ void LanczosSample4BPP(const uint8_t* __restrict__ inPixels,
   Resample(inPixels, inputDimensions, inputStride, outPixels, desiredDimensions, Resampler::LANCZOS4, 4, true);
 }
 
+void LanczosSample3BPP(const uint8_t* __restrict__ inPixels,
+                       ImageDimensions inputDimensions,
+                       uint32_t        inputStride,
+                       uint8_t* __restrict__ outPixels,
+                       ImageDimensions desiredDimensions)
+{
+  Resample(inPixels, inputDimensions, inputStride, outPixels, desiredDimensions, Resampler::LANCZOS4, 3, false);
+}
+
 void LanczosSample1BPP(const uint8_t* __restrict__ inPixels,
                        ImageDimensions inputDimensions,
                        uint32_t        inputStride,
@@ -2429,11 +2443,19 @@ void LanczosSample(const uint8_t* __restrict__ inPixels,
                    uint8_t* __restrict__ outPixels,
                    ImageDimensions outDimensions)
 {
+  // TODO : Need to support LanczosSample various pixel format.
+  // Until now, just use LinearSample instead.
+  //
   // Check the pixel format is one that is supported:
-  if(pixelFormat == Pixel::RGBA8888 || pixelFormat == Pixel::BGRA8888 || pixelFormat == Pixel::L8 || pixelFormat == Pixel::A8)
+  if(pixelFormat == Pixel::RGB888 || pixelFormat == Pixel::RGBA8888 || pixelFormat == Pixel::BGRA8888 || pixelFormat == Pixel::L8 || pixelFormat == Pixel::A8)
   {
     switch(pixelFormat)
     {
+      case Pixel::RGB888:
+      {
+        LanczosSample3BPP(inPixels, inDimensions, inStride, outPixels, outDimensions);
+        break;
+      }
       case Pixel::RGBA8888:
       case Pixel::BGRA8888:
       {
@@ -2454,6 +2476,7 @@ void LanczosSample(const uint8_t* __restrict__ inPixels,
   }
   else
   {
+    LinearSample(inPixels, inDimensions, inStride, pixelFormat, outPixels, outDimensions);
     DALI_LOG_INFO(gImageOpsLogFilter, Dali::Integration::Log::Verbose, "Bitmap was not lanczos sampled: unsupported pixel format: %u.\n", static_cast<uint32_t>(pixelFormat));
   }
 }
index 6cf24cea997dd3826be238cf1f41e448eee5b5e3..1a1d5ab7654208eea99bc6470ae6a08e3babc11a 100644 (file)
@@ -1206,6 +1206,7 @@ bool TransformSize(int requiredWidth, int requiredHeight, FittingMode::Type fitt
       case SamplingMode::BOX:
       case SamplingMode::BOX_THEN_NEAREST:
       case SamplingMode::BOX_THEN_LINEAR:
+      case SamplingMode::BOX_THEN_LANCZOS:
       case SamplingMode::DONT_CARE:
       {
         useTurboJpegScaleFactor = true;
@@ -1214,6 +1215,7 @@ bool TransformSize(int requiredWidth, int requiredHeight, FittingMode::Type fitt
       case SamplingMode::NO_FILTER:
       case SamplingMode::NEAREST:
       case SamplingMode::LINEAR:
+      case SamplingMode::LANCZOS:
       {
         useTurboJpegScaleFactor = false;
         break;
index 79406420b9d5a53ed744aa9fb7c96eb0c40c0d63..9bc6533f5d3e5d6d3b90d50832ca526c2d104e37 100644 (file)
@@ -48,9 +48,17 @@ namespace Adaptor
 {
 namespace // unnamed namespace
 {
+static constexpr int32_t USE_ENVIRONMENT_VALUE = -1;
+static constexpr int32_t USE_CHROMIUM_WEB_ENGINE = 0;
+static constexpr int32_t USE_LIGHT_WEIGHT_WEB_ENGINE = 1;
+static constexpr int32_t DEFAULT_WEB_ENGINE_PLUGIN_TYPE = USE_ENVIRONMENT_VALUE;
+static int32_t webEnginePluginType = DEFAULT_WEB_ENGINE_PLUGIN_TYPE;
+
 constexpr char const* const kPluginFullNamePrefix  = "libdali2-web-engine-";
 constexpr char const* const kPluginFullNamePostfix = "-plugin.so";
 constexpr char const* const kPluginFullNameDefault = "libdali2-web-engine-plugin.so";
+constexpr char const* const kPluginFullNameChromium = "libdali2-web-engine-chromium-plugin.so";
+constexpr char const* const kPluginFullNameLwe = "libdali2-web-engine-lwe-plugin.so";
 
 std::string MakePluginName(const char* environmentName)
 {
@@ -143,14 +151,26 @@ private:
     mGetWebEngineCookieManagerPtr{nullptr}
   {
     std::string pluginName;
-    const char* name = EnvironmentVariable::GetEnvironmentVariable(DALI_ENV_WEB_ENGINE_NAME);
-    if(name)
+
+    if(webEnginePluginType == USE_CHROMIUM_WEB_ENGINE)
+    {
+      pluginName = kPluginFullNameChromium;
+    }
+    else if(webEnginePluginType == USE_LIGHT_WEIGHT_WEB_ENGINE)
     {
-      pluginName = MakePluginName(name);
+      pluginName = kPluginFullNameLwe;
     }
     else
     {
-      pluginName = std::string(kPluginFullNameDefault);
+      const char* name = EnvironmentVariable::GetEnvironmentVariable(DALI_ENV_WEB_ENGINE_NAME);
+      if(name)
+      {
+        pluginName = MakePluginName(name);
+      }
+      else
+      {
+        pluginName = std::string(kPluginFullNameDefault);
+      }
     }
 
     mHandle = dlopen(pluginName.c_str(), RTLD_LAZY);
@@ -212,9 +232,9 @@ public:
 
 } // unnamed namespace
 
-WebEnginePtr WebEngine::New()
+WebEnginePtr WebEngine::New(int32_t type)
 {
-  WebEngine* instance = new WebEngine();
+  WebEngine* instance = new WebEngine(type);
   if(!instance->Initialize())
   {
     delete instance;
@@ -254,9 +274,10 @@ Dali::WebEngineCookieManager* WebEngine::GetCookieManager()
   return nullptr;
 }
 
-WebEngine::WebEngine()
+WebEngine::WebEngine(int32_t type)
 : mPlugin(nullptr)
 {
+  webEnginePluginType = type;
 }
 
 WebEngine::~WebEngine()
@@ -815,6 +836,27 @@ void WebEngine::GetPlainTextAsynchronously(Dali::WebEnginePlugin::PlainTextRecei
   mPlugin->GetPlainTextAsynchronously(callback);
 }
 
+void WebEngine::WebAuthenticationCancel()
+{
+  mPlugin->WebAuthenticationCancel();
+}
+
+void WebEngine::RegisterWebAuthDisplayQRCallback(Dali::WebEnginePlugin::WebEngineWebAuthDisplayQRCallback callback)
+{
+  mPlugin->RegisterWebAuthDisplayQRCallback(callback);
+}
+
+void WebEngine::RegisterWebAuthResponseCallback(Dali::WebEnginePlugin::WebEngineWebAuthResponseCallback callback)
+{
+  mPlugin->RegisterWebAuthResponseCallback(callback);
+}
+
+void WebEngine::RegisterUserMediaPermissionRequestCallback(Dali::WebEnginePlugin::WebEngineUserMediaPermissionRequestCallback callback)
+{
+  mPlugin->RegisterUserMediaPermissionRequestCallback(callback);
+}
+
+
 } // namespace Adaptor
 } // namespace Internal
 } // namespace Dali
index 3e18f8d9f3f398b9474f7abe323fc0fbd40a5004..e557e69cbab4260749343458430fffa6929688e8 100755 (executable)
@@ -49,11 +49,11 @@ class WebEngine : public Dali::BaseObject
 {
 public:
   /**
-   * @brief Create a new WebEngine handle
-   *
+   * @brief Create a new WebEngine handle with type (0: Chromium, 1: LWE, otherwise: depend on system environment).
+   * @param[in] type The WebEngine type (0: Chromium, 1: LWE, otherwise: depend on system environment).
    * @return WebEngine pointer
    */
-  static WebEnginePtr New();
+  static WebEnginePtr New(int32_t type);
 
   /**
    * @brief Get context of web engine
@@ -592,11 +592,31 @@ public:
    */
   void GetPlainTextAsynchronously(Dali::WebEnginePlugin::PlainTextReceivedCallback callback);
 
+  /**
+   * @copydoc Dali::WebEngine::WebAuthenticationCancel()
+   */
+  void WebAuthenticationCancel();
+
+  /**
+   * @copydoc Dali::WebEngine::RegisterWebAuthDisplayQRCallback()
+   */
+  void RegisterWebAuthDisplayQRCallback(Dali::WebEnginePlugin::WebEngineWebAuthDisplayQRCallback callback);
+
+  /**
+   * @copydoc Dali::WebEngine::RegisterWebAuthResponseCallback()
+   */
+  void RegisterWebAuthResponseCallback(Dali::WebEnginePlugin::WebEngineWebAuthResponseCallback callback);
+
+  /**
+   * @copydoc Dali::WebEngine::RegisterUserMediaPermissionRequestCallback()
+   */
+  void RegisterUserMediaPermissionRequestCallback(Dali::WebEnginePlugin::WebEngineUserMediaPermissionRequestCallback callback);
+
 private:
   /**
-   * @brief Constructor.
+   * @brief Constructor with WebEngine type (0: Chromium, 1: LWE, otherwise: depend on system environment).
    */
-  WebEngine();
+  WebEngine(int32_t type);
 
   /**
    * @brief Destructor.
index 82df35f5657ba0033250244d73d161bd37dc8463..cb9aea66de4ac545a3ad3245995ae8fd0ee7522c 100644 (file)
@@ -516,6 +516,15 @@ bool WindowBaseAndroid::IsAlwaysOnTop()
   return false;
 }
 
+void WindowBaseAndroid::SetBottom(bool enable)
+{
+}
+
+bool WindowBaseAndroid::IsBottom()
+{
+  return false;
+}
+
 Any WindowBaseAndroid::GetNativeBuffer() const
 {
   return 0;
@@ -540,6 +549,15 @@ int WindowBaseAndroid::GetBackgroundBlur()
   return 0;
 }
 
+void WindowBaseAndroid::SetBehindBlur(int blurRadius)
+{
+}
+
+int WindowBaseAndroid::GetBehindBlur()
+{
+  return 0;
+}
+
 } // namespace Adaptor
 
 } // namespace Internal
index 83ce26b0cf21a2e284ca96f1a82bc7b69c267a91..a7ffb96ba52d9e6bc3fd79f118fc720ea5bfbfa6 100644 (file)
@@ -539,6 +539,16 @@ public:
    */
   bool IsAlwaysOnTop() override;
 
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::SetBottom()
+   */
+  void SetBottom(bool enable) override;
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::IsBottom()
+   */
+  bool IsBottom() override;
+
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetNativeBuffer()
    */
@@ -554,17 +564,26 @@ public:
    */
   bool RelativeMotionUnGrab() override;
 
-/**
+  /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::SetBackgroundBlur()
    */
   void SetBackgroundBlur(int blurRadius, int cornerRadius) override;
 
-
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetBackgroundBlur()
    */
   int GetBackgroundBlur() override;
 
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::SetBehindBlur()
+   */
+  void SetBehindBlur(int blurRadius) override;
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::GetBehindBlur()
+   */
+  int GetBehindBlur() override;
+
 private:
   /**
    * Second stage initialization
index 2a6eff8e084847c86157a548e9bca019fa36f618..5afb0848aaeca3ba158dae43d94d80f60d85369e 100644 (file)
@@ -582,6 +582,9 @@ public:
   /**
    * @brief Enables or disables the window always is on top.
    *
+   * This is valid between windows that have no notification level or a notification level of 'none'.
+   * If it has a notification level, this will not do anything.
+   *
    * @param[in] alwaysOnTop true to enable the window always is on top, false to disable.
    */
   virtual void SetAlwaysOnTop(bool alwaysOnTop) = 0;
@@ -593,6 +596,24 @@ public:
    */
   virtual bool IsAlwaysOnTop() = 0;
 
+  /**
+   * @brief Enables or disables the window's layer is changed to bottom.
+   *
+   * If the enable flag is true, this window will be placed below other windows.
+   * Otherwise, if it's called with a false value, it will be located above other windows.
+   *
+   * @param[in] window The window instance.
+   * @param[in] enable true to change the window layer to the bottom.
+   */
+  virtual void SetBottom(bool enable) = 0;
+
+  /**
+   * @brief Returns whether the window layer is the bottom or not.
+   *
+   * @return True if the window layer is the bottom, false otherwise.
+   */
+  virtual bool IsBottom() = 0;
+
   /**
    * @brief Get native buffer of window.
    * @return The native window buffer handle
@@ -617,8 +638,8 @@ public:
    * @brief Set the window's background blur.
    * If this value is 0, the background blur is disabled.
    *
-   * @param[in] blurRadius the background blur.
-   * @param[in] cornerRadius the background blur.
+   * @param[in] blurRadius The radius of the blur effect.
+   * @param[in] cornerRadius The radius of the corner radius.
    */
   virtual void SetBackgroundBlur(int blurRadius, int cornerRadius) = 0;
 
@@ -630,6 +651,22 @@ public:
    */
   virtual int GetBackgroundBlur() = 0;
 
+  /**
+   * @brief Set the window's behind blur.
+   * If this value is 0, the behind blur is disabled.
+   *
+   * @param[in] blurRadius The radius of the blur effect.
+   */
+  virtual void SetBehindBlur(int blurRadius) = 0;
+
+  /**
+   * @brief Returns current behind blur.
+   * If this value is 0, behind blur is disabled.
+   *
+   * @return current behind blur.
+   */
+  virtual int GetBehindBlur() = 0;
+
   // Signals
 
   /**
index 3fce651f90527d6e96b92dde1ca08be3b8c00126..279630f94df3e176971578fef4c2c5c0901d758f 100644 (file)
@@ -113,16 +113,6 @@ Window::Window()
 
 Window::~Window()
 {
-  if(mScene)
-  {
-    auto bridge     = Accessibility::Bridge::GetCurrentBridge();
-    auto rootLayer  = mScene.GetRootLayer();
-    auto accessible = Accessibility::Accessible::Get(rootLayer);
-    bridge->RemoveTopLevelWindow(accessible);
-    // Related to multi-window case. This is called for default window and non-default window, but it is effective for non-default window.
-    bridge->Emit(accessible, Accessibility::WindowEvent::DESTROY);
-  }
-
   if(mAdaptor)
   {
     mAdaptor->RemoveWindow(this);
@@ -1308,14 +1298,9 @@ void Window::OnAccessibilityEnabled()
 
 void Window::OnAccessibilityDisabled()
 {
-  auto bridge     = Accessibility::Bridge::GetCurrentBridge();
-  auto rootLayer  = mScene.GetRootLayer();
-  auto accessible = Accessibility::Accessible::Get(rootLayer);
-
   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Accessibility is disabled\n", this, mNativeWindowId);
 
   InterceptKeyEventSignal().Disconnect(this, &Window::OnAccessibilityInterceptKeyEvent);
-  bridge->RemoveTopLevelWindow(accessible);
 }
 
 bool Window::OnAccessibilityInterceptKeyEvent(const Dali::KeyEvent& keyEvent)
@@ -1329,7 +1314,8 @@ bool Window::OnAccessibilityInterceptKeyEvent(const Dali::KeyEvent& keyEvent)
     return false;
   }
 
-  auto callback = [handle = Dali::Window(this)](Dali::KeyEvent keyEvent, bool consumed) {
+  auto callback = [handle = Dali::Window(this)](Dali::KeyEvent keyEvent, bool consumed)
+  {
     if(!consumed)
     {
       Dali::DevelKeyEvent::SetNoInterceptModifier(keyEvent, true);
@@ -1648,6 +1634,16 @@ bool Window::IsAlwaysOnTop()
   return mWindowBase->IsAlwaysOnTop();
 }
 
+void Window::SetBottom(bool enable)
+{
+  mWindowBase->SetBottom(enable);
+}
+
+bool Window::IsBottom()
+{
+  return mWindowBase->IsBottom();
+}
+
 Dali::Any Window::GetNativeBuffer() const
 {
   return mWindowBase->GetNativeBuffer();
@@ -1675,13 +1671,16 @@ void Window::SetBlur(const WindowBlurInfo& blurInfo)
 
   if(mBlurInfo.windowBlurType == WindowBlurType::BACKGROUND)
   {
-    mWindowBase->SetBackgroundBlur(mBlurInfo.windowBlurRadius, mBlurInfo.backgroundBlurRadius);
+    mWindowBase->SetBackgroundBlur(mBlurInfo.windowBlurRadius, mBlurInfo.backgroundCornerRadius);
+  }
+  else if(mBlurInfo.windowBlurType == WindowBlurType::BEHIND)
+  {
+    mWindowBase->SetBehindBlur(mBlurInfo.windowBlurRadius);
   }
   else
   {
     mWindowBase->SetBackgroundBlur(0, 0);
   }
-  // TODO : When new Blur type is append, it will be added
 }
 
 WindowBlurInfo Window::GetBlur() const
index 031046915e0f5bf5ab6bcc4b7b4be53777854ff7..3c31b00ab00f07a9472db3adb6a352c15c4ff185 100644 (file)
@@ -602,6 +602,16 @@ public: // Dali::Internal::Adaptor::SceneHolder
    */
   bool IsAlwaysOnTop();
 
+  /**
+   * @copydoc Dali::DevelWindow::SetBottom()
+   */
+  void SetBottom(bool enable);
+
+  /**
+   * @copydoc Dali::DevelWindow::IsBottom()
+   */
+  bool IsBottom();
+
   /**
    * @copydoc Dali::DevelWindow::GetNativeBuffer()
    */
index df3bb5266598812bcfc270cf68ae8e73fe4333c9..fd50d91de44cd4b2e404a71b468e26a5d08e8f91 100644 (file)
@@ -58,7 +58,7 @@ public:
   std::string GetNativeWindowResourceId() override;
 
   /**
-  * @copydoc Dali::Internal::Adaptor::WindowBase::CreateWindow()
+   * @copydoc Dali::Internal::Adaptor::WindowBase::CreateWindow()
    */
   Dali::Any CreateWindow(int width, int height) override;
 
@@ -467,6 +467,16 @@ public:
    */
   bool IsAlwaysOnTop() override;
 
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::SetBottom()
+   */
+  void SetBottom(bool enable) override;
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::IsBottom()
+   */
+  bool IsBottom() override;
+
   /**
    * @brief Sets front buffer rendering to the window.
    * @param[in] enable True to enable front buffer rendering mode, False to otherwise.
@@ -498,6 +508,16 @@ public:
    */
   int GetBackgroundBlur() override;
 
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::SetBehindBlur()
+   */
+  void SetBehindBlur(int blurRadius) override;
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::GetBehindBlur()
+   */
+  int GetBehindBlur() override;
+
 private:
   // Undefined
   WindowBaseCocoa(const WindowBaseCocoa&) = delete;
index ecae8fee73d2aa9107a9f68ce640a13252bce757..a414e0529ae4f2bbfeb67922e2490f11ca5c6730 100644 (file)
@@ -824,6 +824,15 @@ bool WindowBaseCocoa::IsAlwaysOnTop()
   return false;
 }
 
+void WindowBaseCocoa::SetBottom(bool enable)
+{
+}
+
+bool WindowBaseCocoa::IsBottom()
+{
+  return false;
+}
+
 Any WindowBaseCocoa::GetNativeBuffer() const
 {
   return 0;
@@ -848,6 +857,15 @@ int WindowBaseCocoa::GetBackgroundBlur()
   return 0;
 }
 
+void WindowBaseCocoa::SetBehindBlur(int blurRadius)
+{
+}
+
+int WindowBaseCocoa::GetBehindBlur()
+{
+  return 0;
+}
+
 } // namespace Dali::Internal::Adaptor
 
 @implementation CocoaView
index ae99a46e6b25aef92e14b0c7ad8945207e24237a..6027bb16d1d2498668c4fa1dd40d62af11d6a65b 100644 (file)
@@ -936,7 +936,8 @@ WindowBaseEcoreWl2::WindowBaseEcoreWl2(Dali::PositionSize positionSize, Any surf
   mOwnSurface(false),
   mBrightnessChangeDone(true),
   mIsFrontBufferRendering(false),
-  mIsIMEWindowInitialized(false)
+  mIsIMEWindowInitialized(false),
+  mBottom(false)
 {
   Initialize(positionSize, surface, isTransparent);
 }
@@ -3690,6 +3691,7 @@ void WindowBaseEcoreWl2::SetAlwaysOnTop(bool alwaysOnTop)
   DALI_LOG_RELEASE_INFO("ecore_wl2_window_pin_mode_set, window: [%p], flag [%d]\n", mEcoreWindow, alwaysOnTop);
   START_DURATION_CHECK();
   ecore_wl2_window_pin_mode_set(mEcoreWindow, alwaysOnTop);
+  ecore_wl2_window_commit(mEcoreWindow, EINA_TRUE);
   FINISH_DURATION_CHECK("ecore_wl2_window_pin_mode_set");
 }
 
@@ -3700,6 +3702,29 @@ bool WindowBaseEcoreWl2::IsAlwaysOnTop()
   return ret;
 }
 
+void WindowBaseEcoreWl2::SetBottom(bool enable)
+{
+  START_DURATION_CHECK();
+  mBottom = enable;
+  if(mBottom)
+  {
+    DALI_LOG_RELEASE_INFO("ecore_wl2_window_stack_mode_set, window: [%p], flag[%d] ECORE_WL2_WINDOW_STACK_BELOW\n", mEcoreWindow, mBottom);
+    ecore_wl2_window_stack_mode_set(mEcoreWindow, ECORE_WL2_WINDOW_STACK_BELOW);
+  }
+  else
+  {
+    DALI_LOG_RELEASE_INFO("ecore_wl2_window_stack_mode_set, window: [%p], flag[%d] ECORE_WL2_WINDOW_STACK_NONE\n", mEcoreWindow, mBottom);
+    ecore_wl2_window_stack_mode_set(mEcoreWindow, ECORE_WL2_WINDOW_STACK_NONE);
+  }
+  ecore_wl2_window_commit(mEcoreWindow, EINA_TRUE);
+  FINISH_DURATION_CHECK("ecore_wl2_window_stack_mode_set");
+}
+
+bool WindowBaseEcoreWl2::IsBottom()
+{
+  return mBottom;
+}
+
 Any WindowBaseEcoreWl2::GetNativeBuffer() const
 {
   DALI_LOG_RELEASE_INFO("Get wl_egl_window, ecore_window: [%p], wl_egl_window [%p]\n", mEcoreWindow, mEglWindow);
@@ -3736,6 +3761,21 @@ int WindowBaseEcoreWl2::GetBackgroundBlur()
   return radius;
 }
 
+void WindowBaseEcoreWl2::SetBehindBlur(int blurRadius)
+{
+  DALI_LOG_RELEASE_INFO("ecore_wl2_window_behind_blur_set, window: [%p], blur radius [%d]\n", mEcoreWindow, blurRadius);
+  START_DURATION_CHECK();
+  ecore_wl2_window_behind_blur_set(mEcoreWindow, blurRadius);
+  FINISH_DURATION_CHECK("ecore_wl2_window_behind_blur_set");
+}
+
+int WindowBaseEcoreWl2::GetBehindBlur()
+{
+  int radius = ecore_wl2_window_behind_blur_get(mEcoreWindow);
+  DALI_LOG_RELEASE_INFO("ecore_wl2_window_behind_blur_get, window: [%p], radius [%d]\n", mEcoreWindow, radius);
+  return radius;
+}
+
 } // namespace Adaptor
 
 } // namespace Internal
index 413801203f0627d6d08582c5cf70070cc180bf53..1d12c2de538158e90f661ba2ac0452a830d8234a 100644 (file)
@@ -682,6 +682,16 @@ public:
    */
   bool IsAlwaysOnTop() override;
 
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::SetBottom()
+   */
+  void SetBottom(bool enable) override;
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::IsBottom()
+   */
+  bool IsBottom() override;
+
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetNativeBuffer()
    */
@@ -707,6 +717,16 @@ public:
    */
   int GetBackgroundBlur() override;
 
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::SetBehindBlur()
+   */
+  void SetBehindBlur(int blurRadius) override;
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::GetBehindBlur()
+   */
+  int GetBehindBlur() override;
+
 private:
   /**
    * Second stage initialization
@@ -796,6 +816,7 @@ private:
   bool mBrightnessChangeDone;
   bool mIsFrontBufferRendering;
   bool mIsIMEWindowInitialized;
+  bool mBottom;
 };
 
 } // namespace Adaptor
index 15ce844a7b0d9c69a72c171042572230cb578c5b..cdb15dad14e2dc56331822f9bb3444b91aefec8d 100644 (file)
@@ -1115,6 +1115,15 @@ bool WindowBaseEcoreX::IsAlwaysOnTop()
   return false;
 }
 
+void WindowBaseEcoreX::SetBottom(bool enable)
+{
+}
+
+bool WindowBaseEcoreX::IsBottom()
+{
+  return false;
+}
+
 Any WindowBaseEcoreX::GetNativeBuffer() const
 {
   return 0;
@@ -1139,6 +1148,15 @@ int WindowBaseEcoreX::GetBackgroundBlur()
   return 0;
 }
 
+void WindowBaseEcoreX::SetBehindBlur(int blurRadius)
+{
+}
+
+int WindowBaseEcoreX::GetBehindBlur()
+{
+  return 0;
+}
+
 } // namespace Adaptor
 
 } // namespace Internal
index f701e4069be85414c50f538b96c4bdf95310ea73..eaacefc0891d3e70eda8549ac37841dd2672318a 100644 (file)
@@ -544,6 +544,16 @@ public:
    */
   bool IsAlwaysOnTop() override;
 
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::SetBottom()
+   */
+  void SetBottom(bool enable) override;
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::IsBottom()
+   */
+  bool IsBottom() override;
+
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetNativeBuffer()
    */
@@ -569,6 +579,15 @@ public:
    */
   int GetBackgroundBlur() override;
 
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::SetBehindBlur()
+   */
+  void SetBehindBlur(int blurRadius) override;
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::GetBehindBlur()
+   */
+  int GetBehindBlur() override;
 private:
   /**
    * Second stage initialization
index 14f606661ea14dd1b439d2a526d658d9ab6797ce..12a152177b27d827c3f7c2830bc9f79e7732512b 100644 (file)
@@ -744,6 +744,15 @@ bool WindowBaseWin::IsAlwaysOnTop()
   return false;
 }
 
+void WindowBaseWin::SetBottom(bool enable)
+{
+}
+
+bool WindowBaseWin::IsBottom()
+{
+  return false;
+}
+
 Any WindowBaseWin::GetNativeBuffer() const
 {
   return 0;
@@ -768,6 +777,15 @@ int WindowBaseWin::GetBackgroundBlur()
   return 0;
 }
 
+void WindowBaseWin::SetBehindBlur(int blurRadius)
+{
+}
+
+int WindowBaseWin::GetBehindBlur()
+{
+  return 0;
+}
+
 } // namespace Adaptor
 
 } // namespace Internal
index 60d0097a0de7706813bc027e5d59a5981f34c255..c69991ac2454b8abd238baa20ca9d220366cf937 100644 (file)
@@ -526,6 +526,16 @@ public:
    */
   bool IsAlwaysOnTop() override;
 
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::SetBottom()
+   */
+  void SetBottom(bool enable) override;
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::IsBottom()
+   */
+  bool IsBottom() override;
+
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetNativeBuffer()
    */
@@ -551,6 +561,15 @@ public:
    */
   int GetBackgroundBlur() override;
 
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::SetBehindBlur()
+   */
+  void SetBehindBlur(int blurRadius) override;
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::GetBehindBlur()
+   */
+  int GetBehindBlur() override;
 private:
   /**
    * Second stage initialization
index a10fbd27fd39f83dd904199446239bf39db8f785..f1164d1e42b3c9ed1c162715b9b1a1d3e15edeee 100644 (file)
@@ -1049,6 +1049,15 @@ bool WindowBaseX::IsAlwaysOnTop()
   return false;
 }
 
+void WindowBaseX::SetBottom(bool enable)
+{
+}
+
+bool WindowBaseX::IsBottom()
+{
+  return false;
+}
+
 Any WindowBaseX::GetNativeBuffer()
 {
   return 0;
@@ -1073,6 +1082,15 @@ int WindowBaseX::GetBackgroundBlur()
   return 0;
 }
 
+void WindowBaseX::SetBehindBlur(int blurRadius)
+{
+}
+
+int WindowBaseX::GetBehindBlur()
+{
+  return 0;
+}
+
 } // namespace Adaptor
 
 } // namespace Internal
index 9b4792a6ef71d284f9c9797650bd7f2ca03e4b28..fd3c9f474cfd42f676e30b673826d3ff2d221ebe 100644 (file)
@@ -549,6 +549,16 @@ public:
    */
   bool IsAlwaysOnTop() override;
 
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::SetBottom()
+   */
+  void SetBottom(bool enable) override;
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::IsBottom()
+   */
+  bool IsBottom() override;
+
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetNativeBuffer()
    */
@@ -574,6 +584,15 @@ public:
    */
   int GetBackgroundBlur() override;
 
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::SetBehindBlur()
+   */
+  void SetBehindBlur(int blurRadius) override;
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::WindowBase::GetBehindBlur()
+   */
+  int GetBehindBlur() override;
 private:
   /**
    * Second stage initialization
index 7ee8ba0931872d2195e1de548463835297e9a9c7..dfdae00857547918a16ea488bf7f370388232c77 100644 (file)
@@ -155,8 +155,7 @@ enum class WindowBlurType
 {
   NONE = 0,   ///< default value for blur disable
   BACKGROUND, ///< the window's background
-  // BEHIND,  ///< the window's behind except background
-  // BOTH,    ///< both window's background and behind
+  BEHIND,     ///< the window's behind except background
 };
 
 } // namespace Dali
index 17a3257d7cbe27a07b11bce6573625cdaa3dc96b..7b2a466eb9cc06bb2994f5b750bf7091149f6608 100644 (file)
@@ -27,7 +27,7 @@ namespace Dali
 {
 const unsigned int ADAPTOR_MAJOR_VERSION = 2;
 const unsigned int ADAPTOR_MINOR_VERSION = 3;
-const unsigned int ADAPTOR_MICRO_VERSION = 41;
+const unsigned int ADAPTOR_MICRO_VERSION = 44;
 const char* const  ADAPTOR_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 8ab66d1c637a055bdea9ad69a86fba047ee14dd5..2e3324b506bcbf962e6c1711c36389d562a6bf08 100644 (file)
@@ -17,7 +17,7 @@
 
 Name:       dali2-adaptor
 Summary:    The DALi Tizen Adaptor
-Version:    2.3.41
+Version:    2.3.44
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT