dinput: Use a single list for all acquired devices.

Instead of going through devices list of dinputs list, and checking
their acquired field, which is not CPU friendly.

This also removes the now unused IDirectInputImpl critical section and
devices list.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
feature/deterministic
Rémi Bernon 2020-06-08 09:47:08 +02:00 committed by Alexandre Julliard
parent 9463684d55
commit 26c1131201
9 changed files with 51 additions and 80 deletions

View File

@ -1001,8 +1001,10 @@ HRESULT WINAPI IDirectInputDevice2WImpl_Acquire(LPDIRECTINPUTDEVICE8W iface)
res = This->acquired ? S_FALSE : DI_OK;
This->acquired = 1;
LeaveCriticalSection(&This->crit);
if (res == DI_OK)
check_dinput_hooks(iface, TRUE);
if (res != DI_OK) return res;
dinput_hooks_acquire_device(iface);
check_dinput_hooks(iface, TRUE);
return res;
}
@ -1029,8 +1031,10 @@ HRESULT WINAPI IDirectInputDevice2WImpl_Unacquire(LPDIRECTINPUTDEVICE8W iface)
res = !This->acquired ? DI_NOEFFECT : DI_OK;
This->acquired = 0;
LeaveCriticalSection(&This->crit);
if (res == DI_OK)
check_dinput_hooks(iface, FALSE);
if (res != DI_OK) return res;
dinput_hooks_unacquire_device(iface);
check_dinput_hooks(iface, FALSE);
return res;
}
@ -1164,10 +1168,6 @@ ULONG WINAPI IDirectInputDevice2WImpl_Release(LPDIRECTINPUTDEVICE8W iface)
/* Free action mapping */
HeapFree(GetProcessHeap(), 0, This->action_map);
EnterCriticalSection( &This->dinput->crit );
list_remove( &This->entry );
LeaveCriticalSection( &This->dinput->crit );
IDirectInput_Release(&This->dinput->IDirectInput7A_iface);
This->crit.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->crit);

View File

@ -63,7 +63,7 @@ struct IDirectInputDeviceImpl
GUID guid;
CRITICAL_SECTION crit;
IDirectInputImpl *dinput;
struct list entry; /* entry into IDirectInput devices list */
struct list entry; /* entry into acquired device list */
HANDLE hEvent;
DWORD dwCoopLevel;
HWND win;

View File

