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 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This file is distributed in the hope that it will be useful, This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License 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/>. along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "filter/filter.h" #include "filter/filter.h"
@ -44,6 +44,7 @@ public:
int prescaleTotal; int prescaleTotal;
size_t scratchBufferSize; size_t scratchBufferSize;
size_t rawBufferSize;
u8* srcBuffer; u8* srcBuffer;
size_t srcBufferSize; size_t srcBufferSize;
u32 *buffer, *buffer_raw; u32 *buffer, *buffer_raw;
@ -59,27 +60,37 @@ public:
prescaleTotal = prescaleHD; prescaleTotal = prescaleHD;
const int kInflationFactor = 5; //the largest filter is going up 5x in each dimension 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;
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;
setfilter(currentfilter); 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 { enum {
NONE, NONE,
HQ2X, HQ2X,
@ -114,62 +125,63 @@ public:
//{ //{
// memset(srcBuffer, 0xFF, size() * 2); // memset(srcBuffer, 0xFF, size() * 2);
//} //}
memset(buffer_raw, 0, scratchBufferSize); memset(buffer_raw, 0, rawBufferSize);
memset(filteredbuffer, 0, scratchBufferSize); memset(filteredbuffer, 0, scratchBufferSize);
} }
void reset() { void reset() {
SetPrescale(1,1); //should i do this here? SetPrescale(1, 1); //should i do this here?
width = 256; width = 256;
height = 384; height = 384;
} }
void setfilter(int filter) { void setfilter(int filter) {
if(filter < 0 || filter >= NUM_FILTERS) if (filter < 0 || filter >= NUM_FILTERS)
filter = NONE; filter = NONE;
currentfilter = filter; currentfilter = filter;
switch(filter) { switch (filter) {
case NONE: case NONE:
width = 256; width = 256;
height = 384; height = 384;
break; break;
case EPX1POINT5: case EPX1POINT5:
case EPXPLUS1POINT5: case EPXPLUS1POINT5:
case NEAREST1POINT5: case NEAREST1POINT5:
case NEARESTPLUS1POINT5: case NEARESTPLUS1POINT5:
width = 256*3/2; width = 256 * 3 / 2;
height = 384*3/2; height = 384 * 3 / 2;
break; break;
case _5XBRZ: case _5XBRZ:
width = 256*5; width = 256 * 5;
height = 384*5; height = 384 * 5;
break; break;
case HQ4X: case HQ4X:
case _4XBRZ: case _4XBRZ:
width = 256*4; width = 256 * 4;
height = 384*4; height = 384 * 4;
break; break;
case _3XBRZ: case _3XBRZ:
width = 256*3; width = 256 * 3;
height = 384*3; height = 384 * 3;
break; break;
case _2XBRZ: case _2XBRZ:
default: default:
width = 256*2; width = 256 * 2;
height = 384*2; height = 384 * 2;
break; break;
} }
width *= prescaleHD; width *= prescaleHD;
height *= prescaleHD; height *= prescaleHD;
ResizeBuffers();
} }
SSurface src; SSurface src;
@ -177,7 +189,7 @@ public:
u16* finalBuffer() const u16* finalBuffer() const
{ {
if(currentfilter == NONE) if (currentfilter == NONE)
return (u16*)buffer; return (u16*)buffer;
else return (u16*)filteredbuffer; else return (u16*)filteredbuffer;
} }
@ -191,81 +203,81 @@ public:
dst.Height = height * prescaleHD; dst.Height = height * prescaleHD;
dst.Width = width * prescaleHD; dst.Width = width * prescaleHD;
dst.Pitch = width*2; dst.Pitch = width * 2;
dst.Surface = (u8*)filteredbuffer; dst.Surface = (u8*)filteredbuffer;
switch(currentfilter) switch (currentfilter)
{ {
case NONE: case NONE:
break; break;
case LQ2X: case LQ2X:
RenderLQ2X(src, dst); RenderLQ2X(src, dst);
break; break;
case LQ2XS: case LQ2XS:
RenderLQ2XS(src, dst); RenderLQ2XS(src, dst);
break; break;
case HQ2X: case HQ2X:
RenderHQ2X(src, dst); RenderHQ2X(src, dst);
break; break;
case HQ4X: case HQ4X:
RenderHQ4X(src, dst); RenderHQ4X(src, dst);
break; break;
case HQ2XS: case HQ2XS:
RenderHQ2XS(src, dst); RenderHQ2XS(src, dst);
break; break;
case _2XSAI: case _2XSAI:
Render2xSaI (src, dst); Render2xSaI(src, dst);
break; break;
case SUPER2XSAI: case SUPER2XSAI:
RenderSuper2xSaI (src, dst); RenderSuper2xSaI(src, dst);
break; break;
case SUPEREAGLE: case SUPEREAGLE:
RenderSuperEagle (src, dst); RenderSuperEagle(src, dst);
break; break;
case SCANLINE: case SCANLINE:
RenderScanline(src, dst); RenderScanline(src, dst);
break; break;
case BILINEAR: case BILINEAR:
RenderBilinear(src, dst); RenderBilinear(src, dst);
break; break;
case NEAREST2X: case NEAREST2X:
RenderNearest2X(src,dst); RenderNearest2X(src, dst);
break; break;
case EPX: case EPX:
RenderEPX(src,dst); RenderEPX(src, dst);
break; break;
case EPXPLUS: case EPXPLUS:
RenderEPXPlus(src,dst); RenderEPXPlus(src, dst);
break; break;
case EPX1POINT5: case EPX1POINT5:
RenderEPX_1Point5x(src,dst); RenderEPX_1Point5x(src, dst);
break; break;
case EPXPLUS1POINT5: case EPXPLUS1POINT5:
RenderEPXPlus_1Point5x(src,dst); RenderEPXPlus_1Point5x(src, dst);
break; break;
case NEAREST1POINT5: case NEAREST1POINT5:
RenderNearest_1Point5x(src,dst); RenderNearest_1Point5x(src, dst);
break; break;
case NEARESTPLUS1POINT5: case NEARESTPLUS1POINT5:
RenderNearestPlus_1Point5x(src,dst); RenderNearestPlus_1Point5x(src, dst);
break; break;
case _2XBRZ: case _2XBRZ:
Render2xBRZ(src,dst); Render2xBRZ(src, dst);
break; break;
case _3XBRZ: case _3XBRZ:
Render3xBRZ(src,dst); Render3xBRZ(src, dst);
break; break;
case _4XBRZ: case _4XBRZ:
Render4xBRZ(src,dst); Render4xBRZ(src, dst);
break; break;
case _5XBRZ: case _5XBRZ:
Render5xBRZ(src,dst); Render5xBRZ(src, dst);
break; break;
} }
} }
int size() { int size() {
return width*height; return width * height;
} }
int dividebyratio(int x) { int dividebyratio(int x) {
@ -273,62 +285,62 @@ public:
} }
int rotatedwidth() { int rotatedwidth() {
switch(rotation) { switch (rotation) {
case 0: case 0:
return width; return width;
case 90: case 90:
return height; return height;
case 180: case 180:
return width; return width;
case 270: case 270:
return height; return height;
default: default:
return 0; return 0;
} }
} }
int rotatedheight() { int rotatedheight() {
switch(rotation) { switch (rotation) {
case 0: case 0:
return height; return height;
case 90: case 90:
return width; return width;
case 180: case 180:
return height; return height;
case 270: case 270:
return width; return width;
default: default:
return 0; return 0;
} }
} }
int rotatedwidthgap() { int rotatedwidthgap() {
switch(rotation) { switch (rotation) {
case 0: case 0:
return width; return width;
case 90: case 90:
return height + ((layout == 0) ? scaledscreengap() : 0); return height + ((layout == 0) ? scaledscreengap() : 0);
case 180: case 180:
return width; return width;
case 270: case 270:
return height + ((layout == 0) ? scaledscreengap() : 0); return height + ((layout == 0) ? scaledscreengap() : 0);
default: default:
return 0; return 0;
} }
} }
int rotatedheightgap() { int rotatedheightgap() {
switch(rotation) { switch (rotation) {
case 0: case 0:
return height + ((layout == 0) ? scaledscreengap() : 0); return height + ((layout == 0) ? scaledscreengap() : 0);
case 90: case 90:
return width; return width;
case 180: case 180:
return height + ((layout == 0) ? scaledscreengap() : 0); return height + ((layout == 0) ? scaledscreengap() : 0);
case 270: case 270:
return width; return width;
default: default:
return 0; return 0;
} }
} }