winex11: Implement refcounting of GL drawables.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
eebdb457bf
commit
6dc30a2ed3
|
@ -253,6 +253,7 @@ enum dc_gl_type
|
||||||
|
|
||||||
struct gl_drawable
|
struct gl_drawable
|
||||||
{
|
{
|
||||||
|
LONG ref; /* reference count */
|
||||||
enum dc_gl_type type; /* type of GL surface */
|
enum dc_gl_type type; /* type of GL surface */
|
||||||
GLXDrawable drawable; /* drawable for rendering with GL */
|
GLXDrawable drawable; /* drawable for rendering with GL */
|
||||||
Window window; /* window if drawable is a GLXWindow */
|
Window window; /* window if drawable is a GLXWindow */
|
||||||
|
@ -1215,27 +1216,57 @@ static const struct wgl_pixel_format *get_pixel_format(Display *display, int iPi
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct gl_drawable *grab_gl_drawable( struct gl_drawable *gl )
|
||||||
|
{
|
||||||
|
InterlockedIncrement( &gl->ref );
|
||||||
|
return gl;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void release_gl_drawable( struct gl_drawable *gl )
|
||||||
|
{
|
||||||
|
if (!gl) return;
|
||||||
|
if (InterlockedDecrement( &gl->ref )) return;
|
||||||
|
switch (gl->type)
|
||||||
|
{
|
||||||
|
case DC_GL_CHILD_WIN:
|
||||||
|
pglXDestroyWindow( gdi_display, gl->drawable );
|
||||||
|
XDestroyWindow( gdi_display, gl->window );
|
||||||
|
XFreeColormap( gdi_display, gl->colormap );
|
||||||
|
break;
|
||||||
|
case DC_GL_PIXMAP_WIN:
|
||||||
|
pglXDestroyPixmap( gdi_display, gl->drawable );
|
||||||
|
XFreePixmap( gdi_display, gl->pixmap );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
HeapFree( GetProcessHeap(), 0, gl );
|
||||||
|
}
|
||||||
|
|
||||||
/* Mark any allocated context using the glx drawable 'old' to use 'new' */
|
/* Mark any allocated context using the glx drawable 'old' to use 'new' */
|
||||||
static void mark_drawable_dirty(GLXDrawable old, GLXDrawable new)
|
static void mark_drawable_dirty( struct gl_drawable *old, struct gl_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->drawable == ctx->drawables[0]) {
|
||||||
ctx->drawables[0] = new;
|
ctx->drawables[0] = new->drawable;
|
||||||
ctx->refresh_drawables = TRUE;
|
ctx->refresh_drawables = TRUE;
|
||||||
}
|
}
|
||||||
if (old == ctx->drawables[1]) {
|
if (old->drawable == ctx->drawables[1]) {
|
||||||
ctx->drawables[1] = new;
|
ctx->drawables[1] = new->drawable;
|
||||||
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 */
|
||||||
static inline void sync_context(struct wgl_context *context)
|
static inline void sync_context(struct wgl_context *context)
|
||||||
{
|
{
|
||||||
|
EnterCriticalSection( &context_section );
|
||||||
if (context->refresh_drawables) {
|
if (context->refresh_drawables) {
|
||||||
if (glxRequireVersion(3))
|
if (glxRequireVersion(3))
|
||||||
pglXMakeContextCurrent(gdi_display, context->drawables[0],
|
pglXMakeContextCurrent(gdi_display, context->drawables[0],
|
||||||
|
@ -1244,6 +1275,7 @@ static inline void sync_context(struct wgl_context *context)
|
||||||
pglXMakeCurrent(gdi_display, context->drawables[0], context->ctx);
|
pglXMakeCurrent(gdi_display, context->drawables[0], context->ctx);
|
||||||
context->refresh_drawables = FALSE;
|
context->refresh_drawables = FALSE;
|
||||||
}
|
}
|
||||||
|
LeaveCriticalSection( &context_section );
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL set_swap_interval(GLXDrawable drawable, int interval)
|
static BOOL set_swap_interval(GLXDrawable drawable, int interval)
|
||||||
|
@ -1288,15 +1320,14 @@ static struct gl_drawable *get_gl_drawable( HWND hwnd, HDC hdc )
|
||||||
struct gl_drawable *gl;
|
struct gl_drawable *gl;
|
||||||
|
|
||||||
EnterCriticalSection( &context_section );
|
EnterCriticalSection( &context_section );
|
||||||
if (hwnd && !XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl )) return gl;
|
if (hwnd && !XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl ))
|
||||||
if (hdc && !XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl )) return gl;
|
gl = grab_gl_drawable( gl );
|
||||||
|
else if (hdc && !XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl ))
|
||||||
|
gl = grab_gl_drawable( gl );
|
||||||
|
else
|
||||||
|
gl = NULL;
|
||||||
LeaveCriticalSection( &context_section );
|
LeaveCriticalSection( &context_section );
|
||||||
return NULL;
|
return gl;
|
||||||
}
|
|
||||||
|
|
||||||
static void release_gl_drawable( struct gl_drawable *gl )
|
|
||||||
{
|
|
||||||
if (gl) LeaveCriticalSection( &context_section );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLXContext create_glxcontext(Display *display, struct wgl_context *context, GLXContext shareList)
|
static GLXContext create_glxcontext(Display *display, struct wgl_context *context, GLXContext shareList)
|
||||||
|
@ -1319,35 +1350,13 @@ static GLXContext create_glxcontext(Display *display, struct wgl_context *contex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* free_gl_drawable
|
|
||||||
*/
|
|
||||||
static void free_gl_drawable( struct gl_drawable *gl )
|
|
||||||
{
|
|
||||||
switch (gl->type)
|
|
||||||
{
|
|
||||||
case DC_GL_CHILD_WIN:
|
|
||||||
pglXDestroyWindow( gdi_display, gl->drawable );
|
|
||||||
XDestroyWindow( gdi_display, gl->window );
|
|
||||||
XFreeColormap( gdi_display, gl->colormap );
|
|
||||||
break;
|
|
||||||
case DC_GL_PIXMAP_WIN:
|
|
||||||
pglXDestroyPixmap( gdi_display, gl->drawable );
|
|
||||||
XFreePixmap( gdi_display, gl->pixmap );
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
HeapFree( GetProcessHeap(), 0, gl );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* create_gl_drawable
|
* create_gl_drawable
|
||||||
*/
|
*/
|
||||||
static BOOL create_gl_drawable( HWND hwnd, struct gl_drawable *gl )
|
static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct wgl_pixel_format *format )
|
||||||
{
|
{
|
||||||
XVisualInfo *visual = gl->format->visual;
|
struct gl_drawable *gl, *prev;
|
||||||
|
XVisualInfo *visual = format->visual;
|
||||||
RECT rect;
|
RECT rect;
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|
||||||
|
@ -1355,7 +1364,15 @@ static BOOL create_gl_drawable( HWND hwnd, struct gl_drawable *gl )
|
||||||
width = min( max( 1, rect.right ), 65535 );
|
width = min( max( 1, rect.right ), 65535 );
|
||||||
height = min( max( 1, rect.bottom ), 65535 );
|
height = min( max( 1, rect.bottom ), 65535 );
|
||||||
|
|
||||||
gl->drawable = 0;
|
if (!(gl = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*gl) ))) return NULL;
|
||||||
|
|
||||||
|
/* Default GLX and WGL swap interval is 1, but in case of glXSwapIntervalSGI
|
||||||
|
* there is no way to query it, so we have to store it here.
|
||||||
|
*/
|
||||||
|
gl->swap_interval = 1;
|
||||||
|
gl->refresh_swap_interval = TRUE;
|
||||||
|
gl->format = format;
|
||||||
|
gl->ref = 1;
|
||||||
|
|
||||||
if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow()) /* top-level window */
|
if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow()) /* top-level window */
|
||||||
{
|
{
|
||||||
|
@ -1425,9 +1442,21 @@ static BOOL create_gl_drawable( HWND hwnd, struct gl_drawable *gl )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gl->drawable)
|
if (!gl->drawable)
|
||||||
gl->refresh_swap_interval = TRUE;
|
{
|
||||||
return gl->drawable != 0;
|
HeapFree( GetProcessHeap(), 0, gl );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnterCriticalSection( &context_section );
|
||||||
|
if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&prev ))
|
||||||
|
{
|
||||||
|
gl->swap_interval = prev->swap_interval;
|
||||||
|
release_gl_drawable( prev );
|
||||||
|
}
|
||||||
|
XSaveContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char *)grab_gl_drawable(gl) );
|
||||||
|
LeaveCriticalSection( &context_section );
|
||||||
|
return gl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1436,37 +1465,17 @@ static BOOL create_gl_drawable( HWND hwnd, struct gl_drawable *gl )
|
||||||
*/
|
*/
|
||||||
static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format )
|
static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format )
|
||||||
{
|
{
|
||||||
struct gl_drawable *gl, *prev;
|
struct gl_drawable *gl;
|
||||||
|
|
||||||
if (!format->visual) return FALSE;
|
if (!format->visual) return FALSE;
|
||||||
|
|
||||||
gl = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*gl) );
|
if (!(gl = create_gl_drawable( hwnd, format ))) return FALSE;
|
||||||
/* Default GLX and WGL swap interval is 1, but in case of glXSwapIntervalSGI
|
|
||||||
* there is no way to query it, so we have to store it here.
|
|
||||||
*/
|
|
||||||
gl->swap_interval = 1;
|
|
||||||
gl->refresh_swap_interval = TRUE;
|
|
||||||
gl->format = format;
|
|
||||||
|
|
||||||
if (!create_gl_drawable( hwnd, gl ))
|
|
||||||
{
|
|
||||||
HeapFree( GetProcessHeap(), 0, gl );
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE( "created GL drawable %lx for win %p %s\n",
|
TRACE( "created GL drawable %lx for win %p %s\n",
|
||||||
gl->drawable, hwnd, debugstr_fbconfig( format->fbconfig ));
|
gl->drawable, hwnd, debugstr_fbconfig( format->fbconfig ));
|
||||||
|
|
||||||
XFlush( gdi_display );
|
XFlush( gdi_display );
|
||||||
|
release_gl_drawable( gl );
|
||||||
EnterCriticalSection( &context_section );
|
|
||||||
if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&prev ))
|
|
||||||
{
|
|
||||||
gl->swap_interval = prev->swap_interval;
|
|
||||||
free_gl_drawable( prev );
|
|
||||||
}
|
|
||||||
XSaveContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char *)gl );
|
|
||||||
LeaveCriticalSection( &context_section );
|
|
||||||
|
|
||||||
__wine_set_pixel_format( hwnd, pixel_format_index( format ));
|
__wine_set_pixel_format( hwnd, pixel_format_index( format ));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1521,50 +1530,31 @@ static BOOL set_pixel_format(HDC hdc, int format, BOOL allow_change)
|
||||||
*/
|
*/
|
||||||
void sync_gl_drawable( HWND hwnd, int width, int height )
|
void sync_gl_drawable( HWND hwnd, int width, int height )
|
||||||
{
|
{
|
||||||
struct gl_drawable *gl;
|
struct gl_drawable *old, *new;
|
||||||
GLXDrawable glxp;
|
|
||||||
Pixmap pix;
|
|
||||||
XWindowChanges changes;
|
XWindowChanges changes;
|
||||||
|
|
||||||
changes.width = min( max( 1, width ), 65535 );
|
if (!(old = get_gl_drawable( hwnd, 0 ))) return;
|
||||||
changes.height = min( max( 1, height ), 65535 );
|
|
||||||
|
|
||||||
if (!(gl = get_gl_drawable( hwnd, 0 ))) return;
|
TRACE( "setting drawable %lx size %dx%d\n", old->drawable, width, height );
|
||||||
|
|
||||||
TRACE( "setting drawable %lx size %dx%d\n", gl->drawable, changes.width, changes.height );
|
switch (old->type)
|
||||||
|
|
||||||
switch (gl->type)
|
|
||||||
{
|
{
|
||||||
case DC_GL_CHILD_WIN:
|
case DC_GL_CHILD_WIN:
|
||||||
XConfigureWindow( gdi_display, gl->window, CWWidth | CWHeight, &changes );
|
changes.width = min( max( 1, width ), 65535 );
|
||||||
|
changes.height = min( max( 1, height ), 65535 );
|
||||||
|
XConfigureWindow( gdi_display, old->window, CWWidth | CWHeight, &changes );
|
||||||
break;
|
break;
|
||||||
case DC_GL_PIXMAP_WIN:
|
case DC_GL_PIXMAP_WIN:
|
||||||
pix = XCreatePixmap(gdi_display, root_window, changes.width, changes.height,
|
if (!(new = create_gl_drawable( hwnd, old->format ))) break;
|
||||||
gl->format->visual->depth);
|
mark_drawable_dirty( old, new );
|
||||||
if (!pix) goto done;
|
|
||||||
glxp = pglXCreatePixmap(gdi_display, gl->format->fbconfig, pix, NULL );
|
|
||||||
if (!glxp)
|
|
||||||
{
|
|
||||||
XFreePixmap(gdi_display, pix);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
mark_drawable_dirty(gl->drawable, glxp);
|
|
||||||
XFlush( gdi_display );
|
XFlush( gdi_display );
|
||||||
|
TRACE( "Recreated GL drawable %lx to replace %lx\n", new->drawable, old->drawable );
|
||||||
XFreePixmap(gdi_display, gl->pixmap);
|
release_gl_drawable( new );
|
||||||
pglXDestroyPixmap(gdi_display, gl->drawable);
|
|
||||||
TRACE( "Recreated GL drawable %lx to replace %lx\n", glxp, gl->drawable );
|
|
||||||
|
|
||||||
gl->pixmap = pix;
|
|
||||||
gl->drawable = glxp;
|
|
||||||
gl->pixmap_size.cx = width;
|
|
||||||
gl->pixmap_size.cy = height;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
done:
|
release_gl_drawable( old );
|
||||||
release_gl_drawable( gl );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1573,46 +1563,36 @@ done:
|
||||||
*/
|
*/
|
||||||
void set_gl_drawable_parent( HWND hwnd, HWND parent )
|
void set_gl_drawable_parent( HWND hwnd, HWND parent )
|
||||||
{
|
{
|
||||||
struct gl_drawable *gl;
|
struct gl_drawable *old, *new;
|
||||||
GLXDrawable old_drawable;
|
|
||||||
|
|
||||||
if (!(gl = get_gl_drawable( hwnd, 0 ))) return;
|
if (!(old = get_gl_drawable( hwnd, 0 ))) return;
|
||||||
|
|
||||||
TRACE( "setting drawable %lx parent %p\n", gl->drawable, parent );
|
TRACE( "setting drawable %lx parent %p\n", old->drawable, parent );
|
||||||
|
|
||||||
old_drawable = gl->drawable;
|
switch (old->type)
|
||||||
switch (gl->type)
|
|
||||||
{
|
{
|
||||||
case DC_GL_WINDOW:
|
case DC_GL_WINDOW:
|
||||||
break;
|
break;
|
||||||
case DC_GL_CHILD_WIN:
|
case DC_GL_CHILD_WIN:
|
||||||
if (parent != GetDesktopWindow()) goto done;
|
|
||||||
pglXDestroyWindow( gdi_display, gl->drawable );
|
|
||||||
XDestroyWindow( gdi_display, gl->window );
|
|
||||||
XFreeColormap( gdi_display, gl->colormap );
|
|
||||||
break;
|
|
||||||
case DC_GL_PIXMAP_WIN:
|
case DC_GL_PIXMAP_WIN:
|
||||||
if (parent != GetDesktopWindow()) goto done;
|
if (parent == GetDesktopWindow()) break;
|
||||||
pglXDestroyPixmap( gdi_display, gl->drawable );
|
/* fall through */
|
||||||
XFreePixmap( gdi_display, gl->pixmap );
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
goto done;
|
release_gl_drawable( old );
|
||||||
}
|
|
||||||
|
|
||||||
if (!create_gl_drawable( hwnd, gl ))
|
|
||||||
{
|
|
||||||
XDeleteContext( gdi_display, (XID)hwnd, gl_hwnd_context );
|
|
||||||
release_gl_drawable( gl );
|
|
||||||
HeapFree( GetProcessHeap(), 0, gl );
|
|
||||||
__wine_set_pixel_format( hwnd, 0 );
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mark_drawable_dirty( old_drawable, gl->drawable );
|
|
||||||
|
|
||||||
done:
|
|
||||||
release_gl_drawable( gl );
|
|
||||||
|
|
||||||
|
if ((new = create_gl_drawable( hwnd, old->format )))
|
||||||
|
{
|
||||||
|
mark_drawable_dirty( old, new );
|
||||||
|
release_gl_drawable( new );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
destroy_gl_drawable( hwnd );
|
||||||
|
__wine_set_pixel_format( hwnd, 0 );
|
||||||
|
}
|
||||||
|
release_gl_drawable( old );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1627,7 +1607,7 @@ void destroy_gl_drawable( HWND hwnd )
|
||||||
if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl ))
|
if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl ))
|
||||||
{
|
{
|
||||||
XDeleteContext( gdi_display, (XID)hwnd, gl_hwnd_context );
|
XDeleteContext( gdi_display, (XID)hwnd, gl_hwnd_context );
|
||||||
free_gl_drawable( gl );
|
release_gl_drawable( gl );
|
||||||
}
|
}
|
||||||
LeaveCriticalSection( &context_section );
|
LeaveCriticalSection( &context_section );
|
||||||
}
|
}
|
||||||
|
@ -1827,7 +1807,9 @@ static struct wgl_context *glxdrv_wglCreateContext( HDC hdc )
|
||||||
ret->hdc = hdc;
|
ret->hdc = hdc;
|
||||||
ret->fmt = gl->format;
|
ret->fmt = gl->format;
|
||||||
ret->ctx = create_glxcontext(gdi_display, ret, NULL);
|
ret->ctx = create_glxcontext(gdi_display, ret, NULL);
|
||||||
|
EnterCriticalSection( &context_section );
|
||||||
list_add_head( &context_list, &ret->entry );
|
list_add_head( &context_list, &ret->entry );
|
||||||
|
LeaveCriticalSection( &context_section );
|
||||||
}
|
}
|
||||||
release_gl_drawable( gl );
|
release_gl_drawable( gl );
|
||||||
TRACE( "%p -> %p\n", hdc, ret );
|
TRACE( "%p -> %p\n", hdc, ret );
|
||||||
|
@ -1896,6 +1878,7 @@ static BOOL glxdrv_wglMakeCurrent(HDC hdc, struct wgl_context *ctx)
|
||||||
TRACE("hdc %p drawable %lx fmt %p ctx %p %s\n", hdc, gl->drawable, gl->format, ctx->ctx,
|
TRACE("hdc %p drawable %lx fmt %p ctx %p %s\n", hdc, gl->drawable, gl->format, ctx->ctx,
|
||||||
debugstr_fbconfig( gl->format->fbconfig ));
|
debugstr_fbconfig( gl->format->fbconfig ));
|
||||||
|
|
||||||
|
EnterCriticalSection( &context_section );
|
||||||
ret = pglXMakeCurrent(gdi_display, gl->drawable, ctx->ctx);
|
ret = pglXMakeCurrent(gdi_display, gl->drawable, ctx->ctx);
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
|
@ -1905,8 +1888,10 @@ static BOOL glxdrv_wglMakeCurrent(HDC hdc, struct wgl_context *ctx)
|
||||||
ctx->drawables[0] = gl->drawable;
|
ctx->drawables[0] = gl->drawable;
|
||||||
ctx->drawables[1] = gl->drawable;
|
ctx->drawables[1] = gl->drawable;
|
||||||
ctx->refresh_drawables = FALSE;
|
ctx->refresh_drawables = FALSE;
|
||||||
|
LeaveCriticalSection( &context_section );
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
LeaveCriticalSection( &context_section );
|
||||||
}
|
}
|
||||||
SetLastError( ERROR_INVALID_HANDLE );
|
SetLastError( ERROR_INVALID_HANDLE );
|
||||||
|
|
||||||
|
@ -1938,6 +1923,8 @@ static BOOL X11DRV_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct
|
||||||
if ((draw_gl = get_gl_drawable( WindowFromDC( draw_hdc ), draw_hdc )))
|
if ((draw_gl = get_gl_drawable( WindowFromDC( draw_hdc ), draw_hdc )))
|
||||||
{
|
{
|
||||||
read_gl = get_gl_drawable( WindowFromDC( read_hdc ), read_hdc );
|
read_gl = get_gl_drawable( WindowFromDC( read_hdc ), read_hdc );
|
||||||
|
|
||||||
|
EnterCriticalSection( &context_section );
|
||||||
ret = pglXMakeContextCurrent(gdi_display, draw_gl->drawable,
|
ret = pglXMakeContextCurrent(gdi_display, draw_gl->drawable,
|
||||||
read_gl ? read_gl->drawable : 0, ctx->ctx);
|
read_gl ? read_gl->drawable : 0, ctx->ctx);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -1948,8 +1935,10 @@ static BOOL X11DRV_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct
|
||||||
ctx->drawables[1] = read_gl ? read_gl->drawable : 0;
|
ctx->drawables[1] = read_gl ? read_gl->drawable : 0;
|
||||||
ctx->refresh_drawables = FALSE;
|
ctx->refresh_drawables = FALSE;
|
||||||
NtCurrentTeb()->glContext = ctx;
|
NtCurrentTeb()->glContext = ctx;
|
||||||
|
LeaveCriticalSection( &context_section );
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
LeaveCriticalSection( &context_section );
|
||||||
}
|
}
|
||||||
SetLastError( ERROR_INVALID_HANDLE );
|
SetLastError( ERROR_INVALID_HANDLE );
|
||||||
done:
|
done:
|
||||||
|
@ -2148,7 +2137,12 @@ static struct wgl_context *X11DRV_wglCreateContextAttribsARB( HDC hdc, struct wg
|
||||||
HeapFree( GetProcessHeap(), 0, ret );
|
HeapFree( GetProcessHeap(), 0, ret );
|
||||||
ret = NULL;
|
ret = NULL;
|
||||||
}
|
}
|
||||||
else list_add_head( &context_list, &ret->entry );
|
else
|
||||||
|
{
|
||||||
|
EnterCriticalSection( &context_section );
|
||||||
|
list_add_head( &context_list, &ret->entry );
|
||||||
|
LeaveCriticalSection( &context_section );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
release_gl_drawable( gl );
|
release_gl_drawable( gl );
|
||||||
|
@ -2394,10 +2388,11 @@ static HDC X11DRV_wglGetPbufferDCARB( struct wgl_pbuffer *object )
|
||||||
gl->type = DC_GL_PBUFFER;
|
gl->type = DC_GL_PBUFFER;
|
||||||
gl->drawable = object->drawable;
|
gl->drawable = object->drawable;
|
||||||
gl->format = object->fmt;
|
gl->format = object->fmt;
|
||||||
|
gl->ref = 1;
|
||||||
|
|
||||||
EnterCriticalSection( &context_section );
|
EnterCriticalSection( &context_section );
|
||||||
if (!XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&prev ))
|
if (!XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&prev ))
|
||||||
free_gl_drawable( prev );
|
release_gl_drawable( prev );
|
||||||
XSaveContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char *)gl );
|
XSaveContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char *)gl );
|
||||||
LeaveCriticalSection( &context_section );
|
LeaveCriticalSection( &context_section );
|
||||||
|
|
||||||
|
@ -2516,7 +2511,7 @@ static int X11DRV_wglReleasePbufferDCARB( struct wgl_pbuffer *object, HDC hdc )
|
||||||
if (!XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl ))
|
if (!XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl ))
|
||||||
{
|
{
|
||||||
XDeleteContext( gdi_display, (XID)hdc, gl_pbuffer_context );
|
XDeleteContext( gdi_display, (XID)hdc, gl_pbuffer_context );
|
||||||
free_gl_drawable( gl );
|
release_gl_drawable( gl );
|
||||||
}
|
}
|
||||||
else hdc = 0;
|
else hdc = 0;
|
||||||
|
|
||||||
|
@ -3100,6 +3095,7 @@ static BOOL X11DRV_wglSwapIntervalEXT(int interval)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EnterCriticalSection( &context_section );
|
||||||
ret = set_swap_interval(gl->drawable, interval);
|
ret = set_swap_interval(gl->drawable, interval);
|
||||||
gl->refresh_swap_interval = FALSE;
|
gl->refresh_swap_interval = FALSE;
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -3107,6 +3103,7 @@ static BOOL X11DRV_wglSwapIntervalEXT(int interval)
|
||||||
else
|
else
|
||||||
SetLastError(ERROR_DC_NOT_FOUND);
|
SetLastError(ERROR_DC_NOT_FOUND);
|
||||||
|
|
||||||
|
LeaveCriticalSection( &context_section );
|
||||||
release_gl_drawable(gl);
|
release_gl_drawable(gl);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -3325,11 +3322,13 @@ static BOOL glxdrv_wglSwapBuffers( HDC hdc )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EnterCriticalSection( &context_section );
|
||||||
if (gl->refresh_swap_interval)
|
if (gl->refresh_swap_interval)
|
||||||
{
|
{
|
||||||
set_swap_interval(gl->drawable, gl->swap_interval);
|
set_swap_interval(gl->drawable, gl->swap_interval);
|
||||||
gl->refresh_swap_interval = FALSE;
|
gl->refresh_swap_interval = FALSE;
|
||||||
}
|
}
|
||||||
|
LeaveCriticalSection( &context_section );
|
||||||
|
|
||||||
switch (gl->type)
|
switch (gl->type)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue