winex11.drv: Add a cache for querying XRandR 1.4 current modes.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51047 Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
095bdc6c43
commit
7fabcf6fed
|
@ -324,6 +324,32 @@ static LONG xrandr10_set_current_mode( ULONG_PTR id, DEVMODEW *mode )
|
|||
|
||||
#ifdef HAVE_XRRGETPROVIDERRESOURCES
|
||||
|
||||
static struct current_mode
|
||||
{
|
||||
ULONG_PTR id;
|
||||
BOOL loaded;
|
||||
DEVMODEW mode;
|
||||
} *current_modes;
|
||||
static int current_mode_count;
|
||||
|
||||
static CRITICAL_SECTION current_modes_section;
|
||||
static CRITICAL_SECTION_DEBUG current_modes_critsect_debug =
|
||||
{
|
||||
0, 0, ¤t_modes_section,
|
||||
{¤t_modes_critsect_debug.ProcessLocksList, ¤t_modes_critsect_debug.ProcessLocksList},
|
||||
0, 0, {(DWORD_PTR)(__FILE__ ": current_modes_section")}
|
||||
};
|
||||
static CRITICAL_SECTION current_modes_section = {¤t_modes_critsect_debug, -1, 0, 0, 0, 0};
|
||||
|
||||
static void xrandr14_invalidate_current_mode_cache(void)
|
||||
{
|
||||
EnterCriticalSection( ¤t_modes_section );
|
||||
heap_free( current_modes);
|
||||
current_modes = NULL;
|
||||
current_mode_count = 0;
|
||||
LeaveCriticalSection( ¤t_modes_section );
|
||||
}
|
||||
|
||||
static XRRScreenResources *xrandr_get_screen_resources(void)
|
||||
{
|
||||
XRRScreenResources *resources = pXRRGetScreenResourcesCurrent( gdi_display, root_window );
|
||||
|
@ -1115,6 +1141,7 @@ static void xrandr14_free_monitors( struct x11drv_monitor *monitors )
|
|||
|
||||
static BOOL xrandr14_device_change_handler( HWND hwnd, XEvent *event )
|
||||
{
|
||||
xrandr14_invalidate_current_mode_cache();
|
||||
if (hwnd == GetDesktopWindow() && GetWindowThreadProcessId( hwnd, NULL ) == GetCurrentThreadId())
|
||||
{
|
||||
/* Don't send a WM_DISPLAYCHANGE message here because this event may be a result from
|
||||
|
@ -1148,7 +1175,8 @@ static void xrandr14_register_event_handlers(void)
|
|||
/* XRandR 1.4 display settings handler */
|
||||
static BOOL xrandr14_get_id( const WCHAR *device_name, ULONG_PTR *id )
|
||||
{
|
||||
INT gpu_count, adapter_count, display_count = 0;
|
||||
struct current_mode *tmp_modes, *new_current_modes = NULL;
|
||||
INT gpu_count, adapter_count, new_current_mode_count = 0;
|
||||
INT gpu_idx, adapter_idx, display_idx;
|
||||
struct x11drv_adapter *adapters;
|
||||
struct x11drv_gpu *gpus;
|
||||
|
@ -1159,31 +1187,60 @@ static BOOL xrandr14_get_id( const WCHAR *device_name, ULONG_PTR *id )
|
|||
if (*end)
|
||||
return FALSE;
|
||||
|
||||
if (!xrandr14_get_gpus2( &gpus, &gpu_count, FALSE ))
|
||||
return FALSE;
|
||||
|
||||
for (gpu_idx = 0; gpu_idx < gpu_count; ++gpu_idx)
|
||||
/* Update cache */
|
||||
EnterCriticalSection( ¤t_modes_section );
|
||||
if (!current_modes)
|
||||
{
|
||||
if (!xrandr14_get_adapters( gpus[gpu_idx].id, &adapters, &adapter_count ))
|
||||
if (!xrandr14_get_gpus2( &gpus, &gpu_count, FALSE ))
|
||||
{
|
||||
xrandr14_free_gpus( gpus );
|
||||
LeaveCriticalSection( ¤t_modes_section );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
adapter_idx = display_idx - display_count;
|
||||
if (adapter_idx < adapter_count)
|
||||
for (gpu_idx = 0; gpu_idx < gpu_count; ++gpu_idx)
|
||||
{
|
||||
*id = adapters[adapter_idx].id;
|
||||
xrandr14_free_adapters( adapters );
|
||||
xrandr14_free_gpus( gpus );
|
||||
return TRUE;
|
||||
}
|
||||
if (!xrandr14_get_adapters( gpus[gpu_idx].id, &adapters, &adapter_count ))
|
||||
break;
|
||||
|
||||
display_count += adapter_count;
|
||||
xrandr14_free_adapters( adapters );
|
||||
if (!new_current_modes)
|
||||
tmp_modes = heap_alloc( adapter_count * sizeof(*tmp_modes) );
|
||||
else
|
||||
tmp_modes = heap_realloc( new_current_modes, (new_current_mode_count + adapter_count) * sizeof(*tmp_modes) );
|
||||
|
||||
if (!tmp_modes)
|
||||
{
|
||||
xrandr14_free_adapters( adapters );
|
||||
break;
|
||||
}
|
||||
new_current_modes = tmp_modes;
|
||||
|
||||
for (adapter_idx = 0; adapter_idx < adapter_count; ++adapter_idx)
|
||||
{
|
||||
new_current_modes[new_current_mode_count + adapter_idx].id = adapters[adapter_idx].id;
|
||||
new_current_modes[new_current_mode_count + adapter_idx].loaded = FALSE;
|
||||
}
|
||||
new_current_mode_count += adapter_count;
|
||||
xrandr14_free_adapters( adapters );
|
||||
}
|
||||
xrandr14_free_gpus( gpus );
|
||||
|
||||
if (new_current_modes)
|
||||
{
|
||||
heap_free( current_modes );
|
||||
current_modes = new_current_modes;
|
||||
current_mode_count = new_current_mode_count;
|
||||
}
|
||||
}
|
||||
xrandr14_free_gpus( gpus );
|
||||
return FALSE;
|
||||
|
||||
if (display_idx >= current_mode_count)
|
||||
{
|
||||
LeaveCriticalSection( ¤t_modes_section );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*id = current_modes[display_idx].id;
|
||||
LeaveCriticalSection( ¤t_modes_section );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void add_xrandr14_mode( DEVMODEW *mode, XRRModeInfo *info, DWORD depth, DWORD frequency,
|
||||
|
@ -1342,6 +1399,21 @@ static BOOL xrandr14_get_current_mode( ULONG_PTR id, DEVMODEW *mode )
|
|||
RECT primary;
|
||||
INT mode_idx;
|
||||
|
||||
EnterCriticalSection( ¤t_modes_section );
|
||||
for (mode_idx = 0; mode_idx < current_mode_count; ++mode_idx)
|
||||
{
|
||||
if (current_modes[mode_idx].id != id)
|
||||
continue;
|
||||
|
||||
if (!current_modes[mode_idx].loaded)
|
||||
break;
|
||||
|
||||
memcpy( mode, ¤t_modes[mode_idx].mode, sizeof(*mode) );
|
||||
LeaveCriticalSection( ¤t_modes_section );
|
||||
return TRUE;
|
||||
}
|
||||
LeaveCriticalSection( ¤t_modes_section );
|
||||
|
||||
screen_resources = xrandr_get_screen_resources();
|
||||
if (!screen_resources)
|
||||
goto done;
|
||||
|
@ -1400,6 +1472,21 @@ static BOOL xrandr14_get_current_mode( ULONG_PTR id, DEVMODEW *mode )
|
|||
mode->u1.s2.dmPosition.x = crtc_info->x - primary.left;
|
||||
mode->u1.s2.dmPosition.y = crtc_info->y - primary.top;
|
||||
ret = TRUE;
|
||||
|
||||
EnterCriticalSection( ¤t_modes_section );
|
||||
for (mode_idx = 0; mode_idx < current_mode_count; ++mode_idx)
|
||||
{
|
||||
if (current_modes[mode_idx].id != id)
|
||||
continue;
|
||||
|
||||
memcpy( ¤t_modes[mode_idx].mode, mode, sizeof(*mode) );
|
||||
current_modes[mode_idx].mode.dmSize = sizeof(*mode);
|
||||
current_modes[mode_idx].mode.dmDriverExtra = 0;
|
||||
current_modes[mode_idx].loaded = TRUE;
|
||||
break;
|
||||
}
|
||||
LeaveCriticalSection( ¤t_modes_section );
|
||||
|
||||
done:
|
||||
if (crtc_info)
|
||||
pXRRFreeCrtcInfo( crtc_info );
|
||||
|
@ -1517,6 +1604,7 @@ done:
|
|||
if (output_info)
|
||||
pXRRFreeOutputInfo( output_info );
|
||||
pXRRFreeScreenResources( screen_resources );
|
||||
xrandr14_invalidate_current_mode_cache();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue