mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-21 10:12:32 +01:00
input: add enumeration threads for each hid_pad_handler
There was a roughly 60 ms lag for each hid handler every 2 seconds. (sucks if you use all 3 hid handlers)
This commit is contained in:
parent
8efc29972d
commit
a4c4548c3a
@ -12,7 +12,7 @@ private:
|
||||
steady_clock::time_point m_end;
|
||||
|
||||
public:
|
||||
Timer() : m_stopped(false)
|
||||
Timer() : m_stopped(false), m_start(steady_clock::now())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,9 @@
|
||||
#include "ds4_pad_handler.h"
|
||||
#include "dualsense_pad_handler.h"
|
||||
#include "util/logs.hpp"
|
||||
#include "Utilities/Timer.h"
|
||||
#include "Emu/System.h"
|
||||
#include "pad_thread.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
@ -23,6 +26,13 @@ hid_pad_handler<Device>::hid_pad_handler(pad_handler type, std::vector<id_pair>
|
||||
template <class Device>
|
||||
hid_pad_handler<Device>::~hid_pad_handler()
|
||||
{
|
||||
if (m_enumeration_thread)
|
||||
{
|
||||
auto& enumeration_thread = *m_enumeration_thread;
|
||||
enumeration_thread = thread_state::aborting;
|
||||
enumeration_thread();
|
||||
}
|
||||
|
||||
for (auto& controller : m_controllers)
|
||||
{
|
||||
if (controller.second && controller.second->hidDevice)
|
||||
@ -59,21 +69,30 @@ bool hid_pad_handler<Device>::Init()
|
||||
}
|
||||
|
||||
enumerate_devices();
|
||||
update_devices();
|
||||
|
||||
m_is_init = true;
|
||||
|
||||
m_enumeration_thread = std::make_unique<named_thread<std::function<void()>>>(fmt::format("%s Enumerator", m_type), [this]()
|
||||
{
|
||||
while (thread_ctrl::state() != thread_state::aborting)
|
||||
{
|
||||
if (pad::g_enabled && Emu.IsRunning())
|
||||
{
|
||||
enumerate_devices();
|
||||
}
|
||||
|
||||
thread_ctrl::wait_for(2'000'000);
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class Device>
|
||||
void hid_pad_handler<Device>::ThreadProc()
|
||||
{
|
||||
const auto now = std::chrono::system_clock::now();
|
||||
const auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - m_last_enumeration).count();
|
||||
if (elapsed > 2000)
|
||||
{
|
||||
m_last_enumeration = now;
|
||||
enumerate_devices();
|
||||
}
|
||||
update_devices();
|
||||
|
||||
PadHandlerBase::ThreadProc();
|
||||
}
|
||||
@ -97,6 +116,7 @@ std::vector<std::string> hid_pad_handler<Device>::ListDevices()
|
||||
template <class Device>
|
||||
void hid_pad_handler<Device>::enumerate_devices()
|
||||
{
|
||||
Timer timer;
|
||||
std::set<std::string> device_paths;
|
||||
std::map<std::string, std::wstring_view> serials;
|
||||
|
||||
@ -113,18 +133,29 @@ void hid_pad_handler<Device>::enumerate_devices()
|
||||
}
|
||||
hid_free_enumeration(head);
|
||||
}
|
||||
hid_log.notice("%s enumeration found %d devices (%f ms)", m_type, device_paths.size(), timer.GetElapsedTimeInMilliSec());
|
||||
|
||||
if (m_last_enumerated_devices == device_paths)
|
||||
std::lock_guard lock(m_enumeration_mutex);
|
||||
m_new_enumerated_devices = device_paths;
|
||||
m_enumerated_serials = serials;
|
||||
}
|
||||
|
||||
template <class Device>
|
||||
void hid_pad_handler<Device>::update_devices()
|
||||
{
|
||||
std::lock_guard lock(m_enumeration_mutex);
|
||||
|
||||
if (m_last_enumerated_devices == m_new_enumerated_devices)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_last_enumerated_devices = device_paths;
|
||||
m_last_enumerated_devices = m_new_enumerated_devices;
|
||||
|
||||
// Scrap devices that are not in the new list
|
||||
for (auto& controller : m_controllers)
|
||||
{
|
||||
if (controller.second && !controller.second->path.empty() && !device_paths.contains(controller.second->path))
|
||||
if (controller.second && !controller.second->path.empty() && !m_new_enumerated_devices.contains(controller.second->path))
|
||||
{
|
||||
hid_close(controller.second->hidDevice);
|
||||
cfg_pad* config = controller.second->config;
|
||||
@ -136,7 +167,7 @@ void hid_pad_handler<Device>::enumerate_devices()
|
||||
bool warn_about_drivers = false;
|
||||
|
||||
// Find and add new devices
|
||||
for (const auto& path : device_paths)
|
||||
for (const auto& path : m_new_enumerated_devices)
|
||||
{
|
||||
// Check if we have at least one virtual controller left
|
||||
if (std::none_of(m_controllers.cbegin(), m_controllers.cend(), [](const auto& c) { return !c.second || !c.second->hidDevice; }))
|
||||
@ -149,7 +180,7 @@ void hid_pad_handler<Device>::enumerate_devices()
|
||||
hid_device* dev = hid_open_path(path.c_str());
|
||||
if (dev)
|
||||
{
|
||||
check_add_device(dev, path, serials[path]);
|
||||
check_add_device(dev, path, m_enumerated_serials[path]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "Emu/Io/PadHandler.h"
|
||||
#include "Utilities/CRC.h"
|
||||
#include "Utilities/Thread.h"
|
||||
|
||||
#include "hidapi.h"
|
||||
|
||||
@ -77,10 +78,14 @@ protected:
|
||||
std::map<std::string, std::shared_ptr<Device>> m_controllers;
|
||||
|
||||
bool m_is_init = false;
|
||||
std::chrono::system_clock::time_point m_last_enumeration;
|
||||
std::set<std::string> m_last_enumerated_devices;
|
||||
std::set<std::string> m_new_enumerated_devices;
|
||||
std::map<std::string, std::wstring_view> m_enumerated_serials;
|
||||
std::mutex m_enumeration_mutex;
|
||||
std::unique_ptr<named_thread<std::function<void()>>> m_enumeration_thread;
|
||||
|
||||
void enumerate_devices();
|
||||
void update_devices();
|
||||
std::shared_ptr<Device> get_hid_device(const std::string& padId);
|
||||
|
||||
virtual void check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view serial) = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user