Commit dee2fc09 authored by Roderick Colenbrander's avatar Roderick Colenbrander Committed by Alexandre Julliard

wgl: Rewrite ChoosePixelFormat.

parent ae98679e
......@@ -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;
}
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment