From Marius Heise, "here is a patch that implements Win32 HW-synced swapping using wglJoinSwapGroupNV, wglBindSwapBarrierNV and the existing traits. It was tested with multiple ATI FirePro S400 cards.

I also fixed the vsync implementation introduced with rev.11357 that was crashing with the Windows Error #170. So I removed your temporary /* */ around the vsync condition..."
This commit is contained in:
Robert Osfield 2011-04-21 13:34:03 +00:00
parent 02081af4f8
commit 634344aef5
5 changed files with 61 additions and 9 deletions

View File

@ -108,6 +108,11 @@ class OSG_EXPORT GraphicsContext : public Object
// V-sync
bool vsync;
// Swap Group
bool swapGroupEnabled;
GLuint swapGroup;
GLuint swapBarrier;
// use multithreaded OpenGL-engine (OS X only)
bool useMultiThreadedOpenGLEngine;

View File

@ -145,6 +145,14 @@ class OSGVIEWER_EXPORT GraphicsWindow : public osg::GraphicsContext, public osgG
bool getSyncToVBlank() const { return _traits.valid() ? _traits->vsync : true; }
/** Set swap group. */
virtual void setSwapGroup(bool on, GLuint group, GLuint barrier)
{
osg::notify(osg::NOTICE) << "GraphicsWindow::setSwapGroup(" << on << " " << group << " " << barrier << ") not implemented." << std::endl;
}
void getSwapGroup(bool& on, GLuint& group, GLuint& barrier) const { on = _traits->swapGroupEnabled; group = _traits->swapGroup; barrier = _traits->swapBarrier; }
public:
/** Return whether a valid and usable GraphicsContext has been created.*/

View File

@ -90,6 +90,9 @@ class OSGVIEWER_EXPORT GraphicsWindowWin32 : public osgViewer::GraphicsWindow, p
/** Set sync-to-vblank. */
virtual void setSyncToVBlank(bool on);
/** Set swap group. */
virtual void setSwapGroup(bool on, GLuint group, GLuint barrier);
/** Handle a native (Win32) windowing event as received from the system */
virtual LRESULT handleNativeWindowingEvent( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );

View File

@ -178,6 +178,9 @@ GraphicsContext::Traits::Traits(DisplaySettings* ds):
face(0),
mipMapGeneration(false),
vsync(true),
swapGroupEnabled(false),
swapGroup(0),
swapBarrier(0),
useMultiThreadedOpenGLEngine(false),
useCursor(true),
glContextVersion("1.0"),

View File

@ -1815,7 +1815,7 @@ bool GraphicsWindowWin32::realizeImplementation()
if (!_initialized) return false;
}
if (_traits.valid() && (_traits->sharedContext /*|| _traits->vsync*/))
if (_traits.valid() && (_traits->sharedContext || _traits->vsync || _traits->swapGroupEnabled))
{
// make context current so we can test capabilities and set up context sharing
struct RestoreContext
@ -1827,10 +1827,7 @@ bool GraphicsWindowWin32::realizeImplementation()
}
~RestoreContext()
{
if (_hdc)
{
wglMakeCurrent(_hdc,_hglrc);
}
wglMakeCurrent(_hdc,_hglrc);
}
protected:
HDC _hdc;
@ -1862,6 +1859,12 @@ bool GraphicsWindowWin32::realizeImplementation()
{
setSyncToVBlank(_traits->vsync);
}
// If the swap group is active then enable it.
if (_traits->swapGroupEnabled)
{
setSwapGroup(_traits->swapGroupEnabled, _traits->swapGroup, _traits->swapBarrier);
}
}
if (_ownsWindow)
@ -2207,6 +2210,36 @@ HCURSOR GraphicsWindowWin32::getOrCreateCursor(MouseCursor mouseCursor)
return _mouseCursorMap[mouseCursor];
}
void GraphicsWindowWin32::setSwapGroup(bool on, GLuint group, GLuint barrier)
{
if (_traits.valid())
{
_traits->swapGroupEnabled = on;
_traits->swapGroup = group;
_traits->swapBarrier = barrier;
}
typedef BOOL (GL_APIENTRY *PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group);
PFNWGLJOINSWAPGROUPNVPROC wglJoinSwapGroupNV = (PFNWGLJOINSWAPGROUPNVPROC)wglGetProcAddress( "wglJoinSwapGroupNV" );
typedef BOOL (GL_APIENTRY *PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier);
PFNWGLBINDSWAPBARRIERNVPROC wglBindSwapBarrierNV = (PFNWGLBINDSWAPBARRIERNVPROC)wglGetProcAddress( "wglBindSwapBarrierNV" );
if ((!wglJoinSwapGroupNV) || (!wglBindSwapBarrierNV))
{
OSG_INFO << "GraphicsWindowWin32::wglJoinSwapGroupNV(bool, GLuint, GLuint) not supported" << std::endl;
return;
}
int swapGroup = (on ? group : 0);
BOOL resultJoin = wglJoinSwapGroupNV(_hdc, swapGroup);
OSG_INFO << "GraphicsWindowWin32::wglJoinSwapGroupNV (" << swapGroup << ") returned " << resultJoin << std::endl;
int swapBarrier = (on ? barrier : 0);
BOOL resultBind = wglBindSwapBarrierNV(swapGroup, swapBarrier);
OSG_INFO << "GraphicsWindowWin32::wglBindSwapBarrierNV (" << swapGroup << ", " << swapBarrier << ") returned " << resultBind << std::endl;
}
void GraphicsWindowWin32::setSyncToVBlank( bool on )
{
if (_traits.valid())
@ -2214,7 +2247,7 @@ void GraphicsWindowWin32::setSyncToVBlank( bool on )
_traits->vsync = on;
}
#if 0
//#if 0
// we ought to properly check if the extension is listed as supported rather than just
// if the function pointer resolves through wglGetProcAddress, but in practice everything
// supports this extension
@ -2232,9 +2265,9 @@ void GraphicsWindowWin32::setSyncToVBlank( bool on )
{
OSG_INFO << "GraphicsWindowWin32::setSyncToVBlank(bool) not supported" << std::endl;
}
#else
OSG_INFO << "GraphicsWindowWin32::setSyncToVBlank(bool) not yet implemented."<< std::endl;
#endif
//#else
// OSG_INFO << "GraphicsWindowWin32::setSyncToVBlank(bool) not yet implemented."<< std::endl;
//#endif
}
void GraphicsWindowWin32::adaptKey( WPARAM wParam, LPARAM lParam, int& keySymbol, unsigned int& modifierMask, int& unmodifiedKeySymbol)