Interframe filters are now created per thread

This simplifies the interface.
Also fixed an issue with another width+1
I really hate that the original code tried to not display the border.
This commit is contained in:
Arthur Moore 2015-03-12 22:08:57 -04:00
parent 27e95b3f99
commit 347c86aeda
4 changed files with 56 additions and 49 deletions

View File

@ -32,23 +32,16 @@ SmartIB::~SmartIB()
frm1 = frm2 = frm3 = NULL;
}
void SmartIB::run(u32 *srcPtr, unsigned int num_threads,unsigned int thread_number)
void SmartIB::run(u32 *srcPtr)
{
//Actual width needs to take into account the +1 border
unsigned int width = getWidth() +1;
//Height to process (for multithreading)
unsigned int band_height = getHeight() / num_threads;
//First pixel to operate on (for multithreading)
u32 offset = band_height * thread_number * width;
u32 *src0 = srcPtr + offset;
u32 *src1 = frm1 + offset;
u32 *src2 = frm2 + offset;
u32 *src3 = frm3 + offset;
u32 *src0 = srcPtr;
u32 *src1 = frm1;
u32 *src2 = frm2;
u32 *src3 = frm3;
u32 colorMask = 0xfefefe;
for (unsigned int i = 0; i < width*band_height; i++)
for (unsigned int i = 0; i < getWidth()*getHeight(); i++)
{
u32 color = src0[i];
src0[i] =
@ -81,21 +74,14 @@ MotionBlurIB::~MotionBlurIB()
frm1=NULL;
}
void MotionBlurIB::run(u32 *srcPtr, unsigned int num_threads,unsigned int thread_number)
void MotionBlurIB::run(u32 *srcPtr)
{
//Actual width needs to take into account the +1 border
unsigned int width = getWidth() +1;
//Height to process (for multithreading)
unsigned int band_height = getHeight() / num_threads;
//First pixel to operate on (for multithreading)
u32 offset = band_height * thread_number * width;
u32 *src0 = srcPtr + offset;
u32 *src1 = frm1 + offset;
u32 *src0 = srcPtr;
u32 *src1 = frm1;
u32 colorMask = 0xfefefe;
for (unsigned int i = 0; i < width*band_height; i++)
for (unsigned int i = 0; i < getWidth()*getHeight(); i++)
{
u32 color = src0[i];
src0[i] = (((color & colorMask) >> 1) +

View File

@ -29,7 +29,7 @@ public:
unsigned int getWidth() {return width;}
unsigned int getHeight() {return height;}
///New smarter Interframe function
virtual void run(u32 *srcPtr, unsigned int num_threads=1,unsigned int thread_number=0) {}
virtual void run(u32 *srcPtr) {}
virtual bool exists() {return false;}
};
@ -49,7 +49,7 @@ public:
SmartIB(unsigned int _width,unsigned int _height);
~SmartIB();
std::string getName() {return "SmartIB";}
void run(u32 *srcPtr, unsigned int num_threads=1,unsigned int thread_number=0);
void run(u32 *srcPtr);
bool exists() {return true;}
};
@ -63,7 +63,7 @@ public:
MotionBlurIB(unsigned int _width,unsigned int _height);
~MotionBlurIB();
std::string getName() {return "MotionBlurIB";}
void run(u32 *srcPtr, unsigned int num_threads=1,unsigned int thread_number=0);
void run(u32 *srcPtr);
bool exists() {return true;}
};
@ -79,7 +79,8 @@ class interframe_factory
public:
static interframe_filter * createIFB(ifbfunc filter_select,unsigned int width,unsigned int height)
{
switch(filter_select) {
switch(filter_select)
{
case IFB_SMART:
return new SmartIB(width,height);
break;
@ -91,6 +92,19 @@ public:
break;
}
}
static bool exists(ifbfunc filter_select)
{
switch(filter_select)
{
case IFB_SMART:
case IFB_MOTION_BLUR:
return true;
break;
default:
return false;
break;
}
}
};
#endif //NEW_INTERFRAME_HPP

View File

@ -1007,6 +1007,16 @@ class FilterThread : public wxThread
public:
FilterThread() : wxThread(wxTHREAD_JOINABLE), lock(), sig(lock) {}
//Cleanup on exit
~FilterThread()
{
if(iFilter)
{
delete iFilter;
iFilter = NULL;
}
}
wxMutex lock;
wxCondition sig;
wxSemaphore *done;
@ -1024,16 +1034,14 @@ public:
ExitCode Entry()
{
//The filter is run with each thread handling bands of data
//This is how tall each of those bands are
unsigned int band_height = height/nthreads;
// This is the lower height value of the band this thread will process
int band_lower = band_height * threadno;
int band_lower = height * threadno;
//Set the starting location for the destination buffer
dst += width * scale * band_lower * scale;
while(sig.Wait() == wxCOND_NO_ERROR) {
//If no source, do thread cleanup before exiting
if(!src ) {
lock.Unlock();
return (wxThread::ExitCode) 0;
@ -1045,15 +1053,15 @@ public:
return (wxThread::ExitCode) -1;
}
//Run the interframe blending filter
iFilter->run(src, nthreads, threadno);
//Set the start of the source pointer to the first pixel of the appropriate height
src += width * band_lower;
//Set the start of the source pointer to the first pixel of the appropriate height
src += width * band_lower;
//Run the interframe blending filter
iFilter->run(src);
// naturally, any of these with accumulation buffers like those of
// the IFB filters will screw up royally as well
mainFilter->run(src, dst, band_height);
mainFilter->run(src, dst, height);
done->Post();
}
@ -1070,11 +1078,11 @@ DrawingPanel::DrawingPanel(int _width, int _height) :
myFilter = new filter(std::string(gopts.filter.mb_str(wxConvUTF8)));
iFilter = interframe_factory::createIFB((ifbfunc)gopts.ifb,width,height);
scale = myFilter->getScale();
myFilter->setWidth(width);
isFiltered = interframe_factory::exists((ifbfunc)gopts.ifb) || myFilter->exists();
//Do a quick run to initialize the filter
//\TODO: Fix the filters so this is no longer needed
myFilter->run(reinterpret_cast<u32 *>(&todraw), reinterpret_cast<u32 *>(&todraw), height);
@ -1082,16 +1090,20 @@ DrawingPanel::DrawingPanel(int _width, int _height) :
// Create and start up new threads
nthreads = gopts.max_threads;
if(nthreads) {
//The filter is run with each thread handling bands of data
//This is how tall each of those bands are
unsigned int band_height = height/nthreads;
//Create and initialize the threads
threads = new FilterThread[nthreads];
for(int i = 0; i < nthreads; i++) {
threads[i].threadno = i;
threads[i].nthreads = nthreads;
threads[i].width = width;
threads[i].height = height;
threads[i].height = band_height;
threads[i].scale = scale;
threads[i].dst = reinterpret_cast<u32 *>(&todraw);
threads[i].mainFilter=myFilter;
threads[i].iFilter=iFilter;
threads[i].iFilter=interframe_factory::createIFB((ifbfunc)gopts.ifb,width,band_height);
threads[i].done = &filt_done;
threads[i].lock.Lock();
threads[i].Create();
@ -1188,12 +1200,6 @@ DrawingPanel::~DrawingPanel()
delete myFilter;
myFilter = NULL;
}
//Interframe Filter cleanup
if(iFilter)
{
delete iFilter;
iFilter = NULL;
}
}
IMPLEMENT_CLASS2(BasicDrawingPanel, DrawingPanel, wxPanel)
@ -1207,7 +1213,7 @@ BasicDrawingPanel::BasicDrawingPanel(wxWindow *parent, int _width, int _height)
wxFULL_REPAINT_ON_RESIZE), DrawingPanel(_width, _height)
{
// wxImage is 24-bit RGB, so 24-bit is preferred. Filters require 32, though
if(!myFilter->exists() && !iFilter->exists())
if(!isFiltered)
{
// changing from 32 to 24 does not require regenerating color tables
systemColorDepth = 24;

View File

@ -485,11 +485,12 @@ public:
protected:
virtual void DrawArea(wxWindowDC&) = 0;
filter * myFilter;
interframe_filter * iFilter;
int width, height, scale;
// largest buffer required is 32-bit * (max width + 1) * (max height + 2) * (4x4) scaling factor
u8 todraw[257 * 226 * 4 * 16];
FilterThread *threads;
///Is the output going through a filter?
bool isFiltered;
int nthreads;
wxSemaphore filt_done;
const RENDER_PLUGIN_INFO *rpi; // also flag indicating plugin loaded