Skip to content

Commit

Permalink
Began refactoring the management of abstract fonts and their namespac…
Browse files Browse the repository at this point in the history
…es to

allow partially clearing the font database.

Fixed: After a GL_TotalReset we need to choose system fonts again and then
resize the console history buffer to suit.
  • Loading branch information
danij-deng committed Jul 16, 2011
1 parent 8b2d1f8 commit 3566be5
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 30 deletions.
34 changes: 32 additions & 2 deletions doomsday/engine/portable/include/fonts.h
Expand Up @@ -22,6 +22,14 @@
* Boston, MA 02110-1301 USA
*/

/**
* Runtime fonts are not loaded until precached or actually needed.
* They may be cleared, in which case they will be reloaded when needed.
*
* System fonts are loaded at startup and remain in memory all the time.
* After clearing they must be manually reloaded.
*/

#ifndef LIBDENG_FONTS_H
#define LIBDENG_FONTS_H

Expand All @@ -38,8 +46,30 @@ void Fonts_Init(void);
/// Shutdown this module.
void Fonts_Shutdown(void);

/// Mark all fonts as requiring a full update. Called during engine/renderer reset.
void Fonts_Update(void);
void Fonts_Clear(void);

void Fonts_ClearRuntimeFonts(void);

void Fonts_ClearSystemFonts(void);

/**
* To be called during engine/gl-subsystem reset to release all resources
* acquired from the GL subsystem (v-buffers, d-lists, textures, etc...)
* for fonts.
* \note Called automatically by this subsystem prior to module shutdown.
*/
void Fonts_ReleaseRuntimeGLResources(void);
void Fonts_ReleaseSystemGLResources(void);
void Fonts_ReleaseGLResourcesByNamespace(fontnamespaceid_t namespaceId);

/**
* To be called during a texture/font-renderer reset to release all texture
* memory acquired from the GL subsystem for fonts.
* \note Called automatically by this subsystem prior to module shutdown.
*/
void Fonts_ReleaseRuntimeGLTextures(void);
void Fonts_ReleaseSystemGLTextures(void);
void Fonts_ReleaseGLTexturesByNamespace(fontnamespaceid_t namespaceId);

/// @return Number of known font bindings in all namespaces.
uint Fonts_Count(void);
Expand Down
10 changes: 4 additions & 6 deletions doomsday/engine/portable/src/dd_main.c
Expand Up @@ -1050,7 +1050,6 @@ boolean DD_ChangeGame2(gameinfo_t* info, boolean allowReload)

GL_PurgeDeferredTasks();
GL_ClearTextureMemory();
UI_ReleaseTextures();
GL_SetFilter(false);

// If a game is presently loaded; unload it.
Expand Down Expand Up @@ -1096,6 +1095,7 @@ boolean DD_ChangeGame2(gameinfo_t* info, boolean allowReload)
R_DestroyColorPalettes();

GL_DestroyRuntimeTextures();
Fonts_ClearRuntimeFonts();

Sfx_InitLogical();
P_InitThinkerLists(0x1|0x2);
Expand Down Expand Up @@ -1123,7 +1123,8 @@ boolean DD_ChangeGame2(gameinfo_t* info, boolean allowReload)

FI_Shutdown();
titleFinale = 0; // If the title finale was in progress it isn't now.
Fonts_Shutdown();

/// \fixme Materials database should not be shutdown during a reload.
Materials_Shutdown();

