Commit 7fabcf6f authored by Zhiyi Zhang's avatar Zhiyi Zhang Committed by Alexandre Julliard

winex11.drv: Add a cache for querying XRandR 1.4 current modes.

parent 095bdc6c
...@@ -324,6 +324,32 @@ static LONG xrandr10_set_current_mode( ULONG_PTR id, DEVMODEW *mode ) ...@@ -324,6 +324,32 @@ static LONG xrandr10_set_current_mode( ULONG_PTR id, DEVMODEW *mode )
#ifdef HAVE_XRRGETPROVIDERRESOURCES #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, &current_modes_section,
{&current_modes_critsect_debug.ProcessLocksList, &current_modes_critsect_debug.ProcessLocksList},
0, 0, {(DWORD_PTR)(__FILE__ ": current_modes_section")}
};
static CRITICAL_SECTION current_modes_section = {&current_modes_critsect_debug, -1, 0, 0, 0, 0};
static void xrandr14_invalidate_current_mode_cache(void)
{
EnterCriticalSection( &current_modes_section );
heap_free( current_modes);
current_modes = NULL;
current_mode_count = 0;
LeaveCriticalSection( &current_modes_section );
}
static XRRScreenResources *xrandr_get_screen_resources(void) static XRRScreenResources *xrandr_get_screen_resources(void)
{ {
XRRScreenResources *resources = pXRRGetScreenResourcesCurrent( gdi_display, root_window ); XRRScreenResources *resources = pXRRGetScreenResourcesCurrent( gdi_display, root_window );
...@@ -1115,6 +1141,7 @@ static void xrandr14_free_monitors( struct x11drv_monitor *monitors ) ...@@ -1115,6 +1141,7 @@ static void xrandr14_free_monitors( struct x11drv_monitor *monitors )
static BOOL xrandr14_device_change_handler( HWND hwnd, XEvent *event ) static BOOL xrandr14_device_change_handler( HWND hwnd, XEvent *event )
{ {
xrandr14_invalidate_current_mode_cache();
if (hwnd == GetDesktopWindow() && GetWindowThreadProcessId( hwnd, NULL ) == GetCurrentThreadId()) if (hwnd == GetDesktopWindow() && GetWindowThreadProcessId( hwnd, NULL ) == GetCurrentThreadId())
{ {
/* Don't send a WM_DISPLAYCHANGE message here because this event may be a result from /* 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) ...@@ -1148,7 +1175,8 @@ static void xrandr14_register_event_handlers(void)
/* XRandR 1.4 display settings handler */ /* XRandR 1.4 display settings handler */
static BOOL xrandr14_get_id( const WCHAR *device_name, ULONG_PTR *id ) 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; INT gpu_idx, adapter_idx, display_idx;
struct x11drv_adapter *adapters; struct x11drv_adapter *adapters;
struct x11drv_gpu *gpus; struct x11drv_gpu *gpus;
...@@ -1159,31 +1187,60 @@ static BOOL xrandr14_get_id( const WCHAR *device_name, ULONG_PTR *id ) ...@@ -1159,31 +1187,60 @@ static BOOL xrandr14_get_id( const WCHAR *device_name, ULONG_PTR *id )
if (*end) if (*end)
return FALSE; return FALSE;
if (!xrandr14_get_gpus2( &gpus, &gpu_count, FALSE )) /* Update cache */
return FALSE; EnterCriticalSection( &current_modes_section );
if (!current_modes)
for (gpu_idx = 0; gpu_idx < gpu_count; ++gpu_idx)
{ {
if (!xrandr14_get_adapters( gpus[gpu_idx].id, &adapters, &adapter_count )) if (!xrandr14_get_gpus2( &gpus, &gpu_count, FALSE ))
{ {
xrandr14_free_gpus( gpus ); LeaveCriticalSection( &current_modes_section );
return FALSE; return FALSE;
} }
adapter_idx = display_idx - display_count; for (gpu_idx = 0; gpu_idx < gpu_count; ++gpu_idx)
if (adapter_idx < adapter_count)
{ {
*id = adapters[adapter_idx].id; if (!xrandr14_get_adapters( gpus[gpu_idx].id, &adapters, &adapter_count ))
break;
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_adapters( adapters );
xrandr14_free_gpus( gpus );
return TRUE;
} }
xrandr14_free_gpus( gpus );
display_count += adapter_count; if (new_current_modes)
xrandr14_free_adapters( adapters ); {
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( &current_modes_section );
return FALSE;
}
*id = current_modes[display_idx].id;
LeaveCriticalSection( &current_modes_section );
return TRUE;
} }
static void add_xrandr14_mode( DEVMODEW *mode, XRRModeInfo *info, DWORD depth, DWORD frequency, 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 ) ...@@ -1342,6 +1399,21 @@ static BOOL xrandr14_get_current_mode( ULONG_PTR id, DEVMODEW *mode )
RECT primary; RECT primary;
INT mode_idx; INT mode_idx;
EnterCriticalSection( &current_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, &current_modes[mode_idx].mode, sizeof(*mode) );
LeaveCriticalSection( &current_modes_section );
return TRUE;
}
LeaveCriticalSection( &current_modes_section );
screen_resources = xrandr_get_screen_resources(); screen_resources = xrandr_get_screen_resources();
if (!screen_resources) if (!screen_resources)
goto done; goto done;
...@@ -1400,6 +1472,21 @@ static BOOL xrandr14_get_current_mode( ULONG_PTR id, DEVMODEW *mode ) ...@@ -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.x = crtc_info->x - primary.left;
mode->u1.s2.dmPosition.y = crtc_info->y - primary.top; mode->u1.s2.dmPosition.y = crtc_info->y - primary.top;
ret = TRUE; ret = TRUE;
EnterCriticalSection( &current_modes_section );
for (mode_idx = 0; mode_idx < current_mode_count; ++mode_idx)
{
if (current_modes[mode_idx].id != id)
continue;
memcpy( &current_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( &current_modes_section );
done: done:
if (crtc_info) if (crtc_info)
pXRRFreeCrtcInfo( crtc_info ); pXRRFreeCrtcInfo( crtc_info );
...@@ -1517,6 +1604,7 @@ done: ...@@ -1517,6 +1604,7 @@ done:
if (output_info) if (output_info)
pXRRFreeOutputInfo( output_info ); pXRRFreeOutputInfo( output_info );
pXRRFreeScreenResources( screen_resources ); pXRRFreeScreenResources( screen_resources );
xrandr14_invalidate_current_mode_cache();
return ret; return ret;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment