Rework buffer size allocations to only allocate as much space as is actually required.
This commit is contained in:
parent
0f4b3ead00
commit
8622a334a2
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue