diff options
Diffstat (limited to 'nx-X11/lib/GL/apple/dri_driver.c')
-rw-r--r-- | nx-X11/lib/GL/apple/dri_driver.c | 1141 |
1 files changed, 0 insertions, 1141 deletions
diff --git a/nx-X11/lib/GL/apple/dri_driver.c b/nx-X11/lib/GL/apple/dri_driver.c deleted file mode 100644 index ce8b0736a..000000000 --- a/nx-X11/lib/GL/apple/dri_driver.c +++ /dev/null @@ -1,1141 +0,0 @@ -/* $XFree86: xc/lib/GL/apple/dri_driver.c,v 1.2 2003/10/31 02:22:12 torrey Exp $ */ -/************************************************************************** - -Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. -Copyright (c) 2002 Apple Computer, Inc. -Copyright (c) 2004 Torrey T. Lyons -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sub license, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice (including the -next paragraph) shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. -IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR 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. - -**************************************************************************/ - -/* - * Original Authors: - * Kevin E. Martin <kevin@precisioninsight.com> - * Brian E. Paul <brian@precisioninsight.com> - */ - -/* - * This file follows Mesa's dri_util.c closely. The code in dri_util.c - * gets compiled into each of the DRI 3D drivers. A typical DRI driver, - * is loaded dynamically by libGL, so libGL knows nothing about the - * internal functions here. On Mac OS X the AppleDRI driver code is - * statically linked into libGL, but otherwise it tries to behave like - * a standard DRI driver. - * - * The functions defined here are called from the GL library via function - * pointers in the __DRIdisplayRec, __DRIscreenRec, __DRIcontextRec, - * __DRIdrawableRec structures defined in glxclient.h. Those function - * pointers are initialized by code in this file. The process starts when - * libGL calls the __driCreateScreen() function at the end of this file. - * - * The above-mentioned DRI structures have no dependencies on Mesa. - * Each structure instead has a generic (void *) private pointer that - * points to a private structure. For Mesa drivers, these private - * structures are the __DRIdrawablePrivateRec, __DRIcontextPrivateRec, - * __DRIscreenPrivateRec, and __DRIvisualPrivateRec structures defined - * in dri_mesaint.h. We allocate and attach those structs here in - * this file. - */ - - -#ifdef GLX_DIRECT_RENDERING - -/* These are first to ensure that Apple's GL headers are used. */ -#include <OpenGL/OpenGL.h> -#include <OpenGL/CGLContext.h> - -#include <unistd.h> -#include <X11/Xlibint.h> -#include <X11/extensions/Xext.h> - -#define GLAPIENTRYP * -#include "extutil.h" -#include "glxclient.h" -#include "appledri.h" -#include "dri_driver.h" -#include "x-list.h" -#include "x-hash.h" - -/** - * This is used in a couple of places that call \c driMesaCreateNewDrawable. - */ -static const int empty_attribute_list[1] = { None }; - -/* Context binding */ -static Bool driMesaBindContext(Display *dpy, int scrn, - GLXDrawable draw, GLXContext gc); -static Bool driMesaUnbindContext(Display *dpy, int scrn, - GLXDrawable draw, GLXContext gc, - int will_rebind); - -/* Drawable methods */ -static void *driMesaCreateNewDrawable(__DRInativeDisplay *dpy, - const __GLcontextModes *modes, - __DRIid draw, __DRIdrawable *pdraw, - int renderType, const int *attrs); -static __DRIdrawable *driMesaGetDrawable(__DRInativeDisplay *dpy, - GLXDrawable draw, - void *screenPrivate); -static void driMesaSwapBuffers(__DRInativeDisplay *dpy, void *drawPrivate); -static void driMesaDestroyDrawable(__DRInativeDisplay *dpy, void *drawPrivate); - -/* Context methods */ -static void *driMesaCreateContext(Display *dpy, XVisualInfo *vis, void *shared, - __DRIcontext *pctx); -static void driMesaDestroyContext(__DRInativeDisplay *dpy, int scrn, - void *screenPrivate); - -/* Screen methods */ -static void *driMesaCreateScreen(__DRInativeDisplay *dpy, int scrn, - __DRIscreen *psc, int numConfigs, - __GLXvisualConfig *config); -static void driMesaDestroyScreen(__DRInativeDisplay *dpy, int scrn, - void *screenPrivate); - -static void driMesaCreateSurface(Display *dpy, int scrn, - __DRIdrawablePrivate *pdp); - -static void unwrap_context(__DRIcontextPrivate *pcp); -static void wrap_context(__DRIcontextPrivate *pcp); - -extern const CGLContextObj XAppleDRIGetIndirectContext(void); - -/*****************************************************************/ - -/* Maintain a list of drawables */ - -static inline Bool -__driMesaAddDrawable(x_hash_table *drawHash, __DRIdrawable *pdraw) -{ - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private; - - assert(drawHash != NULL); - - x_hash_table_insert(drawHash, (void *) pdp->draw, pdraw); - - return GL_TRUE; -} - -static inline __DRIdrawable * -__driMesaFindDrawable(x_hash_table *drawHash, GLXDrawable draw) -{ - if (drawHash == NULL) - return NULL; - - return x_hash_table_lookup(drawHash, (void *) draw, NULL); -} - -struct find_by_uid_closure { - unsigned int uid; - __DRIdrawable *ret; -}; - -static void -find_by_uid_cb(void *k, void *v, void *data) -{ - __DRIdrawable *pdraw = v; - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private; - struct find_by_uid_closure *c = data; - - if (pdp->uid == c->uid) - c->ret = pdraw; -} - -static __DRIdrawable * -__driMesaFindDrawableByUID(x_hash_table *drawHash, unsigned int uid) -{ - struct find_by_uid_closure c; - - c.uid = uid; - c.ret = NULL; - x_hash_table_foreach(drawHash, find_by_uid_cb, &c); - - return c.ret; -} - -static inline void -__driMesaRemoveDrawable(x_hash_table *drawHash, __DRIdrawable *pdraw) -{ - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private; - - if (drawHash == NULL) - return; - - x_hash_table_remove(drawHash, (void *) pdp->draw); -} - -static Bool __driMesaWindowExistsFlag; - -static int __driMesaWindowExistsErrorHandler(Display *dpy, XErrorEvent *xerr) -{ - if (xerr->error_code == BadWindow) { - __driMesaWindowExistsFlag = GL_FALSE; - } - return 0; -} - -static Bool __driMesaWindowExists(Display *dpy, GLXDrawable draw) -{ - XWindowAttributes xwa; - int (*oldXErrorHandler)(Display *, XErrorEvent *); - - __driMesaWindowExistsFlag = GL_TRUE; - oldXErrorHandler = XSetErrorHandler(__driMesaWindowExistsErrorHandler); - XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */ - XSetErrorHandler(oldXErrorHandler); - return __driMesaWindowExistsFlag; -} - -static void __driMesaCollectCallback(void *k, void *v, void *data) -{ - GLXDrawable draw = (GLXDrawable) k; - __DRIdrawable *pdraw = v; - x_list **todelete = data; - - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private; - Display *dpy; - - dpy = pdp->driScreenPriv->display; - XSync(dpy, GL_FALSE); - if (!pdp->destroyed && !__driMesaWindowExists(dpy, draw)) { - /* Destroy the local drawable data in the hash table, if the - drawable no longer exists in the Xserver */ - pdp->destroyed = TRUE; - *todelete = x_list_prepend(*todelete, pdraw); - } -} - -/* pdp->mutex is held. */ -static void __driMesaGarbageCollectDrawables(void *drawHash) -{ - __DRIdrawable *pdraw; - __DRIdrawablePrivate *pdp; - Display *dpy; - x_list *todelete = NULL, *node; - - x_hash_table_foreach(drawHash, __driMesaCollectCallback, &todelete); - - for (node = todelete; node != NULL; node = node->next) - { - pdraw = node->data; - pdp = (__DRIdrawablePrivate *)pdraw->private; - dpy = pdp->driScreenPriv->display; - - /* Destroy the local drawable data in the hash table, if the - drawable no longer exists in the Xserver */ - - __driMesaRemoveDrawable(drawHash, pdraw); - (*pdraw->destroyDrawable)(dpy, pdraw->private); - Xfree(pdraw); - } - - x_list_free(todelete); -} - -/*****************************************************************/ - -/* returns with psp->mutex locked if successful. */ -static Bool -driMesaFindDrawableByUID(Display *dpy,unsigned int uid, - __DRIscreenPrivate **psp_ret, - __DRIdrawablePrivate **pdp_ret) -{ - __DRIscreen *pDRIScreen; - __DRIscreenPrivate *psp; - __DRIdrawable *pdraw; - int scrn; - - for (scrn = 0; scrn < ScreenCount(dpy); scrn++) - { - if (!(pDRIScreen = __glXFindDRIScreen(dpy, scrn))) { - /* ERROR!!! */ - return FALSE; - } else if (!(psp = (__DRIscreenPrivate *)pDRIScreen->private)) { - /* ERROR!!! */ - return FALSE; - } - - xmutex_lock(psp->mutex); - - pdraw = __driMesaFindDrawableByUID(psp->drawHash, uid); - if (pdraw != NULL) { - *psp_ret = psp; - *pdp_ret = pdraw->private; - return TRUE; - }; - - xmutex_unlock(psp->mutex); - } - - return FALSE; -} - -static void -unbind_context(__DRIcontextPrivate *pcp) -{ - /* Unbind the context from its old drawable. */ - - if (pcp->driDrawablePriv != NULL) - { - if (pcp->next != NULL) - pcp->next->prev = pcp->prev; - if (pcp->prev != NULL) - pcp->prev->next = pcp->next; - - if (pcp->driDrawablePriv->driContextPriv == pcp) - pcp->driDrawablePriv->driContextPriv = pcp->next; - - pcp->driDrawablePriv = NULL; - pcp->prev = pcp->next = NULL; - } - - if (pcp->surface_id != 0) - { - pcp->surface_id = 0; - pcp->pending_clear = TRUE; - } -} - -static void -unbind_drawable(__DRIdrawablePrivate *pdp) -{ - __DRIcontextPrivate *pcp, *next; - - for (pcp = pdp->driContextPriv; pcp != NULL; pcp = next) - { - next = pcp->next; - unbind_context(pcp); - } -} - -static void -update_context(__DRIcontextPrivate *pcp) -{ - if (pcp->pending_clear) - { - CGLClearDrawable(pcp->ctx); - pcp->pending_clear = FALSE; - } - - if (pcp->pending_update && pcp->surface_id != 0) - { - xp_update_gl_context(pcp->ctx); - pcp->pending_update = FALSE; - } -} - -static Bool driMesaUnbindContext(Display *dpy, int scrn, - GLXDrawable draw, GLXContext gc, - int will_rebind) -{ - __DRIscreen *pDRIScreen; -// __DRIdrawable *pdraw; - __DRIcontextPrivate *pcp; - __DRIscreenPrivate *psp; - __DRIdrawablePrivate *pdp; - - /* - ** Assume error checking is done properly in glXMakeCurrent before - ** calling driMesaUnbindContext. - */ - - if (gc == NULL || draw == None) { - /* ERROR!!! */ - return GL_FALSE; - } - - if (!(pDRIScreen = __glXFindDRIScreen(dpy, scrn))) { - /* ERROR!!! */ - return GL_FALSE; - } else if (!(psp = (__DRIscreenPrivate *)pDRIScreen->private)) { - /* ERROR!!! */ - return GL_FALSE; - } - - xmutex_lock(psp->mutex); - - pcp = (__DRIcontextPrivate *)gc->driContext.private; - - pdp = pcp->driDrawablePriv; - if (pdp == NULL) { - /* ERROR!!! */ - xmutex_unlock(psp->mutex); - return GL_FALSE; - } - - /* Put this thread back into normal (indirect) dispatch mode. */ - CGLSetCurrentContext(XAppleDRIGetIndirectContext()); - pcp->thread_id = 0; - - /* Lazily unbind the drawable from the context */ - unbind_context(pcp); - - if (pdp->refcount == 0) { - /* ERROR!!! */ - xmutex_unlock(psp->mutex); - return GL_FALSE; - } else if (--pdp->refcount == 0) { -#if 0 - /* - ** NOT_DONE: When a drawable is unbound from one direct - ** rendering context and then bound to another, we do not want - ** to destroy the drawable data structure each time only to - ** recreate it immediatly afterwards when binding to the next - ** context. This also causes conflicts with caching of the - ** drawable stamp. - ** - ** In addition, we don't destroy the drawable here since Mesa - ** keeps private data internally (e.g., software accumulation - ** buffers) that should not be destroyed unless the client - ** explicitly requests that the window be destroyed. - ** - ** When GLX 1.3 is integrated, the create and destroy drawable - ** functions will have user level counterparts and the memory - ** will be able to be recovered. - ** - ** Below is an example of what needs to go into the destroy - ** drawable routine to support GLX 1.3. - */ - __driMesaRemoveDrawable(psp->drawHash, pdraw); - (*pdraw->destroyDrawable)(dpy, pdraw->private); - Xfree(pdraw); -#endif - } - - xmutex_unlock(psp->mutex); - return GL_TRUE; -} - -static Bool driMesaBindContext(Display *dpy, int scrn, - GLXDrawable draw, GLXContext gc) -{ - __DRIscreen *pDRIScreen; - const __GLcontextModes *modes; - __DRIdrawable *pdraw; - __DRIdrawablePrivate *pdp; - __DRIscreenPrivate *psp; - __DRIcontextPrivate *pcp; - - /* - ** Assume error checking is done properly in glXMakeCurrent before - ** calling driMesaBindContext. - */ - - if (gc == NULL || draw == None) { - /* ERROR!!! */ - return GL_FALSE; - } - - if (!(pDRIScreen = __glXFindDRIScreen(dpy, scrn))) { - /* ERROR!!! */ - return GL_FALSE; - } else if (!(psp = (__DRIscreenPrivate *)pDRIScreen->private)) { - /* ERROR!!! */ - return GL_FALSE; - } - - modes = gc->driContext.mode; - - if ( modes == NULL ) { - /* ERROR!!! */ - return GL_FALSE; - } - - xmutex_lock(psp->mutex); - - pdraw = __driMesaFindDrawable(psp->drawHash, draw); - if (!pdraw) { - /* Allocate a new drawable */ - pdraw = (__DRIdrawable *)Xmalloc(sizeof(__DRIdrawable)); - if (!pdraw) { - /* ERROR!!! */ - xmutex_unlock(psp->mutex); - return GL_FALSE; - } - - /* Create a new drawable */ - pdraw->private = driMesaCreateNewDrawable(dpy, modes, draw, pdraw, - GLX_WINDOW_BIT, - empty_attribute_list); - if (!pdraw->private) { - /* ERROR!!! */ - Xfree(pdraw); - xmutex_unlock(psp->mutex); - return GL_FALSE; - } - - /* Add pdraw to drawable list */ - if (!__driMesaAddDrawable(psp->drawHash, pdraw)) { - /* ERROR!!! */ - (*pdraw->destroyDrawable)(dpy, pdraw->private); - Xfree(pdraw); - xmutex_unlock(psp->mutex); - return GL_FALSE; - } - } - - pdp = (__DRIdrawablePrivate *)pdraw->private; - pcp = (__DRIcontextPrivate *)gc->driContext.private; - - if (pdp->surface_id == 0) - { - /* Surface got destroyed. Try to create a new one. */ - - driMesaCreateSurface(dpy, scrn, pdp); - } - - unbind_context(pcp); - - /* Bind the drawable to the context */ - pcp->driDrawablePriv = pdp; - pcp->prev = NULL; - pcp->next = pdp->driContextPriv; - pdp->driContextPriv = pcp; - pdp->refcount++; - - /* And the physical surface to the physical context */ - if (pcp->surface_id != pdp->surface_id) - { - pcp->surface_id = 0; - - /* Attaching the drawable sets the default viewport. But we don't - want to catch that call to glViewport in our wrappers. */ - unwrap_context(pcp); - - if (pdp->surface_id == 0) - CGLClearDrawable(pcp->ctx); - else if (xp_attach_gl_context(pcp->ctx, pdp->surface_id) == Success) - pcp->surface_id = pdp->surface_id; - else - fprintf(stderr, "failed to bind to surface\n"); - - wrap_context(pcp); - - pcp->pending_clear = FALSE; - pcp->pending_update = FALSE; - } - else if (pcp->pending_clear) - { - CGLClearDrawable(pcp->ctx); - pcp->pending_clear = FALSE; - } - - /* Activate the CGL context and remember which thread it's current for. */ - CGLSetCurrentContext(pcp->ctx); - pcp->thread_id = xthread_self(); - - xmutex_unlock(psp->mutex); - return GL_TRUE; -} - -/*****************************************************************/ - -static xp_client_id -get_client_id(void) -{ - static xp_client_id id; - - if (id == 0) - { - if (xp_init(XP_IN_BACKGROUND) != Success - || xp_get_client_id(&id) != Success) - { - return 0; - } - } - - return id; -} - -static void driMesaCreateSurface(Display *dpy, int scrn, - __DRIdrawablePrivate *pdp) -{ - xp_client_id client_id; - unsigned int key[2]; - - pdp->surface_id = 0; - pdp->uid = 0; - - client_id = get_client_id(); - if (client_id == 0) - return; - - if (XAppleDRICreateSurface(dpy, scrn, pdp->draw, - client_id, key, &pdp->uid)) - { - xp_import_surface(key, &pdp->surface_id); - } -} - -/** - * This is called via __DRIscreenRec's createNewDrawable pointer. - */ -static void *driMesaCreateNewDrawable(__DRInativeDisplay *dpy, - const __GLcontextModes *modes, - __DRIid draw, - __DRIdrawable *pdraw, - int renderType, - const int *attrs) -{ - __DRIscreen * const pDRIScreen = __glXFindDRIScreen(dpy, modes->screen); - __DRIscreenPrivate *psp; - __DRIdrawablePrivate *pdp; - - - pdraw->private = NULL; - - /* Since pbuffers are not yet supported, no drawable attributes are - * supported either. - */ - (void) attrs; - - if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { - return NULL; - } - - pdp = (__DRIdrawablePrivate *)Xmalloc(sizeof(__DRIdrawablePrivate)); - if (!pdp) { - return NULL; - } - - pdp->draw = draw; - pdp->refcount = 0; - pdp->surface_id = 0; - pdp->uid = 0; - pdp->destroyed = FALSE; - - psp = (__DRIscreenPrivate *)pDRIScreen->private; - pdp->driScreenPriv = psp; - pdp->driContextPriv = NULL; - - driMesaCreateSurface(dpy, modes->screen, pdp); - if (pdp->surface_id == 0) { - Xfree(pdp); - return NULL; - } - - pdraw->private = pdp; - pdraw->destroyDrawable = driMesaDestroyDrawable; - pdraw->swapBuffers = driMesaSwapBuffers; /* called by glXSwapBuffers() */ - -#if 0 - /* We don't support these yet. */ - if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) { - pdraw->getSBC = driGetSBC; - pdraw->waitForSBC = driWaitForSBC; - pdraw->waitForMSC = driWaitForMSC; - pdraw->swapBuffersMSC = driSwapBuffersMSC; - pdraw->frameTracking = NULL; - pdraw->queryFrameTracking = driQueryFrameTracking; - - /* This special default value is replaced with the configured - * default value when the drawable is first bound to a direct - * rendering context. */ - pdraw->swap_interval = (unsigned)-1; - } -#endif - - return (void *) pdp; -} - -static __DRIdrawable *driMesaGetDrawable(__DRInativeDisplay *dpy, - GLXDrawable draw, - void *screenPrivate) -{ - __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate; - __DRIdrawable *dri_draw; - - xmutex_lock(psp->mutex); - - /* - ** Make sure this routine returns NULL if the drawable is not bound - ** to a direct rendering context! - */ - dri_draw = __driMesaFindDrawable(psp->drawHash, draw); - - xmutex_unlock(psp->mutex); - return dri_draw; -} - -static void driMesaSwapBuffers(__DRInativeDisplay *dpy, void *drawPrivate) -{ - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *) drawPrivate; - __DRIcontextPrivate *pcp; - xthread_t self = xthread_self(); - static Bool warned; - - xmutex_lock(pdp->driScreenPriv->mutex); - - /* FIXME: this is sub-optimal, since we may not always find a context - bound to the given drawable on this thread. */ - - for (pcp = pdp->driContextPriv; pcp != NULL; pcp = pcp->next) - { - if (pcp->thread_id == self || pcp->thread_id == 0) - break; - } - - if (pcp != NULL) - { - CGLFlushDrawable(pcp->ctx); - } - else - { - if (!warned) { - fprintf(stderr, "glXSwapBuffers: no context for this drawable\n"); - warned = TRUE; - } - } - - xmutex_unlock(pdp->driScreenPriv->mutex); -} - -/* pdp->mutex is held. */ -static void driMesaDestroyDrawable(__DRInativeDisplay *dpy, void *drawPrivate) -{ - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)drawPrivate; - - if (pdp) { - unbind_drawable(pdp); - if (pdp->surface_id != 0) { - xp_destroy_surface(pdp->surface_id); - pdp->surface_id = 0; - } - if (!pdp->destroyed) { - /* don't try to destroy an already destroyed surface. */ - XAppleDRIDestroySurface(dpy, pdp->driScreenPriv->myNum, pdp->draw); - } - Xfree(pdp); - } -} - -/*****************************************************************/ - -static CGLPixelFormatObj -driCreatePixelFormat(Display *dpy, __DRIscreenPrivate *psp, - XVisualInfo *visinfo, __GLXvisualConfig *config) -{ - int i; - CGLPixelFormatAttribute attr[64]; // currently uses max of 30 - CGLPixelFormatObj result; - long n_formats; - - i = 0; - - if (!config->rgba) - return NULL; - - if (config->stereo) - attr[i++] = kCGLPFAStereo; - - if (config->doubleBuffer) - attr[i++] = kCGLPFADoubleBuffer; - - attr[i++] = kCGLPFAColorSize; - attr[i++] = config->redSize + config->greenSize + config->blueSize; - attr[i++] = kCGLPFAAlphaSize; - attr[i++] = 1; /* FIXME: ignoring config->alphaSize which is always 0 */ - - if (config->accumRedSize + config->accumGreenSize - + config->accumBlueSize + config->accumAlphaSize > 0) - { - attr[i++] = kCGLPFAAccumSize; - attr[i++] = (config->accumRedSize + config->accumGreenSize - + config->accumBlueSize + config->accumAlphaSize); - } - - if (config->depthSize > 0) { - attr[i++] = kCGLPFADepthSize; - attr[i++] = config->depthSize; - } - - if (config->stencilSize > 0) { - attr[i++] = kCGLPFAStencilSize; - attr[i++] = config->stencilSize; - } - - if (config->auxBuffers > 0) { - attr[i++] = kCGLPFAAuxBuffers; - attr[i++] = config->auxBuffers; - } - - /* FIXME: things we don't handle: color/alpha masks, level, - visualrating, transparentFoo */ - - attr[i++] = 0; - - result = NULL; - CGLChoosePixelFormat(attr, &result, &n_formats); - - return result; -} - -static void *driMesaCreateContext(Display *dpy, XVisualInfo *vis, void *shared, - __DRIcontext *pctx) -{ - __DRIscreen *pDRIScreen; - __DRIcontextPrivate *pcp; - __DRIcontextPrivate *pshare = (__DRIcontextPrivate *)shared; - __DRIscreenPrivate *psp; - int i; - - if (!(pDRIScreen = __glXFindDRIScreen(dpy, vis->screen))) { - /* ERROR!!! */ - return NULL; - } else if (!(psp = (__DRIscreenPrivate *)pDRIScreen->private)) { - /* ERROR!!! */ - return NULL; - } - - /* Create the hash table */ - if (!psp->drawHash) { - xmutex_lock(psp->mutex); - if (!psp->drawHash) - psp->drawHash = x_hash_table_new(NULL, NULL, NULL, NULL); - xmutex_unlock(psp->mutex); - } - - pcp = (__DRIcontextPrivate *)Xmalloc(sizeof(__DRIcontextPrivate)); - if (!pcp) { - return NULL; - } - - pcp->display = dpy; - pcp->driScreenPriv = psp; - pcp->driDrawablePriv = NULL; - - pcp->ctx = NULL; - pcp->surface_id = 0; - - pcp->pending_clear = FALSE; - pcp->pending_update = FALSE; - - pcp->ctx = NULL; - for (i = 0; pcp->ctx == NULL && i < psp->numVisuals; i++) { - if (psp->visuals[i].vid == vis->visualid) { - CGLCreateContext(psp->visuals[i].pixel_format, - pshare ? pshare->ctx : NULL, &pcp->ctx); - } - } - - if (!pcp->ctx) { - Xfree(pcp); - return NULL; - } - - pctx->destroyContext = driMesaDestroyContext; - pctx->bindContext = driMesaBindContext; - pctx->unbindContext = driMesaUnbindContext; - - wrap_context(pcp); - - xmutex_lock(psp->mutex); - __driMesaGarbageCollectDrawables(pcp->driScreenPriv->drawHash); - xmutex_unlock(psp->mutex); - - return pcp; -} - -static void driMesaDestroyContext(__DRInativeDisplay *dpy, int scrn, - void *contextPrivate) -{ - __DRIcontextPrivate *pcp = (__DRIcontextPrivate *) contextPrivate; - - if (pcp) { - xmutex_lock(pcp->driScreenPriv->mutex); - unbind_context(pcp); - __driMesaGarbageCollectDrawables(pcp->driScreenPriv->drawHash); - xmutex_unlock(pcp->driScreenPriv->mutex); - CGLDestroyContext(pcp->ctx); - Xfree(pcp); - } -} - -/*****************************************************************/ - -static void *driMesaCreateScreen(__DRInativeDisplay *dpy, int scrn, - __DRIscreen *psc, int numConfigs, - __GLXvisualConfig *config) -{ - int directCapable, i, n; - __DRIscreenPrivate *psp; - XVisualInfo visTmpl, *visinfo; - - if (!XAppleDRIQueryDirectRenderingCapable(dpy, scrn, &directCapable)) { - return NULL; - } - - if (!directCapable) { - return NULL; - } - - psp = (__DRIscreenPrivate *)Xmalloc(sizeof(__DRIscreenPrivate)); - if (!psp) { - return NULL; - } - - psp->mutex = xmutex_malloc(); - if (psp->mutex != NULL) { - xmutex_init (psp->mutex); - xmutex_set_name (psp->mutex, "AppleDRI"); - } - psp->display = dpy; - psp->myNum = scrn; - -#if 0 - if (!XAppleDRIAuthConnection(dpy, scrn, magic)) { - Xfree(psp); - (void)XAppleDRICloseConnection(dpy, scrn); - return NULL; - } -#endif - - /* - * Allocate space for an array of visual records and initialize them. - */ - psp->visuals = (__DRIvisualPrivate *)Xmalloc(numConfigs * - sizeof(__DRIvisualPrivate)); - if (!psp->visuals) { - Xfree(psp); - return NULL; - } - - visTmpl.screen = scrn; - visinfo = XGetVisualInfo(dpy, VisualScreenMask, &visTmpl, &n); - if (n != numConfigs) { - Xfree(psp); - return NULL; - } - - psp->numVisuals = 0; - for (i = 0; i < numConfigs; i++, config++) { - psp->visuals[psp->numVisuals].vid = visinfo[i].visualid; - psp->visuals[psp->numVisuals].pixel_format = - driCreatePixelFormat(dpy, psp, &visinfo[i], config); - if (psp->visuals[psp->numVisuals].pixel_format != NULL) { - psp->numVisuals++; - } - } - - XFree(visinfo); - - if (psp->numVisuals == 0) { - /* Couldn't create any pixel formats. */ - Xfree(psp->visuals); - Xfree(psp); - return NULL; - } - - /* Initialize the drawHash when the first context is created */ - psp->drawHash = NULL; - - psc->destroyScreen = driMesaDestroyScreen; - psc->createContext = driMesaCreateContext; - psc->createNewDrawable = driMesaCreateNewDrawable; - psc->getDrawable = driMesaGetDrawable; - - return (void *)psp; -} - -static void driMesaDestroyScreen(__DRInativeDisplay *dpy, int scrn, - void *screenPrivate) -{ - __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate; - - if (psp) { - //FIXME resetDriver ? - Xfree(psp->visuals); - Xfree(psp); - } -} - -/* Note: definitely can't make any X protocol requests here. */ -static void driAppleSurfaceNotify(Display *dpy, unsigned int uid, int kind) -{ - __DRIscreenPrivate *psp; - __DRIdrawablePrivate *pdp; - __DRIcontextPrivate *pcp; - - /* locks psp->mutex if successful. */ - if (driMesaFindDrawableByUID(dpy, uid, &psp, &pdp)) - { - xthread_t self = xthread_self(); - - switch (kind) - { - Bool all_safe; - - case AppleDRISurfaceNotifyDestroyed: - xp_destroy_surface(pdp->surface_id); - pdp->surface_id = 0; - - for (pcp = pdp->driContextPriv; pcp != NULL; pcp = pcp->next) - { - pcp->surface_id = 0; - - if (pcp->thread_id == self || pcp->thread_id == 0) { - CGLClearDrawable(pcp->ctx); - pcp->pending_clear = FALSE; - } else - pcp->pending_clear = TRUE; - } - break; - - case AppleDRISurfaceNotifyChanged: - all_safe = TRUE; - for (pcp = pdp->driContextPriv; pcp != NULL; pcp = pcp->next) - { - if (pcp->thread_id != 0 && pcp->thread_id != self) { - all_safe = FALSE; - break; - } - } - for (pcp = pdp->driContextPriv; pcp != NULL; pcp = pcp->next) - { - if (all_safe) { - xp_update_gl_context(pcp->ctx); - pcp->pending_update = FALSE; - } else - pcp->pending_update = TRUE; - } - break; - } - - xmutex_unlock(psp->mutex); - } -} - -/** - * Entrypoint function used to create a new driver-private screen structure. - * - * \param dpy Display pointer. - * \param scrn Index of the screen. - * \param psc DRI screen data (not driver private) - * \param numConfigs Number of visual configs pointed to by \c configs. - * \param config Array of GLXvisualConfigs exported by the 2D driver. - * - * \deprecated - * In dynamically linked drivers, this function has been replaced by - * \c __driCreateNewScreen. - */ -void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, - int numConfigs, __GLXvisualConfig *config) -{ - static int here_before; - - if (!here_before) - { - XAppleDRISetSurfaceNotifyHandler(driAppleSurfaceNotify); - here_before = True; - } - - return driMesaCreateScreen(dpy, scrn, psc, numConfigs, config); -} - -void __driRegisterExtensions(void) -{ -} - -__private_extern__ void XAppleDRIUseIndirectDispatch(void) -{ - CGLSetCurrentContext(XAppleDRIGetIndirectContext()); -} - -/*****************************************************************/ - -/* - * Currently (Mac OS X 10.3) the only way we have of regaining control - * from threads calling GL and nothing else is by patching the dispatch - * table of the CGLContext, so that glViewport, glFlush and glFinish - * call us back. - * - * Since glNewList and glEndList overwrite the entire dispatch table we - * also need to patch those so we can restore the others. - * - * WARNING: This is not expected to work on future OS releases. - */ - -#define WRAP_CGL(context, vec, fun) \ - do { \ - (context)->disp.vec = (context)->ctx->disp.vec; \ - (context)->ctx->disp.vec = (fun); \ - } while (0) - -#define UNWRAP_CGL(context, vec) \ - do { \ - (context)->ctx->disp.vec = (context)->disp.vec; \ - } while (0) - -#define WRAP_BOILERPLATE \ - GLXContext gc; \ - __DRIcontextPrivate *pcp; \ - gc = __glXGetCurrentContext(); \ - if (gc == NULL || !gc->isDirect) return; \ - pcp = (__DRIcontextPrivate *) gc->driContext.private; \ - if (pcp == NULL) return; - -static void viewport_callback(GLIContext ctx, GLint x, GLint y, - GLsizei width, GLsizei height) -{ - WRAP_BOILERPLATE - - xmutex_lock(pcp->driScreenPriv->mutex); - update_context(pcp); - xmutex_unlock(pcp->driScreenPriv->mutex); - - (*pcp->disp.viewport)(ctx, x, y, width, height); -} - -static void new_list_callback(GLIContext ctx, GLuint list, GLenum mode) -{ - WRAP_BOILERPLATE - - unwrap_context(pcp); - (*pcp->ctx->disp.new_list)(ctx, list, mode); - wrap_context(pcp); -} - -static void end_list_callback(GLIContext ctx) -{ - WRAP_BOILERPLATE - - unwrap_context(pcp); - (*pcp->ctx->disp.end_list)(ctx); - wrap_context(pcp); -} - -static void unwrap_context(__DRIcontextPrivate *pcp) -{ - UNWRAP_CGL(pcp, viewport); - UNWRAP_CGL(pcp, new_list); - UNWRAP_CGL(pcp, end_list); -} - -static void wrap_context(__DRIcontextPrivate *pcp) -{ - WRAP_CGL(pcp, new_list, new_list_callback); - WRAP_CGL(pcp, end_list, end_list_callback); - WRAP_CGL(pcp, viewport, viewport_callback); -} - -#endif /* GLX_DIRECT_RENDERING */ |