diff --git a/glx/glxscreens.h b/glx/glxscreens.h index 93b4109e0..eb2926045 100644 --- a/glx/glxscreens.h +++ b/glx/glxscreens.h @@ -142,7 +142,6 @@ struct __GLXscreen { char *GLextensions; char *GLXvendor; - char *GLXversion; char *GLXextensions; /** diff --git a/hw/dmx/glxProxy/glxscreens.h b/hw/dmx/glxProxy/glxscreens.h index a57c387fe..da50bdc85 100644 --- a/hw/dmx/glxProxy/glxscreens.h +++ b/hw/dmx/glxProxy/glxscreens.h @@ -43,7 +43,6 @@ typedef struct { GLint *isGLXvis; char *GLXvendor; - char *GLXversion; char *GLXextensions; } __GLXscreenInfo; diff --git a/hw/xquartz/GL/indirect.c b/hw/xquartz/GL/indirect.c index 41168729f..4876ab992 100644 --- a/hw/xquartz/GL/indirect.c +++ b/hw/xquartz/GL/indirect.c @@ -477,7 +477,8 @@ static __GLXscreen * __glXAquaScreenProbe(ScreenPtr pScreen) { __glXScreenInit(&screen->base, pScreen); - screen->base.GLXversion = strdup("1.4"); + screen->base.GLXmajor = 1; + screen->base.GLXminor = 4; screen->base.GLXextensions = strdup("GLX_SGIX_fbconfig " "GLX_SGIS_multisample " "GLX_ARB_multisample " diff --git a/hw/xwin/glx/Makefile.am b/hw/xwin/glx/Makefile.am index cdcba35c9..6b840bacb 100644 --- a/hw/xwin/glx/Makefile.am +++ b/hw/xwin/glx/Makefile.am @@ -16,7 +16,11 @@ if XWIN_MULTIWINDOWEXTWM DEFS_MULTIWINDOWEXTWM = -DXWIN_MULTIWINDOWEXTWM endif -DEFS = $(DEFS_MULTIWINDOW) $(DEFS_MULTIWINDOWEXTWM) +if XWIN_GLX_WINDOWS +DEFS_GLX_WINDOWS = -DXWIN_GLX_WINDOWS +endif + +DEFS = $(DEFS_MULTIWINDOW) $(DEFS_MULTIWINDOWEXTWM) $(DEFS_GLX_WINDOWS) INCLUDES = -I$(top_srcdir)/miext/rootless diff --git a/hw/xwin/glx/gen_gl_wrappers.py b/hw/xwin/glx/gen_gl_wrappers.py index d7fe98dec..e2d960ec6 100755 --- a/hw/xwin/glx/gen_gl_wrappers.py +++ b/hw/xwin/glx/gen_gl_wrappers.py @@ -312,7 +312,7 @@ if dispatchheader : for d in sorted(dispatch.keys()) : if wrappers.has_key(d) : - print ' SET_'+ d + '(disp, ' + prefix + d + 'Wrapper);' + print ' SET_'+ d + '(disp, (void *)' + prefix + d + 'Wrapper);' else : print '#warning No wrapper for ' + prefix + d + ' !' diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c index bd2a1ad30..86fef55d1 100644 --- a/hw/xwin/glx/indirect.c +++ b/hw/xwin/glx/indirect.c @@ -49,8 +49,17 @@ - pbuffer clobbering: we don't get async notification, but can we arrange to emit the event when we notice it's been clobbered? at the very least, check if it's been clobbered before using it? - - are the __GLXConfig * we get handed back ones we are made (so we can extend the structure - with privates?) Or are they created inside the GLX core as well? + - XGetImage() doesn't work on pixmaps; need to do more work to make the format and location + of the native pixmap compatible + - implement GLX_EXT_texture_from_pixmap in terms of WGL_ARB_render_texture + (not quite straightforward as we will have to create a pbuffer and copy the pixmap texture + into it) +*/ + +/* + Assumptions: + - the __GLXConfig * we get handed back ones we are made (so we can extend the structure + with privates) and never get created inside the GLX core */ /* @@ -80,6 +89,17 @@ #define NUM_ELEMENTS(x) (sizeof(x)/ sizeof(x[1])) +/* Not yet in w32api */ +#ifndef PFD_SUPPORT_DIRECTDRAW +#define PFD_SUPPORT_DIRECTDRAW 0x00002000 +#endif +#ifndef PFD_DIRECT3D_ACCELERATED +#define PFD_DIRECT3D_ACCELERATED 0x00004000 +#endif +#ifndef PFD_SUPPORT_COMPOSITION +#define PFD_SUPPORT_COMPOSITION 0x00008000 +#endif + /* ---------------------------------------------------------------------- */ /* * structure definitions @@ -200,22 +220,25 @@ static const char *glxWinErrorMessage(void) { static char errorbuffer[1024]; + unsigned int last_error = GetLastError(); if (!FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + last_error, + 0, (LPTSTR) &errorbuffer, sizeof(errorbuffer), NULL )) { - snprintf(errorbuffer, sizeof(errorbuffer), "Unknown error in FormatMessage: %08x!", (unsigned)GetLastError()); + snprintf(errorbuffer, sizeof(errorbuffer), "Unknown error"); } - if (errorbuffer[strlen(errorbuffer)-1] == '\n') + if ((errorbuffer[strlen(errorbuffer)-1] == '\n') || (errorbuffer[strlen(errorbuffer)-1] == '\r')) errorbuffer[strlen(errorbuffer)-1] = 0; + sprintf(errorbuffer + strlen(errorbuffer), " (%08x)", last_error); + return errorbuffer; } @@ -247,6 +270,9 @@ static void pfdOut(const PIXELFORMATDESCRIPTOR *pfd) DUMP_PFD_FLAG(PFD_SWAP_COPY); DUMP_PFD_FLAG(PFD_SWAP_LAYER_BUFFERS); DUMP_PFD_FLAG(PFD_GENERIC_ACCELERATED); + DUMP_PFD_FLAG(PFD_SUPPORT_DIRECTDRAW); + DUMP_PFD_FLAG(PFD_DIRECT3D_ACCELERATED); + DUMP_PFD_FLAG(PFD_SUPPORT_COMPOSITION); DUMP_PFD_FLAG(PFD_DEPTH_DONTCARE); DUMP_PFD_FLAG(PFD_DOUBLEBUFFER_DONTCARE); DUMP_PFD_FLAG(PFD_STEREO_DONTCARE); @@ -328,7 +354,7 @@ fbConfigsDump(unsigned int n, __GLXconfig *c) { unsigned int i = ((GLXWinConfig *)c)->pixelFormatIndex; - ErrorF("%3d %2x %2x " + ErrorF("%3d %3x %3x " "%-11s" " %3d %3d %s %s %s %s %s " "%2d %2d %2d %2d " @@ -651,17 +677,37 @@ glxWinScreenProbe(ScreenPtr pScreen) screen->base.swapInterval = glxWinScreenSwapInterval; screen->base.pScreen = pScreen; + // Creating the fbConfigs initializes screen->base.fbconfigs and screen->base.numFBConfigs if (strstr(wgl_extensions, "WGL_ARB_pixel_format")) { glxWinCreateConfigsExt(hdc, screen); - screen->has_WGL_ARB_pixel_format = TRUE; + + /* + Some graphics drivers appear to advertise WGL_ARB_pixel_format, + but it doesn't work usefully, so we have to be prepared for it + to fail and fall back to using DescribePixelFormat() + */ + if (screen->base.numFBConfigs > 0) + { + screen->has_WGL_ARB_pixel_format = TRUE; + } } - else + + if (screen->base.numFBConfigs <= 0) { glxWinCreateConfigs(hdc, screen); screen->has_WGL_ARB_pixel_format = FALSE; } - // Initializes screen->base.fbconfigs and screen->base.numFBConfigs + + /* + If we still didn't get any fbConfigs, we can't provide GLX for this screen + */ + if (screen->base.numFBConfigs <= 0) + { + free(screen); + LogMessage(X_ERROR,"AIGLX: No fbConfigs could be made from native OpenGL pixel formats\n"); + return NULL; + } /* These will be set by __glXScreenInit */ screen->base.visuals = NULL; @@ -689,30 +735,26 @@ glxWinScreenProbe(ScreenPtr pScreen) // // Override the GLX version (__glXScreenInit() sets it to "1.2") - // if we have all the needed extensionsto operate as a higher version + // if we have all the needed extensions to operate as a higher version // // SGIX_fbconfig && SGIX_pbuffer && SGI_make_current_read -> 1.3 // ARB_multisample -> 1.4 // if (screen->has_WGL_ARB_pbuffer && glx_sgi_make_current_read) { - free(screen->base.GLXversion); - if (screen->has_WGL_ARB_multisample) { - screen->base.GLXversion = strdup("1.4"); screen->base.GLXmajor = 1; screen->base.GLXminor = 4; } else { - screen->base.GLXversion = strdup("1.3"); screen->base.GLXmajor = 1; screen->base.GLXminor = 3; } - LogMessage(X_INFO, "AIGLX: Set GLX version to %s\n", screen->base.GLXversion); } } + LogMessage(X_INFO, "AIGLX: Set GLX version to %d.%d\n", screen->base.GLXmajor, screen->base.GLXminor); wglMakeCurrent(NULL, NULL); wglDeleteContext(hglrc); @@ -970,7 +1012,7 @@ int glxWinReleaseTexImage(__GLXcontext *baseContext, * lists with the old one... */ -static void +static Bool glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawableTypeOverride) { __GLXscreen *screen = gc->base.pGlxScreen; @@ -992,10 +1034,10 @@ glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawable if (!SetPixelFormat(hdc, winConfig->pixelFormatIndex, NULL)) { ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage()); - return; + return FALSE; } - return; + return TRUE; } /* @@ -1027,7 +1069,7 @@ glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawable if (fbConfigToPixelFormat(gc->base.config, &pfd, drawableTypeOverride)) { ErrorF("glxWinSetPixelFormat: fbConfigToPixelFormat failed\n"); - return; + return FALSE; } if (glxWinDebugSettings.dumpPFD) @@ -1043,7 +1085,7 @@ glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawable if (pixelFormat == 0) { ErrorF("ChoosePixelFormat error: %s\n", glxWinErrorMessage()); - return; + return FALSE; } GLWIN_DEBUG_MSG("ChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat); @@ -1052,7 +1094,7 @@ glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawable if (!SetPixelFormat(hdc, pixelFormat, &pfd)) { ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage()); - return; + return FALSE; } } else @@ -1061,7 +1103,7 @@ glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawable if (pixelFormat == 0) { ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage()); - return; + return FALSE; } GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat); @@ -1070,9 +1112,11 @@ glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawable if (!SetPixelFormat(hdc, pixelFormat, NULL)) { ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage()); - return; + return FALSE; } } + + return TRUE; } static HDC @@ -1123,7 +1167,13 @@ glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HDC *hdc, HWND *hwnd) gc->hwnd = *hwnd; /* We must select a pixelformat, but SetPixelFormat can only be called once for a window... */ - glxWinSetPixelFormat(gc, *hdc, 0, GLX_WINDOW_BIT); + if (!glxWinSetPixelFormat(gc, *hdc, 0, GLX_WINDOW_BIT)) + { + ErrorF("glxWinSetPixelFormat error: %s\n", glxWinErrorMessage()); + ReleaseDC(*hwnd, *hdc); + *hdc = NULL; + return NULL; + } } } break; diff --git a/hw/xwin/glx/wgl_ext_api.c b/hw/xwin/glx/wgl_ext_api.c index 1020916dc..78b6e2a02 100644 --- a/hw/xwin/glx/wgl_ext_api.c +++ b/hw/xwin/glx/wgl_ext_api.c @@ -43,17 +43,14 @@ static type type##proc = NULL; #define PRERESOLVE(type, symbol) \ - type##proc = (type)wglGetProcAddress(symbol); \ - if (type##proc == NULL) \ - ErrorF("wglwrap: Can't resolve \"%s\"\n", symbol); \ - else \ - ErrorF("wglwrap: Resolved \"%s\"\n", symbol); + type##proc = (type)wglGetProcAddress(symbol); #define RESOLVE_RET(type, symbol, retval) \ if (type##proc == NULL) { \ - __glXErrorCallBack(0); \ - return retval; \ - } + ErrorF("wglwrap: Can't resolve \"%s\"\n", symbol); \ + __glXErrorCallBack(0); \ + return retval; \ + } #define RESOLVE(procname, symbol) RESOLVE_RET(procname, symbol,) diff --git a/hw/xwin/glx/winpriv.c b/hw/xwin/glx/winpriv.c index a35392b26..460973730 100644 --- a/hw/xwin/glx/winpriv.c +++ b/hw/xwin/glx/winpriv.c @@ -19,7 +19,7 @@ winCreateWindowsWindow (WindowPtr pWin); */ HWND winGetWindowInfo(WindowPtr pWin) { - winDebug("%s: pWin=%p\n", __FUNCTION__, pWin); + winTrace("%s: pWin %p XID 0x%x\n", __FUNCTION__, pWin, pWin->drawable.id); /* a real window was requested */ if (pWin != NULL) @@ -61,6 +61,9 @@ HWND winGetWindowInfo(WindowPtr pWin) { /* copy window handle */ hwnd = pWinPriv->hWnd; + + /* mark GLX active on that hwnd */ + pWinPriv->fWglUsed = TRUE; } return hwnd; diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man index 7975fd30d..6e69a185d 100644 --- a/hw/xwin/man/XWin.man +++ b/hw/xwin/man/XWin.man @@ -208,6 +208,10 @@ Enable or disable the \fICtrl-Alt-Backspace\fP key combination as a signal to exit the X Server. The \fICtrl-Alt-Backspace\fP key combination is disabled by default. .TP 8 +.B \-[no]wgl +Enable [disable] the GLX extension to use the native Windows WGL interface +for hardware accelerated OpenGL (AIGLX). (Experimental) +.TP 8 .B \-[no]winkill Enable or disable the \fIAlt-F4\fP key combination as a signal to exit the X Server. diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c index 2d9a46e40..2329d163e 100644 --- a/hw/xwin/winmultiwindowwindow.c +++ b/hw/xwin/winmultiwindowwindow.c @@ -110,7 +110,10 @@ winCreateWindowMultiWindow (WindowPtr pWin) pWinPriv->hWnd = NULL; pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen); pWinPriv->fXKilled = FALSE; - +#ifdef XWIN_GLX_WINDOWS + pWinPriv->fWglUsed = FALSE; +#endif + return fResult; } @@ -372,9 +375,8 @@ winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent) ScreenPtr pScreen = pWin->drawable.pScreen; winScreenPriv(pScreen); -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winReparentMultiWindow - pWin: %08x\n", pWin); -#endif + winDebug("winReparentMultiWindow - pWin:%08x XID:0x%x, reparent from pWin:%08x XID:0x%x to pWin:%08x XID:0x%x\n", + pWin, pWin->drawable.id, pPriorParent, pPriorParent->drawable.id, pWin->parent, pWin->parent->drawable.id); WIN_UNWRAP(ReparentWindow); if (pScreen->ReparentWindow) @@ -498,9 +500,7 @@ winCreateWindowsWindow (WindowPtr pWin) winInitMultiWindowClass(); -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin); -#endif + winDebug("winCreateWindowsTopLevelWindow - pWin:%08x XID:0x%x \n", pWin, pWin->drawable.id); iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN); iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN); @@ -626,9 +626,7 @@ winDestroyWindowsWindow (WindowPtr pWin) HICON hIcon; HICON hIconSm; -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winDestroyWindowsWindow\n"); -#endif + winDebug("winDestroyWindowsWindow - pWin:%08x XID:0x%x \n", pWin, pWin->drawable.id); /* Bail out if the Windows window handle is invalid */ if (pWinPriv->hWnd == NULL) @@ -652,6 +650,11 @@ winDestroyWindowsWindow (WindowPtr pWin) winDestroyIcon(hIcon); winDestroyIcon(hIconSm); +#ifdef XWIN_GLX_WINDOWS + /* No longer note WGL used on this window */ + pWinPriv->fWglUsed = FALSE; +#endif + /* Process all messages on our queue */ while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { @@ -663,9 +666,7 @@ winDestroyWindowsWindow (WindowPtr pWin) winInDestroyWindowsWindow = oldstate; -#if CYGMULTIWINDOW_DEBUG - ErrorF ("-winDestroyWindowsWindow\n"); -#endif + winDebug("winDestroyWindowsWindow - done\n"); } diff --git a/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c index 1a3be78d5..fb1938b3a 100644 --- a/hw/xwin/winmultiwindowwndproc.c +++ b/hw/xwin/winmultiwindowwndproc.c @@ -472,6 +472,20 @@ winTopLevelWindowProc (HWND hwnd, UINT message, return 0; } +#ifdef XWIN_GLX_WINDOWS + if (pWinPriv->fWglUsed) + { + /* + For regions which are being drawn by GL, the shadow framebuffer doesn't have the + correct bits, so don't bitblt from the shadow framebuffer + + XXX: For now, just leave it alone, but ideally we want to send an expose event to + the window so it really redraws the affected region... + */ + ValidateRect(hwnd, &(ps.rcPaint)); + } + else +#endif /* Try to copy from the shadow buffer */ if (!BitBlt (hdcUpdate, ps.rcPaint.left, ps.rcPaint.top, diff --git a/hw/xwin/winwindow.h b/hw/xwin/winwindow.h index ebe43091f..a6c8e05dd 100644 --- a/hw/xwin/winwindow.h +++ b/hw/xwin/winwindow.h @@ -80,6 +80,9 @@ typedef struct winPrivScreenPtr pScreenPriv; Bool fXKilled; HDWP hDwp; +#ifdef XWIN_GLX_WINDOWS + Bool fWglUsed; +#endif /* Privates used by primary fb DirectDraw server */ LPDDSURFACEDESC pddsdPrimary;