Factored out a lot of common code from ScreenAreaCairo, ScreenAreaXv and ScreenAreaGl to the parent class, ScreenArea.

git-svn-id: https://svn.code.sf.net/p/vbam/code/trunk@744 a31d4220-a93d-0410-bf67-fe4944624d44
This commit is contained in:
bgk 2008-09-20 19:59:04 +00:00
parent dea5e60f3c
commit 9e2ac31a9e
8 changed files with 115 additions and 257 deletions

View File

@ -27,46 +27,14 @@ template<typename T> T min( T x, T y ) { return x < y ? x : y; }
template<typename T> T max( T x, T y ) { return x > y ? x : y; }
ScreenAreaCairo::ScreenAreaCairo(int _iWidth, int _iHeight, int _iScale) :
ScreenArea(_iWidth, _iHeight, _iScale),
m_puiPixels(NULL),
m_puiDelta(NULL),
m_iScaledWidth(_iWidth),
m_iScaledHeight(_iHeight)
ScreenArea(_iWidth, _iHeight, _iScale)
{
vUpdateSize();
}
ScreenAreaCairo::~ScreenAreaCairo()
{
}
void ScreenAreaCairo::vDrawPixels(u8 * _puiData)
{
const int iSrcPitch = (m_iWidth + 1) * sizeof(u32);
const int iScaledPitch = (m_iScaledWidth + 1) * sizeof(u32);
if (m_vFilterIB != NULL)
{
m_vFilterIB(_puiData + iSrcPitch,
iSrcPitch,
m_iWidth,
m_iHeight);
}
if (m_vFilter2x != NULL)
{
m_vFilter2x(_puiData + iSrcPitch,
iSrcPitch,
m_puiDelta,
(u8 *)m_puiPixels,
iScaledPitch,
m_iWidth,
m_iHeight);
}
else
{
memcpy(m_puiPixels, _puiData + iSrcPitch, m_iHeight * iSrcPitch);
}
ScreenArea::vDrawPixels(_puiData);
queue_draw();
}
@ -110,31 +78,6 @@ void ScreenAreaCairo::vDrawBlackScreen()
}
}
void ScreenAreaCairo::vUpdateSize()
{
if (m_puiPixels)
{
delete[] m_puiPixels;
}
if (m_puiDelta)
{
delete[] m_puiDelta;
}
m_iScaledWidth = m_iFilterScale * m_iWidth;
m_iScaledHeight = m_iFilterScale * m_iHeight;
vOnWidgetResize();
m_puiPixels = new u32[(m_iScaledWidth + 1) * m_iScaledHeight];
m_puiDelta = new u8[(m_iWidth + 2) * (m_iHeight + 2) * sizeof(u32)];
memset(m_puiPixels, 0, (m_iScaledWidth + 1) * m_iScaledHeight * sizeof(u32));
memset(m_puiDelta, 255, (m_iWidth + 2) * (m_iHeight + 2) * sizeof(u32));
set_size_request(m_iScale * m_iWidth, m_iScale * m_iHeight);
}
void ScreenAreaCairo::vOnWidgetResize()
{
m_dScaleFactor = min<double>(get_height() / (double)m_iHeight, get_width() / (double)m_iWidth);
@ -144,11 +87,4 @@ void ScreenAreaCairo::vOnWidgetResize()
m_iAreaLeft = (get_width() / m_dScaleFactor - m_iWidth * m_iFilterScale) / 2;
}
bool ScreenAreaCairo::on_configure_event(GdkEventConfigure * event)
{
vOnWidgetResize();
return true;
}
} // namespace VBA

View File

@ -29,25 +29,17 @@ class ScreenAreaCairo : public ScreenArea
{
public:
ScreenAreaCairo(int _iWidth, int _iHeight, int _iScale = 1);
virtual ~ScreenAreaCairo();
void vDrawPixels(u8 * _puiData);
void vDrawBlackScreen();
protected:
bool on_configure_event(GdkEventConfigure * event);
bool on_expose_event(GdkEventExpose * _pstEvent);
void vOnWidgetResize();
private:
double m_dScaleFactor;
int m_iAreaTop;
int m_iAreaLeft;
u32 * m_puiPixels;
u8 * m_puiDelta;
int m_iScaledWidth;
int m_iScaledHeight;
void vUpdateSize();
void vOnWidgetResize();
};
} // namespace VBA

