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:
parent
27e95b3f99
commit
347c86aeda
|
@ -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) +
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue