- rewrote texture caching so that not the base texture but the actually used translations for sprites get precached.

This commit is contained in:
Christoph Oelckers 2016-05-03 01:00:52 +02:00
parent ec037bfd1a
commit 6f2b0a6293
7 changed files with 104 additions and 64 deletions

View file

@ -73,6 +73,7 @@
#include "gl/shaders/gl_shader.h"
#include "gl/stereo3d/gl_stereo3d.h"
#include "gl/stereo3d/scoped_view_shifter.h"
#include "gl/textures/gl_translate.h"
#include "gl/textures/gl_material.h"
#include "gl/textures/gl_skyboxtexture.h"
#include "gl/utility/gl_clock.h"
@ -979,6 +980,7 @@ struct FGLInterface : public FRenderer
{
bool UsesColormap() const;
void PrecacheTexture(FTexture *tex, int cache);
void PrecacheSprite(FTexture *tex, SpriteHits &hits);
void Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhitlist);
void RenderView(player_t *player);
void WriteSavePic (player_t *player, FILE *file, int width, int height);
@ -1021,20 +1023,54 @@ void FGLInterface::PrecacheTexture(FTexture *tex, int cache)
{
if (cache)
{
tex->PrecacheGL(cache);
if (gl_precache)
{
if (cache & (FTextureManager::HIT_Wall | FTextureManager::HIT_Flat | FTextureManager::HIT_Sky))
{
FMaterial * gltex = FMaterial::ValidateTexture(tex, false);
if (gltex) gltex->Precache();
}
}
}
else
{
tex->UncacheGL();
if (tex->gl_info.Material[0]) tex->gl_info.Material[0]->Clean(true);
}
}
}
//==========================================================================
//
// DFrameBuffer :: PrecacheSprite
//
//==========================================================================
void FGLInterface::PrecacheSprite(FTexture *tex, SpriteHits &hits)
{
if (hits.CountUsed() == 0)
{
if (tex->gl_info.Material[1]) tex->gl_info.Material[1]->Clean(true);
}
else
{
FMaterial * gltex = FMaterial::ValidateTexture(tex, true);
if (gltex) gltex->PrecacheList(hits);
}
}
//==========================================================================
//
// DFrameBuffer :: Precache
//
//==========================================================================
void FGLInterface::Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhitlist)
{
BYTE *spritelist = new BYTE[sprites.Size()];
SpriteHits *spritelist = new SpriteHits[sprites.Size()];
SpriteHits **spritehitlist = new SpriteHits*[TexMan.NumTextures()];
TMap<PClassActor*, bool>::Iterator it(actorhitlist);
TMap<PClassActor*, bool>::Pair *pair;
memset(spritehitlist, 0, sizeof(SpriteHits**) * TexMan.NumTextures());
// this isn't done by the main code so it needs to be done here first:
// check skybox textures and mark the separate faces as used
@ -1059,19 +1095,14 @@ void FGLInterface::Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhit
}
}
memset(spritelist, 0, sprites.Size());
while (it.NextPair(pair))
{
PClassActor *cls = pair->Key;
int gltrans = GLTranslationPalette::GetInternalTranslation(GetDefaultByType(cls)->Translation);
for (int i = 0; i < cls->NumOwnedStates; i++)
{
spritelist[cls->OwnedStates[i].sprite] = true;
spritelist[cls->OwnedStates[i].sprite].Insert(gltrans, true);
}
}
@ -1079,7 +1110,7 @@ void FGLInterface::Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhit
for (int i = (int)(sprites.Size() - 1); i >= 0; i--)
{
if (spritelist[i])
if (spritelist[i].CountUsed())
{
int j, k;
for (j = 0; j < sprites[i].numframes; j++)
@ -1091,21 +1122,21 @@ void FGLInterface::Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhit
FTextureID pic = frame->Texture[k];
if (pic.isValid())
{
texhitlist[pic.GetIndex()] = FTextureManager::HIT_Sprite;
spritehitlist[pic.GetIndex()] = &spritelist[i];
}
}
}
}
}
delete[] spritelist;
TexMan.precacheTime = I_FPSTime();
int cnt = TexMan.NumTextures();
for (int i = cnt - 1; i >= 0; i--)
{
PrecacheTexture(TexMan.ByIndex(i), texhitlist[i]);
if (spritehitlist[i] != nullptr) PrecacheSprite(TexMan.ByIndex(i), *spritehitlist[i]);
}
delete[] spritehitlist;
delete[] spritelist;
}

View file

@ -306,6 +306,29 @@ void FHardwareTexture::Clean(bool all)
if (glDepthID != 0) glDeleteRenderbuffers(1, &glDepthID);
}
//===========================================================================
//
// Deletes all allocated resources and considers translations
// This will only be called for sprites
//
//===========================================================================
void FHardwareTexture::CleanUnused(SpriteHits &usedtranslations)
{
if (usedtranslations.CheckKey(0) != nullptr)
{
glDefTex.Delete();
}
for (int i = glTex_Translated.Size()-1; i>= 0; i--)
{
if (usedtranslations.CheckKey(glTex_Translated[i].translation) != nullptr)
{
glTex_Translated[i].Delete();
glTex_Translated.Delete(i);
}
}
}
//===========================================================================
//
// Destroys the texture

View file

