- moved the SectorMarker handling into the level itself.

This commit is contained in:
Christoph Oelckers 2019-01-10 02:00:58 +01:00
parent ea849e5aca
commit 68fe5534a4
3 changed files with 117 additions and 103 deletions

View File

@ -96,9 +96,6 @@
#define DEFAULT_GCMUL 400 // GC runs 'quadruple the speed' of memory allocation
// Number of sectors to mark for each step.
#define SECTORSTEPSIZE 32
#define POLYSTEPSIZE 120
#define SIDEDEFSTEPSIZE 240
#define GCSTEPSIZE 1024u
#define GCSWEEPMAX 40
@ -107,22 +104,6 @@
// TYPES -------------------------------------------------------------------
// This object is responsible for marking sectors during the propagate
// stage. In case there are many, many sectors, it lets us break them
// up instead of marking them all at once.
class DSectorMarker : public DObject
{
DECLARE_CLASS(DSectorMarker, DObject)
public:
DSectorMarker() : SecNum(0),PolyNum(0),SideNum(0) {}
size_t PropagateMark();
int SecNum;
int PolyNum;
int SideNum;
};
IMPLEMENT_CLASS(DSectorMarker, false, false)
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
@ -154,8 +135,6 @@ bool FinalGC;
// PRIVATE DATA DEFINITIONS ------------------------------------------------
static DSectorMarker *SectorMarker;
// CODE --------------------------------------------------------------------
//==========================================================================
@ -316,19 +295,11 @@ static void MarkRoot()
players[i].PropagateMark();
}
// Mark sectors.
if (SectorMarker == nullptr && level.sectors.Size() > 0)
for auto Level : AllLevels())
{
SectorMarker = Create<DSectorMarker>();
Level->Mark();
}
else if (level.sectors.Size() == 0)
{
SectorMarker = nullptr;
}
else
{
SectorMarker->SecNum = 0;
}
Mark(SectorMarker);
// Mark bot stuff.
Mark(bglobal.firstthing);
Mark(bglobal.body1);
@ -615,77 +586,6 @@ void DelSoftRoot(DObject *obj)
}
//==========================================================================
//
// DSectorMarker :: PropagateMark
//
// Propagates marks across a few sectors and reinserts itself into the
// gray list if it didn't do them all.
//
//==========================================================================
size_t DSectorMarker::PropagateMark()
{
int i;
int marked = 0;
bool moretodo = false;
int numsectors = level.sectors.Size();
for (i = 0; i < SECTORSTEPSIZE && SecNum + i < numsectors; ++i)
{
sector_t *sec = &level.sectors[SecNum + i];
GC::Mark(sec->SoundTarget);
GC::Mark(sec->SecActTarget);
GC::Mark(sec->floordata);
GC::Mark(sec->ceilingdata);
GC::Mark(sec->lightingdata);
for(int j=0;j<4;j++) GC::Mark(sec->interpolations[j]);
}
marked += i * sizeof(sector_t);
if (SecNum + i < numsectors)
{
SecNum += i;
moretodo = true;
}
if (!moretodo && level.Polyobjects.Size() > 0)
{
for (i = 0; i < POLYSTEPSIZE && PolyNum + i < (int)level.Polyobjects.Size(); ++i)
{
GC::Mark(level.Polyobjects[PolyNum + i].interpolation);
}
marked += i * sizeof(FPolyObj);
if (PolyNum + i < (int)level.Polyobjects.Size())
{
PolyNum += i;
moretodo = true;
}
}
if (!moretodo && level.sides.Size() > 0)
{
for (i = 0; i < SIDEDEFSTEPSIZE && SideNum + i < (int)level.sides.Size(); ++i)
{
side_t *side = &level.sides[SideNum + i];
for (int j = 0; j < 3; j++) GC::Mark(side->textures[j].interpolation);
}
marked += i * sizeof(side_t);
if (SideNum + i < (int)level.sides.Size())
{
SideNum += i;
moretodo = true;
}
}
// If there are more sectors to mark, put ourself back into the gray
// list.
if (moretodo)
{
Black2Gray();
GCNext = GC::Gray;
GC::Gray = this;
}
return marked;
}
//==========================================================================
//
// STAT gc

