- 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/shaders/gl_shader.h"
#include "gl/stereo3d/gl_stereo3d.h" #include "gl/stereo3d/gl_stereo3d.h"
#include "gl/stereo3d/scoped_view_shifter.h" #include "gl/stereo3d/scoped_view_shifter.h"
#include "gl/textures/gl_translate.h"
#include "gl/textures/gl_material.h" #include "gl/textures/gl_material.h"
#include "gl/textures/gl_skyboxtexture.h" #include "gl/textures/gl_skyboxtexture.h"
#include "gl/utility/gl_clock.h" #include "gl/utility/gl_clock.h"
@ -979,6 +980,7 @@ struct FGLInterface : public FRenderer
{ {
bool UsesColormap() const; bool UsesColormap() const;
void PrecacheTexture(FTexture *tex, int cache); void PrecacheTexture(FTexture *tex, int cache);
void PrecacheSprite(FTexture *tex, SpriteHits &hits);
void Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhitlist); void Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhitlist);
void RenderView(player_t *player); void RenderView(player_t *player);
void WriteSavePic (player_t *player, FILE *file, int width, int height); void WriteSavePic (player_t *player, FILE *file, int width, int height);
@ -1021,20 +1023,54 @@ void FGLInterface::PrecacheTexture(FTexture *tex, int cache)
{ {
if (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 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) 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>::Iterator it(actorhitlist);
TMap<PClassActor*, bool>::Pair *pair; 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: // 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 // 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)) while (it.NextPair(pair))
{ {
PClassActor *cls = pair->Key; PClassActor *cls = pair->Key;
int gltrans = GLTranslationPalette::GetInternalTranslation(GetDefaultByType(cls)->Translation);
for (int i = 0; i < cls->NumOwnedStates; i++) 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--) for (int i = (int)(sprites.Size() - 1); i >= 0; i--)
{ {
if (spritelist[i]) if (spritelist[i].CountUsed())
{ {
int j, k; int j, k;
for (j = 0; j < sprites[i].numframes; j++) 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]; FTextureID pic = frame->Texture[k];
if (pic.isValid()) if (pic.isValid())
{ {
texhitlist[pic.GetIndex()] = FTextureManager::HIT_Sprite; spritehitlist[pic.GetIndex()] = &spritelist[i];
} }
} }
} }
} }
} }
delete[] spritelist;
TexMan.precacheTime = I_FPSTime();
int cnt = TexMan.NumTextures(); int cnt = TexMan.NumTextures();
for (int i = cnt - 1; i >= 0; i--) for (int i = cnt - 1; i >= 0; i--)
{ {
PrecacheTexture(TexMan.ByIndex(i), texhitlist[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); 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 // Destroys the texture

View file

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

View file

@ -91,6 +91,7 @@ FGLTexture::FGLTexture(FTexture * tx, bool expandpatches)
bIsTransparent = -1; bIsTransparent = -1;
bExpandFlag = expandpatches; bExpandFlag = expandpatches;
lastSampler = 254; lastSampler = 254;
lastTranslation = -1;
tex->gl_info.SystemTexture[expandpatches] = this; 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) void FGLTexture::Clean(bool all)
{ {
if (mHwTexture) if (mHwTexture != nullptr)
{ {
if (!all) mHwTexture->Clean(false); if (!all) mHwTexture->Clean(false);
else else
{ {
delete mHwTexture; delete mHwTexture;
mHwTexture = NULL; mHwTexture = nullptr;
} }
lastSampler = 253; 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 (!needmipmap) clampmode = CLAMP_XY_NOMIP;
if (tex->bHasCanvas) static_cast<FCanvasTexture*>(tex)->NeedUpdate(); if (tex->bHasCanvas) static_cast<FCanvasTexture*>(tex)->NeedUpdate();
if (lastSampler != clampmode) if (lastSampler != clampmode || lastTranslation != translation)
lastSampler = GLRenderer->mSamplerManager->Bind(texunit, clampmode, lastSampler); lastSampler = GLRenderer->mSamplerManager->Bind(texunit, clampmode, lastSampler);
lastTranslation = translation;
return hwtex; return hwtex;
} }
return NULL; return NULL;
@ -710,6 +724,19 @@ void FMaterial::Precache()
Bind(0, 0); 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 // Retrieve texture coordinate info for per-wall scaling

View file

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

View file

@ -240,7 +240,6 @@ FTexture::MiscGLInfo::MiscGLInfo() throw()
mIsTransparent = -1; mIsTransparent = -1;
shaderspeed = 1.f; shaderspeed = 1.f;
shaderindex = 0; shaderindex = 0;
precacheTime = 0;
Material[1] = Material[0] = NULL; Material[1] = Material[0] = NULL;
SystemTexture[1] = SystemTexture[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 // Calculates glow color for a texture

View file

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