From 07571da98ccad2fd2c360c4b73ba989a902f184b Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 10 Jun 2016 18:43:49 +0200 Subject: [PATCH] Improved how threaded rendering is handled --- src/r_draw.h | 16 ++++++++++++---- src/r_draw_rgba.cpp | 24 ++++++++++++++++++++++-- src/r_main.cpp | 4 +++- src/r_swrenderer.cpp | 3 ++- 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/r_draw.h b/src/r_draw.h index 37a0e67788..d192dc5e49 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -443,8 +443,11 @@ void R_SetDSColorMapLight(FColormap *base_colormap, float light, int shade); void R_SetTranslationMap(lighttable_t *translation); +// Redirect drawer commands to worker threads +void R_BeginDrawerCommands(); + // Wait until all drawers finished executing -void R_FinishDrawerCommands(); +void R_EndDrawerCommands(); class DrawerCommandQueue; @@ -530,13 +533,14 @@ class DrawerCommandQueue std::condition_variable end_condition; size_t finished_threads = 0; - bool no_threading = false; + int threaded_render = 0; DrawerThread single_core_thread; int num_passes = 2; int rows_in_pass = 540; void StartThreads(); void StopThreads(); + void Finish(); static DrawerCommandQueue *Instance(); @@ -551,7 +555,7 @@ public: static void QueueCommand(Types &&... args) { auto queue = Instance(); - if (queue->no_threading) + if (queue->threaded_render == 0) { T command(std::forward(args)...); command.Execute(&queue->single_core_thread); @@ -565,9 +569,13 @@ public: queue->commands.push_back(command); } } + + // Redirects all drawing commands to worker threads until Finish is called + // Begin/End blocks can be nested. + static void Begin(); // Wait until all worker threads finished executing commands - static void Finish(); + static void End(); }; #endif diff --git a/src/r_draw_rgba.cpp b/src/r_draw_rgba.cpp index e2dbd443ab..23ab106a65 100644 --- a/src/r_draw_rgba.cpp +++ b/src/r_draw_rgba.cpp @@ -82,6 +82,21 @@ void* DrawerCommandQueue::AllocMemory(size_t size) return data; } +void DrawerCommandQueue::Begin() +{ + auto queue = Instance(); + queue->Finish(); + queue->threaded_render++; +} + +void DrawerCommandQueue::End() +{ + auto queue = Instance(); + queue->Finish(); + if (queue->threaded_render > 0) + queue->threaded_render--; +} + void DrawerCommandQueue::Finish() { auto queue = Instance(); @@ -3515,9 +3530,14 @@ public: ///////////////////////////////////////////////////////////////////////////// -void R_FinishDrawerCommands() +void R_BeginDrawerCommands() { - DrawerCommandQueue::Finish(); + DrawerCommandQueue::Begin(); +} + +void R_EndDrawerCommands() +{ + DrawerCommandQueue::End(); } void R_DrawColumnP_RGBA_C() diff --git a/src/r_main.cpp b/src/r_main.cpp index 348c701204..c1b78303b3 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -960,6 +960,8 @@ void R_RenderViewToCanvas (AActor *actor, DCanvas *canvas, r_swtruecolor = canvas->IsBgra(); R_InitColumnDrawers(); } + + R_BeginDrawerCommands(); viewwidth = width; RenderTarget = canvas; @@ -979,7 +981,7 @@ void R_RenderViewToCanvas (AActor *actor, DCanvas *canvas, R_SetupBuffer (); screen->Unlock (); - R_FinishDrawerCommands(); + R_EndDrawerCommands(); viewactive = savedviewactive; r_swtruecolor = savedoutputformat; diff --git a/src/r_swrenderer.cpp b/src/r_swrenderer.cpp index 62190b6064..11f879c38c 100644 --- a/src/r_swrenderer.cpp +++ b/src/r_swrenderer.cpp @@ -162,10 +162,11 @@ void FSoftwareRenderer::RenderView(player_t *player) R_InitColumnDrawers(); } + R_BeginDrawerCommands(); R_RenderActorView (player->mo); // [RH] Let cameras draw onto textures that were visible this frame. FCanvasTextureInfo::UpdateAll (); - R_FinishDrawerCommands(); + R_EndDrawerCommands(); } //==========================================================================