winex11: Move the GL drawable management to opengl.c.

This commit is contained in:
Alexandre Julliard 2012-08-31 12:22:03 +02:00
parent ef034e71e2
commit 9f042298f7
4 changed files with 272 additions and 290 deletions

View File

@ -47,6 +47,7 @@
#undef WINGDIAPI #undef WINGDIAPI
#include "x11drv.h" #include "x11drv.h"
#include "xcomposite.h"
#include "winternl.h" #include "winternl.h"
#include "wine/library.h" #include "wine/library.h"
#include "wine/debug.h" #include "wine/debug.h"
@ -172,6 +173,15 @@ struct wgl_pbuffer
int texture_level; int texture_level;
}; };
enum dc_gl_type
{
DC_GL_NONE, /* no GL support (pixel format not set yet) */
DC_GL_WINDOW, /* normal top-level window */
DC_GL_CHILD_WIN, /* child window using XComposite */
DC_GL_PIXMAP_WIN, /* child window using intermediate pixmap */
DC_GL_PBUFFER /* pseudo memory DC using a PBuffer */
};
struct glx_physdev struct glx_physdev
{ {
struct gdi_physdev dev; struct gdi_physdev dev;
@ -182,6 +192,19 @@ struct glx_physdev
Pixmap pixmap; /* pixmap for a DL_GL_PIXMAP_WIN drawable */ Pixmap pixmap; /* pixmap for a DL_GL_PIXMAP_WIN drawable */
}; };
struct gl_drawable
{
enum dc_gl_type type; /* type of GL surface */
Drawable drawable; /* drawable for rendering to the client area */
Pixmap pixmap; /* base pixmap if drawable is a GLXPixmap */
Colormap colormap; /* colormap used for the drawable */
int pixel_format; /* pixel format for the drawable */
XVisualInfo *visual; /* information about the GL visual */
};
/* X context to associate a struct gl_drawable to an hwnd */
static XContext gl_drawable_context;
static const struct gdi_dc_funcs glxdrv_funcs; static const struct gdi_dc_funcs glxdrv_funcs;
static inline struct glx_physdev *get_glxdrv_dev( PHYSDEV dev ) static inline struct glx_physdev *get_glxdrv_dev( PHYSDEV dev )
@ -568,6 +591,7 @@ static BOOL has_opengl(void)
ERR( "GLX extension is missing, disabling OpenGL.\n" ); ERR( "GLX extension is missing, disabling OpenGL.\n" );
goto failed; goto failed;
} }
gl_drawable_context = XUniqueContext();
/* In case of GLX you have direct and indirect rendering. Most of the time direct rendering is used /* In case of GLX you have direct and indirect rendering. Most of the time direct rendering is used
* as in general only that is hardware accelerated. In some cases like in case of remote X indirect * as in general only that is hardware accelerated. In some cases like in case of remote X indirect
@ -1060,11 +1084,10 @@ static int pixelformat_from_fbconfig_id(XID fbconfig_id)
/* Mark any allocated context using the glx drawable 'old' to use 'new' */ /* Mark any allocated context using the glx drawable 'old' to use 'new' */
void mark_drawable_dirty(Drawable old, Drawable new) static void mark_drawable_dirty(Drawable old, Drawable new)
{ {
struct wgl_context *ctx; struct wgl_context *ctx;
EnterCriticalSection( &context_section );
LIST_FOR_EACH_ENTRY( ctx, &context_list, struct wgl_context, entry ) LIST_FOR_EACH_ENTRY( ctx, &context_list, struct wgl_context, entry )
{ {
if (old == ctx->drawables[0]) { if (old == ctx->drawables[0]) {
@ -1076,7 +1099,6 @@ void mark_drawable_dirty(Drawable old, Drawable new)
ctx->refresh_drawables = TRUE; ctx->refresh_drawables = TRUE;
} }
} }
LeaveCriticalSection( &context_section );
} }
/* Given the current context, make sure its drawable is sync'd */ /* Given the current context, make sure its drawable is sync'd */
@ -1118,9 +1140,213 @@ static GLXContext create_glxcontext(Display *display, struct wgl_context *contex
} }
Drawable create_glxpixmap(Display *display, XVisualInfo *vis, Pixmap parent) /***********************************************************************
* free_gl_drawable
*/
static void free_gl_drawable( struct gl_drawable *gl )
{ {
return pglXCreateGLXPixmap(display, vis, parent); switch (gl->type)
{
case DC_GL_WINDOW:
case DC_GL_CHILD_WIN:
XDestroyWindow( gdi_display, gl->drawable );
XFreeColormap( gdi_display, gl->colormap );
break;
case DC_GL_PIXMAP_WIN:
pglXDestroyGLXPixmap( gdi_display, gl->drawable );
XFreePixmap( gdi_display, gl->pixmap );
break;
default:
break;
}
XFree( gl->visual );
HeapFree( GetProcessHeap(), 0, gl );
}
/***********************************************************************
* set_win_format
*/
BOOL set_win_format( HWND hwnd, XID fbconfig_id )
{
XSetWindowAttributes attrib;
struct x11drv_win_data *data;
struct gl_drawable *gl, *prev;
int format, w, h;
if (!(format = pixelformat_from_fbconfig_id( fbconfig_id ))) return FALSE;
if (!(data = X11DRV_get_win_data(hwnd)) &&
!(data = X11DRV_create_win_data(hwnd))) return FALSE;
gl = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*gl) );
gl->pixel_format = format;
gl->visual = pglXGetVisualFromFBConfig( gdi_display, pixel_formats[format - 1].fbconfig );
if (!gl->visual)
{
HeapFree( GetProcessHeap(), 0, gl );
return FALSE;
}
w = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 );
h = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 );
if (data->whole_window)
{
gl->type = DC_GL_WINDOW;
gl->colormap = XCreateColormap( gdi_display, root_window, gl->visual->visual,
(gl->visual->class == PseudoColor ||
gl->visual->class == GrayScale ||
gl->visual->class == DirectColor) ? AllocAll : AllocNone );
attrib.colormap = gl->colormap;
attrib.bit_gravity = NorthWestGravity;
attrib.win_gravity = NorthWestGravity;
attrib.backing_store = NotUseful;
gl->drawable = XCreateWindow( gdi_display, data->whole_window,
data->client_rect.left - data->whole_rect.left,
data->client_rect.top - data->whole_rect.top,
w, h, 0, screen_depth, InputOutput, gl->visual->visual,
CWBitGravity | CWWinGravity | CWBackingStore | CWColormap,
&attrib );
if (gl->drawable)
XMapWindow( gdi_display, gl->drawable );
else
XFreeColormap( gdi_display, gl->colormap );
}
#ifdef SONAME_LIBXCOMPOSITE
else if(usexcomposite)
{
static Window dummy_parent;
attrib.override_redirect = True;
if (!dummy_parent)
{
dummy_parent = XCreateWindow( gdi_display, root_window, -1, -1, 1, 1, 0, screen_depth,
InputOutput, visual, CWOverrideRedirect, &attrib );
XMapWindow( gdi_display, dummy_parent );
}
gl->colormap = XCreateColormap(gdi_display, dummy_parent, gl->visual->visual,
(gl->visual->class == PseudoColor ||
gl->visual->class == GrayScale ||
gl->visual->class == DirectColor) ?
AllocAll : AllocNone);
attrib.colormap = gl->colormap;
XInstallColormap(gdi_display, attrib.colormap);
gl->type = DC_GL_CHILD_WIN;
gl->drawable = XCreateWindow( gdi_display, dummy_parent, 0, 0, w, h, 0,
gl->visual->depth, InputOutput, gl->visual->visual,
CWColormap | CWOverrideRedirect, &attrib );
if (gl->drawable)
{
pXCompositeRedirectWindow(gdi_display, gl->drawable, CompositeRedirectManual);
XMapWindow(gdi_display, gl->drawable);
}
else XFreeColormap( gdi_display, gl->colormap );
}
#endif
else
{
WARN("XComposite is not available, using GLXPixmap hack\n");
gl->type = DC_GL_PIXMAP_WIN;
gl->pixmap = XCreatePixmap(gdi_display, root_window, w, h, gl->visual->depth);
if (gl->pixmap)
{
gl->drawable = pglXCreateGLXPixmap( gdi_display, gl->visual, gl->pixmap );
if (!gl->drawable) XFreePixmap( gdi_display, gl->pixmap );
}
}
if (!gl->drawable)
{
XFree( gl->visual );
HeapFree( GetProcessHeap(), 0, gl );
return FALSE;
}
TRACE("Created GL drawable 0x%lx, using FBConfigID 0x%lx\n", gl->drawable, fbconfig_id);
XFlush( gdi_display );
EnterCriticalSection( &context_section );
if (!XFindContext( gdi_display, (XID)hwnd, gl_drawable_context, (char **)&prev ))
free_gl_drawable( prev );
XSaveContext( gdi_display, (XID)hwnd, gl_drawable_context, (char *)gl );
LeaveCriticalSection( &context_section );
/* force DCE invalidation */
SetWindowPos( hwnd, 0, 0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE |
SWP_NOREDRAW | SWP_DEFERERASE | SWP_NOSENDCHANGING | SWP_STATECHANGED);
return TRUE;
}
/***********************************************************************
* sync_gl_drawable
*/
void sync_gl_drawable( HWND hwnd, int mask, XWindowChanges *changes )
{
struct gl_drawable *gl;
Drawable glxp;
Pixmap pix;
EnterCriticalSection( &context_section );
if (XFindContext( gdi_display, (XID)hwnd, gl_drawable_context, (char **)&gl )) goto done;
TRACE( "setting drawable %lx pos %d,%d,%dx%d changes=%x\n",
gl->drawable, changes->x, changes->y, changes->width, changes->height, mask );
switch (gl->type)
{
case DC_GL_CHILD_WIN:
if (!(mask &= CWWidth | CWHeight)) break;
/* fall through */
case DC_GL_WINDOW:
XConfigureWindow( gdi_display, gl->drawable, mask, changes );
break;
case DC_GL_PIXMAP_WIN:
pix = XCreatePixmap(gdi_display, root_window, changes->width, changes->height, gl->visual->depth);
if (!pix) goto done;
glxp = pglXCreateGLXPixmap(gdi_display, gl->visual, pix);
if (!glxp)
{
XFreePixmap(gdi_display, pix);
goto done;
}
mark_drawable_dirty(gl->drawable, glxp);
XFlush( gdi_display );
XFreePixmap(gdi_display, gl->pixmap);
pglXDestroyGLXPixmap(gdi_display, gl->drawable);
TRACE( "Recreated GL drawable %lx to replace %lx\n", glxp, gl->drawable );
gl->pixmap = pix;
gl->drawable = glxp;
break;
default:
break;
}
done:
LeaveCriticalSection( &context_section );
}
/***********************************************************************
* destroy_gl_drawable
*/
void destroy_gl_drawable( HWND hwnd )
{
struct gl_drawable *gl;
EnterCriticalSection( &context_section );
if (!XFindContext( gdi_display, (XID)hwnd, gl_drawable_context, (char **)&gl ))
{
XDeleteContext( gdi_display, (XID)hwnd, gl_drawable_context );
free_gl_drawable( gl );
}
LeaveCriticalSection( &context_section );
} }
@ -1969,13 +2195,11 @@ static HDC X11DRV_wglGetPbufferDCARB( struct wgl_pbuffer *object )
if (!hdc) return 0; if (!hdc) return 0;
escape.code = X11DRV_SET_DRAWABLE; escape.code = X11DRV_SET_DRAWABLE;
escape.hwnd = 0;
escape.drawable = object->drawable; escape.drawable = object->drawable;
escape.mode = IncludeInferiors; escape.mode = IncludeInferiors;
SetRect( &escape.dc_rect, 0, 0, object->width, object->height ); SetRect( &escape.dc_rect, 0, 0, object->width, object->height );
escape.fbconfig_id = object->fmt->fmt_id; escape.fbconfig_id = object->fmt->fmt_id;
escape.gl_drawable = object->drawable;
escape.pixmap = 0;
escape.gl_type = DC_GL_PBUFFER;
ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL ); ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL );
TRACE( "(%p)->(%p)\n", object, hdc ); TRACE( "(%p)->(%p)\n", object, hdc );
@ -2804,12 +3028,6 @@ static void X11DRV_WineGL_LoadExtensions(void)
} }
BOOL destroy_glxpixmap(Display *display, XID glxpixmap)
{
pglXDestroyGLXPixmap(display, glxpixmap);
return TRUE;
}
/** /**
* glxdrv_SwapBuffers * glxdrv_SwapBuffers
* *
@ -2882,14 +3100,6 @@ static BOOL glxdrv_SwapBuffers(PHYSDEV dev)
return TRUE; return TRUE;
} }
XVisualInfo *visual_from_fbconfig_id( XID fbconfig_id )
{
int format = pixelformat_from_fbconfig_id( fbconfig_id );
if (!format) return NULL;
return pglXGetVisualFromFBConfig(gdi_display, pixel_formats[format - 1].fbconfig);
}
static BOOL create_glx_dc( PHYSDEV *pdev ) static BOOL create_glx_dc( PHYSDEV *pdev )
{ {
/* assume that only the main x11 device implements GetDeviceCaps */ /* assume that only the main x11 device implements GetDeviceCaps */
@ -2952,11 +3162,35 @@ static INT glxdrv_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID in_d
case X11DRV_SET_DRAWABLE: case X11DRV_SET_DRAWABLE:
if (in_count >= sizeof(struct x11drv_escape_set_drawable)) if (in_count >= sizeof(struct x11drv_escape_set_drawable))
{ {
struct gl_drawable *gl;
const struct x11drv_escape_set_drawable *data = in_data; const struct x11drv_escape_set_drawable *data = in_data;
physdev->pixel_format = pixelformat_from_fbconfig_id( data->fbconfig_id );
physdev->type = data->gl_type; if (!data->hwnd) /* pbuffer */
physdev->drawable = data->gl_drawable; {
physdev->pixmap = data->pixmap; physdev->pixel_format = pixelformat_from_fbconfig_id( data->fbconfig_id );
physdev->type = DC_GL_PBUFFER;
physdev->drawable = data->drawable;
physdev->pixmap = 0;
}
else
{
EnterCriticalSection( &context_section );
if (!XFindContext( gdi_display, (XID)data->hwnd, gl_drawable_context, (char **)&gl ))
{
physdev->pixel_format = gl->pixel_format;
physdev->type = gl->type;
physdev->drawable = gl->drawable;
physdev->pixmap = gl->pixmap;
}
else
{
physdev->pixel_format = 0;
physdev->type = DC_GL_NONE;
physdev->drawable = 0;
physdev->pixmap = 0;
}
LeaveCriticalSection( &context_section );
}
TRACE( "SET_DRAWABLE hdc %p drawable %lx pf %u type %u\n", TRACE( "SET_DRAWABLE hdc %p drawable %lx pf %u type %u\n",
dev->hdc, physdev->drawable, physdev->pixel_format, physdev->type ); dev->hdc, physdev->drawable, physdev->pixel_format, physdev->type );
} }
@ -2966,9 +3200,7 @@ static INT glxdrv_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID in_d
{ {
struct x11drv_escape_get_drawable *data = out_data; struct x11drv_escape_get_drawable *data = out_data;
data->pixel_format = physdev->pixel_format; data->pixel_format = physdev->pixel_format;
data->gl_type = physdev->type;
data->gl_drawable = physdev->drawable; data->gl_drawable = physdev->drawable;
data->pixmap = physdev->pixmap;
} }
break; break;
case X11DRV_FLUSH_GL_DRAWABLE: case X11DRV_FLUSH_GL_DRAWABLE:
@ -3158,24 +3390,17 @@ const struct gdi_dc_funcs *get_glx_driver(void)
return NULL; return NULL;
} }
void mark_drawable_dirty(Drawable old, Drawable new) BOOL set_win_format( HWND hwnd, XID fbconfig_id )
{
}
Drawable create_glxpixmap(Display *display, XVisualInfo *vis, Pixmap parent)
{
return 0;
}
BOOL destroy_glxpixmap(Display *display, XID glxpixmap)
{ {
return FALSE; return FALSE;
} }
XVisualInfo *visual_from_fbconfig_id( XID fbconfig_id ) void sync_gl_drawable( HWND hwnd, int mask, XWindowChanges *changes )
{
}
void destroy_gl_drawable( HWND hwnd )
{ {
return NULL;
} }
#endif /* defined(SONAME_LIBGL) */ #endif /* defined(SONAME_LIBGL) */

