Roderick Colenbrander : wgl: Rewrite ChoosePixelFormat.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Aug 9 08:23:04 CDT 2007


Module: wine
Branch: master
Commit: dee2fc09f5fc68097634dec89910d3667eafa4f8
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=dee2fc09f5fc68097634dec89910d3667eafa4f8

Author: Roderick Colenbrander <thunderbird2k at gmx.net>
Date:   Thu Aug  9 01:17:07 2007 +0200

wgl: Rewrite ChoosePixelFormat.

---

 dlls/winex11.drv/opengl.c |  239 +++++++++++++++++++++++++++++---------------
 1 files changed, 157 insertions(+), 82 deletions(-)

diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c
index a63ba27..0881198 100644
--- a/dlls/winex11.drv/opengl.c
+++ b/dlls/winex11.drv/opengl.c
@@ -1009,105 +1009,180 @@ static int ConvertPixelFormatGLXtoWGL(Display *display, int fmt_id)
  */
 int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev, 
 			     const PIXELFORMATDESCRIPTOR *ppfd) {
-  WineGLPixelFormat *fmt;
-  int ret = 0;
-  int value = 0;
+    WineGLPixelFormat *fmt = NULL;
+    int ret = 0;
+    int nPixelFormats;
+    int value = 0;
+    int i = 0;
+    int bestFormat = -1;
+    int bestColor = -1;
+    int bestAlpha = -1;
+    int bestDepth = -1;
+    int bestStencil = -1;
+    int bestAux = -1;
+    int score;
 
-  if (!has_opengl()) {
-    ERR("No libGL on this box - disabling OpenGL support !\n");
-    return 0;
-  }
+    if (!has_opengl()) {
+        ERR("No libGL on this box - disabling OpenGL support !\n");
+        return 0;
+    }
 
-  if (TRACE_ON(opengl)) {
-    TRACE("(%p,%p)\n", physDev, ppfd);
+    if (TRACE_ON(opengl)) {
+        TRACE("(%p,%p)\n", physDev, ppfd);
 
-    dump_PIXELFORMATDESCRIPTOR((const PIXELFORMATDESCRIPTOR *) ppfd);
-  }
+        dump_PIXELFORMATDESCRIPTOR((const PIXELFORMATDESCRIPTOR *) ppfd);
+    }
 
-  wine_tsx11_lock(); 
-  if(!visual) {
-    ERR("Can't get an opengl visual!\n");
-    goto choose_exit;
-  }
+    wine_tsx11_lock();
+    ConvertPixelFormatWGLtoGLX(gdi_display, 0, FALSE /* offscreen */, &nPixelFormats);
+    for(i=0; i<nPixelFormats; i++)
+    {
+        int dwFlags = 0;
+        int iPixelType = 0;
+        int alpha=0, color=0, depth=0, stencil=0, aux=0;
 
-  fmt = ConvertPixelFormatWGLtoGLX(gdi_display, 1 /* main visual */, FALSE /* offscreen */, &value);
-  /* In case an fbconfig was found, check if it matches to the requirements of the ppfd */
-  if(!fmt) {
-    ERR("Can't find a matching FBCONFIG_ID for VISUAL_ID 0x%lx!\n", visual->visualid);
-  } else {
-    int dwFlags = 0;
-    int iPixelType = 0;
-    int value = 0;
+        fmt = ConvertPixelFormatWGLtoGLX(gdi_display, i+1 /* 1-based index */, FALSE /* offscreen */, &value);
+        score = 0;
 
-    /* Pixel type */
-    pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_RENDER_TYPE, &value);
-    if (value & GLX_RGBA_BIT)
-      iPixelType = PFD_TYPE_RGBA;
-    else
-      iPixelType = PFD_TYPE_COLORINDEX;
+        /* Pixel type */
+        pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_RENDER_TYPE, &value);
+        if (value & GLX_RGBA_BIT)
+            iPixelType = PFD_TYPE_RGBA;
+        else
+            iPixelType = PFD_TYPE_COLORINDEX;
 
-    if (ppfd->iPixelType != iPixelType) {
-      TRACE("pixel type mismatch\n");
-      goto choose_exit;
-    }
+        if (ppfd->iPixelType != iPixelType)
+        {
+            TRACE("pixel type mismatch for iPixelFormat=%d\n", i+1);
+            continue;
+        }
 
-    /* Doublebuffer */
-    pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DOUBLEBUFFER, &value); if (value) dwFlags |= PFD_DOUBLEBUFFER;
-    if (!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) && (ppfd->dwFlags & PFD_DOUBLEBUFFER)) {
-      if (!(dwFlags & PFD_DOUBLEBUFFER)) {
-        TRACE("dbl buffer mismatch\n");
-        goto choose_exit;
-      }
-    }
+        /* 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 */
-    pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_STEREO, &value); if (value) dwFlags |= PFD_STEREO;
-    if (!(ppfd->dwFlags & PFD_STEREO_DONTCARE) && (ppfd->dwFlags & PFD_STEREO)) {
-      if (!(dwFlags & PFD_STEREO)) {
-        TRACE("stereo mismatch\n");
-        goto choose_exit;
-      }
-    }
+        /* 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;
+        }
 
-    /* Alpha bits */
-    pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ALPHA_SIZE, &value);
-    if (ppfd->iPixelType==PFD_TYPE_RGBA && ppfd->cAlphaBits && !value) {
-      TRACE("alpha mismatch\n");
-      goto choose_exit;
-    }
+        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 */
 
-    /* Depth bits */
-    pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DEPTH_SIZE, &value);
-    if (ppfd->cDepthBits && !value) {
-      TRACE("depth mismatch\n");
-      goto choose_exit;
-    }
+        /* 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.
+         * When a reasonable format is found, we will try to match more options. */
 
-    /* Stencil bits */
-    pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_STENCIL_SIZE, &value);
-    if (ppfd->cStencilBits && !value) {
-      TRACE("stencil mismatch\n");
-      goto choose_exit;
-    }
+        /* Color bits */
+        if( ((ppfd->cColorBits > bestColor) && (color > bestColor)) ||
+            ((color >= ppfd->cColorBits) && (color < bestColor)) )
+        {
+            bestAlpha = alpha;
+            bestColor = color;
+            bestDepth = depth;
+            bestStencil = stencil;
+            bestAux = aux;
+            bestFormat = i;
+            continue;
+        } else if(bestColor != color) {  /* Do further checks if the format is compatible */
+            TRACE("color mismatch for iPixelFormat=%d\n", i+1);
+            continue;
+        }
+
+        /* Alpha bits */
+        if( ((ppfd->cAlphaBits > bestAlpha) && (alpha > bestAlpha)) ||
+            ((alpha >= ppfd->cAlphaBits) && (alpha < bestAlpha)) )
+        {
+            bestAlpha = alpha;
+            bestColor = color;
+            bestDepth = depth;
+            bestStencil = stencil;
+            bestAux = aux;
+            bestFormat = i;
+            continue;
+        } else if(bestAlpha != alpha) {
+            TRACE("alpha mismatch for iPixelFormat=%d\n", i+1);
+            continue;
+        }
+
+        /* Depth bits */
+        if( ((ppfd->cDepthBits > bestDepth) && (depth > bestDepth)) ||
+            ((depth >= ppfd->cDepthBits) && (depth < bestDepth)) )
+        {
+            bestAlpha = alpha;
+            bestColor = color;
+            bestDepth = depth;
+            bestStencil = stencil;
+            bestAux = aux;
+            bestFormat = i;
+            continue;
+        } else if(bestDepth != depth) {
+            TRACE("depth mismatch for iPixelFormat=%d\n", i+1);
+            continue;
+        }
 
-    /* Aux buffers */
-    pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_AUX_BUFFERS, &value);
-    if (ppfd->cAuxBuffers && !value) {
-      TRACE("aux mismatch\n");
-      goto choose_exit;
+        /* Stencil bits */
+        if( ((ppfd->cStencilBits > bestStencil) && (stencil > bestStencil)) ||
+            ((stencil >= ppfd->cStencilBits) && (stencil < bestStencil)) )
+        {
+            bestAlpha = alpha;
+            bestColor = color;
+            bestDepth = depth;
+            bestStencil = stencil;
+            bestAux = aux;
+            bestFormat = i;
+            continue;
+        } else if(bestStencil != stencil) {
+            TRACE("stencil mismatch for iPixelFormat=%d\n", i+1);
+            continue;
+        }
+
+        /* Aux buffers */
+        if( ((ppfd->cAuxBuffers > bestAux) && (aux > bestAux)) ||
+            ((aux >= ppfd->cAuxBuffers) && (aux < bestAux)) )
+        {
+            bestAlpha = alpha;
+            bestColor = color;
+            bestDepth = depth;
+            bestStencil = stencil;
+            bestAux = aux;
+            bestFormat = i;
+            continue;
+        } else if(bestAux != aux) {
+            TRACE("aux mismatch for iPixelFormat=%d\n", i+1);
+            continue;
+        }
     }
 
-    /* When we pass all the checks we have found a matching format :) */
-    ret = 1;
-    TRACE("Successfully found a matching mode, returning index: %d\n", ret);
-  }
+    if(bestFormat == -1) {
+        TRACE("No matching mode was found returning 0\n");
+        ret = 0;
+    }
+    else {
+        ret = bestFormat+1; /* the return value should be a 1-based index */
+        TRACE("Successfully found a matching mode, returning index: %d %x\n", ret, WineGLPixelFormatList[bestFormat-1].fmt_id);
+    }
 
-choose_exit:
-  if(!ret)
-    TRACE("No matching mode was found returning 0\n");
+    wine_tsx11_unlock();
 
-  wine_tsx11_unlock();
-  return ret;
+    return ret;
 }
 
 /**




More information about the wine-cvs mailing list