Implement WSI layer swapchain functions for Tizen: 18/256718/3
authorTianhao Ni <tianhao.ni@samsung.com>
Mon, 12 Apr 2021 02:16:23 +0000 (10:16 +0800)
committerTianhao Ni <tianhao.ni@samsung.com>
Mon, 19 Apr 2021 06:25:55 +0000 (14:25 +0800)
1. Create TPL swapchain for Tizen platform;
2. Alloc tbm buffer for vulkan image;
3. Acquire and present image via dequeue/enqueue tpl buffer queue.

Change-Id: I5319c45fe0aa7f0f508b6279532412467d4fe438
Signed-off-by: Tianhao Ni <tianhao.ni@samsung.com>
CMakeLists.txt
wsi/swapchain_base_tizen.cpp [new file with mode: 0644]
wsi/swapchain_base_tizen.hpp [new file with mode: 0644]
wsi/tizen/surface_properties.cpp
wsi/tizen/swapchain.cpp
wsi/tizen/swapchain.hpp
wsi/tizen/swapchain_wl_helpers.cpp [deleted file]
wsi/tizen/swapchain_wl_helpers.hpp [deleted file]
wsi/wsi_factory.cpp
wsi/wsi_factory.hpp

index 23cf287..0b43e99 100644 (file)
@@ -59,10 +59,6 @@ if(BUILD_WSI_WAYLAND)
    set(BUILD_DRM_UTILS True)
 endif()
 
-if(BUILD_WSI_TIZEN)
-   set(BUILD_DRM_UTILS True)
-endif()
-
 # DRM Utilities
 if(BUILD_DRM_UTILS)
    add_library(drm_utils STATIC util/drm/drm_utils.cpp)
@@ -145,51 +141,30 @@ if(BUILD_WSI_WAYLAND)
 elseif(BUILD_WSI_TIZEN)
    add_library(tizen_wsi STATIC
       wsi/tizen/surface_properties.cpp
-      wsi/tizen/swapchain_wl_helpers.cpp
       wsi/tizen/swapchain.cpp)
 
-   pkg_check_modules(WAYLAND_CLIENT REQUIRED wayland-client)
-   message(STATUS "Using Wayland client include directories: ${WAYLAND_CLIENT_INCLUDE_DIRS}")
-   message(STATUS "Using Wayland client cflags: ${WAYLAND_CLIENT_CFLAGS}")
-   message(STATUS "Using Wayland client ldflags: ${WAYLAND_CLIENT_LDFLAGS}")
-
-   pkg_check_modules(WAYLAND_SCANNER REQUIRED wayland-scanner)
-   pkg_get_variable(WAYLAND_SCANNER_EXEC wayland-scanner wayland_scanner)
-   message(STATUS "Using wayland-scanner : ${WAYLAND_SCANNER_EXEC}")
-
-   pkg_check_modules(WAYLAND_PROTOCOLS REQUIRED wayland-protocols)
-   pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir)
-   message(STATUS "Using wayland protocols dir : ${WAYLAND_PROTOCOLS_DIR}")
-
-   add_custom_target(wayland_generated_files
-      COMMAND ${WAYLAND_SCANNER_EXEC} client-header
-      ${WAYLAND_PROTOCOLS_DIR}/unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml
-      ${CMAKE_CURRENT_BINARY_DIR}/linux-dmabuf-unstable-v1-client-protocol.h
-      COMMAND ${WAYLAND_SCANNER_EXEC} code
-      ${WAYLAND_PROTOCOLS_DIR}/unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml
-      ${CMAKE_CURRENT_BINARY_DIR}/linux-dmabuf-unstable-v1-protocol.c
-      BYPRODUCTS linux-dmabuf-unstable-v1-protocol.c linux-dmabuf-unstable-v1-client-protocol.h)
-
-   target_sources(tizen_wsi PRIVATE
-      ${CMAKE_CURRENT_BINARY_DIR}/linux-dmabuf-unstable-v1-protocol.c
-      ${CMAKE_CURRENT_BINARY_DIR}/linux-dmabuf-unstable-v1-client-protocol.h)
-   add_dependencies(tizen_wsi wayland_generated_files)
+   pkg_check_modules(LIBDRM REQUIRED libdrm)
+   message(STATUS "Using libdrm include directories: ${LIBDRM_INCLUDE_DIRS}")
 
    target_include_directories(tizen_wsi PRIVATE
       ${PROJECT_SOURCE_DIR}
       ${VULKAN_CXX_INCLUDE}
-      ${WAYLAND_CLIENT_INCLUDE_DIRS}
-      ${CMAKE_CURRENT_BINARY_DIR})
+      ${CMAKE_CURRENT_BINARY_DIR}
+         ${LIBDRM_INCLUDE_DIRS})
 
-   target_compile_options(tizen_wsi PRIVATE ${WAYLAND_CLIENT_CFLAGS})
    target_compile_options(tizen_wsi INTERFACE "-DBUILD_WSI_TIZEN=1")
-   target_link_libraries(tizen_wsi dlog tbm tpl-egl drm_utils ${WAYLAND_CLIENT_LDFLAGS})
+   target_link_libraries(tizen_wsi dlog tbm tpl-egl)
    list(APPEND LINK_WSI_LIBS tizen_wsi)
 else()
    list(APPEND JSON_COMMANDS COMMAND sed -i '/VK_KHR_wayland_surface/d' ${CMAKE_CURRENT_BINARY_DIR}/VkLayer_window_system_integration.json)
 endif()
 
 # Layer
