Issuing audio driver callbacks from their own thread.
This commit is contained in:
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <xenia/emulator.h>
|
#include <xenia/emulator.h>
|
||||||
#include <xenia/cpu/processor.h>
|
#include <xenia/cpu/processor.h>
|
||||||
|
#include <xenia/cpu/xenon_thread_state.h>
|
||||||
#include <xenia/apu/audio_driver.h>
|
#include <xenia/apu/audio_driver.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -44,6 +45,14 @@ X_STATUS AudioSystem::Setup() {
|
|||||||
callbacks.write = (RegisterWriteCallback)WriteRegisterThunk;
|
callbacks.write = (RegisterWriteCallback)WriteRegisterThunk;
|
||||||
emulator_->processor()->AddRegisterAccessCallbacks(callbacks);
|
emulator_->processor()->AddRegisterAccessCallbacks(callbacks);
|
||||||
|
|
||||||
|
// Setup worker thread state. This lets us make calls into guest code.
|
||||||
|
thread_state_ = new XenonThreadState(
|
||||||
|
emulator_->processor()->runtime(), 0, 16 * 1024, 0);
|
||||||
|
thread_state_->set_name("Audio Worker");
|
||||||
|
thread_block_ = (uint32_t)memory_->HeapAlloc(
|
||||||
|
0, 2048, alloy::MEMORY_FLAG_ZERO);
|
||||||
|
thread_state_->context()->r[13] = thread_block_;
|
||||||
|
|
||||||
// Create worker thread.
|
// Create worker thread.
|
||||||
// This will initialize the audio system.
|
// This will initialize the audio system.
|
||||||
// Init needs to happen there so that any thread-local stuff
|
// Init needs to happen there so that any thread-local stuff
|
||||||
@@ -82,8 +91,8 @@ void AudioSystem::ThreadStart() {
|
|||||||
auto clients = clients_;
|
auto clients = clients_;
|
||||||
xe_mutex_unlock(lock_);
|
xe_mutex_unlock(lock_);
|
||||||
for (auto it = clients.begin(); it != clients.end(); ++it) {
|
for (auto it = clients.begin(); it != clients.end(); ++it) {
|
||||||
processor->ExecuteInterrupt(
|
processor->Execute(
|
||||||
0, it->callback, it->wrapped_callback_arg, 0);
|
thread_state_, it->callback, it->wrapped_callback_arg, 0);
|
||||||
}
|
}
|
||||||
//worker_->Pump();
|
//worker_->Pump();
|
||||||
Sleep(1000);
|
Sleep(1000);
|
||||||
@@ -110,6 +119,9 @@ void AudioSystem::Shutdown() {
|
|||||||
xe_thread_join(thread_);
|
xe_thread_join(thread_);
|
||||||
xe_thread_release(thread_);
|
xe_thread_release(thread_);
|
||||||
|
|
||||||
|
delete thread_state_;
|
||||||
|
memory()->HeapFree(thread_block_, 0);
|
||||||
|
|
||||||
xe_run_loop_release(run_loop_);
|
xe_run_loop_release(run_loop_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
XEDECLARECLASS1(xe, Emulator);
|
XEDECLARECLASS1(xe, Emulator);
|
||||||
XEDECLARECLASS2(xe, cpu, Processor);
|
XEDECLARECLASS2(xe, cpu, Processor);
|
||||||
|
XEDECLARECLASS2(xe, cpu, XenonThreadState);
|
||||||
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
@@ -72,6 +73,8 @@ protected:
|
|||||||
|
|
||||||
xe_run_loop_ref run_loop_;
|
xe_run_loop_ref run_loop_;
|
||||||
xe_thread_ref thread_;
|
xe_thread_ref thread_;
|
||||||
|
cpu::XenonThreadState* thread_state_;
|
||||||
|
uint32_t thread_block_;
|
||||||
bool running_;
|
bool running_;
|
||||||
xe_mutex_t* lock_;
|
xe_mutex_t* lock_;
|
||||||
|
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ int Processor::Setup() {
|
|||||||
interrupt_thread_lock_ = xe_mutex_alloc(10000);
|
interrupt_thread_lock_ = xe_mutex_alloc(10000);
|
||||||
interrupt_thread_state_ = new XenonThreadState(
|
interrupt_thread_state_ = new XenonThreadState(
|
||||||
runtime_, 0, 16 * 1024, 0);
|
runtime_, 0, 16 * 1024, 0);
|
||||||
|
interrupt_thread_state_->set_name("Interrupt");
|
||||||
interrupt_thread_block_ = memory_->HeapAlloc(
|
interrupt_thread_block_ = memory_->HeapAlloc(
|
||||||
0, 2048, MEMORY_FLAG_ZERO);
|
0, 2048, MEMORY_FLAG_ZERO);
|
||||||
interrupt_thread_state_->context()->r[13] = interrupt_thread_block_;
|
interrupt_thread_state_->context()->r[13] = interrupt_thread_block_;
|
||||||
|
|||||||
Reference in New Issue
Block a user