16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-18 12:19:19 +02:00

Merge branch 'milek-dev' into gfx-work

This commit is contained in:
milek7
2018-10-25 13:37:57 +02:00
26 changed files with 2056 additions and 1669 deletions

View File

@@ -27,12 +27,11 @@ void render_task::run() {
if( output != nullptr ) {
auto *outputwidth { PyObject_CallMethod( m_renderer, "get_width", nullptr ) };
auto *outputheight { PyObject_CallMethod( m_renderer, "get_height", nullptr ) };
opengl_texture &tex = GfxRenderer.Texture( m_target );
// upload texture data
if( ( outputwidth != nullptr )
&& ( outputheight != nullptr )
&& tex.id != -1) {
::glBindTexture( GL_TEXTURE_2D, tex.id );
&& m_target != -1) {
::glBindTexture( GL_TEXTURE_2D, m_target );
int w = PyInt_AsLong( outputwidth );
int h = PyInt_AsLong( outputheight );
@@ -108,8 +107,6 @@ auto python_taskqueue::init() -> bool {
PyObject *stringioclassname { nullptr };
PyObject *stringioobject { nullptr };
// save a pointer to the main PyThreadState object
m_mainthread = PyThreadState_Get();
// do the setup work while we hold the lock
m_main = PyImport_ImportModule("__main__");
if (m_main == nullptr) {
@@ -135,8 +132,8 @@ auto python_taskqueue::init() -> bool {
if( false == run_file( "abstractscreenrenderer" ) ) { goto release_and_exit; }
// release the lock
PyEval_ReleaseLock();
// release the lock, save the state for future use
m_mainthread = PyEval_SaveThread();
WriteLog( "Python Interpreter setup complete" );
@@ -144,12 +141,11 @@ auto python_taskqueue::init() -> bool {
for( auto &worker : m_workers ) {
auto *openglcontextwindow { Application.window( -1 ) };
worker =
std::make_unique<std::thread>(
&python_taskqueue::run, this,
openglcontextwindow, std::ref( m_tasks ), std::ref( m_condition ), std::ref( m_exit ) );
worker = std::thread(
&python_taskqueue::run, this,
openglcontextwindow, std::ref( m_tasks ), std::ref( m_condition ), std::ref( m_exit ) );
if( worker == nullptr ) { return false; }
if( false == worker.joinable() ) { return false; }
}
return true;
@@ -168,9 +164,8 @@ void python_taskqueue::exit() {
m_exit = true;
m_condition.notify_all();
// let them free up their shit before we proceed
for( auto const &worker : m_workers ) {
if (worker && worker->joinable())
worker->join();
for( auto &worker : m_workers ) {
worker.join();
}
// get rid of the leftover tasks
// with the workers dead we don't have to worry about concurrent access anymore
@@ -178,8 +173,7 @@ void python_taskqueue::exit() {
task->cancel();
}
// take a bow
PyEval_AcquireLock();
PyThreadState_Swap( m_mainthread );
acquire_lock();
Py_Finalize();
}
@@ -188,7 +182,7 @@ auto python_taskqueue::insert( task_request const &Task ) -> bool {
if( ( Task.renderer.empty() )
|| ( Task.input == nullptr )
|| ( Task.target == null_handle ) ) { return false; }
|| ( Task.target == 0 ) ) { return false; }
auto *renderer { fetch_renderer( Task.renderer ) };
if( renderer == nullptr ) { return false; }
@@ -202,11 +196,11 @@ auto python_taskqueue::insert( task_request const &Task ) -> bool {
for( auto &task : m_tasks.data ) {
if( task->target() == Task.target ) {
// replace pending task in the slot with the more recent one
PyEval_AcquireLock();
acquire_lock();
{
task->cancel();
}
PyEval_ReleaseLock();
release_lock();
task = newtask;
newtaskinserted = true;
break;
@@ -240,6 +234,18 @@ auto python_taskqueue::run_file( std::string const &File, std::string const &Pat
return true;
}
// acquires the python gil and sets the main thread as current
void python_taskqueue::acquire_lock() {
PyEval_RestoreThread( m_mainthread );
}
// releases the python gil and swaps the main thread out
void python_taskqueue::release_lock() {
PyEval_SaveThread();
}
auto python_taskqueue::fetch_renderer( std::string const Renderer ) ->PyObject * {
auto const lookup { m_renderers.find( Renderer ) };
@@ -250,17 +256,15 @@ auto python_taskqueue::fetch_renderer( std::string const Renderer ) ->PyObject *
auto const path { substr_path( Renderer ) };
auto const file { Renderer.substr( path.size() ) };
PyObject *renderer { nullptr };
PyObject *rendererarguments { nullptr };
PyObject *renderername { nullptr };
PyEval_AcquireLock();
if( m_main == nullptr ) {
ErrorLog( "Python Renderer: __main__ module is missing" );
goto cache_and_return;
}
PyObject *rendererarguments { nullptr };
PyObject *renderername { nullptr };
acquire_lock();
{
if( m_main == nullptr ) {
ErrorLog( "Python Renderer: __main__ module is missing" );
goto cache_and_return;
}
if( false == run_file( file, path ) ) {
goto cache_and_return;
}
@@ -287,7 +291,7 @@ cache_and_return:
Py_DECREF( rendererarguments );
}
}
PyEval_ReleaseLock();
release_lock();
// cache the failures as well so we don't try again on subsequent requests
m_renderers.emplace( Renderer, renderer );
return renderer;
@@ -320,14 +324,14 @@ void python_taskqueue::run( GLFWwindow *Context, rendertask_sequence &Tasks, thr
}
if( task != nullptr ) {
// swap in my thread state
PyEval_AcquireLock();
PyThreadState_Swap( threadstate );
// execute python code
task->run();
error();
PyEval_RestoreThread( threadstate );
{
// execute python code
task->run();
error();
}
// clear the thread state
PyThreadState_Swap( nullptr );
PyEval_ReleaseLock();
PyEval_SaveThread();
}
// TBD, TODO: add some idle time between tasks in case we're on a single thread cpu?
} while( task != nullptr );