Simplified the filter system even further

This commit is contained in:
Arthur Moore 2015-03-10 01:28:12 -04:00
parent 5109fce00c
commit 0efd3e4099
2 changed files with 78 additions and 21 deletions

View File

@ -5,7 +5,7 @@
#include <map> #include <map>
#include <string> #include <string>
#include <stdexcept> #include <stdexcept>
// #include <iostream> #include <iostream>
#include "interframe.hpp" #include "interframe.hpp"
#include "../common/Types.h" #include "../common/Types.h"
@ -77,9 +77,15 @@ private:
FilterFunc myFilter; FilterFunc myFilter;
///The internal scale ///The internal scale
int myScale; int myScale;
///The filter's width
unsigned int width;
///Don't need to calculate these every time (based off width)
unsigned int horiz_bytes;
unsigned int horiz_bytes_out;
public: public:
filter(std::string myName): filter(std::string myName):
name(myName), myFilter(filters::GetFilter(myName)), myScale(filters::GetFilterScale(myName)) name(myName), myFilter(filters::GetFilter(myName)), myScale(filters::GetFilterScale(myName)),
width(0), horiz_bytes(0), horiz_bytes_out(0)
{ {
// std::cerr << name << std::endl; // std::cerr << name << std::endl;
} }
@ -87,22 +93,70 @@ public:
{ {
return name; return name;
} }
///Set the number of pixels per horizontal row
///
///Always use this after initialization if using the new run function.
void setWidth(unsigned int _width)
{
width = _width;
//32 bit filter, so 8 bytes per pixel
// The +1 is for a 1 pixel border that the emulator spits out
horiz_bytes = (width+1) * 4;
//Unfortunately, the filter keeps the border on the scaled output, but DOES NOT scale it
horiz_bytes_out = width * 4 * myScale + 4;
}
unsigned int getWidth()
{
return width;
}
int getScale() int getScale()
{ {
return myScale; return myScale;
} }
void run(u8 *srcPtr, u32 srcPitch, u8 *deltaPtr, u8 *dstPtr, u32 dstPitch, int width, int height) /**
* New Version: Run the filter
*
* This one is smart.
* It knows it's a 32 bit filter, and the input width will not change from when it is initialized.
*
* \param[in] srcPtr A pointer to a 16/32 bit RGB Pixel Array
*/
void run(u8 *srcPtr, u8 *deltaPtr, u8 *dstPtr, int height)
{ {
// std::cerr << name <<": srcPitch: "<<srcPitch<<" dstPitch: "<<dstPitch<<" width: "<<width<<" height: "<<height<< std::endl; if(!width)
{
throw std::runtime_error("ERROR: Filter width not set");
}
std::cerr << name <<": width: "<<width<<" height: "<<height<< std::endl;
if(myFilter!=NULL) if(myFilter!=NULL)
{ {
myFilter(srcPtr,srcPitch,deltaPtr,dstPtr,dstPitch,width,height); myFilter(srcPtr,horiz_bytes,deltaPtr,dstPtr,horiz_bytes_out,width,height);
} }
else else
{ {
throw std::runtime_error("ERROR: Filter does not exist!"); throw std::runtime_error("ERROR: Filter does not exist!");
} }
} }
/**
* DEPRECATED Run the filter
*
* \param[in] srcPtr A pointer to a 16/32 bit RGB Pixel Array
* \param[in] srcPitch The number of bytes per single horizontal line
*/
void run(u8 *srcPtr, u32 srcPitch, u8 *deltaPtr, u8 *dstPtr, u32 dstPitch, int width, int height)
{
setWidth(width);
//Make sure the math was correct
if( (srcPitch != horiz_bytes) || dstPitch != horiz_bytes_out )
{
throw std::runtime_error("ERROR: Filter programmer is an idiot, and messed up an important calculation!");
}
run(srcPtr, deltaPtr, dstPtr, height);
}
bool exists() bool exists()
{ {
if (myFilter==NULL) if (myFilter==NULL)

View File

@ -989,6 +989,9 @@ DrawingPanel::DrawingPanel(int _width, int _height) :
myFilter = new filter(std::string(gopts.filter.mb_str(wxConvUTF8))); myFilter = new filter(std::string(gopts.filter.mb_str(wxConvUTF8)));
scale = myFilter->getScale(); scale = myFilter->getScale();
myFilter->setWidth(width);
std::cerr << "width: " << width << " Height: " << height << std::endl;
#define out_16 (systemColorDepth == 16) #define out_16 (systemColorDepth == 16)
systemColorDepth = 32; systemColorDepth = 32;
@ -1073,18 +1076,18 @@ public:
// threadno == -1 means just do a dummy round on the border line // threadno == -1 means just do a dummy round on the border line
int band_lower = band_height * threadno; int band_lower = band_height * threadno;
//The number of bytes per pixel, as determined by the systemColorDepth //The number of bytes for each 32 bit pixel
int bytes_per_pixel = systemColorDepth/8; int bytes_per_pixel = 4;
int inrb = systemColorDepth == 16 ? 2 : systemColorDepth == 24 ? 0 : 1; //This is the number of bytes per single horizontal line
int instride = (width + inrb) * bytes_per_pixel; // The +1 is for a 1 pixel border
int horiz_bytes = (width + 1) * bytes_per_pixel;
//Unfortunately, the filter keeps the border on the scaled output, but DOES NOT scale it
int horiz_bytes_out = width * bytes_per_pixel * scale + bytes_per_pixel;
int outrb = systemColorDepth == 24 ? 0 : 4; delta += horiz_bytes * band_lower;
int outstride = width * bytes_per_pixel * scale + outrb;
delta += instride * band_lower;
// + 1 for stupid top border // + 1 for stupid top border
dst += outstride * (band_lower + 1) * scale; dst += horiz_bytes_out * (band_lower + 1) * scale;
while(nthreads == 1 || sig.Wait() == wxCOND_NO_ERROR) { while(nthreads == 1 || sig.Wait() == wxCOND_NO_ERROR) {
if(!src /* && nthreads > 1 */ ) { if(!src /* && nthreads > 1 */ ) {
@ -1092,7 +1095,7 @@ public:
return 0; return 0;
} }
// + 1 for stupid top border // + 1 for stupid top border
src += instride; src += horiz_bytes;
// interframe blending filter // interframe blending filter
// definitely not thread safe by default // definitely not thread safe by default
// added band_lower param to provide offset into accum buffers // added band_lower param to provide offset into accum buffers
@ -1100,16 +1103,16 @@ public:
switch(gopts.ifb) { switch(gopts.ifb) {
case IFB_SMART: case IFB_SMART:
if(systemColorDepth == 16) if(systemColorDepth == 16)
SmartIB(src, instride, width, band_lower, band_height); SmartIB(src, horiz_bytes, width, band_lower, band_height);
else else
SmartIB32(src, instride, width, band_lower, band_height); SmartIB32(src, horiz_bytes, width, band_lower, band_height);
break; break;
case IFB_MOTION_BLUR: case IFB_MOTION_BLUR:
// FIXME: if(renderer == d3d/gl && filter == NONE) break; // FIXME: if(renderer == d3d/gl && filter == NONE) break;
if(systemColorDepth == 16) if(systemColorDepth == 16)
MotionBlurIB(src, instride, width, band_lower, band_height); MotionBlurIB(src, horiz_bytes, width, band_lower, band_height);
else else
MotionBlurIB32(src, instride, width, band_lower, band_height); MotionBlurIB32(src, horiz_bytes, width, band_lower, band_height);
break; break;
} }
} }
@ -1126,11 +1129,11 @@ public:
continue; continue;
} }
src += instride * band_lower; src += horiz_bytes * band_lower;
// naturally, any of these with accumulation buffers like those of // naturally, any of these with accumulation buffers like those of
// the IFB filters will screw up royally as well // the IFB filters will screw up royally as well
mainFilter->run(src, instride, delta, dst, outstride, width, band_height); mainFilter->run(src, delta, dst, band_height);
if(nthreads == 1) if(nthreads == 1)
return 0; return 0;