- Always use a double-buffered visual if one is available.

- Ensure that all colormaps created use the double-buffered visual if
  it exists. This prevents problems where DRI GL implementations fail
  to work unless the colormap visual matches the window visual matches the
  glX visual.
- Get around similar visual issue with the default GL context created for
  apps that don't create their own contexts before trying to use GL functions.
This commit is contained in:
Gavriel State 2001-03-28 01:45:08 +00:00 committed by Alexandre Julliard
parent 219353be4e
commit 4d73ba6e21
4 changed files with 77 additions and 42 deletions

View File

@ -78,6 +78,8 @@ HGLRC WINAPI wglCreateContext(HDC hdc) {
X11DRV_PDEVICE *physDev; X11DRV_PDEVICE *physDev;
XVisualInfo *vis; XVisualInfo *vis;
Wine_GLContext *ret; Wine_GLContext *ret;
int num;
XVisualInfo template;
TRACE("(%08x)\n", hdc); TRACE("(%08x)\n", hdc);
@ -88,8 +90,9 @@ HGLRC WINAPI wglCreateContext(HDC hdc) {
physDev = (X11DRV_PDEVICE *)dc->physDev; physDev = (X11DRV_PDEVICE *)dc->physDev;
/* First, get the visual for the choosen pixel format */ /* First, get the visual in use by the X11DRV */
vis = physDev->visuals[physDev->current_pf - 1]; template.visualid = XVisualIDFromVisual(X11DRV_GetVisual());
vis = XGetVisualInfo(display, VisualIDMask, &template, &num);
if (vis == NULL) { if (vis == NULL) {
ERR("NULL visual !!!\n"); ERR("NULL visual !!!\n");
@ -299,7 +302,7 @@ void* WINAPI wglGetProcAddress(LPCSTR lpszProc) {
return ret->func; return ret->func;
} else { } else {
ERR("Extension defined in the OpenGL library but NOT in opengl_ext.c... Please report (lionel.ulmer@free.fr) !\n"); ERR("Extension %s defined in the OpenGL library but NOT in opengl_ext.c... Please report (lionel.ulmer@free.fr) !\n", lpszProc);
return NULL; return NULL;
} }
} }
@ -458,6 +461,8 @@ BOOL WINAPI wglUseFontOutlinesA(HDC hdc,
/* This is for brain-dead applications that use OpenGL functions before even /* This is for brain-dead applications that use OpenGL functions before even
creating a rendering context.... */ creating a rendering context.... */
static void process_attach(void) { static void process_attach(void) {
XWindowAttributes win_attr;
Visual *rootVisual;
int num; int num;
XVisualInfo template; XVisualInfo template;
XVisualInfo *vis = NULL; XVisualInfo *vis = NULL;
@ -468,7 +473,24 @@ static void process_attach(void) {
} }
ENTER_GL(); ENTER_GL();
template.visualid = XVisualIDFromVisual(visual);
/* Try to get the visual from the Root Window. We can't use the standard (presumably
double buffered) X11DRV visual with the Root Window, since we don't know if the Root
Window was created using the standard X11DRV visual, and glXMakeCurrent can't deal
with mismatched visuals. Note that the Root Window visual may not be double
buffered, so apps actually attempting to render this way may flicker */
if (TSXGetWindowAttributes( display, X11DRV_GetXRootWindow(), &win_attr ))
{
rootVisual = win_attr.visual;
}
else
{
/* Get the default visual, since we can't seem to get the attributes from the
Root Window. Let's hope that the Root Window Visual matches the DefaultVisual */
rootVisual = DefaultVisual( display, DefaultScreen(display) );
}
template.visualid = XVisualIDFromVisual(rootVisual);
vis = XGetVisualInfo(display, VisualIDMask, &template, &num); vis = XGetVisualInfo(display, VisualIDMask, &template, &num);
if (vis != NULL) default_cx = glXCreateContext(display, vis, 0, GL_TRUE); if (vis != NULL) default_cx = glXCreateContext(display, vis, 0, GL_TRUE);
if (default_cx != NULL) glXMakeCurrent(display, X11DRV_GetXRootWindow(), default_cx); if (default_cx != NULL) glXMakeCurrent(display, X11DRV_GetXRootWindow(), default_cx);

View File

@ -192,6 +192,37 @@ static void setup_options(void)
} }
/***********************************************************************
* setup_opengl_visual
*
* Setup the default visual used for OpenGL and Direct3D, and the desktop
* window (if it exists). If OpenGL isn't available, the visual is simply
* set to the default visual for the display
*/
XVisualInfo *desktop_vi = NULL;
#ifdef HAVE_OPENGL
static void setup_opengl_visual( void )
{
int err_base, evt_base;
/* In order to support OpenGL or D3D, we require a double-buffered
* visual */
if (glXQueryExtension(display, &err_base, &evt_base) == True) {
int dblBuf[]={GLX_RGBA,GLX_DEPTH_SIZE,16,GLX_DOUBLEBUFFER,None};
ENTER_GL();
desktop_vi = glXChooseVisual(display, DefaultScreen(display), dblBuf);
LEAVE_GL();
}
if (desktop_vi != NULL) {
visual = desktop_vi->visual;
screen = ScreenOfDisplay(display, desktop_vi->screen);
screen_depth = desktop_vi->depth;
}
}
#endif /* HAVE_OPENGL */
/*********************************************************************** /***********************************************************************
* create_desktop * create_desktop
* *
@ -208,27 +239,6 @@ static void create_desktop( const char *geometry )
XSetWindowAttributes win_attr; XSetWindowAttributes win_attr;
XTextProperty window_name; XTextProperty window_name;
Atom XA_WM_DELETE_WINDOW; Atom XA_WM_DELETE_WINDOW;
/* Used to create the desktop window with a good visual */
XVisualInfo *vi = NULL;
#ifdef HAVE_OPENGL
BOOL dblbuf_visual;
int err_base, evt_base;
/* Get in wine.ini if the desktop window should have a double-buffered visual or not.
But first, test if OpenGL is even supported on the display ! */
if (glXQueryExtension(display, &err_base, &evt_base) == True) {
dblbuf_visual = PROFILE_GetWineIniBool( "x11drv", "DesktopDoubleBuffered", 0 );
if (dblbuf_visual) {
int dblBuf[]={GLX_RGBA,GLX_DEPTH_SIZE,16,GLX_DOUBLEBUFFER,None};
ENTER_GL();
vi = glXChooseVisual(display, DefaultScreen(display), dblBuf);
win_attr.colormap = XCreateColormap(display, RootWindow(display,vi->screen),
vi->visual, AllocNone);
LEAVE_GL();
}
}
#endif /* HAVE_OPENGL */
flags = TSXParseGeometry( geometry, &x, &y, &width, &height ); flags = TSXParseGeometry( geometry, &x, &y, &width, &height );
screen_width = width; screen_width = width;
@ -241,18 +251,17 @@ static void create_desktop( const char *geometry )
ButtonReleaseMask | EnterWindowMask; ButtonReleaseMask | EnterWindowMask;
win_attr.cursor = TSXCreateFontCursor( display, XC_top_left_arrow ); win_attr.cursor = TSXCreateFontCursor( display, XC_top_left_arrow );
if (vi != NULL) { if (desktop_vi != NULL) {
visual = vi->visual; win_attr.colormap = XCreateColormap(display, RootWindow(display,desktop_vi->screen),
screen = ScreenOfDisplay(display, vi->screen); desktop_vi->visual, AllocNone);
screen_depth = vi->depth;
} }
root_window = TSXCreateWindow( display, root_window = TSXCreateWindow( display,
(vi == NULL ? DefaultRootWindow(display) : RootWindow(display, vi->screen)), (desktop_vi == NULL ? DefaultRootWindow(display) : RootWindow(display, desktop_vi->screen)),
x, y, width, height, 0, x, y, width, height, 0,
(vi == NULL ? CopyFromParent : vi->depth), (desktop_vi == NULL ? CopyFromParent : desktop_vi->depth),
InputOutput, InputOutput,
(vi == NULL ? CopyFromParent : vi->visual), (desktop_vi == NULL ? CopyFromParent : desktop_vi->visual),
CWBackPixel | CWEventMask | CWCursor | (vi == NULL ? 0 : CWColormap), CWBackPixel | CWEventMask | CWCursor | (desktop_vi == NULL ? 0 : CWColormap),
&win_attr ); &win_attr );
/* Set window manager properties */ /* Set window manager properties */
@ -342,6 +351,11 @@ static void process_attach(void)
} }
else screen_depth = DefaultDepthOfScreen( screen ); else screen_depth = DefaultDepthOfScreen( screen );
/* If OpenGL is available, change the default visual, etc as necessary */
#ifdef HAVE_OPENGL
setup_opengl_visual();
#endif /* HAVE_OPENGL */
/* tell the libX11 that we will do input method handling ourselves /* tell the libX11 that we will do input method handling ourselves
* that keep libX11 from doing anything whith dead keys, allowing Wine * that keep libX11 from doing anything whith dead keys, allowing Wine
* to have total control over dead keys, that is this line allows * to have total control over dead keys, that is this line allows

View File

@ -139,11 +139,11 @@ BOOL X11DRV_PALETTE_Init(void)
break; break;
} }
} }
X11DRV_PALETTE_PaletteXColormap = DefaultColormapOfScreen( X11DRV_GetXScreen() ); X11DRV_PALETTE_PaletteXColormap = TSXCreateColormap(display, X11DRV_GetXRootWindow(), visual, AllocNone);
break; break;
case StaticGray: case StaticGray:
X11DRV_PALETTE_PaletteXColormap = DefaultColormapOfScreen( X11DRV_GetXScreen() ); X11DRV_PALETTE_PaletteXColormap = TSXCreateColormap(display, X11DRV_GetXRootWindow(), visual, AllocNone);
X11DRV_PALETTE_PaletteFlags |= X11DRV_PALETTE_FIXED; X11DRV_PALETTE_PaletteFlags |= X11DRV_PALETTE_FIXED;
X11DRV_PALETTE_Graymax = (1 << X11DRV_GetDepth())-1; X11DRV_PALETTE_Graymax = (1 << X11DRV_GetDepth())-1;
break; break;
@ -161,18 +161,18 @@ BOOL X11DRV_PALETTE_Init(void)
for( white = X11DRV_DevCaps.sizePalette - 1; !(white & 1); white >>= 1 ) for( white = X11DRV_DevCaps.sizePalette - 1; !(white & 1); white >>= 1 )
monoPlane++; monoPlane++;
X11DRV_PALETTE_PaletteFlags = (white & mask) ? X11DRV_PALETTE_WHITESET : 0; X11DRV_PALETTE_PaletteFlags = (white & mask) ? X11DRV_PALETTE_WHITESET : 0;
X11DRV_PALETTE_PaletteXColormap = DefaultColormapOfScreen( X11DRV_GetXScreen() ); X11DRV_PALETTE_PaletteXColormap = TSXCreateColormap(display, X11DRV_GetXRootWindow(), visual, AllocNone);
TSXFree(depths); TSXFree(depths);
break; break;
} }
TSXFree(depths); TSXFree(depths);
X11DRV_PALETTE_PaletteXColormap = DefaultColormapOfScreen( X11DRV_GetXScreen() ); X11DRV_PALETTE_PaletteXColormap = TSXCreateColormap(display, X11DRV_GetXRootWindow(), visual, AllocNone);
X11DRV_PALETTE_PaletteFlags |= X11DRV_PALETTE_FIXED; X11DRV_PALETTE_PaletteFlags |= X11DRV_PALETTE_FIXED;
X11DRV_PALETTE_ComputeShifts(visual->red_mask, &X11DRV_PALETTE_Redshift, &X11DRV_PALETTE_Redmax); X11DRV_PALETTE_ComputeShifts(visual->red_mask, &X11DRV_PALETTE_Redshift, &X11DRV_PALETTE_Redmax);
X11DRV_PALETTE_ComputeShifts(visual->green_mask, &X11DRV_PALETTE_Greenshift, &X11DRV_PALETTE_Greenmax); X11DRV_PALETTE_ComputeShifts(visual->green_mask, &X11DRV_PALETTE_Greenshift, &X11DRV_PALETTE_Greenmax);
X11DRV_PALETTE_ComputeShifts(visual->blue_mask, &X11DRV_PALETTE_Blueshift, &X11DRV_PALETTE_Bluemax); X11DRV_PALETTE_ComputeShifts(visual->blue_mask, &X11DRV_PALETTE_Blueshift, &X11DRV_PALETTE_Bluemax);
break; break;
} }
} }
TRACE(" visual class %i (%i)\n", visual->class, monoPlane); TRACE(" visual class %i (%i)\n", visual->class, monoPlane);

View File

@ -349,17 +349,16 @@ BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CREATESTRUCTA *cs, BOOL bUnicode)
if (cs->cx <= 0) cs->cx = 1; if (cs->cx <= 0) cs->cx = 1;
if (cs->cy <= 0) cs->cy = 1; if (cs->cy <= 0) cs->cy = 1;
((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window =
TSXCreateWindow( display, X11DRV_GetXRootWindow(), TSXCreateWindow( display, X11DRV_GetXRootWindow(),
cs->x, cs->y, cs->cx, cs->cy, cs->x, cs->y, cs->cx, cs->cy,
0, CopyFromParent, 0, screen_depth,
InputOutput, CopyFromParent, InputOutput, visual,
CWEventMask | CWOverrideRedirect | CWEventMask | CWOverrideRedirect |
CWColormap | CWCursor | CWSaveUnder | CWColormap | CWCursor | CWSaveUnder |
CWBackingStore | CWBitGravity, CWBackingStore | CWBitGravity,
&win_attr ); &win_attr );
if(!(wGroupLeader = X11DRV_WND_GetXWindow(wndPtr))) if(!(wGroupLeader = X11DRV_WND_GetXWindow(wndPtr)))
return FALSE; return FALSE;