View File

@ -27,11 +27,7 @@ template<typename T> T min( T x, T y ) { return x < y ? x : y; }
template<typename T> T max( T x, T y ) { return x > y ? x : y; }
ScreenAreaGl::ScreenAreaGl(int _iWidth, int _iHeight, int _iScale) :
ScreenArea(_iWidth, _iHeight, _iScale),
m_iScaledWidth(_iWidth),
m_iScaledHeight(_iHeight),
m_puiPixels(NULL),
m_puiDelta(NULL)
ScreenArea(_iWidth, _iHeight, _iScale)
{
Glib::RefPtr<Gdk::GL::Config> glconfig;
@ -63,46 +59,9 @@ void ScreenAreaGl::on_realize()
glClearColor(0.0, 0.0, 0.0, 1.0);
}
ScreenAreaGl::~ScreenAreaGl()
{
if (m_puiPixels)
{
delete[] m_puiPixels;
}
if (m_puiDelta)
{
delete[] m_puiDelta;
}
}
void ScreenAreaGl::vDrawPixels(u8 * _puiData)
{
const int iSrcPitch = (m_iWidth + 1) * sizeof(u32);
const int iScaledPitch = (m_iScaledWidth + 1) * sizeof(u32);
if (m_vFilterIB != NULL)
{
m_vFilterIB(_puiData + iSrcPitch,
iSrcPitch,
m_iWidth,
m_iHeight);
}
if (m_vFilter2x != NULL)
{
m_vFilter2x(_puiData + iSrcPitch,
iSrcPitch,
m_puiDelta,
(u8 *)m_puiPixels,
iScaledPitch,
m_iWidth,
m_iHeight);
}
else
{
memcpy(m_puiPixels, _puiData + iSrcPitch, m_iHeight * iSrcPitch);
}
ScreenArea::vDrawPixels(_puiData);
queue_draw_area(0, 0, get_width(), get_height());
}
@ -116,31 +75,6 @@ void ScreenAreaGl::vDrawBlackScreen()
}
}
void ScreenAreaGl::vUpdateSize()
{
if (m_puiPixels)
{
delete[] m_puiPixels;
}
if (m_puiDelta)
{
delete[] m_puiDelta;
}
m_iScaledWidth = m_iFilterScale * m_iWidth;
m_iScaledHeight = m_iFilterScale * m_iHeight;
vOnWidgetResize();
m_puiPixels = new u32[(m_iScaledWidth + 1) * m_iScaledHeight];
m_puiDelta = new u8[(m_iWidth + 2) * (m_iHeight + 2) * sizeof(u32)];
memset(m_puiPixels, 0, (m_iScaledWidth + 1) * m_iScaledHeight * sizeof(u32));
memset(m_puiDelta, 255, (m_iWidth + 2) * (m_iHeight + 2) * sizeof(u32));
set_size_request(m_iScale * m_iWidth, m_iScale * m_iHeight);
}
void ScreenAreaGl::vOnWidgetResize()
{
m_dScaleFactor = min<double>(get_height() / (double)m_iScaledHeight, get_width() / (double)m_iScaledWidth);
@ -150,13 +84,6 @@ void ScreenAreaGl::vOnWidgetResize()
m_dAreaLeft = 1 - m_dScaleFactor * m_iScaledWidth / (double)get_width();
}
bool ScreenAreaGl::on_configure_event(GdkEventConfigure * event)
{
vOnWidgetResize();
return true;
}
bool ScreenAreaGl::on_expose_event(GdkEventExpose * _pstEvent)
{
Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();

View File

@ -31,26 +31,18 @@ class ScreenAreaGl : public ScreenArea,
{
public:
ScreenAreaGl(int _iWidth, int _iHeight, int _iScale = 1);
virtual ~ScreenAreaGl();
void vDrawPixels(u8 * _puiData);
void vDrawBlackScreen();
protected:
void on_realize();
bool on_expose_event(GdkEventExpose * _pstEvent);
bool on_configure_event(GdkEventConfigure * event);
void vOnWidgetResize();
private:
double m_dAreaTop;
double m_dAreaLeft;
double m_dScaleFactor;
int m_iScaledWidth;
int m_iScaledHeight;
u32 * m_puiPixels;
u8 * m_puiDelta;
void vUpdateSize();
void vOnWidgetResize();
};
} // namespace VBA

View File

@ -37,8 +37,6 @@ template<typename T> T max( T x, T y ) { return x > y ? x : y; }
ScreenAreaXv::ScreenAreaXv(int _iWidth, int _iHeight, int _iScale) :
ScreenArea(_iWidth, _iHeight, _iScale),
m_puiPixels(0),
m_puiDelta(0),
m_iAreaTop(0),
m_iAreaLeft(0)
{
@ -126,52 +124,20 @@ ScreenAreaXv::ScreenAreaXv(int _iWidth, int _iHeight, int _iScale) :
ScreenAreaXv::~ScreenAreaXv()
{
XShmDetach(m_pDisplay, &m_oShm);
if (m_puiPixels != NULL)
{
delete[] m_puiPixels;
}
if (m_puiDelta != NULL)
{
delete[] m_puiDelta;
}
}
void ScreenAreaXv::vDrawPixels(u8 * _puiData)
{
GtkWidget *pDrawingArea = GTK_WIDGET(this->gobj());
GdkGC *gc = pDrawingArea->style->bg_gc[GTK_WIDGET_STATE (pDrawingArea)];
u32 * puiPixels = (u32 *)_puiData;
const int iSrcPitch = m_iWidth * sizeof(u32) + 4;
const int iScaledWidth = m_iFilterScale * m_iWidth;
const int iScaledHeight = m_iFilterScale * m_iHeight;
const int iScaledPitch = iScaledWidth * sizeof(u32) + 4;
const int iDstPitch = (iScaledWidth + 4) * sizeof(u16);
const int iScaledPitch = m_iScaledWidth * sizeof(u32) + 4;
const int iDstPitch = (m_iScaledWidth + 4) * sizeof(u16);
if (m_vFilterIB != NULL)
{
m_vFilterIB(_puiData + iSrcPitch,
iSrcPitch,
m_iWidth,
m_iHeight);
}
ScreenArea::vDrawPixels(_puiData);
if (m_vFilter2x)
{
m_vFilter2x(_puiData + iSrcPitch,
iSrcPitch,
m_puiDelta,
(u8 *)m_puiPixels,
iScaledPitch,
m_iWidth,
m_iHeight);
puiPixels = m_puiPixels;
}
vRGB32toYUY2((unsigned char*)m_pXvImage->data, iScaledWidth, iScaledHeight, iDstPitch,
(u8 *)puiPixels + iScaledPitch, iScaledWidth + 4, iScaledHeight + 4, iScaledPitch);
vRGB32toYUY2((unsigned char*)m_pXvImage->data, m_iScaledWidth, m_iScaledHeight, iDstPitch,
(u8 *)m_puiPixels + iScaledPitch, m_iScaledWidth + 4, m_iScaledHeight + 4, iScaledPitch);
gdk_display_sync(gtk_widget_get_display(pDrawingArea));
@ -181,7 +147,7 @@ void ScreenAreaXv::vDrawPixels(u8 * _puiData)
GDK_GC_XGC (gc),
m_pXvImage,
0, 0,
iScaledWidth, iScaledHeight,
m_iScaledWidth, m_iScaledHeight,
m_iAreaLeft, m_iAreaTop,
m_iAreaWidth + 4, m_iAreaHeight + 4,
True);
@ -194,52 +160,6 @@ void ScreenAreaXv::vDrawBlackScreen()
modify_bg(get_state(), Gdk::Color("black"));
}
void ScreenAreaXv::vUpdateSize()
{
const int iScaledWidth = m_iFilterScale * m_iWidth;
const int iScaledHeight = m_iFilterScale * m_iHeight;
if (m_puiPixels != NULL)
{
delete[] m_puiPixels;
}
if (m_puiDelta != NULL)
{
delete[] m_puiDelta;
}
if (m_oShm.shmid)
{
XShmDetach(m_pDisplay, &m_oShm);
}
vOnWidgetResize();
m_pXvImage = XvShmCreateImage(m_pDisplay,
m_iXvPortId,
m_iFormat,
0,
iScaledWidth + 4,
iScaledHeight + 4,
&m_oShm);
m_oShm.shmid = shmget(IPC_PRIVATE, m_pXvImage->data_size, IPC_CREAT | 0777);
m_oShm.shmaddr = (char *) shmat(m_oShm.shmid, 0, 0);
m_oShm.readOnly = FALSE;
m_pXvImage->data = m_oShm.shmaddr;
XShmAttach(m_pDisplay, &m_oShm);
m_puiPixels = new u32[iScaledWidth * iScaledHeight];
m_puiDelta = new u8[(m_iWidth + 2) * (m_iHeight + 2) * 4];
memset(m_puiPixels, 0, iScaledWidth * iScaledHeight * sizeof(u32));
memset(m_puiDelta, 255, (m_iWidth + 2) * (m_iHeight + 2) * 4);
set_size_request(m_iScale * m_iWidth, m_iScale* m_iHeight);
}
void ScreenAreaXv::vRGB32toYUY2 (unsigned char* dest_ptr,
int dest_width,
int dest_height,
@ -302,18 +222,32 @@ void ScreenAreaXv::vOnWidgetResize()
{
double dAspectRatio = m_iWidth / (double)m_iHeight;
if (m_oShm.shmid)
{
XShmDetach(m_pDisplay, &m_oShm);
}
m_iAreaHeight = min<int>(get_height(), get_width() / dAspectRatio);
m_iAreaWidth = min<int>(get_width(), get_height() * dAspectRatio);
m_iAreaTop = (get_height() - m_iAreaHeight) / 2;
m_iAreaLeft = (get_width() - m_iAreaWidth) / 2;
}
bool ScreenAreaXv::on_configure_event(GdkEventConfigure * event)
{
vOnWidgetResize();
m_pXvImage = XvShmCreateImage(m_pDisplay,
m_iXvPortId,
m_iFormat,
0,
m_iFilterScale * m_iWidth + 4,
m_iFilterScale * m_iHeight + 4,
&m_oShm);
return true;
m_oShm.shmid = shmget(IPC_PRIVATE, m_pXvImage->data_size, IPC_CREAT | 0777);
m_oShm.shmaddr = (char *) shmat(m_oShm.shmid, 0, 0);
m_oShm.readOnly = FALSE;
m_pXvImage->data = m_oShm.shmaddr;
XShmAttach(m_pDisplay, &m_oShm);
}
} // namespace VBA

