Module: wine Branch: master Commit: 8293a9ead0ddbc40be62815f0f0823356665b3dc URL: http://source.winehq.org/git/wine.git/?a=commit;h=8293a9ead0ddbc40be62815f0f...
Author: Roderick Colenbrander thunderbird2k@gmx.net Date: Fri Feb 22 20:40:00 2008 +0000
wgl: Remove the pixel format limitation.
---
dlls/winex11.drv/opengl.c | 91 +++++++++++++++++++++----------------------- 1 files changed, 43 insertions(+), 48 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 3531918..d685b94 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -829,17 +829,10 @@ static int get_render_type_from_fbconfig(Display *display, GLXFBConfig fbconfig)
static BOOL init_formats(Display *display, int screen, Visual *visual) { - int fmt_id, tmp_fmt_id, nCfgs, i; + int fmt_id, nCfgs, i, run; GLXFBConfig* cfgs; - GLXFBConfig fbconfig = NULL; XVisualInfo *visinfo; - VisualID visualid = XVisualIDFromVisual(visual); - int nOffscreenFormats = 0;
- /* As mentioned in various parts of the code only the format of the main visual can be used for onscreen rendering. - * Next to this format there are also so called offscreen rendering formats (used for pbuffers) which can be supported - * because they don't need a visual. Below we use glXGetFBConfigs instead of glXChooseFBConfig to enumerate the fb configurations - * because this call lists both types of formats instead of only onscreen ones. */ cfgs = pglXGetFBConfigs(display, DefaultScreen(display), &nCfgs); if (NULL == cfgs || 0 == nCfgs) { ERR("glXChooseFBConfig returns NULL\n"); @@ -847,48 +840,50 @@ static BOOL init_formats(Display *display, int screen, Visual *visual) return FALSE; }
- /* Count the number of offscreen formats to determine the size for our pixelformat list */ - for(i=0; i<nCfgs; i++) { - pglXGetFBConfigAttrib(display, cfgs[i], GLX_FBCONFIG_ID, &tmp_fmt_id); + WineGLPixelFormatList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nCfgs*sizeof(WineGLPixelFormat));
- visinfo = pglXGetVisualFromFBConfig(display, cfgs[i]); - /* Onscreen formats have a corresponding XVisual, offscreen ones don't */ - if(!visinfo) { - nOffscreenFormats++; - } else if(visinfo && visinfo->visualid == visualid) { + /* Fill the pixel format list. Put onscreen formats at the top and offscreen ones at the bottom. + * Do this as GLX doesn't guarantee that the list is sorted */ + for(run=0; run < 2; run++) + { + for(i=0; i<nCfgs; i++) { pglXGetFBConfigAttrib(display, cfgs[i], GLX_FBCONFIG_ID, &fmt_id); - fbconfig = cfgs[i]; - XFree(visinfo); - } - } - TRACE("Number of offscreen formats: %d\n", nOffscreenFormats); - - /* Allocate memory for all the offscreen pixelformats and the format of Wine's main visual */ - WineGLPixelFormatList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (1+nOffscreenFormats)*sizeof(WineGLPixelFormat)); - WineGLPixelFormatList[0].iPixelFormat = 1; - WineGLPixelFormatList[0].fbconfig = fbconfig; - WineGLPixelFormatList[0].fmt_id = fmt_id; - WineGLPixelFormatList[0].render_type = get_render_type_from_fbconfig(display, fbconfig); - WineGLPixelFormatList[0].offscreenOnly = FALSE; - WineGLPixelFormatListSize = 1; - WineGLPixelFormatOnScreenSize = 1; - - /* Fill the list with offscreen formats */ - for(i=0; i<nCfgs; i++) { - pglXGetFBConfigAttrib(display, cfgs[i], GLX_FBCONFIG_ID, &tmp_fmt_id); - - visinfo = pglXGetVisualFromFBConfig(display, cfgs[i]); - /* We have found an offscreen rendering format when there is no visualinfo :) */ - if(!visinfo) { - TRACE("Found offscreen format FBCONFIG_ID 0x%x corresponding to iPixelFormat %d at GLX index %d\n", tmp_fmt_id, WineGLPixelFormatListSize+1, i); - WineGLPixelFormatList[WineGLPixelFormatListSize].iPixelFormat = WineGLPixelFormatListSize+1; /* The index starts at 1 */ - WineGLPixelFormatList[WineGLPixelFormatListSize].fbconfig = cfgs[i]; - WineGLPixelFormatList[WineGLPixelFormatListSize].fmt_id = tmp_fmt_id; - WineGLPixelFormatList[WineGLPixelFormatListSize].render_type = get_render_type_from_fbconfig(display, cfgs[i]); - WineGLPixelFormatList[WineGLPixelFormatListSize].offscreenOnly = TRUE; - WineGLPixelFormatListSize++; - } else { - XFree(visinfo); + visinfo = pglXGetVisualFromFBConfig(display, cfgs[i]); + + /* The first run we only add onscreen formats (ones which have an associated X Visual). + * The second run we only set offscreen formats. */ + if(!run && visinfo) + { + /* We implement child window rendering using offscreen buffers (using composite or an XPixmap). + * The contents is copied to the destination using XCopyArea. For the copying to work + * the depth of the source and destination window should be the same. In general this should + * not be a problem for OpenGL as drivers only advertise formats with a similar depth (or no depth). + * As of the introduction of composition managers at least Nvidia now also offers ARGB visuals + * with a depth of 32 in addition to the default 24 bit. In order to prevent BadMatch errors we only + * list formats with the same depth. */ + if(visinfo->depth != screen_depth) + continue; + + TRACE("Found onscreen format FBCONFIG_ID 0x%x corresponding to iPixelFormat %d at GLX index %d\n", fmt_id, WineGLPixelFormatListSize+1, i); + WineGLPixelFormatList[WineGLPixelFormatListSize].iPixelFormat = WineGLPixelFormatListSize+1; /* The index starts at 1 */ + WineGLPixelFormatList[WineGLPixelFormatListSize].fbconfig = cfgs[i]; + WineGLPixelFormatList[WineGLPixelFormatListSize].fmt_id = fmt_id; + WineGLPixelFormatList[WineGLPixelFormatListSize].render_type = get_render_type_from_fbconfig(display, cfgs[i]); + + WineGLPixelFormatList[WineGLPixelFormatListSize].offscreenOnly = FALSE; + WineGLPixelFormatListSize++; + WineGLPixelFormatOnScreenSize++; + XFree(visinfo); + } else if(run && !visinfo) { + TRACE("Found offscreen format FBCONFIG_ID 0x%x corresponding to iPixelFormat %d at GLX index %d\n", fmt_id, WineGLPixelFormatListSize+1, i); + WineGLPixelFormatList[WineGLPixelFormatListSize].iPixelFormat = WineGLPixelFormatListSize+1; /* The index starts at 1 */ + WineGLPixelFormatList[WineGLPixelFormatListSize].fbconfig = cfgs[i]; + WineGLPixelFormatList[WineGLPixelFormatListSize].fmt_id = fmt_id; + WineGLPixelFormatList[WineGLPixelFormatListSize].render_type = get_render_type_from_fbconfig(display, cfgs[i]); + + WineGLPixelFormatList[WineGLPixelFormatListSize].offscreenOnly = TRUE; + WineGLPixelFormatListSize++; + } } }