Remove XIDs from DRI interface (see #5714).

This commit is contained in:
Kristian Høgsberg 2007-01-07 08:12:01 -05:00
parent 4ceefccbfa
commit 4a22ae8d44
11 changed files with 213 additions and 320 deletions

View File

@ -48,16 +48,16 @@
* side library and the DRI (direct rendering infrastructure).
*/
/*@{*/
typedef struct __DRIdisplayRec __DRIdisplay;
typedef struct __DRIscreenRec __DRIscreen;
typedef struct __DRIcontextRec __DRIcontext;
typedef struct __DRIdrawableRec __DRIdrawable;
typedef struct __DRIdriverRec __DRIdriver;
typedef struct __DRIframebufferRec __DRIframebuffer;
typedef struct __DRIversionRec __DRIversion;
typedef struct __DRIinterfaceMethodsRec __DRIinterfaceMethods;
typedef unsigned long __DRIid;
typedef void __DRInativeDisplay;
typedef struct __DRIdisplayRec __DRIdisplay;
typedef struct __DRIscreenRec __DRIscreen;
typedef struct __DRIcontextRec __DRIcontext;
typedef struct __DRIdrawableRec __DRIdrawable;
typedef struct __DRIdriverRec __DRIdriver;
typedef struct __DRIframebufferRec __DRIframebuffer;
typedef struct __DRIversionRec __DRIversion;
typedef struct __DRIinterfaceMethodsRec __DRIinterfaceMethods;
typedef unsigned long __DRIid;
typedef void __DRInativeDisplay;
/*@}*/
@ -106,7 +106,7 @@ typedef void *(CREATENEWSCREENFUNC)(__DRInativeDisplay *dpy, int scrn,
const __DRIinterfaceMethods * interface,
__GLcontextModes ** driver_modes);
typedef CREATENEWSCREENFUNC* PFNCREATENEWSCREENFUNC;
extern CREATENEWSCREENFUNC __driCreateNewScreen_20050727;
extern CREATENEWSCREENFUNC __driCreateNewScreen_20070105;
/**
@ -170,16 +170,6 @@ struct __DRIinterfaceMethodsRec {
* the wire protocol (e.g., EGL) will implement glorified no-op functions.
*/
/*@{*/
/**
* Determine if the specified window ID still exists.
*
* \note
* Implementations may assume that the driver will only pass an ID into
* this function that actually corresponds to a window. On
* implementations where windows can only be destroyed by the DRI driver
* (e.g., EGL), this function is allowed to always return \c GL_TRUE.
*/
GLboolean (*windowExists)(__DRInativeDisplay *dpy, __DRIid draw);
/**
* Create the server-side portion of the GL context.
@ -306,12 +296,6 @@ struct __DRIscreenRec {
__DRIid draw, __DRIdrawable *pdraw,
int renderType, const int *attrs);
/**
* Method to return a pointer to the DRI drawable data.
*/
__DRIdrawable *(*getDrawable)(__DRInativeDisplay *dpy, __DRIid draw,
void *drawablePrivate);
/**
* Opaque pointer to private per screen direct rendering data. \c NULL
* if direct rendering is not supported on this screen. Never
@ -392,28 +376,23 @@ struct __DRIcontextRec {
*/
void *private;
/**
* Pointer to the mode used to create this context.
*
* \since Internal API version 20040317.
*/
const __GLcontextModes * mode;
/**
* Method to bind a DRI drawable to a DRI graphics context.
*
* \since Internal API version 20050727.
*/
GLboolean (*bindContext)(__DRInativeDisplay *dpy, int scrn, __DRIid draw,
__DRIid read, __DRIcontext *ctx);
GLboolean (*bindContext)(__DRInativeDisplay *dpy, int scrn,
__DRIdrawable *pdraw,
__DRIdrawable *pread,
__DRIcontext *ctx);
/**
* Method to unbind a DRI drawable from a DRI graphics context.
*
* \since Internal API version 20050727.
*/
GLboolean (*unbindContext)(__DRInativeDisplay *dpy, int scrn, __DRIid draw,
__DRIid read, __DRIcontext *ctx);
GLboolean (*unbindContext)(__DRInativeDisplay *dpy, int scrn,
__DRIcontext *ctx);
};
/**

View File

@ -427,16 +427,37 @@ PUBLIC GLboolean XF86DRICreateDrawable( __DRInativeDisplay * ndpy, int screen,
return True;
}
static int noopErrorHandler(Display *dpy, XErrorEvent *xerr)
{
return 0;
}
PUBLIC GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen,
__DRIid drawable )
{
Display * const dpy = (Display *) ndpy;
XExtDisplayInfo *info = find_display (dpy);
xXF86DRIDestroyDrawableReq *req;
int (*oldXErrorHandler)(Display *, XErrorEvent *);
TRACE("DestroyDrawable...");
XF86DRICheckExtension (dpy, info, False);
/* This is called from the DRI driver, which used call it like this
*
* if (windowExists(drawable))
* destroyDrawable(drawable);
*
* which is a textbook race condition - the window may disappear
* from the server between checking for its existance and
* destroying it. Instead we change the semantics of
* __DRIinterfaceMethodsRec::destroyDrawable() to succeed even if
* the windows is gone, by wrapping the destroy call in an error
* handler. */
XSync(dpy, GL_FALSE);
oldXErrorHandler = XSetErrorHandler(noopErrorHandler);
LockDisplay(dpy);
GetReq(XF86DRIDestroyDrawable, req);
req->reqType = info->codes->major_opcode;
@ -445,6 +466,9 @@ PUBLIC GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen,
req->drawable = drawable;
UnlockDisplay(dpy);
SyncHandle();
XSetErrorHandler(oldXErrorHandler);
TRACE("DestroyDrawable... return True");
return True;
}

