Henri Verbeet : winex11: Use GLX_OML_sync_control to synchronise buffer swaps with X11DRV_FLUSH_GL_DRAWABLE requests.

Alexandre Julliard julliard at winehq.org
Fri Mar 24 16:24:24 CDT 2017


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

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Thu Mar 23 23:58:10 2017 +0100

winex11: Use GLX_OML_sync_control to synchronise buffer swaps with X11DRV_FLUSH_GL_DRAWABLE requests.

Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winex11.drv/init.c   |  3 ---
 dlls/winex11.drv/opengl.c | 28 ++++++++++++++++++++++++++++
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c
index af2fd92..7efd603 100644
--- a/dlls/winex11.drv/init.c
+++ b/dlls/winex11.drv/init.c
@@ -375,9 +375,6 @@ static INT X11DRV_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID in_d
                     RECT rect = physDev->dc_rect;
 
                     OffsetRect( &rect, -physDev->dc_rect.left, -physDev->dc_rect.top );
-                    /* The GL drawable may be lagged behind if we don't flush first, so
-                     * flush the display make sure we copy up-to-date data */
-                    XFlush( gdi_display );
                     XSetFunction( gdi_display, physDev->gc, GXcopy );
                     XCopyArea( gdi_display, data->gl_drawable, physDev->drawable, physDev->gc,
                                0, 0, rect.right, rect.bottom,
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c
index 76cc3cc..28f033d 100644
--- a/dlls/winex11.drv/opengl.c
+++ b/dlls/winex11.drv/opengl.c
@@ -418,6 +418,12 @@ static const char *(*pglXQueryCurrentRendererStringMESA)(int attribute);
 static Bool (*pglXQueryRendererIntegerMESA)(Display *dpy, int screen, int renderer, int attribute, unsigned int *value);
 static const char *(*pglXQueryRendererStringMESA)(Display *dpy, int screen, int renderer, int attribute);
 
+/* OpenML GLX Extensions */
+static Bool (*pglXWaitForSbcOML)( Display *dpy, GLXDrawable drawable,
+        INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc );
+static INT64 (*pglXSwapBuffersMscOML)( Display *dpy, GLXDrawable drawable,
+        INT64 target_msc, INT64 divisor, INT64 remainder );
+
 /* Standard OpenGL */
 static void (*pglFinish)(void);
 static void (*pglFlush)(void);
@@ -750,6 +756,12 @@ static BOOL WINAPI init_opengl( INIT_ONCE *once, void *param, void **context )
         pglXQueryRendererStringMESA = pglXGetProcAddressARB( (const GLubyte *)"glXQueryRendererStringMESA" );
     }
 
+    if (has_extension( WineGLInfo.glxExtensions, "GLX_OML_sync_control" ))
+    {
+        pglXWaitForSbcOML = pglXGetProcAddressARB( (const GLubyte *)"glXWaitForSbcOML" );
+        pglXSwapBuffersMscOML = pglXGetProcAddressARB( (const GLubyte *)"glXSwapBuffersMscOML" );
+    }
+
     X11DRV_WineGL_LoadExtensions();
     init_pixel_formats( gdi_display );
     return TRUE;
@@ -3298,6 +3310,7 @@ static BOOL glxdrv_wglSwapBuffers( HDC hdc )
     struct x11drv_escape_flush_gl_drawable escape;
     struct gl_drawable *gl;
     struct wgl_context *ctx = NtCurrentTeb()->glContext;
+    INT64 ust, msc, sbc, target_sbc = 0;
 
     TRACE("(%p)\n", hdc);
 
@@ -3330,6 +3343,12 @@ static BOOL glxdrv_wglSwapBuffers( HDC hdc )
                                    gl->rect.right - gl->rect.left, gl->rect.bottom - gl->rect.top );
             break;
         }
+        if (pglXSwapBuffersMscOML)
+        {
+            pglFlush();
+            target_sbc = pglXSwapBuffersMscOML( gdi_display, gl->drawable, 0, 0, 0 );
+            break;
+        }
         pglXSwapBuffers(gdi_display, gl->drawable);
         break;
     case DC_GL_CHILD_WIN:
@@ -3337,10 +3356,19 @@ static BOOL glxdrv_wglSwapBuffers( HDC hdc )
         escape.gl_drawable = gl->window;
         /* fall through */
     default:
+        if (pglXSwapBuffersMscOML)
+        {
+            pglFlush();
+            target_sbc = pglXSwapBuffersMscOML( gdi_display, gl->drawable, 0, 0, 0 );
+            break;
+        }
         pglXSwapBuffers(gdi_display, gl->drawable);
         break;
     }
 
+    if (escape.gl_drawable && pglXWaitForSbcOML)
+        pglXWaitForSbcOML( gdi_display, gl->drawable, target_sbc, &ust, &msc, &sbc );
+
     release_gl_drawable( gl );
 
     if (escape.gl_drawable) ExtEscape( ctx->hdc, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL );




More information about the wine-cvs mailing list