wgl: Allow per-framebuffer swap interval overrides
authorJesse Natalie <jenatali@microsoft.com>
Mon, 20 Sep 2021 16:39:55 +0000 (09:39 -0700)
committerMarge Bot <emma+marge@anholt.net>
Wed, 10 Aug 2022 21:00:42 +0000 (21:00 +0000)
Acked-by: Daniel Stone <daniels@collabora.com>
Acked-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Acked-by: Sidney Just <justsid@x-plane.com>
Acked-by: Jason Ekstrand <jason.ekstrand@collabora.com>
Tested-by: Yonggang Luo <luoyonggang@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12964>

src/gallium/frontends/wgl/stw_framebuffer.c
src/gallium/frontends/wgl/stw_framebuffer.h
src/gallium/frontends/wgl/stw_winsys.h
src/gallium/winsys/d3d12/wgl/d3d12_wgl_framebuffer.cpp

index 0e4a7a7..762164b 100644 (file)
@@ -302,6 +302,9 @@ stw_framebuffer_create(HWND hWnd, int iPixelFormat, enum stw_framebuffer_owner o
 
    fb->refcnt = 1;
 
+   /* A -1 means defer to the global stw_dev->swap_interval */
+   fb->swap_interval = -1;
+
    /*
     * Windows can be sometimes have zero width and or height, but we ensure
     * a non-zero framebuffer size at all times.
@@ -604,7 +607,8 @@ stw_framebuffer_present_locked(HDC hdc,
                                struct pipe_resource *res)
 {
    if (fb->winsys_framebuffer) {
-      BOOL result = fb->winsys_framebuffer->present(fb->winsys_framebuffer);
+      int interval = fb->swap_interval == -1 ? stw_dev->swap_interval : fb->swap_interval;
+      BOOL result = fb->winsys_framebuffer->present(fb->winsys_framebuffer, interval);
 
       stw_framebuffer_update(fb);
       stw_notify_current_locked(fb);
@@ -653,7 +657,7 @@ stw_framebuffer_present_locked(HDC hdc,
  * This is for the WGL_ARB_swap_interval extension.
  */
 static void
-wait_swap_interval(struct stw_framebuffer *fb)
+wait_swap_interval(struct stw_framebuffer *fb, int interval)
 {
    /* Note: all time variables here are in units of microseconds */
    int64_t cur_time = os_time_get_nano() / 1000;
@@ -662,7 +666,7 @@ wait_swap_interval(struct stw_framebuffer *fb)
       /* Compute time since previous swap */
       int64_t delta = cur_time - fb->prev_swap_time;
       int64_t min_swap_period =
-         1.0e6 / stw_dev->refresh_rate * stw_dev->swap_interval;
+         1.0e6 / stw_dev->refresh_rate * interval;
 
       /* If time since last swap is less than wait period, wait.
        * Note that it's possible for the delta to be negative because of
@@ -704,8 +708,9 @@ stw_framebuffer_swap_locked(HDC hdc, struct stw_framebuffer *fb)
       }
    }
 
-   if (stw_dev->swap_interval != 0 && !fb->winsys_framebuffer) {
-      wait_swap_interval(fb);
+   int interval = fb->swap_interval == -1 ? stw_dev->swap_interval : fb->swap_interval;
+   if (interval != 0 && !fb->winsys_framebuffer) {
+      wait_swap_interval(fb, interval);
    }
 
    return stw_st_swap_framebuffer_locked(hdc, ctx->st, fb->stfb);
index db8a82a..0d120f0 100644 (file)
@@ -129,6 +129,7 @@ struct stw_framebuffer
    struct stw_winsys_framebuffer *winsys_framebuffer;
 
    /* For WGL_EXT_swap_control */
+   int swap_interval;
    int64_t prev_swap_time;
 
    /** 
index 66fb30e..e46137d 100644 (file)
@@ -52,7 +52,8 @@ struct stw_winsys_framebuffer
               struct pipe_context *context);
 
    boolean
-   (*present)(struct stw_winsys_framebuffer *fb);
+   (*present)(struct stw_winsys_framebuffer *fb,
+              int interval);
 
    void
    (*resize)(struct stw_winsys_framebuffer *fb,
index 7864da8..65aebdb 100644 (file)
@@ -150,7 +150,7 @@ d3d12_wgl_framebuffer_resize(stw_winsys_framebuffer *fb,
 }
 
 static boolean
-d3d12_wgl_framebuffer_present(stw_winsys_framebuffer *fb)
+d3d12_wgl_framebuffer_present(stw_winsys_framebuffer *fb, int interval)
 {
    auto framebuffer = d3d12_wgl_framebuffer(fb);
    if (!framebuffer->swapchain) {
@@ -158,10 +158,10 @@ d3d12_wgl_framebuffer_present(stw_winsys_framebuffer *fb)
       return false;
    }
 
-   if (stw_dev->swap_interval < 1)
+   if (interval < 1)
       return S_OK == framebuffer->swapchain->Present(0, DXGI_PRESENT_ALLOW_TEARING);
    else
-       return S_OK == framebuffer->swapchain->Present(stw_dev->swap_interval, 0);
+      return S_OK == framebuffer->swapchain->Present(interval, 0);
 }
 
 static struct pipe_resource *