[PATCH v2 1/2] win32u: Don't pass physdev to wine_get_wgl_driver() driver function.

Paul Gofman pgofman at codeweavers.com
Tue Feb 1 11:32:29 CST 2022


Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
     Supersedes 223960.
     v2:
          - added patch.

     Specific GL driver initialization does not depend on anything in the device or context besides making
     a decision to call or skip the next driver. Copying the driver constant function pointers out allows
     to call driver's _wine_get_wgl_driver outside of any DC lock in the next patch.

 dlls/win32u/dibdrv/dc.c     | 11 ++++++-----
 dlls/win32u/driver.c        | 24 +++++++++++++++++++++---
 dlls/wineandroid.drv/init.c | 11 ++---------
 dlls/winemac.drv/opengl.c   |  4 +++-
 dlls/winex11.drv/init.c     | 11 ++---------
 include/wine/gdi_driver.h   |  2 +-
 6 files changed, 35 insertions(+), 28 deletions(-)

diff --git a/dlls/win32u/dibdrv/dc.c b/dlls/win32u/dibdrv/dc.c
index a96b613d0a3..4cc95e6b843 100644
--- a/dlls/win32u/dibdrv/dc.c
+++ b/dlls/win32u/dibdrv/dc.c
@@ -605,8 +605,10 @@ static struct opengl_funcs opengl_funcs =
 /**********************************************************************
  *	     dibdrv_wine_get_wgl_driver
  */
