diff options
Diffstat (limited to 'GL/apple/aglGlx.c')
-rw-r--r-- | GL/apple/aglGlx.c | 796 |
1 files changed, 511 insertions, 285 deletions
diff --git a/GL/apple/aglGlx.c b/GL/apple/aglGlx.c index 106a6464d..fa7533e73 100644 --- a/GL/apple/aglGlx.c +++ b/GL/apple/aglGlx.c @@ -1,10 +1,14 @@ /* * GLX implementation that uses Apple's AGL.framework for OpenGL + * + * FIXME: This file and indirect.c are very similar. The two should be + * merged by introducing suitable abstractions. */ /* * Copyright (c) 2002 Greg Parker. All Rights Reserved. + * Copyright (c) 2004 Torrey T. Lyons. All Rights Reserved. * - * Portions of this file are copied from xf86glx.c, + * Large portions of this file are copied from Mesa's xf86glx.c, * which contains the following copyright: * * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -27,10 +31,6 @@ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name(s) of the above copyright - * holders shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in this Software without prior written authorization. */ /* $XFree86: xc/programs/Xserver/GL/apple/aglGlx.c,v 1.2 2003/09/16 00:36:11 torrey Exp $ */ @@ -58,6 +58,11 @@ #include <GL/internal/glcore.h> #undef BOOL +#include "glcontextmodes.h" + +// ggs: needed to call back to glx with visual configs +extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs, void **configprivs); + // Write debugging output, or not #ifdef GLAQUA_DEBUG #define GLAQUA_DEBUG_MSG ErrorF @@ -84,14 +89,14 @@ GLboolean glIsTextureEXT (GLuint h) { // some prototypes static Bool glAquaScreenProbe(int screen); static Bool glAquaInitVisuals(VisualPtr *visualp, DepthPtr *depthp, - int *nvisualp, int *ndepthp, - int *rootDepthp, VisualID *defaultVisp, - unsigned long sizes, int bitsPerRGB); + int *nvisualp, int *ndepthp, + int *rootDepthp, VisualID *defaultVisp, + unsigned long sizes, int bitsPerRGB); static void glAquaSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs, - void **privates); + void **privates); static __GLinterface *glAquaCreateContext(__GLimports *imports, - __GLcontextModes *mode, - __GLinterface *shareGC); + __GLcontextModes *mode, + __GLinterface *shareGC); static void glAquaCreateBuffer(__GLXdrawablePrivate *glxPriv); static void glAquaResetExtension(void); @@ -102,14 +107,14 @@ static void glAquaResetExtension(void); * __glXScreenInit to initialize each of the active screens * (__glXActiveScreens[]). Several of the fields must be initialized by * the screenProbe routine before they are copied to the active screens - * struct. In particular, the contextCreate, pGlxVisual, numVisuals, + * struct. In particular, the contextCreate, modes, numVisuals, * and numUsableVisuals fields must be initialized. */ -__GLXscreenInfo __glDDXScreenInfo = { +static __GLXscreenInfo __glDDXScreenInfo = { glAquaScreenProbe, /* Must be generic and handle all screens */ glAquaCreateContext, /* Substitute screen's createContext routine */ glAquaCreateBuffer, /* Substitute screen's createBuffer routine */ - NULL, /* Set up pGlxVisual in probe */ + NULL, /* Set up modes in probe */ NULL, /* Set up pVisualPriv in probe */ 0, /* Set up numVisuals in probe */ 0, /* Set up numUsableVisuals in probe */ @@ -119,13 +124,20 @@ __GLXscreenInfo __glDDXScreenInfo = { NULL /* WrappedPositionWindow is overwritten */ }; -__GLXextensionInfo __glDDXExtensionInfo = { +void *__glXglDDXScreenInfo(void) { + return &__glDDXScreenInfo; +} + +static __GLXextensionInfo __glDDXExtensionInfo = { GL_CORE_APPLE, glAquaResetExtension, glAquaInitVisuals, glAquaSetVisualConfigs }; +void *__glXglDDXExtensionInfo(void) { + return &__glDDXExtensionInfo; +} // prototypes @@ -134,7 +146,7 @@ static GLboolean glAquaLoseCurrent(__GLcontext *gc); static GLboolean glAquaMakeCurrent(__GLcontext *gc); static GLboolean glAquaShareContext(__GLcontext *gc, __GLcontext *gcShare); static GLboolean glAquaCopyContext(__GLcontext *dst, const __GLcontext *src, - GLuint mask); + GLuint mask); static GLboolean glAquaForceCurrent(__GLcontext *gc); /* Drawing surface notification callbacks */ @@ -168,7 +180,7 @@ static __GLexports glAquaExports = { typedef struct { int num_vis; - __GLXvisualConfig *glx_vis; + __GLcontextModes *modes; void **priv; // wrapped screen functions @@ -192,6 +204,7 @@ struct __GLcontextRec { AGLContext ctx; AGLPixelFormat pixelFormat; + Bool isAttached; // TRUE if ctx is really attached to a window }; @@ -206,22 +219,28 @@ static GLboolean glAquaDestroyContext(__GLcontext *gc) if (gc->pixelFormat) aglDestroyPixelFormat(gc->pixelFormat); free(gc); } + return GL_TRUE; } static GLboolean glAquaLoseCurrent(__GLcontext *gc) { - // GLAQUA_DEBUG_MSG("glAquaLoseCurrent (ctx 0x%x)\n", gc->ctx); + GLAQUA_DEBUG_MSG("glAquaLoseCurrent (ctx 0x%x)\n", gc->ctx); + aglSetCurrentContext(NULL); __glXLastContext = NULL; // Mesa does this; why? + gc->isAttached = FALSE; + return GL_TRUE; } -// (x, y, w, h) is global coordinates of view or -1 -// glPriv may be NULL -static void attach(__GLcontext *gc, __GLdrawablePrivate *glPriv, - int x, int y, int w, int h) + +/* + * Attach a GL context to a GL drawable + * If glPriv is NULL, the context is detached. + */ +static void attach(__GLcontext *gc, __GLdrawablePrivate *glPriv) { __GLXdrawablePrivate *glxPriv; @@ -244,7 +263,15 @@ static void attach(__GLcontext *gc, __GLdrawablePrivate *glPriv, CRWindowPtr crWinPtr; AGLDrawable newPort; - crWinPtr = (CRWindowPtr) quartzProcs->FrameForWindow(pWin, TRUE); + if (glPriv->width <= 0 || glPriv->height <= 0) { + // attach to zero size drawable - will really attach later + GLAQUA_DEBUG_MSG("couldn't attach to zero size drawable\n"); + aglSetDrawable(gc->ctx, NULL); + gc->isAttached = FALSE; + return; + } + + crWinPtr = (CRWindowPtr) quartzProcs->FrameForWindow(pWin, FALSE); if (crWinPtr) { newPort = (AGLDrawable) crWinPtr->port; @@ -253,35 +280,43 @@ static void attach(__GLcontext *gc, __GLdrawablePrivate *glPriv, } if (newPort) { - // fixme won't be a CGrafPtr if currently offscreen or fullscreen + // FIXME: won't be a CGrafPtr if currently offscreen or fullscreen AGLDrawable oldPort = aglGetDrawable(gc->ctx); // AGLDrawable newPort = GetWindowPort(window); - GLint frame[4] = {x, y, w, h}; // fixme multi-screen? - // frame is now X11-global + + // Frame is GLdrawable in X11 global coordinates + // FIXME: Does this work for multiple screens? + GLint frame[4] = {glPriv->xOrigin, glPriv->yOrigin, glPriv->width, glPriv->height}; + GLAQUA_DEBUG_MSG("global size %d %d %d %d\n", + frame[0], frame[1], frame[2], frame[3]); + + // Convert to window-local coordinates frame[0] -= topWin->drawable.x - topWin->borderWidth; frame[1] -= topWin->drawable.y - topWin->borderWidth; - // frame is now window-local - // GL uses flipped coordinates + + // AGL uses flipped coordinates frame[1] = topWin->drawable.height + 2*topWin->borderWidth - frame[1] - frame[3]; - // GLAQUA_DEBUG_MSG("local size %d %d %d %d\n", - // frame[0], frame[1], frame[2], frame[3]); + GLAQUA_DEBUG_MSG("local size %d %d %d %d\n", + frame[0], frame[1], frame[2], frame[3]); if (oldPort != newPort) { - // fixme retain/release windows - aglSetDrawable(gc->ctx, newPort); + // FIXME: retain/release windows + if (!aglSetDrawable(gc->ctx, newPort)) return; } - aglSetInteger(gc->ctx, AGL_BUFFER_RECT, frame); - aglEnable(gc->ctx, AGL_BUFFER_RECT); - // aglSetInteger(gc->ctx, AGL_SWAP_RECT, frame); - // aglEnable(gc->ctx, AGL_SWAP_RECT); - aglUpdateContext(gc->ctx); + if (!aglSetInteger(gc->ctx, AGL_BUFFER_RECT, frame)) return; + if (!aglEnable(gc->ctx, AGL_BUFFER_RECT)) return; + if (!aglSetInteger(gc->ctx, AGL_SWAP_RECT, frame)) return; + if (!aglEnable(gc->ctx, AGL_SWAP_RECT)) return; + if (!aglUpdateContext(gc->ctx)) return; + gc->isAttached = TRUE; - GLAQUA_DEBUG_MSG("attached\n"); + GLAQUA_DEBUG_MSG("attached context 0x%x to window 0x%x\n", gc->ctx, + pWin->drawable.id); } else { // attach to not-yet-realized window - will really attach later - GLAQUA_DEBUG_MSG("couldn't attach\n"); + GLAQUA_DEBUG_MSG("couldn't attach to unrealized window\n"); aglSetDrawable(gc->ctx, NULL); gc->isAttached = FALSE; } @@ -294,14 +329,14 @@ static void attach(__GLcontext *gc, __GLdrawablePrivate *glPriv, static GLboolean glAquaMakeCurrent(__GLcontext *gc) { -#if 0 __GLdrawablePrivate *glPriv = gc->interface.imports.getDrawablePrivate(gc); + GLAQUA_DEBUG_MSG("glAquaMakeCurrent (ctx 0x%x)\n", gc->ctx); if (!gc->isAttached) { - attach(gc, glPriv, glPriv->xOrigin, glPriv->yOrigin, glPriv->width, glPriv->height); + attach(gc, glPriv); } -#endif + return aglSetCurrentContext(gc->ctx); } @@ -317,8 +352,8 @@ static GLboolean glAquaCopyContext(__GLcontext *dst, const __GLcontext *src, GLuint mask) { GLAQUA_DEBUG_MSG("glAquaCopyContext\n"); - aglCopyContext(src->ctx, dst->ctx, mask); - return GL_TRUE; + + return aglCopyContext(src->ctx, dst->ctx, mask); } static GLboolean glAquaForceCurrent(__GLcontext *gc) @@ -436,16 +471,15 @@ static AGLPixelFormat makeFormat(__GLcontextModes *mode) } static __GLinterface *glAquaCreateContext(__GLimports *imports, - __GLcontextModes *mode, - __GLinterface *shareGC) + __GLcontextModes *mode, + __GLinterface *shareGC) { __GLcontext *result; __GLcontext *sharectx = (__GLcontext *)shareGC; - GLint value; GLAQUA_DEBUG_MSG("glAquaCreateContext\n"); - result = (__GLcontext *)malloc(sizeof(__GLcontext)); + result = (__GLcontext *)calloc(1, sizeof(__GLcontext)); if (!result) return NULL; result->interface.imports = *imports; @@ -468,10 +502,6 @@ static __GLinterface *glAquaCreateContext(__GLimports *imports, result->isAttached = FALSE; - // Tell aglSwapBuffers to wait for vertical retrace - value = 1; - aglSetInteger(result->ctx, AGL_SWAP_INTERVAL, &value); - GLAQUA_DEBUG_MSG("glAquaCreateContext done\n"); return (__GLinterface *)result; } @@ -505,17 +535,15 @@ glAquaRealizeWindow(WindowPtr pWin) GLAQUA_DEBUG_MSG("glAquaRealizeWindow is GL drawable!\n"); // GL contexts bound to this window for drawing - for (gx = glxPriv->drawGlxc; gx != NULL; gx = gx->next) { + for (gx = glxPriv->drawGlxc; gx != NULL; gx = gx->nextDrawPriv) { gc = (__GLcontext *)gx->gc; - attach(gc, glPriv, glxPriv->xorigin, glxPriv->yorigin, - glxPriv->width, glxPriv->height); + attach(gc, glPriv); } // GL contexts bound to this window for reading - for (gx = glxPriv->readGlxc; gx != NULL; gx = gx->next) { + for (gx = glxPriv->readGlxc; gx != NULL; gx = gx->nextReadPriv) { gc = (__GLcontext *)gx->gc; - attach(gc, glPriv, glxPriv->xorigin, glxPriv->yorigin, - glxPriv->width, glxPriv->height); + attach(gc, glPriv); } } @@ -544,15 +572,15 @@ glAquaUnrealizeWindow(WindowPtr pWin) GLAQUA_DEBUG_MSG("glAquaUnealizeWindow is GL drawable!\n"); // GL contexts bound to this window for drawing - for (gx = glxPriv->drawGlxc; gx != NULL; gx = gx->next) { + for (gx = glxPriv->drawGlxc; gx != NULL; gx = gx->nextDrawPriv) { gc = (__GLcontext *)gx->gc; - attach(gc, NULL, 0, 0, 0, 0); + attach(gc, NULL); } // GL contexts bound to this window for reading - for (gx = glxPriv->readGlxc; gx != NULL; gx = gx->next) { + for (gx = glxPriv->readGlxc; gx != NULL; gx = gx->nextReadPriv) { gc = (__GLcontext *)gx->gc; - attach(gc, NULL, 0, 0, 0, 0); + attach(gc, NULL); } } @@ -564,23 +592,21 @@ glAquaUnrealizeWindow(WindowPtr pWin) } - - - - -/* - * In the case the driver has no GLX visuals we'll use these. - * [0] = RGB, double buffered - * [1] = RGB, double buffered, stencil, accum - */ // Originally copied from Mesa static int numConfigs = 0; static __GLXvisualConfig *visualConfigs = NULL; static void **visualPrivates = NULL; -#define NUM_FALLBACK_CONFIGS 2 +/* + * In the case the driver defines no GLX visuals we'll use these. + * Note that for TrueColor and DirectColor visuals, bufferSize is the + * sum of redSize, greenSize, blueSize and alphaSize, which may be larger + * than the nplanes/rootDepth of the server's X11 visuals + */ +#define NUM_FALLBACK_CONFIGS 5 static __GLXvisualConfig FallbackConfigs[NUM_FALLBACK_CONFIGS] = { + /* [0] = RGB, double buffered, Z */ { -1, /* vid */ -1, /* class */ @@ -595,11 +621,12 @@ static __GLXvisualConfig FallbackConfigs[NUM_FALLBACK_CONFIGS] = { 0, /* stencilSize */ 0, /* auxBuffers */ 0, /* level */ - GLX_NONE_EXT, /* visualRating */ - 0, /* transparentPixel */ + GLX_NONE, /* visualRating */ + GLX_NONE, /* transparentPixel */ 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */ 0 /* transparentIndex */ }, + /* [1] = RGB, double buffered, Z, stencil, accum */ { -1, /* vid */ -1, /* class */ @@ -614,15 +641,94 @@ static __GLXvisualConfig FallbackConfigs[NUM_FALLBACK_CONFIGS] = { 8, /* stencilSize */ 0, /* auxBuffers */ 0, /* level */ + GLX_NONE, /* visualRating */ + GLX_NONE, /* transparentPixel */ + 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */ + 0 /* transparentIndex */ + }, + /* [2] = RGB+Alpha, double buffered, Z, stencil, accum */ + { + -1, /* vid */ + -1, /* class */ + True, /* rgba */ + -1, -1, -1, 8, /* rgba sizes */ + -1, -1, -1, -1, /* rgba masks */ + 16, 16, 16, 16, /* rgba accum sizes */ + True, /* doubleBuffer */ + False, /* stereo */ + -1, /* bufferSize */ + 16, /* depthSize */ + 8, /* stencilSize */ + 0, /* auxBuffers */ + 0, /* level */ + GLX_NONE, /* visualRating */ + GLX_NONE, /* transparentPixel */ + 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */ + 0 /* transparentIndex */ + }, + /* [3] = RGB+Alpha, single buffered, Z, stencil, accum */ + { + -1, /* vid */ + -1, /* class */ + True, /* rgba */ + -1, -1, -1, 8, /* rgba sizes */ + -1, -1, -1, -1, /* rgba masks */ + 16, 16, 16, 16, /* rgba accum sizes */ + False, /* doubleBuffer */ + False, /* stereo */ + -1, /* bufferSize */ + 16, /* depthSize */ + 8, /* stencilSize */ + 0, /* auxBuffers */ + 0, /* level */ + GLX_NONE, /* visualRating */ + GLX_NONE, /* transparentPixel */ + 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */ + 0 /* transparentIndex */ + }, + /* [4] = CI, double buffered, Z */ + { + -1, /* vid */ + -1, /* class */ + False, /* rgba? (false = color index) */ + -1, -1, -1, 0, /* rgba sizes */ + -1, -1, -1, 0, /* rgba masks */ + 0, 0, 0, 0, /* rgba accum sizes */ + True, /* doubleBuffer */ + False, /* stereo */ + -1, /* bufferSize */ + 16, /* depthSize */ + 0, /* stencilSize */ + 0, /* auxBuffers */ + 0, /* level */ + GLX_NONE, /* visualRating */ + GLX_NONE, /* transparentPixel */ + 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */ + 0 /* transparentIndex */ + }, +}; + +static __GLXvisualConfig NullConfig = { + -1, /* vid */ + -1, /* class */ + False, /* rgba */ + -1, -1, -1, 0, /* rgba sizes */ + -1, -1, -1, 0, /* rgba masks */ + 0, 0, 0, 0, /* rgba accum sizes */ + False, /* doubleBuffer */ + False, /* stereo */ + -1, /* bufferSize */ + 16, /* depthSize */ + 0, /* stencilSize */ + 0, /* auxBuffers */ + 0, /* level */ GLX_NONE_EXT, /* visualRating */ 0, /* transparentPixel */ 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */ 0 /* transparentIndex */ - } }; - static int count_bits(unsigned int n) { int bits = 0; @@ -635,11 +741,10 @@ static int count_bits(unsigned int n) } -// Mostly copied from Mesa's xf86glx.c static Bool init_visuals(int *nvisualp, VisualPtr *visualp, - VisualID *defaultVisp, - int ndepth, DepthPtr pdepth, - int rootDepth) + VisualID *defaultVisp, + int ndepth, DepthPtr pdepth, + int rootDepth) { int numRGBconfigs; int numCIconfigs; @@ -649,7 +754,7 @@ static Bool init_visuals(int *nvisualp, VisualPtr *visualp, VisualPtr pVisual = *visualp; VisualPtr pVisualNew = NULL; VisualID *orig_vid = NULL; - __GLXvisualConfig *glXVisualPtr = NULL; + __GLcontextModes *modes; __GLXvisualConfig *pNewVisualConfigs = NULL; void **glXVisualPriv; void **pNewVisualPriv; @@ -667,14 +772,14 @@ static Bool init_visuals(int *nvisualp, VisualPtr *visualp, pNewVisualConfigs = (__GLXvisualConfig *) __glXMalloc(numNewConfigs * sizeof(__GLXvisualConfig)); if (!pNewVisualConfigs) { - return FALSE; + return FALSE; } /* Alloc space for the list of new GLX visual privates */ pNewVisualPriv = (void **) __glXMalloc(numNewConfigs * sizeof(void *)); if (!pNewVisualPriv) { - __glXFree(pNewVisualConfigs); - return FALSE; + __glXFree(pNewVisualConfigs); + return FALSE; } /* @@ -682,9 +787,9 @@ static Bool init_visuals(int *nvisualp, VisualPtr *visualp, ** visual configs. */ if (numConfigs == 0) { - memcpy(pNewVisualConfigs, FallbackConfigs, + memcpy(pNewVisualConfigs, FallbackConfigs, NUM_FALLBACK_CONFIGS * sizeof(__GLXvisualConfig)); - memset(pNewVisualPriv, 0, NUM_FALLBACK_CONFIGS * sizeof(void *)); + memset(pNewVisualPriv, 0, NUM_FALLBACK_CONFIGS * sizeof(void *)); } else { /* copy driver's visual config info */ @@ -698,18 +803,24 @@ static Bool init_visuals(int *nvisualp, VisualPtr *visualp, numRGBconfigs = 0; numCIconfigs = 0; for (i = 0; i < numNewConfigs; i++) { - if (pNewVisualConfigs[i].rgba) - numRGBconfigs++; - else - numCIconfigs++; + if (pNewVisualConfigs[i].rgba) + numRGBconfigs++; + else + numCIconfigs++; } /* Count the total number of visuals to compute */ numNewVisuals = 0; for (i = 0; i < numVisuals; i++) { - numNewVisuals += - (pVisual[i].class == TrueColor || pVisual[i].class == DirectColor) - ? numRGBconfigs : numCIconfigs; + int count; + + count = ((pVisual[i].class == TrueColor || + pVisual[i].class == DirectColor) + ? numRGBconfigs : numCIconfigs); + if (count == 0) + count = 1; /* preserve the existing visual */ + + numNewVisuals += count; } /* Reset variables for use with the next screen/driver's visual configs */ @@ -719,127 +830,159 @@ static Bool init_visuals(int *nvisualp, VisualPtr *visualp, /* Alloc temp space for the list of orig VisualIDs for each new visual */ orig_vid = (VisualID *)__glXMalloc(numNewVisuals * sizeof(VisualID)); if (!orig_vid) { - __glXFree(pNewVisualPriv); - __glXFree(pNewVisualConfigs); - return FALSE; + __glXFree(pNewVisualPriv); + __glXFree(pNewVisualConfigs); + return FALSE; } /* Alloc space for the list of glXVisuals */ - glXVisualPtr = (__GLXvisualConfig *)__glXMalloc(numNewVisuals * - sizeof(__GLXvisualConfig)); - if (!glXVisualPtr) { - __glXFree(orig_vid); - __glXFree(pNewVisualPriv); - __glXFree(pNewVisualConfigs); - return FALSE; + modes = _gl_context_modes_create(numNewVisuals, sizeof(__GLcontextModes)); + if (modes == NULL) { + __glXFree(orig_vid); + __glXFree(pNewVisualPriv); + __glXFree(pNewVisualConfigs); + return FALSE; } /* Alloc space for the list of glXVisualPrivates */ glXVisualPriv = (void **)__glXMalloc(numNewVisuals * sizeof(void *)); if (!glXVisualPriv) { - __glXFree(glXVisualPtr); - __glXFree(orig_vid); - __glXFree(pNewVisualPriv); - __glXFree(pNewVisualConfigs); - return FALSE; + _gl_context_modes_destroy( modes ); + __glXFree(orig_vid); + __glXFree(pNewVisualPriv); + __glXFree(pNewVisualConfigs); + return FALSE; } /* Alloc space for the new list of the X server's visuals */ pVisualNew = (VisualPtr)__glXMalloc(numNewVisuals * sizeof(VisualRec)); if (!pVisualNew) { - __glXFree(glXVisualPriv); - __glXFree(glXVisualPtr); - __glXFree(orig_vid); - __glXFree(pNewVisualPriv); - __glXFree(pNewVisualConfigs); - return FALSE; + __glXFree(glXVisualPriv); + _gl_context_modes_destroy( modes ); + __glXFree(orig_vid); + __glXFree(pNewVisualPriv); + __glXFree(pNewVisualConfigs); + return FALSE; } /* Initialize the new visuals */ found_default = FALSE; + glAquaScreens[screenInfo.numScreens-1].modes = modes; for (i = j = 0; i < numVisuals; i++) { int is_rgb = (pVisual[i].class == TrueColor || - pVisual[i].class == DirectColor); - - for (k = 0; k < numNewConfigs; k++) { - if (pNewVisualConfigs[k].rgba != is_rgb) - continue; - - /* Initialize the new visual */ - pVisualNew[j] = pVisual[i]; - pVisualNew[j].vid = FakeClientID(0); - - /* Check for the default visual */ - if (!found_default && pVisual[i].vid == *defaultVisp) { - *defaultVisp = pVisualNew[j].vid; - found_default = TRUE; - } - - /* Save the old VisualID */ - orig_vid[j] = pVisual[i].vid; - - /* Initialize the glXVisual */ - glXVisualPtr[j] = pNewVisualConfigs[k]; - glXVisualPtr[j].vid = pVisualNew[j].vid; - - /* - * If the class is -1, then assume the X visual information - * is identical to what GLX needs, and take them from the X - * visual. NOTE: if class != -1, then all other fields MUST - * be initialized. - */ - if (glXVisualPtr[j].class == -1) { - glXVisualPtr[j].class = pVisual[i].class; - glXVisualPtr[j].redSize = count_bits(pVisual[i].redMask); - glXVisualPtr[j].greenSize = count_bits(pVisual[i].greenMask); - glXVisualPtr[j].blueSize = count_bits(pVisual[i].blueMask); - glXVisualPtr[j].alphaSize = glXVisualPtr[j].alphaSize; - glXVisualPtr[j].redMask = pVisual[i].redMask; - glXVisualPtr[j].greenMask = pVisual[i].greenMask; - glXVisualPtr[j].blueMask = pVisual[i].blueMask; - glXVisualPtr[j].alphaMask = glXVisualPtr[j].alphaMask; - glXVisualPtr[j].bufferSize = rootDepth; - } - - /* Save the device-dependent private for this visual */ - glXVisualPriv[j] = pNewVisualPriv[k]; - - j++; - } + pVisual[i].class == DirectColor); + + if (!is_rgb) + { + /* We don't support non-rgb visuals for GL. But we don't + want to remove them either, so just pass them through + with null glX configs */ + + pVisualNew[j] = pVisual[i]; + pVisualNew[j].vid = FakeClientID(0); + + /* Check for the default visual */ + if (!found_default && pVisual[i].vid == *defaultVisp) { + *defaultVisp = pVisualNew[j].vid; + found_default = TRUE; + } + + /* Save the old VisualID */ + orig_vid[j] = pVisual[i].vid; + + /* Initialize the glXVisual */ + _gl_copy_visual_to_context_mode( modes, & NullConfig ); + modes->visualID = pVisualNew[j].vid; + + j++; + + continue; + } + + for (k = 0; k < numNewConfigs; k++) { + if (pNewVisualConfigs[k].rgba != is_rgb) + continue; + + assert( modes != NULL ); + + /* Initialize the new visual */ + pVisualNew[j] = pVisual[i]; + pVisualNew[j].vid = FakeClientID(0); + + /* Check for the default visual */ + if (!found_default && pVisual[i].vid == *defaultVisp) { + *defaultVisp = pVisualNew[j].vid; + found_default = TRUE; + } + + /* Save the old VisualID */ + orig_vid[j] = pVisual[i].vid; + + /* Initialize the glXVisual */ + _gl_copy_visual_to_context_mode( modes, & pNewVisualConfigs[k] ); + modes->visualID = pVisualNew[j].vid; + + /* + * If the class is -1, then assume the X visual information + * is identical to what GLX needs, and take them from the X + * visual. NOTE: if class != -1, then all other fields MUST + * be initialized. + */ + if (modes->visualType == GLX_NONE) { + modes->visualType = _gl_convert_from_x_visual_type( pVisual[i].class ); + modes->redBits = count_bits(pVisual[i].redMask); + modes->greenBits = count_bits(pVisual[i].greenMask); + modes->blueBits = count_bits(pVisual[i].blueMask); + modes->alphaBits = modes->alphaBits; + modes->redMask = pVisual[i].redMask; + modes->greenMask = pVisual[i].greenMask; + modes->blueMask = pVisual[i].blueMask; + modes->alphaMask = modes->alphaMask; + modes->rgbBits = (is_rgb) + ? (modes->redBits + modes->greenBits + + modes->blueBits + modes->alphaBits) + : rootDepth; + } + + /* Save the device-dependent private for this visual */ + glXVisualPriv[j] = pNewVisualPriv[k]; + + j++; + modes = modes->next; + } } assert(j <= numNewVisuals); /* Save the GLX visuals in the screen structure */ glAquaScreens[screenInfo.numScreens-1].num_vis = numNewVisuals; - glAquaScreens[screenInfo.numScreens-1].glx_vis = glXVisualPtr; glAquaScreens[screenInfo.numScreens-1].priv = glXVisualPriv; /* Set up depth's VisualIDs */ for (i = 0; i < ndepth; i++) { - int numVids = 0; - VisualID *pVids = NULL; - int k, n = 0; - - /* Count the new number of VisualIDs at this depth */ - for (j = 0; j < pdepth[i].numVids; j++) - for (k = 0; k < numNewVisuals; k++) - if (pdepth[i].vids[j] == orig_vid[k]) - numVids++; - - /* Allocate a new list of VisualIDs for this depth */ - pVids = (VisualID *)__glXMalloc(numVids * sizeof(VisualID)); - - /* Initialize the new list of VisualIDs for this depth */ - for (j = 0; j < pdepth[i].numVids; j++) - for (k = 0; k < numNewVisuals; k++) - if (pdepth[i].vids[j] == orig_vid[k]) - pVids[n++] = pVisualNew[k].vid; - - /* Update this depth's list of VisualIDs */ - __glXFree(pdepth[i].vids); - pdepth[i].vids = pVids; - pdepth[i].numVids = numVids; + int numVids = 0; + VisualID *pVids = NULL; + int k, n = 0; + + /* Count the new number of VisualIDs at this depth */ + for (j = 0; j < pdepth[i].numVids; j++) + for (k = 0; k < numNewVisuals; k++) + if (pdepth[i].vids[j] == orig_vid[k]) + numVids++; + + /* Allocate a new list of VisualIDs for this depth */ + pVids = (VisualID *)__glXMalloc(numVids * sizeof(VisualID)); + + /* Initialize the new list of VisualIDs for this depth */ + for (j = 0; j < pdepth[i].numVids; j++) + for (k = 0; k < numNewVisuals; k++) + if (pdepth[i].vids[j] == orig_vid[k]) + pVids[n++] = pVisualNew[k].vid; + + /* Update this depth's list of VisualIDs */ + __glXFree(pdepth[i].vids); + pdepth[i].vids = pVids; + pdepth[i].numVids = numVids; } /* Update the X server's visuals */ @@ -862,9 +1005,96 @@ static Bool init_visuals(int *nvisualp, VisualPtr *visualp, return TRUE; } -// Copied from Mesa +/* based on code in i830_dri.c + This ends calling glAquaSetVisualConfigs to set the static + numconfigs, etc. */ +static void +glAquaInitVisualConfigs(void) +{ + int lclNumConfigs = 0; + __GLXvisualConfig *lclVisualConfigs = NULL; + void **lclVisualPrivates = NULL; + + int depth, aux, buffers, stencil, accum; + int i = 0; + + GLAQUA_DEBUG_MSG("glAquaInitVisualConfigs "); + + /* count num configs: + 2 Z buffer (0, 24 bit) + 2 AUX buffer (0, 2) + 2 buffers (single, double) + 2 stencil (0, 8 bit) + 2 accum (0, 64 bit) + = 32 configs */ + + lclNumConfigs = 2 * 2 * 2 * 2 * 2; /* 32 */ + + /* alloc */ + lclVisualConfigs = xcalloc(sizeof(__GLXvisualConfig), lclNumConfigs); + lclVisualPrivates = xcalloc(sizeof(void *), lclNumConfigs); + + /* fill in configs */ + if (NULL != lclVisualConfigs) { + i = 0; /* current buffer */ + for (depth = 0; depth < 2; depth++) { + for (aux = 0; aux < 2; aux++) { + for (buffers = 0; buffers < 2; buffers++) { + for (stencil = 0; stencil < 2; stencil++) { + for (accum = 0; accum < 2; accum++) { + lclVisualConfigs[i].vid = -1; + lclVisualConfigs[i].class = -1; + lclVisualConfigs[i].rgba = TRUE; + lclVisualConfigs[i].redSize = -1; + lclVisualConfigs[i].greenSize = -1; + lclVisualConfigs[i].blueSize = -1; + lclVisualConfigs[i].redMask = -1; + lclVisualConfigs[i].greenMask = -1; + lclVisualConfigs[i].blueMask = -1; + lclVisualConfigs[i].alphaMask = 0; + if (accum) { + lclVisualConfigs[i].accumRedSize = 16; + lclVisualConfigs[i].accumGreenSize = 16; + lclVisualConfigs[i].accumBlueSize = 16; + lclVisualConfigs[i].accumAlphaSize = 16; + } + else { + lclVisualConfigs[i].accumRedSize = 0; + lclVisualConfigs[i].accumGreenSize = 0; + lclVisualConfigs[i].accumBlueSize = 0; + lclVisualConfigs[i].accumAlphaSize = 0; + } + lclVisualConfigs[i].doubleBuffer = buffers ? TRUE : FALSE; + lclVisualConfigs[i].stereo = FALSE; + lclVisualConfigs[i].bufferSize = -1; + + lclVisualConfigs[i].depthSize = depth? 24 : 0; + lclVisualConfigs[i].stencilSize = stencil ? 8 : 0; + lclVisualConfigs[i].auxBuffers = aux ? 2 : 0; + lclVisualConfigs[i].level = 0; + lclVisualConfigs[i].visualRating = GLX_NONE_EXT; + lclVisualConfigs[i].transparentPixel = 0; + lclVisualConfigs[i].transparentRed = 0; + lclVisualConfigs[i].transparentGreen = 0; + lclVisualConfigs[i].transparentBlue = 0; + lclVisualConfigs[i].transparentAlpha = 0; + lclVisualConfigs[i].transparentIndex = 0; + i++; + } + } + } + } + } + } + if (i != lclNumConfigs) + GLAQUA_DEBUG_MSG("glAquaInitVisualConfigs failed to alloc visual configs"); + + GlxSetVisualConfigs(lclNumConfigs, lclVisualConfigs, lclVisualPrivates); +} + + static void glAquaSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs, - void **privates) + void **privates) { GLAQUA_DEBUG_MSG("glAquaSetVisualConfigs\n"); @@ -873,19 +1103,21 @@ static void glAquaSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs, visualPrivates = privates; } -// Copied from Mesa static Bool glAquaInitVisuals(VisualPtr *visualp, DepthPtr *depthp, - int *nvisualp, int *ndepthp, - int *rootDepthp, VisualID *defaultVisp, - unsigned long sizes, int bitsPerRGB) + int *nvisualp, int *ndepthp, + int *rootDepthp, VisualID *defaultVisp, + unsigned long sizes, int bitsPerRGB) { GLAQUA_DEBUG_MSG("glAquaInitVisuals\n"); + if (numConfigs == 0) /* if no configs */ + glAquaInitVisualConfigs(); /* ensure the visual configs are setup */ + /* * Setup the visuals supported by this particular screen. */ return init_visuals(nvisualp, visualp, defaultVisp, - *ndepthp, *depthp, *rootDepthp); + *ndepthp, *depthp, *rootDepthp); } @@ -893,100 +1125,92 @@ static void fixup_visuals(int screen) { ScreenPtr pScreen = screenInfo.screens[screen]; glAquaScreenRec *pScr = &glAquaScreens[screen]; - __GLXvisualConfig *pGLXVis = pScr->glx_vis; - VisualPtr pVis; - int i, j; + int j; + __GLcontextModes *modes; GLAQUA_DEBUG_MSG("fixup_visuals\n"); - for (i = 0; i < pScr->num_vis; i++, pGLXVis++) { - pVis = pScreen->visuals; - - /* Find a visual that matches the GLX visual's class and size */ - for (j = 0; j < pScreen->numVisuals; j++, pVis++) { - if (pVis->class == pGLXVis->class && - pVis->nplanes == pGLXVis->bufferSize) { - - /* Fixup the masks */ - pGLXVis->redMask = pVis->redMask; - pGLXVis->greenMask = pVis->greenMask; - pGLXVis->blueMask = pVis->blueMask; - - /* Recalc the sizes */ - pGLXVis->redSize = count_bits(pGLXVis->redMask); - pGLXVis->greenSize = count_bits(pGLXVis->greenMask); - pGLXVis->blueSize = count_bits(pGLXVis->blueMask); - } - } + for ( modes = pScr->modes ; modes != NULL ; modes = modes->next ) { + const int vis_class = _gl_convert_to_x_visual_type( modes->visualType ); + const int nplanes = (modes->rgbBits - modes->alphaBits); + const VisualPtr pVis = pScreen->visuals; + + /* Find a visual that matches the GLX visual's class and size */ + for (j = 0; j < pScreen->numVisuals; j++) { + if (pVis[j].class == vis_class && + pVis[j].nplanes == nplanes) { + + /* Fixup the masks */ + modes->redMask = pVis[j].redMask; + modes->greenMask = pVis[j].greenMask; + modes->blueMask = pVis[j].blueMask; + + /* Recalc the sizes */ + modes->redBits = count_bits(modes->redMask); + modes->greenBits = count_bits(modes->greenMask); + modes->blueBits = count_bits(modes->blueMask); + } + } } } static void init_screen_visuals(int screen) { ScreenPtr pScreen = screenInfo.screens[screen]; - __GLXvisualConfig *pGLXVis = glAquaScreens[screen].glx_vis; - // XMesaVisual *pXMesaVisual; - VisualPtr pVis; + __GLcontextModes *modes; int *used; int i, j; GLAQUA_DEBUG_MSG("init_screen_visuals\n"); - /* Alloc space for the list of XMesa visuals */ - // pXMesaVisual = (XMesaVisual *)__glXMalloc(MESAScreens[screen].num_vis * - // sizeof(XMesaVisual)); - // __glXMemset(pXMesaVisual, 0, - // MESAScreens[screen].num_vis * sizeof(XMesaVisual)); - + /* FIXME: Change 'used' to be a array of bits (rather than of ints), + * FIXME: create a stack array of 8 or 16 bytes. If 'numVisuals' is less + * FIXME: than 64 or 128 the stack array can be used instead of calling + * FIXME: __glXMalloc / __glXFree. If nothing else, convert 'used' to + * FIXME: array of bytes instead of ints! + */ used = (int *)__glXMalloc(pScreen->numVisuals * sizeof(int)); __glXMemset(used, 0, pScreen->numVisuals * sizeof(int)); - for (i = 0; i < glAquaScreens[screen].num_vis; i++, pGLXVis++) { - pVis = pScreen->visuals; - for (j = 0; j < pScreen->numVisuals; j++, pVis++) { - - if (pVis->class == pGLXVis->class && - pVis->nplanes == pGLXVis->bufferSize && - !used[j]) { - - if (pVis->redMask == pGLXVis->redMask && - pVis->greenMask == pGLXVis->greenMask && - pVis->blueMask == pGLXVis->blueMask) { - - /* Create the XMesa visual */ - /* - pXMesaVisual[i] = - XMesaCreateVisual(pScreen, - pVis, - pGLXVis->rgba, - (pGLXVis->alphaSize > 0), - pGLXVis->doubleBuffer, - pGLXVis->stereo, - GL_TRUE, // ximage_flag - pGLXVis->depthSize, - pGLXVis->stencilSize, - pGLXVis->accumRedSize, - pGLXVis->accumGreenSize, - pGLXVis->accumBlueSize, - pGLXVis->accumAlphaSize, - 0, // numSamples - pGLXVis->level, - pGLXVis->visualRating ); - */ - /* Set the VisualID */ - pGLXVis->vid = pVis->vid; - - /* Mark this visual used */ - used[j] = 1; - break; - } - } - } + i = 0; + for ( modes = glAquaScreens[screen].modes + ; modes != NULL + ; modes = modes->next ) { + const int vis_class = _gl_convert_to_x_visual_type( modes->visualType ); + const int nplanes = (modes->rgbBits - modes->alphaBits); + const VisualPtr pVis = pScreen->visuals; + + for (j = 0; j < pScreen->numVisuals; j++) { + if (pVis[j].class == vis_class && + pVis[j].nplanes == nplanes && + pVis[j].redMask == modes->redMask && + pVis[j].greenMask == modes->greenMask && + pVis[j].blueMask == modes->blueMask && + !used[j]) { + + /* Set the VisualID */ + modes->visualID = pVis[j].vid; + + /* Mark this visual used */ + used[j] = 1; + break; + } + } + if ( j == pScreen->numVisuals ) { + ErrorF("No matching visual for __GLcontextMode with " + "visual class = %d (%d), nplanes = %u\n", + vis_class, + (int)modes->visualType, + (unsigned int)(modes->rgbBits - modes->alphaBits) ); + } + else if ( modes->visualID == -1 ) { + FatalError( "Matching visual found, but visualID still -1!\n" ); + } + + i++; } __glXFree(used); - - // glAquaScreens[screen].xm_vis = pXMesaVisual; } static Bool glAquaScreenProbe(int screen) @@ -999,10 +1223,10 @@ static Bool glAquaScreenProbe(int screen) /* * Set up the current screen's visuals. */ - __glDDXScreenInfo.pGlxVisual = glAquaScreens[screen].glx_vis; + __glDDXScreenInfo.modes = glAquaScreens[screen].modes; __glDDXScreenInfo.pVisualPriv = glAquaScreens[screen].priv; __glDDXScreenInfo.numVisuals = - __glDDXScreenInfo.numUsableVisuals = glAquaScreens[screen].num_vis; + __glDDXScreenInfo.numUsableVisuals = glAquaScreens[screen].num_vis; /* * Set the current screen's createContext routine. This could be @@ -1022,7 +1246,9 @@ static Bool glAquaScreenProbe(int screen) */ init_screen_visuals(screen); - // Wrap RealizeWindow and UnrealizeWindow on this screen + /* + * Wrap RealizeWindow and UnrealizeWindow on this screen + */ pScreen = screenInfo.screens[screen]; screenPriv = &glAquaScreens[screen]; screenPriv->RealizeWindow = pScreen->RealizeWindow; @@ -1035,28 +1261,28 @@ static Bool glAquaScreenProbe(int screen) static GLboolean glAquaResizeBuffers(__GLdrawableBuffer *buffer, - GLint x, GLint y, - GLuint width, GLuint height, - __GLdrawablePrivate *glPriv, - GLuint bufferMask) + GLint x, GLint y, + GLuint width, GLuint height, + __GLdrawablePrivate *glPriv, + GLuint bufferMask) { GLAquaDrawableRec *aquaPriv = (GLAquaDrawableRec *)glPriv->private; + __GLXdrawablePrivate *glxPriv = (__GLXdrawablePrivate *)glPriv->other; __GLXcontext *gx; __GLcontext *gc; - __GLXdrawablePrivate *glxPriv = (__GLXdrawablePrivate *)glPriv->other; GLAQUA_DEBUG_MSG("glAquaResizeBuffers to (%d %d %d %d)\n", x, y, width, height); // update all contexts that point at this drawable for drawing (hack?) - for (gx = glxPriv->drawGlxc; gx != NULL; gx = gx->next) { + for (gx = glxPriv->drawGlxc; gx != NULL; gx = gx->nextDrawPriv) { gc = (__GLcontext *)gx->gc; - attach(gc, glPriv, x, y, width, height); + attach(gc, glPriv); } // update all contexts that point at this drawable for reading (hack?) - for (gx = glxPriv->readGlxc; gx != NULL; gx = gx->next) { + for (gx = glxPriv->readGlxc; gx != NULL; gx = gx->nextReadPriv) { gc = (__GLcontext *)gx->gc; - attach(gc, glPriv, x, y, width, height); + attach(gc, glPriv); } return aquaPriv->resize(buffer, x, y, width, height, glPriv, bufferMask); @@ -1122,24 +1348,24 @@ GLint __glEvalComputeK(GLenum target) case GL_MAP2_VERTEX_4: case GL_MAP2_COLOR_4: case GL_MAP2_TEXTURE_COORD_4: - return 4; + return 4; case GL_MAP1_VERTEX_3: case GL_MAP1_TEXTURE_COORD_3: case GL_MAP1_NORMAL: case GL_MAP2_VERTEX_3: case GL_MAP2_TEXTURE_COORD_3: case GL_MAP2_NORMAL: - return 3; + return 3; case GL_MAP1_TEXTURE_COORD_2: case GL_MAP2_TEXTURE_COORD_2: - return 2; + return 2; case GL_MAP1_TEXTURE_COORD_1: case GL_MAP2_TEXTURE_COORD_1: case GL_MAP1_INDEX: case GL_MAP2_INDEX: - return 1; + return 1; default: - return 0; + return 0; } } @@ -1148,8 +1374,8 @@ GLuint __glFloorLog2(GLuint val) int c = 0; while (val > 1) { - c++; - val >>= 1; + c++; + val >>= 1; } return c; } |