From: Zhiyi Zhang zzhang@codeweavers.com
Using EnumDisplaySettings() directly to query display depth has a high overhead when using the XRandR 1.0 display device handler on some NVIDIA setups.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51420 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53382 --- dlls/win32u/driver.c | 19 +++++++++++++------ dlls/win32u/sysparams.c | 25 +++++++++++++++++++++++++ dlls/win32u/win32u_private.h | 1 + dlls/winemac.drv/display.c | 8 ++++++++ dlls/winemac.drv/gdi.c | 1 + dlls/winemac.drv/macdrv.h | 1 + dlls/winex11.drv/display.c | 10 ++++++++++ dlls/winex11.drv/init.c | 1 + dlls/winex11.drv/x11drv.h | 1 + include/wine/gdi_driver.h | 1 + 10 files changed, 62 insertions(+), 6 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 557d555d673..e2c9ba04efd 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -207,18 +207,13 @@ static INT CDECL nulldrv_GetDeviceCaps( PHYSDEV dev, INT cap ) case BITSPIXEL: { UNICODE_STRING display; - DEVMODEW devmode; DC *dc;
if (NtGdiGetDeviceCaps( dev->hdc, TECHNOLOGY ) == DT_RASDISPLAY) { dc = get_nulldrv_dc( dev ); - memset( &devmode, 0, sizeof(devmode) ); - devmode.dmSize = sizeof(devmode); RtlInitUnicodeString( &display, dc->display ); - if (NtUserEnumDisplaySettings( &display, ENUM_CURRENT_SETTINGS, &devmode, 0 ) && - (devmode.dmFields & DM_BITSPERPEL) && devmode.dmBitsPerPel) - return devmode.dmBitsPerPel; + return get_display_depth( &display ); } return 32; } @@ -764,6 +759,11 @@ static BOOL nulldrv_GetCurrentDisplaySettings( LPCWSTR name, BOOL is_primary, LP return FALSE; /* use default implementation */ }
+static INT nulldrv_GetDisplayDepth( LPCWSTR name, BOOL is_primary ) +{ + return 32; +} + static BOOL nulldrv_UpdateDisplayDevices( const struct gdi_device_manager *manager, BOOL force, void *param ) { return FALSE; @@ -1077,6 +1077,11 @@ static BOOL loaderdrv_GetCurrentDisplaySettings( LPCWSTR name, BOOL is_primary, return load_driver()->pGetCurrentDisplaySettings( name, is_primary, mode ); }
+static INT loaderdrv_GetDisplayDepth( LPCWSTR name, BOOL is_primary ) +{ + return load_driver()->pGetDisplayDepth( name, is_primary ); +} + static void loaderdrv_SetCursor( HCURSOR cursor ) { load_driver()->pSetCursor( cursor ); @@ -1179,6 +1184,7 @@ static const struct user_driver_funcs lazy_load_driver = /* display modes */ loaderdrv_ChangeDisplaySettings, loaderdrv_GetCurrentDisplaySettings, + loaderdrv_GetDisplayDepth, loaderdrv_UpdateDisplayDevices, /* windowing functions */ loaderdrv_CreateDesktopWindow, @@ -1254,6 +1260,7 @@ void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version SET_USER_FUNC(UpdateClipboard); SET_USER_FUNC(ChangeDisplaySettings); SET_USER_FUNC(GetCurrentDisplaySettings); + SET_USER_FUNC(GetDisplayDepth); SET_USER_FUNC(UpdateDisplayDevices); SET_USER_FUNC(CreateDesktopWindow); SET_USER_FUNC(CreateWindow); diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 13aaaa308c9..2269193b7ff 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2655,6 +2655,31 @@ static unsigned int active_monitor_count(void) return count; }
+INT get_display_depth( UNICODE_STRING *name ) +{ + struct display_device *device; + INT depth; + + if (!lock_display_devices()) + return 32; + + if (name && name->Length) + device = find_adapter_device_by_name( name ); + else + device = find_adapter_device_by_id( 0 ); /* use primary adapter */ + + if (!device) + { + unlock_display_devices(); + return 32; + } + + depth = user_driver->pGetDisplayDepth( device->device_name, + !!(device->state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE) ); + unlock_display_devices(); + return depth; +} + /*********************************************************************** * NtUserEnumDisplayMonitors (win32u.@) */ diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index dfa83daba91..96b1b7647fe 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -334,6 +334,7 @@ extern BOOL enable_thunk_lock DECLSPEC_HIDDEN; extern HBRUSH get_55aa_brush(void) DECLSPEC_HIDDEN; extern DWORD get_dialog_base_units(void) DECLSPEC_HIDDEN; extern LONG get_char_dimensions( HDC hdc, TEXTMETRICW *metric, int *height ) DECLSPEC_HIDDEN; +extern INT get_display_depth( UNICODE_STRING *name ) DECLSPEC_HIDDEN; extern RECT get_display_rect( const WCHAR *display ) DECLSPEC_HIDDEN; extern UINT get_monitor_dpi( HMONITOR monitor ) DECLSPEC_HIDDEN; extern BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info ) DECLSPEC_HIDDEN; diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index 12e12d297d9..dab81cc8ffb 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -927,6 +927,14 @@ BOOL macdrv_GetCurrentDisplaySettings(LPCWSTR devname, BOOL is_primary, LPDEVMOD return TRUE; }
+/*********************************************************************** + * GetDisplayDepth (MACDRV.@) + * + */ +INT macdrv_GetDisplayDepth(LPCWSTR name, BOOL is_primary) +{ + return get_default_bpp(); +}
/*********************************************************************** * GetDeviceGammaRamp (MACDRV.@) diff --git a/dlls/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c index 193a3f4bbd2..fd1da722061 100644 --- a/dlls/winemac.drv/gdi.c +++ b/dlls/winemac.drv/gdi.c @@ -276,6 +276,7 @@ static const struct user_driver_funcs macdrv_funcs = .pDestroyCursorIcon = macdrv_DestroyCursorIcon, .pDestroyWindow = macdrv_DestroyWindow, .pGetCurrentDisplaySettings = macdrv_GetCurrentDisplaySettings, + .pGetDisplayDepth = macdrv_GetDisplayDepth, .pUpdateDisplayDevices = macdrv_UpdateDisplayDevices, .pGetCursorPos = macdrv_GetCursorPos, .pGetKeyboardLayoutList = macdrv_GetKeyboardLayoutList, diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index f6f9e5b6c67..40f70e55094 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -124,6 +124,7 @@ extern BOOL macdrv_ActivateKeyboardLayout(HKL hkl, UINT flags) DECLSPEC_HIDDEN; extern void macdrv_Beep(void) DECLSPEC_HIDDEN; extern LONG macdrv_ChangeDisplaySettings(LPDEVMODEW displays, LPCWSTR primary_name, HWND hwnd, DWORD flags, LPVOID lpvoid) DECLSPEC_HIDDEN; extern BOOL macdrv_GetCurrentDisplaySettings(LPCWSTR name, BOOL is_primary, LPDEVMODEW devmode) DECLSPEC_HIDDEN; +extern INT macdrv_GetDisplayDepth(LPCWSTR name, BOOL is_primary) DECLSPEC_HIDDEN; extern LRESULT macdrv_ClipboardWindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) DECLSPEC_HIDDEN; extern BOOL macdrv_UpdateDisplayDevices( const struct gdi_device_manager *device_manager, BOOL force, void *param ) DECLSPEC_HIDDEN; diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index 5e8305432a0..34085c49543 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -239,6 +239,16 @@ static DWORD get_display_depth(ULONG_PTR display_id) return screen_bpp; }
+INT X11DRV_GetDisplayDepth(LPCWSTR name, BOOL is_primary) +{ + ULONG_PTR id; + + if (settings_handler.get_id( name, is_primary, &id )) + return get_display_depth( id ); + + return screen_bpp; +} + /*********************************************************************** * GetCurrentDisplaySettings (X11DRV.@) * diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 4ebe3a16367..7e343591413 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -405,6 +405,7 @@ static const struct user_driver_funcs x11drv_funcs = .pClipCursor = X11DRV_ClipCursor, .pChangeDisplaySettings = X11DRV_ChangeDisplaySettings, .pGetCurrentDisplaySettings = X11DRV_GetCurrentDisplaySettings, + .pGetDisplayDepth = X11DRV_GetDisplayDepth, .pUpdateDisplayDevices = X11DRV_UpdateDisplayDevices, .pCreateDesktopWindow = X11DRV_CreateDesktopWindow, .pCreateWindow = X11DRV_CreateWindow, diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index b394795a326..4997367ce9a 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -216,6 +216,7 @@ extern BOOL X11DRV_GetCursorPos( LPPOINT pos ) DECLSPEC_HIDDEN; extern BOOL X11DRV_ClipCursor( LPCRECT clip ) DECLSPEC_HIDDEN; extern LONG X11DRV_ChangeDisplaySettings( LPDEVMODEW displays, LPCWSTR primary_name, HWND hwnd, DWORD flags, LPVOID lpvoid ) DECLSPEC_HIDDEN; extern BOOL X11DRV_GetCurrentDisplaySettings( LPCWSTR name, BOOL is_primary, LPDEVMODEW devmode ) DECLSPEC_HIDDEN; +extern INT X11DRV_GetDisplayDepth( LPCWSTR name, BOOL is_primary ) DECLSPEC_HIDDEN; extern BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manager, BOOL force, void *param ) DECLSPEC_HIDDEN; extern BOOL X11DRV_CreateDesktopWindow( HWND hwnd ) DECLSPEC_HIDDEN; diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index d074c09cceb..3db3d0d6af3 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -299,6 +299,7 @@ struct user_driver_funcs /* display modes */ LONG (*pChangeDisplaySettings)(LPDEVMODEW,LPCWSTR,HWND,DWORD,LPVOID); BOOL (*pGetCurrentDisplaySettings)(LPCWSTR,BOOL,LPDEVMODEW); + INT (*pGetDisplayDepth)(LPCWSTR,BOOL); BOOL (*pUpdateDisplayDevices)(const struct gdi_device_manager *,BOOL,void*); /* windowing functions */ BOOL (*pCreateDesktopWindow)(HWND);