vk_res = image_wait_present(sc_images[*pending_index], timeout);
if (vk_res != VK_SUCCESS)
{
- m_is_valid = false;
+ /*
+ * Setting the error state to VK_TIMEOUT would communicate the wrong error
+ * state to the application through acquire_next_image. For this reason we
+ * convert it to VK_ERROR_DEVICE_LOST.
+ */
+ if (vk_res == VK_TIMEOUT)
+ {
+ vk_res = VK_ERROR_DEVICE_LOST;
+ }
+ set_error_state(vk_res);
m_free_image_semaphore.post();
continue;
}
swapchain_base::swapchain_base(layer::device_private_data &dev_data, const VkAllocationCallbacks *callbacks)
: m_device_data(dev_data)
, m_page_flip_thread_run(false)
- , m_is_valid(false)
, m_start_present_semaphore()
, m_thread_sem_defined(false)
, m_first_present(true)
, m_device(VK_NULL_HANDLE)
, m_queue(VK_NULL_HANDLE)
, m_image_acquire_lock()
+ , m_error_state(VK_NOT_READY)
{
}
ancestor->deprecate(reinterpret_cast<VkSwapchainKHR>(this));
}
- m_is_valid = true;
+ set_error_state(VK_SUCCESS);
return VK_SUCCESS;
}
auto *desc = reinterpret_cast<swapchain_base *>(m_descendant);
sem_wait(&desc->m_start_present_semaphore);
}
- else if (m_is_valid)
+ else if (!error_has_occured())
{
/* If descendant hasn't started presenting, there are pending buffers in the swapchain. */
wait_for_pending_buffers();
return retval;
}
- if (!m_is_valid)
+ if (error_has_occured())
{
- return VK_ERROR_OUT_OF_HOST_MEMORY;
+ return get_error_state();
}
std::unique_lock<std::recursive_mutex> image_status_lock(m_image_status_mutex);
*/
bool m_page_flip_thread_run;
- /**
- * @brief In case we encounter threading or drm errors we need a way to
- * notify the user of the failure. When this flag is false, acquire_next_image
- * will return an error code.
- */
- bool m_is_valid;
-
/**
* @brief A semaphore to be signalled once a page flip event occurs.
*/
*/
virtual VkResult image_wait_present(swapchain_image &image, uint64_t timeout) = 0;
+ /**
+ * @brief Returns true if an error has occurred.
+ */
+ bool error_has_occured() const
+ {
+ return m_error_state != VK_SUCCESS;
+ }
+
+ VkResult get_error_state() const
+ {
+ return m_error_state;
+ }
+
+ /*
+ * @brief Set the error state.
+ *
+ * The error state should be set when a failure that should be communicated
+ * to the application occurs during the page flipping thread.
+ *
+ * @param state Error code to be returned from acquire_next_image.
+ */
+ void set_error_state(VkResult state)
+ {
+ m_error_state = state;
+ }
+
private:
std::mutex m_image_acquire_lock;
+ /**
+ * @brief In case we encounter threading or drm errors we need a way to
+ * notify the user of the failure. While no error has occurred its value
+ * is VK_SUCCESS. When an error occurs, its value is set to the
+ * appropriate error code and it is returned to the user through the next
+ * acquire_next_image call.
+ */
+ VkResult m_error_state;
+
/**
* @brief Wait for a buffer to become free.
*/
/* if a frame is already pending, wait for a hint to present again */
if (!m_wsi_surface->wait_next_frame_event())
{
- m_is_valid = false;
+ set_error_state(VK_ERROR_SURFACE_LOST_KHR);
}
wl_surface_attach(m_surface, image_data->buffer, 0, 0);
if (!present_sync_fd.has_value())
{
WSI_LOG_ERROR("Failed to export present fence.");
- m_is_valid = false;
+ set_error_state(VK_ERROR_SURFACE_LOST_KHR);
}
else if (present_sync_fd->is_valid())
{
{
if (!m_wsi_surface->set_frame_callback())
{
- m_is_valid = false;
+ set_error_state(VK_ERROR_SURFACE_LOST_KHR);
}
}
{
WSI_LOG_ERROR("error flushing the display");
/* Setting the swapchain as invalid */
- m_is_valid = false;
+ set_error_state(VK_ERROR_SURFACE_LOST_KHR);
}
}