- 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, WallJob,
SpriteJob, SpriteJob,
ParticleJob, ParticleJob,
PortalJob,
TerminateJob // inserted when all work is done so that the worker can return. TerminateJob // inserted when all work is done so that the worker can return.
}; };
@ -177,7 +178,12 @@ void HWDrawInfo::WorkerThread()
RenderParticles(job->sub, front); RenderParticles(job->sub, front);
SetupSprite.Unclock(); SetupSprite.Unclock();
break; break;
case RenderJob::PortalJob:
AddSubsectorToPortal((FSectorPortalGroup *)job->seg, job->sub);
break;
} }
} }
} }
@ -706,16 +712,35 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
// This is for portal coverage. // This is for portal coverage.
FSectorPortalGroup *portal; 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); portal = fakesector->GetPortalGroup(sector_t::ceiling);
if (portal != nullptr) if (portal != nullptr)
{ {
AddSubsectorToPortal(portal, sub); if (multithread)
{
jobQueue.AddJob(RenderJob::PortalJob, sub, (seg_t *)portal);
}
else
{
AddSubsectorToPortal(portal, sub);
}
} }
portal = fakesector->GetPortalGroup(sector_t::floor); portal = fakesector->GetPortalGroup(sector_t::floor);
if (portal != nullptr) if (portal != nullptr)
{ {
AddSubsectorToPortal(portal, sub); if (multithread)
{
jobQueue.AddJob(RenderJob::PortalJob, sub, (seg_t *)portal);
}
else
{
AddSubsectorToPortal(portal, sub);
}
} }
} }
} }