1
0
Fork 0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-12-22 17:49:43 +01:00

Fix analogue filter allocating/freeing surfaces every frame

This removes memory churn caused by using analogue mode.

The surfaces are only allocated if analogue mode is turned on, and kept
after they are initialized. Otherwise, if analogue mode is never turned
on (which will be the case for the vast majority of the time the game is
played), then no extra memory is used.
This commit is contained in:
Misa 2023-03-04 14:02:47 -08:00
parent 5eecc2a21d
commit 58d21e956b
3 changed files with 17 additions and 23 deletions

View file

@ -171,6 +171,9 @@ void Graphics::destroy(void)
#undef CLEAR_ARRAY #undef CLEAR_ARRAY
} }
static SDL_Surface* tempFilterSrc = NULL;
static SDL_Surface* tempFilterDest = NULL;
void Graphics::create_buffers(void) void Graphics::create_buffers(void)
{ {
#define CREATE_TEXTURE_WITH_DIMENSIONS(w, h) \ #define CREATE_TEXTURE_WITH_DIMENSIONS(w, h) \
@ -212,6 +215,8 @@ void Graphics::destroy_buffers(void)
VVV_freefunc(SDL_DestroyTexture, tempScrollingTexture); VVV_freefunc(SDL_DestroyTexture, tempScrollingTexture);
VVV_freefunc(SDL_DestroyTexture, towerbg.texture); VVV_freefunc(SDL_DestroyTexture, towerbg.texture);
VVV_freefunc(SDL_DestroyTexture, titlebg.texture); VVV_freefunc(SDL_DestroyTexture, titlebg.texture);
VVV_freefunc(SDL_FreeSurface, tempFilterSrc);
VVV_freefunc(SDL_FreeSurface, tempFilterDest);
} }
void Graphics::drawspritesetcol(int x, int y, int t, int c) void Graphics::drawspritesetcol(int x, int y, int t, int c)
@ -3153,7 +3158,7 @@ void Graphics::screenshake(void)
{ {
if (gameScreen.badSignalEffect) if (gameScreen.badSignalEffect)
{ {
ApplyFilter(); ApplyFilter(tempFilterSrc, tempFilterDest);
} }
set_render_target(menuoffTexture); set_render_target(menuoffTexture);
@ -3191,7 +3196,7 @@ void Graphics::render(void)
{ {
if (gameScreen.badSignalEffect) if (gameScreen.badSignalEffect)
{ {
ApplyFilter(); ApplyFilter(tempFilterSrc, tempFilterDest);
} }
set_render_target(NULL); set_render_target(NULL);

View file

@ -144,11 +144,17 @@ void UpdateFilter(void)
} }
} }
void ApplyFilter(void) void ApplyFilter(SDL_Surface* src, SDL_Surface* dest)
{ {
// Copy the screen to a temporary surface
SDL_Surface* src = SDL_CreateRGBSurface(0, SCREEN_WIDTH_PIXELS, SCREEN_HEIGHT_PIXELS, 32, 0, 0, 0, 0);
if (src == NULL) if (src == NULL)
{
src = SDL_CreateRGBSurface(0, SCREEN_WIDTH_PIXELS, SCREEN_HEIGHT_PIXELS, 32, 0, 0, 0, 0);
}
if (dest == NULL)
{
dest = SDL_CreateRGBSurface(0, SCREEN_WIDTH_PIXELS, SCREEN_HEIGHT_PIXELS, 32, 0, 0, 0, 0);
}
if (src == NULL || dest == NULL)
{ {
return; return;
} }
@ -161,18 +167,6 @@ void ApplyFilter(void)
return; return;
} }
Uint32 rawFormat;
if (graphics.query_texture(graphics.gameTexture, &rawFormat, NULL, NULL, NULL) != 0)
{
return;
}
SDL_PixelFormat* format = SDL_AllocFormat(rawFormat);
// Have a second surface to do work on
SDL_Surface* dest = SDL_CreateRGBSurface(0, SCREEN_WIDTH_PIXELS, SCREEN_HEIGHT_PIXELS, 32, 0, 0, 0, 0);
const int red_offset = rand() % 4; const int red_offset = rand() % 4;
for (int x = 0; x < src->w; x++) for (int x = 0; x < src->w; x++)
@ -226,10 +220,5 @@ void ApplyFilter(void)
} }
} }
SDL_FreeFormat(format);
SDL_UpdateTexture(graphics.gameTexture, NULL, dest->pixels, dest->pitch); SDL_UpdateTexture(graphics.gameTexture, NULL, dest->pixels, dest->pitch);
SDL_FreeSurface(src);
SDL_FreeSurface(dest);
} }

View file

@ -12,6 +12,6 @@ void DrawPixel(SDL_Surface* surface, int x, int y, SDL_Color color);
SDL_Color ReadPixel(const SDL_Surface* surface, int x, int y); SDL_Color ReadPixel(const SDL_Surface* surface, int x, int y);
void UpdateFilter(void); void UpdateFilter(void);
void ApplyFilter(void); void ApplyFilter(SDL_Surface* src, SDL_Surface* dest);
#endif /* GRAPHICSUTIL_H */ #endif /* GRAPHICSUTIL_H */