@ -100,10 +100,29 @@ HINSTANCE DINPUT_instance;
static BOOL check_hook_thread(void);
static CRITICAL_SECTION dinput_hook_crit;
static struct list direct_input_list = LIST_INIT( direct_input_list );
static struct list acquired_device_list = LIST_INIT( acquired_device_list );
static HRESULT initialize_directinput_instance(IDirectInputImpl *This, DWORD dwVersion);
static void uninitialize_directinput_instance(IDirectInputImpl *This);
void dinput_hooks_acquire_device(LPDIRECTINPUTDEVICE8W iface)
{
IDirectInputDeviceImpl *dev = impl_from_IDirectInputDevice8W(iface);
EnterCriticalSection( &dinput_hook_crit );
list_add_tail( &acquired_device_list, &dev->entry );
LeaveCriticalSection( &dinput_hook_crit );
}
void dinput_hooks_unacquire_device(LPDIRECTINPUTDEVICE8W iface)
{
IDirectInputDeviceImpl *dev = impl_from_IDirectInputDevice8W(iface);
EnterCriticalSection( &dinput_hook_crit );
list_remove( &dev->entry );
LeaveCriticalSection( &dinput_hook_crit );
}
static HRESULT create_directinput_instance(REFIID riid, LPVOID *ppDI, IDirectInputImpl **out)
{
IDirectInputImpl *This = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectInputImpl) );
@ -618,10 +637,6 @@ static HRESULT initialize_directinput_instance(IDirectInputImpl *This, DWORD dwV
This->dwVersion = dwVersion;
This->evsequence = 1;
InitializeCriticalSection( &This->crit );
This->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IDirectInputImpl*->crit");
list_init( &This->devices_list );
list_init( &This->device_players );
/* Add self to the list of the IDirectInputs */
@ -657,9 +672,6 @@ static void uninitialize_directinput_instance(IDirectInputImpl *This)
check_hook_thread();
This->crit.DebugInfo->Spare[0] = 0;
DeleteCriticalSection( &This->crit );
This->initialized = FALSE;
}
}
@ -1641,24 +1653,19 @@ HRESULT WINAPI DllUnregisterServer(void)
static LRESULT CALLBACK LL_hook_proc( int code, WPARAM wparam, LPARAM lparam )
{
IDirectInputImpl *dinput;
IDirectInputDeviceImpl *dev;
int skip = 0;
if (code != HC_ACTION) return CallNextHookEx( 0, code, wparam, lparam );
EnterCriticalSection( &dinput_hook_crit );
LIST_FOR_EACH_ENTRY( dinput, &direct_input_list, IDirectInputImpl, entry )
LIST_FOR_EACH_ENTRY( dev, &acquired_device_list, IDirectInputDeviceImpl, entry )
{
IDirectInputDeviceImpl *dev;
EnterCriticalSection( &dinput->crit );
LIST_FOR_EACH_ENTRY( dev, &dinput->devices_list, IDirectInputDeviceImpl, entry )
if (dev->acquired && dev->event_proc)
{
TRACE("calling %p->%p (%lx %lx)\n", dev, dev->event_proc, wparam, lparam);
skip |= dev->event_proc( &dev->IDirectInputDevice8A_iface, wparam, lparam );
}
LeaveCriticalSection( &dinput->crit );
if (dev->event_proc)
{
TRACE("calling %p->%p (%lx %lx)\n", dev, dev->event_proc, wparam, lparam);
skip |= dev->event_proc( &dev->IDirectInputDevice8A_iface, wparam, lparam );
}
}
LeaveCriticalSection( &dinput_hook_crit );
@ -1667,8 +1674,8 @@ static LRESULT CALLBACK LL_hook_proc( int code, WPARAM wparam, LPARAM lparam )
static LRESULT CALLBACK callwndproc_proc( int code, WPARAM wparam, LPARAM lparam )
{
IDirectInputDeviceImpl *dev, *next;
CWPSTRUCT *msg = (CWPSTRUCT *)lparam;
IDirectInputImpl *dinput;
HWND foreground;
if (code != HC_ACTION || (msg->message != WM_KILLFOCUS &&
@ -1678,23 +1685,13 @@ static LRESULT CALLBACK callwndproc_proc( int code, WPARAM wparam, LPARAM lparam
foreground = GetForegroundWindow();
EnterCriticalSection( &dinput_hook_crit );
LIST_FOR_EACH_ENTRY( dinput, &direct_input_list, IDirectInputImpl, entry )
LIST_FOR_EACH_ENTRY_SAFE( dev, next, &acquired_device_list, IDirectInputDeviceImpl, entry )
{
IDirectInputDeviceImpl *dev;
EnterCriticalSection( &dinput->crit );
LIST_FOR_EACH_ENTRY( dev, &dinput->devices_list, IDirectInputDeviceImpl, entry )
if (msg->hwnd == dev->win && msg->hwnd != foreground)
{
if (!dev->acquired) continue;
if (msg->hwnd == dev->win && msg->hwnd != foreground)
{
TRACE( "%p window is not foreground - unacquiring %p\n", dev->win, dev );
IDirectInputDevice_Unacquire( &dev->IDirectInputDevice8A_iface );
}
TRACE( "%p window is not foreground - unacquiring %p\n", dev->win, dev );
IDirectInputDevice_Unacquire( &dev->IDirectInputDevice8A_iface );
}
LeaveCriticalSection( &dinput->crit );
}
LeaveCriticalSection( &dinput_hook_crit );
@ -1716,7 +1713,7 @@ static DWORD WINAPI hook_thread_proc(void *param)
if (msg.message == WM_USER+0x10)
{
IDirectInputImpl *dinput;
IDirectInputDeviceImpl *dev;
HANDLE finished_event = (HANDLE)msg.lParam;
TRACE( "Processing hook change notification wp:%ld lp:%#lx\n", msg.wParam, msg.lParam );
@ -1732,22 +1729,15 @@ static DWORD WINAPI hook_thread_proc(void *param)
EnterCriticalSection( &dinput_hook_crit );
/* Count acquired keyboards and mice*/
LIST_FOR_EACH_ENTRY( dinput, &direct_input_list, IDirectInputImpl, entry )
LIST_FOR_EACH_ENTRY( dev, &acquired_device_list, IDirectInputDeviceImpl, entry )
{
IDirectInputDeviceImpl *dev;
if (!dev->event_proc) continue;
EnterCriticalSection( &dinput->crit );
LIST_FOR_EACH_ENTRY( dev, &dinput->devices_list, IDirectInputDeviceImpl, entry )
{
if (!dev->acquired || !dev->event_proc) continue;
if (IsEqualGUID( &dev->guid, &GUID_SysKeyboard ))
kbd_cnt++;
else
if (IsEqualGUID( &dev->guid, &GUID_SysMouse ))
mice_cnt++;
}
LeaveCriticalSection( &dinput->crit );
if (IsEqualGUID( &dev->guid, &GUID_SysKeyboard ))
kbd_cnt++;
else
if (IsEqualGUID( &dev->guid, &GUID_SysMouse ))
mice_cnt++;
}
LeaveCriticalSection( &dinput_hook_crit );

View File

@ -42,12 +42,10 @@ struct IDirectInputImpl
LONG ref;
BOOL initialized;
CRITICAL_SECTION crit;
struct list entry; /* entry into list of all IDirectInputs */
DWORD evsequence; /* unique sequence number for events */
DWORD dwVersion; /* direct input version number */
struct list devices_list; /* list of all created dinput devices */
struct list device_players; /* device instance guid to player name */
};
@ -71,6 +69,9 @@ extern const struct dinput_device joystick_linux_device DECLSPEC_HIDDEN;
extern const struct dinput_device joystick_linuxinput_device DECLSPEC_HIDDEN;
extern const struct dinput_device joystick_osx_device DECLSPEC_HIDDEN;
extern void dinput_hooks_acquire_device(LPDIRECTINPUTDEVICE8W iface);
extern void dinput_hooks_unacquire_device(LPDIRECTINPUTDEVICE8W iface);
extern void check_dinput_hooks(LPDIRECTINPUTDEVICE8W, BOOL) DECLSPEC_HIDDEN;
extern void check_dinput_events(void) DECLSPEC_HIDDEN;
typedef int (*DI_EVENT_PROC)(LPDIRECTINPUTDEVICE8A, WPARAM, LPARAM);

View File

@ -554,10 +554,6 @@ static HRESULT alloc_device(REFGUID rguid, IDirectInputImpl *dinput,
IDirectInput_AddRef(&newDevice->generic.base.dinput->IDirectInput7A_iface);
EnterCriticalSection(&dinput->crit);
list_add_tail(&dinput->devices_list, &newDevice->generic.base.entry);
LeaveCriticalSection(&dinput->crit);
newDevice->generic.devcaps.dwSize = sizeof(newDevice->generic.devcaps);
newDevice->generic.devcaps.dwFlags = DIDC_ATTACHED;

View File

@ -595,10 +595,6 @@ static JoystickImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput, unsig
IDirectInput_AddRef(&newDevice->generic.base.dinput->IDirectInput7A_iface);
EnterCriticalSection(&dinput->crit);
list_add_tail(&dinput->devices_list, &newDevice->generic.base.entry);
LeaveCriticalSection(&dinput->crit);
return newDevice;
failed:

View File

@ -1242,10 +1242,6 @@ static HRESULT alloc_device(REFGUID rguid, IDirectInputImpl *dinput,
IDirectInput_AddRef(&newDevice->generic.base.dinput->IDirectInput7A_iface);
EnterCriticalSection(&dinput->crit);
list_add_tail(&dinput->devices_list, &newDevice->generic.base.entry);
LeaveCriticalSection(&dinput->crit);
newDevice->generic.devcaps.dwSize = sizeof(newDevice->generic.devcaps);
newDevice->generic.devcaps.dwFlags |= DIDC_ATTACHED;
if (newDevice->generic.base.dinput->dwVersion >= 0x0800)

View File

@ -291,10 +291,6 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
newDevice->base.data_format.wine_df = df;
IDirectInput_AddRef(&newDevice->base.dinput->IDirectInput7A_iface);
EnterCriticalSection(&dinput->crit);
list_add_tail(&dinput->devices_list, &newDevice->base.entry);
LeaveCriticalSection(&dinput->crit);
return newDevice;
failed:

View File

@ -242,10 +242,6 @@ static SysMouseImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
newDevice->base.data_format.wine_df = df;
IDirectInput_AddRef(&newDevice->base.dinput->IDirectInput7A_iface);
EnterCriticalSection(&dinput->crit);
list_add_tail(&dinput->devices_list, &newDevice->base.entry);
LeaveCriticalSection(&dinput->crit);
return newDevice;
failed: