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