-static struct opengl_funcs * CDECL dibdrv_wine_get_wgl_driver( PHYSDEV dev, UINT version )
+static struct opengl_funcs * CDECL dibdrv_wine_get_wgl_driver( UINT version, const struct gdi_dc_funcs ***next_funcs )
 {
+    *next_funcs = NULL;
+
     if (version != WINE_WGL_DRIVER_VERSION)
     {
         ERR( "version mismatch, opengl32 wants %u but dibdrv has %u\n", version, WINE_WGL_DRIVER_VERSION );
@@ -1177,11 +1179,10 @@ static INT CDECL windrv_StretchDIBits( PHYSDEV dev, INT x_dst, INT y_dst, INT wi
     return ret;
 }
 
-static struct opengl_funcs * CDECL windrv_wine_get_wgl_driver( PHYSDEV dev, UINT version )
+static struct opengl_funcs * CDECL windrv_wine_get_wgl_driver( UINT version, const struct gdi_dc_funcs ***next_funcs )
 {
-    dev = GET_NEXT_PHYSDEV( dev, wine_get_wgl_driver );
-    if (dev->funcs == &dib_driver) dev = GET_NEXT_PHYSDEV( dev, wine_get_wgl_driver );
-    return dev->funcs->wine_get_wgl_driver( dev, version );
+    if (*(*next_funcs + 1) == &dib_driver) ++*next_funcs;
+    return NULL;
 }
 
 static const struct gdi_dc_funcs window_driver =
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c
index 39996086c6d..f527c6c51cf 100644
--- a/dlls/win32u/driver.c
+++ b/dlls/win32u/driver.c
@@ -579,8 +579,10 @@ static NTSTATUS CDECL nulldrv_D3DKMTSetVidPnSourceOwner( const D3DKMT_SETVIDPNSO
     return STATUS_PROCEDURE_NOT_FOUND;
 }
 
-static struct opengl_funcs * CDECL nulldrv_wine_get_wgl_driver( PHYSDEV dev, UINT version )
+static struct opengl_funcs * CDECL nulldrv_wine_get_wgl_driver( UINT version, const struct gdi_dc_funcs ***next_funcs )
 {
+    *next_funcs = NULL;
+
     return (void *)-1;
 }
 
@@ -1347,13 +1349,29 @@ NTSTATUS WINAPI NtGdiDdDDICheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNE
  */
 struct opengl_funcs * CDECL __wine_get_wgl_driver( HDC hdc, UINT version )
 {
+    const struct gdi_dc_funcs *driver_funcs[11], **next_funcs;
     struct opengl_funcs *ret = NULL;
     DC * dc = get_dc_ptr( hdc );
+    PHYSDEV physdev;
 
     if (dc)
     {
-        PHYSDEV physdev = GET_DC_PHYSDEV( dc, wine_get_wgl_driver );
-        ret = physdev->funcs->wine_get_wgl_driver( physdev, version );
+        next_funcs = driver_funcs;
+        physdev = GET_DC_PHYSDEV( dc, wine_get_wgl_driver );
+        while (physdev && next_funcs - driver_funcs < ARRAY_SIZE(driver_funcs) - 1)
+        {
+            *next_funcs++ = physdev->funcs;
+            if (physdev->funcs == &null_driver) break;
+            physdev = GET_NEXT_PHYSDEV( physdev, wine_get_wgl_driver );
+        }
+        *next_funcs = NULL;
+        next_funcs = driver_funcs;
+        while (*next_funcs)
+        {
+            ret = (*next_funcs)->wine_get_wgl_driver( version, &next_funcs );
+            if (ret || !next_funcs) break;
+            ++next_funcs;
+        }
         release_dc_ptr( dc );
     }
     return ret;
diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c
index ed9116eb47e..3c7da3f780f 100644
--- a/dlls/wineandroid.drv/init.c
+++ b/dlls/wineandroid.drv/init.c
@@ -261,16 +261,9 @@ BOOL CDECL ANDROID_EnumDisplaySettingsEx( LPCWSTR name, DWORD n, LPDEVMODEW devm
 /**********************************************************************
  *           ANDROID_wine_get_wgl_driver
  */
-static struct opengl_funcs * CDECL ANDROID_wine_get_wgl_driver( PHYSDEV dev, UINT version )
+static struct opengl_funcs * CDECL ANDROID_wine_get_wgl_driver( UINT version, const struct gdi_dc_funcs ***next_funcs )
 {
-    struct opengl_funcs *ret;
-
-    if (!(ret = get_wgl_driver( version )))
-    {
-        dev = GET_NEXT_PHYSDEV( dev, wine_get_wgl_driver );
-        ret = dev->funcs->wine_get_wgl_driver( dev, version );
-    }
-    return ret;
+    return get_wgl_driver( version );
 }
 
 
diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c
index daf194c2aec..b5670906e93 100644
--- a/dlls/winemac.drv/opengl.c
+++ b/dlls/winemac.drv/opengl.c
@@ -4632,10 +4632,12 @@ static struct opengl_funcs opengl_funcs =
 /**********************************************************************
  *              macdrv_wine_get_wgl_driver
  */
-struct opengl_funcs * CDECL macdrv_wine_get_wgl_driver(PHYSDEV dev, UINT version)
+struct opengl_funcs * CDECL macdrv_wine_get_wgl_driver(UINT version, const struct gdi_dc_funcs ***next_funcs)
 {
     static INIT_ONCE opengl_init = INIT_ONCE_STATIC_INIT;
 
+    *next_funcs = NULL;
+
     if (version != WINE_WGL_DRIVER_VERSION)
     {
         ERR("version mismatch, opengl32 wants %u but macdrv has %u\n", version, WINE_WGL_DRIVER_VERSION);
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c
index 5b31c352a23..ebd221c2d38 100644
--- a/dlls/winex11.drv/init.c
+++ b/dlls/winex11.drv/init.c
@@ -312,16 +312,9 @@ static INT CDECL X11DRV_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOI
 /**********************************************************************
  *           X11DRV_wine_get_wgl_driver
  */
-static struct opengl_funcs * CDECL X11DRV_wine_get_wgl_driver( PHYSDEV dev, UINT version )
+static struct opengl_funcs * CDECL X11DRV_wine_get_wgl_driver( UINT version, const struct gdi_dc_funcs ***next_funcs )
 {
-    struct opengl_funcs *ret;
-
-    if (!(ret = get_glx_driver( version )))
-    {
-        dev = GET_NEXT_PHYSDEV( dev, wine_get_wgl_driver );
-        ret = dev->funcs->wine_get_wgl_driver( dev, version );
-    }
-    return ret;
+    return get_glx_driver( version );
 }
 
 /**********************************************************************
diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h
index 567a6c21608..0e3bbade6c4 100644
--- a/include/wine/gdi_driver.h
+++ b/include/wine/gdi_driver.h
@@ -159,7 +159,7 @@ struct gdi_dc_funcs
     BOOL     (CDECL *pUnrealizePalette)(HPALETTE);
     NTSTATUS (CDECL *pD3DKMTCheckVidPnExclusiveOwnership)(const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *);
     NTSTATUS (CDECL *pD3DKMTSetVidPnSourceOwner)(const D3DKMT_SETVIDPNSOURCEOWNER *);
-    struct opengl_funcs * (CDECL *wine_get_wgl_driver)(PHYSDEV,UINT);
+    struct opengl_funcs * (CDECL *wine_get_wgl_driver)(UINT,const struct gdi_dc_funcs ***);
 
     /* priority order for the driver on the stack */
     UINT       priority;
-- 
2.34.1




More information about the wine-devel mailing list