+if(BUILD_WSI_TIZEN)
+   set(WSI_PLATFORM_SPECIFIED wsi/swapchain_base_tizen.cpp)
+else()
+   set(WSI_PLATFORM_SPECIFIED wsi/swapchain_base.cpp wsi/headless/surface_properties.cpp wsi/headless/swapchain.cpp)
+endif()
 add_library(${PROJECT_NAME} SHARED
    layer/layer.cpp
    layer/private_data.cpp
@@ -198,10 +173,8 @@ add_library(${PROJECT_NAME} SHARED
    util/timed_semaphore.cpp
    util/custom_allocator.cpp
    util/extension_list.cpp
-   wsi/swapchain_base.cpp
    wsi/wsi_factory.cpp
-   wsi/headless/surface_properties.cpp
-   wsi/headless/swapchain.cpp)
+   ${WSI_PLATFORM_SPECIFIED})
 target_compile_definitions(${PROJECT_NAME} PRIVATE ${WSI_DEFINES})
 target_include_directories(${PROJECT_NAME} PRIVATE
         ${PROJECT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${VULKAN_CXX_INCLUDE})
diff --git a/wsi/swapchain_base_tizen.cpp b/wsi/swapchain_base_tizen.cpp
new file mode 100644 (file)
index 0000000..acbafb6
--- /dev/null
@@ -0,0 +1,227 @@
+#include <array>
+#include <cassert>
+#include <cerrno>
+#include <cstdio>
+#include <cstdlib>
+
+#include <unistd.h>
+#include <vulkan/vulkan.h>
+
+#include "swapchain_base_tizen.hpp"
+
+#if VULKAN_WSI_DEBUG > 0
+#define WSI_PRINT_ERROR(...) fprintf(stderr, ##__VA_ARGS__)
+#else
+#define WSI_PRINT_ERROR(...) (void)0
+#endif
+
+namespace wsi
+{
+
+swapchain_base::swapchain_base(layer::device_private_data &dev_data, const VkAllocationCallbacks *callbacks)
+   : m_device_data(dev_data)
+   , m_allocator(callbacks, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)
+   , m_swapchain_images(m_allocator)
+   , m_surface(VK_NULL_HANDLE)
+   , m_present_mode(VK_PRESENT_MODE_IMMEDIATE_KHR)
+   , m_descendant(VK_NULL_HANDLE)
+   , m_ancestor(VK_NULL_HANDLE)
+   , m_device(VK_NULL_HANDLE)
+   , m_queue(VK_NULL_HANDLE)
+{
+}
+
+VkResult swapchain_base::init(VkDevice device, const VkSwapchainCreateInfoKHR *swapchain_create_info)
+{
+   assert(device != VK_NULL_HANDLE);
+   assert(swapchain_create_info != nullptr);
+   assert(swapchain_create_info->surface != VK_NULL_HANDLE);
+
+   VkResult result;
+
+   m_device = device;
+   m_surface = swapchain_create_info->surface;
+
+   /* We have allocated images, we can call the platform init function if something needs to be done. */
+   result = init_platform(device, swapchain_create_info);
+   if (result != VK_SUCCESS)
+   {
+      return result;
+   }
+
+   VkImageCreateInfo image_create_info = {};
+   image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+   image_create_info.pNext = nullptr;
+   image_create_info.imageType = VK_IMAGE_TYPE_2D;
+   image_create_info.format = swapchain_create_info->imageFormat;
+   image_create_info.extent = { swapchain_create_info->imageExtent.width, swapchain_create_info->imageExtent.height, 1 };
+   image_create_info.mipLevels = 1;
+   image_create_info.arrayLayers = swapchain_create_info->imageArrayLayers;
+   image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
+   image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
+   image_create_info.usage = swapchain_create_info->imageUsage;
+   image_create_info.flags = 0;
+   image_create_info.sharingMode = swapchain_create_info->imageSharingMode;
+   image_create_info.queueFamilyIndexCount = swapchain_create_info->queueFamilyIndexCount;
+   image_create_info.pQueueFamilyIndices = swapchain_create_info->pQueueFamilyIndices;
+   image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+
+   result = create_image(image_create_info);
+   if (result != VK_SUCCESS)
+   {
+      return result;
+   }
+
+   m_device_data.disp.GetDeviceQueue(m_device, 0, 0, &m_queue);
+   result = m_device_data.SetDeviceLoaderData(m_device, m_queue);
+   if (VK_SUCCESS != result)
+   {
+      return result;
+   }
+
+   if (swapchain_create_info->oldSwapchain != VK_NULL_HANDLE)
+   {
+      /* TO BE DONE - How to reuse the old swapchain */
+         /*
+      m_ancestor = swapchain_create_info->oldSwapchain;
+
+      auto *ancestor = reinterpret_cast<swapchain_base *>(m_ancestor);
+      ancestor->deprecate(reinterpret_cast<VkSwapchainKHR>(this));
+      */
+   }
+
+   return VK_SUCCESS;
+}
+
+void swapchain_base::teardown()
+{
+   if (m_queue != VK_NULL_HANDLE)
+   {
+      /* Make sure the vkFences are done signaling. */
+      m_device_data.disp.QueueWaitIdle(m_queue);
+   }
+}
+
+VkResult swapchain_base::acquire_next_image(uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *image_index)
+{
+   VkResult retval;
+
+   retval = acquire_image(image_index);
+   if (retval != VK_SUCCESS)
+      return retval;
+
+   if (VK_NULL_HANDLE != semaphore || VK_NULL_HANDLE != fence)
+   {
+      VkSubmitInfo submit = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
+
+      if (VK_NULL_HANDLE != semaphore)
+      {
+         submit.signalSemaphoreCount = 1;
+         submit.pSignalSemaphores = &semaphore;
+      }
+
+      submit.commandBufferCount = 0;
+      submit.pCommandBuffers = nullptr;
+      retval = m_device_data.disp.QueueSubmit(m_queue, 1, &submit, fence);
+      assert(retval == VK_SUCCESS);
+   }
+
+   return VK_SUCCESS;
+}
+
+VkResult swapchain_base::get_swapchain_images(uint32_t *swapchain_image_count, VkImage *swapchain_images)
+{
+   if (swapchain_images == nullptr)
+   {
+      /* Return the number of swapchain images. */
+      *swapchain_image_count = m_swapchain_images.size();
+
+      return VK_SUCCESS;
+   }
+   else
+   {
+      assert(m_swapchain_images.size() > 0);
+      assert(*swapchain_image_count > 0);
+
+      /* Populate array, write actual number of images returned. */
+      uint32_t current_image = 0;
+
+      do
+      {
+         swapchain_images[current_image] = m_swapchain_images[current_image].image;
+
+         current_image++;
+
+         if (current_image == m_swapchain_images.size())
+         {
+            *swapchain_image_count = current_image;
+
+            return VK_SUCCESS;
+         }
+
+      } while (current_image < *swapchain_image_count);
+
+      /* If swapchain_image_count is smaller than the number of presentable images
+       * in the swapchain, VK_INCOMPLETE must be returned instead of VK_SUCCESS. */
+      *swapchain_image_count = current_image;
+
+      return VK_INCOMPLETE;
+   }
+}
+
+VkResult swapchain_base::queue_present(VkQueue queue, const VkPresentInfoKHR *present_info, const uint32_t image_index)
+{
+   VkResult result;
+
+   /* When the semaphore that comes in is signalled, we know that all work is done. So, we do not
+    * want to block any future Vulkan queue work on it. So, we pass in BOTTOM_OF_PIPE bit as the
+    * wait flag.
+    */
+   VkPipelineStageFlags pipeline_stage_flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
+
+   VkSubmitInfo submit_info = { VK_STRUCTURE_TYPE_SUBMIT_INFO,
+                               NULL,
+                               present_info->waitSemaphoreCount,
+                               present_info->pWaitSemaphores,
+                               &pipeline_stage_flags,
+                               0,
+                               NULL,
+                               0,
+                               NULL };
+
+   result = m_device_data.disp.ResetFences(m_device, 1, &m_swapchain_images[image_index].present_fence);
+   if (result != VK_SUCCESS)
+   {
+      return result;
+   }
+
+   result = m_device_data.disp.QueueSubmit(queue, 1, &submit_info, m_swapchain_images[image_index].present_fence);
+   if (result != VK_SUCCESS)
+   {
+      return result;
+   }
+
+   present_image(image_index);
+
+   return VK_SUCCESS;
+}
+
+void swapchain_base::deprecate(VkSwapchainKHR descendant)
+{
+   // TO BE DONE - release old swapchain resources
+}
+
+void swapchain_base::clear_ancestor()
+{
+   m_ancestor = VK_NULL_HANDLE;
+}
+
+void swapchain_base::clear_descendant()
+{
+   m_descendant = VK_NULL_HANDLE;
+}
+
+#undef WSI_PRINT_ERROR
+
+} /* namespace wsi */
+
diff --git a/wsi/swapchain_base_tizen.hpp b/wsi/swapchain_base_tizen.hpp
new file mode 100644 (file)
index 0000000..9c6ff27
--- /dev/null
@@ -0,0 +1,235 @@
+#pragma once
+
+#include <vulkan/vulkan.h>
+
+#include <layer/private_data.hpp>
+#include <util/timed_semaphore.hpp>
+#include <util/custom_allocator.hpp>
+
+namespace wsi
+{
+struct swapchain_image
+{
+   /* Implementation specific data */
+   void *data{nullptr};
+
+   VkImage image{VK_NULL_HANDLE};
+   VkFence present_fence{VK_NULL_HANDLE};
+};
+
+/**
+ * @brief Base swapchain class
+ *
+ * - the swapchain implementations inherit from this class.
+ * - the VkSwapchain will hold a pointer to this class.
+ * - much of the swapchain implementation is done by this class, as the only things needed
+ *   in the implementation are how to create a presentable image and how to present an image.
+ */
+class swapchain_base
+{
+public:
+   swapchain_base(layer::device_private_data &dev_data, const VkAllocationCallbacks *allocator);
+
+   virtual ~swapchain_base()
+   {
+      /* nop */
+   }
+
+   /**
+    * @brief Create swapchain.
+    *
+    * Perform all swapchain initialization, create presentable images etc.
+    */
+   VkResult init(VkDevice device, const VkSwapchainCreateInfoKHR *swapchain_create_info);
+
+   /**
+    * @brief Acquires a free image.
+    *
+    * Current implementation blocks until a free image is available.
+    *
+    * @param timeout Unused since we block until a free image is available.
+    *
+    * @param semaphore A semaphore signaled once an image is acquired.
+    *
+    * @param fence A fence signaled once an image is acquired.
+    *
+    * @param pImageIndex The index of the acquired image.
+    *
+    * @return VK_SUCCESS on completion.
+    */
+   VkResult acquire_next_image(uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *image_index);
+
+   /**
+    * @brief Gets the number of swapchain images or a number of at most
+    * m_num_swapchain_images images.
+    *
+    * @param pSwapchainImageCount Used to return number of images in
+    * the swapchain if second parameter is nullptr or represents the
+    * number of images to be returned in second parameter.
+    *
+    * @param pSwapchainImage Array of VkImage handles.
+    *
+    * @return If number of requested images is less than the number of available
+    * images in the swapchain returns VK_INCOMPLETE otherwise VK_SUCCESS.
+    */
+   VkResult get_swapchain_images(uint32_t *swapchain_image_count, VkImage *swapchain_image);
+
+   /**
+    * @brief Submits a present request for the supplied image.
+    *
+    * @param queue The queue to which the submission will be made to.
+    *
+    * @param pPresentInfo Information about the swapchain and image to be presented.
+    *
+    * @param imageIndex The index of the image to be presented.
+    *
+    * @return If queue submission fails returns error of vkQueueSubmit, if the
+    * swapchain has a descendant who started presenting returns VK_ERROR_OUT_OF_DATE_KHR,
+    * otherwise returns VK_SUCCESS.
+    */
+   VkResult queue_present(VkQueue queue, const VkPresentInfoKHR *present_info, const uint32_t image_index);
+
+protected:
+
+   layer::device_private_data &m_device_data;
+
+   /**
+    * @brief User provided memory allocation callbacks.
+    */
+   const util::allocator m_allocator;
+
+   /**
+    * @brief Vector of images in the swapchain.
+    */
+   util::vector<swapchain_image> m_swapchain_images;
+
+   /**
+    * @brief Handle to the surface object this swapchain will present images to.
+    */
+   VkSurfaceKHR m_surface;
+
+   /**
+    * @brief present mode to use for this swapchain
+    */
+   VkPresentModeKHR m_present_mode;
+
+   /**
+    * @brief Descendant of this swapchain.
+    * Used to check whether or not a descendant of this swapchain has started
+    * presenting images to the surface already. If it has, any calls to queuePresent
+    * for this swapchain will return VK_ERROR_OUT_OF_DATE_KHR.
+    */
+   VkSwapchainKHR m_descendant;
+
+   /**
+    * @brief Ancestor of this swapchain.
+    * Used to check whether the ancestor swapchain has completed all of its
+    * pending page flips (this is required before this swapchain presents for the
+    * first time.
+    */
+   VkSwapchainKHR m_ancestor;
+
+   /**
+    *  @brief Handle to the logical device the swapchain is created for.
+    */
+   VkDevice m_device;
+
+   /**
+    *  @brief Handle to the queue used for signalling submissions
+    */
+   VkQueue m_queue;
+
+   /**
+    * @brief Return the VkAllocationCallbacks passed in this object constructor.
+    */
+   const VkAllocationCallbacks *get_allocation_callbacks()
+   {
+      return m_allocator.get_original_callbacks();
+   }
+
+   /**
+    * @brief Method to wait on all pending buffers to be displayed.
+    */
+   void wait_for_pending_buffers();
+
+   /**
+    * @brief Remove cached ancestor.
+    */
+   void clear_ancestor();
+
+   /**
+    * @brief Remove cached descendant.
+    */
+   void clear_descendant();
+
+   /**
+    * @brief Deprecate this swapchain.
+    *
+    * If an application replaces an old swapchain with a new one, the older swapchain
+    * needs to be deprecated. This method releases all the FREE images and sets the
+    * descendant of the swapchain. We do not need to care about images in other states
+    * at this point since they will be released by the page flip thread.
+    *
+    * @param descendant Handle to the descendant swapchain.
+    */
+   void deprecate(VkSwapchainKHR descendant);
+
+   /**
+    * @brief Platform specific initialization
+    */
+   virtual VkResult init_platform(VkDevice device, const VkSwapchainCreateInfoKHR *swapchain_create_info) = 0;
+
+   /**
+    * @brief Base swapchain teardown.
+    *
+    * Even though the inheritance gives us a nice way to defer display specific allocation
+    * and presentation outside of the base class, it however robs the children classes - which
+    * also happen to do some of their state setting - the oppurtunity to do the last clean up
+    * call, as the base class' destructor is called at the end. This method provides a way to do it.
+    * The destructor is a virtual function and much of the swapchain teardown happens in this method
+    * which gets called from the child's destructor.
+    */
+   void teardown();
+
+   /**
+    * @brief Creates a new swapchain image.
+    *
+    * @param image_create_info Data to be used to create the image.
+    *
+    * @param image Handle to the image.
+    *
+    * @return If image creation is successful returns VK_SUCCESS, otherwise
+    * will return VK_ERROR_OUT_OF_DEVICE_MEMORY or VK_ERROR_INITIALIZATION_FAILED
+    * depending on the error that occured.
+    */
+   virtual VkResult create_image(const VkImageCreateInfo &image_create_info) = 0;
+
+   virtual VkResult acquire_image(uint32_t *image_index) = 0;
+
+   /**
+    * @brief Method to present and image
+    *
+    * @param pending_index Index of the pending image to be presented.
+    *
+    */
+   virtual void present_image(uint32_t pending_index) = 0;
+
+   /**
+    * @brief Transition a presented image to free.
+    *
+    * Called by swapchain implementation when a new image has been presented.
+    *
+    * @param presented_index Index of the image to be marked as free.
+    */
+   void unpresent_image(uint32_t presented_index);
+
+   /**
+    * @brief Method to release a swapchain image
+    *
+    * @param image Handle to the image about to be released.
+    */
+   virtual void destroy_image(void){};
+};
+
+} /* namespace wsi */
+
index 28fc5cb..3bd73d7 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
+#define VK_USE_PLATFORM_WAYLAND_KHR 1
 
 extern "C" {
-#include <wayland-client.h>
-#include <linux-dmabuf-unstable-v1-client-protocol.h>
+#include <vulkan/vk_icd.h>
+#include <tpl.h>
 }
 
 #include <cassert>
@@ -51,10 +52,26 @@ surface_properties &surface_properties::get_instance()
 VkResult surface_properties::get_surface_capabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
                                                       VkSurfaceCapabilitiesKHR *pSurfaceCapabilities)
 {
+   VkIcdSurfaceWayland *vk_surf = reinterpret_cast<VkIcdSurfaceWayland *>(surface);
+   tpl_result_t res;
+
+   if (vk_surf == NULL || vk_surf->display == NULL || vk_surf->surface == NULL)
+      return VK_ERROR_SURFACE_LOST_KHR;
+
+   tpl_display_t *tpl_display = tpl_display_create(TPL_BACKEND_WAYLAND_VULKAN_WSI, vk_surf->display);
+   if (tpl_display == NULL) {
+      return VK_ERROR_OUT_OF_HOST_MEMORY;
+   }
+
+   int cnt_min = 0, cnt_max = 0;
+   res = tpl_display_query_supported_buffer_count_from_native_window(tpl_display, vk_surf->display, &cnt_min, &cnt_max);
+   if (res != TPL_ERROR_NONE) {
+      return VK_ERROR_SURFACE_LOST_KHR;
+   }
+
    /* Image count limits */
-   pSurfaceCapabilities->minImageCount = 2;
-   /* There is no maximum theoretically speaking */
-   pSurfaceCapabilities->maxImageCount = UINT32_MAX;
+   pSurfaceCapabilities->minImageCount = cnt_min;
+   pSurfaceCapabilities->maxImageCount = cnt_max;
 
    /* Surface extents */
    pSurfaceCapabilities->currentExtent = { 0xffffffff, 0xffffffff };
index edc6453..77d6983 100644 (file)
@@ -25,7 +25,6 @@
 #define VK_USE_PLATFORM_WAYLAND_KHR 1
 
 #include "swapchain.hpp"
-#include "swapchain_wl_helpers.hpp"
 
 #include <cstring>
 #include <cassert>
 #include <climits>
 #include <drm_fourcc.h>
 
-#include "util/drm/drm_utils.hpp"
-
 #if VULKAN_WSI_DEBUG > 0
-#define WSI_PRINT_ERROR(...) fprintf(stderr, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
+#define WSI_PRINT_ERROR(fmt, ...) fprintf(stderr, "[%s:%d - %s]" fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
 #else
 #define WSI_PRINT_ERROR(...) (void)0
 #endif
@@ -49,645 +46,347 @@ namespace wsi
 namespace tizen
 {
 
-struct swapchain::wayland_image_data
+struct swapchain::tizen_image_data
 {
    int buffer_fd;
+   tbm_surface_h tbm_buffer;
+
    int stride;
    uint32_t offset;
 
-   wl_buffer *buffer;
    VkDeviceMemory memory;
 };
 
 swapchain::swapchain(layer::device_private_data &dev_data, const VkAllocationCallbacks *pAllocator)
    : swapchain_base(dev_data, pAllocator)
-   , m_display(nullptr)
-   , m_surface(nullptr)
-   , m_dmabuf_interface(nullptr)
-   , m_surface_queue(nullptr)
-   , m_buffer_queue(nullptr)
-   , m_present_pending(false)
 {
 }
 
 swapchain::~swapchain()
 {
-   //int res;
    teardown();
-   if (m_dmabuf_interface != nullptr)
-   {
-      zwp_linux_dmabuf_v1_destroy(m_dmabuf_interface);
-   }
-   /*
-   res = wsialloc_delete(&m_wsi_allocator);
-   if (res != 0)
-   {
-      WSI_PRINT_ERROR("error deleting the allocator: %d\n", res);
-   }*/
-   if (m_surface_queue != nullptr)
-   {
-      wl_event_queue_destroy(m_surface_queue);
-   }
-   if (m_buffer_queue != nullptr)
-   {
-      wl_event_queue_destroy(m_buffer_queue);
-   }
+   destroy_image();
+   tpl_surface_destroy_swapchain(m_tpl_surface);
+   tpl_object_unreference((tpl_object_t *)m_tpl_surface);
+   tpl_object_unreference((tpl_object_t *)m_tpl_display);
 }
 
-static void roundtrip_cb_done(void *data, wl_callback *cb, uint32_t cb_data)
+#define TBM_FORMAT_0   0
+#define RETURN_FORMAT(comp, opaque, pre, post, inherit)                                        \
+       do {                                                                                                                            \
+               if (comp == VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)                                  \
+                       return TBM_FORMAT_##opaque;                                                                     \
+               else if (comp == VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR)             \
+                       return TBM_FORMAT_##pre;                                                                        \
+               else if (comp == VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR)    \
+                       return TBM_FORMAT_##post;                                                                       \
+               else if (comp == VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR)                    \
+                       return TBM_FORMAT_##inherit;                                                            \
+               else                                                                                                                    \
+                       return 0;                                                                                                       \
+       } while (0)
+
+
+static inline tbm_format
+wsi_tizen_get_tbm_format(VkFormat format, VkCompositeAlphaFlagBitsKHR comp)
 {
-   (void)cb_data;
-
-   bool *cb_recvd = reinterpret_cast<bool *>(data);
-   assert(cb_recvd);
-
-   *cb_recvd = true;
+       switch (format) {
+       /* 4 4 4 4 */
+       case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
+               RETURN_FORMAT(comp, RGBX4444, RGBA4444, 0, RGBA4444);
+       case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
+               RETURN_FORMAT(comp, BGRX4444, BGRA4444, 0, BGRA4444);
+       /* 5 6 5 */
+       case VK_FORMAT_R5G6B5_UNORM_PACK16:
+               RETURN_FORMAT(comp, RGB565, RGB565, RGB565, RGB565);
+       case VK_FORMAT_B5G6R5_UNORM_PACK16:
+               RETURN_FORMAT(comp, BGR565, BGR565, BGR565, BGR565);
+       /* 5 5 5 1 */
+       case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
+               RETURN_FORMAT(comp, RGBX5551, RGBA5551, 0, RGBA5551);
+       case VK_FORMAT_B5G5R5A1_UNORM_PACK16:
+               RETURN_FORMAT(comp, BGRX5551, BGRA5551, 0, BGRA5551);
+       case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
+               RETURN_FORMAT(comp, XRGB1555, ARGB1555, 0, ARGB1555);
+       /* 8 8 8 */
+       case VK_FORMAT_R8G8B8_UNORM:
+               RETURN_FORMAT(comp, BGR888, BGR888, BGR888, BGR888);
+       case VK_FORMAT_B8G8R8_UNORM:
+               RETURN_FORMAT(comp, RGB888, RGB888, RGB888, RGB888);
+       /* 8 8 8 8 */
+       case VK_FORMAT_B8G8R8A8_UNORM:
+               RETURN_FORMAT(comp, XRGB8888, ARGB8888, 0, ARGB8888);
+       case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
+               RETURN_FORMAT(comp, XBGR8888, ABGR8888, 0, ABGR8888);
+       /* 2 10 10 10 */
+       case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
+               RETURN_FORMAT(comp, XRGB2101010, ARGB2101010, 0, ARGB2101010);
+       case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
+               RETURN_FORMAT(comp, XBGR2101010, ABGR2101010, 0, ABGR2101010);
+       default:
+               break;
+       }
+
+       return 0;
 }
 
-int swapchain::roundtrip()
+VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKHR *pSwapchainCreateInfo)
 {
-   int res;
-   const wl_callback_listener listener = { roundtrip_cb_done };
-   bool cb_recvd = false;
+   VkIcdSurfaceWayland *vk_surf = reinterpret_cast<VkIcdSurfaceWayland *>(pSwapchainCreateInfo->surface);
+   tbm_format format;
+   int tpl_present_mode;
+   tpl_result_t res;
 
-   wl_callback *cb = wl_display_sync(m_display);
-   if (!cb)
-   {
-      WSI_PRINT_ERROR("failed to create wl_display::sync callback\n");
-      res = -1;
-      goto exit;
+   m_tpl_display = tpl_display_create(TPL_BACKEND_WAYLAND_VULKAN_WSI_THREAD, vk_surf->display);
+   if (m_tpl_display == NULL) {
+      WSI_PRINT_ERROR("create tpl display failed\n");
+         return VK_ERROR_INITIALIZATION_FAILED;
    }
+   tpl_object_reference((tpl_object_t *)m_tpl_display);
 
-   wl_proxy_set_queue((wl_proxy *)cb, m_surface_queue);
+   format = wsi_tizen_get_tbm_format(pSwapchainCreateInfo->imageFormat, pSwapchainCreateInfo->compositeAlpha);
+   m_tpl_surface = tpl_surface_get(m_tpl_display, vk_surf->surface);
+   if (m_tpl_surface == NULL)
+      m_tpl_surface = tpl_surface_create(m_tpl_display, vk_surf->surface, TPL_SURFACE_TYPE_WINDOW, format);
 
-   res = wl_callback_add_listener(cb, &listener, &cb_recvd);
-   if (res == -1)
-   {
-      WSI_PRINT_ERROR("error setting wl_display::sync callback listener\n");
-      goto exit;
+   if (m_tpl_surface == NULL) {
+      WSI_PRINT_ERROR("create tpl surface failed\n");
+         return VK_ERROR_INITIALIZATION_FAILED;
    }
+   tpl_object_reference((tpl_object_t *)m_tpl_surface);
 
-   res = wl_display_flush(m_display);
-   if (res == -1)
-   {
-      WSI_PRINT_ERROR("error performing a flush on the display\n");
-      goto exit;
+   switch(pSwapchainCreateInfo->presentMode) {
+      case VK_PRESENT_MODE_IMMEDIATE_KHR:
+         tpl_present_mode = TPL_DISPLAY_PRESENT_MODE_IMMEDIATE;
+         break;
+      case VK_PRESENT_MODE_MAILBOX_KHR:
+         tpl_present_mode = TPL_DISPLAY_PRESENT_MODE_MAILBOX;
+         break;
+      case VK_PRESENT_MODE_FIFO_KHR:
+         tpl_present_mode = TPL_DISPLAY_PRESENT_MODE_FIFO;
+         break;
+      case VK_PRESENT_MODE_FIFO_RELAXED_KHR:
+         tpl_present_mode = TPL_DISPLAY_PRESENT_MODE_FIFO_RELAXED;
+         break;
+      default:
+         WSI_PRINT_ERROR("unsupported present mode, presentMode[%d].", pSwapchainCreateInfo->presentMode);
+         return VK_ERROR_INITIALIZATION_FAILED;
    }
-   do
-   {
-      res = dispatch_queue(m_display, m_surface_queue, 1000);
-   } while (res > 0 && !cb_recvd);
 
-   if (res < 0)
-   {
-      WSI_PRINT_ERROR("error dispatching on the surface queue\n");
-      goto exit;
-   }
-   else if (res == 0)
-   {
-      WSI_PRINT_ERROR("timeout waiting for roundtrip callback\n");
-      goto exit;
+   res = tpl_surface_create_swapchain(m_tpl_surface, format,
+                                                                          pSwapchainCreateInfo->imageExtent.width, pSwapchainCreateInfo->imageExtent.height,
+                                                                          pSwapchainCreateInfo->minImageCount, tpl_present_mode);
+   if (res != TPL_ERROR_NONE) {
+          WSI_PRINT_ERROR("create swapchain failed, ret[%d].\n", res);
+          return VK_ERROR_INITIALIZATION_FAILED;
    }
 
-exit:
-   if (cb)
-   {
-      wl_callback_destroy(cb);
-   }
-   return res;
+   return VK_SUCCESS;
 }
 
-struct display_queue
-{
-   wl_display *display;
-   wl_event_queue *queue;
-};
-
-VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKHR *pSwapchainCreateInfo)
+VkResult swapchain::allocate_image(const VkImageCreateInfo &image_create_info, tizen_image_data *image_data,
+                                   VkImage *image)
 {
-   VkIcdSurfaceWayland *vk_surf = reinterpret_cast<VkIcdSurfaceWayland *>(pSwapchainCreateInfo->surface);
-
-   m_display = vk_surf->display;
-   m_surface = vk_surf->surface;
-#if 0
-   m_surface_queue = wl_display_create_queue(m_display);
-   if (m_surface_queue == nullptr)
-   {
-      WSI_PRINT_ERROR("Failed to create wl surface display_queue.\n");
-      return VK_ERROR_INITIALIZATION_FAILED;
-   }
-
-   m_buffer_queue = wl_display_create_queue(m_display);
-   if (m_buffer_queue == nullptr)
-   {
-      WSI_PRINT_ERROR("Failed to create wl buffer display_queue.\n");
-      return VK_ERROR_INITIALIZATION_FAILED;
-   }
+   VkResult result = VK_SUCCESS;
 
-   wl_registry *registry = wl_display_get_registry(m_display);
-   if (registry == nullptr)
+   assert(image_data->stride >= 0);
+   VkSubresourceLayout image_layout = {};
+   image_layout.offset = image_data->offset;
+   image_layout.rowPitch = static_cast<uint32_t>(image_data->stride);
+   VkImageDrmFormatModifierExplicitCreateInfoEXT drm_mod_info = {};
+   drm_mod_info.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT;
+   drm_mod_info.pNext = image_create_info.pNext;
+   drm_mod_info.drmFormatModifier = DRM_FORMAT_MOD_LINEAR;
+   drm_mod_info.drmFormatModifierPlaneCount = 1;
+   drm_mod_info.pPlaneLayouts = &image_layout;
+
+   VkExternalMemoryImageCreateInfoKHR external_info = {};
+   external_info.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR;
+   external_info.pNext = &drm_mod_info;
+   external_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
+
+   VkImageCreateInfo image_info = image_create_info;
+   image_info.pNext = &external_info;
+   image_info.tiling = VK_IMAGE_TILING_LINEAR;
+   result = m_device_data.disp.CreateImage(m_device, &image_info, get_allocation_callbacks(), image);
+   if (result != VK_SUCCESS)
    {
-      WSI_PRINT_ERROR("Failed to get wl display registry.\n");
-      return VK_ERROR_INITIALIZATION_FAILED;
+      WSI_PRINT_ERROR("Image creation failed.\n");
+      return result;
    }
 
-   wl_proxy_set_queue((struct wl_proxy *)registry, m_surface_queue);
+   VkMemoryFdPropertiesKHR mem_props = {};
+   mem_props.sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR;
 
-   const wl_registry_listener registry_listener = { registry_handler };
-   int res = wl_registry_add_listener(registry, &registry_listener, &m_dmabuf_interface);
-   if (res < 0)
+   result = m_device_data.disp.GetMemoryFdPropertiesKHR(m_device, VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
+                                                     image_data->buffer_fd, &mem_props);
+   if (result != VK_SUCCESS)
    {
-      WSI_PRINT_ERROR("Failed to add registry listener.\n");
-      return VK_ERROR_INITIALIZATION_FAILED;
+      WSI_PRINT_ERROR("Error querying Fd properties.\n");
+      return result;
    }
 
-   res = roundtrip();
-   if (res < 0)
+   uint32_t mem_idx;
+   for (mem_idx = 0; mem_idx < VK_MAX_MEMORY_TYPES; mem_idx++)
    {
-      WSI_PRINT_ERROR("Roundtrip failed.\n");
-      return VK_ERROR_INITIALIZATION_FAILED;
+      if (mem_props.memoryTypeBits & (1 << mem_idx))
+      {
+         break;
+      }
    }
-
-   /* we should have the dma_buf interface by now */
-   assert(m_dmabuf_interface);
-
-   wl_registry_destroy(registry);
-
-   res = wsialloc_new(-1, &m_wsi_allocator);
-   if (res != 0)
+   off_t dma_buf_size = lseek(image_data->buffer_fd, 0, SEEK_END);
+   if (dma_buf_size < 0)
    {
-      WSI_PRINT_ERROR("Failed to create wsi allocator.\n");
-      return VK_ERROR_INITIALIZATION_FAILED;
+      WSI_PRINT_ERROR("Failed to get DMA Buf size.\n");
+      return VK_ERROR_OUT_OF_HOST_MEMORY;
    }
-#endif
-   return VK_SUCCESS;
-}
 
-static void create_succeeded(void *data, struct zwp_linux_buffer_params_v1 *params, struct wl_buffer *buffer)
-{
-   struct wl_buffer **wayland_buffer = (struct wl_buffer **)data;
-   *wayland_buffer = buffer;
-}
+   VkImportMemoryFdInfoKHR import_mem_info = {};
+   import_mem_info.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR;
+   import_mem_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
+   import_mem_info.fd = image_data->buffer_fd;
 
-static const struct zwp_linux_buffer_params_v1_listener params_listener = { create_succeeded, NULL };
+   VkMemoryAllocateInfo alloc_info = {};
+   alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+   alloc_info.pNext = &import_mem_info;
+   alloc_info.allocationSize = static_cast<uint64_t>(dma_buf_size);
+   alloc_info.memoryTypeIndex = mem_idx;
 
-static void buffer_release(void *data, struct wl_buffer *wayl_buffer)
-{
-   swapchain *sc = (swapchain *)data;
-   sc->release_buffer(wayl_buffer);
-}
+   result = m_device_data.disp.AllocateMemory(m_device, &alloc_info, get_allocation_callbacks(), &image_data->memory);
 
-void swapchain::release_buffer(struct wl_buffer *wayl_buffer)
-{
-   uint32_t i;
-   for (i = 0; i < m_swapchain_images.size(); i++)
+   if (result != VK_SUCCESS)
    {
-      wayland_image_data *data;
-      data = (wayland_image_data *)m_swapchain_images[i].data;
-      if (data->buffer == wayl_buffer)
-      {
-         unpresent_image(i);
-         break;
-      }
+      WSI_PRINT_ERROR("Failed to import memory.\n");
+      return result;
    }
+   result = m_device_data.disp.BindImageMemory(m_device, *image, image_data->memory, 0);
 
-   /* check we found a buffer to unpresent */
-   assert(i < m_swapchain_images.size());
+   return result;
 }
 
-static struct wl_buffer_listener buffer_listener = { buffer_release };
-
-VkResult swapchain::allocate_image(const VkImageCreateInfo &image_create_info, wayland_image_data *image_data,
-                                   VkImage *image)
+VkResult swapchain::create_image(const VkImageCreateInfo &image_create_info)
 {
    VkResult result = VK_SUCCESS;
-
-   image_data->buffer = nullptr;
-   image_data->buffer_fd = -1;
-   image_data->memory = VK_NULL_HANDLE;
-
-   VkExternalImageFormatPropertiesKHR external_props = {};
-   external_props.sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR;
-
-   VkImageFormatProperties2KHR format_props = {};
-   format_props.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR;
-   format_props.pNext = &external_props;
-   {
-      VkPhysicalDeviceExternalImageFormatInfoKHR external_info = {};
-      external_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR;
-      external_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
-
-      VkPhysicalDeviceImageDrmFormatModifierInfoEXT drm_mod_info = {};
-      drm_mod_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT;
-      drm_mod_info.pNext = &external_info;
-      drm_mod_info.drmFormatModifier = DRM_FORMAT_MOD_LINEAR;
-      drm_mod_info.sharingMode = image_create_info.sharingMode;
-      drm_mod_info.queueFamilyIndexCount = image_create_info.queueFamilyIndexCount;
-      drm_mod_info.pQueueFamilyIndices = image_create_info.pQueueFamilyIndices;
-
-      VkPhysicalDeviceImageFormatInfo2KHR info = {};
-      info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR;
-      info.pNext = &drm_mod_info;
-      info.format = image_create_info.format;
-      info.type = image_create_info.imageType;
-      info.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
-      info.usage = image_create_info.usage;
-      info.flags = image_create_info.flags;
-
-      result = m_device_data.instance_data.disp.GetPhysicalDeviceImageFormatProperties2KHR(m_device_data.physical_device,
-                                                                                           &info, &format_props);
-   }
-   if (result != VK_SUCCESS)
-   {
-      WSI_PRINT_ERROR("Failed to get physical device format support.\n");
-      return result;
-   }
-   if (format_props.imageFormatProperties.maxExtent.width < image_create_info.extent.width ||
-       format_props.imageFormatProperties.maxExtent.height < image_create_info.extent.height ||
-       format_props.imageFormatProperties.maxExtent.depth < image_create_info.extent.depth)
-   {
-      WSI_PRINT_ERROR("Physical device does not support required extent.\n");
+   tpl_result_t res;
+   tbm_surface_h *buffers;
+   int tbm_buf_cnt, i = 0;
+
+   res = tpl_surface_get_swapchain_buffers(m_tpl_surface, &buffers, &tbm_buf_cnt);
+   if (res == TPL_ERROR_OUT_OF_MEMORY)
+      return VK_ERROR_OUT_OF_HOST_MEMORY;
+   else if (res != TPL_ERROR_NONE)
       return VK_ERROR_INITIALIZATION_FAILED;
-   }
-   if (format_props.imageFormatProperties.maxMipLevels < image_create_info.mipLevels ||
-       format_props.imageFormatProperties.maxArrayLayers < image_create_info.arrayLayers)
-   {
-      WSI_PRINT_ERROR("Physical device does not support required array layers or mip levels.\n");
-      return VK_ERROR_INITIALIZATION_FAILED;
-   }
-   if ((format_props.imageFormatProperties.sampleCounts & image_create_info.samples) != image_create_info.samples)
-   {
-      WSI_PRINT_ERROR("Physical device does not support required sample count.\n");
-      return VK_ERROR_INITIALIZATION_FAILED;
-   }
 
-   if (external_props.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR)
-   {
-      /* TODO: Handle exportable images which use ICD allocated memory in preference to an external allocator. */
-   }
-   if (!(external_props.externalMemoryProperties.externalMemoryFeatures &
-         VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR))
-   {
-      WSI_PRINT_ERROR("Export/Import not supported.\n");
-      return VK_ERROR_INITIALIZATION_FAILED;
-   }
-   else
-   {
-      /* TODO: Handle Dedicated allocation bit. */
-      uint32_t fourcc = util::drm::vk_to_drm_format(image_create_info.format);
-/*
-      int res =
-         wsialloc_alloc(&m_wsi_allocator, fourcc, image_create_info.extent.width, image_create_info.extent.height,
-                        &image_data->stride, &image_data->buffer_fd, &image_data->offset, nullptr);
-      if (res != 0)
-      {
-         WSI_PRINT_ERROR("Failed allocation of DMA Buffer.\n");
-         return VK_ERROR_OUT_OF_HOST_MEMORY;
-      }
-*/
-      {
-         assert(image_data->stride >= 0);
-         VkSubresourceLayout image_layout = {};
-         image_layout.offset = image_data->offset;
-         image_layout.rowPitch = static_cast<uint32_t>(image_data->stride);
-         VkImageDrmFormatModifierExplicitCreateInfoEXT drm_mod_info = {};
-         drm_mod_info.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT;
-         drm_mod_info.pNext = image_create_info.pNext;
-         drm_mod_info.drmFormatModifier = DRM_FORMAT_MOD_LINEAR;
-         drm_mod_info.drmFormatModifierPlaneCount = 1;
-         drm_mod_info.pPlaneLayouts = &image_layout;
-
-         VkExternalMemoryImageCreateInfoKHR external_info = {};
-         external_info.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR;
-         external_info.pNext = &drm_mod_info;
-         external_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
-
-         VkImageCreateInfo image_info = image_create_info;
-         image_info.pNext = &external_info;
-         image_info.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
-         result = m_device_data.disp.CreateImage(m_device, &image_info, get_allocation_callbacks(), image);
-      }
-      if (result != VK_SUCCESS)
+   if (!m_swapchain_images.try_resize(tbm_buf_cnt))
+      return VK_ERROR_OUT_OF_HOST_MEMORY;
+
+   i = 0;
+   for (auto &image: m_swapchain_images) {
+      tizen_image_data *image_data = nullptr;
+         if (get_allocation_callbacks() != nullptr)
       {
-         WSI_PRINT_ERROR("Image creation failed.\n");
-         return result;
+         image_data = static_cast<tizen_image_data *>(
+            get_allocation_callbacks()->pfnAllocation(get_allocation_callbacks()->pUserData, sizeof(tizen_image_data),
+                                                      alignof(tizen_image_data), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
+      } else {
+         image_data = static_cast<tizen_image_data *>(malloc(sizeof(tizen_image_data)));
       }
-      {
-         VkMemoryFdPropertiesKHR mem_props = {};
-         mem_props.sType = VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR;
-
-         result = m_device_data.disp.GetMemoryFdPropertiesKHR(m_device, VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
-                                                              image_data->buffer_fd, &mem_props);
-         if (result != VK_SUCCESS)
-         {
-            WSI_PRINT_ERROR("Error querying Fd properties.\n");
-            return result;
-         }
 
-         uint32_t mem_idx;
-         for (mem_idx = 0; mem_idx < VK_MAX_MEMORY_TYPES; mem_idx++)
-         {
-            if (mem_props.memoryTypeBits & (1 << mem_idx))
-            {
-               break;
-            }
-         }
-         off_t dma_buf_size = lseek(image_data->buffer_fd, 0, SEEK_END);
-         if (dma_buf_size < 0)
-         {
-            WSI_PRINT_ERROR("Failed to get DMA Buf size.\n");
-            return VK_ERROR_OUT_OF_HOST_MEMORY;
-         }
+      tbm_surface_info_s info;
+      tbm_bo bo = tbm_surface_internal_get_bo(buffers[i], 0);
+      tbm_bo_handle bo_handle = tbm_bo_get_handle(bo, TBM_DEVICE_3D);
+      tbm_surface_get_info(buffers[i], &info);
 
-         VkImportMemoryFdInfoKHR import_mem_info = {};
-         import_mem_info.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR;
-         import_mem_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
-         import_mem_info.fd = image_data->buffer_fd;
+         image_data->tbm_buffer = buffers[i];
+      image_data->buffer_fd = bo_handle.u32;
+      image_data->stride = info.planes[0].stride;
+      image_data->offset = info.planes[0].offset;
+         image_data->memory = VK_NULL_HANDLE;
 
-         VkMemoryAllocateInfo alloc_info = {};
-         alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
-         alloc_info.pNext = &import_mem_info;
-         alloc_info.allocationSize = static_cast<uint64_t>(dma_buf_size);
-         alloc_info.memoryTypeIndex = mem_idx;
+         image.data = static_cast<void *>(image_data);
 
-         result = m_device_data.disp.AllocateMemory(m_device, &alloc_info, get_allocation_callbacks(), &image_data->memory);
-      }
+      result = allocate_image(image_create_info, image_data, &image.image);
       if (result != VK_SUCCESS)
       {
-         WSI_PRINT_ERROR("Failed to import memory.\n");
-         return result;
+         WSI_PRINT_ERROR("Failed to allocate image.\n");
+         goto out;
       }
-      result = m_device_data.disp.BindImageMemory(m_device, *image, image_data->memory, 0);
-   }
-
-   return result;
-}
 
-VkResult swapchain::create_image(const VkImageCreateInfo &image_create_info, swapchain_image &image)
-{
-   uint32_t fourcc = util::drm::vk_to_drm_format(image_create_info.format);
+         /* Initialize presentation fence. */
+         VkFenceCreateInfo fenceInfo = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 };
+      result = m_device_data.disp.CreateFence(m_device, &fenceInfo, get_allocation_callbacks(), &image.present_fence);
 
-   int res;
-   VkResult result = VK_SUCCESS;
-
-   wayland_image_data *image_data = nullptr;
-   VkFenceCreateInfo fenceInfo = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 };
-
-   /* Create image_data */
-   if (get_allocation_callbacks() != nullptr)
-   {
-      image_data = static_cast<wayland_image_data *>(
-         get_allocation_callbacks()->pfnAllocation(get_allocation_callbacks()->pUserData, sizeof(wayland_image_data),
-                                                   alignof(wayland_image_data), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
-   }
-   else
-   {
-      image_data = static_cast<wayland_image_data *>(malloc(sizeof(wayland_image_data)));
-   }
-   if (image_data == nullptr)
-   {
-      result = VK_ERROR_OUT_OF_HOST_MEMORY;
-      goto out;
+         i++;
    }
 
-   image.data = reinterpret_cast<void *>(image_data);
-   image.status = swapchain_image::FREE;
-   result = allocate_image(image_create_info, image_data, &image.image);
-   if (result != VK_SUCCESS)
-   {
-      WSI_PRINT_ERROR("Failed to allocate image.\n");
-      goto out;
-   }
-
-   /* create a wl_buffer using the dma_buf protocol */
-   struct zwp_linux_buffer_params_v1 *params;
-   params = zwp_linux_dmabuf_v1_create_params(m_dmabuf_interface);
-   zwp_linux_buffer_params_v1_add(params, image_data->buffer_fd, 0, image_data->offset, image_data->stride, 0, 0);
-   wl_proxy_set_queue((struct wl_proxy *)params, m_surface_queue);
-   res = zwp_linux_buffer_params_v1_add_listener(params, &params_listener, &image_data->buffer);
-   if (res < 0)
-   {
-      result = VK_ERROR_INITIALIZATION_FAILED;
-      goto out;
-   }
-   zwp_linux_buffer_params_v1_create(params, image_create_info.extent.width, image_create_info.extent.height, fourcc,
-                                     0);
-
-   /* TODO: don't roundtrip - we should be able to send the create request now,
-    * and only wait for it on first present. only do this once, not for all buffers created */
-   res = roundtrip();
-   if (res < 0)
-   {
-      result = VK_ERROR_INITIALIZATION_FAILED;
-      goto out;
-   }
+   return VK_SUCCESS;
 
-   /* should now have a wl_buffer */
-   assert(image_data->buffer);
-   zwp_linux_buffer_params_v1_destroy(params);
-   wl_proxy_set_queue((struct wl_proxy *)image_data->buffer, m_buffer_queue);
-   res = wl_buffer_add_listener(image_data->buffer, &buffer_listener, this);
-   if (res < 0)
-   {
-      result = VK_ERROR_INITIALIZATION_FAILED;
-      goto out;
-   }
+out:
 
-   /* Initialize presentation fence. */
-   result = m_device_data.disp.CreateFence(m_device, &fenceInfo, get_allocation_callbacks(), &image.present_fence);
+   destroy_image();
 
-out:
-   if (result != VK_SUCCESS)
-   {
-      destroy_image(image);
-      return result;
-   }
    return result;
 }
 
-static void frame_done(void *data, wl_callback *cb, uint32_t cb_data)
+VkResult swapchain::acquire_image(uint32_t *image_index)
 {
-   (void)cb_data;
+   tbm_surface_h tbm_buf = tpl_surface_dequeue_buffer_with_sync(m_tpl_surface, UINT64_MAX, NULL);
 
-   bool *present_pending = reinterpret_cast<bool *>(data);
-   assert(present_pending);
+   if (tbm_buf == NULL)
+      return VK_ERROR_SURFACE_LOST_KHR;
 
-   *present_pending = false;
+   for (unsigned int i = 0; i < m_swapchain_images.size(); i++) {
+      tizen_image_data *image_data = reinterpret_cast<tizen_image_data *>(m_swapchain_images[i].data);
+      if (image_data->tbm_buffer == tbm_buf) {
+         *image_index = i;
+         return VK_SUCCESS;
+      }
+   }
 
-   wl_callback_destroy(cb);
+   return VK_ERROR_SURFACE_LOST_KHR;
 }
 
 void swapchain::present_image(uint32_t pendingIndex)
 {
-   int res;
-   wayland_image_data *image_data = reinterpret_cast<wayland_image_data *>(m_swapchain_images[pendingIndex].data);
-   /* if a frame is already pending, wait for a hint to present again */
-   if (m_present_pending)
-   {
-      assert(m_present_mode == VK_PRESENT_MODE_FIFO_KHR);
-      do
-      {
-         /* block waiting for the compositor to return the wl_surface::frame
-          * callback. We may want to change this to timeout after a period of
-          * time if the compositor isn't responding (perhaps because the
-          * window is hidden).
-          */
-         res = dispatch_queue(m_display, m_surface_queue, -1);
-      } while (res > 0 && m_present_pending);
-
-      if (res <= 0)
-      {
-         WSI_PRINT_ERROR("error waiting for Wayland compositor frame hint\n");
-         m_is_valid = false;
-         /* try to present anyway */
-      }
-   }
-
-   wl_surface_attach(m_surface, image_data->buffer, 0, 0);
-   /* TODO: work out damage */
-   wl_surface_damage(m_surface, 0, 0, INT32_MAX, INT32_MAX);
-
-   if (m_present_mode == VK_PRESENT_MODE_FIFO_KHR)
-   {
-      /* request a hint when we can present the _next_ frame */
-      wl_callback *cb = wl_surface_frame(m_surface);
-      if (cb)
-      {
-         wl_proxy_set_queue((wl_proxy *)cb, m_surface_queue);
-         static const wl_callback_listener frame_listener = { frame_done };
-         m_present_pending = true;
-         wl_callback_add_listener(cb, &frame_listener, &m_present_pending);
-      }
-   }
-   else
-   {
-      assert(m_present_mode == VK_PRESENT_MODE_MAILBOX_KHR);
-      /* weston only _queues_ wl_buffer::release events. This means when the
-       * compositor flushes the client it only sends the events if some other events
-       * have been posted.
-       *
-       * As such we have to request a sync callback - we discard it straight away
-       * as we don't actually need the callback, but it means the
-       * wl_buffer::release event is actually sent.
-       */
-      wl_callback *cb = wl_display_sync(m_display);
-      assert(cb);
-      if (cb)
-      {
-         wl_callback_destroy(cb);
-      }
-   }
-
-   wl_surface_commit(m_surface);
-   res = wl_display_flush(m_display);
-   if (res < 0)
-   {
-      WSI_PRINT_ERROR("error flushing the display\n");
-      /* Setting the swapchain as invalid */
-      m_is_valid = false;
-   }
+   tizen_image_data *image_data = reinterpret_cast<tizen_image_data *>(m_swapchain_images[pendingIndex].data);
+   tpl_surface_enqueue_buffer_with_damage_and_sync(m_tpl_surface, image_data->tbm_buffer, 0, NULL, -1);
 }
 
-void swapchain::destroy_image(swapchain_image &image)
+void swapchain::destroy_image(void)
 {
-   if (image.status != swapchain_image::INVALID)
-   {
+   for (auto &image: m_swapchain_images) {
       if (image.present_fence != VK_NULL_HANDLE)
       {
          m_device_data.disp.DestroyFence(m_device, image.present_fence, get_allocation_callbacks());
          image.present_fence = VK_NULL_HANDLE;
       }
-
       if (image.image != VK_NULL_HANDLE)
       {
          m_device_data.disp.DestroyImage(m_device, image.image, get_allocation_callbacks());
          image.image = VK_NULL_HANDLE;
       }
-   }
-   if (image.data != nullptr)
-   {
-      auto image_data = reinterpret_cast<wayland_image_data *>(image.data);
-      if (image_data->buffer != nullptr)
-      {
-         wl_buffer_destroy(image_data->buffer);
-      }
-      if (image_data->memory != VK_NULL_HANDLE)
-      {
-         m_device_data.disp.FreeMemory(m_device, image_data->memory, get_allocation_callbacks());
-      }
-      else if (image_data->buffer_fd >= 0)
-      {
-         close(image_data->buffer_fd);
-      }
-
-      if (get_allocation_callbacks() != nullptr)
+      if (image.data != nullptr)
       {
-         get_allocation_callbacks()->pfnFree(get_allocation_callbacks()->pUserData, image_data);
-      }
-      else
-      {
-         free(image_data);
-      }
-      image.data = nullptr;
-   }
-
-   image.status = swapchain_image::INVALID;
-}
-
-bool swapchain::free_image_found()
-{
-   for (auto &img : m_swapchain_images)
-   {
-      if (img.status == swapchain_image::FREE)
-      {
-         return true;
-      }
-   }
-   return false;
-}
-
-VkResult swapchain::get_free_buffer(uint64_t *timeout)
-{
-   int ms_timeout, res;
-
-   if (*timeout >= INT_MAX * 1000llu * 1000llu)
-   {
-      ms_timeout = INT_MAX;
-   }
-   else
-   {
-      ms_timeout = *timeout / 1000llu / 1000llu;
-   }
-
-   /* The current dispatch_queue implementation will return if any
-    * events are returned, even if no events are dispatched to the buffer
-    * queue. Therefore dispatch repeatedly until a buffer has been freed.
-    */
-   do
-   {
-      res = dispatch_queue(m_display, m_buffer_queue, ms_timeout);
-   } while (!free_image_found() && res > 0);
-
-   if (res > 0)
-   {
-      *timeout = 0;
-      return VK_SUCCESS;
-   }
-   else if (res == 0)
-   {
-      if (*timeout == 0)
-      {
-         return VK_NOT_READY;
-      }
-      else
-      {
-         return VK_TIMEOUT;
+         tizen_image_data *image_data = reinterpret_cast<tizen_image_data *>(image.data);
+         if (image_data->memory != VK_NULL_HANDLE)
+         {
+            m_device_data.disp.FreeMemory(m_device, image_data->memory, get_allocation_callbacks());
+         }
+         else if (image_data->buffer_fd >= 0)
+         {
+            close(image_data->buffer_fd);
+         }
+         if (get_allocation_callbacks() != nullptr)
+         {
+            get_allocation_callbacks()->pfnFree(get_allocation_callbacks()->pUserData, image_data);
+         }
+         else
+         {
+            free(image_data);
+         }
+         image.data = nullptr;
       }
    }
-   else
-   {
-      return VK_ERROR_DEVICE_LOST;
-   }
 }
 
 } // namespace wayland
index 7151b87..3a6e41a 100644 (file)
 
 #pragma once
 
-#include "wsi/swapchain_base.hpp"
+#include "wsi/swapchain_base_tizen.hpp"
 
 extern "C" {
 #include <vulkan/vk_icd.h>
-//#include <util/wsialloc/wsialloc.h>
-#include <wayland-client.h>
-#include <linux-dmabuf-unstable-v1-client-protocol.h>
+#include <tpl.h>
+#include <tbm_sync.h>
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
 }
 
 namespace wsi
@@ -45,9 +46,6 @@ public:
 
    ~swapchain();
 
-   /* TODO: make the buffer destructor a friend? so this can be protected */
-   void release_buffer(struct wl_buffer *wl_buffer);
-
 protected:
    /**
     * @brief Initialize platform specifics.
@@ -55,17 +53,17 @@ protected:
    VkResult init_platform(VkDevice device, const VkSwapchainCreateInfoKHR *pSwapchainCreateInfo) override;
 
    /**
-    * @brief Creates a new swapchain image.
+    * @brief Creates swapchain images.
     *
     * @param image_create_info Data to be used to create the image.
     *
-    * @param image Handle to the image.
-    *
     * @return If image creation is successful returns VK_SUCCESS, otherwise
     * will return VK_ERROR_OUT_OF_DEVICE_MEMORY or VK_ERROR_INITIALIZATION_FAILED
     * depending on the error that occurred.
     */
-   VkResult create_image(const VkImageCreateInfo &image_create_info, swapchain_image &image) override;
+   VkResult create_image(const VkImageCreateInfo &image_create_info) override;
+
+   VkResult acquire_image(uint32_t *image_index) override;
 
    /**
     * @brief Method to present an image
@@ -79,58 +77,15 @@ protected:
     *
     * @param image Handle to the image about to be released.
     */
-   void destroy_image(swapchain_image &image) override;
-
-   /**
-    * @brief Method to perform a rountrip to the Wayland compositor
-    *
-    * @return -1 on error. Otherwise non-negative.
-    */
-   int roundtrip();
-
-   /**
-    * @brief Method to check if there are any free images
-    *
-    * @return true if any images are free, otherwise false.
-    */
-   bool free_image_found();
-
-   /**
-    * @brief Hook for any actions to free up a buffer for acquire
-    *
-    * @param[in,out] timeout time to wait, in nanoseconds. 0 doesn't block,
-    *                        UINT64_MAX waits indefinitely. The timeout should
-    *                        be updated if a sleep is required - this can
-    *                        be set to 0 if the semaphore is now not expected
-    *                        block.
-    */
-   VkResult get_free_buffer(uint64_t *timeout) override;
+   void destroy_image(void) override;
 
 private:
-   struct wayland_image_data;
-   VkResult allocate_image(const VkImageCreateInfo &image_create_info, wayland_image_data *image_data, VkImage *image);
-
-   struct wl_display *m_display;
-   struct wl_surface *m_surface;
-   struct zwp_linux_dmabuf_v1 *m_dmabuf_interface;
+   struct tizen_image_data;
+   VkResult allocate_image(const VkImageCreateInfo &image_create_info, tizen_image_data *image_data, VkImage *image);
 
-   /* The queue on which we dispatch the swapchain related events, mostly frame completion */
-   struct wl_event_queue *m_surface_queue;
-   /* The queue on which we dispatch buffer related events, mostly buffer_release */
-   struct wl_event_queue *m_buffer_queue;
+   tpl_display_t *m_tpl_display;
+   tpl_surface_t *m_tpl_surface;
 
-   /**
-    * @brief Handle to the WSI allocator.
-    */
-   //wsialloc_allocator m_wsi_allocator;
-
-   /**
-    * @brief true when waiting for the server hint to present a buffer
-    *
-    * true if a buffer has been presented and we've not had a wl_surface::frame
-    * callback to indicate the server is ready for the next buffer.
-    */
-   bool m_present_pending;
 };
 } // namespace wayland
 } // namespace wsi
diff --git a/wsi/tizen/swapchain_wl_helpers.cpp b/wsi/tizen/swapchain_wl_helpers.cpp
deleted file mode 100644 (file)
index 197ca04..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2017-2019, 2021 Arm Limited.
- *
- * SPDX-License-Identifier: MIT
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include "swapchain_wl_helpers.hpp"
-
-#include <wayland-client.h>
-#include <linux-dmabuf-unstable-v1-client-protocol.h>
-#include <string.h>
-#include <assert.h>
-#include <poll.h>
-#include <errno.h>
-
-extern "C" {
-
-   void registry_handler(void *data, struct wl_registry *wl_registry, uint32_t name, const char *interface,
-                         uint32_t version)
-   {
-      zwp_linux_dmabuf_v1 **dmabuf_interface = (zwp_linux_dmabuf_v1 **)data;
-
-      if (!strcmp(interface, "zwp_linux_dmabuf_v1"))
-      {
-         *dmabuf_interface =
-            (zwp_linux_dmabuf_v1 *)wl_registry_bind(wl_registry, name, &zwp_linux_dmabuf_v1_interface, version);
-         assert(*dmabuf_interface);
-      }
-   }
-
-   int dispatch_queue(struct wl_display *display, struct wl_event_queue *queue, int timeout)
-   {
-      int err;
-      struct pollfd pfd = {};
-      int retval;
-
-      /* Before we sleep, dispatch any pending events. prepare_read_queue will return 0 whilst there are pending
-       * events to dispatch on the queue. */
-      while (0 != wl_display_prepare_read_queue(display, queue))
-      {
-         /* dispatch_queue_pending returns -1 on error, or the number of events dispatched otherwise. If we
-          * already dispatched some events, then we might not need to sleep, as we might have just dispatched
-          * the event we want, so return immediately. */
-         err = wl_display_dispatch_queue_pending(display, queue);
-         if (err)
-         {
-            return (0 > err) ? -1 : 1;
-         }
-      }
-
-      /* wl_display_read_events performs a non-blocking read. */
-      pfd.fd = wl_display_get_fd(display);
-      pfd.events = POLLIN;
-      while (true)
-      {
-         /* Timeout is given in milliseconds. A return value of 0, or -1 with errno set to EINTR means that we
-          * should retry as the timeout was exceeded or we were interrupted by a signal, respectively. A
-          * return value of 1 means that something happened, and we should inspect the pollfd structure to see
-          * just what that was.
-          */
-         err = poll(&pfd, 1, timeout);
-         if (0 == err)
-         {
-            /* Timeout. */
-            wl_display_cancel_read(display);
-            return 0;
-         }
-         else if (-1 == err)
-         {
-            if (EINTR == errno)
-            {
-               /* Interrupted by a signal; restart. This resets the timeout. */
-               continue;
-            }
-            else
-            {
-               /* Something else bad happened; abort. */
-               wl_display_cancel_read(display);
-               return -1;
-            }
-         }
-         else
-         {
-            if (POLLIN == pfd.revents)
-            {
-               /* We have data to read, and no errors; proceed to read_events. */
-               break;
-            }
-            else
-            {
-               /* An error occurred, e.g. file descriptor was closed from underneath us. */
-               wl_display_cancel_read(display);
-               return -1;
-            }
-         }
-      }
-
-      /* Actually read the events from the display. A failure in read_events calls cancel_read internally for us,
-       * so we don't need to do that here. */
-      err = wl_display_read_events(display);
-      if (0 != err)
-      {
-         return -1;
-      }
-
-      /* Finally, if we read any events relevant to our queue, we can dispatch them. */
-      err = wl_display_dispatch_queue_pending(display, queue);
-      retval = err < 0 ? -1 : 1;
-
-      return retval;
-   }
-}
diff --git a/wsi/tizen/swapchain_wl_helpers.hpp b/wsi/tizen/swapchain_wl_helpers.hpp
deleted file mode 100644 (file)
index 5318682..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2017-2019, 2021 Arm Limited.
- *
- * SPDX-License-Identifier: MIT
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#pragma once
-
-#include <wayland-client.h>
-
-extern "C" {
-   void registry_handler(void *data, struct wl_registry *wl_registry, uint32_t name, const char *interface,
-                         uint32_t version);
-
-   /**
-    * @brief Dispatch events from a Wayland event queue
-    *
-    * Dispatch events from a given Wayland display event queue, including calling event handlers, and flush out any
-    * requests the event handlers may have written. Specification of a timeout allows the wait to be bounded. If any
-    * events are already pending dispatch (have been read from the display by another thread or event queue), they
-    * will be dispatched and the function will return immediately, without waiting for new events to arrive.
-    *
-    * @param  display Wayland display to dispatch events from
-    * @param  queue   Event queue to dispatch events from; other event queues will not have their handlers called from
-    *                 within this function
-    * @param  timeout Maximum time to wait for events to arrive, in milliseconds
-    * @return         1 if one or more events were dispatched on this queue, 0 if the timeout was reached without any
-    *                 events being dispatched, or -1 on error.
-    */
-   int dispatch_queue(struct wl_display *display, struct wl_event_queue *queue, int timeout);
-}
index 5da2394..51e5e86 100644 (file)
@@ -28,8 +28,6 @@
  */
 
 #include "wsi_factory.hpp"
-#include "headless/surface_properties.hpp"
-#include "headless/swapchain.hpp"
 
 #include <cassert>
 #include <cstdlib>
 
 #include <vulkan/vk_icd.h>
 
+#if BUILD_WSI_TIZEN
+#include <vulkan/vulkan_wayland.h>
+#include "tizen/surface_properties.hpp"
+#include "tizen/swapchain.hpp"
+#else
+#include "headless/surface_properties.hpp"
+#include "headless/swapchain.hpp"
 #if BUILD_WSI_WAYLAND
 #include <vulkan/vulkan_wayland.h>
 #include "wayland/surface_properties.hpp"
 #include "wayland/swapchain.hpp"
-#elif BUILD_WSI_TIZEN
-#include <vulkan/vulkan_wayland.h>
-#include "tizen/surface_properties.hpp"
-#include "tizen/swapchain.hpp"
+#endif
 #endif
 
 namespace wsi
@@ -56,24 +58,30 @@ static struct wsi_extension
    VkExtensionProperties extension;
    VkIcdWsiPlatform platform;
 } const supported_wsi_extensions[] = {
+#if BUILD_WSI_TIZEN
+   { { VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_SPEC_VERSION }, VK_ICD_WSI_PLATFORM_WAYLAND },
+#else
    { { VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, VK_EXT_HEADLESS_SURFACE_SPEC_VERSION }, VK_ICD_WSI_PLATFORM_HEADLESS },
-#if BUILD_WSI_WAYLAND || BUILD_WSI_TIZEN
+#if BUILD_WSI_WAYLAND
    { { VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_SPEC_VERSION }, VK_ICD_WSI_PLATFORM_WAYLAND },
 #endif
+#endif
 };
 
 static surface_properties *get_surface_properties(VkIcdWsiPlatform platform)
 {
    switch (platform)
    {
+#if BUILD_WSI_TIZEN
+   case VK_ICD_WSI_PLATFORM_WAYLAND:
+      return &tizen::surface_properties::get_instance();
+#else
    case VK_ICD_WSI_PLATFORM_HEADLESS:
       return &headless::surface_properties::get_instance();
 #if BUILD_WSI_WAYLAND
    case VK_ICD_WSI_PLATFORM_WAYLAND:
       return &wayland::surface_properties::get_instance();
-#elif BUILD_WSI_TIZEN
-   case VK_ICD_WSI_PLATFORM_WAYLAND:
-      return &tizen::surface_properties::get_instance();
+#endif
 #endif
    default:
       return nullptr;
@@ -106,14 +114,16 @@ swapchain_base *allocate_surface_swapchain(VkSurfaceKHR surface, layer::device_p
 
    switch (surface_base->platform)
    {
+#if BUILD_WSI_TIZEN
+   case VK_ICD_WSI_PLATFORM_WAYLAND:
+                return allocate_swapchain<wsi::tizen::swapchain>(dev_data, pAllocator);
+#else
    case VK_ICD_WSI_PLATFORM_HEADLESS:
       return allocate_swapchain<wsi::headless::swapchain>(dev_data, pAllocator);
 #if BUILD_WSI_WAYLAND
    case VK_ICD_WSI_PLATFORM_WAYLAND:
       return allocate_swapchain<wsi::wayland::swapchain>(dev_data, pAllocator);
-#elif BUILD_WSI_TIZEN
-   case VK_ICD_WSI_PLATFORM_WAYLAND:
-      return allocate_swapchain<wsi::tizen::swapchain>(dev_data, pAllocator);
+#endif
 #endif
    default:
       return nullptr;
index 1c8174f..73b751e 100644 (file)
 
 #pragma once
 
+#if BUILD_WSI_TIZEN
+#include "swapchain_base_tizen.hpp"
+#else
 #include "swapchain_base.hpp"
+#endif
 #include "surface_properties.hpp"
 #include "util/platform_set.hpp"