[Mesa-dev] [PATCH] vulkan/wsi/x11: handle timeouts properly in next image acquire
Edward O'Callaghan
funfunctor at folklore1984.net
Wed Oct 26 11:40:17 UTC 2016
Reviewed-by: Edward O'Callaghan <funfunctor at folklore1984.net>
On 10/26/2016 01:23 PM, Dave Airlie wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> For 0 timeout, just poll for an event, and if none, return
> For UINT64_MAX timeout, just wait for special event blocked
> For other timeouts get the xcb fd and block on it, decreasing
> the timeout if we get woken up for non-special events.
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
> src/vulkan/wsi/wsi_common_x11.c | 58 +++++++++++++++++++++++++++++++++++++----
> 1 file changed, 53 insertions(+), 5 deletions(-)
>
> diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
> index b5832c6..2ed47b0 100644
> --- a/src/vulkan/wsi/wsi_common_x11.c
> +++ b/src/vulkan/wsi/wsi_common_x11.c
> @@ -34,6 +34,7 @@
> #include <errno.h>
> #include <string.h>
>
> +#include <poll.h>
> #include "util/hash_table.h"
>
> #include "wsi_common.h"
> @@ -538,6 +539,26 @@ x11_handle_dri3_present_event(struct x11_swapchain *chain,
> return VK_SUCCESS;
> }
>
> +
> +static uint64_t wsi_get_current_time(void)
> +{
> + uint64_t current_time;
> + struct timespec tv;
> +
> + clock_gettime(CLOCK_MONOTONIC, &tv);
> + current_time = tv.tv_nsec + tv.tv_sec*1000000000ull;
> + return current_time;
> +}
> +
> +static uint64_t wsi_get_absolute_timeout(uint64_t timeout)
> +{
> + uint64_t current_time = wsi_get_current_time();
> +
> + timeout = MIN2(UINT64_MAX - current_time, timeout);
> +
> + return current_time + timeout;
> +}
> +
> static VkResult
> x11_acquire_next_image(struct wsi_swapchain *anv_chain,
> uint64_t timeout,
> @@ -545,7 +566,9 @@ x11_acquire_next_image(struct wsi_swapchain *anv_chain,
> uint32_t *image_index)
> {
> struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain;
> -
> + xcb_generic_event_t *event;
> + struct pollfd pfds;
> + uint64_t atimeout;
> while (1) {
> for (uint32_t i = 0; i < chain->image_count; i++) {
> if (!chain->images[i].busy) {
> @@ -558,10 +581,35 @@ x11_acquire_next_image(struct wsi_swapchain *anv_chain,
> }
>
> xcb_flush(chain->conn);
> - xcb_generic_event_t *event =
> - xcb_wait_for_special_event(chain->conn, chain->special_event);
> - if (!event)
> - return VK_ERROR_OUT_OF_DATE_KHR;
> +
> + if (timeout == UINT64_MAX) {
> + event = xcb_wait_for_special_event(chain->conn, chain->special_event);
> + if (!event)
> + return VK_ERROR_OUT_OF_DATE_KHR;
> + } else {
> + event = xcb_poll_for_special_event(chain->conn, chain->special_event);
> + if (!event) {
> + int ret;
> + if (timeout == 0)
> + return VK_NOT_READY;
> +
> + atimeout = wsi_get_absolute_timeout(timeout);
> +
> + pfds.fd = xcb_get_file_descriptor(chain->conn);
> + pfds.events = POLLIN;
> + ret = poll(&pfds, 1, timeout / 1000 / 1000);
> + if (ret == 0)
> + return VK_NOT_READY;
> + if (ret == -1)
> + return VK_ERROR_OUT_OF_DATE_KHR;
> +
> + /* If a non-special event happens, the fd will still
> + * poll. So recalculate the timeout now just in case.
> + */
> + timeout = atimeout - wsi_get_current_time();
> + continue;
> + }
> + }
>
> VkResult result = x11_handle_dri3_present_event(chain, (void *)event);
> free(event);
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20161026/f8bff6f0/attachment.sig>
More information about the mesa-dev
mailing list