Rework buffer size allocations to only allocate as much space as is actually required.

This commit is contained in:
SuuperW 2018-06-27 11:23:36 -05:00
parent 0f4b3ead00
commit 8622a334a2
1 changed files with 186 additions and 174 deletions

View File

@ -1,18 +1,18 @@
/*
Copyright (C) 2009-2015 DeSmuME team
Copyright (C) 2009-2015 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "filter/filter.h"
@ -44,6 +44,7 @@ public:
int prescaleTotal;
size_t scratchBufferSize;
size_t rawBufferSize;
u8* srcBuffer;
size_t srcBufferSize;
u32 *buffer, *buffer_raw;
@ -59,27 +60,37 @@ public:
prescaleTotal = prescaleHD;
const int kInflationFactor = 5; //the largest filter is going up 5x in each dimension
//all these stupid video filters read outside of their buffer. let's allocate too much and hope it stays filled with black. geeze
const int kPadSize = 4;
size_t scratchBufferWidth = 256*kInflationFactor*prescaleHD + (kPadSize*2);
size_t scratchBufferHeight = 192*2*prescaleHD*kInflationFactor + (kPadSize*2);
scratchBufferSize = scratchBufferWidth * scratchBufferHeight * 4;
//why are these the same size, anyway?
buffer_raw = buffer = (u32*)malloc_alignedCacheLine(scratchBufferSize);
filteredbuffer = (u32*)malloc_alignedCacheLine(scratchBufferSize);
clear();
//move the buffer pointer inside it's padded area so that earlier reads won't go out of the buffer we allocated
buffer += (kPadSize*scratchBufferWidth + kPadSize)*4;
ResizeBuffers();
setfilter(currentfilter);
}
void ResizeBuffers()
{
// all these stupid video filters read outside of their buffer. let's allocate too much and hope it stays filled with black. geeze
const int kPadSize = 4;
// raw buffer
size_t rawBufferWidth = 256 * prescaleHD + (kPadSize * 2);
size_t rawBufferHeight = 192 * 2 * prescaleHD + (kPadSize * 2);
rawBufferSize = rawBufferWidth * rawBufferHeight * 4;
buffer_raw = buffer = (u32*)malloc_alignedCacheLine(rawBufferSize);
// display buffer
size_t scratchBufferWidth = width + (kPadSize * 2);
size_t scratchBufferHeight = height + (kPadSize * 2);
scratchBufferSize = scratchBufferWidth * scratchBufferHeight * 4;
filteredbuffer = (u32*)malloc_alignedCacheLine(scratchBufferSize);
//move the buffer pointer inside it's padded area so that earlier reads won't go out of the buffer we allocated
buffer += (kPadSize*rawBufferWidth + kPadSize) * 4;
// clean the new buffers
clear();
// prevent crashing when reducing the scaling
srcBufferSize = 0;
}
enum {
NONE,
HQ2X,
@ -114,62 +125,63 @@ public:
//{
// memset(srcBuffer, 0xFF, size() * 2);
//}
memset(buffer_raw, 0, scratchBufferSize);
memset(buffer_raw, 0, rawBufferSize);
memset(filteredbuffer, 0, scratchBufferSize);
}
void reset() {
SetPrescale(1,1); //should i do this here?
SetPrescale(1, 1); //should i do this here?
width = 256;
height = 384;
}
void setfilter(int filter) {
if(filter < 0 || filter >= NUM_FILTERS)
if (filter < 0 || filter >= NUM_FILTERS)
filter = NONE;
currentfilter = filter;
switch(filter) {
switch (filter) {
case NONE:
width = 256;
height = 384;
break;
case EPX1POINT5:
case EPXPLUS1POINT5:
case NEAREST1POINT5:
case NEARESTPLUS1POINT5:
width = 256*3/2;
height = 384*3/2;
break;
case NONE:
width = 256;
height = 384;
break;
case EPX1POINT5:
case EPXPLUS1POINT5:
case NEAREST1POINT5:
case NEARESTPLUS1POINT5:
width = 256 * 3 / 2;
height = 384 * 3 / 2;
break;
case _5XBRZ:
width = 256*5;
height = 384*5;
break;
case _5XBRZ:
width = 256 * 5;
height = 384 * 5;
break;
case HQ4X:
case _4XBRZ:
width = 256*4;
height = 384*4;
break;
case HQ4X:
case _4XBRZ:
width = 256 * 4;
height = 384 * 4;
break;
case _3XBRZ:
width = 256*3;
height = 384*3;
break;
case _3XBRZ:
width = 256 * 3;
height = 384 * 3;
break;
case _2XBRZ:
default:
width = 256*2;
height = 384*2;
break;
case _2XBRZ:
default:
width = 256 * 2;
height = 384 * 2;
break;
}
width *= prescaleHD;
height *= prescaleHD;
ResizeBuffers();
}
SSurface src;
@ -177,7 +189,7 @@ public:
u16* finalBuffer() const
{
if(currentfilter == NONE)
if (currentfilter == NONE)
return (u16*)buffer;
else return (u16*)filteredbuffer;
}
@ -191,81 +203,81 @@ public:
dst.Height = height * prescaleHD;
dst.Width = width * prescaleHD;
dst.Pitch = width*2;
dst.Pitch = width * 2;
dst.Surface = (u8*)filteredbuffer;
switch(currentfilter)
switch (currentfilter)
{
case NONE:
break;
case LQ2X:
RenderLQ2X(src, dst);
break;
case LQ2XS:
RenderLQ2XS(src, dst);
break;
case HQ2X:
RenderHQ2X(src, dst);
break;
case HQ4X:
RenderHQ4X(src, dst);
break;
case HQ2XS:
RenderHQ2XS(src, dst);
break;
case _2XSAI:
Render2xSaI (src, dst);
break;
case SUPER2XSAI:
RenderSuper2xSaI (src, dst);
break;
case SUPEREAGLE:
RenderSuperEagle (src, dst);
break;
case SCANLINE:
RenderScanline(src, dst);
break;
case BILINEAR:
RenderBilinear(src, dst);
break;
case NEAREST2X:
RenderNearest2X(src,dst);
break;
case EPX:
RenderEPX(src,dst);
break;
case EPXPLUS:
RenderEPXPlus(src,dst);
break;
case EPX1POINT5:
RenderEPX_1Point5x(src,dst);
break;
case EPXPLUS1POINT5:
RenderEPXPlus_1Point5x(src,dst);
break;
case NEAREST1POINT5:
RenderNearest_1Point5x(src,dst);
break;
case NEARESTPLUS1POINT5:
RenderNearestPlus_1Point5x(src,dst);
break;
case _2XBRZ:
Render2xBRZ(src,dst);
break;
case _3XBRZ:
Render3xBRZ(src,dst);
break;
case _4XBRZ:
Render4xBRZ(src,dst);
break;
case _5XBRZ:
Render5xBRZ(src,dst);
break;
case NONE:
break;
case LQ2X:
RenderLQ2X(src, dst);
break;
case LQ2XS:
RenderLQ2XS(src, dst);
break;
case HQ2X:
RenderHQ2X(src, dst);
break;
case HQ4X:
RenderHQ4X(src, dst);
break;
case HQ2XS:
RenderHQ2XS(src, dst);
break;
case _2XSAI:
Render2xSaI(src, dst);
break;
case SUPER2XSAI:
RenderSuper2xSaI(src, dst);
break;
case SUPEREAGLE:
RenderSuperEagle(src, dst);
break;
case SCANLINE:
RenderScanline(src, dst);
break;
case BILINEAR:
RenderBilinear(src, dst);
break;
case NEAREST2X:
RenderNearest2X(src, dst);
break;
case EPX:
RenderEPX(src, dst);
break;
case EPXPLUS:
RenderEPXPlus(src, dst);
break;
case EPX1POINT5:
RenderEPX_1Point5x(src, dst);
break;
case EPXPLUS1POINT5:
RenderEPXPlus_1Point5x(src, dst);
break;
case NEAREST1POINT5:
RenderNearest_1Point5x(src, dst);
break;
case NEARESTPLUS1POINT5:
RenderNearestPlus_1Point5x(src, dst);
break;
case _2XBRZ:
Render2xBRZ(src, dst);
break;
case _3XBRZ:
Render3xBRZ(src, dst);
break;
case _4XBRZ:
Render4xBRZ(src, dst);
break;
case _5XBRZ:
Render5xBRZ(src, dst);
break;
}
}
int size() {
return width*height;
return width * height;
}
int dividebyratio(int x) {
@ -273,62 +285,62 @@ public:
}
int rotatedwidth() {
switch(rotation) {
case 0:
return width;
case 90:
return height;
case 180:
return width;
case 270:
return height;
default:
return 0;
switch (rotation) {
case 0:
return width;
case 90:
return height;
case 180:
return width;
case 270:
return height;
default:
return 0;
}
}
int rotatedheight() {
switch(rotation) {
case 0:
return height;
case 90:
return width;
case 180:
return height;
case 270:
return width;
default:
return 0;
switch (rotation) {
case 0:
return height;
case 90:
return width;
case 180:
return height;
case 270:
return width;
default:
return 0;
}
}
int rotatedwidthgap() {
switch(rotation) {
case 0:
return width;
case 90:
return height + ((layout == 0) ? scaledscreengap() : 0);
case 180:
return width;
case 270:
return height + ((layout == 0) ? scaledscreengap() : 0);
default:
return 0;
switch (rotation) {
case 0:
return width;
case 90:
return height + ((layout == 0) ? scaledscreengap() : 0);
case 180:
return width;
case 270:
return height + ((layout == 0) ? scaledscreengap() : 0);
default:
return 0;
}
}
int rotatedheightgap() {
switch(rotation) {
case 0:
return height + ((layout == 0) ? scaledscreengap() : 0);
case 90:
return width;
case 180:
return height + ((layout == 0) ? scaledscreengap() : 0);
case 270:
return width;
default:
return 0;
switch (rotation) {
case 0:
return height + ((layout == 0) ? scaledscreengap() : 0);
case 90:
return width;
case 180:
return height + ((layout == 0) ? scaledscreengap() : 0);
case 270:
return width;
default:
return 0;
}
}