From 68fe5534a46e60b3b8d7039374991fa063b6a59f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 10 Jan 2019 02:00:58 +0100 Subject: [PATCH] - moved the SectorMarker handling into the level itself. --- src/dobjgc.cpp | 106 ++--------------------------------------- src/g_level.cpp | 112 ++++++++++++++++++++++++++++++++++++++++++++ src/g_levellocals.h | 2 + 3 files changed, 117 insertions(+), 103 deletions(-) diff --git a/src/dobjgc.cpp b/src/dobjgc.cpp index f86cdb1d3c..94d6a946c7 100644 --- a/src/dobjgc.cpp +++ b/src/dobjgc.cpp @@ -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(); + 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 diff --git a/src/g_level.cpp b/src/g_level.cpp index 6825d78edb..24fa264a52 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -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(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); diff --git a/src/g_levellocals.h b/src/g_levellocals.h index 6e15f2a651..17c834788b 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -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