From ad0f4d58fed7957a06e1834dc7e6c737edd33099 Mon Sep 17 00:00:00 2001 From: AquariusPower Date: Wed, 28 Mar 2018 09:36:08 -0300 Subject: [PATCH 1/6] Improved library performance by caching the internal image data, this way, instead of delete (free) the image data memory, if it matches the requirements (WxH) that cached data will be re-used. By not trying to free memory, therefore not requiring to allocate new memory, it is easier on the OS. As a practical result, it avoids slowness and memory swapping to HD. --- libxbrzscale.cpp | 75 ++++++++++++++++++++++++++++++++++++++---------- libxbrzscale.h | 18 ++++++++++-- 2 files changed, 75 insertions(+), 18 deletions(-) diff --git a/libxbrzscale.cpp b/libxbrzscale.cpp index 5623e73..51515dd 100644 --- a/libxbrzscale.cpp +++ b/libxbrzscale.cpp @@ -23,17 +23,20 @@ #include #include #include +#include +#include #include "xbrz/xbrz.h" -//#include -//#include -//#include "SDL.h" -//#include "SDL_image.h" -//#include "xbrz/xbrz.h" - bool libxbrzscale::bEnableOutput=false; +bool libxbrzscale::bDbgMsg=false; + +bool libxbrzscale::bUseCache=false; + +bool libxbrzscale::bFreeInputSurfaceAfterScale=true; +bool libxbrzscale::bFreeOutputSurfaceAfterScale=true; + Uint32 libxbrzscale::SDL_GetPixel(SDL_Surface *surface, int x, int y) { int bpp = surface->format->BytesPerPixel; @@ -96,6 +99,7 @@ void libxbrzscale::SDL_PutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel SDL_Surface* libxbrzscale::createARGBSurface(int w, int h) { + if(bDbgMsg)printf("Creating SDL RGB surface w=%d h=%d\n",w,h); return SDL_CreateRGBSurface(0, w, h, 32, 0xff0000U, 0xff00U, 0xffU, 0xff000000U); } @@ -134,8 +138,30 @@ void displayImage(SDL_Surface* surface, const char* message) { } */ +struct imgUint32{ + uint32_t *data; + int iW; + int iH; +}; +std::vector vImgUint32Cache; +imgUint32 ImgUint32Cache(int iW,int iH){ //as that memory deletion wont happen promptly, it may consume too much memory too fast unnecessarily becoming a bottle neck on performance + for(int i=0;iw!=dst_width || dst_imgCache->h!=dst_height || dst_imgCache->refcount==0){ + if(bFreeOutputSurfaceAfterScale && dst_imgCache!=NULL && dst_imgCache->refcount>0){ + SDL_FreeSurface(dst_imgCache); //previous OUTPUT surface + } + + dst_imgCache = createARGBSurface(dst_width, dst_height); + } + + if (!dst_imgCache) { + if(!bUseCache)delete [] dest; if(bEnableOutput)fprintf(stderr, "Failed to create SDL surface: %s\n", SDL_GetError()); return NULL; } - uint32toSurface(dest,dst_img); + uint32toSurface(dest,dst_imgCache); - return dst_img; + return dst_imgCache; } diff --git a/libxbrzscale.h b/libxbrzscale.h index a20b1d9..7b881f9 100644 --- a/libxbrzscale.h +++ b/libxbrzscale.h @@ -23,13 +23,25 @@ struct SDL_Surface; class libxbrzscale { public: - static inline Uint32 SDL_GetPixel(SDL_Surface *surface, int x, int y); - static inline void SDL_PutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel); + static Uint32 SDL_GetPixel(SDL_Surface *surface, int x, int y); + static void SDL_PutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel); static SDL_Surface* createARGBSurface(int w, int h); static SDL_Surface* scale(SDL_Surface* src_img,int scale); - static void setEnableOutput(bool b){bEnableOutput=true;}; + static SDL_Surface* scale(SDL_Surface* dst_imgCache,SDL_Surface* src_img,int scale); + static void setEnableOutput(bool b){bEnableOutput=b;}; + static void setDebugMsg(bool b){bDbgMsg=b;}; + static void setFreeSurfaceAfterScale(bool bInputSurface,bool bOutputSurface){ + bFreeInputSurfaceAfterScale=bInputSurface; + bFreeOutputSurfaceAfterScale=bOutputSurface; + }; + static void setUseCache(bool b){bUseCache=b;}; static uint32_t* surfaceToUint32(SDL_Surface* img); static void uint32toSurface(uint32_t* dest, SDL_Surface* dst_img); + static bool isDbgMsg(){return bDbgMsg;} private: static bool bEnableOutput; + static bool bDbgMsg; + static bool bUseCache; + static bool bFreeInputSurfaceAfterScale; + static bool bFreeOutputSurfaceAfterScale; }; From 835a665d1f829726c0233b538a557923c944e10d Mon Sep 17 00:00:00 2001 From: AquariusPower Date: Wed, 28 Mar 2018 12:39:01 -0300 Subject: [PATCH 2/6] fixed to work as expected with inline modifier --- libxbrzscale.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libxbrzscale.cpp b/libxbrzscale.cpp index 51515dd..5cd69b2 100644 --- a/libxbrzscale.cpp +++ b/libxbrzscale.cpp @@ -37,7 +37,7 @@ bool libxbrzscale::bUseCache=false; bool libxbrzscale::bFreeInputSurfaceAfterScale=true; bool libxbrzscale::bFreeOutputSurfaceAfterScale=true; -Uint32 libxbrzscale::SDL_GetPixel(SDL_Surface *surface, int x, int y) +inline Uint32 libxbrzscale::SDL_GetPixel(SDL_Surface *surface, int x, int y) { int bpp = surface->format->BytesPerPixel; /* Here p is the address to the pixel we want to retrieve */ @@ -64,7 +64,7 @@ Uint32 libxbrzscale::SDL_GetPixel(SDL_Surface *surface, int x, int y) } } -void libxbrzscale::SDL_PutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) +inline void libxbrzscale::SDL_PutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) { int bpp = surface->format->BytesPerPixel; /* Here p is the address to the pixel we want to set */ From 8b9105efb2d347567602a142fa8dceb9229b6676 Mon Sep 17 00:00:00 2001 From: AquariusPower Date: Wed, 4 Apr 2018 20:34:44 -0300 Subject: [PATCH 3/6] adding flexibility to other compilers concerning some inline methods and SDL lib include path. --- libxbrzscale.cpp | 26 +++++++++++++++++++++----- libxbrzscale.h | 4 ++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/libxbrzscale.cpp b/libxbrzscale.cpp index 5cd69b2..e123d57 100644 --- a/libxbrzscale.cpp +++ b/libxbrzscale.cpp @@ -18,13 +18,23 @@ #include "libxbrzscale.h" +#include +#include +#include + +#ifndef XBRZLIB_RELATIVEPATHSDL +//#include #include #include #include #include -#include -#include -#include +#else +//#include "SDL.h" +#include "SDL_endian.h" +#include "SDL_error.h" +#include "SDL_pixels.h" +#include "SDL_surface.h" +#endif #include "xbrz/xbrz.h" @@ -37,7 +47,10 @@ bool libxbrzscale::bUseCache=false; bool libxbrzscale::bFreeInputSurfaceAfterScale=true; bool libxbrzscale::bFreeOutputSurfaceAfterScale=true; -inline Uint32 libxbrzscale::SDL_GetPixel(SDL_Surface *surface, int x, int y) +#ifndef XBRZLIB_NOINLINEGETSETPIX //this may be required to let some compillers linking actually work w/o error: "undefined reference to" these +inline +#endif +Uint32 libxbrzscale::SDL_GetPixel(SDL_Surface *surface, int x, int y) { int bpp = surface->format->BytesPerPixel; /* Here p is the address to the pixel we want to retrieve */ @@ -64,7 +77,10 @@ inline Uint32 libxbrzscale::SDL_GetPixel(SDL_Surface *surface, int x, int y) } } -inline void libxbrzscale::SDL_PutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) +#ifndef XBRZLIB_NOINLINEGETSETPIX //this may be required to let some compillers linking actually work w/o error: "undefined reference to" these +inline +#endif +void libxbrzscale::SDL_PutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) { int bpp = surface->format->BytesPerPixel; /* Here p is the address to the pixel we want to set */ diff --git a/libxbrzscale.h b/libxbrzscale.h index 7b881f9..0a8bbbc 100644 --- a/libxbrzscale.h +++ b/libxbrzscale.h @@ -16,7 +16,11 @@ * along with this program. If not, see . */ +#ifndef XBRZLIB_RELATIVEPATHSDL #include +#else +#include "SDL_stdinc.h" +#endif struct SDL_Surface; From d2e4adc063965687ba4d3bdef1aba422840e5197 Mon Sep 17 00:00:00 2001 From: AquariusPower Date: Wed, 4 Apr 2018 21:26:49 -0300 Subject: [PATCH 4/6] libxbrz improving cache management --- libxbrzscale.cpp | 54 ++++++++++++++++++++++++++---------------------- libxbrzscale.h | 2 +- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/libxbrzscale.cpp b/libxbrzscale.cpp index e123d57..2d34257 100644 --- a/libxbrzscale.cpp +++ b/libxbrzscale.cpp @@ -20,16 +20,13 @@ #include #include -#include #ifndef XBRZLIB_RELATIVEPATHSDL -//#include #include #include #include #include #else -//#include "SDL.h" #include "SDL_endian.h" #include "SDL_error.h" #include "SDL_pixels.h" @@ -154,30 +151,37 @@ void displayImage(SDL_Surface* surface, const char* message) { } */ -struct imgUint32{ - uint32_t *data; - int iW; - int iH; -}; -std::vector vImgUint32Cache; -imgUint32 ImgUint32Cache(int iW,int iH){ //as that memory deletion wont happen promptly, it may consume too much memory too fast unnecessarily becoming a bottle neck on performance - for(int i=0;i (bIn?lUInt32ImgCacheSizeIN:lUInt32ImgCacheSizeOUT)){ + if(libxbrzscale::isDbgMsg())std::cerr<<"libxBRZ: increasing "<<(bIn?"IN":"OUT")<<" image cache to "< Date: Wed, 4 Apr 2018 21:38:55 -0300 Subject: [PATCH 5/6] libxbrz: fixed error messages. --- libxbrzscale.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libxbrzscale.cpp b/libxbrzscale.cpp index 2d34257..0fa5b53 100644 --- a/libxbrzscale.cpp +++ b/libxbrzscale.cpp @@ -232,7 +232,10 @@ SDL_Surface* libxbrzscale::scale(SDL_Surface* src_img, int scale){ * dst_img if not null may be re-used, and is also returned */ SDL_Surface* libxbrzscale::scale(SDL_Surface* dst_imgCache, SDL_Surface* src_img, int scale){ - if(scale<2 || scale>6){std::cerr<<"invalid stretch value min=2, max=6, requested="<6){ + fprintf(stderr, "invalid stretch value min=2, max=6, requested=%d\n", scale); + return NULL; + } int src_width = src_img->w; int src_height = src_img->h; @@ -263,7 +266,7 @@ SDL_Surface* libxbrzscale::scale(SDL_Surface* dst_imgCache, SDL_Surface* src_img if (!dst_imgCache) { if(!bUseCache){DeleteCache(false);dest=NULL;} - if(bEnableOutput)fprintf(stderr, "Failed to create SDL surface: %s\n", SDL_GetError()); + fprintf(stderr, "Failed to create SDL surface: %s\n", SDL_GetError()); //error messages must always output return NULL; } From 580885c895058f54714870898b88b0b3183cbcdc Mon Sep 17 00:00:00 2001 From: AquariusPower Date: Thu, 5 Apr 2018 16:04:55 -0300 Subject: [PATCH 6/6] libxbrzscale: improved inline define readability. --- libxbrzscale.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libxbrzscale.cpp b/libxbrzscale.cpp index 0fa5b53..b495ff2 100644 --- a/libxbrzscale.cpp +++ b/libxbrzscale.cpp @@ -44,10 +44,13 @@ bool libxbrzscale::bUseCache=false; bool libxbrzscale::bFreeInputSurfaceAfterScale=true; bool libxbrzscale::bFreeOutputSurfaceAfterScale=true; -#ifndef XBRZLIB_NOINLINEGETSETPIX //this may be required to let some compillers linking actually work w/o error: "undefined reference to" these -inline +#ifdef XBRZLIB_NOINLINEGETSETPIX //this may be required to let some compillers linking actually work w/o error: "undefined reference to" these +#define XBRZLIB_GSPINLINE +#else +#define XBRZLIB_GSPINLINE inline #endif -Uint32 libxbrzscale::SDL_GetPixel(SDL_Surface *surface, int x, int y) + +XBRZLIB_GSPINLINE Uint32 libxbrzscale::SDL_GetPixel(SDL_Surface *surface, int x, int y) { int bpp = surface->format->BytesPerPixel; /* Here p is the address to the pixel we want to retrieve */ @@ -74,10 +77,7 @@ Uint32 libxbrzscale::SDL_GetPixel(SDL_Surface *surface, int x, int y) } } -#ifndef XBRZLIB_NOINLINEGETSETPIX //this may be required to let some compillers linking actually work w/o error: "undefined reference to" these -inline -#endif -void libxbrzscale::SDL_PutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) +XBRZLIB_GSPINLINE void libxbrzscale::SDL_PutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) { int bpp = surface->format->BytesPerPixel; /* Here p is the address to the pixel we want to set */