- moved the SectorMarker handling into the level itself.

This commit is contained in:
Christoph Oelckers 2019-01-10 02:00:58 +01:00
parent 8cc563b80f
commit 9506b0e337
3 changed files with 118 additions and 105 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 --------------------------------------------------------------------
//==========================================================================
@ -306,7 +285,6 @@ static void MarkRoot()
DThinker::MarkRoots();
Mark(E_FirstEventHandler);
Mark(E_LastEventHandler);
level.Mark();
// Mark players.
for (i = 0; i < MAXPLAYERS; i++)
@ -315,19 +293,11 @@ static void MarkRoot()
players[i].PropagateMark();
}
// Mark sectors.
if (SectorMarker == nullptr && level.sectors.Size() > 0)
ForAllLevels([](FLevelLocals *Level)
{
SectorMarker = Create<DSectorMarker>();
}
else if (level.sectors.Size() == 0)
{
SectorMarker = nullptr;
}
else
{
SectorMarker->SecNum = 0;
}
Mark(SectorMarker);
Level->Mark();
});
// Mark bot stuff.
Mark(bglobal.firstthing);
Mark(bglobal.body1);
@ -614,77 +584,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

@ -1973,6 +1973,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) : 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;
}
//==========================================================================
//
//
@ -1980,6 +2078,20 @@ void P_ReadACSDefereds (FSerializer &arc)
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

@ -56,6 +56,7 @@ class DFraggleThinker;
class DSpotState;
class DSeqNode;
struct FStrifeDialogueNode;
class DSectorMarker;
typedef TMap<int, int> FDialogueIDMap; // maps dialogue IDs to dialogue array index (for ACS)
typedef TMap<FName, int> FDialogueMap; // maps actor class names to dialogue array index
@ -154,6 +155,7 @@ struct FLevelLocals : public FLevelData
memset(TIDHash, 0, sizeof(TIDHash));
}
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