VERBOSE(
Expand All @@ -1139,7 +1140,6 @@ boolean DD_ChangeGame2(gameinfo_t* info, boolean allowReload)

if(!exchangeEntryPoints(GameInfo_PluginId(info)))
{
Fonts_Init();
Materials_Initialize();
FI_Init();
P_PtcInit();
Expand All @@ -1151,7 +1151,6 @@ boolean DD_ChangeGame2(gameinfo_t* info, boolean allowReload)
// This is now the current game.
currentGameInfoIndex = gameInfoIndex(info);

Fonts_Init();
Materials_Initialize();
FI_Init();
P_PtcInit();
Expand Down Expand Up @@ -1408,7 +1407,7 @@ int DD_Main(void)

Sys_Init();

// Initialize the subsystems and load resources needed for busy mode.
// Initialize the subsystems needed prior to entering busy mode.
Fonts_Init();
if(!isDedicated)
{
Expand Down Expand Up @@ -1688,7 +1687,6 @@ static int DD_StartupWorker(void* parm)
// Get the material manager up and running.
Con_SetProgress(90);
GL_EarlyInitTextureManager();
Fonts_Init();
Materials_Initialize();

Con_SetProgress(140);
Expand Down
137 changes: 121 additions & 16 deletions doomsday/engine/portable/src/fonts.c
Expand Up @@ -337,6 +337,8 @@ void Fonts_Init(void)
if(inited)
return; // Already been here.

VERBOSE( Con_Message("Initializing Fonts collection...\n") )

fonts = NULL;
bindings = NULL;
bindingsCount = 0;
Expand All @@ -357,11 +359,35 @@ void Fonts_Shutdown(void)
if(!inited)
return;

Fonts_ReleaseRuntimeGLResources();
Fonts_ReleaseSystemGLResources();

destroyBindings();
destroyFonts();
inited = false;
}

void Fonts_ClearRuntimeFonts(void)
{
errorIfNotInited("Fonts::ClearRuntimeFonts");
Fonts_ReleaseRuntimeGLResources();
//destroyFonts(FN_GAME);
#pragma message("!!!Fonts::ClearRuntimeFonts not yet implemented!!!")
}

void Fonts_ClearSystemFonts(void)
{
errorIfNotInited("Fonts::ClearSystemFonts");
Fonts_ReleaseSystemGLResources();
#pragma message("!!!Fonts::ClearSystemFonts not yet implemented!!!")
}

void Fonts_Clear(void)
{
Fonts_ClearRuntimeFonts();
Fonts_ClearSystemFonts();
}

uint Fonts_Count(void)
{
if(inited)
Expand Down Expand Up @@ -720,15 +746,77 @@ dduri_t* Fonts_GetUri(font_t* font)
return uri;
}

void Fonts_Update(void)
void Fonts_ReleaseGLTexturesByNamespace(fontnamespaceid_t namespaceId)
{
errorIfNotInited("Fonts::ReleaseGLTexturesByNamespace");

if(namespaceId != FN_ANY && !VALID_FONTNAMESPACEID(namespaceId))
Con_Error("Fonts::ReleaseGLTexturesByNamespace: Invalid namespace %i.", (int) namespaceId);

if(novideo || isDedicated)
return;

{ fontlist_node_t* node;
for(node = fonts; node; node = node->next)
{
font_t* font = node->font;

if(!(namespaceId == FN_ANY || !Font_BindId(font)))
{
fontbind_t* fb = bindByIndex(Font_BindId(font));
if(fb && FontBind_Namespace(fb) != namespaceId)
continue;
}

switch(Font_Type(font))
{
case FT_BITMAP:
BitmapFont_DeleteGLTexture(node->font);
break;
case FT_BITMAPCOMPOSITE:
BitmapCompositeFont_DeleteGLTextures(node->font);
break;
default:
Con_Error("Fonts::ReleaseGLTexturesByNamespace: Invalid font type %i.", (int) Font_Type(font));
exit(1); // Unreachable.
}
}}
}

void Fonts_ReleaseRuntimeGLTextures(void)
{
errorIfNotInited("Fonts::ReleaseRuntimeGLTextures");
Fonts_ReleaseGLTexturesByNamespace(FN_GAME);
}

void Fonts_ReleaseSystemGLTextures(void)
{
if(!inited || novideo || isDedicated)
errorIfNotInited("Fonts::ReleaseSystemGLTextures");
Fonts_ReleaseGLTexturesByNamespace(FN_SYSTEM);
}

void Fonts_ReleaseGLResourcesByNamespace(fontnamespaceid_t namespaceId)
{
errorIfNotInited("Fonts::ReleaseGLResourcesByNamespace");

if(namespaceId != FN_ANY && !VALID_FONTNAMESPACEID(namespaceId))
Con_Error("Fonts::ReleaseGLResourcesByNamespace: Invalid namespace %i.", (int) namespaceId);

if(novideo || isDedicated)
return;

{ fontlist_node_t* node;
for(node = fonts; node; node = node->next)
{
font_t* font = node->font;

if(!(namespaceId == FN_ANY || !Font_BindId(font)))
{
fontbind_t* fb = bindByIndex(Font_BindId(font));
if(fb && FontBind_Namespace(fb) != namespaceId)
continue;
}

switch(Font_Type(font))
{
case FT_BITMAP:
Expand All @@ -740,12 +828,24 @@ void Fonts_Update(void)
BitmapCompositeFont_DeleteGLDisplayLists(node->font);
break;
default:
Con_Error("Fonts::Update: Invalid font type %i.", (int) Font_Type(font));
Con_Error("Fonts::ReleaseGLResourcesByNamespace: Invalid font type %i.", (int) Font_Type(font));
exit(1); // Unreachable.
}
}}
}

void Fonts_ReleaseRuntimeGLResources(void)
{
errorIfNotInited("Fonts::ReleaseRuntimeTextures");
Fonts_ReleaseGLTexturesByNamespace(FN_GAME);
}

void Fonts_ReleaseSystemGLResources(void)
{
errorIfNotInited("Fonts::ReleaseSystemTextures");
Fonts_ReleaseGLTexturesByNamespace(FN_SYSTEM);
}

int Fonts_Ascent(font_t* font)
{
Fonts_Prepare(font);
Expand Down Expand Up @@ -833,12 +933,19 @@ static void printFontInfo(const fontbind_t* fb, boolean printNamespace)
if(printNamespace)
Con_Printf("%s:", Str_Text(nameForFontNamespaceId(FontBind_Namespace(fb))));
Con_Printf("%s\" %s ", Str_Text(FontBind_Name(fb)), Font_Type(font) == FT_BITMAP? "bitmap" : "bitmap_composite");
Con_Printf("(ascent:%i, descent:%i, leading:%i", Fonts_Ascent(font), Fonts_Descent(font), Fonts_Leading(font));
if(Font_Type(font) == FT_BITMAP && BitmapFont_GLTextureName(font))
if(Font_IsPrepared(font))
{
Con_Printf(", texWidth:%i, texHeight:%i", BitmapFont_TextureWidth(font), BitmapFont_TextureHeight(font));
Con_Printf("(ascent:%i, descent:%i, leading:%i", Fonts_Ascent(font), Fonts_Descent(font), Fonts_Leading(font));
if(Font_Type(font) == FT_BITMAP && BitmapFont_GLTextureName(font))
{
Con_Printf(", texWidth:%i, texHeight:%i", BitmapFont_TextureWidth(font), BitmapFont_TextureHeight(font));
}
Con_Printf(")\n");
}
else
{
Con_Printf("\n");
}
Con_Printf(")\n");
}

static fontbind_t** collectFontBinds(fontnamespaceid_t namespaceId,
Expand Down Expand Up @@ -925,16 +1032,14 @@ static size_t printFonts2(fontnamespaceid_t namespaceId, const char* like)
}

// Print the result index key.
if(VALID_FONTNAMESPACEID(namespaceId))
Con_Printf(" uid: \"%s\" font-type", VALID_FONTNAMESPACEID(namespaceId)? "font-name" : "<namespace>:font-name");
// Fonts may be prepared only if GL is inited thus if we can't prepare, we can't list property values.
if(GL_IsInited())
{
Con_Printf(" uid: \"name\" font-type (<property-name>:<value>, ...)\n");
Con_FPrintf(CBLF_RULER, "");
}
else
{ // Any namespace.
Con_Printf(" uid: \"(namespace:)name\" font-type (<property-name>:<value>, ...)\n");
Con_FPrintf(CBLF_RULER, "");
Con_Printf(" (<property-name>:<value>, ...)");
}
Con_Printf("\n");
Con_FPrintf(CBLF_RULER, "");

// Sort and print the index.
qsort(foundFonts, count, sizeof(*foundFonts), compareFontBindByName);
Expand Down Expand Up @@ -974,6 +1079,6 @@ D_CMD(ListFonts)
Con_Printf("Unknown font namespace \"%s\".\n", argv[1]);
return false;
}
printFonts(namespaceId, (argc > 2? argv[2] : (argc > 1 && namespaceId == FN_ANY? argv[1] : NULL)));
printFonts(namespaceId, (argc > 2? argv[2] : (argc > 1 && !VALID_FONTNAMESPACEID(namespaceId)? argv[1] : NULL)));
return true;
}
13 changes: 12 additions & 1 deletion doomsday/engine/portable/src/gl_main.c
Expand Up @@ -506,7 +506,9 @@ void GL_InitRefresh(void)
{
GL_InitTextureManager();
GL_LoadSystemTextures();
GL_LoadSystemFonts();

// Register/create Texture objects for the system textures.
R_InitSystemTextures();
}