View File

@ -40,7 +40,7 @@ public:
void vDrawBlackScreen();
protected:
bool on_configure_event(GdkEventConfigure * event);
void vOnWidgetResize();
private:
Display *m_pDisplay;
@ -49,13 +49,9 @@ private:
int m_iFormat;
u16* m_paYUY;
XShmSegmentInfo m_oShm;
u32 * m_puiPixels;
u8 * m_puiDelta;
int m_iAreaTop;
int m_iAreaLeft;
void vUpdateSize();
void vOnWidgetResize();
void vRGB32toYUY2 (unsigned char* dest_ptr,
int dest_width,
int dest_height,

View File

@ -27,6 +27,10 @@ ScreenArea::ScreenArea(int _iWidth, int _iHeight, int _iScale) :
m_iFilterScale(1),
m_vFilter2x(NULL),
m_vFilterIB(NULL),
m_puiPixels(NULL),
m_puiDelta(NULL),
m_iScaledWidth(_iWidth),
m_iScaledHeight(_iHeight),
m_bShowCursor(true)
{
g_assert(_iWidth >= 1 && _iHeight >= 1 && _iScale >= 1);
@ -54,6 +58,16 @@ ScreenArea::ScreenArea(int _iWidth, int _iHeight, int _iScale) :
ScreenArea::~ScreenArea()
{
if (m_puiPixels)
{
delete[] m_puiPixels;
}
if (m_puiDelta)
{
delete[] m_puiDelta;
}
if (m_poEmptyCursor != NULL)
{
delete m_poEmptyCursor;
@ -160,4 +174,65 @@ bool ScreenArea::bOnCursorTimeout()
return false;
}
void ScreenArea::vDrawPixels(u8 * _puiData)
{
const int iSrcPitch = (m_iWidth + 1) * sizeof(u32);
const int iScaledPitch = (m_iScaledWidth + 1) * sizeof(u32);
if (m_vFilterIB != NULL)
{
m_vFilterIB(_puiData + iSrcPitch,
iSrcPitch,
m_iWidth,
m_iHeight);
}
if (m_vFilter2x != NULL)
{
m_vFilter2x(_puiData + iSrcPitch,
iSrcPitch,
m_puiDelta,
(u8 *)m_puiPixels,
iScaledPitch,
m_iWidth,
m_iHeight);
}
else
{
memcpy(m_puiPixels, _puiData + iSrcPitch, m_iHeight * iSrcPitch);
}
}
void ScreenArea::vUpdateSize()
{
if (m_puiPixels)
{
delete[] m_puiPixels;
}
if (m_puiDelta)
{
delete[] m_puiDelta;
}
m_iScaledWidth = m_iFilterScale * m_iWidth;
m_iScaledHeight = m_iFilterScale * m_iHeight;
vOnWidgetResize();
m_puiPixels = new u32[(m_iScaledWidth + 1) * m_iScaledHeight];
m_puiDelta = new u8[(m_iWidth + 2) * (m_iHeight + 2) * sizeof(u32)];
memset(m_puiPixels, 0, (m_iScaledWidth + 1) * m_iScaledHeight * sizeof(u32));
memset(m_puiDelta, 255, (m_iWidth + 2) * (m_iHeight + 2) * sizeof(u32));
set_size_request(m_iScale * m_iWidth, m_iScale * m_iHeight);
}
bool ScreenArea::on_configure_event(GdkEventConfigure * event)
{
vOnWidgetResize();
return true;
}
} // namespace VBA

View File

@ -38,13 +38,14 @@ public:
void vSetScale(int _iScale);
void vSetFilter2x(EFilter2x _eFilter2x);
void vSetFilterIB(EFilterIB _eFilterIB);
virtual void vDrawPixels(u8 * _puiData) = 0;
virtual void vDrawPixels(u8 * _puiData);
virtual void vDrawBlackScreen() = 0;
protected:
virtual bool on_motion_notify_event(GdkEventMotion * _pstEvent);
virtual bool on_enter_notify_event(GdkEventCrossing * _pstEvent);
virtual bool on_leave_notify_event(GdkEventCrossing * _pstEvent);
virtual bool on_configure_event(GdkEventConfigure * event);
virtual bool bOnCursorTimeout();
int m_iWidth;
@ -55,12 +56,17 @@ protected:
int m_iAreaHeight;
Filter2x m_vFilter2x;
FilterIB m_vFilterIB;
u32 * m_puiPixels;
u8 * m_puiDelta;
int m_iScaledWidth;
int m_iScaledHeight;
bool m_bShowCursor;
Gdk::Cursor * m_poEmptyCursor;
sigc::connection m_oCursorSig;
virtual void vUpdateSize() = 0;
void vUpdateSize();
virtual void vOnWidgetResize() = 0;
void vStartCursorTimeout();
void vStopCursorTimeout();
void vHideCursor();