winex11.drv: Import glx makecurrent/wglsharelists.

This commit is contained in:
Roderick Colenbrander 2006-08-29 16:58:49 +02:00 committed by Alexandre Julliard
parent 9377c23eff
commit 2b36c4a4c3
3 changed files with 225 additions and 165 deletions

View File

@ -65,6 +65,10 @@ typedef struct wine_wgl_s {
HGLRC WINAPI (*p_wglGetCurrentContext)(void);
HDC WINAPI (*p_wglGetCurrentDC)(void);
HDC WINAPI (*p_wglGetCurrentReadDCARB)(void);
BOOL WINAPI (*p_wglMakeCurrent)(HDC hdc, HGLRC hglrc);
BOOL WINAPI (*p_wglMakeContextCurrentARB)(HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
BOOL WINAPI (*p_wglShareLists)(HGLRC hglrc1, HGLRC hglrc2);
void WINAPI (*p_wglGetIntegerv)(GLenum pname, GLint* params);
} wine_wgl_t;
@ -138,18 +142,6 @@ inline static Display *get_display( HDC hdc )
return display;
}
/* retrieve the GLX drawable to use on a given DC */
inline static Drawable get_drawable( HDC hdc )
{
GLXDrawable drawable;
enum x11drv_escape_codes escape = X11DRV_GET_GLX_DRAWABLE;
if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
sizeof(drawable), (LPSTR)&drawable )) drawable = 0;
return drawable;
}
/* retrieve the X font to use on a given DC */
inline static Font get_font( HDC hdc )
{
@ -424,105 +416,12 @@ PROC WINAPI wglGetProcAddress(LPCSTR lpszProc) {
}
}
static int describeContext(Wine_GLContext* ctx) {
int tmp;
int ctx_vis_id;
TRACE(" Context %p have (vis:%p):\n", ctx, ctx->vis);
wine_glx.p_glXGetFBConfigAttrib(ctx->display, ctx->fb_conf, GLX_FBCONFIG_ID, &tmp);
TRACE(" - FBCONFIG_ID 0x%x\n", tmp);
wine_glx.p_glXGetFBConfigAttrib(ctx->display, ctx->fb_conf, GLX_VISUAL_ID, &tmp);
TRACE(" - VISUAL_ID 0x%x\n", tmp);
ctx_vis_id = tmp;
return ctx_vis_id;
}
static int describeDrawable(Wine_GLContext* ctx, Drawable drawable) {
int tmp;
int nElements;
int attribList[3] = { GLX_FBCONFIG_ID, 0, None };
GLXFBConfig *fbCfgs;
if (wine_glx.p_glXQueryDrawable == NULL) {
/** glXQueryDrawable not available so returns not supported */
return -1;
}
TRACE(" Drawable %p have :\n", (void*) drawable);
wine_glx.p_glXQueryDrawable(ctx->display, drawable, GLX_WIDTH, (unsigned int*) &tmp);
TRACE(" - WIDTH as %d\n", tmp);
wine_glx.p_glXQueryDrawable(ctx->display, drawable, GLX_HEIGHT, (unsigned int*) &tmp);
TRACE(" - HEIGHT as %d\n", tmp);
wine_glx.p_glXQueryDrawable(ctx->display, drawable, GLX_FBCONFIG_ID, (unsigned int*) &tmp);
TRACE(" - FBCONFIG_ID as 0x%x\n", tmp);
attribList[1] = tmp;
fbCfgs = wine_glx.p_glXChooseFBConfig(ctx->display, DefaultScreen(ctx->display), attribList, &nElements);
if (fbCfgs == NULL) {
return -1;
}
wine_glx.p_glXGetFBConfigAttrib(ctx->display, fbCfgs[0], GLX_VISUAL_ID, &tmp);
TRACE(" - VISUAL_ID as 0x%x\n", tmp);
XFree(fbCfgs);
return tmp;
}
/***********************************************************************
* wglMakeCurrent (OPENGL32.@)
*/
BOOL WINAPI wglMakeCurrent(HDC hdc,
HGLRC hglrc) {
BOOL ret;
DWORD type = GetObjectType(hdc);
TRACE("(%p,%p)\n", hdc, hglrc);
ENTER_GL();
if (hglrc == NULL) {
ret = glXMakeCurrent(default_display, None, NULL);
NtCurrentTeb()->glContext = NULL;
} else {
Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
Drawable drawable = get_drawable( hdc );
if (ctx->ctx == NULL) {
int draw_vis_id, ctx_vis_id;
VisualID visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
TRACE(" Wine desktop VISUAL_ID is 0x%x\n", (unsigned int) visualid);
draw_vis_id = describeDrawable(ctx, drawable);
ctx_vis_id = describeContext(ctx);
if (-1 == draw_vis_id || (draw_vis_id == visualid && draw_vis_id != ctx_vis_id)) {
/**
* Inherits from root window so reuse desktop visual
*/
XVisualInfo template;
XVisualInfo *vis;
int num;
template.visualid = visualid;
vis = XGetVisualInfo(ctx->display, VisualIDMask, &template, &num);
TRACE(" Creating GLX Context\n");
ctx->ctx = glXCreateContext(ctx->display, vis, NULL, type == OBJ_MEMDC ? False : True);
} else {
TRACE(" Creating GLX Context\n");
ctx->ctx = glXCreateContext(ctx->display, ctx->vis, NULL, type == OBJ_MEMDC ? False : True);
}
TRACE(" created a delayed OpenGL context (%p)\n", ctx->ctx);
}
TRACE(" make current for dis %p, drawable %p, ctx %p\n", ctx->display, (void*) drawable, ctx->ctx);
ret = glXMakeCurrent(ctx->display, drawable, ctx->ctx);
NtCurrentTeb()->glContext = ctx;
if(ret && type == OBJ_MEMDC)
{
ctx->do_escape = TRUE;
glDrawBuffer(GL_FRONT_LEFT);
}
}
LEAVE_GL();
TRACE(" returning %s\n", (ret ? "True" : "False"));
return ret;
BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc) {
TRACE("hdc: (%p), hglrc: (%p)\n", hdc, hglrc);
return wine_wgl.p_wglMakeCurrent(hdc, hglrc);
}
/***********************************************************************
@ -530,31 +429,8 @@ BOOL WINAPI wglMakeCurrent(HDC hdc,
*/
BOOL WINAPI wglMakeContextCurrentARB(HDC hDrawDC, HDC hReadDC, HGLRC hglrc)
{
BOOL ret;
TRACE("(%p,%p,%p)\n", hDrawDC, hReadDC, hglrc);
ENTER_GL();
if (hglrc == NULL) {
ret = glXMakeCurrent(default_display, None, NULL);
} else {
if (NULL == wine_glx.p_glXMakeContextCurrent) {
ret = FALSE;
} else {
Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
Drawable d_draw = get_drawable( hDrawDC );
Drawable d_read = get_drawable( hReadDC );
if (ctx->ctx == NULL) {
ctx->ctx = glXCreateContext(ctx->display, ctx->vis, NULL, GetObjectType(hDrawDC) == OBJ_MEMDC ? False : True);
TRACE(" created a delayed OpenGL context (%p)\n", ctx->ctx);
}
ret = wine_glx.p_glXMakeContextCurrent(ctx->display, d_draw, d_read, ctx->ctx);
}
}
LEAVE_GL();
TRACE(" returning %s\n", (ret ? "True" : "False"));
return ret;
TRACE("hDrawDC: (%p), hReadDC: (%p), hglrc: (%p)\n", hDrawDC, hReadDC, hglrc);
return wine_wgl.p_wglMakeContextCurrentARB(hDrawDC, hReadDC, hglrc);
}
/***********************************************************************
@ -593,35 +469,9 @@ int WINAPI wglSetLayerPaletteEntries(HDC hdc,
/***********************************************************************
* wglShareLists (OPENGL32.@)
*/
BOOL WINAPI wglShareLists(HGLRC hglrc1,
HGLRC hglrc2) {
Wine_GLContext *org = (Wine_GLContext *) hglrc1;
Wine_GLContext *dest = (Wine_GLContext *) hglrc2;
TRACE("(%p, %p)\n", org, dest);
if (NULL != dest && dest->ctx != NULL) {
ERR("Could not share display lists, context already created !\n");
return FALSE;
} else {
if (org->ctx == NULL) {
ENTER_GL();
describeContext(org);
org->ctx = glXCreateContext(org->display, org->vis, NULL, GetObjectType(org->hdc) == OBJ_MEMDC ? False : True);
LEAVE_GL();
TRACE(" created a delayed OpenGL context (%p) for Wine context %p\n", org->ctx, org);
}
if (NULL != dest) {
ENTER_GL();
describeContext(dest);
/* Create the destination context with display lists shared */
dest->ctx = glXCreateContext(org->display, dest->vis, org->ctx, GetObjectType(org->hdc) == OBJ_MEMDC ? False : True);
LEAVE_GL();
TRACE(" created a delayed OpenGL context (%p) for Wine context %p sharing lists with OpenGL ctx %p\n", dest->ctx, dest, org->ctx);
return TRUE;
}
}
return FALSE;
BOOL WINAPI wglShareLists(HGLRC hglrc1, HGLRC hglrc2) {
TRACE("(%p, %p)\n", hglrc1, hglrc2);
return wine_wgl.p_wglShareLists(hglrc1, hglrc2);
}
/***********************************************************************
@ -1212,6 +1062,10 @@ static BOOL process_attach(void)
wine_wgl.p_wglGetCurrentContext = (void *)GetProcAddress(mod, "wglGetCurrentContext");
wine_wgl.p_wglGetCurrentDC = (void *)GetProcAddress(mod, "wglGetCurrentDC");
wine_wgl.p_wglGetCurrentReadDCARB = (void *)GetProcAddress(mod, "wglGetCurrentReadDCARB");
wine_wgl.p_wglMakeCurrent = (void *)GetProcAddress(mod, "wglMakeCurrent");
wine_wgl.p_wglMakeContextCurrentARB = (void *)GetProcAddress(mod, "wglMakeContextCurrentARB");
wine_wgl.p_wglShareLists = (void *)GetProcAddress(mod, "wglShareLists");
/* Interal WGL function */
wine_wgl.p_wglGetIntegerv = (void *)GetProcAddress(mod, "wglGetIntegerv");
hdc = GetDC(0);

View File

@ -26,6 +26,7 @@
#include <string.h>
#include "x11drv.h"
#include "winternl.h"
#include "wine/library.h"
#include "wine/debug.h"
@ -133,6 +134,7 @@ MAKE_FUNCPTR(glXChooseVisual)
MAKE_FUNCPTR(glXGetConfig)
MAKE_FUNCPTR(glXSwapBuffers)
MAKE_FUNCPTR(glXQueryExtension)
MAKE_FUNCPTR(glXQueryServerString)
MAKE_FUNCPTR(glXGetFBConfigs)
MAKE_FUNCPTR(glXChooseFBConfig)
@ -144,13 +146,18 @@ MAKE_FUNCPTR(glXCreateContext)
MAKE_FUNCPTR(glXDestroyContext)
MAKE_FUNCPTR(glXGetCurrentContext)
MAKE_FUNCPTR(glXGetCurrentReadDrawable)
/* MAKE_FUNCPTR(glXQueryDrawable) */
MAKE_FUNCPTR(glXMakeCurrent)
MAKE_FUNCPTR(glXMakeContextCurrent)
MAKE_FUNCPTR(glXQueryDrawable)
MAKE_FUNCPTR(glDrawBuffer)
#undef MAKE_FUNCPTR
static BOOL has_opengl(void)
{
static int init_done;
static void *opengl_handle;
const char *server_glx_version;
int error_base, event_base;
@ -166,6 +173,7 @@ LOAD_FUNCPTR(glXChooseVisual)
LOAD_FUNCPTR(glXGetConfig)
LOAD_FUNCPTR(glXSwapBuffers)
LOAD_FUNCPTR(glXQueryExtension)
LOAD_FUNCPTR(glXQueryServerString)
LOAD_FUNCPTR(glXGetFBConfigs)
LOAD_FUNCPTR(glXChooseFBConfig)
@ -177,15 +185,31 @@ LOAD_FUNCPTR(glXCreateContext)
LOAD_FUNCPTR(glXDestroyContext)
LOAD_FUNCPTR(glXGetCurrentContext)
LOAD_FUNCPTR(glXGetCurrentReadDrawable)
LOAD_FUNCPTR(glXMakeCurrent)
LOAD_FUNCPTR(glXMakeContextCurrent)
/* Standard OpenGL call, need in wglMakeCurrent */
LOAD_FUNCPTR(glDrawBuffer)
#undef LOAD_FUNCPTR
wine_tsx11_lock();
if (pglXQueryExtension(gdi_display, &error_base, &event_base) == True) {
TRACE("GLX is up and running error_base = %d\n", error_base);
TRACE("GLX is up and running error_base = %d\n", error_base);
} else {
wine_dlclose(opengl_handle, NULL, 0);
opengl_handle = NULL;
opengl_handle = NULL;
}
server_glx_version = pglXQueryServerString(gdi_display, DefaultScreen(gdi_display), GLX_VERSION);
TRACE("Server GLX version: %s\n", server_glx_version);
/* The mesa libGL client library seems to forward glXQueryDrawable to the Xserver, so only
* enable this function when the Xserver understand GLX 1.3 or newer
*/
if (!strcmp("1.2", server_glx_version))
pglXQueryDrawable = NULL;
else
pglXQueryDrawable = wine_dlsym(RTLD_DEFAULT, "glXQueryDrawable", NULL, 0);
wine_tsx11_unlock();
return (opengl_handle != NULL);
@ -255,6 +279,51 @@ inline static BOOL is_valid_context( Wine_GLContext *ctx )
return (ptr != NULL);
}
static int describeContext(Wine_GLContext* ctx) {
int tmp;
int ctx_vis_id;
TRACE(" Context %p have (vis:%p):\n", ctx, ctx->vis);
pglXGetFBConfigAttrib(ctx->display, ctx->fb_conf, GLX_FBCONFIG_ID, &tmp);
TRACE(" - FBCONFIG_ID 0x%x\n", tmp);
pglXGetFBConfigAttrib(ctx->display, ctx->fb_conf, GLX_VISUAL_ID, &tmp);
TRACE(" - VISUAL_ID 0x%x\n", tmp);
ctx_vis_id = tmp;
return ctx_vis_id;
}
static int describeDrawable(Wine_GLContext* ctx, Drawable drawable) {
int tmp;
int nElements;
int attribList[3] = { GLX_FBCONFIG_ID, 0, None };
GLXFBConfig *fbCfgs;
if (pglXQueryDrawable == NULL) {
/** glXQueryDrawable not available so returns not supported */
return -1;
}
TRACE(" Drawable %p have :\n", (void*) drawable);
pglXQueryDrawable(ctx->display, drawable, GLX_WIDTH, (unsigned int*) &tmp);
TRACE(" - WIDTH as %d\n", tmp);
pglXQueryDrawable(ctx->display, drawable, GLX_HEIGHT, (unsigned int*) &tmp);
TRACE(" - HEIGHT as %d\n", tmp);
pglXQueryDrawable(ctx->display, drawable, GLX_FBCONFIG_ID, (unsigned int*) &tmp);
TRACE(" - FBCONFIG_ID as 0x%x\n", tmp);
attribList[1] = tmp;
fbCfgs = pglXChooseFBConfig(ctx->display, DefaultScreen(ctx->display), attribList, &nElements);
if (fbCfgs == NULL) {
return -1;
}
pglXGetFBConfigAttrib(ctx->display, fbCfgs[0], GLX_VISUAL_ID, &tmp);
TRACE(" - VISUAL_ID as 0x%x\n", tmp);
XFree(fbCfgs);
return tmp;
}
/* GLX can advertise dozens of different pixelformats including offscreen and onscreen ones.
* In our WGL implementation we only support a subset of these formats namely the format of
* Wine's main visual and offscreen formats (if they are available).
@ -804,6 +873,121 @@ HDC WINAPI X11DRV_wglGetCurrentReadDCARB(void)
return ret;
}
/* OpenGL32 wglMakeCurrent */
BOOL WINAPI X11DRV_wglMakeCurrent(HDC hdc, HGLRC hglrc) {
BOOL ret;
DWORD type = GetObjectType(hdc);
TRACE("(%p,%p)\n", hdc, hglrc);
wine_tsx11_lock();
if (hglrc == NULL) {
ret = pglXMakeCurrent(gdi_display, None, NULL);
NtCurrentTeb()->glContext = NULL;
} else {
Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
Drawable drawable = get_drawable( hdc );
if (ctx->ctx == NULL) {
int draw_vis_id, ctx_vis_id;
VisualID visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
TRACE(" Wine desktop VISUAL_ID is 0x%x\n", (unsigned int) visualid);
draw_vis_id = describeDrawable(ctx, drawable);
ctx_vis_id = describeContext(ctx);
if (-1 == draw_vis_id || (draw_vis_id == visualid && draw_vis_id != ctx_vis_id)) {
/**
* Inherits from root window so reuse desktop visual
*/
XVisualInfo template;
XVisualInfo *vis;
int num;
template.visualid = visualid;
vis = XGetVisualInfo(ctx->display, VisualIDMask, &template, &num);
TRACE(" Creating GLX Context\n");
ctx->ctx = pglXCreateContext(ctx->display, vis, NULL, type == OBJ_MEMDC ? False : True);
} else {
TRACE(" Creating GLX Context\n");
ctx->ctx = pglXCreateContext(ctx->display, ctx->vis, NULL, type == OBJ_MEMDC ? False : True);
}
TRACE(" created a delayed OpenGL context (%p)\n", ctx->ctx);
}
TRACE(" make current for dis %p, drawable %p, ctx %p\n", ctx->display, (void*) drawable, ctx->ctx);
ret = pglXMakeCurrent(ctx->display, drawable, ctx->ctx);
NtCurrentTeb()->glContext = ctx;
if(ret && type == OBJ_MEMDC)
{
ctx->do_escape = TRUE;
pglDrawBuffer(GL_FRONT_LEFT);
}
}
wine_tsx11_unlock();
TRACE(" returning %s\n", (ret ? "True" : "False"));
return ret;
}
/* OpenGL32 wglMakeContextCurrentARB */
BOOL WINAPI X11DRV_wglMakeContextCurrentARB(HDC hDrawDC, HDC hReadDC, HGLRC hglrc)
{
BOOL ret;
TRACE("(%p,%p,%p)\n", hDrawDC, hReadDC, hglrc);
wine_tsx11_lock();
if (hglrc == NULL) {
ret = pglXMakeCurrent(gdi_display, None, NULL);
} else {
if (NULL == pglXMakeContextCurrent) {
ret = FALSE;
} else {
Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
Drawable d_draw = get_drawable( hDrawDC );
Drawable d_read = get_drawable( hReadDC );
if (ctx->ctx == NULL) {
ctx->ctx = pglXCreateContext(ctx->display, ctx->vis, NULL, GetObjectType(hDrawDC) == OBJ_MEMDC ? False : True);
TRACE(" created a delayed OpenGL context (%p)\n", ctx->ctx);
}
ret = pglXMakeContextCurrent(ctx->display, d_draw, d_read, ctx->ctx);
}
}
wine_tsx11_unlock();
TRACE(" returning %s\n", (ret ? "True" : "False"));
return ret;
}
/* OpenGL32 wglShaderLists */
BOOL WINAPI X11DRV_wglShareLists(HGLRC hglrc1, HGLRC hglrc2) {
Wine_GLContext *org = (Wine_GLContext *) hglrc1;
Wine_GLContext *dest = (Wine_GLContext *) hglrc2;
TRACE("(%p, %p)\n", org, dest);
if (NULL != dest && dest->ctx != NULL) {
ERR("Could not share display lists, context already created !\n");
return FALSE;
} else {
if (org->ctx == NULL) {
wine_tsx11_lock();
describeContext(org);
org->ctx = pglXCreateContext(org->display, org->vis, NULL, GetObjectType(org->hdc) == OBJ_MEMDC ? False : True);
wine_tsx11_unlock();
TRACE(" created a delayed OpenGL context (%p) for Wine context %p\n", org->ctx, org);
}
if (NULL != dest) {
wine_tsx11_lock();
describeContext(dest);
/* Create the destination context with display lists shared */
dest->ctx = pglXCreateContext(org->display, dest->vis, org->ctx, GetObjectType(org->hdc) == OBJ_MEMDC ? False : True);
wine_tsx11_unlock();
TRACE(" created a delayed OpenGL context (%p) for Wine context %p sharing lists with OpenGL ctx %p\n", dest->ctx, dest, org->ctx);
return TRUE;
}
}
return FALSE;
}
/* WGL helper function which handles differences in glGetIntegerv from WGL and GLX */
void X11DRV_wglGetIntegerv(GLenum pname, GLint* params) {
TRACE("pname: 0x%x, params: %p\n", pname, params);
@ -1042,6 +1226,25 @@ HDC WINAPI X11DRV_wglGetCurrentDC(void) {
return 0;
}
/* OpenGL32 wglMakeCurrent */
BOOL WINAPI X11DRV_wglMakeCurrent(HDC hdc, HGLRC hglrc) {
ERR_(opengl)("No OpenGL support compiled in.\n");
return FALSE;
}
/* OpenGL32 wglMakeContextCurrentARB */
BOOL WINAPI X11DRV_wglMakeContextCurrentARB(HDC hDrawDC, HDC hReadDC, HGLRC hglrc)
{
ERR_(opengl)("No OpenGL support compiled in.\n");
return FALSE;
}
/* OpenGL32 wglShaderLists */
BOOL WINAPI X11DRV_wglShareLists(HGLRC hglrc1, HGLRC hglrc2) {
ERR_(opengl)("No OpenGL support compiled in.\n");
return FALSE;
}
/* WGL helper function which handles differences in glGetIntegerv from WGL and GLX */
void X11DRV_wglGetIntegerv(GLenum pname, GLint* params) {
ERR_(opengl)("No OpenGL support compiled in.\n");

View File

@ -135,3 +135,6 @@
@ cdecl wglGetCurrentDC() X11DRV_wglGetCurrentDC
@ cdecl wglGetCurrentReadDCARB() X11DRV_wglGetCurrentReadDCARB
@ cdecl wglGetIntegerv(long ptr) X11DRV_wglGetIntegerv
@ cdecl wglMakeContextCurrentARB(long long long) X11DRV_wglMakeContextCurrentARB
@ cdecl wglMakeCurrent(long long) X11DRV_wglMakeCurrent
@ cdecl wglShareLists(long long) X11DRV_wglShareLists