View File

@ -1974,6 +1974,104 @@ void P_ReadACSDefereds (FSerializer &arc)
}
//==========================================================================
//
// This object is responsible for marking sectors during the propagate
// stage. In case there are many, many sectors, it lets us break them
// up instead of marking them all at once.
//
//==========================================================================
class DSectorMarker : public DObject
{
enum
{
SECTORSTEPSIZE = 32,
POLYSTEPSIZE = 120,
SIDEDEFSTEPSIZE = 240
};
DECLARE_CLASS(DSectorMarker, DObject)
public:
DSectorMarker(FLevelLocals *l) : Level(l), SecNum(0),PolyNum(0),SideNum(0) {}
size_t PropagateMark();
FLevelLocals *Level;
int SecNum;
int PolyNum;
int SideNum;
};
IMPLEMENT_CLASS(DSectorMarker, true, false)
//==========================================================================
//
// DSectorMarker :: PropagateMark
//
// Propagates marks across a few sectors and reinserts itself into the
// gray list if it didn't do them all.
//
//==========================================================================
size_t DSectorMarker::PropagateMark()
{
int i;
int marked = 0;
bool moretodo = false;
int numsectors = Level->sectors.Size();
for (i = 0; i < SECTORSTEPSIZE && SecNum + i < numsectors; ++i)
{
sector_t *sec = &Level->sectors[SecNum + i];
GC::Mark(sec->SoundTarget);
GC::Mark(sec->SecActTarget);
GC::Mark(sec->floordata);
GC::Mark(sec->ceilingdata);
GC::Mark(sec->lightingdata);
for(int j = 0; j < 4; j++) GC::Mark(sec->interpolations[j]);
}
marked += i * sizeof(sector_t);
if (SecNum + i < numsectors)
{
SecNum += i;
moretodo = true;
}
if (!moretodo && Level->Polyobjects.Size() > 0)
{
for (i = 0; i < POLYSTEPSIZE && PolyNum + i < (int)Level->Polyobjects.Size(); ++i)
{
GC::Mark(Level->Polyobjects[PolyNum + i].interpolation);
}
marked += i * sizeof(FPolyObj);
if (PolyNum + i < (int)Level->Polyobjects.Size())
{
PolyNum += i;
moretodo = true;
}
}
if (!moretodo && Level->sides.Size() > 0)
{
for (i = 0; i < SIDEDEFSTEPSIZE && SideNum + i < (int)Level->sides.Size(); ++i)
{
side_t *side = &Level->sides[SideNum + i];
for (int j = 0; j < 3; j++) GC::Mark(side->textures[j].interpolation);
}
marked += i * sizeof(side_t);
if (SideNum + i < (int)Level->sides.Size())
{
SideNum += i;
moretodo = true;
}
}
// If there are more items to mark, put ourself back into the gray list.
if (moretodo)
{
Black2Gray();
GCNext = GC::Gray;
GC::Gray = this;
}
return marked;
}
//==========================================================================
//
//
@ -1995,6 +2093,20 @@ void FLevelLocals::Tick ()
void FLevelLocals::Mark()
{
if (SectorMarker == nullptr && (sectors.Size() > 0 || Polyobjects.Size() > 0 || sides.Size() > 0))
{
SectorMarker = Create<DSectorMarker>(this);
}
else if (sectors.Size() == 0 && Polyobjects.Size() == 0 && sides.Size() == 0)
{
SectorMarker = nullptr;
}
else
{
SectorMarker->SecNum = 0;
}
GC::Mark(SectorMarker);
GC::Mark(SpotState);
GC::Mark(FraggleScriptThinker);
GC::Mark(ACSThinker);

View File

@ -452,6 +452,8 @@ public:
int i_compatflags = 0;
int i_compatflags2 = 0;
DSectorMarker *SectorMarker;
uint8_t md5[16]; // for savegame validation. If the MD5 does not match the savegame won't be loaded.
int time; // time in the hub
int maptime; // time in the map