Fixed a lot of disable lights bugs

develop
Warmist 2013-06-30 22:03:07 +03:00
parent f34a4ce34e
commit 5ad3a7570f
3 changed files with 37 additions and 9 deletions

@ -1043,10 +1043,11 @@ void lightThread::run()
{
while(!isDone)
{
{
tthread::lock_guard<tthread::mutex> guard(dispatch.occlusionMutex);
{//wait for occlusion (and lights) to be ready
tthread::lock_guard<tthread::mutex> 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<tthread::mutex> 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<tthread::mutex> guardWrite(writeLock);
writeCount=0;
}
tthread::lock_guard<tthread::mutex> guard(occlusionMutex);
tthread::lock_guard<tthread::mutex> guard1(occlusionMutex);
tthread::lock_guard<tthread::mutex> 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;i<threadPool.size();i++)
{
threadPool[i]->isDone=true;
}
occlusionDone.notify_all();//if stuck signal that you are done with stuff.
for(int i=0;i<threadPool.size();i++)
{
threadPool[i]->myThread->join();
}
threadPool.clear();
@ -1239,3 +1259,8 @@ void lightThreadDispatch::waitForWrites()
writesDone.wait(writeLock); //if not, wait a bit
}
}
lightThreadDispatch::~lightThreadDispatch()
{
shutdown();
}

@ -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<DFHack::rect2d> unprocessed; //stack of parts of map where lighting is not finished
std::vector<rgbf>& occlusion;
@ -156,6 +157,7 @@ public:
int writeCount;
lightThreadDispatch(lightingEngineViewscreen* p);
~lightThreadDispatch();
void signalDoneOcclusion();
void shutdown();
void waitForWrites();

@ -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 <string> & 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;