Ken Thomases : winex11: Maintain the swap interval when the drawable is recreated.

Alexandre Julliard julliard at winehq.org
Tue Apr 1 14:32:01 CDT 2014


Module: wine
Branch: master
Commit: 4325ecdca841d6d161f723339afe9277f5d09704
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=4325ecdca841d6d161f723339afe9277f5d09704

Author: Ken Thomases <ken at codeweavers.com>
Date:   Mon Mar 31 21:46:48 2014 -0500

winex11: Maintain the swap interval when the drawable is recreated.

The swap interval is a property of the GLX drawable, which is destroyed and
recreated by set_gl_drawable_parent() and wglSetPixelFormatWINE().  When that
happens, copy the interval from the old gl_drawable and apply it at the next
call to wglSwapBuffers().

---

 dlls/winex11.drv/opengl.c |   82 ++++++++++++++++++++++++++++-----------------
 1 file changed, 52 insertions(+), 30 deletions(-)

diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c
index b3bd45b..85231f0 100644
--- a/dlls/winex11.drv/opengl.c
+++ b/dlls/winex11.drv/opengl.c
@@ -252,6 +252,7 @@ struct gl_drawable
     XVisualInfo                   *visual;       /* information about the GL visual */
     RECT                           rect;         /* drawable rect, relative to whole window drawable */
     int                            swap_interval;
+    BOOL                           refresh_swap_interval;
 };
 
 enum glx_swap_control_method
@@ -1185,6 +1186,43 @@ static inline void sync_context(struct wgl_context *context)
     }
 }
 
+static BOOL set_swap_interval(Drawable drawable, int interval)
+{
+    BOOL ret = TRUE;
+
+    switch (swap_control_method)
+    {
+    case GLX_SWAP_CONTROL_EXT:
+        X11DRV_expect_error(gdi_display, GLXErrorHandler, NULL);
+        pglXSwapIntervalEXT(gdi_display, drawable, interval);
+        XSync(gdi_display, False);
+        ret = !X11DRV_check_error();
+        break;
+
+    case GLX_SWAP_CONTROL_MESA:
+        ret = !pglXSwapIntervalMESA(interval);
+        break;
+
+    case GLX_SWAP_CONTROL_SGI:
+        /* wglSwapIntervalEXT considers an interval value of zero to mean that
+         * vsync should be disabled, but glXSwapIntervalSGI considers such a
+         * value to be an error. Just silently ignore the request for now.
+         */
+        if (!interval)
+            WARN("Request to disable vertical sync is not handled\n");
+        else
+            ret = !pglXSwapIntervalSGI(interval);
+        break;
+
+    case GLX_SWAP_CONTROL_NONE:
+        /* Unlikely to happen on modern GLX implementations */
+        WARN("Request to adjust swap interval is not handled\n");
+        break;
+    }
+
+    return ret;
+}
+
 static struct gl_drawable *get_gl_drawable( HWND hwnd, HDC hdc )
 {
     struct gl_drawable *gl;
@@ -1314,6 +1352,8 @@ static BOOL create_gl_drawable( HWND hwnd, struct gl_drawable *gl )
         }
     }
 
+    if (gl->drawable)
+        gl->refresh_swap_interval = TRUE;
     return gl->drawable != 0;
 }
 
@@ -1330,6 +1370,7 @@ static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format )
      * there is no way to query it, so we have to store it here.
      */
     gl->swap_interval = 1;
+    gl->refresh_swap_interval = TRUE;
     gl->format = format;
     gl->visual = pglXGetVisualFromFBConfig( gdi_display, format->fbconfig );
     if (!gl->visual)
@@ -1355,7 +1396,10 @@ static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format )
 
     EnterCriticalSection( &context_section );
     if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&prev ))
+    {
+        gl->swap_interval = prev->swap_interval;
         free_gl_drawable( prev );
+    }
     XSaveContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char *)gl );
     LeaveCriticalSection( &context_section );
 
@@ -2957,36 +3001,8 @@ static BOOL X11DRV_wglSwapIntervalEXT(int interval)
         return FALSE;
     }
 
-    switch (swap_control_method)
-    {
-    case GLX_SWAP_CONTROL_EXT:
-        X11DRV_expect_error(gdi_display, GLXErrorHandler, NULL);
-        pglXSwapIntervalEXT(gdi_display, gl->drawable, interval);
-        XSync(gdi_display, False);
-        ret = !X11DRV_check_error();
-        break;
-
-    case GLX_SWAP_CONTROL_MESA:
-        ret = !pglXSwapIntervalMESA(interval);
-        break;
-
-    case GLX_SWAP_CONTROL_SGI:
-        /* wglSwapIntervalEXT considers an interval value of zero to mean that
-         * vsync should be disabled, but glXSwapIntervalSGI considers such a
-         * value to be an error. Just silently ignore the request for now.
-         */
-        if (!interval)
-            WARN("Request to disable vertical sync is not handled\n");
-        else
-            ret = !pglXSwapIntervalSGI(interval);
-        break;
-
-    case GLX_SWAP_CONTROL_NONE:
-        /* Unlikely to happen on modern GLX implementations */
-        WARN("Request to adjust swap interval is not handled\n");
-        break;
-    }
-
+    ret = set_swap_interval(gl->drawable, interval);
+    gl->refresh_swap_interval = FALSE;
     if (ret)
         gl->swap_interval = interval;
     else
@@ -3202,6 +3218,12 @@ static BOOL glxdrv_wglSwapBuffers( HDC hdc )
         return FALSE;
     }
 
+    if (gl->refresh_swap_interval)
+    {
+        set_swap_interval(gl->drawable, gl->swap_interval);
+        gl->refresh_swap_interval = FALSE;
+    }
+
     switch (gl->type)
     {
     case DC_GL_PIXMAP_WIN:




More information about the wine-cvs mailing list