mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
Input: multithreaded handlers
Implements naive multithreading for input handlers.
This commit is contained in:
parent
ec3e8de780
commit
d6597038ee
@ -253,6 +253,8 @@ struct cfg_root : cfg::node
|
||||
cfg::_enum<buzz_handler> buzz{ this, "Buzz emulated controller", buzz_handler::null };
|
||||
cfg::_enum<turntable_handler> turntable{this, "Turntable emulated controller", turntable_handler::null};
|
||||
cfg::_enum<ghltar_handler> ghltar{this, "GHLtar emulated controller", ghltar_handler::null};
|
||||
cfg::_enum<pad_handler_mode> pad_mode{this, "Pad handler mode", pad_handler_mode::single_threaded, true};
|
||||
cfg::uint<0, 100'000> pad_sleep{this, "Pad handler sleep (microseconds)", 1'000, true};
|
||||
} io{ this };
|
||||
|
||||
struct node_sys : cfg::node
|
||||
|
@ -385,6 +385,21 @@ void fmt_class_string<move_handler>::format(std::string& out, u64 arg)
|
||||
});
|
||||
}
|
||||
|
||||
template <>
|
||||
void fmt_class_string<pad_handler_mode>::format(std::string& out, u64 arg)
|
||||
{
|
||||
format_enum(out, arg, [](auto value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case pad_handler_mode::single_threaded: return "Single-threaded";
|
||||
case pad_handler_mode::multi_threaded: return "Multi-threaded";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
template <>
|
||||
void fmt_class_string<buzz_handler>::format(std::string& out, u64 arg)
|
||||
{
|
||||
|
@ -135,6 +135,12 @@ enum class microphone_handler
|
||||
rocksmith,
|
||||
};
|
||||
|
||||
enum class pad_handler_mode
|
||||
{
|
||||
single_threaded, // All pad handlers run on the same thread sequentially.
|
||||
multi_threaded // Each pad handler has its own thread.
|
||||
};
|
||||
|
||||
enum class video_resolution
|
||||
{
|
||||
_1080,
|
||||
|
@ -15,7 +15,9 @@
|
||||
#include "Emu/Io/PadHandler.h"
|
||||
#include "Emu/Io/pad_config.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/system_config.h"
|
||||
#include "Utilities/Thread.h"
|
||||
#include "util/atomic.hpp"
|
||||
|
||||
LOG_CHANNEL(input_log, "Input");
|
||||
|
||||
@ -212,6 +214,55 @@ void pad_thread::operator()()
|
||||
{
|
||||
pad::g_reset = true;
|
||||
|
||||
atomic_t<pad_handler_mode> pad_mode{g_cfg.io.pad_mode.get()};
|
||||
std::vector<std::unique_ptr<named_thread<std::function<void()>>>> threads;
|
||||
|
||||
const auto stop_threads = [&threads]()
|
||||
{
|
||||
for (auto& thread : threads)
|
||||
{
|
||||
if (thread)
|
||||
{
|
||||
auto& enumeration_thread = *thread;
|
||||
enumeration_thread = thread_state::aborting;
|
||||
enumeration_thread();
|
||||
}
|
||||
}
|
||||
threads.clear();
|
||||
};
|
||||
|
||||
const auto start_threads = [this, &threads, &pad_mode]()
|
||||
{
|
||||
if (pad_mode == pad_handler_mode::single_threaded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& handler : handlers)
|
||||
{
|
||||
if (handler.first == pad_handler::null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
threads.push_back(std::make_unique<named_thread<std::function<void()>>>(fmt::format("%s Thread", handler.second->m_type), [&handler = handler.second, &pad_mode]()
|
||||
{
|
||||
while (thread_ctrl::state() != thread_state::aborting)
|
||||
{
|
||||
if (!pad::g_enabled || Emu.IsPaused())
|
||||
{
|
||||
thread_ctrl::wait_for(10'000);
|
||||
continue;
|
||||
}
|
||||
|
||||
handler->ThreadProc();
|
||||
|
||||
thread_ctrl::wait_for(g_cfg.io.pad_sleep);
|
||||
}
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
while (thread_ctrl::state() != thread_state::aborting)
|
||||
{
|
||||
if (!pad::g_enabled || Emu.IsPaused())
|
||||
@ -220,17 +271,43 @@ void pad_thread::operator()()
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pad::g_reset && pad::g_reset.exchange(false))
|
||||
// Update variables
|
||||
const bool needs_reset = pad::g_reset && pad::g_reset.exchange(false);
|
||||
const bool mode_changed = pad_mode != pad_mode.exchange(g_cfg.io.pad_mode.get());
|
||||
|
||||
// Reset pad handlers if necessary
|
||||
if (needs_reset || mode_changed)
|
||||
{
|
||||
Init();
|
||||
stop_threads();
|
||||
|
||||
if (needs_reset)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
else
|
||||
{
|
||||
input_log.success("The pad mode was changed to %s", pad_mode.load());
|
||||
}
|
||||
|
||||
start_threads();
|
||||
}
|
||||
|
||||
u32 connected_devices = 0;
|
||||
|
||||
for (auto& cur_pad_handler : handlers)
|
||||
if (pad_mode == pad_handler_mode::single_threaded)
|
||||
{
|
||||
cur_pad_handler.second->ThreadProc();
|
||||
connected_devices += cur_pad_handler.second->connected_devices;
|
||||
for (auto& handler : handlers)
|
||||
{
|
||||
handler.second->ThreadProc();
|
||||
connected_devices += handler.second->connected_devices;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto& handler : handlers)
|
||||
{
|
||||
connected_devices += handler.second->connected_devices;
|
||||
}
|
||||
}
|
||||
|
||||
m_info.now_connect = connected_devices + num_ldd_pad;
|
||||
@ -271,8 +348,10 @@ void pad_thread::operator()()
|
||||
}
|
||||
}
|
||||
|
||||
thread_ctrl::wait_for(1000);
|
||||
thread_ctrl::wait_for(g_cfg.io.pad_sleep);
|
||||
}
|
||||
|
||||
stop_threads();
|
||||
}
|
||||
|
||||
void pad_thread::InitLddPad(u32 handle)
|
||||
|
@ -1027,6 +1027,13 @@ QString emu_settings::GetLocalizedSetting(const QString& original, emu_settings_
|
||||
case camera_handler::qt: return tr("Qt", "Camera handler");
|
||||
}
|
||||
break;
|
||||
case emu_settings_type::PadHandlerMode:
|
||||
switch (static_cast<pad_handler_mode>(index))
|
||||
{
|
||||
case pad_handler_mode::single_threaded: return tr("Single-threaded", "Pad handler mode");
|
||||
case pad_handler_mode::multi_threaded: return tr("Multi-threaded", "Pad handler mode");
|
||||
}
|
||||
break;
|
||||
case emu_settings_type::Move:
|
||||
switch (static_cast<move_handler>(index))
|
||||
{
|
||||
|
@ -126,6 +126,7 @@ enum class emu_settings_type
|
||||
MicrophoneDevices,
|
||||
|
||||
// Input / Output
|
||||
PadHandlerMode,
|
||||
KeyboardHandler,
|
||||
MouseHandler,
|
||||
Camera,
|
||||
@ -287,6 +288,7 @@ inline static const QMap<emu_settings_type, cfg_location> settings_location =
|
||||
{ emu_settings_type::MicrophoneDevices, { "Audio", "Microphone Devices" }},
|
||||
|
||||
// Input / Output
|
||||
{ emu_settings_type::PadHandlerMode, { "Input/Output", "Pad handler mode"}},
|
||||
{ emu_settings_type::KeyboardHandler, { "Input/Output", "Keyboard"}},
|
||||
{ emu_settings_type::MouseHandler, { "Input/Output", "Mouse"}},
|
||||
{ emu_settings_type::Camera, { "Input/Output", "Camera"}},
|
||||
|
@ -1063,6 +1063,9 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
||||
SubscribeTooltip(ui->gb_camera_id, tooltips.settings.camera_id);
|
||||
}
|
||||
|
||||
m_emu_settings->EnhanceComboBox(ui->padModeBox, emu_settings_type::PadHandlerMode);
|
||||
SubscribeTooltip(ui->gb_pad_mode, tooltips.settings.pad_mode);
|
||||
|
||||
m_emu_settings->EnhanceComboBox(ui->moveBox, emu_settings_type::Move);
|
||||
SubscribeTooltip(ui->gb_move_handler, tooltips.settings.move);
|
||||
|
||||
|
@ -53,6 +53,9 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="coreTab">
|
||||
<attribute name="title">
|
||||
<string>CPU</string>
|
||||
@ -1572,6 +1575,18 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QGroupBox" name="gb_pad_mode">
|
||||
<property name="title">
|
||||
<string>Pad Handler Mode</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="gb_pad_mode_layout">
|
||||
<item>
|
||||
<widget class="QComboBox" name="padModeBox"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -193,8 +193,7 @@ public:
|
||||
|
||||
// input
|
||||
|
||||
const QString pad_handler = tr("If you want to use the keyboard to control, select the Keyboard option.\nIf you have a DualShock 4, select DualShock 4.\nIf you have an Xbox controller, or another compatible device, use XInput.\nOlder controllers such as PS2 controllers with an adapter usually work fine with MMJoystick.\nCheck button mappings in the Windows control panel.");
|
||||
const QString pad_handler_linux = tr("If you want to use the keyboard to control, select the Keyboard option.\nIf you have a DualShock 4, select DualShock 4.");
|
||||
const QString pad_mode = tr("Single-threaded: All pad handlers run on the same thread sequentially.\nMulti-threaded: Each pad handler has its own thread.\nOnly use multi-threaded if you can spare the extra threads.");
|
||||
const QString keyboard_handler = tr("Some games support native keyboard input.\nBasic will work in these cases.");
|
||||
const QString mouse_handler = tr("Some games support native mouse input.\nBasic will work in these cases.");
|
||||
const QString camera = tr("Select Qt Camera to use the default camera device of your operating system.");
|
||||
|
Loading…
Reference in New Issue
Block a user