From: Guus Sliepen Date: Wed, 7 Jul 2010 17:08:12 +0000 (+0200) Subject: Cache text surfaces. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=877c46f3f824fabf9f9b28988f0cbb36de4b193d;p=quix0rs-blobwars.git Cache text surfaces. According to callgrind, a lot of time was spent drawing the same text over and over to a surface. A caching version of Graphics::drawString has been added, that keeps the surface around when the text hasn't changed. --- diff --git a/src/CGraphics.cpp b/src/CGraphics.cpp index 5c3071e..353a837 100644 --- a/src/CGraphics.cpp +++ b/src/CGraphics.cpp @@ -895,18 +895,50 @@ void Graphics::drawString(const char *in, int x, int y, int alignment, SDL_Surfa SDL_Surface *text = TTF_RenderUTF8_Shaded(font[fontSize], in, fontForeground, fontBackground); if (!text) - { text = TTF_RenderUTF8_Shaded(font[fontSize], "FONT_ERROR", fontForeground, fontBackground); - } + + if (!text) + return; + + setTransparent(text); if (alignment == TXT_RIGHT) x -= text->w; if (alignment == TXT_CENTERED) center = true; - setTransparent(text); blit(text, x, y, dest, center); SDL_FreeSurface(text); } +void Graphics::drawString(const char *in, int x, int y, int alignment, SDL_Surface *dest, SurfaceCache &cache) +{ + bool center = false; + + if(!cache.text || strcmp(in, cache.text)) { + if(cache.surface) + SDL_FreeSurface(cache.surface); + + if(cache.text) + ::free(cache.text); + + cache.text = strdup(in); + + cache.surface = TTF_RenderUTF8_Shaded(font[fontSize], in, fontForeground, fontBackground); + + if (!cache.surface) + cache.surface = TTF_RenderUTF8_Shaded(font[fontSize], "FONT_ERROR", fontForeground, fontBackground); + + if(!cache.surface) + return; + + setTransparent(cache.surface); + } + + if (alignment == TXT_RIGHT) x -= cache.surface->w; + if (alignment == TXT_CENTERED) center = true; + + blit(cache.surface, x, y, dest, center); +} + void Graphics::clearChatString() { chatString[0] = 0; diff --git a/src/CGraphics.h b/src/CGraphics.h index be8a21a..3ad2c52 100755 --- a/src/CGraphics.h +++ b/src/CGraphics.h @@ -49,6 +49,11 @@ class Graphics { SDL_Surface *infoMessage; public: + struct SurfaceCache { + char *text; + SDL_Surface *surface; + SurfaceCache(): text(NULL), surface(NULL) {} + }; bool takeRandomScreenShots; @@ -101,6 +106,7 @@ class Graphics { void setFontSize(int size); SDL_Surface *getString(const char *in, bool transparent); void drawString(const char *in, int x, int y, int alignment, SDL_Surface *dest); + void drawString(const char *in, int x, int y, int alignment, SDL_Surface *dest, SurfaceCache &cache); void clearChatString(); void createChatString(const char *in); void showMedalMessage(int type, const char *in); diff --git a/src/game.cpp b/src/game.cpp index c6e4e43..1e04687 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -843,7 +843,8 @@ int doGame() frameLimit = SDL_GetTicks() + 64; #if DEBUG - graphics.drawString(fps, 600, 30, true, graphics.screen); + static Graphics::SurfaceCache fpsCache; + graphics.drawString(fps, 600, 30, true, graphics.screen, fpsCache); if (SDL_GetTicks() > frameCounter + 500) { diff --git a/src/hub.cpp b/src/hub.cpp index 4a11741..bcfe2e1 100644 --- a/src/hub.cpp +++ b/src/hub.cpp @@ -609,16 +609,18 @@ int doHub() if (validStage) { + static Graphics::SurfaceCache cache; graphics.drawRect(10, 400, 620, 20, graphics.black, graphics.white, graphics.screen); snprintf(string, sizeof string, "%s : %s", _("Selected Destination"), _(game.stageName)); - graphics.drawString(string, 320, 409, true, graphics.screen); + graphics.drawString(string, 320, 409, true, graphics.screen, cache); } graphics.drawRect(10, 430, 620, 40, graphics.black, graphics.white, graphics.screen); #if DEBUG + static Graphics::SurfaceCache posCache; snprintf(pos, sizeof pos, "%.3d:%.3d", engine.getMouseX(), engine.getMouseY()); - graphics.drawString(pos, 320, 15, true, graphics.screen); + graphics.drawString(pos, 320, 15, true, graphics.screen, posCache); #endif engine.getInput(); diff --git a/src/info.cpp b/src/info.cpp index 7225629..6174266 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -51,6 +51,10 @@ void doTimeRemaining() void doStatusBar() { + static Graphics::SurfaceCache healthCache; + static Graphics::SurfaceCache oxygenCache; + static Graphics::SurfaceCache jetpackCache; + graphics.setFontSize(0); graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00); @@ -58,7 +62,7 @@ void doStatusBar() graphics.blit(graphics.infoBar, 0, 0, graphics.screen, false); - graphics.drawString(_("Health"), 50, 5, TXT_RIGHT, graphics.screen); + graphics.drawString(_("Health"), 50, 5, TXT_RIGHT, graphics.screen, healthCache); for (int i = 0 ; i < MAX_HEALTH ; i++) { @@ -75,7 +79,7 @@ void doStatusBar() if ((!game.hasAquaLung) && (!engine.cheatExtras)) { - graphics.drawString(_("Oxygen"), 305, 5, TXT_RIGHT, graphics.screen); + graphics.drawString(_("Oxygen"), 305, 5, TXT_RIGHT, graphics.screen, oxygenCache); for (int i = 0 ; i < 7 ; i++) { @@ -92,7 +96,7 @@ void doStatusBar() } else if ((game.hasJetPack) || (engine.cheatExtras)) { - graphics.drawString(_("Jetpack"), 305, 5, TXT_RIGHT, graphics.screen); + graphics.drawString(_("Jetpack"), 305, 5, TXT_RIGHT, graphics.screen, jetpackCache); for (int i = 0 ; i < 7 ; i++) { @@ -131,8 +135,9 @@ void doStatusBar() break; } + static Graphics::SurfaceCache cache; graphics.blit(graphics.infoBar, 0, 455, graphics.screen, false); - graphics.drawString(_(engine.message), 320, 466, true, graphics.screen); + graphics.drawString(_(engine.message), 320, 466, true, graphics.screen, cache); engine.messageTime--; if (engine.messageTime == -1) @@ -150,7 +155,8 @@ void doStatusBar() { graphics.blit(graphics.infoBar, 0, 455, graphics.screen, false); - graphics.drawString(_(map.mainBossPart->name), 255, 460, TXT_RIGHT, graphics.screen); + static Graphics::SurfaceCache cache; + graphics.drawString(_(map.mainBossPart->name), 255, 460, TXT_RIGHT, graphics.screen, cache); graphics.drawRect(265 - 1, 463 - 1, 200 + 2, 10 + 2, graphics.white, graphics.screen); graphics.drawRect(265, 463, 200, 10, graphics.black, graphics.screen); @@ -161,8 +167,9 @@ void doStatusBar() } } + static Graphics::SurfaceCache weaponCache; snprintf(string, sizeof string, "%s %s", _("Weapon:"), _(player.currentWeapon->name)); - graphics.drawString(string, 630, 5, TXT_RIGHT, graphics.screen); + graphics.drawString(string, 630, 5, TXT_RIGHT, graphics.screen, weaponCache); if (game.skill == 3) { @@ -185,13 +192,15 @@ void doStatusBar() } } } - graphics.drawString(string, 320, 35, TXT_CENTERED, graphics.screen); + static Graphics::SurfaceCache cache; + graphics.drawString(string, 320, 35, TXT_CENTERED, graphics.screen, cache); } else { + static Graphics::SurfaceCache cache; graphics.setFontColor(0xff, 0x00, 0x00, 0x00, 0x00, 0x00); graphics.setFontSize(3); - graphics.drawString(_("Mission Failed! Time Up!"), 320, 220, TXT_CENTERED, graphics.screen); + graphics.drawString(_("Mission Failed! Time Up!"), 320, 220, TXT_CENTERED, graphics.screen, cache); graphics.setFontSize(0); game.canContinue = 0; } diff --git a/src/mias.cpp b/src/mias.cpp index e8df50d..2415a3c 100644 --- a/src/mias.cpp +++ b/src/mias.cpp @@ -99,8 +99,9 @@ void doMIAs() if ((mia->value != 100) && (!(mia->flags & ENT_DYING))) { + static Graphics::SurfaceCache cache; graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00); - graphics.drawString(_((char*)mia_scared[mia->value]), x + 10, y - 10, true, graphics.screen); + graphics.drawString(_((char*)mia_scared[mia->value]), x + 10, y - 10, true, graphics.screen, cache); } graphics.blit(mia->getFaceImage(), x, y, graphics.screen, false); diff --git a/src/mission.cpp b/src/mission.cpp index d562df8..7fca190 100644 --- a/src/mission.cpp +++ b/src/mission.cpp @@ -365,8 +365,9 @@ void showMissionClear() } } + static Graphics::SurfaceCache cache; snprintf(message, sizeof message, "%s - %.2d:%.2d:%.2d", _("Mission Time"), game.currentMissionHours, game.currentMissionMinutes, game.currentMissionSeconds); - graphics.drawString(message, 320, 420, true, graphics.screen); + graphics.drawString(message, 320, 420, true, graphics.screen, cache); engine.delay(frameLimit); frameLimit = SDL_GetTicks() + 16;