Skip to content

Commit dc08225

Browse files
committed
Move emulation to dedicated worker thread
1 parent 71dba28 commit dc08225

29 files changed

+235
-79
lines changed

Diff for: ares/ares/node/video/screen.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Screen::~Screen() {
2424
}
2525

2626
auto Screen::main(uintptr_t) -> void {
27+
thread::setName("dev.ares.screen");
2728
while(!_kill) {
2829
unique_lock<mutex> lock(_frameMutex);
2930

Diff for: ares/n64/system/system.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ auto System::game() -> string {
7777
}
7878

7979
auto System::run() -> void {
80+
// not ideal
81+
if(!vulkanLoaded) {
82+
vulkan.load(node);
83+
vulkanLoaded = true;
84+
}
8085
cpu.main();
8186
}
8287

@@ -134,9 +139,6 @@ auto System::load(Node::System& root, string name) -> bool {
134139
rdp.load(node);
135140
if(_DD()) dd.load(node);
136141
if(model() == Model::Aleck64) aleck64.load(node);
137-
#if defined(VULKAN)
138-
vulkan.load(node);
139-
#endif
140142

141143
initDebugHooks();
142144

@@ -308,6 +310,7 @@ auto System::unload() -> void {
308310
if(vi.screen) vi.screen->quit(); //stop video thread
309311
#if defined(VULKAN)
310312
vulkan.unload();
313+
vulkanLoaded = false;
311314
#endif
312315
cartridgeSlot.unload();
313316
controllerPort1.unload();

Diff for: ares/n64/system/system.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ struct System {
3737
u32 videoFrequency = 48'681'818;
3838
bool dd = false;
3939
} information;
40+
41+
bool vulkanLoaded = false;
4042

4143
auto initDebugHooks() -> void;
4244

Diff for: ares/n64/vi/vi.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ auto VI::main() -> void {
117117
io.vcounter = 0;
118118
if(++inactiveCounter >= 200) {
119119
inactiveCounter = 0;
120-
screen->frame();
120+
//screen->frame();
121121
refreshed = true;
122122
}
123123
step(0x800);

Diff for: desktop-ui/desktop-ui.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,10 @@ auto nall::main(Arguments arguments) -> void {
156156

157157
Instances::presentation.construct();
158158
Instances::settingsWindow.construct();
159-
Instances::toolsWindow.construct();
160159
Instances::gameBrowserWindow.construct();
161160

162161
program.create();
162+
Instances::toolsWindow.construct(&program.programMutex);
163163
Application::onMain({&Program::main, &program});
164164
Application::run();
165165

Diff for: desktop-ui/emulator/emulator.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ auto Emulator::location() -> string {
2525
}
2626

2727
auto Emulator::locate(const string& location, const string& suffix, const string& path, maybe<string> system) -> string {
28+
lock_guard<recursive_mutex> lock(program.programMutex);
2829
if(!system) system = root->name();
2930

3031
//game path
@@ -111,6 +112,7 @@ auto Emulator::handleLoadResult(LoadResult result) -> void {
111112
}
112113

113114
auto Emulator::load(const string& location) -> bool {
115+
lock_guard<recursive_mutex> lock(program.programMutex);
114116
if(inode::exists(location)) locationQueue.append(location);
115117

116118
LoadResult result = load();
@@ -130,6 +132,7 @@ auto Emulator::load(const string& location) -> bool {
130132
}
131133

132134
auto Emulator::load(shared_pointer<mia::Pak> pak, string& path) -> string {
135+
lock_guard<recursive_mutex> lock(program.programMutex);
133136
string location;
134137
if(locationQueue) {
135138
location = locationQueue.takeFirst(); //pull from the game queue if an entry is available
@@ -160,6 +163,7 @@ auto Emulator::load(shared_pointer<mia::Pak> pak, string& path) -> string {
160163
}
161164

162165
auto Emulator::loadFirmware(const Firmware& firmware) -> shared_pointer<vfs::file> {
166+
lock_guard<recursive_mutex> lock(program.programMutex);
163167
if(firmware.location.iendsWith(".zip")) {
164168
Decode::ZIP archive;
165169
if(archive.open(firmware.location) && archive.file) {
@@ -173,6 +177,7 @@ auto Emulator::loadFirmware(const Firmware& firmware) -> shared_pointer<vfs::fil
173177
}
174178

175179
auto Emulator::unload() -> void {
180+
lock_guard<recursive_mutex> lock(program.programMutex);
176181
save();
177182
root->unload();
178183
game = {};
@@ -182,6 +187,7 @@ auto Emulator::unload() -> void {
182187
}
183188

184189
auto Emulator::load(mia::Pak& node, string name) -> bool {
190+
lock_guard<recursive_mutex> lock(program.programMutex);
185191
if(auto fp = node.pak->read(name)) {
186192
if(auto memory = file::read({node.location, name})) {
187193
fp->read(memory);
@@ -192,19 +198,22 @@ auto Emulator::load(mia::Pak& node, string name) -> bool {
192198
}
193199

194200
auto Emulator::save(mia::Pak& node, string name) -> bool {
201+
lock_guard<recursive_mutex> lock(program.programMutex);
195202
if(auto memory = node.pak->write(name)) {
196203
return file::write({node.location, name}, {memory->data(), memory->size()});
197204
}
198205
return false;
199206
}
200207

201208
auto Emulator::refresh() -> void {
209+
lock_guard<recursive_mutex> lock(program.programMutex);
202210
if(auto screen = root->scan<ares::Node::Video::Screen>("Screen")) {
203211
screen->refresh();
204212
}
205213
}
206214

207215
auto Emulator::setBoolean(const string& name, bool value) -> bool {
216+
lock_guard<recursive_mutex> lock(program.programMutex);
208217
if(auto node = root->scan<ares::Node::Setting::Boolean>(name)) {
209218
node->setValue(value); //setValue() will not call modify() if value has not changed;
210219
node->modify(value); //but that may prevent the initial setValue() from working
@@ -214,6 +223,7 @@ auto Emulator::setBoolean(const string& name, bool value) -> bool {
214223
}
215224

216225
auto Emulator::setOverscan(bool value) -> bool {
226+
lock_guard<recursive_mutex> lock(program.programMutex);
217227
if(auto screen = root->scan<ares::Node::Video::Screen>("Screen")) {
218228
screen->setOverscan(value);
219229
return true;
@@ -222,6 +232,7 @@ auto Emulator::setOverscan(bool value) -> bool {
222232
}
223233

224234
auto Emulator::setColorBleed(bool value) -> bool {
235+
lock_guard<recursive_mutex> lock(program.programMutex);
225236
if(auto screen = root->scan<ares::Node::Video::Screen>("Screen")) {
226237
screen->setColorBleed(screen->height() < 720 ? value : false); //only apply to sub-HD content
227238
return true;
@@ -235,6 +246,7 @@ auto Emulator::error(const string& text) -> void {
235246
}
236247

237248
auto Emulator::input(ares::Node::Input::Input input) -> void {
249+
lock_guard<recursive_mutex> lock(program.inputMutex); //necessary?
238250
//looking up inputs is very time-consuming; skip call if input was called too recently
239251
//note: allow rumble to be polled at full speed to prevent missed motor events
240252
if(!input->cast<ares::Node::Input::Rumble>()) {
@@ -281,6 +293,7 @@ auto Emulator::input(ares::Node::Input::Input input) -> void {
281293
}
282294

283295
auto Emulator::inputKeyboard(string name) -> bool {
296+
lock_guard<recursive_mutex> lock(program.inputMutex);
284297
for (auto& device : inputManager.devices) {
285298
if (!device->isKeyboard()) continue;
286299

Diff for: desktop-ui/input/input.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ VirtualPort virtualPorts[5];
55
InputManager inputManager;
66

77
auto InputMapping::bind() -> void {
8+
lock_guard<recursive_mutex> lock(program.inputMutex);
89
for(auto& binding : bindings) binding = {};
910

1011
for(u32 index : range(BindingLimit)) {
@@ -32,22 +33,26 @@ auto InputMapping::bind() -> void {
3233
}
3334

3435
auto InputMapping::bind(u32 binding, string assignment) -> void {
36+
lock_guard<recursive_mutex> lock(program.inputMutex);
3537
if(binding >= BindingLimit) return;
3638
assignments[binding] = assignment;
3739
bind();
3840
}
3941

4042
auto InputMapping::unbind() -> void {
43+
lock_guard<recursive_mutex> lock(program.inputMutex);
4144
for(u32 binding : range(BindingLimit)) unbind(binding);
4245
}
4346

4447
auto InputMapping::unbind(u32 binding) -> void {
48+
lock_guard<recursive_mutex> lock(program.inputMutex);
4549
if(binding >= BindingLimit) return;
4650
bindings[binding] = {};
4751
assignments[binding] = {};
4852
}
4953

5054
auto InputMapping::Binding::icon() -> multiFactorImage {
55+
lock_guard<recursive_mutex> lock(program.inputMutex);
5156
if(!device && deviceID) return Icon::Device::Joypad;
5257
if(!device) return {};
5358
if(device->isKeyboard()) return Icon::Device::Keyboard;
@@ -57,6 +62,7 @@ auto InputMapping::Binding::icon() -> multiFactorImage {
5762
}
5863

5964
auto InputMapping::Binding::text() -> string {
65+
lock_guard<recursive_mutex> lock(program.inputMutex);
6066
if(!device && deviceID) return "(disconnected)";
6167
if(!device) return {};
6268
if(groupID >= device->size()) return {};
@@ -90,6 +96,7 @@ auto InputMapping::Binding::text() -> string {
9096
//
9197

9298
auto InputDigital::bind(u32 binding, shared_pointer<HID::Device> device, u32 groupID, u32 inputID, s16 oldValue, s16 newValue) -> bool {
99+
lock_guard<recursive_mutex> lock(program.inputMutex);
93100
string assignment = {"0x", hex(device->id()), "/", groupID, "/", inputID};
94101

95102
if(device->isNull()) {
@@ -128,6 +135,7 @@ auto InputDigital::bind(u32 binding, shared_pointer<HID::Device> device, u32 gro
128135
}
129136

130137
auto InputDigital::value() -> s16 {
138+
lock_guard<recursive_mutex> lock(program.inputMutex);
131139
s16 result = 0;
132140

133141
for(auto& binding : bindings) {
@@ -165,11 +173,13 @@ auto InputDigital::value() -> s16 {
165173
}
166174

167175
auto InputDigital::pressed() -> bool {
176+
lock_guard<recursive_mutex> lock(program.inputMutex);
168177
return value() != 0;
169178
}
170179

171180

172181
auto InputHotkey::value() -> s16 {
182+
lock_guard<recursive_mutex> lock(program.inputMutex);
173183
s16 result = 0;
174184

175185
for(auto& binding : bindings) {
@@ -210,6 +220,7 @@ auto InputHotkey::value() -> s16 {
210220
//
211221

212222
auto InputAnalog::bind(u32 binding, shared_pointer<HID::Device> device, u32 groupID, u32 inputID, s16 oldValue, s16 newValue) -> bool {
223+
lock_guard<recursive_mutex> lock(program.inputMutex);
213224
string assignment = {"0x", hex(device->id()), "/", groupID, "/", inputID};
214225

215226
if(device->isNull()) {
@@ -244,6 +255,7 @@ auto InputAnalog::bind(u32 binding, shared_pointer<HID::Device> device, u32 grou
244255
}
245256

246257
auto InputAnalog::value() -> s16 {
258+
lock_guard<recursive_mutex> lock(program.inputMutex);
247259
s32 result = 0;
248260

249261
for(auto& binding : bindings) {
@@ -274,12 +286,14 @@ auto InputAnalog::value() -> s16 {
274286
}
275287

276288
auto InputAnalog::pressed() -> bool {
289+
lock_guard<recursive_mutex> lock(program.inputMutex);
277290
return value() > 16384;
278291
}
279292

280293
//
281294

282295
auto InputAbsolute::bind(u32 binding, shared_pointer<HID::Device> device, u32 groupID, u32 inputID, s16 oldValue, s16 newValue) -> bool {
296+
lock_guard<recursive_mutex> lock(program.inputMutex);
283297
string assignment = {"0x", hex(device->id()), "/", groupID, "/", inputID};
284298

285299
if(device->isNull()) {
@@ -310,6 +324,7 @@ auto InputAbsolute::bind(u32 binding, shared_pointer<HID::Device> device, u32 gr
310324
}
311325

312326
auto InputAbsolute::value() -> s16 {
327+
lock_guard<recursive_mutex> lock(program.inputMutex);
313328
s32 result = 0;
314329

315330
for(auto& binding : bindings) {
@@ -337,6 +352,7 @@ auto InputAbsolute::value() -> s16 {
337352
//
338353

339354
auto InputRelative::bind(u32 binding, shared_pointer<HID::Device> device, u32 groupID, u32 inputID, s16 oldValue, s16 newValue) -> bool {
355+
lock_guard<recursive_mutex> lock(program.inputMutex);
340356
string assignment = {"0x", hex(device->id()), "/", groupID, "/", inputID};
341357

342358
if(device->isNull()) {
@@ -367,6 +383,7 @@ auto InputRelative::bind(u32 binding, shared_pointer<HID::Device> device, u32 gr
367383
}
368384

369385
auto InputRelative::value() -> s16 {
386+
lock_guard<recursive_mutex> lock(program.inputMutex);
370387
s32 result = 0;
371388

372389
for(auto& binding : bindings) {
@@ -394,6 +411,7 @@ auto InputRelative::value() -> s16 {
394411
//
395412

396413
auto InputRumble::bind(u32 binding, shared_pointer<HID::Device> device, u32 groupID, u32 inputID, s16 oldValue, s16 newValue) -> bool {
414+
lock_guard<recursive_mutex> lock(program.inputMutex);
397415
string assignment = {"0x", hex(device->id()), "/", groupID, "/", inputID};
398416

399417
if(device->isNull()) {
@@ -468,10 +486,12 @@ VirtualMouse::VirtualMouse() {
468486
//
469487

470488
auto InputManager::create() -> void {
489+
lock_guard<recursive_mutex> lock(program.inputMutex);
471490
createHotkeys();
472491
}
473492

474493
auto InputManager::bind() -> void {
494+
lock_guard<recursive_mutex> lock(program.inputMutex);
475495
for(auto& port : virtualPorts) {
476496
for(auto& input : port.pad.inputs) input.mapping->bind();
477497
for(auto& input : port.mouse.inputs) input.mapping->bind();
@@ -480,6 +500,7 @@ auto InputManager::bind() -> void {
480500
}
481501

482502
auto InputManager::poll(bool force) -> void {
503+
lock_guard<recursive_mutex> lock(program.inputMutex);
483504
//polling actual hardware is very time-consuming; skip call if poll was called too recently
484505
auto thisPoll = chrono::millisecond();
485506
if(thisPoll - lastPoll < pollFrequency && !force) return;
@@ -502,6 +523,7 @@ auto InputManager::poll(bool force) -> void {
502523
}
503524

504525
auto InputManager::eventInput(shared_pointer<HID::Device> device, u32 groupID, u32 inputID, s16 oldValue, s16 newValue) -> void {
526+
lock_guard<recursive_mutex> lock(program.inputMutex);
505527
inputSettings.eventInput(device, groupID, inputID, oldValue, newValue);
506528
hotkeySettings.eventInput(device, groupID, inputID, oldValue, newValue);
507529
}

Diff for: desktop-ui/presentation/presentation.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ auto Presentation::loadEmulators() -> void {
355355
item.setIconForFile(location);
356356
item.setText({Location::base(location).trimRight("/"), " (", system, ")"});
357357
item.onActivate([=] {
358+
lock_guard<recursive_mutex> lock(program.programMutex);
358359
if(!inode::exists(location)) {
359360
MessageDialog()
360361
.setTitle("Error")
@@ -369,7 +370,8 @@ auto Presentation::loadEmulators() -> void {
369370
}
370371
for(auto& emulator : emulators) {
371372
if(emulator->name == system) {
372-
return (void)program.load(emulator, location);
373+
program.load(emulator, location);
374+
return;
373375
}
374376
}
375377
});

0 commit comments

Comments
 (0)