View File

@ -171,7 +171,7 @@ ExtractDir(int index, const char *paths, int dirLen, char *dir)
* \todo
* Create a macro or something so that this is automatically updated.
*/
static const char createNewScreenName[] = "__driCreateNewScreen_20050727";
static const char createNewScreenName[] = "__driCreateNewScreen_20070105";
/**

View File

@ -60,6 +60,7 @@
#include "GL/internal/glcore.h"
#include "glapitable.h"
#include "glxextensions.h"
#include "glxhash.h"
#if defined( USE_XTHREADS )
# include <X11/Xthreads.h>
#elif defined( PTHREADS )
@ -349,6 +350,11 @@ struct __GLXcontextRec {
* Per context direct rendering interface functions and data.
*/
__DRIcontext driContext;
/**
* Pointer to the mode used to create this context.
*/
const __GLcontextModes * mode;
#endif
/**
@ -456,6 +462,7 @@ typedef struct __GLXscreenConfigsRec {
* Per screen direct rendering interface functions and data.
*/
__DRIscreen driScreen;
__glxHashTable *drawHash;
#endif
/**

View File

@ -61,41 +61,92 @@ static const char __glXGLXClientVersion[] = "1.4";
/****************************************************************************/
#ifdef GLX_DIRECT_RENDERING
static Bool windowExistsFlag;
static int windowExistsErrorHandler(Display *dpy, XErrorEvent *xerr)
{
if (xerr->error_code == BadWindow) {
windowExistsFlag = GL_FALSE;
}
return 0;
}
/**
* Find drawables in the local hash that have been destroyed on the
* server.
*
* \param dpy Display to destroy drawables for
* \param screen Screen number to destroy drawables for
*/
static void GarbageCollectDRIDrawables(Display *dpy, int screen)
{
__GLXdisplayPrivate * const priv = __glXInitialize(dpy);
__GLXscreenConfigs *sc;
__DRIid draw;
__DRIdrawable *pdraw;
XWindowAttributes xwa;
int (*oldXErrorHandler)(Display *, XErrorEvent *);
if (priv == NULL || priv->driDisplay.private == NULL)
return;
/* Set no-op error handler so Xlib doesn't bail out if the windows
* has alreay been destroyed on the server. */
XSync(dpy, GL_FALSE);
oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler);
sc = &priv->screenConfigs[screen];
if (__glxHashFirst(sc->drawHash, &draw, (void *)&pdraw) == 1) {
do {
windowExistsFlag = GL_TRUE;
XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */
if (!windowExistsFlag) {
/* Destroy the local drawable data, if the drawable no
longer exists in the Xserver */
(*pdraw->destroyDrawable)(dpy, pdraw->private);
Xfree(pdraw);
}
} while (__glxHashNext(sc->drawHash, &draw, (void *)&pdraw) == 1);
}
XSetErrorHandler(oldXErrorHandler);
}
/**
* Get the __DRIdrawable for the drawable associated with a GLXContext
*
* \param dpy The display associated with \c drawable.
* \param drawable GLXDrawable whose __DRIdrawable part is to be retrieved.
* \param scrn_num If non-NULL, the drawables screen is stored there
* \returns A pointer to the context's __DRIdrawable on success, or NULL if
* the drawable is not associated with a direct-rendering context.
*/
#ifdef GLX_DIRECT_RENDERING
static __DRIdrawable *
GetDRIDrawable( Display *dpy, GLXDrawable drawable, int * const scrn_num )
{
__GLXdisplayPrivate * const priv = __glXInitialize(dpy);
__DRIdrawable * const pdraw;
const unsigned screen_count = ScreenCount(dpy);
unsigned i;
__GLXscreenConfigs *sc;
if ( (priv != NULL) && (priv->driDisplay.private != NULL) ) {
const unsigned screen_count = ScreenCount(dpy);
unsigned i;
for ( i = 0 ; i < screen_count ; i++ ) {
__DRIscreen * const psc = &priv->screenConfigs[i].driScreen;
__DRIdrawable * const pdraw = (psc->private != NULL)
? (*psc->getDrawable)(dpy, drawable, psc->private) : NULL;
if ( pdraw != NULL ) {
if ( scrn_num != NULL ) {
*scrn_num = i;
}
return pdraw;
}
if (priv == NULL || priv->driDisplay.private == NULL)
return NULL;
for (i = 0; i < screen_count; i++) {
sc = &priv->screenConfigs[i];
if (__glxHashLookup(sc->drawHash, drawable, (void *) &pdraw) == 0) {
if (scrn_num != NULL)
*scrn_num = i;
return pdraw;
}
}
return NULL;
}
#endif
@ -359,7 +410,7 @@ CreateContext(Display *dpy, XVisualInfo *vis,
gc->screen = mode->screen;
gc->vid = mode->visualID;
gc->fbconfigID = mode->fbconfigID;
gc->driContext.mode = mode;
gc->mode = mode;
}
}
}
@ -473,6 +524,7 @@ DestroyContext(Display *dpy, GLXContext gc)
gc->driContext.private);
gc->driContext.private = NULL;
}
GarbageCollectDRIDrawables(dpy, gc->screen);
}
#endif
@ -1730,9 +1782,7 @@ static int __glXSwapIntervalMESA(unsigned int interval)
if ( (psc != NULL) && (psc->driScreen.private != NULL)
&& __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) {
__DRIdrawable * const pdraw =
(*psc->driScreen.getDrawable)(gc->currentDpy,
gc->currentDrawable,
psc->driScreen.private);
GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
if ( pdraw != NULL ) {
pdraw->swap_interval = interval;
return 0;
@ -1759,9 +1809,7 @@ static int __glXGetSwapIntervalMESA(void)
if ( (psc != NULL) && (psc->driScreen.private != NULL)
&& __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) {
__DRIdrawable * const pdraw =
(*psc->driScreen.getDrawable)(gc->currentDpy,
gc->currentDrawable,
psc->driScreen.private);
GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
if ( pdraw != NULL ) {
return pdraw->swap_interval;
}
@ -1919,9 +1967,7 @@ static int __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count
if ( __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit )
&& psc->driScreen.private ) {
__DRIdrawable * const pdraw =
(*psc->driScreen.getDrawable)(gc->currentDpy,
gc->currentDrawable,
psc->driScreen.private);
GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
if ( (pdraw != NULL) && (pdraw->waitForMSC != NULL) ) {
int ret;
int64_t msc;
@ -2140,11 +2186,10 @@ Bool __glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
int i;
GetDRIDrawable( dpy, drawable, & screen_num );
if ( (screen_num != -1)
&& XF86VidModeQueryVersion( dpy, & i, & i )
&& XF86VidModeGetModeLine( dpy, screen_num, & dot_clock,
& mode_line ) ) {
if (GetDRIDrawable( dpy, drawable, & screen_num) != NULL
&& XF86VidModeQueryVersion( dpy, & i, & i )
&& XF86VidModeGetModeLine( dpy, screen_num, & dot_clock,
& mode_line ) ) {
unsigned n = dot_clock * 1000;
unsigned d = mode_line.vtotal * mode_line.htotal;
@ -2889,50 +2934,6 @@ int __glXGetInternalVersion(void)
}
static Bool windowExistsFlag;
static int windowExistsErrorHandler(Display *dpy, XErrorEvent *xerr)
{
if (xerr->error_code == BadWindow) {
windowExistsFlag = GL_FALSE;
}
return 0;
}
/**
* Determine if a window associated with a \c GLXDrawable exists on the
* X-server. This function is not used internally by libGL. It is provided
* as a utility function for DRI drivers.
* Drivers should not call this function directly. They should instead use
* \c glXGetProcAddress to obtain a pointer to the function.
*
* \param dpy Display associated with the drawable to be queried.
* \param draw \c GLXDrawable to test.
*
* \returns \c GL_TRUE if a window exists that is associated with \c draw,
* otherwise \c GL_FALSE is returned.
*
* \warning This function is not currently thread-safe.
*
* \sa glXGetProcAddress
*
* \since Internal API version 20021128.
*/
Bool __glXWindowExists(Display *dpy, GLXDrawable draw)
{
XWindowAttributes xwa;
int (*oldXErrorHandler)(Display *, XErrorEvent *);
XSync(dpy, GL_FALSE);
windowExistsFlag = GL_TRUE;
oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler);
XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */
XSetErrorHandler(oldXErrorHandler);
return windowExistsFlag;
}
/**
* Get the unadjusted system time (UST). Currently, the UST is measured in
* microseconds since Epoc. The actual resolution of the UST may vary from

View File

@ -61,6 +61,7 @@
#include <inttypes.h>
#include <sys/mman.h>
#include "xf86dri.h"
#include "xf86drm.h"
#include "sarea.h"
#include "dri_glx.h"
#endif
@ -366,6 +367,7 @@ static void FreeScreenConfigs(__GLXdisplayPrivate *priv)
(*psc->driScreen.destroyScreen)(priv->dpy, i,
psc->driScreen.private);
psc->driScreen.private = NULL;
__glxHashDestroy(psc->drawHash);
#endif
}
XFree((char*) priv->screenConfigs);
@ -781,7 +783,6 @@ static const __DRIinterfaceMethods interface_methods = {
_gl_context_modes_destroy,
__glXFindDRIScreen,
__glXWindowExists,
XF86DRICreateContextWithConfig,
XF86DRIDestroyContext,
@ -816,7 +817,7 @@ static const __DRIinterfaceMethods interface_methods = {
* returned by the client-side driver.
*/
static void *
CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc,
CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
__DRIdisplay * driDpy,
PFNCREATENEWSCREENFUNC createNewScreen)
{
@ -937,13 +938,12 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc,
if ( status == 0 ) {
__GLcontextModes * driver_modes = NULL;
__GLXscreenConfigs *configs = psc->screenConfigs;
err_msg = "InitDriver";
err_extra = NULL;
psp = (*createNewScreen)(dpy, scrn,
psc,
configs->configs,
&psc->driScreen,
psc->configs,
& ddx_version,
& dri_version,
& drm_version,
@ -954,7 +954,7 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc,
& interface_methods,
& driver_modes );
filter_modes( & configs->configs,
filter_modes( & psc->configs,
driver_modes );
_gl_context_modes_destroy( driver_modes );
}
@ -1169,6 +1169,14 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
UnlockDisplay(dpy);
#ifdef GLX_DIRECT_RENDERING
/* Create drawable hash */
psc->drawHash = __glxHashCreate();
if ( psc->drawHash == NULL ) {
SyncHandle();
FreeScreenConfigs(priv);
return GL_FALSE;
}
/* Initialize per screen dynamic client GLX extensions */
psc->ext_list_first_time = GL_TRUE;
/* Initialize the direct rendering per screen data and functions */
@ -1181,7 +1189,7 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
psc->driScreen.screenConfigs = (void *)psc;
psc->driScreen.private =
CallCreateNewScreen(dpy, i, & psc->driScreen,
CallCreateNewScreen(dpy, i, psc,
& priv->driDisplay,
priv->driDisplay.createNewScreen[i] );
}
@ -1617,20 +1625,64 @@ static Bool SendMakeCurrentRequest(Display *dpy, CARD8 opcode,
#ifdef GLX_DIRECT_RENDERING
static __DRIdrawable *
FetchDRIDrawable( Display *dpy, GLXDrawable drawable, GLXContext gc)
{
__GLXdisplayPrivate * const priv = __glXInitialize(dpy);
__DRIdrawable *pdraw;
__GLXscreenConfigs *sc;
void *empty_attribute_list = NULL;
if (priv == NULL || priv->driDisplay.private == NULL)
return NULL;
sc = &priv->screenConfigs[gc->screen];
if (__glxHashLookup(sc->drawHash, drawable, (void *) &pdraw) == 0)
return pdraw;
/* Allocate a new drawable */
pdraw = (__DRIdrawable *)Xmalloc(sizeof(__DRIdrawable));
if (!pdraw)
return NULL;
/* Create a new drawable */
pdraw->private =
(*sc->driScreen.createNewDrawable)(dpy,
gc->mode,
drawable, pdraw,
GLX_WINDOW_BIT,
empty_attribute_list);
if (!pdraw->private) {
/* ERROR!!! */
Xfree(pdraw);
return NULL;
}
if (__glxHashInsert(sc->drawHash, drawable, pdraw)) {
(*pdraw->destroyDrawable)(dpy, pdraw->private);
Xfree(pdraw);
return NULL;
}
return pdraw;
}
static Bool BindContextWrapper( Display *dpy, GLXContext gc,
GLXDrawable draw, GLXDrawable read )
{
return (*gc->driContext.bindContext)(dpy, gc->screen, draw, read,
__DRIdrawable *pdraw = FetchDRIDrawable(dpy, draw, gc);
__DRIdrawable *pread = FetchDRIDrawable(dpy, read, gc);
return (*gc->driContext.bindContext)(dpy, gc->screen, pdraw, pread,
& gc->driContext);
}
static Bool UnbindContextWrapper( GLXContext gc )
{
return (*gc->driContext.unbindContext)(gc->currentDpy, gc->screen,
gc->currentDrawable,
gc->currentReadable,
& gc->driContext );
return (*gc->driContext.unbindContext)(gc->currentDpy, gc->screen,
&gc->driContext );
}
#endif /* GLX_DIRECT_RENDERING */

View File

@ -1,4 +1,6 @@
/* xf86drmHash.c -- Small hash table support for integer -> integer mapping
/* glxhash.c -- Small hash table support for integer -> integer mapping
* Taken from libdrm.
*
* Created: Sun Apr 18 09:35:45 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
@ -25,8 +27,6 @@
*
* Authors: Rickard E. (Rik) Faith <faith@valinux.com>
*
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmHash.c,v 1.4 2001/03/21 18:08:54 dawes Exp $
*
* DESCRIPTION
*
* This file contains a straightforward implementation of a fixed-sized

View File

@ -50,9 +50,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* 4.0.0: Original
* 4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02
* 4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02
* 5.0.0: Drop XIDs from DRI interface.
*/
#define XF86DRI_MAJOR_VERSION 4
#define XF86DRI_MINOR_VERSION 1
#define XF86DRI_MAJOR_VERSION 5
#define XF86DRI_MINOR_VERSION 0
#define XF86DRI_PATCH_VERSION 0
typedef struct _XF86DRIQueryVersion {

View File

@ -88,63 +88,6 @@ __driUtilMessage(const char *f, ...)
}
/*****************************************************************/
/** \name Drawable list management */
/*****************************************************************/
/*@{*/
static GLboolean __driAddDrawable(void *drawHash, __DRIdrawable *pdraw)
{
__DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private;
if (drmHashInsert(drawHash, pdp->draw, pdraw))
return GL_FALSE;
return GL_TRUE;
}
static __DRIdrawable *__driFindDrawable(void *drawHash, __DRIid draw)
{
int retcode;
__DRIdrawable *pdraw;
retcode = drmHashLookup(drawHash, draw, (void *)&pdraw);
if (retcode)
return NULL;
return pdraw;
}
/**
* Find drawables in the local hash that have been destroyed on the
* server.
*
* \param drawHash Hash-table containing all know drawables.
*/
static void __driGarbageCollectDrawables(void *drawHash)
{
__DRIid draw;
__DRInativeDisplay *dpy;
__DRIdrawable *pdraw;
if (drmHashFirst(drawHash, &draw, (void *)&pdraw) == 1) {
do {
__DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private;
dpy = pdp->driScreenPriv->display;
if (! (*dri_interface->windowExists)(dpy, draw)) {
/* Destroy the local drawable data, if the drawable no
longer exists in the Xserver */
(*pdraw->destroyDrawable)(dpy, pdraw->private);
_mesa_free(pdraw);
}
} while (drmHashNext(drawHash, &draw, (void *)&pdraw) == 1);
}
}
/*@}*/
/*****************************************************************/
/** \name Context (un)binding functions */
/*****************************************************************/
@ -155,8 +98,6 @@ static void __driGarbageCollectDrawables(void *drawHash)
*
* \param dpy the display handle.
* \param scrn the screen number.
* \param draw drawable.
* \param read Current reading drawable.
* \param gc context.
*
* \return \c GL_TRUE on success, or \c GL_FALSE on failure.
@ -170,12 +111,9 @@ static void __driGarbageCollectDrawables(void *drawHash)
* into their respective real types it also assures they are not \c NULL.
*/
static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn,
__DRIid draw, __DRIid read,
__DRIcontext *ctx)
__DRIcontext *ctx)
{
__DRIscreen *pDRIScreen;
__DRIdrawable *pdraw;
__DRIdrawable *pread;
__DRIcontextPrivate *pcp;
__DRIscreenPrivate *psp;
__DRIdrawablePrivate *pdp;
@ -186,7 +124,7 @@ static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn,
** calling driUnbindContext.
*/
if (ctx == NULL || draw == None || read == None) {
if (ctx == NULL) {
/* ERROR!!! */
return GL_FALSE;
}
@ -199,26 +137,12 @@ static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn,
psp = (__DRIscreenPrivate *)pDRIScreen->private;
pcp = (__DRIcontextPrivate *)ctx->private;
pdraw = __driFindDrawable(psp->drawHash, draw);
if (!pdraw) {
/* ERROR!!! */
return GL_FALSE;
}
pdp = (__DRIdrawablePrivate *)pdraw->private;
pread = __driFindDrawable(psp->drawHash, read);
if (!pread) {
/* ERROR!!! */
return GL_FALSE;
}
prp = (__DRIdrawablePrivate *)pread->private;
pdp = (__DRIdrawablePrivate *)pcp->driDrawablePriv;
prp = (__DRIdrawablePrivate *)pcp->driReadablePriv;
/* Let driver unbind drawable from context */
(*psp->DriverAPI.UnbindContext)(pcp);
if (pdp->refcount == 0) {
/* ERROR!!! */
return GL_FALSE;
@ -254,72 +178,20 @@ static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn,
* This function takes both a read buffer and a draw buffer. This is needed
* for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
* function.
*
* \bug This function calls \c driCreateNewDrawable in two places with the
* \c renderType hard-coded to \c GLX_WINDOW_BIT. Some checking might
* be needed in those places when support for pbuffers and / or pixmaps
* is added. Is it safe to assume that the drawable is a window?
*/
static GLboolean DoBindContext(__DRInativeDisplay *dpy,
__DRIid draw, __DRIid read,
__DRIcontext *ctx, const __GLcontextModes * modes,
__DRIscreenPrivate *psp)
__DRIdrawable *pdraw,
__DRIdrawable *pread,
__DRIcontext *ctx,
__DRIscreenPrivate *psp)
{
__DRIdrawable *pdraw;
__DRIdrawablePrivate *pdp;
__DRIdrawable *pread;
__DRIdrawablePrivate *prp;
__DRIcontextPrivate * const pcp = ctx->private;
/* Find the _DRIdrawable which corresponds to the writing drawable. */
pdraw = __driFindDrawable(psp->drawHash, draw);
if (!pdraw) {
/* Allocate a new drawable */
pdraw = (__DRIdrawable *)_mesa_malloc(sizeof(__DRIdrawable));
if (!pdraw) {
/* ERROR!!! */
return GL_FALSE;
}
/* Create a new drawable */
driCreateNewDrawable(dpy, modes, draw, pdraw, GLX_WINDOW_BIT,
empty_attribute_list);
if (!pdraw->private) {
/* ERROR!!! */
_mesa_free(pdraw);
return GL_FALSE;
}
}
pdp = (__DRIdrawablePrivate *) pdraw->private;
/* Find the _DRIdrawable which corresponds to the reading drawable. */
if (read == draw) {
/* read buffer == draw buffer */
prp = pdp;
}
else {
pread = __driFindDrawable(psp->drawHash, read);
if (!pread) {
/* Allocate a new drawable */
pread = (__DRIdrawable *)_mesa_malloc(sizeof(__DRIdrawable));
if (!pread) {
/* ERROR!!! */
return GL_FALSE;
}
/* Create a new drawable */
driCreateNewDrawable(dpy, modes, read, pread, GLX_WINDOW_BIT,
empty_attribute_list);
if (!pread->private) {
/* ERROR!!! */
_mesa_free(pread);
return GL_FALSE;
}
}
prp = (__DRIdrawablePrivate *) pread->private;
}
prp = (__DRIdrawablePrivate *) pread->private;
/* Bind the drawable to the context */
pcp->driDrawablePriv = pdp;
@ -359,8 +231,9 @@ static GLboolean DoBindContext(__DRInativeDisplay *dpy,
* function.
*/
static GLboolean driBindContext(__DRInativeDisplay *dpy, int scrn,
__DRIid draw, __DRIid read,
__DRIcontext * ctx)
__DRIdrawable *pdraw,
__DRIdrawable *pread,
__DRIcontext * ctx)
{
__DRIscreen *pDRIScreen;
@ -369,7 +242,7 @@ static GLboolean driBindContext(__DRInativeDisplay *dpy, int scrn,
** calling driBindContext.
*/
if (ctx == NULL || draw == None || read == None) {
if (ctx == NULL || pdraw == None || pread == None) {
/* ERROR!!! */
return GL_FALSE;
}
@ -380,7 +253,7 @@ static GLboolean driBindContext(__DRInativeDisplay *dpy, int scrn,
return GL_FALSE;
}
return DoBindContext( dpy, draw, read, ctx, ctx->mode,
return DoBindContext( dpy, pdraw, pread, ctx,
(__DRIscreenPrivate *)pDRIScreen->private );
}
/*@}*/
@ -438,8 +311,7 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
if (!__driFindDrawable(psp->drawHash, pdp->draw) ||
! (*dri_interface->getDrawableInfo)(pdp->display, pdp->screen, pdp->draw,
if (! (*dri_interface->getDrawableInfo)(pdp->display, pdp->screen, pdp->draw,
&pdp->index, &pdp->lastStamp,
&pdp->x, &pdp->y, &pdp->w, &pdp->h,
&pdp->numClipRects, &pdp->pClipRects,
@ -675,30 +547,9 @@ static void *driCreateNewDrawable(__DRInativeDisplay *dpy,
pdp->swapBuffers = psp->DriverAPI.SwapBuffers;
/* Add pdraw to drawable list */
if (!__driAddDrawable(psp->drawHash, pdraw)) {
/* ERROR!!! */
(*pdraw->destroyDrawable)(dpy, pdp);
_mesa_free(pdp);
pdp = NULL;
pdraw->private = NULL;
}
return (void *) pdp;
}
static __DRIdrawable *
driGetDrawable(__DRInativeDisplay *dpy, __DRIid draw, void *screenPrivate)
{
__DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate;
/*
** Make sure this routine returns NULL if the drawable is not bound
** to a direct rendering context!
*/
return __driFindDrawable(psp->drawHash, draw);
}
static void
driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate)
{
@ -710,9 +561,7 @@ driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate)
psp = pdp->driScreenPriv;
scrn = psp->myNum;
(*psp->DriverAPI.DestroyBuffer)(pdp);
if ((*dri_interface->windowExists)(dpy, pdp->draw))
(void)(*dri_interface->destroyDrawable)(dpy, scrn, pdp->draw);
drmHashDelete(psp->drawHash, pdp->draw);
(void)(*dri_interface->destroyDrawable)(dpy, scrn, pdp->draw);
if (pdp->pClipRects) {
_mesa_free(pdp->pClipRects);
pdp->pClipRects = NULL;
@ -751,7 +600,6 @@ driDestroyContext(__DRInativeDisplay *dpy, int scrn, void *contextPrivate)
if (pcp) {
(*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp);
__driGarbageCollectDrawables(pcp->driScreenPriv->drawHash);
(void) (*dri_interface->destroyContext)(dpy, scrn, pcp->contextID);
_mesa_free(pcp);
}
@ -836,8 +684,6 @@ driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
return NULL;
}
__driGarbageCollectDrawables(pcp->driScreenPriv->drawHash);
return pcp;
}
/*@}*/
@ -874,15 +720,11 @@ static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPriv
(void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
(void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
_mesa_free(psp->pDevPriv);
(void)drmCloseOnce(psp->fd);
if ( psp->modes != NULL ) {
(*dri_interface->destroyContextModes)( psp->modes );
}
assert(psp->drawHash);
drmHashDestroy(psp->drawHash);
_mesa_free(psp);
}
}
@ -939,13 +781,6 @@ __driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
return NULL;
}
/* Create the hash table */
psp->drawHash = drmHashCreate();
if ( psp->drawHash == NULL ) {
_mesa_free( psp );
return NULL;
}
psp->display = dpy;
psp->myNum = scrn;
psp->psc = psc;
@ -993,7 +828,6 @@ __driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
psc->destroyScreen = driDestroyScreen;
psc->createNewDrawable = driCreateNewDrawable;
psc->getDrawable = driGetDrawable;
psc->getMSC = driGetMSC;
psc->createNewContext = driCreateNewContext;

View File

@ -489,11 +489,6 @@ struct __DRIscreenPrivateRec {
*/
__DRIcontextPrivate dummyContextPriv;
/**
* Hash table to hold the drawable information for this screen.
*/
void *drawHash;
/**
* Device-dependent private information (not stored in the SAREA).
*

View File

@ -431,7 +431,7 @@ static const struct __DriverAPIRec i810API = {
* failure.
*/
PUBLIC
void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
void * __driCreateNewScreen_20070105( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
const __GLcontextModes * modes,
const __DRIversion * ddx_version,
const __DRIversion * dri_version,