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:
Megamouse 2022-01-27 23:57:39 +01:00
parent 8efc29972d
commit a4c4548c3a
3 changed files with 50 additions and 14 deletions

View File

@ -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())
{
}

View File

@ -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
{

View File

@ -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;