- fixed: Both main and worker thread were modifying the portal state.

The parts in the main thread have been offloaded to a new worker job to avoid having to use a mutex to protect the portal state.
This commit is contained in:
Christoph Oelckers 2018-12-16 09:05:02 +01:00
parent c92e6b03ac
commit d0ce021805

View file

@ -56,6 +56,7 @@ struct RenderJob
WallJob,
SpriteJob,
ParticleJob,
PortalJob,
TerminateJob // inserted when all work is done so that the worker can return.
};
@ -177,7 +178,12 @@ void HWDrawInfo::WorkerThread()
RenderParticles(job->sub, front);
SetupSprite.Unclock();
break;
case RenderJob::PortalJob:
AddSubsectorToPortal((FSectorPortalGroup *)job->seg, job->sub);
break;
}
}
}
@ -706,14 +712,32 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
// This is for portal coverage.
FSectorPortalGroup *portal;
// AddSubsectorToPortal cannot be called here when using multithreaded processing,
// because the wall processing code in the worker can also modify the portal state.
// To avoid costly synchronization for every access to the portal list,
// the call to AddSubsectorToPortal will be deferred to the worker.
// (GetPortalGruop only accesses static sector data so this check can be done here, restricting the new job to the minimum possible extent.)
portal = fakesector->GetPortalGroup(sector_t::ceiling);
if (portal != nullptr)
{
if (multithread)
{
jobQueue.AddJob(RenderJob::PortalJob, sub, (seg_t *)portal);
}
else
{
AddSubsectorToPortal(portal, sub);
}
}
portal = fakesector->GetPortalGroup(sector_t::floor);
if (portal != nullptr)
{
if (multithread)
{
jobQueue.AddJob(RenderJob::PortalJob, sub, (seg_t *)portal);
}
else
{
AddSubsectorToPortal(portal, sub);
}
@ -721,6 +745,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
}
}
}
}