Merge pull request #147 from SuuperW/master

Reduce RAM usage
This commit is contained in:
zeromus 2018-06-27 12:59:03 -04:00 committed by GitHub
commit 23f4dcc009
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 193 additions and 175 deletions

View File

@ -4477,6 +4477,9 @@ void FilterUpdate(HWND hwnd, bool user)
SetRotate(hwnd, video.rotation, false); SetRotate(hwnd, video.rotation, false);
if(user && windowSize==0) {} if(user && windowSize==0) {}
else ScaleScreen(windowSize, false); else ScaleScreen(windowSize, false);
if (romloaded)
Display();
WritePrivateProfileInt("Video", "Filter", video.currentfilter, IniName); WritePrivateProfileInt("Video", "Filter", video.currentfilter, IniName);
WritePrivateProfileInt("Video", "Width", video.width, IniName); WritePrivateProfileInt("Video", "Width", video.width, IniName);
WritePrivateProfileInt("Video", "Height", video.height, IniName); WritePrivateProfileInt("Video", "Height", video.height, IniName);

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;
@ -51,33 +52,46 @@ public:
void SetPrescale(int prescaleHD, int prescalePost) void SetPrescale(int prescaleHD, int prescalePost)
{ {
free_aligned(buffer_raw); if (this->prescaleHD != prescaleHD || this->prescalePost != prescalePost)
free_aligned(filteredbuffer); {
free_aligned(buffer_raw);
free_aligned(filteredbuffer);
this->prescaleHD = prescaleHD; this->prescaleHD = prescaleHD;
this->prescalePost = prescalePost; this->prescalePost = prescalePost;
prescaleTotal = prescaleHD; 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 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; 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? // raw buffer
buffer_raw = buffer = (u32*)malloc_alignedCacheLine(scratchBufferSize); 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); 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 //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; buffer += (kPadSize*rawBufferWidth + kPadSize) * 4;
setfilter(currentfilter); // clean the new buffers
clear();
// prevent crashing when reducing the scaling
srcBufferSize = 0;
} }
enum { enum {
@ -114,62 +128,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 +192,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 +206,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 +288,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;
} }
} }