Commit dcaad758 by Jaime Ita Passos

Improved memory management for patches

parent 92c4993d
......@@ -1046,11 +1046,6 @@ static void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2)
spriteinfo_t *info = Z_Calloc(sizeof(spriteinfo_t), PU_STATIC, NULL);
info->available = true;
#ifdef ROTSPRITE
if ((sprites != NULL) && (!sprite2))
R_FreeRotSprite(&sprites[num]);
#endif
do
{
lastline = f->curpos;
......@@ -1179,9 +1174,6 @@ static void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2)
size_t skinnum = skinnumbers[i];
skin_t *skin = &skins[skinnum];
spriteinfo_t *sprinfo = skin->sprinfo;
#ifdef ROTSPRITE
R_FreeSkinRotSprite(skinnum);
#endif
M_Memcpy(&sprinfo[num], info, sizeof(spriteinfo_t));
}
}
......
......@@ -733,7 +733,7 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf)
if (!M_PointInBox(segbbox,splat->v1.x,splat->v1.y) && !M_PointInBox(segbbox,splat->v2.x,splat->v2.y))
continue;
gpatch = W_CachePatchNum(splat->patch, PU_PATCH);
gpatch = W_CachePatchNum(splat->patch, PU_SPRITE);
HWR_GetPatch(gpatch);
wallVerts[0].x = wallVerts[3].x = FIXED_TO_FLOAT(splat->v1.x);
......@@ -3586,7 +3586,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
if (alpha >= 255) return;
alpha = 255 - alpha;
gpatch = (patch_t *)W_CachePatchName("DSHADOW", PU_CACHE);
gpatch = (patch_t *)W_CachePatchName("DSHADOW", PU_SPRITE);
if (!(gpatch && ((GLPatch_t *)gpatch->hardware)->mipmap->format)) return;
HWR_GetPatch(gpatch);
......@@ -4901,8 +4901,8 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (thing->rollangle)
{
rollangle = R_GetRollAngle(thing->rollangle);
if (!(sprframe->rotsprite.cached & (1<<rot)))
R_CacheRotSprite(thing->sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip);
if (sprframe->rotsprite.patch[rot][rollangle] == NULL)
R_CacheRotSprite(thing->sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, rollangle, flip);
rotsprite = sprframe->rotsprite.patch[rot][rollangle];
if (rotsprite != NULL)
{
......@@ -5030,7 +5030,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
vis->gpatch = (patch_t *)rotsprite;
else
#endif
vis->gpatch = (patch_t *)W_CachePatchNum(sprframe->lumppat[rot], PU_CACHE);
vis->gpatch = (patch_t *)W_CachePatchNum(sprframe->lumppat[rot], PU_SPRITE);
vis->flip = flip;
vis->mobj = thing;
vis->z1 = z1;
......@@ -5165,7 +5165,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
vis->z2 = z2;
vis->tz = tz;
vis->dispoffset = 0; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST
vis->gpatch = (patch_t *)W_CachePatchNum(sprframe->lumppat[rot], PU_CACHE);
vis->gpatch = (patch_t *)W_CachePatchNum(sprframe->lumppat[rot], PU_SPRITE);
vis->flip = flip;
vis->mobj = (mobj_t *)thing;
......
......@@ -458,8 +458,8 @@ static int libd_getSpritePatch(lua_State *L)
INT32 rot = R_GetRollAngle(rollangle);
if (rot) {
if (!(sprframe->rotsprite.cached & (1<<angle)))
R_CacheRotSprite(i, frame, NULL, sprframe, angle, sprframe->flip & (1<<angle));
if (sprframe->rotsprite.patch[angle][rot] == NULL)
R_CacheRotSprite(i, frame, NULL, sprframe, angle, rot, sprframe->flip & (1<<angle));
LUA_PushUserdata(L, sprframe->rotsprite.patch[angle][rot], META_PATCH);
lua_pushboolean(L, false);
lua_pushboolean(L, true);
......@@ -469,7 +469,7 @@ static int libd_getSpritePatch(lua_State *L)
#endif
// push both the patch and it's "flip" value
LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_PATCH), META_PATCH);
LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_SPRITE), META_PATCH);
lua_pushboolean(L, (sprframe->flip & (1<<angle)) != 0);
return 2;
}
......@@ -571,8 +571,8 @@ static int libd_getSprite2Patch(lua_State *L)
INT32 rot = R_GetRollAngle(rollangle);
if (rot) {
if (!(sprframe->rotsprite.cached & (1<<angle)))
R_CacheRotSprite(SPR_PLAY, frame, &skins[i].sprinfo[j], sprframe, angle, sprframe->flip & (1<<angle));
if (sprframe->rotsprite.patch[angle][rot] == NULL)
R_CacheRotSprite(SPR_PLAY, frame, &skins[i].sprinfo[j], sprframe, angle, rot, sprframe->flip & (1<<angle));
LUA_PushUserdata(L, sprframe->rotsprite.patch[angle][rot], META_PATCH);
lua_pushboolean(L, false);
lua_pushboolean(L, true);
......@@ -582,7 +582,7 @@ static int libd_getSprite2Patch(lua_State *L)
#endif
// push both the patch and it's "flip" value
LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_PATCH), META_PATCH);
LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_SPRITE), META_PATCH);
lua_pushboolean(L, (sprframe->flip & (1<<angle)) != 0);
return 2;
}
......
......@@ -378,10 +378,6 @@ static int lib_setSpriteInfo(lua_State *L)
UINT32 i = luaL_checkinteger(L, 1);
if (i == 0 || i >= NUMSPRITES)
return luaL_error(L, "spriteinfo[] index %d out of range (1 - %d)", i, NUMSPRITES-1);
#ifdef ROTSPRITE
if (sprites != NULL)
R_FreeRotSprite(&sprites[i]);
#endif
info = &spriteinfo[i]; // get the spriteinfo to assign to.
}
luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table.
......@@ -463,11 +459,6 @@ static int spriteinfo_set(lua_State *L)
lua_remove(L, 1); // remove field
lua_settop(L, 1); // leave only one value
#ifdef ROTSPRITE
if (sprites != NULL)
R_FreeRotSprite(&sprites[sprinfo-spriteinfo]);
#endif
if (fastcmp(field, "pivot"))
{
// pivot[] is a table
......
......@@ -5840,8 +5840,6 @@ static void M_DrawNightsAttackSuperSonic(void)
const UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_YELLOW, GTC_CACHE);
INT32 timer = (ntsatkdrawtimer/4) % 2;
angle_t fa = (FixedAngle(((ntsatkdrawtimer * 4) % 360)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK;
ntssupersonic[0] = W_CachePatchName("NTSSONC1", PU_PATCH);
ntssupersonic[1] = W_CachePatchName("NTSSONC2", PU_PATCH);
V_DrawFixedPatch(235<<FRACBITS, (120<<FRACBITS) - (8*FINESINE(fa)), FRACUNIT, 0, ntssupersonic[timer], colormap);
}
......@@ -6185,7 +6183,7 @@ static void M_StopMessage(INT32 choice)
static void M_DrawImageDef(void)
{
// Grr. Need to autodetect for pic_ts.
pic_t *pictest = (pic_t *)W_CachePatchName(currentMenu->menuitems[itemOn].text,PU_CACHE);
pic_t *pictest = (pic_t *)W_CacheLumpName(currentMenu->menuitems[itemOn].text,PU_CACHE);
if (!pictest->zero)
V_DrawScaledPic(0,0,0,W_GetNumForName(currentMenu->menuitems[itemOn].text));
else
......@@ -10153,6 +10151,9 @@ static void M_NightsAttack(INT32 choice)
// This is really just to make sure Sonic is the played character, just in case
M_PatchSkinNameTable();
ntssupersonic[0] = W_CachePatchName("NTSSONC1", PU_PATCH);
ntssupersonic[1] = W_CachePatchName("NTSSONC2", PU_PATCH);
G_SetGamestate(GS_TIMEATTACK); // do this before M_SetupNextMenu so that menu meta state knows that we're switching
titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please
M_SetupNextMenu(&SP_NightsAttackDef);
......
......@@ -4090,6 +4090,8 @@ boolean P_LoadLevel(boolean fromnetsave)
// Clear pointers that would be left dangling by the purge
R_FlushTranslationColormapCache();
Patch_FreeTag(PU_PATCH_LOWPRIORITY);
Patch_FreeTag(PU_SPRITE_ROTATED);
Z_FreeTags(PU_LEVEL, PU_PURGELEVEL - 1);
#if defined (WALLSPLATS) || defined (FLOORSPLATS)
......@@ -4475,6 +4477,8 @@ boolean P_AddWadFile(const char *wadfilename)
//
// search for sprite replacements
//
Patch_FreeTag(PU_SPRITE);
Patch_FreeTag(PU_SPRITE_ROTATED);
R_AddSpriteDefs(wadnum);
// Reload it all anyway, just in case they
......
......@@ -1308,7 +1308,7 @@ void R_PrecacheLevel(void)
lump = sf->lumppat[a];\
if (devparm)\
spritememory += W_LumpLength(lump);\
W_CachePatchNum(lump, PU_PATCH);\
W_CachePatchNum(lump, PU_SPRITE);\
}
// see R_InitSprites for more about lumppat,lumpid
switch (sf->rotate)
......
......@@ -711,7 +711,6 @@ typedef struct
typedef struct
{
patch_t *patch[16][ROTANGLES];
UINT16 cached;
} rotsprite_t;
#endif/*ROTSPRITE*/
......
......@@ -64,7 +64,7 @@ patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest)
// Frees a patch from memory.
//
void Patch_Free(patch_t *patch)
static void Patch_FreeData(patch_t *patch)
{
#ifdef HWRENDER
if (patch->hardware)
......@@ -75,10 +75,30 @@ void Patch_Free(patch_t *patch)
Z_Free(patch->columnofs);
if (patch->columns)
Z_Free(patch->columns);
}
void Patch_Free(patch_t *patch)
{
Patch_FreeData(patch);
Z_Free(patch);
}
//
// Frees patches with a tag range.
//
static boolean Patch_FreeTagsCallback(void *mem)
{
patch_t *patch = (patch_t *)mem;
Patch_FreeData(patch);
return true;
}
void Patch_FreeTags(INT32 lowtag, INT32 hightag)
{
Z_IterateTags(lowtag, hightag, Patch_FreeTagsCallback);
}
#ifdef HWRENDER
//
// Allocates a hardware patch.
......
......@@ -19,6 +19,9 @@
patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest);
void Patch_Free(patch_t *patch);
#define Patch_FreeTag(tagnum) Patch_FreeTags(tagnum, tagnum)
void Patch_FreeTags(INT32 lowtag, INT32 hightag);
#ifdef HWRENDER
void *Patch_AllocateHardwarePatch(patch_t *patch);
void *Patch_CreateGL(patch_t *patch);
......
......@@ -126,9 +126,7 @@ void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum);
// Sprite rotation
#ifdef ROTSPRITE
INT32 R_GetRollAngle(angle_t rollangle);
void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, spriteframe_t *sprframe, INT32 rot, UINT8 flip);
void R_FreeRotSprite(spritedef_t *spritedef);
void R_FreeSkinRotSprite(size_t skinnum);
void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, spriteframe_t *sprframe, INT32 rot, INT32 angle, UINT8 flip);
extern fixed_t rollcosang[ROTANGLES];
extern fixed_t rollsinang[ROTANGLES];
#endif
......
......@@ -107,7 +107,6 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
// rotsprite
#ifdef ROTSPRITE
sprtemp[frame].rotsprite.cached = 0;
for (r = 0; r < 16; r++)
{
for (ang = 0; ang < ROTANGLES; ang++)
......@@ -241,9 +240,6 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
// if so, it might patch only certain frames, not all
if (spritedef->numframes) // (then spriteframes is not null)
{
#ifdef ROTSPRITE
R_FreeRotSprite(spritedef);
#endif
// copy the already defined sprite frames
M_Memcpy(sprtemp, spritedef->spriteframes,
spritedef->numframes * sizeof (spriteframe_t));
......@@ -402,9 +398,6 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
if (spritedef->numframes && // has been allocated
spritedef->numframes < maxframe) // more frames are defined ?
{
#ifdef ROTSPRITE
R_FreeRotSprite(spritedef);
#endif
Z_Free(spritedef->spriteframes);
spritedef->spriteframes = NULL;
}
......@@ -1237,7 +1230,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
scalemul = FixedMul(FRACUNIT - floordiff/640, scale);
patch = W_CachePatchName("DSHADOW", PU_CACHE);
patch = W_CachePatchName("DSHADOW", PU_SPRITE);
xscale = FixedDiv(projection, tz);
yscale = FixedDiv(projectiony, tz);
shadowxscale = FixedMul(thing->radius*2, scalemul);
......@@ -1533,8 +1526,8 @@ static void R_ProjectSprite(mobj_t *thing)
if (thing->rollangle)
{
rollangle = R_GetRollAngle(thing->rollangle);
if (!(sprframe->rotsprite.cached & (1<<rot)))
R_CacheRotSprite(thing->sprite, frame, sprinfo, sprframe, rot, flip);
if (sprframe->rotsprite.patch[rot][rollangle] == NULL)
R_CacheRotSprite(thing->sprite, frame, sprinfo, sprframe, rot, rollangle, flip);
rotsprite = sprframe->rotsprite.patch[rot][rollangle];
if (rotsprite != NULL)
{
......@@ -1823,7 +1816,7 @@ static void R_ProjectSprite(mobj_t *thing)
vis->patch = rotsprite;
else
#endif
vis->patch = W_CachePatchNum(sprframe->lumppat[rot], PU_CACHE);
vis->patch = W_CachePatchNum(sprframe->lumppat[rot], PU_SPRITE);
//
// determine the colormap (lightlevel & special effects)
......@@ -2006,7 +1999,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
//Fab: lumppat is the lump number of the patch to use, this is different
// than lumpid for sprites-in-pwad : the graphics are patched
vis->patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
vis->patch = W_CachePatchNum(sprframe->lumppat[0], PU_SPRITE);
// specific translucency
if (thing->frame & FF_TRANSMASK)
......
......@@ -232,7 +232,7 @@ void ST_doPaletteStuff(void)
void ST_UnloadGraphics(void)
{
Z_FreeTag(PU_HUDGFX);
Patch_FreeTag(PU_HUDGFX);
}
void ST_LoadGraphics(void)
......@@ -2080,21 +2080,21 @@ static void ST_drawNiGHTSHUD(void)
if (stplyr->powers[pw_nights_superloop])
{
pwr = stplyr->powers[pw_nights_superloop];
V_DrawSmallScaledPatch(110, 44, 0, W_CachePatchName("NPRUA0",PU_CACHE));
V_DrawSmallScaledPatch(110, 44, 0, W_CachePatchName("NPRUA0",PU_SPRITE));
V_DrawThinString(106, 52, V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr)));
}
if (stplyr->powers[pw_nights_helper])
{
pwr = stplyr->powers[pw_nights_helper];
V_DrawSmallScaledPatch(150, 44, 0, W_CachePatchName("NPRUC0",PU_CACHE));
V_DrawSmallScaledPatch(150, 44, 0, W_CachePatchName("NPRUC0",PU_SPRITE));
V_DrawThinString(146, 52, V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr)));
}
if (stplyr->powers[pw_nights_linkfreeze])
{
pwr = stplyr->powers[pw_nights_linkfreeze];
V_DrawSmallScaledPatch(190, 44, 0, W_CachePatchName("NPRUE0",PU_CACHE));
V_DrawSmallScaledPatch(190, 44, 0, W_CachePatchName("NPRUE0",PU_SPRITE));
V_DrawThinString(186, 52, V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr)));
}
}
......
......@@ -2044,18 +2044,13 @@ void Y_EndIntermission(void)
usebuffer = false;
}
#define UNLOAD(x) if (x) {Z_ChangeTag(x, PU_CACHE);} x = NULL;
#define UNLOAD(x) if (x) {Patch_Free(x);} x = NULL;
//
// Y_UnloadData
//
static void Y_UnloadData(void)
{
// In hardware mode, don't Z_ChangeTag a pointer returned by W_CachePatchName().
// It doesn't work and is unnecessary.
if (rendermode != render_soft)
return;
// unload the background patches
UNLOAD(bgpatch);
UNLOAD(bgtile);
......
......@@ -496,6 +496,33 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag)
}
}
/** Iterates through all memory for a given set of tags.
*
* \param lowtag The lowest tag to consider.
* \param hightag The highest tag to consider.
* \param iterfunc The iterator function.
*/
void Z_IterateTags(INT32 lowtag, INT32 hightag, boolean (*iterfunc)(void *))
{
memblock_t *block, *next;
if (!iterfunc)
I_Error("Z_IterateTags: no iterator function was given");
for (block = head.next; block != &head; block = next)
{
next = block->next; // get link before possibly freeing
if (block->tag >= lowtag && block->tag <= hightag)
{
void *mem = (UINT8 *)block->hdr + sizeof *block->hdr;
boolean free = iterfunc(mem);
if (free)
Z_Free(mem);
}
}
}
// -----------------
// Utility functions
// -----------------
......@@ -772,6 +799,11 @@ static void Command_Memfree_f(void)
CONS_Printf(M_GetText("Static : %7s KB\n"), sizeu1(Z_TagUsage(PU_STATIC)>>10));
CONS_Printf(M_GetText("Static (sound) : %7s KB\n"), sizeu1(Z_TagUsage(PU_SOUND)>>10));
CONS_Printf(M_GetText("Static (music) : %7s KB\n"), sizeu1(Z_TagUsage(PU_MUSIC)>>10));
CONS_Printf(M_GetText("Patches : %7s KB\n"), sizeu1(Z_TagUsage(PU_PATCH)>>10));
CONS_Printf(M_GetText("Patches (low) : %7s KB\n"), sizeu1(Z_TagUsage(PU_PATCH_LOWPRIORITY)>>10));
CONS_Printf(M_GetText("Sprites : %7s KB\n"), sizeu1(Z_TagUsage(PU_SPRITE)>>10));
CONS_Printf(M_GetText("Sprites (rotated) : %7s KB\n"), sizeu1(Z_TagUsage(PU_SPRITE_ROTATED)>>10));
CONS_Printf(M_GetText("HUD graphics : %7s KB\n"), sizeu1(Z_TagUsage(PU_HUDGFX)>>10));
CONS_Printf(M_GetText("Locked cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_CACHE)>>10));
CONS_Printf(M_GetText("Level : %7s KB\n"), sizeu1(Z_TagUsage(PU_LEVEL)>>10));
CONS_Printf(M_GetText("Special thinker : %7s KB\n"), sizeu1(Z_TagUsage(PU_LEVSPEC)>>10));
......
......@@ -42,8 +42,12 @@ enum
PU_SOUND = 11, // static while playing
PU_MUSIC = 12, // static while playing
PU_HUDGFX = 13, // static until WAD added
PU_PATCH = 14, // static until renderer change
PU_PATCH = 14, // static entire execution time
PU_PATCH_LOWPRIORITY = 15, // lower priority patch, static until level exited
PU_SPRITE = 16, // sprite patch, static until WAD added
PU_SPRITE_ROTATED = 17, // sprite patch, static until level exited or WAD added
PU_HUDGFX = 18, // HUD patch, static until WAD added
PU_HWRPATCHINFO = 21, // Hardware GLPatch_t struct for OpenGL texture cache
PU_HWRPATCHCOLMIPMAP = 22, // Hardware GLMipmap_t struct colormap variation of patch
......@@ -63,7 +67,7 @@ enum
PU_HWRCACHE_UNLOCKED = 102, // 'unlocked' PU_HWRCACHE memory:
// 'second-level' cache for graphics
// stored in hardware format and downloaded as needed
PU_HWRPATCHINFO_UNLOCKED = 103, // 'unlocked' PU_HWRPATCHINFO memory
PU_HWRPATCHINFO_UNLOCKED = 103, // 'unlocked' PU_HWRPATCHINFO memory
PU_HWRMODELTEXTURE_UNLOCKED = 104, // 'unlocked' PU_HWRMODELTEXTURE memory
};
......@@ -107,6 +111,10 @@ void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignb
#define Z_FreeTag(tagnum) Z_FreeTags(tagnum, tagnum)
void Z_FreeTags(INT32 lowtag, INT32 hightag);
// Iterate memory by tag
#define Z_IterateTag(tagnum, func) Z_IterateTags(tagnum, tagnum, func)
void Z_IterateTags(INT32 lowtag, INT32 hightag, boolean (*iterfunc)(void *));
//
// Utility functions
//
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment