[PATCH v2 2/2] win32u: Cache GL driver functions in DC.
Paul Gofman
pgofman at codeweavers.com
Tue Feb 1 11:32:30 CST 2022
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
v2:
- call actual driver init function outside of any locks.
dlls/win32u/dc.c | 19 -------------
dlls/win32u/driver.c | 55 +++++++++++++++++++++++--------------
dlls/win32u/ntgdi_private.h | 21 ++++++++++++++
3 files changed, 56 insertions(+), 39 deletions(-)
diff --git a/dlls/win32u/dc.c b/dlls/win32u/dc.c
index aed2d3684a7..cb38c4161ee 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)
{
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c
index f527c6c51cf..eda49ab2700 100644
--- a/dlls/win32u/driver.c
+++ b/dlls/win32u/driver.c
@@ -1350,29 +1350,44 @@ 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 );
+ struct opengl_funcs *ret;
PHYSDEV physdev;
+ DC * dc;
- if (dc)
+ if (!(dc = get_dc_obj( hdc ))) return NULL;
+ if (dc->attr->disabled)
{
- 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 );
+ GDI_ReleaseObj( hdc );
+ return NULL;
+ }
+ if ((ret = dc->gl_funcs))
+ {
+ GDI_ReleaseObj( hdc );
+ return ret;
}
+
+ 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;
+ GDI_ReleaseObj( hdc );
+
+ next_funcs = driver_funcs;
+ while (*next_funcs)
+ {
+ ret = (*next_funcs)->wine_get_wgl_driver( version, &next_funcs );
+ if (ret || !next_funcs) break;
+ ++next_funcs;
+ }
+
+ if (!(dc = get_dc_obj( hdc ))) return NULL;
+ if (dc->gl_funcs) ret = dc->gl_funcs;
+ else dc->gl_funcs = ret;
+ GDI_ReleaseObj( hdc );
return ret;
}
diff --git a/dlls/win32u/ntgdi_private.h b/dlls/win32u/ntgdi_private.h
index bfeb4557da7..54a4dc17eaf 100644
--- a/dlls/win32u/ntgdi_private.h
+++ b/dlls/win32u/ntgdi_private.h
@@ -87,6 +87,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.
@@ -660,6 +662,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;
--
2.34.1
More information about the wine-devel
mailing list