[PATCH v4] win32u: Cache GL driver functions in DC.
Paul Gofman
pgofman at codeweavers.com
Fri Feb 18 09:52:45 CST 2022
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
v4:
- move wine_get_wgl_driver() to user driver and add a special case for dibdrv.
dlls/user32/driver.c | 4 ++-
dlls/win32u/dc.c | 58 +++++++++++++++++++++++++------------
dlls/win32u/dibdrv/dc.c | 11 +------
dlls/win32u/driver.c | 36 +++++++++++++++--------
dlls/win32u/emfdrv.c | 1 -
dlls/win32u/font.c | 1 -
dlls/win32u/ntgdi_private.h | 25 ++++++++++++++++
dlls/win32u/path.c | 1 -
dlls/wineandroid.drv/init.c | 13 ++-------
dlls/winemac.drv/gdi.c | 2 +-
dlls/winemac.drv/macdrv.h | 2 +-
dlls/winemac.drv/opengl.c | 2 +-
dlls/wineps.drv/init.c | 1 -
dlls/winex11.drv/init.c | 13 ++-------
dlls/winex11.drv/xrender.c | 1 -
include/wine/gdi_driver.h | 3 +-
16 files changed, 103 insertions(+), 71 deletions(-)
diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
index 7e9f63ad1c7..2c5497761a0 100644
--- a/dlls/user32/driver.c
+++ b/dlls/user32/driver.c
@@ -394,7 +394,9 @@ static struct user_driver_funcs lazy_load_driver =
/* vulkan support */
NULL,
/* thread management */
- NULL
+ NULL,
+ /* opengl support */
+ NULL,
};
void CDECL __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version )
diff --git a/dlls/win32u/dc.c b/dlls/win32u/dc.c
index aed2d3684a7..e7ebb57776b 100644
--- a/dlls/win32u/dc.c
+++ b/dlls/win32u/dc.c
@@ -63,25 +63,6 @@ static const struct gdi_obj_funcs dc_funcs =
};
-static inline DC *get_dc_obj( HDC hdc )
-{
- DWORD type;
- DC *dc = get_any_obj_ptr( hdc, &type );
- if (!dc) return NULL;
-
- switch (type)
- {
- case NTGDI_OBJ_DC:
- case NTGDI_OBJ_MEMDC:
- case NTGDI_OBJ_ENHMETADC:
- return dc;
- default:
- GDI_ReleaseObj( hdc );
- SetLastError( ERROR_INVALID_HANDLE );
- return NULL;
- }
-}
-
/* alloc DC_ATTR from a pool of memory accessible from client */
static DC_ATTR *alloc_dc_attr(void)
{
@@ -310,6 +291,43 @@ DC *get_dc_ptr( HDC hdc )
}
+/***********************************************************************
+ * grab_dc
+ *
+ * Retrieve a DC pointer, increase ref count and release the GDI lock.
+ */
+DC *grab_dc( HDC hdc )
+{
+ DC *dc;
+
+ if (!GDI_inc_ref_count( hdc )) return NULL;
+ if (!(dc = get_dc_obj( hdc )))
+ {
+ GDI_dec_ref_count( hdc );
+ return NULL;
+ }
+ if (dc->attr->disabled)
+ {
+ GDI_dec_ref_count( hdc );
+ GDI_ReleaseObj( hdc );
+ return NULL;
+ }
+ GDI_ReleaseObj( hdc );
+ return dc;
+}
+
+
+/***********************************************************************
+ * put_dc
+ *
+ * Decrease ref count previously increased by grab_dc().
+ */
+void put_dc( HDC hdc )
+{
+ GDI_dec_ref_count( hdc );
+}
+
+
/***********************************************************************
* release_dc_ptr
*/
@@ -816,6 +834,8 @@ HDC WINAPI NtGdiCreateCompatibleDC( HDC hdc )
free_dc_ptr( dc );
return 0;
}
+ dc->dibdrv = TRUE;
+
physDev = GET_DC_PHYSDEV( dc, pSelectBitmap );
physDev->funcs->pSelectBitmap( physDev, dc->hBitmap );
diff --git a/dlls/win32u/dibdrv/dc.c b/dlls/win32u/dibdrv/dc.c
index a96b613d0a3..a91cd76f936 100644
--- a/dlls/win32u/dibdrv/dc.c
+++ b/dlls/win32u/dibdrv/dc.c
@@ -605,7 +605,7 @@ 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 )
+struct opengl_funcs *dibdrv_wine_get_wgl_driver( UINT version )
{
if (version != WINE_WGL_DRIVER_VERSION)
{
@@ -715,7 +715,6 @@ const struct gdi_dc_funcs dib_driver =
NULL, /* pUnrealizePalette */
NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */
NULL, /* pD3DKMTSetVidPnSourceOwner */
- dibdrv_wine_get_wgl_driver, /* wine_get_wgl_driver */
GDI_PRIORITY_DIB_DRV /* priority */
};
@@ -1177,13 +1176,6 @@ 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 )
-{
- 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 );
-}
-
static const struct gdi_dc_funcs window_driver =
{
NULL, /* pAbortDoc */
@@ -1277,6 +1269,5 @@ static const struct gdi_dc_funcs window_driver =
NULL, /* pUnrealizePalette */
NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */
NULL, /* pD3DKMTSetVidPnSourceOwner */
- windrv_wine_get_wgl_driver, /* wine_get_wgl_driver */
GDI_PRIORITY_DIB_DRV + 10 /* priority */
};
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c
index 5e6cee33bc6..ea7165bc3ae 100644
--- a/dlls/win32u/driver.c
+++ b/dlls/win32u/driver.c
@@ -571,11 +571,6 @@ 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 )
-{
- return (void *)-1;
-}
-
const struct gdi_dc_funcs null_driver =
{
nulldrv_AbortDoc, /* pAbortDoc */
@@ -669,7 +664,6 @@ const struct gdi_dc_funcs null_driver =
nulldrv_UnrealizePalette, /* pUnrealizePalette */
nulldrv_D3DKMTCheckVidPnExclusiveOwnership, /* pD3DKMTCheckVidPnExclusiveOwnership */
nulldrv_D3DKMTSetVidPnSourceOwner, /* pD3DKMTSetVidPnSourceOwner */
- nulldrv_wine_get_wgl_driver, /* wine_get_wgl_driver */
GDI_PRIORITY_NULL_DRV /* priority */
};
@@ -1373,14 +1367,32 @@ NTSTATUS WINAPI NtGdiDdDDICheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNE
*/
struct opengl_funcs * CDECL __wine_get_wgl_driver( HDC hdc, UINT version )
{
- struct opengl_funcs *ret = NULL;
- DC * dc = get_dc_ptr( hdc );
+ struct opengl_funcs *ret;
+ PHYSDEV physdev;
+ BOOL dibdrv;
+ DC * dc;
+
+ if (!(dc = get_dc_obj( hdc ))) return NULL;
+ if (dc->attr->disabled)
+ {
+ GDI_ReleaseObj( hdc );
+ return NULL;
+ }
+ ret = dc->gl_funcs;
+ dibdrv = dc->dibdrv;
+ GDI_ReleaseObj( hdc );
+
+ if (ret) return ret;
- if (dc)
+ if (dibdrv) ret = dibdrv_wine_get_wgl_driver( version );
+ else
{
- PHYSDEV physdev = GET_DC_PHYSDEV( dc, wine_get_wgl_driver );
- ret = physdev->funcs->wine_get_wgl_driver( physdev, version );
- release_dc_ptr( dc );
+ if (user_driver->pwine_get_wgl_driver) ret = user_driver->pwine_get_wgl_driver( version );
+ else ret = (void *)-1;
}
+ if (!(dc = get_dc_obj( hdc ))) return NULL;
+ if (!dc->gl_funcs) dc->gl_funcs = ret;
+ else ret = dc->gl_funcs;
+ GDI_ReleaseObj( hdc );
return ret;
}
diff --git a/dlls/win32u/emfdrv.c b/dlls/win32u/emfdrv.c
index f261a86e392..81481953288 100644
--- a/dlls/win32u/emfdrv.c
+++ b/dlls/win32u/emfdrv.c
@@ -524,7 +524,6 @@ static const struct gdi_dc_funcs emfdrv_driver =
NULL, /* pUnrealizePalette */
NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */
NULL, /* pD3DKMTSetVidPnSourceOwner */
- NULL, /* wine_get_wgl_driver */
GDI_PRIORITY_GRAPHICS_DRV /* priority */
};
diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c
index b8213ac9e6a..87ef75f04af 100644
--- a/dlls/win32u/font.c
+++ b/dlls/win32u/font.c
@@ -4351,7 +4351,6 @@ const struct gdi_dc_funcs font_driver =
NULL, /* pUnrealizePalette */
NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */
NULL, /* pD3DKMTSetVidPnSourceOwner */
- NULL, /* wine_get_wgl_driver */
GDI_PRIORITY_FONT_DRV /* priority */
};
diff --git a/dlls/win32u/ntgdi_private.h b/dlls/win32u/ntgdi_private.h
index bfeb4557da7..f256ed36d38 100644
--- a/dlls/win32u/ntgdi_private.h
+++ b/dlls/win32u/ntgdi_private.h
@@ -59,6 +59,7 @@ typedef struct tagDC
DCHOOKPROC hookProc; /* DC hook */
BOOL bounds_enabled:1; /* bounds tracking is enabled */
BOOL path_open:1; /* path is currently open (only for saved DCs) */
+ BOOL dibdrv:1; /* memory DC */
RECT device_rect; /* rectangle for the whole device */
int pixel_format; /* pixel format (for memory DCs) */
@@ -87,6 +88,8 @@ typedef struct tagDC
XFORM xformVport2World; /* Inverse of the above transformation */
BOOL vport2WorldValid; /* Is xformVport2World valid? */
RECT bounds; /* Current bounding rect */
+
+ struct opengl_funcs *gl_funcs; /* Opengl driver functions */
} DC;
/* Certain functions will do no further processing if the driver returns this.
@@ -170,6 +173,8 @@ static inline HRGN get_dc_region( DC *dc )
extern DC *alloc_dc_ptr( DWORD magic ) DECLSPEC_HIDDEN;
extern void free_dc_ptr( DC *dc ) DECLSPEC_HIDDEN;
extern DC *get_dc_ptr( HDC hdc ) DECLSPEC_HIDDEN;
+extern DC *grab_dc( HDC hdc ) DECLSPEC_HIDDEN;
+extern void put_dc( HDC hdc ) DECLSPEC_HIDDEN;
extern void release_dc_ptr( DC *dc ) DECLSPEC_HIDDEN;
extern void update_dc( DC *dc ) DECLSPEC_HIDDEN;
extern void DC_InitDC( DC * dc ) DECLSPEC_HIDDEN;
@@ -206,6 +211,7 @@ extern UINT get_dib_dc_color_table( HDC hdc, UINT startpos, UINT entries,
extern UINT set_dib_dc_color_table( HDC hdc, UINT startpos, UINT entries,
const RGBQUAD *colors ) DECLSPEC_HIDDEN;
extern void dibdrv_set_window_surface( DC *dc, struct window_surface *surface ) DECLSPEC_HIDDEN;
+extern struct opengl_funcs *dibdrv_wine_get_wgl_driver( UINT version ) DECLSPEC_HIDDEN;
/* driver.c */
extern const struct gdi_dc_funcs null_driver DECLSPEC_HIDDEN;
@@ -660,6 +666,25 @@ static inline void copy_bitmapinfo( BITMAPINFO *dst, const BITMAPINFO *src )
memcpy( dst, src, get_dib_info_size( src, DIB_RGB_COLORS ));
}
+static inline DC *get_dc_obj( HDC hdc )
+{
+ DWORD type;
+ DC *dc = get_any_obj_ptr( hdc, &type );
+ if (!dc) return NULL;
+
+ switch (type)
+ {
+ case NTGDI_OBJ_DC:
+ case NTGDI_OBJ_MEMDC:
+ case NTGDI_OBJ_ENHMETADC:
+ return dc;
+ default:
+ GDI_ReleaseObj( hdc );
+ SetLastError( ERROR_INVALID_HANDLE );
+ return NULL;
+ }
+}
+
extern void CDECL free_heap_bits( struct gdi_image_bits *bits ) DECLSPEC_HIDDEN;
void set_gdi_client_ptr( HGDIOBJ handle, void *ptr ) DECLSPEC_HIDDEN;
diff --git a/dlls/win32u/path.c b/dlls/win32u/path.c
index a87a7ab06c2..93a124953af 100644
--- a/dlls/win32u/path.c
+++ b/dlls/win32u/path.c
@@ -2121,6 +2121,5 @@ const struct gdi_dc_funcs path_driver =
NULL, /* pUnrealizePalette */
NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */
NULL, /* pD3DKMTSetVidPnSourceOwner */
- NULL, /* wine_get_wgl_driver */
GDI_PRIORITY_PATH_DRV /* priority */
};
diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c
index ed9116eb47e..7c103475e6b 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 )
{
- 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 );
}
@@ -279,7 +272,6 @@ static const struct user_driver_funcs android_drv_funcs =
.dc_funcs.pCreateCompatibleDC = ANDROID_CreateCompatibleDC,
.dc_funcs.pCreateDC = ANDROID_CreateDC,
.dc_funcs.pDeleteDC = ANDROID_DeleteDC,
- .dc_funcs.wine_get_wgl_driver = ANDROID_wine_get_wgl_driver,
.dc_funcs.priority = GDI_PRIORITY_GRAPHICS_DRV,
.pGetKeyNameText = ANDROID_GetKeyNameText,
@@ -302,6 +294,7 @@ static const struct user_driver_funcs android_drv_funcs =
.pWindowMessage = ANDROID_WindowMessage,
.pWindowPosChanging = ANDROID_WindowPosChanging,
.pWindowPosChanged = ANDROID_WindowPosChanged,
+ .pwine_get_wgl_driver = ANDROID_wine_get_wgl_driver,
};
diff --git a/dlls/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c
index 40ba4c570c5..264781c6ac1 100644
--- a/dlls/winemac.drv/gdi.c
+++ b/dlls/winemac.drv/gdi.c
@@ -268,7 +268,6 @@ static const struct user_driver_funcs macdrv_funcs =
.dc_funcs.pGetDeviceCaps = macdrv_GetDeviceCaps,
.dc_funcs.pGetDeviceGammaRamp = macdrv_GetDeviceGammaRamp,
.dc_funcs.pSetDeviceGammaRamp = macdrv_SetDeviceGammaRamp,
- .dc_funcs.wine_get_wgl_driver = macdrv_wine_get_wgl_driver,
.dc_funcs.priority = GDI_PRIORITY_GRAPHICS_DRV,
.pActivateKeyboardLayout = macdrv_ActivateKeyboardLayout,
@@ -309,6 +308,7 @@ static const struct user_driver_funcs macdrv_funcs =
.pWindowPosChanged = macdrv_WindowPosChanged,
.pWindowPosChanging = macdrv_WindowPosChanging,
.pwine_get_vulkan_driver = macdrv_wine_get_vulkan_driver,
+ .pwine_get_wgl_driver = macdrv_wine_get_wgl_driver,
};
diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h
index 0bd0a18f111..4e4524722af 100644
--- a/dlls/winemac.drv/macdrv.h
+++ b/dlls/winemac.drv/macdrv.h
@@ -263,7 +263,7 @@ extern DWORD CDECL macdrv_MsgWaitForMultipleObjectsEx(DWORD count, const HANDLE
extern BOOL query_drag_exited(macdrv_query* query) DECLSPEC_HIDDEN;
extern BOOL query_drag_drop(macdrv_query* query) DECLSPEC_HIDDEN;
-extern struct opengl_funcs * CDECL macdrv_wine_get_wgl_driver(PHYSDEV dev, UINT version) DECLSPEC_HIDDEN;
+extern struct opengl_funcs * CDECL macdrv_wine_get_wgl_driver(UINT version) DECLSPEC_HIDDEN;
extern const struct vulkan_funcs * CDECL macdrv_wine_get_vulkan_driver(UINT version) DECLSPEC_HIDDEN;
extern void sync_gl_view(struct macdrv_win_data* data, const RECT* old_whole_rect, const RECT* old_client_rect) DECLSPEC_HIDDEN;
diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c
index daf194c2aec..02ac613ddc9 100644
--- a/dlls/winemac.drv/opengl.c
+++ b/dlls/winemac.drv/opengl.c
@@ -4632,7 +4632,7 @@ 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)
{
static INIT_ONCE opengl_init = INIT_ONCE_STATIC_INIT;
diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c
index 9e32bf31d1f..5a01a97973f 100644
--- a/dlls/wineps.drv/init.c
+++ b/dlls/wineps.drv/init.c
@@ -858,7 +858,6 @@ static const struct gdi_dc_funcs psdrv_funcs =
NULL, /* pUnrealizePalette */
NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */
NULL, /* pD3DKMTSetVidPnSourceOwner */
- NULL, /* wine_get_wgl_driver */
GDI_PRIORITY_GRAPHICS_DRV /* priority */
};
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c
index 5b31c352a23..35bf47c2e74 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 )
{
- 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 );
}
/**********************************************************************
@@ -377,7 +370,6 @@ static const struct user_driver_funcs x11drv_funcs =
.dc_funcs.pUnrealizePalette = X11DRV_UnrealizePalette,
.dc_funcs.pD3DKMTCheckVidPnExclusiveOwnership = X11DRV_D3DKMTCheckVidPnExclusiveOwnership,
.dc_funcs.pD3DKMTSetVidPnSourceOwner = X11DRV_D3DKMTSetVidPnSourceOwner,
- .dc_funcs.wine_get_wgl_driver = X11DRV_wine_get_wgl_driver,
.dc_funcs.priority = GDI_PRIORITY_GRAPHICS_DRV,
.pActivateKeyboardLayout = X11DRV_ActivateKeyboardLayout,
@@ -418,6 +410,7 @@ static const struct user_driver_funcs x11drv_funcs =
.pWindowPosChanging = X11DRV_WindowPosChanging,
.pWindowPosChanged = X11DRV_WindowPosChanged,
.pSystemParametersInfo = X11DRV_SystemParametersInfo,
+ .pwine_get_wgl_driver = X11DRV_wine_get_wgl_driver,
.pwine_get_vulkan_driver = X11DRV_wine_get_vulkan_driver,
.pThreadDetach = X11DRV_ThreadDetach,
};
diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c
index 92dc35fa9e1..5ede97fb026 100644
--- a/dlls/winex11.drv/xrender.c
+++ b/dlls/winex11.drv/xrender.c
@@ -2246,7 +2246,6 @@ static const struct gdi_dc_funcs xrender_funcs =
NULL, /* pUnrealizePalette */
NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */
NULL, /* pD3DKMTSetVidPnSourceOwner */
- NULL, /* wine_get_wgl_driver */
GDI_PRIORITY_GRAPHICS_DRV + 10 /* priority */
};
diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h
index 567a6c21608..24a4bba1c8b 100644
--- a/include/wine/gdi_driver.h
+++ b/include/wine/gdi_driver.h
@@ -159,7 +159,6 @@ 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);
/* priority order for the driver on the stack */
UINT priority;
@@ -323,6 +322,8 @@ struct user_driver_funcs
const struct vulkan_funcs * (CDECL *pwine_get_vulkan_driver)(UINT);
/* thread management */
void (CDECL *pThreadDetach)(void);
+ /* opengl support */
+ struct opengl_funcs * (CDECL *pwine_get_wgl_driver)(UINT);
};
extern void CDECL __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version );
--
2.35.1
More information about the wine-devel
mailing list