Roderick Colenbrander : wgl: Proper stereo /
double buffering support for ChoosePixelFormat.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Aug 14 07:13:07 CDT 2007
Module: wine
Branch: master
Commit: 454a612223d056212a6b359f26b7e6749bf928c1
URL: http://source.winehq.org/git/wine.git/?a=commit;h=454a612223d056212a6b359f26b7e6749bf928c1
Author: Roderick Colenbrander <thunderbird2k at gmx.net>
Date: Sun Aug 12 14:40:24 2007 +0200
wgl: Proper stereo / double buffering support for ChoosePixelFormat.
---
dlls/winex11.drv/opengl.c | 84 ++++++++++++++++++++++++++++++++++----------
1 files changed, 65 insertions(+), 19 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c
index ea4a28a..62d7e2d 100644
--- a/dlls/winex11.drv/opengl.c
+++ b/dlls/winex11.drv/opengl.c
@@ -1020,6 +1020,8 @@ int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev,
int value = 0;
int i = 0;
int bestFormat = -1;
+ int bestDBuffer = -1;
+ int bestStereo = -1;
int bestColor = -1;
int bestAlpha = -1;
int bestDepth = -1;
@@ -1062,34 +1064,69 @@ int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev,
continue;
}
- /* Doublebuffer:
- * Ignore doublebuffer when PFD_DOUBLEBUFFER_DONTCARE is set. Further if the flag
- * is not set, we must return a format without double buffering. */
pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DOUBLEBUFFER, &value);
if (value) dwFlags |= PFD_DOUBLEBUFFER;
- if (!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) && ((ppfd->dwFlags^dwFlags) & PFD_DOUBLEBUFFER))
- {
- TRACE("dbl buffer mismatch for iPixelFormat=%d\n", i+1);
- continue;
- }
-
- /* Stereo:
- * Ignore stereo when PFD_STEREO_DONTCARE is set. Further if the flag
- * is not set, we must return a format without stereo support. */
pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_STEREO, &value);
if (value) dwFlags |= PFD_STEREO;
- if (!(ppfd->dwFlags & PFD_STEREO_DONTCARE) && ((ppfd->dwFlags^dwFlags) & PFD_STEREO))
- {
- TRACE("stereo mismatch for iPixelFormat=%d\n", i+1);
- continue;
- }
-
pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_BUFFER_SIZE, &color); /* cColorBits */
pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ALPHA_SIZE, &alpha); /* cAlphaBits */
pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DEPTH_SIZE, &depth); /* cDepthBits */
pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_STENCIL_SIZE, &stencil); /* cStencilBits */
pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_AUX_BUFFERS, &aux); /* cAuxBuffers */
+ /* The behavior of PDF_STEREO/PFD_STEREO_DONTCARE and PFD_DOUBLEBUFFER / PFD_DOUBLEBUFFER_DONTCARE
+ * is not very clear on MSDN. They specify that ChoosePixelFormat tries to match pixel formats
+ * with the flag (PFD_STEREO / PFD_DOUBLEBUFFERING) set. Otherwise it says that it tries to match
+ * formats without the given flag set.
+ * A test on Windows using a Radeon 9500pro on WinXP (the driver doesn't support Stereo)
+ * has indicated that a format without stereo is returned when stereo is unavailable.
+ * So in case PFD_STEREO is set, formats that support it should have priority above formats
+ * without. In case PFD_STEREO_DONTCARE is set, stereo is ignored.
+ *
+ * To summarize the following is most likely the correct behavior:
+ * stereo not set -> prefer no-stereo formats, else also accept stereo formats
+ * stereo set -> prefer stereo formats, else also accept no-stereo formats
+ * stereo don't care -> it doesn't matter whether we get stereo or not
+ *
+ * In Wine we will treat no-stereo the same way as don't care because it makes
+ * format selection even more complicated and second drivers with Stereo advertise
+ * each format twice anyway.
+ */
+
+ /* Doublebuffer, see the comments above */
+ if( !(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) ) {
+ if( ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != bestDBuffer) &&
+ ((dwFlags & PFD_DOUBLEBUFFER) == (ppfd->dwFlags & PFD_DOUBLEBUFFER)) )
+ {
+ bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
+ bestStereo = dwFlags & PFD_STEREO;
+ bestAlpha = alpha;
+ bestColor = color;
+ bestDepth = depth;
+ bestStencil = stencil;
+ bestAux = aux;
+ bestFormat = i;
+ continue;
+ }
+ }
+
+ /* Stereo, see the comments above. */
+ if( !(ppfd->dwFlags & PFD_STEREO_DONTCARE) ) {
+ if( ((ppfd->dwFlags & PFD_STEREO) != bestStereo) &&
+ ((dwFlags & PFD_STEREO) == (ppfd->dwFlags & PFD_STEREO)) )
+ {
+ bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
+ bestStereo = dwFlags & PFD_STEREO;
+ bestAlpha = alpha;
+ bestColor = color;
+ bestDepth = depth;
+ bestStencil = stencil;
+ bestAux = aux;
+ bestFormat = i;
+ continue;
+ }
+ }
+
/* Below we will do a number of checks to select the 'best' pixelformat.
* We assume the precedence cColorBits > cAlphaBits > cDepthBits > cStencilBits -> cAuxBuffers.
* The code works by trying to match the most important options as close as possible.
@@ -1099,6 +1136,8 @@ int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev,
if( ((ppfd->cColorBits > bestColor) && (color > bestColor)) ||
((color >= ppfd->cColorBits) && (color < bestColor)) )
{
+ bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
+ bestStereo = dwFlags & PFD_STEREO;
bestAlpha = alpha;
bestColor = color;
bestDepth = depth;
@@ -1115,6 +1154,8 @@ int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev,
if( ((ppfd->cAlphaBits > bestAlpha) && (alpha > bestAlpha)) ||
((alpha >= ppfd->cAlphaBits) && (alpha < bestAlpha)) )
{
+ bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
+ bestStereo = dwFlags & PFD_STEREO;
bestAlpha = alpha;
bestColor = color;
bestDepth = depth;
@@ -1131,6 +1172,8 @@ int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev,
if( ((ppfd->cDepthBits > bestDepth) && (depth > bestDepth)) ||
((depth >= ppfd->cDepthBits) && (depth < bestDepth)) )
{
+ bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
+ bestStereo = dwFlags & PFD_STEREO;
bestAlpha = alpha;
bestColor = color;
bestDepth = depth;
@@ -1147,6 +1190,8 @@ int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev,
if( ((ppfd->cStencilBits > bestStencil) && (stencil > bestStencil)) ||
((stencil >= ppfd->cStencilBits) && (stencil < bestStencil)) )
{
+ bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
+ bestStereo = dwFlags & PFD_STEREO;
bestAlpha = alpha;
bestColor = color;
bestDepth = depth;
@@ -1163,6 +1208,8 @@ int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev,
if( ((ppfd->cAuxBuffers > bestAux) && (aux > bestAux)) ||
((aux >= ppfd->cAuxBuffers) && (aux < bestAux)) )
{
+ bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
+ bestStereo = dwFlags & PFD_STEREO;
bestAlpha = alpha;
bestColor = color;
bestDepth = depth;
@@ -1189,7 +1236,6 @@ int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev,
return ret;
}
-
/**
* X11DRV_DescribePixelFormat
*
More information about the wine-cvs
mailing list