Skip to content

Commit

Permalink
Prune unused texture variant specifications when:
Browse files Browse the repository at this point in the history
* Reseting the texture manager.
* After destroying runtime and/or system textures.
* After a texreset.
  • Loading branch information
danij-deng committed Jul 16, 2011
1 parent 8f1d7bd commit 8b2d1f8
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
2 changes: 2 additions & 0 deletions doomsday/engine/portable/include/gl_texmanager.h
Expand Up @@ -84,6 +84,8 @@ void GL_LoadSystemTextures(void);

void GL_ClearTextureMemory(void);

void GL_PruneTextureVariantSpecifications(void);

/**
* Runtime textures are not loaded until precached or actually needed.
* They may be cleared, in which case they will be reloaded when needed.
Expand Down
69 changes: 69 additions & 0 deletions doomsday/engine/portable/src/gl_texmanager.c
Expand Up @@ -532,6 +532,61 @@ static void emptyVariantSpecificationList(variantspecificationlist_t* list)
}
}

static int compareTextureVariantWithVariantSpecification(texturevariant_t* tex, void* paramaters)
{
assert(NULL != tex);
{
texturevariantspecification_t* spec = (texturevariantspecification_t*)paramaters;
if(TextureVariant_Spec(tex) == spec)
return 1;
return 0;
}
}

static int pruneUnusedVariantSpecificationsInList(variantspecificationlist_t* list)
{
texturevariantspecificationlist_node_t* node = list;
int numPruned = 0;
while(node)
{
texturevariantspecificationlist_node_t* next = node->next;
int i, result = 0;
for(i = 0; i < texturesCount; ++i)
{
texture_t* tex = textures[i];
if(0 != (result = Texture_IterateVariants(tex, compareTextureVariantWithVariantSpecification, (void*)node->spec)))
break;
}
if(result == 0)
{
destroyVariantSpecification(node->spec);
++numPruned;
}
node = next;
}
return numPruned;
}

static int pruneUnusedVariantSpecifications(texturevariantspecificationtype_t specType)
{
assert(texInited);
switch(specType)
{
case TST_GENERAL: return pruneUnusedVariantSpecificationsInList(variantSpecs);
case TST_DETAIL: {
int i, numPruned = 0;
for(i = 0; i < DETAILVARIANT_CONTRAST_HASHSIZE; ++i)
{
numPruned += pruneUnusedVariantSpecificationsInList(detailVariantSpecs[i]);
}
return numPruned;
}
default:
Con_Error("Textures::pruneUnusedVariantSpecifications: Invalid variant spec type %i.", (int) specType);
exit(1); // Unreachable.
}
}

static void destroyVariantSpecifications(void)
{
assert(texInited);
Expand Down Expand Up @@ -1332,6 +1387,7 @@ void GL_ResetTextureManager(void)
if(!texInited)
return;
GL_ClearTextureMemory();
GL_PruneTextureVariantSpecifications();
}

int GL_CompareTextureVariantSpecifications(const texturevariantspecification_t* a,
Expand Down Expand Up @@ -1473,13 +1529,15 @@ void GL_DestroyRuntimeTextures(void)
destroyTextures(TN_MODELREFLECTIONSKINS);
destroyTextures(TN_LIGHTMAPS);
destroyTextures(TN_FLAREMAPS);
GL_PruneTextureVariantSpecifications();
}

void GL_DestroySystemTextures(void)
{
if(!texInited)
Con_Error("GL_DestroySystemTextures: Textures collection not yet initialized.");
destroyTextures(TN_SYSTEM);
GL_PruneTextureVariantSpecifications();
}

void GL_DestroyTextures(void)
Expand Down Expand Up @@ -1587,6 +1645,15 @@ void GL_ClearTextureMemory(void)
GL_ReleaseRuntimeTextures();
}

void GL_PruneTextureVariantSpecifications(void)
{
int numPruned = pruneUnusedVariantSpecifications(TST_GENERAL) +
pruneUnusedVariantSpecifications(TST_DETAIL);
#if _DEBUG
Con_Message("Pruned %i unused texture variant %s.", numPruned, numPruned == 1? "specification" : "specifications");
#endif
}

void GL_InitImage(image_t* img)
{
assert(img);
Expand Down Expand Up @@ -3144,6 +3211,8 @@ static int doTexReset(void* parm)
Rend_ParticleLoadExtraTextures();
R_SkyUpdate();

GL_PruneTextureVariantSpecifications();

if(usingBusyMode)
{
Con_SetProgress(200);
Expand Down

0 comments on commit 8b2d1f8

Please sign in to comment.