Fix bug in has_descendant_started_presenting in headless backend
authorDennis Tsiang <dennis.tsiang@arm.com>
Thu, 25 Nov 2021 15:30:46 +0000 (15:30 +0000)
committerMatteo Franchin <matteo.franchin@arm.com>
Mon, 6 Dec 2021 13:06:33 +0000 (13:06 +0000)
If there exists two swapchains where one is a descendant of another, we
need to return VK_ERROR_OUT_OF_DATE_KHR error if the application tries
to present from the ancestor when the descendant has started presenting.

The has_descendant_started_presenting() function checks whether the
descendant has started presenting by looking for pending images in the
descendant's list of swapchain images. However, the descendant could
have already presented its pending image(s) before the ancestor arrives
at this check. In this scenario, the descendant will have marked the
swapchain image(s) as now free, and therefore when the ancestor looks
for pending images it will fail to find any. This causes the function to
incorrectly return false.

This bug can be resolved by creating a new boolean member variable to
track whether the swapchain has started presenting.

Change-Id: Ibc3399a4bb05f89940f0b595d25aa07b8e2a2cb8
Signed-off-by: Dennis Tsiang <dennis.tsiang@arm.com>
Signed-off-by: Normunds Rieksts <normunds.rieksts@arm.com>
wsi/swapchain_base.cpp
wsi/swapchain_base.hpp

index b04dc79..ab24f0b 100644 (file)
@@ -131,15 +131,7 @@ bool swapchain_base::has_descendant_started_presenting()
    }
 
    auto *desc = reinterpret_cast<swapchain_base *>(m_descendant);
-   for (auto &image : desc->m_swapchain_images)
-   {
-      if (image.status == swapchain_image::PRESENTED || image.status == swapchain_image::PENDING)
-      {
-         return true;
-      }
-   }
-
-   return false;
+   return desc->m_started_presenting;
 }
 
 VkResult swapchain_base::init_page_flip_thread()
@@ -194,6 +186,7 @@ swapchain_base::swapchain_base(layer::device_private_data &dev_data, const VkAll
    , m_queue(VK_NULL_HANDLE)
    , m_image_acquire_lock()
    , m_error_state(VK_NOT_READY)
+   , m_started_presenting(false)
 {
 }
 
@@ -486,6 +479,7 @@ VkResult swapchain_base::notify_presentation_engine(uint32_t image_index)
    }
 
    m_swapchain_images[image_index].status = swapchain_image::PENDING;
+   m_started_presenting = true;
 
    if (m_page_flip_thread_run)
    {
index fabc069..c8d5573 100644 (file)
@@ -513,7 +513,7 @@ private:
    void call_present(uint32_t image_index);
 
    /**
-    * @brief Return true if the descendant has an image with PENDING or PRESENTED status.
+    * @brief Return true if the descendant has started presenting.
     */
    bool has_descendant_started_presenting();
 
@@ -536,6 +536,11 @@ private:
     * @return VK_SUCCESS on success or an error code otherwise.
     */
    VkResult notify_presentation_engine(uint32_t image_index);
+
+   /**
+    * @brief A flag to track if swapchain has started presenting.
+    */
+   bool m_started_presenting;
 };
 
 } /* namespace wsi */