From daedf9d158ba6d9265ac1b75bf015889880a856c Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Fri, 20 Dec 2019 11:04:50 +0200 Subject: [PATCH] - improved normalNx scaling performance by ~10% Actual boost heavily depends on platform's memory architecture, made it a bit more cache friendly in general --- src/gamedata/textures/hires/hqresize.cpp | 46 +++++++++++------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/src/gamedata/textures/hires/hqresize.cpp b/src/gamedata/textures/hires/hqresize.cpp index 8e93689dd..f67d4a137 100644 --- a/src/gamedata/textures/hires/hqresize.cpp +++ b/src/gamedata/textures/hires/hqresize.cpp @@ -236,29 +236,7 @@ static unsigned char *scaleNxHelper( void (*scaleNxFunction) ( uint32_t* , uint3 return newBuffer; } -static void normalNx ( uint32_t* inputBuffer, uint32_t* outputBuffer, int inWidth, int inHeight, int size ) -{ - const int width = size * inWidth; - const int height = size * inHeight; - - for ( int i = 0; i < inWidth; ++i ) - { - for ( int j = 0; j < inHeight; ++j ) - { - const uint32_t E = inputBuffer[ i +inWidth*j ]; - for ( int k = 0; k < size; k++ ) - { - for ( int l = 0; l < size; l++ ) - { - outputBuffer[size*i+k + width*(size*j+l)] = E; - } - } - } - } -} - -static unsigned char *normalNxHelper( void (normalNxFunction) ( uint32_t* , uint32_t* , int , int, int), - const int N, +static unsigned char *normalNx(const int N, unsigned char *inputBuffer, const int inWidth, const int inHeight, @@ -269,7 +247,25 @@ static unsigned char *normalNxHelper( void (normalNxFunction) ( uint32_t* , uint outHeight = N *inHeight; unsigned char * newBuffer = new unsigned char[outWidth*outHeight*4]; - normalNxFunction ( reinterpret_cast ( inputBuffer ), reinterpret_cast ( newBuffer ), inWidth, inHeight, N ); + uint32_t *const inBuffer = reinterpret_cast(inputBuffer); + uint32_t *const outBuffer = reinterpret_cast(newBuffer); + + for (int y = 0; y < inHeight; ++y) + { + const int inRowPos = inWidth * y; + const int outRowPos = outWidth * N * y; + + for (int x = 0; x < inWidth; ++x) + { + std::fill_n(&outBuffer[outRowPos + N * x], N, inBuffer[inRowPos + x]); + } + + for (int c = 1; c < N; ++c) + { + std::copy_n(&outBuffer[outRowPos], outWidth, &outBuffer[outRowPos + outWidth * c]); + } + } + delete[] inputBuffer; return newBuffer; } @@ -495,7 +491,7 @@ void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasA else if (type == 5) texbuffer.mBuffer = xbrzHelper(xbrzOldScale, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); else if (type == 6) - texbuffer.mBuffer = normalNxHelper(&normalNx, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + texbuffer.mBuffer = normalNx(mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); else return; }