summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/common/dri_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/common/dri_util.c')
-rw-r--r--src/mesa/drivers/dri/common/dri_util.c1036
1 files changed, 530 insertions, 506 deletions
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index 2013125efe6..fff79c36ad6 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -55,19 +55,39 @@
#include "dri_util.h"
#include "drm_sarea.h"
-#include "utils.h"
#ifndef GLX_OML_sync_control
-typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRIdrawable *drawable, int32_t *numerator, int32_t *denominator);
+typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRInativeDisplay *dpy, __DRIid drawable, int32_t *numerator, int32_t *denominator);
#endif
+/* This pointer *must* be set by the driver's __driCreateNewScreen funciton!
+ */
+const __DRIinterfaceMethods * dri_interface = NULL;
+
/**
- * This is just a token extension used to signal that the driver
- * supports setting a read drawable.
+ * This is used in a couple of places that call \c driCreateNewDrawable.
*/
-const __DRIextension driReadDrawableExtension = {
- __DRI_READ_DRAWABLE, __DRI_READ_DRAWABLE_VERSION
-};
+static const int empty_attribute_list[1] = { None };
+
+
+/**
+ * Cached copy of the internal API version used by libGL and the client-side
+ * DRI driver.
+ */
+static int api_ver = 0;
+
+/* forward declarations */
+static int driQueryFrameTracking( __DRInativeDisplay *dpy, void *priv,
+ int64_t *sbc, int64_t *missedFrames,
+ float *lastMissedUsage, float *usage );
+
+static void *driCreateNewDrawable(__DRInativeDisplay *dpy,
+ const __GLcontextModes *modes,
+ __DRIid draw, __DRIdrawable *pdraw,
+ int renderType, const int *attrs);
+
+static void driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate);
+
/**
* Print message to \c stderr if the \c LIBGL_DEBUG environment variable
@@ -91,19 +111,64 @@ __driUtilMessage(const char *f, ...)
}
}
-GLint
-driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 )
+
+/*****************************************************************/
+/** \name Drawable list management */
+/*****************************************************************/
+/*@{*/
+
+static GLboolean __driAddDrawable(void *drawHash, __DRIdrawable *pdraw)
{
- if (rect2.x1 > rect1.x1) rect1.x1 = rect2.x1;
- if (rect2.x2 < rect1.x2) rect1.x2 = rect2.x2;
- if (rect2.y1 > rect1.y1) rect1.y1 = rect2.y1;
- if (rect2.y2 < rect1.y2) rect1.y2 = rect2.y2;
+ __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private;
- if (rect1.x1 > rect1.x2 || rect1.y1 > rect1.y2) return 0;
+ if (drmHashInsert(drawHash, pdp->draw, pdraw))
+ return GL_FALSE;
- return (rect1.x2 - rect1.x1) * (rect1.y2 - rect1.y1);
+ 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 known 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 */
/*****************************************************************/
@@ -112,7 +177,10 @@ driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 )
/**
* Unbind context.
*
- * \param scrn the screen.
+ * \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.
@@ -125,27 +193,56 @@ driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 )
* While casting the opaque private pointers associated with the parameters
* into their respective real types it also assures they are not \c NULL.
*/
-static int driUnbindContext(__DRIcontext *pcp)
+static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn,
+ __DRIid draw, __DRIid read,
+ __DRIcontext *ctx)
{
- __DRIscreen *psp;
- __DRIdrawable *pdp;
- __DRIdrawable *prp;
+ __DRIscreen *pDRIScreen;
+ __DRIdrawable *pdraw;
+ __DRIdrawable *pread;
+ __DRIcontextPrivate *pcp;
+ __DRIscreenPrivate *psp;
+ __DRIdrawablePrivate *pdp;
+ __DRIdrawablePrivate *prp;
/*
** Assume error checking is done properly in glXMakeCurrent before
** calling driUnbindContext.
*/
- if (pcp == NULL)
- return GL_FALSE;
+ if (ctx == NULL || draw == None || read == None) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
+
+ pDRIScreen = (*dri_interface->getScreen)(dpy, scrn);
+ if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
+
+ 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;
- psp = pcp->driScreenPriv;
- pdp = pcp->driDrawablePriv;
- prp = pcp->driReadablePriv;
/* Let driver unbind drawable from context */
(*psp->DriverAPI.UnbindContext)(pcp);
+
if (pdp->refcount == 0) {
/* ERROR!!! */
return GL_FALSE;
@@ -162,6 +259,12 @@ static int driUnbindContext(__DRIcontext *pcp)
prp->refcount--;
}
+ /* destroy the drawables if they no longer exist on the server */
+ if ((pdp->refcount == 0) || (prp->refcount == 0)) {
+ /* probably shouldn't need the collector here,
+ as we know the affected drawables (or could there be others?) */
+ __driGarbageCollectDrawables(pdp->driScreenPriv->drawHash);
+ }
/* XXX this is disabled so that if we call SwapBuffers on an unbound
* window we can determine the last context bound to the window and
@@ -181,20 +284,72 @@ static int driUnbindContext(__DRIcontext *pcp)
* 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 int driBindContext(__DRIcontext *pcp,
- __DRIdrawable *pdp,
- __DRIdrawable *prp)
+static GLboolean DoBindContext(__DRInativeDisplay *dpy,
+ __DRIid draw, __DRIid read,
+ __DRIcontext *ctx, const __GLcontextModes * modes,
+ __DRIscreenPrivate *psp)
{
- __DRIscreenPrivate *psp = pcp->driScreenPriv;
+ __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;
+ }
- /*
- ** Assume error checking is done properly in glXMakeCurrent before
- ** calling driBindContext.
- */
+ /* 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;
+ }
- if (pcp == NULL || pdp == None || prp == None)
- 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;
+ }
/* Bind the drawable to the context */
pcp->driDrawablePriv = pdp;
@@ -209,22 +364,16 @@ static int driBindContext(__DRIcontext *pcp,
** Now that we have a context associated with this drawable, we can
** initialize the drawable information if has not been done before.
*/
+ if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) {
+ DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+ __driUtilUpdateDrawableInfo(pdp);
+ DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+ }
- if (psp->dri2.enabled) {
- __driParseEvents(pcp, pdp);
- __driParseEvents(pcp, prp);
- } else {
- if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) {
- DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
- __driUtilUpdateDrawableInfo(pdp);
- DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
- }
-
- if ((pdp != prp) && (!prp->pStamp || *prp->pStamp != prp->lastStamp)) {
- DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
- __driUtilUpdateDrawableInfo(prp);
- DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
- }
+ if ((pdp != prp) && (!prp->pStamp || *prp->pStamp != prp->lastStamp)) {
+ DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+ __driUtilUpdateDrawableInfo(prp);
+ DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
}
/* Call device-specific MakeCurrent */
@@ -233,6 +382,37 @@ static int driBindContext(__DRIcontext *pcp,
return GL_TRUE;
}
+
+/**
+ * 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.
+ */
+static GLboolean driBindContext(__DRInativeDisplay *dpy, int scrn,
+ __DRIid draw, __DRIid read,
+ __DRIcontext * ctx)
+{
+ __DRIscreen *pDRIScreen;
+
+ /*
+ ** Assume error checking is done properly in glXMakeCurrent before
+ ** calling driBindContext.
+ */
+
+ if (ctx == NULL || draw == None || read == None) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
+
+ pDRIScreen = (*dri_interface->getScreen)(dpy, scrn);
+ if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
+
+ return DoBindContext( dpy, draw, read, ctx, ctx->mode,
+ (__DRIscreenPrivate *)pDRIScreen->private );
+}
/*@}*/
@@ -256,7 +436,7 @@ static int driBindContext(__DRIcontext *pcp,
void
__driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
{
- __DRIscreenPrivate *psp = pdp->driScreenPriv;
+ __DRIscreenPrivate *psp;
__DRIcontextPrivate *pcp = pdp->driContextPriv;
if (!pcp
@@ -267,6 +447,15 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
*/
}
+ psp = pdp->driScreenPriv;
+ if (!psp) {
+ /* ERROR!!! */
+ _mesa_problem(NULL, "Warning! Possible infinite loop due to bug "
+ "in file %s, line %d\n",
+ __FILE__, __LINE__);
+ return;
+ }
+
if (pdp->pClipRects) {
_mesa_free(pdp->pClipRects);
pdp->pClipRects = NULL;
@@ -279,15 +468,15 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
- if (! (*psp->getDrawableInfo->getDrawableInfo)(pdp,
+ if (!__driFindDrawable(psp->drawHash, pdp->draw) ||
+ ! (*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,
&pdp->backX,
&pdp->backY,
&pdp->numBackClipRects,
- &pdp->pBackClipRects,
- pdp->loaderPrivate)) {
+ &pdp->pBackClipRects )) {
/* Error -- eg the window may have been destroyed. Keep going
* with no cliprects.
*/
@@ -304,138 +493,6 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
}
-int
-__driParseEvents(__DRIcontextPrivate *pcp, __DRIdrawablePrivate *pdp)
-{
- __DRIscreenPrivate *psp = pcp->driScreenPriv;
- __DRIDrawableConfigEvent *dc, *last_dc;
- __DRIBufferAttachEvent *ba, *last_ba;
- unsigned int tail, mask, *p, end, total, size, changed;
- unsigned char *data;
- size_t rect_size;
-
- /* Check for wraparound. */
- if (psp->dri2.buffer->prealloc - pdp->dri2.tail > psp->dri2.buffer->size) {
- /* If prealloc overlaps into what we just parsed, the
- * server overwrote it and we have to reset our tail
- * pointer. */
- DRM_UNLOCK(psp->fd, psp->lock, pcp->hHWContext);
- (*psp->dri2.loader->reemitDrawableInfo)(pdp, &pdp->dri2.tail,
- pdp->loaderPrivate);
- DRM_LIGHT_LOCK(psp->fd, psp->lock, pcp->hHWContext);
- }
-
- total = psp->dri2.buffer->head - pdp->dri2.tail;
- mask = psp->dri2.buffer->size - 1;
- end = psp->dri2.buffer->head;
- data = psp->dri2.buffer->data;
-
- changed = 0;
- last_dc = NULL;
- last_ba = NULL;
-
- for (tail = pdp->dri2.tail; tail != end; tail += size) {
- p = (unsigned int *) (data + (tail & mask));
- size = DRI2_EVENT_SIZE(*p);
- if (size > total || (tail & mask) + size > psp->dri2.buffer->size) {
- /* illegal data, bail out. */
- fprintf(stderr, "illegal event size\n");
- break;
- }
-
- switch (DRI2_EVENT_TYPE(*p)) {
- case DRI2_EVENT_DRAWABLE_CONFIG:
- dc = (__DRIDrawableConfigEvent *) p;
- if (dc->drawable == pdp->dri2.drawable_id)
- last_dc = dc;
- break;
-
- case DRI2_EVENT_BUFFER_ATTACH:
- ba = (__DRIBufferAttachEvent *) p;
- if (ba->drawable == pdp->dri2.drawable_id &&
- ba->buffer.attachment == DRI_DRAWABLE_BUFFER_FRONT_LEFT)
- last_ba = ba;
- break;
- }
- }
-
- if (last_dc) {
- if (pdp->w != last_dc->width || pdp->h != last_dc->height)
- changed = 1;
-
- pdp->x = last_dc->x;
- pdp->y = last_dc->y;
- pdp->w = last_dc->width;
- pdp->h = last_dc->height;
-
- pdp->backX = 0;
- pdp->backY = 0;
- pdp->numBackClipRects = 1;
- pdp->pBackClipRects[0].x1 = 0;
- pdp->pBackClipRects[0].y1 = 0;
- pdp->pBackClipRects[0].x2 = pdp->w;
- pdp->pBackClipRects[0].y2 = pdp->h;
-
- pdp->numClipRects = last_dc->num_rects;
- _mesa_free(pdp->pClipRects);
- rect_size = last_dc->num_rects * sizeof last_dc->rects[0];
- pdp->pClipRects = _mesa_malloc(rect_size);
- memcpy(pdp->pClipRects, last_dc->rects, rect_size);
- }
-
- /* We only care about the most recent drawable config. */
- if (last_dc && changed)
- (*psp->DriverAPI.HandleDrawableConfig)(pdp, pcp, last_dc);
-
- /* Front buffer attachments are special, they typically mean that
- * we're rendering to a redirected window (or a child window of a
- * redirected window) and that it got resized. Resizing the root
- * window on randr events is a special case of this. Other causes
- * may be a window transitioning between redirected and
- * non-redirected, or a window getting reparented between parents
- * with different window pixmaps (eg two redirected windows).
- * These events are special in that the X server allocates the
- * buffer and that the buffer may be shared by other child
- * windows. When our window share the window pixmap with its
- * parent, drawable config events doesn't affect the front buffer.
- * We only care about the last such event in the buffer; in fact,
- * older events will refer to invalid buffer objects.*/
- if (last_ba)
- (*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, last_ba);
-
- /* If there was a drawable config event in the buffer and it
- * changed the size of the window, all buffer auxillary buffer
- * attachments prior to that are invalid (as opposed to the front
- * buffer case discussed above). In that case we can start
- * looking for buffer attachment after the last drawable config
- * event. If there is no drawable config event in this batch of
- * events, we have to assume that the last batch might have had
- * one and process all buffer attach events.*/
- if (last_dc && changed)
- tail = (unsigned char *) last_dc - data;
- else
- tail = pdp->dri2.tail;
-
- for ( ; tail != end; tail += size) {
- ba = (__DRIBufferAttachEvent *) (data + (tail & mask));
- size = DRI2_EVENT_SIZE(ba->event_header);
-
- if (DRI2_EVENT_TYPE(ba->event_header) != DRI2_EVENT_BUFFER_ATTACH)
- continue;
- if (ba->drawable != pdp->dri2.drawable_id)
- continue;
- if (last_ba == ba)
- continue;
-
- (*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, ba);
- changed = 1;
- }
-
- pdp->dri2.tail = tail;
-
- return changed || last_ba;
-}
-
/*@}*/
/*****************************************************************/
@@ -443,33 +500,10 @@ __driParseEvents(__DRIcontextPrivate *pcp, __DRIdrawablePrivate *pdp)
/*****************************************************************/
/*@{*/
-static void driReportDamage(__DRIdrawable *pdp,
- struct drm_clip_rect *pClipRects, int numClipRects)
-{
- __DRIscreen *psp = pdp->driScreenPriv;
-
- /* Check that we actually have the new damage report method */
- if (psp->dri2.enabled) {
- (*psp->dri2.loader->postDamage)(pdp,
- pClipRects,
- numClipRects,
- pdp->loaderPrivate);
- } else if (psp->damage) {
- /* Report the damage. Currently, all our drivers draw
- * directly to the front buffer, so we report the damage there
- * rather than to the backing storein (if any).
- */
- (*psp->damage->reportDamage)(pdp,
- pdp->x, pdp->y,
- pClipRects, numClipRects,
- GL_TRUE, pdp->loaderPrivate);
- }
-}
-
-
/**
* Swap buffers.
*
+ * \param dpy the display handle.
* \param drawablePrivate opaque pointer to the per-drawable private info.
*
* \internal
@@ -477,28 +511,74 @@ static void driReportDamage(__DRIdrawable *pdp,
*
* Is called directly from glXSwapBuffers().
*/
-static void driSwapBuffers(__DRIdrawable *dPriv)
+static void driSwapBuffers( __DRInativeDisplay *dpy, void *drawablePrivate )
+{
+ __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
+ drm_clip_rect_t rect;
+
+ dPriv->swapBuffers(dPriv);
+
+ /* Check that we actually have the new damage report method */
+ if (api_ver < 20070105 || dri_interface->reportDamage == NULL)
+ return;
+
+ /* Assume it's affecting the whole drawable for now */
+ rect.x1 = 0;
+ rect.y1 = 0;
+ rect.x2 = rect.x1 + dPriv->w;
+ rect.y2 = rect.y1 + dPriv->h;
+
+ /* Report the damage. Currently, all our drivers draw directly to the
+ * front buffer, so we report the damage there rather than to the backing
+ * store (if any).
+ */
+ (*dri_interface->reportDamage)(dpy, dPriv->screen, dPriv->draw,
+ dPriv->x, dPriv->y,
+ &rect, 1, GL_TRUE);
+}
+
+/**
+ * Called directly from a number of higher-level GLX functions.
+ */
+static int driGetMSC( void *screenPrivate, int64_t *msc )
+{
+ __DRIscreenPrivate *sPriv = (__DRIscreenPrivate *) screenPrivate;
+
+ return sPriv->DriverAPI.GetMSC( sPriv, msc );
+}
+
+/**
+ * Called directly from a number of higher-level GLX functions.
+ */
+static int driGetSBC( __DRInativeDisplay *dpy, void *drawablePrivate, int64_t *sbc )
{
- __DRIscreen *psp = dPriv->driScreenPriv;
+ __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
+ __DRIswapInfo sInfo;
+ int status;
- if (!dPriv->numClipRects)
- return;
- psp->DriverAPI.SwapBuffers(dPriv);
+ status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo );
+ *sbc = sInfo.swap_count;
- driReportDamage(dPriv, dPriv->pClipRects, dPriv->numClipRects);
+ return status;
}
-static int driDrawableGetMSC( __DRIscreen *sPriv, __DRIdrawable *dPriv,
- int64_t *msc )
+static int driWaitForSBC( __DRInativeDisplay * dpy, void *drawablePriv,
+ int64_t target_sbc,
+ int64_t * msc, int64_t * sbc )
{
- return sPriv->DriverAPI.GetDrawableMSC(sPriv, dPriv, msc);
+ __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv;
+
+ return dPriv->driScreenPriv->DriverAPI.WaitForSBC( dPriv, target_sbc,
+ msc, sbc );
}
-static int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc,
- int64_t divisor, int64_t remainder,
- int64_t * msc, int64_t * sbc)
+static int driWaitForMSC( __DRInativeDisplay * dpy, void *drawablePriv,
+ int64_t target_msc,
+ int64_t divisor, int64_t remainder,
+ int64_t * msc, int64_t * sbc )
{
+ __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv;
__DRIswapInfo sInfo;
int status;
@@ -520,70 +600,63 @@ static int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc,
return status;
}
-const __DRImediaStreamCounterExtension driMediaStreamCounterExtension = {
- { __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION },
- driWaitForMSC,
- driDrawableGetMSC,
-};
-
-static void driCopySubBuffer(__DRIdrawable *dPriv,
- int x, int y, int w, int h)
+static int64_t driSwapBuffersMSC( __DRInativeDisplay * dpy, void *drawablePriv,
+ int64_t target_msc,
+ int64_t divisor, int64_t remainder )
{
- drm_clip_rect_t rect;
+ __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv;
- dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h);
-
- rect.x1 = x;
- rect.y1 = dPriv->h - y - h;
- rect.x2 = x + w;
- rect.y2 = rect.y1 + h;
- driReportDamage(dPriv, &rect, 1);
+ return dPriv->driScreenPriv->DriverAPI.SwapBuffersMSC( dPriv, target_msc,
+ divisor,
+ remainder );
}
-const __DRIcopySubBufferExtension driCopySubBufferExtension = {
- { __DRI_COPY_SUB_BUFFER, __DRI_COPY_SUB_BUFFER_VERSION },
- driCopySubBuffer
-};
-
-static void driSetSwapInterval(__DRIdrawable *dPriv, unsigned int interval)
-{
- dPriv->swap_interval = interval;
-}
-
-static unsigned int driGetSwapInterval(__DRIdrawable *dPriv)
+static void driCopySubBuffer( __DRInativeDisplay *dpy, void *drawablePrivate,
+ int x, int y, int w, int h)
{
- return dPriv->swap_interval;
+ __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
+ dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h);
+ (void) dpy;
}
-const __DRIswapControlExtension driSwapControlExtension = {
- { __DRI_SWAP_CONTROL, __DRI_SWAP_CONTROL_VERSION },
- driSetSwapInterval,
- driGetSwapInterval
-};
-
-
/**
* This is called via __DRIscreenRec's createNewDrawable pointer.
*/
-static __DRIdrawable *
-driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
- drm_drawable_t hwDrawable, int renderType,
- const int *attrs, void *data)
+static void *driCreateNewDrawable(__DRInativeDisplay *dpy,
+ const __GLcontextModes *modes,
+ __DRIid draw,
+ __DRIdrawable *pdraw,
+ int renderType,
+ const int *attrs)
{
- __DRIdrawable *pdp;
+ __DRIscreen * const pDRIScreen = (*dri_interface->getScreen)(dpy, modes->screen);
+ __DRIscreenPrivate *psp;
+ __DRIdrawablePrivate *pdp;
+
+
+ pdraw->private = NULL;
/* Since pbuffers are not yet supported, no drawable attributes are
* supported either.
*/
(void) attrs;
- pdp = _mesa_malloc(sizeof *pdp);
+ if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
+ return NULL;
+ }
+
+ pdp = (__DRIdrawablePrivate *)_mesa_malloc(sizeof(__DRIdrawablePrivate));
if (!pdp) {
return NULL;
}
- pdp->loaderPrivate = data;
- pdp->hHWDrawable = hwDrawable;
+ if (!(*dri_interface->createDrawable)(dpy, modes->screen, draw, &pdp->hHWDrawable)) {
+ _mesa_free(pdp);
+ return NULL;
+ }
+
+ pdp->draw = draw;
+ pdp->pdraw = pdraw;
pdp->refcount = 0;
pdp->pStamp = NULL;
pdp->lastStamp = 0;
@@ -596,55 +669,80 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
pdp->numBackClipRects = 0;
pdp->pClipRects = NULL;
pdp->pBackClipRects = NULL;
- pdp->vblSeq = 0;
- pdp->vblFlags = 0;
+ pdp->display = dpy;
+ pdp->screen = modes->screen;
+ psp = (__DRIscreenPrivate *)pDRIScreen->private;
pdp->driScreenPriv = psp;
pdp->driContextPriv = &psp->dummyContextPriv;
- if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes,
+ if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, modes,
renderType == GLX_PIXMAP_BIT)) {
+ (void)(*dri_interface->destroyDrawable)(dpy, modes->screen, pdp->draw);
_mesa_free(pdp);
return NULL;
}
- pdp->msc_base = 0;
+ pdraw->private = pdp;
+ pdraw->destroyDrawable = driDestroyDrawable;
+ pdraw->swapBuffers = driSwapBuffers; /* called by glXSwapBuffers() */
+
+ pdraw->getSBC = driGetSBC;
+ pdraw->waitForSBC = driWaitForSBC;
+ pdraw->waitForMSC = driWaitForMSC;
+ pdraw->swapBuffersMSC = driSwapBuffersMSC;
+ pdraw->frameTracking = NULL;
+ pdraw->queryFrameTracking = driQueryFrameTracking;
+
+ if (driCompareGLXAPIVersion (20060314) >= 0)
+ pdraw->copySubBuffer = driCopySubBuffer;
/* This special default value is replaced with the configured
* default value when the drawable is first bound to a direct
* rendering context.
*/
- pdp->swap_interval = (unsigned)-1;
+ pdraw->swap_interval = (unsigned)-1;
+
+ pdp->swapBuffers = psp->DriverAPI.SwapBuffers;
- return pdp;
+ /* 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 *
-dri2CreateNewDrawable(__DRIscreen *screen, const __DRIconfig *config,
- unsigned int drawable_id, unsigned int head, void *data)
+driGetDrawable(__DRInativeDisplay *dpy, __DRIid draw, void *screenPrivate)
{
- __DRIdrawable *pdraw;
-
- pdraw = driCreateNewDrawable(screen, config, 0, 0, NULL, data);
- if (!pdraw)
- return NULL;
+ __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate;
- pdraw->dri2.drawable_id = drawable_id;
- pdraw->dri2.tail = head;
- pdraw->pBackClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects);
-
- return pdraw;
+ /*
+ ** 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(__DRIdrawable *pdp)
+driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate)
{
+ __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *) drawablePrivate;
__DRIscreenPrivate *psp;
+ int scrn;
if (pdp) {
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);
if (pdp->pClipRects) {
_mesa_free(pdp->pClipRects);
pdp->pClipRects = NULL;
@@ -668,6 +766,8 @@ driDestroyDrawable(__DRIdrawable *pdp)
/**
* Destroy the per-context private information.
*
+ * \param dpy the display handle.
+ * \param scrn the screen number.
* \param contextPrivate opaque pointer to the per-drawable private info.
*
* \internal
@@ -675,10 +775,14 @@ driDestroyDrawable(__DRIdrawable *pdp)
* drmDestroyContext(), and finally frees \p contextPrivate.
*/
static void
-driDestroyContext(__DRIcontext *pcp)
+driDestroyContext(__DRInativeDisplay *dpy, int scrn, void *contextPrivate)
{
+ __DRIcontextPrivate *pcp = (__DRIcontextPrivate *) contextPrivate;
+
if (pcp) {
(*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp);
+ __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash);
+ (void) (*dri_interface->destroyContext)(dpy, scrn, pcp->contextID);
_mesa_free(pcp);
}
}
@@ -691,7 +795,7 @@ driDestroyContext(__DRIcontext *pcp)
* \param modes Mode used to create the new context.
* \param render_type Type of rendering target. \c GLX_RGBA is the only
* type likely to ever be supported for direct-rendering.
- * \param shared The shared context dependent methods or \c NULL if
+ * \param sharedPrivate The shared context dependent methods or \c NULL if
* non-existent.
* \param pctx DRI context to receive the context dependent methods.
*
@@ -705,18 +809,36 @@ driDestroyContext(__DRIcontext *pcp)
* context.
*
*/
-static __DRIcontext *
-driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
- int render_type, __DRIcontext *shared,
- drm_context_t hwContext, void *data)
+static void *
+driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
+ int render_type, void *sharedPrivate, __DRIcontext *pctx)
{
- __DRIcontext *pcp;
- void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
+ __DRIscreen *pDRIScreen;
+ __DRIcontextPrivate *pcp;
+ __DRIcontextPrivate *pshare = (__DRIcontextPrivate *) sharedPrivate;
+ __DRIscreenPrivate *psp;
+ void * const shareCtx = (pshare != NULL) ? pshare->driverPrivate : NULL;
- pcp = _mesa_malloc(sizeof *pcp);
- if (!pcp)
+ pDRIScreen = (*dri_interface->getScreen)(dpy, modes->screen);
+ if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
+ /* ERROR!!! */
return NULL;
+ }
+
+ psp = (__DRIscreenPrivate *)pDRIScreen->private;
+ pcp = (__DRIcontextPrivate *)_mesa_malloc(sizeof(__DRIcontextPrivate));
+ if (!pcp) {
+ return NULL;
+ }
+
+ if (! (*dri_interface->createContext)(dpy, modes->screen, modes->fbconfigID,
+ &pcp->contextID, &pcp->hHWContext)) {
+ _mesa_free(pcp);
+ return NULL;
+ }
+
+ pcp->display = dpy;
pcp->driScreenPriv = psp;
pcp->driDrawablePriv = NULL;
@@ -724,7 +846,8 @@ driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
* context.
*/
- if (!psp->dri2.enabled && !psp->dummyContextPriv.driScreenPriv) {
+ if (!psp->dummyContextPriv.driScreenPriv) {
+ psp->dummyContextPriv.contextID = 0;
psp->dummyContextPriv.hHWContext = psp->pSAREA->dummy_context;
psp->dummyContextPriv.driScreenPriv = psp;
psp->dummyContextPriv.driDrawablePriv = NULL;
@@ -732,40 +855,21 @@ driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
/* No other fields should be used! */
}
- pcp->hHWContext = hwContext;
+ pctx->destroyContext = driDestroyContext;
+ pctx->bindContext = driBindContext;
+ pctx->unbindContext = driUnbindContext;
- if ( !(*psp->DriverAPI.CreateContext)(&config->modes, pcp, shareCtx) ) {
+ if ( !(*psp->DriverAPI.CreateContext)(modes, pcp, shareCtx) ) {
+ (void) (*dri_interface->destroyContext)(dpy, modes->screen,
+ pcp->contextID);
_mesa_free(pcp);
return NULL;
}
- return pcp;
-}
-
-static __DRIcontext *
-dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
- __DRIcontext *shared, void *data)
-{
- drm_context_t hwContext;
- DRM_CAS_RESULT(ret);
-
- /* DRI2 doesn't use kernel with context IDs, we just need an ID that's
- * different from the kernel context ID to make drmLock() happy. */
+ __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash);
- do {
- hwContext = screen->dri2.lock->next_id;
- DRM_CAS(&screen->dri2.lock->next_id, hwContext, hwContext + 1, ret);
- } while (ret);
-
- return driCreateNewContext(screen, config, 0, shared, hwContext, data);
-}
-
-static int
-driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
-{
- return GL_FALSE;
+ return pcp;
}
-
/*@}*/
@@ -785,8 +889,10 @@ driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
* This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls
* drmClose(), and finally frees \p screenPrivate.
*/
-static void driDestroyScreen(__DRIscreen *psp)
+static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPrivate)
{
+ __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate;
+
if (psp) {
/* No interaction with the X-server is possible at this point. This
* routine is called after XCloseDisplay, so there is no protocol
@@ -796,44 +902,26 @@ static void driDestroyScreen(__DRIscreen *psp)
if (psp->DriverAPI.DestroyScreen)
(*psp->DriverAPI.DestroyScreen)(psp);
- if (psp->dri2.enabled) {
- drmBOUnmap(psp->fd, &psp->dri2.sareaBO);
- drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
- } else {
- (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
- (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
- (void)drmCloseOnce(psp->fd);
+ (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);
}
}
-static void
-setupLoaderExtensions(__DRIscreen *psp,
- const __DRIextension **extensions)
-{
- int i;
-
- for (i = 0; extensions[i]; i++) {
- if (strcmp(extensions[i]->name, __DRI_GET_DRAWABLE_INFO) == 0)
- psp->getDrawableInfo = (__DRIgetDrawableInfoExtension *) extensions[i];
- if (strcmp(extensions[i]->name, __DRI_DAMAGE) == 0)
- psp->damage = (__DRIdamageExtension *) extensions[i];
- if (strcmp(extensions[i]->name, __DRI_SYSTEM_TIME) == 0)
- psp->systemTime = (__DRIsystemTimeExtension *) extensions[i];
- if (strcmp(extensions[i]->name, __DRI_LOADER) == 0)
- psp->dri2.loader = (__DRIloaderExtension *) extensions[i];
- }
-}
/**
- * This is the bootstrap function for the driver. libGL supplies all of the
- * requisite information about the system, and the driver initializes itself.
- * This routine also fills in the linked list pointed to by \c driver_modes
- * with the \c __GLcontextModes that the driver can support for windows or
- * pbuffers.
+ * Utility 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 modes Linked list of known display modes. This list is, at a
@@ -854,29 +942,44 @@ setupLoaderExtensions(__DRIscreen *psp,
* driver and libGL.
* \param driverAPI Driver API functions used by other routines in dri_util.c.
*
- * \note There is no need to check the minimum API version in this
- * function. Since the name of this function is versioned, it is
- * impossible for a loader that is too old to even load this driver.
+ * \note
+ * There is no need to check the minimum API version in this function. Since
+ * the \c __driCreateNewScreen function is versioned, it is impossible for a
+ * loader that is too old to even load this driver.
*/
-static __DRIscreen *
-driCreateNewScreen(int scrn,
- const __DRIversion *ddx_version,
- const __DRIversion *dri_version,
- const __DRIversion *drm_version,
- const __DRIframebuffer *frame_buffer,
- drmAddress pSAREA, int fd,
- const __DRIextension **extensions,
- const __DRIconfig ***driver_modes,
- void *loaderPrivate)
+__DRIscreenPrivate *
+__driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
+ __GLcontextModes * modes,
+ const __DRIversion * ddx_version,
+ const __DRIversion * dri_version,
+ const __DRIversion * drm_version,
+ const __DRIframebuffer * frame_buffer,
+ drm_sarea_t *pSAREA,
+ int fd,
+ int internal_api_version,
+ const struct __DriverAPIRec *driverAPI)
{
- static const __DRIextension *emptyExtensionList[] = { NULL };
- __DRIscreen *psp;
+ __DRIscreenPrivate *psp;
+
+
+ api_ver = internal_api_version;
+
+ psp = (__DRIscreenPrivate *)_mesa_malloc(sizeof(__DRIscreenPrivate));
+ if (!psp) {
+ return NULL;
+ }
- psp = _mesa_malloc(sizeof *psp);
- if (!psp)
+ /* Create the hash table */
+ psp->drawHash = drmHashCreate();
+ if ( psp->drawHash == NULL ) {
+ _mesa_free( psp );
return NULL;
+ }
- setupLoaderExtensions(psp, extensions);
+ psp->display = dpy;
+ psp->myNum = scrn;
+ psp->psc = psc;
+ psp->modes = modes;
/*
** NOT_DONE: This is used by the X server to detect when the client
@@ -885,12 +988,20 @@ driCreateNewScreen(int scrn,
*/
psp->drawLockID = 1;
- psp->drm_version = *drm_version;
- psp->ddx_version = *ddx_version;
- psp->dri_version = *dri_version;
+ psp->drmMajor = drm_version->major;
+ psp->drmMinor = drm_version->minor;
+ psp->drmPatch = drm_version->patch;
+ psp->ddxMajor = ddx_version->major;
+ psp->ddxMinor = ddx_version->minor;
+ psp->ddxPatch = ddx_version->patch;
+ psp->driMajor = dri_version->major;
+ psp->driMinor = dri_version->minor;
+ psp->driPatch = dri_version->patch;
+
+ /* install driver's callback functions */
+ memcpy( &psp->DriverAPI, driverAPI, sizeof(struct __DriverAPIRec) );
psp->pSAREA = pSAREA;
- psp->lock = (drmLock *) &psp->pSAREA->lock;
psp->pFB = frame_buffer->base;
psp->fbSize = frame_buffer->size;
@@ -901,10 +1012,7 @@ driCreateNewScreen(int scrn,
psp->pDevPriv = frame_buffer->dev_priv;
psp->fbBPP = psp->fbStride * 8 / frame_buffer->width;
- psp->extensions = emptyExtensionList;
psp->fd = fd;
- psp->myNum = scrn;
- psp->dri2.enabled = GL_FALSE;
/*
** Do not init dummy context here; actual initialization will be
@@ -913,143 +1021,63 @@ driCreateNewScreen(int scrn,
*/
psp->dummyContextPriv.driScreenPriv = NULL;
- psp->DriverAPI = driDriverAPI;
-
- *driver_modes = driDriverAPI.InitScreen(psp);
- if (*driver_modes == NULL) {
- _mesa_free(psp);
- return NULL;
- }
-
- return psp;
-}
-
-
-static __DRIscreen *
-dri2CreateNewScreen(int scrn, int fd, unsigned int sarea_handle,
- const __DRIextension **extensions,
- const __DRIconfig ***driver_configs, void *data)
-{
- static const __DRIextension *emptyExtensionList[] = { NULL };
- __DRIscreen *psp;
- unsigned int *p;
- drmVersionPtr version;
-
- if (driDriverAPI.InitScreen2 == NULL)
- return NULL;
-
- psp = _mesa_malloc(sizeof(*psp));
- if (!psp)
- return NULL;
-
- setupLoaderExtensions(psp, extensions);
-
- version = drmGetVersion(fd);
- if (version) {
- psp->drm_version.major = version->version_major;
- psp->drm_version.minor = version->version_minor;
- psp->drm_version.patch = version->version_patchlevel;
- drmFreeVersion(version);
- }
-
- psp->extensions = emptyExtensionList;
- psp->fd = fd;
- psp->myNum = scrn;
- psp->dri2.enabled = GL_TRUE;
-
- if (drmBOReference(psp->fd, sarea_handle, &psp->dri2.sareaBO)) {
- fprintf(stderr, "Failed to reference DRI2 sarea BO\n");
- _mesa_free(psp);
- return NULL;
- }
-
- if (drmBOMap(psp->fd, &psp->dri2.sareaBO,
- DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &psp->dri2.sarea)) {
- drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
- _mesa_free(psp);
- return NULL;
- }
-
- p = psp->dri2.sarea;
- while (DRI2_SAREA_BLOCK_TYPE(*p)) {
- switch (DRI2_SAREA_BLOCK_TYPE(*p)) {
- case DRI2_SAREA_BLOCK_LOCK:
- psp->dri2.lock = (__DRILock *) p;
- break;
- case DRI2_SAREA_BLOCK_EVENT_BUFFER:
- psp->dri2.buffer = (__DRIEventBuffer *) p;
- break;
- }
- p = DRI2_SAREA_BLOCK_NEXT(p);
- }
+ psc->destroyScreen = driDestroyScreen;
+ psc->createNewDrawable = driCreateNewDrawable;
+ psc->getDrawable = driGetDrawable;
+ psc->getMSC = driGetMSC;
+ psc->createNewContext = driCreateNewContext;
- psp->lock = (drmLock *) &psp->dri2.lock->lock;
+ if (internal_api_version >= 20070121)
+ psc->setTexOffset = psp->DriverAPI.setTexOffset;
- psp->DriverAPI = driDriverAPI;
- *driver_configs = driDriverAPI.InitScreen2(psp);
- if (*driver_configs == NULL) {
- drmBOUnmap(psp->fd, &psp->dri2.sareaBO);
- drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
- _mesa_free(psp);
+ if ( (psp->DriverAPI.InitDriver != NULL)
+ && !(*psp->DriverAPI.InitDriver)(psp) ) {
+ _mesa_free( psp );
return NULL;
}
- psp->DriverAPI = driDriverAPI;
return psp;
}
-static const __DRIextension **driGetExtensions(__DRIscreen *psp)
-{
- return psp->extensions;
-}
-
-const __DRIlegacyExtension driLegacyExtension = {
- { __DRI_LEGACY, __DRI_LEGACY_VERSION },
- driCreateNewScreen,
- driCreateNewDrawable,
- driCreateNewContext
-};
-
-const __DRIcoreExtension driCoreExtension = {
- { __DRI_CORE, __DRI_CORE_VERSION },
- dri2CreateNewScreen,
- driDestroyScreen,
- driGetExtensions,
- driGetConfigAttrib,
- driIndexConfigAttrib,
- dri2CreateNewDrawable,
- driDestroyDrawable,
- driSwapBuffers,
- dri2CreateNewContext,
- driCopyContext,
- driDestroyContext,
- driBindContext,
- driUnbindContext
-};
-
-/* This is the table of extensions that the loader will dlsym() for. */
-PUBLIC const __DRIextension *__driDriverExtensions[] = {
- &driCoreExtension.base,
- &driLegacyExtension.base,
- NULL
-};
-static int
-driFrameTracking(__DRIdrawable *drawable, GLboolean enable)
+/**
+ * Compare the current GLX API version with a driver supplied required version.
+ *
+ * The minimum required version is compared with the API version exported by
+ * the \c __glXGetInternalVersion function (in libGL.so).
+ *
+ * \param required_version Minimum required internal GLX API version.
+ * \return A tri-value return, as from strcmp is returned. A value less
+ * than, equal to, or greater than zero will be returned if the
+ * internal GLX API version is less than, equal to, or greater
+ * than \c required_version.
+ *
+ * \sa __glXGetInternalVersion().
+ */
+int driCompareGLXAPIVersion( GLint required_version )
{
- return GLX_BAD_CONTEXT;
+ if ( api_ver > required_version ) {
+ return 1;
+ }
+ else if ( api_ver == required_version ) {
+ return 0;
+ }
+
+ return -1;
}
+
static int
-driQueryFrameTracking(__DRIdrawable *dpriv,
- int64_t * sbc, int64_t * missedFrames,
- float * lastMissedUsage, float * usage)
+driQueryFrameTracking( __DRInativeDisplay * dpy, void * priv,
+ int64_t * sbc, int64_t * missedFrames,
+ float * lastMissedUsage, float * usage )
{
__DRIswapInfo sInfo;
int status;
int64_t ust;
- __DRIscreenPrivate *psp = dpriv->driScreenPriv;
+ __DRIdrawablePrivate * dpriv = (__DRIdrawablePrivate *) priv;
+
status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo );
if ( status == 0 ) {
@@ -1057,18 +1085,13 @@ driQueryFrameTracking(__DRIdrawable *dpriv,
*missedFrames = sInfo.swap_missed_count;
*lastMissedUsage = sInfo.swap_missed_usage;
- (*psp->systemTime->getUST)( & ust );
+ (*dri_interface->getUST)( & ust );
*usage = driCalculateSwapUsage( dpriv, sInfo.swap_ust, ust );
}
return status;
}
-const __DRIframeTrackingExtension driFrameTrackingExtension = {
- { __DRI_FRAME_TRACKING, __DRI_FRAME_TRACKING_VERSION },
- driFrameTracking,
- driQueryFrameTracking
-};
/**
* Calculate amount of swap interval used between GLX buffer swaps.
@@ -1106,10 +1129,11 @@ driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, int64_t last_swap_ust,
int32_t d;
int interval;
float usage = 1.0;
- __DRIscreenPrivate *psp = dPriv->driScreenPriv;
- if ( (*psp->systemTime->getMSCRate)(dPriv, &n, &d, dPriv->loaderPrivate) ) {
- interval = (dPriv->swap_interval != 0) ? dPriv->swap_interval : 1;
+
+ if ( (*dri_interface->getMSCRate)( dPriv->display, dPriv->draw, &n, &d ) ) {
+ interval = (dPriv->pdraw->swap_interval != 0)
+ ? dPriv->pdraw->swap_interval : 1;
/* We want to calculate