diff --git a/plugins/rendermax/renderer_light.cpp b/plugins/rendermax/renderer_light.cpp index fc7202890..fb5bd8f0e 100644 --- a/plugins/rendermax/renderer_light.cpp +++ b/plugins/rendermax/renderer_light.cpp @@ -1043,10 +1043,11 @@ void lightThread::run() { while(!isDone) { - { - tthread::lock_guard guard(dispatch.occlusionMutex); + {//wait for occlusion (and lights) to be ready + tthread::lock_guard guard(dispatch.occlusionMutex); + if(!dispatch.occlusionReady) dispatch.occlusionDone.wait(dispatch.occlusionMutex);//wait for work - if(dispatch.unprocessed.size()==0) //spurious wake-up + if(dispatch.unprocessed.size()==0 || !dispatch.occlusionReady) //spurious wake-up continue; if(dispatch.occlusion.size()!=canvas.size()) //oh no somebody resized stuff canvas.resize(dispatch.occlusion.size()); @@ -1055,8 +1056,18 @@ void lightThread::run() { //get my rectangle (any will do) tthread::lock_guard guard(dispatch.unprocessedMutex); + if (dispatch.unprocessed.size()==0) + { + //wtf?? why?! + continue; + } myRect=dispatch.unprocessed.top(); dispatch.unprocessed.pop(); + if (dispatch.unprocessed.size()==0) + { + dispatch.occlusionReady=false; + } + } work(); { @@ -1173,8 +1184,10 @@ void lightThreadDispatch::signalDoneOcclusion() tthread::lock_guard guardWrite(writeLock); writeCount=0; } - tthread::lock_guard guard(occlusionMutex); - + tthread::lock_guard guard1(occlusionMutex); + tthread::lock_guard guard2(unprocessedMutex); + while(!unprocessed.empty()) + unprocessed.pop(); viewPort=getMapViewport(); int threadCount=threadPool.size(); int w=viewPort.second.x-viewPort.first.x; @@ -1189,10 +1202,12 @@ void lightThreadDispatch::signalDoneOcclusion() area.second.x=viewPort.first.x+(i+1)*slicew; unprocessed.push(area); } + occlusionReady=true; occlusionDone.notify_all(); } -lightThreadDispatch::lightThreadDispatch( lightingEngineViewscreen* p ):parent(p),lights(parent->lights),occlusion(parent->ocupancy),lightMap(parent->lightMap),writeCount(0) +lightThreadDispatch::lightThreadDispatch( lightingEngineViewscreen* p ):parent(p),lights(parent->lights),occlusion(parent->ocupancy), + lightMap(parent->lightMap),writeCount(0),occlusionReady(false) { } @@ -1202,6 +1217,11 @@ void lightThreadDispatch::shutdown() for(int i=0;iisDone=true; + + } + occlusionDone.notify_all();//if stuck signal that you are done with stuff. + for(int i=0;imyThread->join(); } threadPool.clear(); @@ -1239,3 +1259,8 @@ void lightThreadDispatch::waitForWrites() writesDone.wait(writeLock); //if not, wait a bit } } + +lightThreadDispatch::~lightThreadDispatch() +{ + shutdown(); +} diff --git a/plugins/rendermax/renderer_light.hpp b/plugins/rendermax/renderer_light.hpp index cb43c20be..0f981cf8b 100644 --- a/plugins/rendermax/renderer_light.hpp +++ b/plugins/rendermax/renderer_light.hpp @@ -71,7 +71,7 @@ class lightingEngine { public: lightingEngine(renderer_light* target):myRenderer(target){} - + virtual ~lightingEngine(){} virtual void reinit()=0; virtual void calculate()=0; @@ -145,6 +145,7 @@ public: tthread::mutex occlusionMutex; tthread::condition_variable occlusionDone; //all threads wait for occlusion to finish + bool occlusionReady; tthread::mutex unprocessedMutex; std::stack unprocessed; //stack of parts of map where lighting is not finished std::vector& occlusion; @@ -156,6 +157,7 @@ public: int writeCount; lightThreadDispatch(lightingEngineViewscreen* p); + ~lightThreadDispatch(); void signalDoneOcclusion(); void shutdown(); void waitForWrites(); diff --git a/plugins/rendermax/rendermax.cpp b/plugins/rendermax/rendermax.cpp index e03de7ed2..c5fe90a66 100644 --- a/plugins/rendermax/rendermax.cpp +++ b/plugins/rendermax/rendermax.cpp @@ -88,7 +88,7 @@ void removeOld() INTERPOSE_HOOK(dwarmode_render_hook,render).apply(false); INTERPOSE_HOOK(dungeon_render_hook,render).apply(false); delete engine; - + engine=0; } if(current_mode!=MODE_DEFAULT) delete df::global::enabler->renderer; @@ -405,7 +405,8 @@ static command_result rendermax(color_ostream &out, vector & parameters out.print("%s\n","Not installed, doing nothing."); else removeOld(); - + CoreSuspender guard; + df::global::gps->force_full_display_count++; return CR_OK; } return CR_WRONG_USAGE;