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