From 2b36c4a4c355fb9cc893c4f7ed7992c22edf6049 Mon Sep 17 00:00:00 2001 From: Roderick Colenbrander <thunderbird2k@gmx.net> Date: Tue, 29 Aug 2006 16:58:49 +0200 Subject: [PATCH] winex11.drv: Import glx makecurrent/wglsharelists. --- dlls/opengl32/wgl.c | 178 +++---------------------- dlls/winex11.drv/opengl.c | 209 +++++++++++++++++++++++++++++- dlls/winex11.drv/winex11.drv.spec | 3 + 3 files changed, 225 insertions(+), 165 deletions(-) diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index d6f1e6b90ee..1a2a51ec8f8 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -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); diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index d8ba5f82950..40aa89f9d4e 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -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"); diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec index 5d5126f9a8e..bfef43cc397 100644 --- a/dlls/winex11.drv/winex11.drv.spec +++ b/dlls/winex11.drv/winex11.drv.spec @@ -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 -- GitLab