View File

@ -43,7 +43,6 @@
#include "wine/unicode.h" #include "wine/unicode.h"
#include "x11drv.h" #include "x11drv.h"
#include "xcomposite.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "wine/server.h" #include "wine/server.h"
#include "mwm.h" #include "mwm.h"
@ -77,9 +76,6 @@ XContext winContext = 0;
/* X context to associate a struct x11drv_win_data to an hwnd */ /* X context to associate a struct x11drv_win_data to an hwnd */
XContext win_data_context = 0; XContext win_data_context = 0;
/* X context to associate a struct gl_drawable to an hwnd */
XContext gl_drawable_context = 0;
/* time of last user event and window where it's stored */ /* time of last user event and window where it's stored */
static Time last_user_time; static Time last_user_time;
static Window user_time_window; static Window user_time_window;
@ -90,16 +86,6 @@ static const char icon_window_prop[] = "__wine_x11_icon_window";
static const char clip_window_prop[] = "__wine_x11_clip_window"; static const char clip_window_prop[] = "__wine_x11_clip_window";
static const char managed_prop[] = "__wine_x11_managed"; static const char managed_prop[] = "__wine_x11_managed";
struct gl_drawable
{
enum dc_gl_type type; /* type of GL surface */
Drawable drawable; /* drawable for rendering to the client area */
Pixmap pixmap; /* base pixmap if drawable is a GLXPixmap */
Colormap colormap; /* colormap used for the drawable */
XID fbconfig_id; /* fbconfig for the drawable */
XVisualInfo *visual; /* information about the GL visual */
};
/*********************************************************************** /***********************************************************************
* http://standards.freedesktop.org/startup-notification-spec * http://standards.freedesktop.org/startup-notification-spec
@ -462,204 +448,6 @@ static void sync_window_text( Display *display, Window win, const WCHAR *text )
} }
/***********************************************************************
* free_gl_drawable
*/
static void free_gl_drawable( struct gl_drawable *gl )
{
switch (gl->type)
{
case DC_GL_WINDOW:
case DC_GL_CHILD_WIN:
XDestroyWindow( gdi_display, gl->drawable );
XFreeColormap( gdi_display, gl->colormap );
break;
case DC_GL_PIXMAP_WIN:
destroy_glxpixmap( gdi_display, gl->drawable );
XFreePixmap( gdi_display, gl->pixmap );
break;
default:
break;
}
XFree( gl->visual );
HeapFree( GetProcessHeap(), 0, gl );
}
/***********************************************************************
* set_win_format
*/
static BOOL set_win_format( HWND hwnd, XID fbconfig_id )
{
XSetWindowAttributes attrib;
struct x11drv_win_data *data;
struct gl_drawable *gl, *prev;
int w, h;
if (!(data = X11DRV_get_win_data(hwnd)) &&
!(data = X11DRV_create_win_data(hwnd))) return FALSE;
gl = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*gl) );
gl->fbconfig_id = fbconfig_id;
if (!(gl->visual = visual_from_fbconfig_id( fbconfig_id )))
{
HeapFree( GetProcessHeap(), 0, gl );
return FALSE;
}
w = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 );
h = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 );
if (data->whole_window)
{
gl->type = DC_GL_WINDOW;
gl->colormap = XCreateColormap( gdi_display, root_window, gl->visual->visual,
(gl->visual->class == PseudoColor ||
gl->visual->class == GrayScale ||
gl->visual->class == DirectColor) ? AllocAll : AllocNone );
attrib.colormap = gl->colormap;
attrib.bit_gravity = NorthWestGravity;
attrib.win_gravity = NorthWestGravity;
attrib.backing_store = NotUseful;
gl->drawable = XCreateWindow( gdi_display, data->whole_window,
data->client_rect.left - data->whole_rect.left,
data->client_rect.top - data->whole_rect.top,
w, h, 0, screen_depth, InputOutput, gl->visual->visual,
CWBitGravity | CWWinGravity | CWBackingStore | CWColormap,
&attrib );
if (gl->drawable)
XMapWindow( gdi_display, gl->drawable );
else
XFreeColormap( gdi_display, gl->colormap );
}
#ifdef SONAME_LIBXCOMPOSITE
else if(usexcomposite)
{
static Window dummy_parent;
attrib.override_redirect = True;
if (!dummy_parent)
{
dummy_parent = XCreateWindow( gdi_display, root_window, -1, -1, 1, 1, 0, screen_depth,
InputOutput, visual, CWOverrideRedirect, &attrib );
XMapWindow( gdi_display, dummy_parent );
}
gl->colormap = XCreateColormap(gdi_display, dummy_parent, gl->visual->visual,
(gl->visual->class == PseudoColor ||
gl->visual->class == GrayScale ||
gl->visual->class == DirectColor) ?
AllocAll : AllocNone);
attrib.colormap = gl->colormap;
XInstallColormap(gdi_display, attrib.colormap);
gl->type = DC_GL_CHILD_WIN;
gl->drawable = XCreateWindow( gdi_display, dummy_parent, 0, 0, w, h, 0,
gl->visual->depth, InputOutput, gl->visual->visual,
CWColormap | CWOverrideRedirect, &attrib );
if (gl->drawable)
{
pXCompositeRedirectWindow(gdi_display, gl->drawable, CompositeRedirectManual);
XMapWindow(gdi_display, gl->drawable);
}
else XFreeColormap( gdi_display, gl->colormap );
}
#endif
else
{
WARN("XComposite is not available, using GLXPixmap hack\n");
gl->type = DC_GL_PIXMAP_WIN;
gl->pixmap = XCreatePixmap(gdi_display, root_window, w, h, gl->visual->depth);
if (gl->pixmap)
{
gl->drawable = create_glxpixmap( gdi_display, gl->visual, gl->pixmap );
if (!gl->drawable) XFreePixmap( gdi_display, gl->pixmap );
XFlush( gdi_display );
}
}
if (!gl->drawable)
{
XFree( gl->visual );
HeapFree( GetProcessHeap(), 0, gl );
return FALSE;
}
TRACE("Created GL drawable 0x%lx, using FBConfigID 0x%lx\n", gl->drawable, fbconfig_id);
if (!XFindContext( gdi_display, (XID)hwnd, gl_drawable_context, (char **)&prev ))
free_gl_drawable( prev );
XSaveContext( gdi_display, (XID)hwnd, gl_drawable_context, (char *)gl );
XFlush( gdi_display );
/* force DCE invalidation */
SetWindowPos( hwnd, 0, 0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE |
SWP_NOREDRAW | SWP_DEFERERASE | SWP_NOSENDCHANGING | SWP_STATECHANGED);
return TRUE;
}
/***********************************************************************
* sync_gl_drawable
*/
static void sync_gl_drawable( HWND hwnd, int mask, XWindowChanges *changes )
{
struct gl_drawable *gl;
Drawable glxp;
Pixmap pix;
if (XFindContext( gdi_display, (XID)hwnd, gl_drawable_context, (char **)&gl )) return;
TRACE( "setting drawable %lx pos %d,%d,%dx%d changes=%x\n",
gl->drawable, changes->x, changes->y, changes->width, changes->height, mask );
switch (gl->type)
{
case DC_GL_CHILD_WIN:
if (!(mask &= CWWidth | CWHeight)) break;
/* fall through */
case DC_GL_WINDOW:
XConfigureWindow( gdi_display, gl->drawable, mask, changes );
break;
case DC_GL_PIXMAP_WIN:
pix = XCreatePixmap(gdi_display, root_window, changes->width, changes->height, gl->visual->depth);
if(!pix) return;
glxp = create_glxpixmap(gdi_display, gl->visual, pix);
if(!glxp)
{
XFreePixmap(gdi_display, pix);
return;
}
mark_drawable_dirty(gl->drawable, glxp);
XFreePixmap(gdi_display, gl->pixmap);
destroy_glxpixmap(gdi_display, gl->drawable);
TRACE( "Recreated GL drawable %lx to replace %lx\n", glxp, gl->drawable );
gl->pixmap = pix;
gl->drawable = glxp;
break;
default:
return;
}
XFlush( gdi_display );
}
/***********************************************************************
* destroy_gl_drawable
*/
static void destroy_gl_drawable( HWND hwnd )
{
struct gl_drawable *gl;
if (XFindContext( gdi_display, (XID)hwnd, gl_drawable_context, (char **)&gl )) return;
XDeleteContext( gdi_display, (XID)hwnd, gl_drawable_context );
free_gl_drawable( gl );
}
/*********************************************************************** /***********************************************************************
* get_window_changes * get_window_changes
* *
@ -2123,16 +1911,12 @@ void CDECL X11DRV_GetDC( HDC hdc, HWND hwnd, HWND top, const RECT *win_rect,
{ {
struct x11drv_escape_set_drawable escape; struct x11drv_escape_set_drawable escape;
struct x11drv_win_data *data = X11DRV_get_win_data( hwnd ); struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
struct gl_drawable *gl;
HWND parent; HWND parent;
escape.code = X11DRV_SET_DRAWABLE; escape.code = X11DRV_SET_DRAWABLE;
escape.hwnd = hwnd;
escape.mode = IncludeInferiors; escape.mode = IncludeInferiors;
escape.fbconfig_id = 0; escape.fbconfig_id = 0;
escape.gl_drawable = 0;
escape.pixmap = 0;
escape.gl_type = DC_GL_NONE;
escape.dc_rect.left = win_rect->left - top_rect->left; escape.dc_rect.left = win_rect->left - top_rect->left;
escape.dc_rect.top = win_rect->top - top_rect->top; escape.dc_rect.top = win_rect->top - top_rect->top;
@ -2167,14 +1951,6 @@ void CDECL X11DRV_GetDC( HDC hdc, HWND hwnd, HWND top, const RECT *win_rect,
else escape.drawable = X11DRV_get_whole_window( top ); else escape.drawable = X11DRV_get_whole_window( top );
} }
if (!XFindContext( gdi_display, (XID)hwnd, gl_drawable_context, (char **)&gl ))
{
escape.fbconfig_id = gl->fbconfig_id;
escape.gl_drawable = gl->drawable;
escape.pixmap = gl->pixmap;
escape.gl_type = gl->type;
}
ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL ); ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL );
} }
@ -2187,15 +1963,13 @@ void CDECL X11DRV_ReleaseDC( HWND hwnd, HDC hdc )
struct x11drv_escape_set_drawable escape; struct x11drv_escape_set_drawable escape;
escape.code = X11DRV_SET_DRAWABLE; escape.code = X11DRV_SET_DRAWABLE;
escape.hwnd = GetDesktopWindow();
escape.drawable = root_window; escape.drawable = root_window;
escape.mode = IncludeInferiors; escape.mode = IncludeInferiors;
SetRect( &escape.dc_rect, 0, 0, virtual_screen_rect.right - virtual_screen_rect.left, SetRect( &escape.dc_rect, 0, 0, virtual_screen_rect.right - virtual_screen_rect.left,
virtual_screen_rect.bottom - virtual_screen_rect.top ); virtual_screen_rect.bottom - virtual_screen_rect.top );
OffsetRect( &escape.dc_rect, -virtual_screen_rect.left, -virtual_screen_rect.top ); OffsetRect( &escape.dc_rect, -virtual_screen_rect.left, -virtual_screen_rect.top );
escape.fbconfig_id = 0; escape.fbconfig_id = 0;
escape.gl_drawable = 0;
escape.pixmap = 0;
escape.gl_type = DC_GL_NONE;
ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL ); ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL );
} }

View File

@ -98,15 +98,6 @@ typedef struct
ChannelShift logicalRed, logicalGreen, logicalBlue; ChannelShift logicalRed, logicalGreen, logicalBlue;
} ColorShifts; } ColorShifts;
enum dc_gl_type
{
DC_GL_NONE, /* no GL support (pixel format not set yet) */
DC_GL_WINDOW, /* normal top-level window */
DC_GL_CHILD_WIN, /* child window using XComposite */
DC_GL_PIXMAP_WIN, /* child window using intermediate pixmap */
DC_GL_PBUFFER /* pseudo memory DC using a PBuffer */
};
/* X physical device */ /* X physical device */
typedef struct typedef struct
{ {
@ -220,7 +211,6 @@ extern int client_side_antialias_with_render DECLSPEC_HIDDEN;
extern const struct gdi_dc_funcs *X11DRV_XRender_Init(void) DECLSPEC_HIDDEN; extern const struct gdi_dc_funcs *X11DRV_XRender_Init(void) DECLSPEC_HIDDEN;
extern const struct gdi_dc_funcs *get_glx_driver(void) DECLSPEC_HIDDEN; extern const struct gdi_dc_funcs *get_glx_driver(void) DECLSPEC_HIDDEN;
extern BOOL destroy_glxpixmap(Display *display, XID glxpixmap) DECLSPEC_HIDDEN;
/* IME support */ /* IME support */
extern void IME_SetOpenStatus(BOOL fOpen) DECLSPEC_HIDDEN; extern void IME_SetOpenStatus(BOOL fOpen) DECLSPEC_HIDDEN;
@ -285,13 +275,11 @@ enum x11drv_escape_codes
struct x11drv_escape_set_drawable struct x11drv_escape_set_drawable
{ {
enum x11drv_escape_codes code; /* escape code (X11DRV_SET_DRAWABLE) */ enum x11drv_escape_codes code; /* escape code (X11DRV_SET_DRAWABLE) */
HWND hwnd; /* window for this drawable */
Drawable drawable; /* X drawable */ Drawable drawable; /* X drawable */
int mode; /* ClipByChildren or IncludeInferiors */ int mode; /* ClipByChildren or IncludeInferiors */
RECT dc_rect; /* DC rectangle relative to drawable */ RECT dc_rect; /* DC rectangle relative to drawable */
XID fbconfig_id; /* fbconfig id used by the GL drawable */ XID fbconfig_id; /* fbconfig id used by the GL drawable */
Drawable gl_drawable; /* GL drawable */
Pixmap pixmap; /* Pixmap for a GLXPixmap gl_drawable */
enum dc_gl_type gl_type; /* type of GL device context */
}; };
struct x11drv_escape_get_drawable struct x11drv_escape_get_drawable
@ -299,9 +287,7 @@ struct x11drv_escape_get_drawable
enum x11drv_escape_codes code; /* escape code (X11DRV_GET_DRAWABLE) */ enum x11drv_escape_codes code; /* escape code (X11DRV_GET_DRAWABLE) */
Drawable drawable; /* X drawable */ Drawable drawable; /* X drawable */
Drawable gl_drawable; /* GL drawable */ Drawable gl_drawable; /* GL drawable */
Pixmap pixmap; /* Pixmap for a GLXPixmap gl_drawable */
int pixel_format; /* internal GL pixel format */ int pixel_format; /* internal GL pixel format */
enum dc_gl_type gl_type; /* type of GL device context */
}; };
/************************************************************************** /**************************************************************************
@ -569,9 +555,9 @@ extern struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd ) DECLSPEC_HIDD
extern Window X11DRV_get_whole_window( HWND hwnd ) DECLSPEC_HIDDEN; extern Window X11DRV_get_whole_window( HWND hwnd ) DECLSPEC_HIDDEN;
extern XIC X11DRV_get_ic( HWND hwnd ) DECLSPEC_HIDDEN; extern XIC X11DRV_get_ic( HWND hwnd ) DECLSPEC_HIDDEN;
extern XVisualInfo *visual_from_fbconfig_id( XID fbconfig_id ) DECLSPEC_HIDDEN; extern BOOL set_win_format( HWND hwnd, XID fbconfig_id ) DECLSPEC_HIDDEN;
extern void mark_drawable_dirty( Drawable old, Drawable new ) DECLSPEC_HIDDEN; extern void sync_gl_drawable( HWND hwnd, int mask, XWindowChanges *changes ) DECLSPEC_HIDDEN;
extern Drawable create_glxpixmap( Display *display, XVisualInfo *vis, Pixmap parent ) DECLSPEC_HIDDEN; extern void destroy_gl_drawable( HWND hwnd ) DECLSPEC_HIDDEN;
extern void wait_for_withdrawn_state( Display *display, struct x11drv_win_data *data, BOOL set ) DECLSPEC_HIDDEN; extern void wait_for_withdrawn_state( Display *display, struct x11drv_win_data *data, BOOL set ) DECLSPEC_HIDDEN;
extern Window init_clip_window(void) DECLSPEC_HIDDEN; extern Window init_clip_window(void) DECLSPEC_HIDDEN;
@ -608,8 +594,6 @@ static inline BOOL is_window_rect_fullscreen( const RECT *rect )
extern XContext winContext DECLSPEC_HIDDEN; extern XContext winContext DECLSPEC_HIDDEN;
/* X context to associate a struct x11drv_win_data to an hwnd */ /* X context to associate a struct x11drv_win_data to an hwnd */
extern XContext win_data_context DECLSPEC_HIDDEN; extern XContext win_data_context DECLSPEC_HIDDEN;
/* X context to associate a struct gl_drawable to an hwnd */
extern XContext gl_drawable_context DECLSPEC_HIDDEN;
/* X context to associate an X cursor to a Win32 cursor handle */ /* X context to associate an X cursor to a Win32 cursor handle */
extern XContext cursor_context DECLSPEC_HIDDEN; extern XContext cursor_context DECLSPEC_HIDDEN;

View File

@ -539,7 +539,6 @@ static BOOL process_attach(void)
winContext = XUniqueContext(); winContext = XUniqueContext();
win_data_context = XUniqueContext(); win_data_context = XUniqueContext();
gl_drawable_context = XUniqueContext();
cursor_context = XUniqueContext(); cursor_context = XUniqueContext();
if (TRACE_ON(synchronous)) XSynchronize( display, True ); if (TRACE_ON(synchronous)) XSynchronize( display, True );