display: Release lock before notifying render thread in GraphicsEngine

Otherwise the render thread will wake up only to be blocked by the mutex right away.
This commit is contained in:
rdb 2022-02-15 17:28:36 +01:00
parent 07586c82e6
commit aea2d6ef45

View File

@ -925,10 +925,14 @@ render_frame() {
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
RenderThread *thread = (*ti).second;
if (thread->_thread_state == TS_wait) {
// Release before notifying, otherwise the other thread will wake up
// and get blocked on the mutex straight away.
thread->_thread_state = TS_do_frame;
thread->_cv_mutex.release();
thread->_cv_start.notify();
} else {
thread->_cv_mutex.release();
}
thread->_cv_mutex.release();
}
// Some threads may still be drawing, so indicate that we have to wait for
@ -1036,8 +1040,8 @@ open_windows() {
}
thread->_thread_state = TS_do_windows;
thread->_cv_start.notify();
thread->_cv_mutex.release();
thread->_cv_start.notify();
}
}
@ -1154,11 +1158,11 @@ extract_texture_data(Texture *tex, GraphicsStateGuardian *gsg) {
thread->_gsg = gsg;
thread->_texture = tex;
thread->_thread_state = TS_do_extract;
thread->_cv_start.notify();
thread->_cv_mutex.release();
thread->_cv_start.notify();
thread->_cv_mutex.acquire();
//XXX is this necessary, or is acquiring the mutex enough?
// Wait for it to finish the extraction.
while (thread->_thread_state != TS_wait) {
thread->_cv_done.wait();
}
@ -1222,11 +1226,11 @@ dispatch_compute(const LVecBase3i &work_groups, const ShaderAttrib *sattr, Graph
thread->_state = state.p();
thread->_work_groups = work_groups;
thread->_thread_state = TS_do_compute;
thread->_cv_start.notify();
thread->_cv_mutex.release();
thread->_cv_start.notify();
thread->_cv_mutex.acquire();
//XXX is this necessary, or is acquiring the mutex enough?
// Wait for it to finish the compute task.
while (thread->_thread_state != TS_wait) {
thread->_cv_done.wait();
}
@ -1292,11 +1296,11 @@ do_get_screenshot(DisplayRegion *region, GraphicsStateGuardian *gsg) {
// Now that the draw thread is idle, signal it to do the extraction task.
thread->_region = region;
thread->_thread_state = TS_do_screenshot;
thread->_cv_start.notify();
thread->_cv_mutex.release();
thread->_cv_start.notify();
thread->_cv_mutex.acquire();
//XXX is this necessary, or is acquiring the mutex enough?
// Wait for it to finish the extraction.
while (thread->_thread_state != TS_wait) {
thread->_cv_done.wait();
}
@ -1937,8 +1941,8 @@ do_flip_frame(Thread *current_thread) {
RenderThread *thread = (*ti).second;
nassertv(thread->_thread_state == TS_wait);
thread->_thread_state = TS_do_flip;
thread->_cv_start.notify();
thread->_cv_mutex.release();
thread->_cv_start.notify();
}
}
@ -2365,8 +2369,8 @@ terminate_threads(Thread *current_thread) {
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
RenderThread *thread = (*ti).second;
thread->_thread_state = TS_terminate;
thread->_cv_start.notify();
thread->_cv_mutex.release();
thread->_cv_start.notify();
}
// Finally, wait for them all to finish cleaning up.