@ -13,6 +13,7 @@
class FCanvasTexture;
class AActor;
typedef TMap<int, bool> SpriteHits;
// For error catching while changing parameters.
enum EInvalid
@ -79,6 +80,7 @@ public:
unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation);
void Clean(bool all);
void CleanUnused(SpriteHits &usedtranslations);
};
#endif

View file

@ -91,6 +91,7 @@ FGLTexture::FGLTexture(FTexture * tx, bool expandpatches)
bIsTransparent = -1;
bExpandFlag = expandpatches;
lastSampler = 254;
lastTranslation = -1;
tex->gl_info.SystemTexture[expandpatches] = this;
}
@ -165,16 +166,28 @@ unsigned char *FGLTexture::LoadHiresTexture(FTexture *tex, int *width, int *heig
void FGLTexture::Clean(bool all)
{
if (mHwTexture)
if (mHwTexture != nullptr)
{
if (!all) mHwTexture->Clean(false);
else
{
delete mHwTexture;
mHwTexture = NULL;
mHwTexture = nullptr;
}
lastSampler = 253;
lastTranslation = -1;
}
}
void FGLTexture::CleanUnused(SpriteHits &usedtranslations)
{
if (mHwTexture != nullptr)
{
mHwTexture->CleanUnused(usedtranslations);
lastSampler = 253;
lastTranslation = -1;
}
}
@ -334,8 +347,9 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla
}
if (!needmipmap) clampmode = CLAMP_XY_NOMIP;
if (tex->bHasCanvas) static_cast<FCanvasTexture*>(tex)->NeedUpdate();
if (lastSampler != clampmode)
if (lastSampler != clampmode || lastTranslation != translation)
lastSampler = GLRenderer->mSamplerManager->Bind(texunit, clampmode, lastSampler);
lastTranslation = translation;
return hwtex;
}
return NULL;
@ -710,6 +724,19 @@ void FMaterial::Precache()
Bind(0, 0);
}
//===========================================================================
//
//
//
//===========================================================================
void FMaterial::PrecacheList(SpriteHits &translations)
{
if (mBaseLayer != nullptr) mBaseLayer->CleanUnused(translations);
SpriteHits::Iterator it(translations);
SpriteHits::Pair *pair;
while(it.NextPair(pair)) Bind(0, pair->Key);
}
//===========================================================================
//
// Retrieve texture coordinate info for per-wall scaling

View file

@ -66,6 +66,7 @@ private:
bool bHasColorkey; // only for hires
bool bExpandFlag;
BYTE lastSampler;
int lastTranslation;
unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height);
@ -80,6 +81,7 @@ public:
unsigned char * CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck, bool createexpanded = true, bool alphatrans = false);
void Clean(bool all);
void CleanUnused(SpriteHits &usedtranslations);
int Dump(int i);
};
@ -127,6 +129,7 @@ public:
FMaterial(FTexture *tex, bool forceexpand);
~FMaterial();
void Precache();
void PrecacheList(SpriteHits &translations);
bool isMasked() const
{
return !!mBaseLayer->tex->bMasked;

View file

@ -240,7 +240,6 @@ FTexture::MiscGLInfo::MiscGLInfo() throw()
mIsTransparent = -1;
shaderspeed = 1.f;
shaderindex = 0;
precacheTime = 0;
Material[1] = Material[0] = NULL;
SystemTexture[1] = SystemTexture[0] = NULL;
@ -310,46 +309,6 @@ void FTexture::CreateDefaultBrightmap()
}
//==========================================================================
//
// Precaches a GL texture
//
//==========================================================================
void FTexture::PrecacheGL(int cache)
{
if (gl_precache)
{
if (cache & (FTextureManager::HIT_Wall | FTextureManager::HIT_Flat | FTextureManager::HIT_Sky))
{
FMaterial * gltex = FMaterial::ValidateTexture(this, false);
if (gltex) gltex->Precache();
}
if (cache & FTextureManager::HIT_Sprite)
{
FMaterial * gltex = FMaterial::ValidateTexture(this, true);
if (gltex) gltex->Precache();
}
gl_info.precacheTime = TexMan.precacheTime;
}
}
//==========================================================================
//
// Precaches a GL texture
//
//==========================================================================
void FTexture::UncacheGL()
{
if (gl_info.precacheTime != TexMan.precacheTime)
{
if (gl_info.Material[0]) gl_info.Material[0]->Clean(true);
if (gl_info.Material[1]) gl_info.Material[1]->Clean(true);
gl_info.precacheTime = 0;
}
}
//==========================================================================
//
// Calculates glow color for a texture

View file

@ -310,7 +310,6 @@ public:
FloatRect *areas;
int areacount;
int shaderindex;
unsigned int precacheTime;
float shaderspeed;
int mIsTransparent:2;
bool bGlowing:1; // Texture glows
@ -328,8 +327,6 @@ public:
};
MiscGLInfo gl_info;
virtual void PrecacheGL(int cache);
virtual void UncacheGL();
void GetGlowColor(float *data);
PalEntry GetSkyCapColor(bool bottom);
bool isGlowing() { return gl_info.bGlowing; }
@ -458,8 +455,6 @@ public:
FSwitchDef *FindSwitch (FTextureID texture);
FDoorAnimation *FindAnimatedDoor (FTextureID picnum);
unsigned int precacheTime;
private:
// texture counting