#define MAP_FAILED ((void *)-1)
#endif
-#include "imports.h"
+#include "main/imports.h"
#define None 0
#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);
#endif
-/* This pointer *must* be set by the driver's __driCreateNewScreen funciton!
- */
-const __DRIinterfaceMethods * dri_interface = NULL;
-
-/**
- * This is used in a couple of places that call \c driCreateNewDrawable.
- */
-static const int empty_attribute_list[1] = { None };
-
-
/**
* This is just a token extension used to signal that the driver
* supports setting a read drawable.
__DRI_READ_DRAWABLE, __DRI_READ_DRAWABLE_VERSION
};
-/**
- * Cached copy of the internal API version used by libGL and the client-side
- * DRI driver.
- */
-static int api_ver = 0;
-
-static void *driCreateNewDrawable(__DRIscreen *screen,
- const __GLcontextModes *modes,
- __DRIdrawable *pdraw,
- drm_drawable_t hwDrawable,
- int renderType, const int *attrs);
-
-static void driDestroyDrawable(__DRIdrawable *drawable);
-
-
/**
* Print message to \c stderr if the \c LIBGL_DEBUG environment variable
* is set.
}
}
+GLint
+driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 )
+{
+ 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;
+
+ if (rect1.x1 > rect1.x2 || rect1.y1 > rect1.y2) return 0;
+
+ return (rect1.x2 - rect1.x1) * (rect1.y2 - rect1.y1);
+}
/*****************************************************************/
/** \name Context (un)binding functions */
* While casting the opaque private pointers associated with the parameters
* into their respective real types it also assures they are not \c NULL.
*/
-static GLboolean driUnbindContext(__DRIcontext *ctx)
+static int driUnbindContext(__DRIcontext *pcp)
{
- __DRIcontextPrivate *pcp;
- __DRIscreenPrivate *psp;
- __DRIdrawablePrivate *pdp;
- __DRIdrawablePrivate *prp;
+ __DRIscreen *psp;
+ __DRIdrawable *pdp;
+ __DRIdrawable *prp;
/*
** Assume error checking is done properly in glXMakeCurrent before
** calling driUnbindContext.
*/
- if (ctx == NULL)
+ if (pcp == NULL)
return GL_FALSE;
- pcp = (__DRIcontextPrivate *)ctx->private;
- psp = (__DRIscreenPrivate *)pcp->driScreenPriv;
- pdp = (__DRIdrawablePrivate *)pcp->driDrawablePriv;
- prp = (__DRIdrawablePrivate *)pcp->driReadablePriv;
+ psp = pcp->driScreenPriv;
+ pdp = pcp->driDrawablePriv;
+ prp = pcp->driReadablePriv;
/* Let driver unbind drawable from context */
(*psp->DriverAPI.UnbindContext)(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(__DRIcontext * ctx,
- __DRIdrawable *pdraw,
- __DRIdrawable *pread)
+static int driBindContext(__DRIcontext *pcp,
+ __DRIdrawable *pdp,
+ __DRIdrawable *prp)
{
- __DRIdrawablePrivate *pdp;
- __DRIdrawablePrivate *prp;
- __DRIcontextPrivate * const pcp = ctx->private;
__DRIscreenPrivate *psp = pcp->driScreenPriv;
/*
** calling driBindContext.
*/
- if (ctx == NULL || pdraw == None || pread == None)
+ if (pcp == NULL || pdp == None || prp == None)
return GL_FALSE;
- pdp = (__DRIdrawablePrivate *) pdraw->private;
- prp = (__DRIdrawablePrivate *) pread->private;
-
/* Bind the drawable to the context */
pcp->driDrawablePriv = pdp;
pcp->driReadablePriv = prp;
** initialize the drawable information if has not been done before.
*/
- if (psp->dri2.enabled) {
- __driParseEvents(psp, pdp);
- __driParseEvents(psp, prp);
- } else {
+ if (!psp->dri2.enabled) {
if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) {
DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
__driUtilUpdateDrawableInfo(pdp);
void
__driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
{
- __DRIscreenPrivate *psp;
+ __DRIscreenPrivate *psp = pdp->driScreenPriv;
__DRIcontextPrivate *pcp = pdp->driContextPriv;
if (!pcp
*/
}
- 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;
DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
- if (! (*dri_interface->getDrawableInfo)(pdp->pdraw,
+ if (! (*psp->getDrawableInfo->getDrawableInfo)(pdp,
&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->pBackClipRects,
+ pdp->loaderPrivate)) {
/* Error -- eg the window may have been destroyed. Keep going
* with no cliprects.
*/
pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp);
DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
-
-}
-
-int
-__driParseEvents(__DRIscreenPrivate *psp, __DRIdrawablePrivate *pdp)
-{
- __DRIDrawableConfigEvent *dc;
- __DRIBufferAttachEvent *ba;
- unsigned int tail, mask, *p, end, total, size, changed;
- unsigned char *data;
- size_t rect_size;
- __DRIcontextPrivate *pcp = pdp->driContextPriv;
-
- if (pcp == NULL)
- return 0;
-
- /* 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);
- (*dri_interface->reemitDrawableInfo)(pdp->pdraw);
- DRM_LIGHT_LOCK(psp->fd, psp->lock, pcp->hHWContext);
- }
-
- total = psp->dri2.buffer->head - pdp->dri2.tail;
- mask = psp->dri2.buffer->size - 1;
- tail = pdp->dri2.tail;
- end = psp->dri2.buffer->head;
- data = psp->dri2.buffer->data;
- changed = 0;
-
- while (tail != end) {
- 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->hHWDrawable)
- break;
-
- if (pdp->w != dc->width || pdp->h != dc->height)
- changed = 1;
-
- pdp->x = dc->x;
- pdp->y = dc->y;
- pdp->w = dc->width;
- pdp->h = 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 = dc->num_rects;
- _mesa_free(pdp->pClipRects);
- rect_size = dc->num_rects * sizeof dc->rects[0];
- pdp->pClipRects = _mesa_malloc(rect_size);
- memcpy(pdp->pClipRects, dc->rects, rect_size);
-
- if (changed)
- (*psp->DriverAPI.UpdateBuffer)(pdp, p);
- break;
-
- case DRI2_EVENT_BUFFER_ATTACH:
- ba = (__DRIBufferAttachEvent *) p;
-
- if (ba->drawable != pdp->hHWDrawable)
- break;
-
- (*psp->DriverAPI.UpdateBuffer)(pdp, p);
- break;
-
- default:
- break;
- }
-
- tail += size;
- }
-
- pdp->dri2.tail = tail;
-
- /* FIXME: Return whether we changed anything. This check always
- * returns true if we received events, but we could refine the
- * check to only return TRUE if the drawable actually changed. */
-
- return total > 0;
}
/*@}*/
/*****************************************************************/
/*@{*/
+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->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.
*
*
* Is called directly from glXSwapBuffers().
*/
-static void driSwapBuffers(__DRIdrawable *drawable)
+static void driSwapBuffers(__DRIdrawable *dPriv)
{
- __DRIdrawablePrivate *dPriv = drawable->private;
- drm_clip_rect_t rect;
-
- if (!dPriv->numClipRects)
- return;
+ __DRIscreen *psp = dPriv->driScreenPriv;
- dPriv->swapBuffers(dPriv);
+ psp->DriverAPI.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)(dPriv->pdraw, dPriv->x, dPriv->y,
- &rect, 1, GL_TRUE);
+ driReportDamage(dPriv, dPriv->pClipRects, dPriv->numClipRects);
}
-static int driDrawableGetMSC( __DRIscreen *screen, __DRIdrawable *drawable,
+static int driDrawableGetMSC( __DRIscreen *sPriv, __DRIdrawable *dPriv,
int64_t *msc )
{
- __DRIscreenPrivate *sPriv = screen->private;
- __DRIdrawablePrivate *dPriv = drawable->private;
-
return sPriv->DriverAPI.GetDrawableMSC(sPriv, dPriv, msc);
}
-static int driWaitForMSC(__DRIdrawable *drawable, int64_t target_msc,
+
+static int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc,
int64_t divisor, int64_t remainder,
int64_t * msc, int64_t * sbc)
{
- __DRIdrawablePrivate *dPriv = drawable->private;
__DRIswapInfo sInfo;
int status;
-
status = dPriv->driScreenPriv->DriverAPI.WaitForMSC( dPriv, target_msc,
divisor, remainder,
msc );
return status;
}
+
const __DRImediaStreamCounterExtension driMediaStreamCounterExtension = {
{ __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION },
driWaitForMSC,
driDrawableGetMSC,
};
-static void driCopySubBuffer(__DRIdrawable *drawable,
+
+static void driCopySubBuffer(__DRIdrawable *dPriv,
int x, int y, int w, int h)
{
- __DRIdrawablePrivate *dPriv = drawable->private;
+ drm_clip_rect_t rect;
+
+ rect.x1 = x;
+ rect.y1 = dPriv->h - y - h;
+ rect.x2 = x + w;
+ rect.y2 = rect.y1 + h;
+ driReportDamage(dPriv, &rect, 1);
+
dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h);
}
driCopySubBuffer
};
-static void driSetSwapInterval(__DRIdrawable *drawable, unsigned int interval)
+static void driSetSwapInterval(__DRIdrawable *dPriv, unsigned int interval)
{
- __DRIdrawablePrivate *dpriv = drawable->private;
-
- dpriv->swap_interval = interval;
+ dPriv->swap_interval = interval;
}
-static unsigned int driGetSwapInterval(__DRIdrawable *drawable)
+static unsigned int driGetSwapInterval(__DRIdrawable *dPriv)
{
- __DRIdrawablePrivate *dpriv = drawable->private;
-
- return dpriv->swap_interval;
+ return dPriv->swap_interval;
}
const __DRIswapControlExtension driSwapControlExtension = {
/**
* This is called via __DRIscreenRec's createNewDrawable pointer.
*/
-static void *driCreateNewDrawable(__DRIscreen *screen,
- const __GLcontextModes *modes,
- __DRIdrawable *pdraw,
- drm_drawable_t hwDrawable,
- int renderType,
- const int *attrs)
+static __DRIdrawable *
+driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
+ drm_drawable_t hwDrawable, int renderType,
+ const int *attrs, void *data)
{
- __DRIscreenPrivate *psp;
- __DRIdrawablePrivate *pdp;
-
-
- pdraw->private = NULL;
+ __DRIdrawable *pdp;
/* Since pbuffers are not yet supported, no drawable attributes are
* supported either.
*/
(void) attrs;
- pdp = (__DRIdrawablePrivate *)_mesa_malloc(sizeof(__DRIdrawablePrivate));
+ pdp = _mesa_malloc(sizeof *pdp);
if (!pdp) {
return NULL;
}
+ pdp->loaderPrivate = data;
pdp->hHWDrawable = hwDrawable;
- pdp->pdraw = pdraw;
pdp->refcount = 0;
pdp->pStamp = NULL;
pdp->lastStamp = 0;
pdp->vblSeq = 0;
pdp->vblFlags = 0;
- psp = (__DRIscreenPrivate *)screen->private;
pdp->driScreenPriv = psp;
pdp->driContextPriv = &psp->dummyContextPriv;
- if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, modes,
+ if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes,
renderType == GLX_PIXMAP_BIT)) {
_mesa_free(pdp);
return NULL;
}
- pdraw->private = pdp;
- pdraw->destroyDrawable = driDestroyDrawable;
- pdraw->swapBuffers = driSwapBuffers; /* called by glXSwapBuffers() */
pdp->msc_base = 0;
/* This special default value is replaced with the configured
*/
pdp->swap_interval = (unsigned)-1;
- pdp->swapBuffers = psp->DriverAPI.SwapBuffers;
+ return pdp;
+}
+
- if (psp->dri2.enabled) {
- pdp->dri2.tail = 0;
- pdp->pBackClipRects = _mesa_malloc(sizeof *pdp->pBackClipRects);
- }
+static __DRIdrawable *
+dri2CreateNewDrawable(__DRIscreen *screen,
+ const __DRIconfig *config,
+ void *loaderPrivate)
+{
+ __DRIdrawable *pdraw;
+
+ pdraw = driCreateNewDrawable(screen, config, 0, 0, NULL, loaderPrivate);
+ if (!pdraw)
+ return NULL;
- return (void *) pdp;
+ pdraw->pClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects);
+ pdraw->pBackClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects);
+
+ return pdraw;
}
+
static void
-driDestroyDrawable(__DRIdrawable *drawable)
+driDestroyDrawable(__DRIdrawable *pdp)
{
- __DRIdrawablePrivate *pdp = drawable->private;
__DRIscreenPrivate *psp;
if (pdp) {
/**
* Destroy the per-context private information.
*
- * \param contextPrivate opaque pointer to the per-drawable private info.
- *
* \internal
* This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls
* drmDestroyContext(), and finally frees \p contextPrivate.
*/
static void
-driDestroyContext(__DRIcontext *context)
+driDestroyContext(__DRIcontext *pcp)
{
- __DRIcontextPrivate *pcp = context->private;
-
if (pcp) {
(*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp);
_mesa_free(pcp);
/**
* Create the per-drawable private driver information.
*
- * \param dpy The display handle.
- * \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
- * non-existent.
- * \param pctx DRI context to receive the context dependent methods.
+ * \param shared Context with which to share textures, etc. or NULL
*
* \returns An opaque pointer to the per-context private information on
* success, or \c NULL on failure.
* context.
*
*/
-static void *
-driCreateNewContext(__DRIscreen *screen, const __GLcontextModes *modes,
+static __DRIcontext *
+driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
int render_type, __DRIcontext *shared,
- drm_context_t hwContext, __DRIcontext *pctx)
+ drm_context_t hwContext, void *data)
{
- __DRIcontextPrivate *pcp;
- __DRIcontextPrivate *pshare = (shared != NULL) ? shared->private : NULL;
- __DRIscreenPrivate *psp;
- void * const shareCtx = (pshare != NULL) ? pshare->driverPrivate : NULL;
+ __DRIcontext *pcp;
+ void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
- psp = (__DRIscreenPrivate *)screen->private;
-
- pcp = (__DRIcontextPrivate *)_mesa_malloc(sizeof(__DRIcontextPrivate));
- if (!pcp) {
+ pcp = _mesa_malloc(sizeof *pcp);
+ if (!pcp)
return NULL;
- }
- pcp->hHWContext = hwContext;
pcp->driScreenPriv = psp;
pcp->driDrawablePriv = NULL;
/* No other fields should be used! */
}
- pctx->destroyContext = driDestroyContext;
- pctx->bindContext = driBindContext;
- pctx->unbindContext = driUnbindContext;
+ pcp->hHWContext = hwContext;
- if ( !(*psp->DriverAPI.CreateContext)(modes, pcp, shareCtx) ) {
+ if ( !(*psp->DriverAPI.CreateContext)(&config->modes, pcp, shareCtx) ) {
_mesa_free(pcp);
return NULL;
}
return pcp;
}
-/*@}*/
-static const __DRIextension **
-driGetExtensions(__DRIscreen *screen)
+static __DRIcontext *
+dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
+ __DRIcontext *shared, void *data)
{
- __DRIscreenPrivate *psp = screen->private;
+ return driCreateNewContext(screen, config, 0, shared, 0, data);
+}
- return psp->extensions;
+
+static int
+driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
+{
+ return GL_FALSE;
}
+/*@}*/
+
+
/*****************************************************************/
/** \name Screen handling functions */
/*****************************************************************/
/**
* Destroy the per-screen private information.
*
- * \param dpy the display handle.
- * \param scrn the screen number.
- * \param screenPrivate opaque pointer to the per-screen private information.
- *
* \internal
* This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls
* drmClose(), and finally frees \p screenPrivate.
*/
-static void driDestroyScreen(__DRIscreen *screen)
+static void driDestroyScreen(__DRIscreen *psp)
{
- __DRIscreenPrivate *psp = screen->private;
-
if (psp) {
/* No interaction with the X-server is possible at this point. This
* routine is called after XCloseDisplay, so there is no protocol
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 {
+ if (!psp->dri2.enabled) {
(void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
(void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
(void)drmCloseOnce(psp->fd);
}
}
+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_DRI2_LOADER) == 0)
+ psp->dri2.loader = (__DRIdri2LoaderExtension *) 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.
+ *
+ * For legacy DRI.
*
* \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
- * minimum, a list of modes based on the current display mode.
- * These roughly match the set of available X11 visuals, but it
- * need not be limited to X11! The calling libGL should create
- * a list that will inform the driver of the current display
- * mode (i.e., color buffer depth, depth buffer depth, etc.).
* \param ddx_version Version of the 2D DDX. This may not be meaningful for
* all drivers.
* \param dri_version Version of the "server-side" DRI.
* framebuffer.
* \param pSAREA Pointer the the SAREA.
* \param fd Device handle for the DRM.
- * \param internal_api_version Version of the internal interface between the
- * driver and libGL.
- * \param driverAPI Driver API functions used by other routines in dri_util.c.
+ * \param extensions ??
+ * \param driver_modes Returns modes suppoted by the driver
+ * \param loaderPrivate ??
*
* \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.
*/
-PUBLIC
-void * __DRI_CREATE_NEW_SCREEN( int scrn, __DRIscreen *psc,
- const __DRIversion * ddx_version,
- const __DRIversion * dri_version,
- const __DRIversion * drm_version,
- const __DRIframebuffer * frame_buffer,
- drmAddress pSAREA, int fd,
- int internal_api_version,
- const __DRIinterfaceMethods * interface,
- __GLcontextModes ** driver_modes )
-
+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 *psp;
static const __DRIextension *emptyExtensionList[] = { NULL };
- dri_interface = interface;
- api_ver = internal_api_version;
+ __DRIscreen *psp;
- psp = _mesa_malloc(sizeof(*psp));
+ psp = _mesa_calloc(sizeof *psp);
if (!psp)
return NULL;
- psp->psc = psc;
+ setupLoaderExtensions(psp, extensions);
/*
** NOT_DONE: This is used by the X server to detect when the client
*/
psp->dummyContextPriv.driScreenPriv = NULL;
- psc->destroyScreen = driDestroyScreen;
- psc->getExtensions = driGetExtensions;
- psc->createNewDrawable = driCreateNewDrawable;
- psc->createNewContext = driCreateNewContext;
+ psp->DriverAPI = driDriverAPI;
- *driver_modes = __driDriverInitScreen(psp);
+ *driver_modes = driDriverAPI.InitScreen(psp);
if (*driver_modes == NULL) {
_mesa_free(psp);
return NULL;
return psp;
}
-PUBLIC void *
-__DRI2_CREATE_NEW_SCREEN(int scrn, __DRIscreen *psc,
- const __DRIversion * ddx_version,
- const __DRIversion * dri_version,
- const __DRIversion * drm_version,
- int fd,
- unsigned int sarea_handle,
- const __DRIinterfaceMethods * interface,
- __GLcontextModes ** driver_modes)
+/**
+ * DRI2
+ */
+static __DRIscreen *
+dri2CreateNewScreen(int scrn, int fd,
+ const __DRIextension **extensions,
+ const __DRIconfig ***driver_configs, void *data)
{
- __DRIscreenPrivate *psp;
static const __DRIextension *emptyExtensionList[] = { NULL };
- dri_interface = interface;
- unsigned int *p;
- __GLcontextModes *(*initScreen)(__DRIscreen *psc);
+ __DRIscreen *psp;
+ drmVersionPtr version;
- initScreen = dlsym(NULL, __dri2DriverInitScreen);
- if (initScreen == NULL)
+ if (driDriverAPI.InitScreen2 == NULL)
return NULL;
psp = _mesa_malloc(sizeof(*psp));
if (!psp)
return NULL;
- psp->psc = psc;
+ 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->drm_version = *drm_version;
- psp->ddx_version = *ddx_version;
- psp->dri_version = *dri_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");
+ psp->DriverAPI = driDriverAPI;
+ *driver_configs = driDriverAPI.InitScreen2(psp);
+ if (*driver_configs == NULL) {
_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);
- }
-
- psp->lock = (drmLock *) &psp->dri2.lock->lock;
-
- psc->destroyScreen = driDestroyScreen;
- psc->getExtensions = driGetExtensions;
- psc->createNewDrawable = driCreateNewDrawable;
- psc->createNewContext = driCreateNewContext;
-
- *driver_modes = initScreen(psp);
- if (*driver_modes == NULL) {
- drmBOUnmap(psp->fd, &psp->dri2.sareaBO);
- drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
- _mesa_free(psp);
- return NULL;
- }
+ psp->DriverAPI = driDriverAPI;
return psp;
}
-/**
- * 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 )
+static const __DRIextension **driGetExtensions(__DRIscreen *psp)
{
- if ( api_ver > required_version ) {
- return 1;
- }
- else if ( api_ver == required_version ) {
- return 0;
- }
-
- return -1;
+ return psp->extensions;
}
+/** Core interface */
+const __DRIcoreExtension driCoreExtension = {
+ { __DRI_CORE, __DRI_CORE_VERSION },
+ NULL,
+ driDestroyScreen,
+ driGetExtensions,
+ driGetConfigAttrib,
+ driIndexConfigAttrib,
+ NULL,
+ driDestroyDrawable,
+ driSwapBuffers,
+ NULL,
+ driCopyContext,
+ driDestroyContext,
+ driBindContext,
+ driUnbindContext
+};
+
+/** Legacy DRI interface */
+const __DRIlegacyExtension driLegacyExtension = {
+ { __DRI_LEGACY, __DRI_LEGACY_VERSION },
+ driCreateNewScreen,
+ driCreateNewDrawable,
+ driCreateNewContext,
+};
+
+/** Legacy DRI interface */
+const __DRIdri2Extension driDRI2Extension = {
+ { __DRI_DRI2, __DRI_DRI2_VERSION },
+ dri2CreateNewScreen,
+ dri2CreateNewDrawable,
+ dri2CreateNewContext,
+};
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+ &driCoreExtension.base,
+ &driLegacyExtension.base,
+ &driDRI2Extension.base,
+ NULL
+};
static int
driFrameTracking(__DRIdrawable *drawable, GLboolean enable)
}
static int
-driQueryFrameTracking(__DRIdrawable *drawable,
+driQueryFrameTracking(__DRIdrawable *dpriv,
int64_t * sbc, int64_t * missedFrames,
float * lastMissedUsage, float * usage)
{
__DRIswapInfo sInfo;
int status;
int64_t ust;
- __DRIdrawablePrivate * dpriv = drawable->private;
-
+ __DRIscreenPrivate *psp = dpriv->driScreenPriv;
status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo );
if ( status == 0 ) {
*missedFrames = sInfo.swap_missed_count;
*lastMissedUsage = sInfo.swap_missed_usage;
- (*dri_interface->getUST)( & ust );
+ (*psp->systemTime->getUST)( & ust );
*usage = driCalculateSwapUsage( dpriv, sInfo.swap_ust, ust );
}
int32_t d;
int interval;
float usage = 1.0;
+ __DRIscreenPrivate *psp = dPriv->driScreenPriv;
-
- if ( (*dri_interface->getMSCRate)(dPriv->pdraw, &n, &d) ) {
+ if ( (*psp->systemTime->getMSCRate)(dPriv, &n, &d, dPriv->loaderPrivate) ) {
interval = (dPriv->swap_interval != 0) ? dPriv->swap_interval : 1;