/**
Expand All @@ -521,6 +523,8 @@ void GL_ShutdownRefresh(void)
R_DestroyFlareTextures();
R_DestroyShinyTextures();
R_DestroyMaskTextures();
R_DestroySystemTextures();

R_DestroyColorPalettes();
}

Expand Down Expand Up @@ -759,6 +763,9 @@ void GL_TotalReset(void)
GL_ResetTextureManager();
GL_ReleaseReservedNames();

Fonts_ReleaseRuntimeGLResources();
Fonts_ReleaseSystemGLResources();

#if _DEBUG
Z_CheckHeap();
#endif
Expand All @@ -775,6 +782,10 @@ void GL_TotalRestore(void)
// Getting back up and running.
GL_ReserveNames();
GL_Init2DState();

// Choose fonts again.
R_LoadSystemFonts();
Con_ResizeHistoryBuffer();

{
gamemap_t* map = P_GetCurrentMap();
Expand Down
7 changes: 2 additions & 5 deletions doomsday/engine/portable/src/gl_texmanager.c
Expand Up @@ -1585,7 +1585,6 @@ void GL_LoadSystemTextures(void)
}

Rend_ParticleLoadSystemTextures();
R_InitSystemTextures();
}

void GL_ReleaseSystemTextures(void)
Expand All @@ -1607,9 +1606,8 @@ void GL_ReleaseSystemTextures(void)

Materials_ReleaseGLTextures(MN_SYSTEM_NAME);
UI_ReleaseTextures();

Rend_ParticleReleaseSystemTextures();
R_DestroySystemTextures();
Fonts_ReleaseSystemGLTextures();
}

void GL_ReleaseRuntimeTextures(void)
Expand All @@ -1636,6 +1634,7 @@ void GL_ReleaseRuntimeTextures(void)
GL_ReleaseTexturesForRawImages();

Rend_ParticleReleaseExtraTextures();
Fonts_ReleaseRuntimeGLTextures();
}

void GL_ClearTextureMemory(void)
Expand Down Expand Up @@ -3207,7 +3206,6 @@ static int doTexReset(void* parm)

/// \todo re-upload ALL textures currently in use.
GL_LoadSystemTextures();
GL_LoadSystemFonts();
Rend_ParticleLoadExtraTextures();
R_SkyUpdate();

Expand All @@ -3226,7 +3224,6 @@ void GL_TexReset(void)
boolean useBusyMode = !Con_IsBusy();

GL_ClearTextureMemory();
Fonts_Update();
Con_Printf("All DGL textures deleted.\n");

if(useBusyMode)
Expand Down

0 comments on commit 3566be5

Please sign in to comment.