From 58d21e956b1ec30ccaa8f1d3689d7e86897aca6a Mon Sep 17 00:00:00 2001 From: Misa Date: Sat, 4 Mar 2023 14:02:47 -0800 Subject: [PATCH] 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. --- desktop_version/src/Graphics.cpp | 9 +++++++-- desktop_version/src/GraphicsUtil.cpp | 29 +++++++++------------------- desktop_version/src/GraphicsUtil.h | 2 +- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/desktop_version/src/Graphics.cpp b/desktop_version/src/Graphics.cpp index 39980aa5..f5842e5c 100644 --- a/desktop_version/src/Graphics.cpp +++ b/desktop_version/src/Graphics.cpp @@ -171,6 +171,9 @@ void Graphics::destroy(void) #undef CLEAR_ARRAY } +static SDL_Surface* tempFilterSrc = NULL; +static SDL_Surface* tempFilterDest = NULL; + void Graphics::create_buffers(void) { #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, towerbg.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) @@ -3153,7 +3158,7 @@ void Graphics::screenshake(void) { if (gameScreen.badSignalEffect) { - ApplyFilter(); + ApplyFilter(tempFilterSrc, tempFilterDest); } set_render_target(menuoffTexture); @@ -3191,7 +3196,7 @@ void Graphics::render(void) { if (gameScreen.badSignalEffect) { - ApplyFilter(); + ApplyFilter(tempFilterSrc, tempFilterDest); } set_render_target(NULL); diff --git a/desktop_version/src/GraphicsUtil.cpp b/desktop_version/src/GraphicsUtil.cpp index ea2d9eb2..ba478d4e 100644 --- a/desktop_version/src/GraphicsUtil.cpp +++ b/desktop_version/src/GraphicsUtil.cpp @@ -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) + { + 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; } @@ -161,18 +167,6 @@ void ApplyFilter(void) 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; 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_FreeSurface(src); - SDL_FreeSurface(dest); } diff --git a/desktop_version/src/GraphicsUtil.h b/desktop_version/src/GraphicsUtil.h index c4544d9c..3552f40b 100644 --- a/desktop_version/src/GraphicsUtil.h +++ b/desktop_version/src/GraphicsUtil.h @@ -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); void UpdateFilter(void); -void ApplyFilter(void); +void ApplyFilter(SDL_Surface* src, SDL_Surface* dest); #endif /* GRAPHICSUTIL_H */