dri_util.c revision 3528d61820e9ae1aafb12fb90849155f3cab6d2c
1680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/* $XFree86: xc/lib/GL/dri/dri_util.c,v 1.7 2003/04/28 17:01:25 dawes Exp $ */ 2680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 3680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \file dri_util.c 4680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * DRI utility functions. 5680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 6680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This module acts as glue between GLX and the actual hardware driver. A DRI 7680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * driver doesn't really \e have to use any of this - it's optional. But, some 8680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * useful stuff is done here that otherwise would have to be duplicated in most 9680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drivers. 10680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 11680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Basically, these utility functions take care of some of the dirty details of 12680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * screen initialization, context creation, context binding, DRM setup, etc. 13680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 14680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * These functions are compiled into each DRI driver so libGL.so knows nothing 15680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * about them. 16680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 17680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 18680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 19680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <assert.h> 20680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <stdarg.h> 21680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <unistd.h> 22680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <sys/mman.h> 23680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <stdio.h> 247c46033130b1b4d6098647d85c2710367572e079Ian Romanick 2538b317d508a2a3a4cc6d700ebca80c3b06c913e2Alan Hourihane#ifndef MAP_FAILED 2638b317d508a2a3a4cc6d700ebca80c3b06c913e2Alan Hourihane#define MAP_FAILED ((void *)-1) 2738b317d508a2a3a4cc6d700ebca80c3b06c913e2Alan Hourihane#endif 2838b317d508a2a3a4cc6d700ebca80c3b06c913e2Alan Hourihane 29c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick#include "imports.h" 30c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick#define None 0 317c46033130b1b4d6098647d85c2710367572e079Ian Romanick 327c46033130b1b4d6098647d85c2710367572e079Ian Romanick#include "dri_util.h" 33ffb36d57a5f6359b5b91b73af60482a0016dd431Jon Smirl#include "drm_sarea.h" 34680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 35c604e457d1ebe9a884b0a1fb08af38a0ce486699Ian Romanick#ifndef GLX_OML_sync_control 367c46033130b1b4d6098647d85c2710367572e079Ian Romanicktypedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRInativeDisplay *dpy, __DRIid drawable, int32_t *numerator, int32_t *denominator); 378cdccc82d7948daee256e092a5253d49e277ef75Ian Romanick#endif 388cdccc82d7948daee256e092a5253d49e277ef75Ian Romanick 395f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick/* This pointer *must* be set by the driver's __driCreateNewScreen funciton! 405f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick */ 415f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanickconst __DRIinterfaceMethods * dri_interface = NULL; 425f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick 43680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 44680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This is used in a couple of places that call \c driCreateNewDrawable. 45680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 46680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic const int empty_attribute_list[1] = { None }; 47680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 48680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 49680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 50680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Cached copy of the internal API version used by libGL and the client-side 51680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * DRI driver. 52680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 53680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic int api_ver = 0; 54680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 55680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/* forward declarations */ 56b4b040f7d83f5f4917c48bf5833394d550e30421Brian Paulstatic int driQueryFrameTracking( __DRInativeDisplay *dpy, void *priv, 57b4b040f7d83f5f4917c48bf5833394d550e30421Brian Paul int64_t *sbc, int64_t *missedFrames, 58b4b040f7d83f5f4917c48bf5833394d550e30421Brian Paul float *lastMissedUsage, float *usage ); 59680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 60b4b040f7d83f5f4917c48bf5833394d550e30421Brian Paulstatic void *driCreateNewDrawable(__DRInativeDisplay *dpy, 61b4b040f7d83f5f4917c48bf5833394d550e30421Brian Paul const __GLcontextModes *modes, 62b4b040f7d83f5f4917c48bf5833394d550e30421Brian Paul __DRIid draw, __DRIdrawable *pdraw, 63b4b040f7d83f5f4917c48bf5833394d550e30421Brian Paul int renderType, const int *attrs); 64680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 6560b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic void driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate); 66680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 67680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 68680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 69680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Print message to \c stderr if the \c LIBGL_DEBUG environment variable 70680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * is set. 71680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 72680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Is called from the drivers. 73680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 74680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param f \c printf like format string. 75680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 76680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellvoid 77680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell__driUtilMessage(const char *f, ...) 78680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 79680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell va_list args; 80680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 81680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (getenv("LIBGL_DEBUG")) { 82680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell fprintf(stderr, "libGL error: \n"); 83680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell va_start(args, f); 84680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell vfprintf(stderr, f, args); 85680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell va_end(args); 86680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell fprintf(stderr, "\n"); 87680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 88680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 89680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 90680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 91680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 92680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Drawable list management */ 93680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 94680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/ 95680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 967c46033130b1b4d6098647d85c2710367572e079Ian Romanickstatic GLboolean __driAddDrawable(void *drawHash, __DRIdrawable *pdraw) 97680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 98680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private; 99680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 100680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (drmHashInsert(drawHash, pdp->draw, pdraw)) 101680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return GL_FALSE; 102680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 103680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return GL_TRUE; 104680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 105680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1060521ab46c1340d785ecfe64f4041c86912bc86afIan Romanickstatic __DRIdrawable *__driFindDrawable(void *drawHash, __DRIid draw) 107680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 108680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int retcode; 1098e5281fbe1a7b9beea77b93a9cdd1e842a3edfa0Keith Whitwell __DRIdrawable *pdraw; 110680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1118e5281fbe1a7b9beea77b93a9cdd1e842a3edfa0Keith Whitwell retcode = drmHashLookup(drawHash, draw, (void *)&pdraw); 112680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (retcode) 113680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return NULL; 114680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1158e5281fbe1a7b9beea77b93a9cdd1e842a3edfa0Keith Whitwell return pdraw; 116680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 117680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 118680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 119680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 120680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Find drawables in the local hash that have been destroyed on the 121680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * server. 122680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 123680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param drawHash Hash-table containing all know drawables. 124680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 125680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic void __driGarbageCollectDrawables(void *drawHash) 126680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 1270521ab46c1340d785ecfe64f4041c86912bc86afIan Romanick __DRIid draw; 12860b0e12830310e7c05b4043857ed277b28b1c781Ian Romanick __DRInativeDisplay *dpy; 1298e5281fbe1a7b9beea77b93a9cdd1e842a3edfa0Keith Whitwell __DRIdrawable *pdraw; 130680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1318e5281fbe1a7b9beea77b93a9cdd1e842a3edfa0Keith Whitwell if (drmHashFirst(drawHash, &draw, (void *)&pdraw) == 1) { 132680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell do { 1338e5281fbe1a7b9beea77b93a9cdd1e842a3edfa0Keith Whitwell __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private; 134680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell dpy = pdp->driScreenPriv->display; 1355f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick if (! (*dri_interface->windowExists)(dpy, draw)) { 13696f216565e09032021bafa7a805aa7707777fda1Brian Paul /* Destroy the local drawable data, if the drawable no 13796f216565e09032021bafa7a805aa7707777fda1Brian Paul longer exists in the Xserver */ 1388e5281fbe1a7b9beea77b93a9cdd1e842a3edfa0Keith Whitwell (*pdraw->destroyDrawable)(dpy, pdraw->private); 1398e5281fbe1a7b9beea77b93a9cdd1e842a3edfa0Keith Whitwell _mesa_free(pdraw); 140680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 1418e5281fbe1a7b9beea77b93a9cdd1e842a3edfa0Keith Whitwell } while (drmHashNext(drawHash, &draw, (void *)&pdraw) == 1); 142680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 143680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 144680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 145680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/ 146680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 147680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 148680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 149680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Context (un)binding functions */ 150680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 151680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/ 152680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 153680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 154680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Unbind context. 155680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 156680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dpy the display handle. 157680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param scrn the screen number. 158680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param draw drawable. 159680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param read Current reading drawable. 160680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param gc context. 161680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 162680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \return \c GL_TRUE on success, or \c GL_FALSE on failure. 163680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 164680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal 165680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::UnbindContext, and then decrements 166680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * __DRIdrawablePrivateRec::refcount which must be non-zero for a successful 167680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * return. 168680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 169680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * While casting the opaque private pointers associated with the parameters 170680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * into their respective real types it also assures they are not \c NULL. 171680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 172c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanickstatic GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn, 1730521ab46c1340d785ecfe64f4041c86912bc86afIan Romanick __DRIid draw, __DRIid read, 17474d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell __DRIcontext *ctx) 175680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 176680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIscreen *pDRIScreen; 177680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIdrawable *pdraw; 178680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIdrawable *pread; 179680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIcontextPrivate *pcp; 180680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIscreenPrivate *psp; 181680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIdrawablePrivate *pdp; 182680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIdrawablePrivate *prp; 183680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 184680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* 185680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** Assume error checking is done properly in glXMakeCurrent before 186c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick ** calling driUnbindContext. 187680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 188680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 18974d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell if (ctx == NULL || draw == None || read == None) { 190680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* ERROR!!! */ 191680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return GL_FALSE; 192680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 193680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1945f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick pDRIScreen = (*dri_interface->getScreen)(dpy, scrn); 195680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { 196680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* ERROR!!! */ 197680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return GL_FALSE; 198680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 199680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 200680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp = (__DRIscreenPrivate *)pDRIScreen->private; 20174d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell pcp = (__DRIcontextPrivate *)ctx->private; 202680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 203680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdraw = __driFindDrawable(psp->drawHash, draw); 204680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (!pdraw) { 205680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* ERROR!!! */ 206680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return GL_FALSE; 207680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 208680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp = (__DRIdrawablePrivate *)pdraw->private; 209680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 210680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pread = __driFindDrawable(psp->drawHash, read); 211680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (!pread) { 212680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* ERROR!!! */ 213680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return GL_FALSE; 214680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 215680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell prp = (__DRIdrawablePrivate *)pread->private; 216680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 217680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 218680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* Let driver unbind drawable from context */ 219680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell (*psp->DriverAPI.UnbindContext)(pcp); 220680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 221680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 222680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (pdp->refcount == 0) { 223680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* ERROR!!! */ 224680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return GL_FALSE; 225680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 226680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 227680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->refcount--; 228680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 229680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (prp != pdp) { 230680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (prp->refcount == 0) { 231680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* ERROR!!! */ 232680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return GL_FALSE; 233680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 234680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 235680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell prp->refcount--; 236680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 237680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 238680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 239680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* XXX this is disabled so that if we call SwapBuffers on an unbound 240680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * window we can determine the last context bound to the window and 241680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * use that context's lock. (BrianP, 2-Dec-2000) 242680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 243680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#if 0 244680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* Unbind the drawable */ 245680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pcp->driDrawablePriv = NULL; 246680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->driContextPriv = &psp->dummyContextPriv; 247680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#endif 248680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 249680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return GL_TRUE; 250680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 251680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 252680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 253680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 254680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function takes both a read buffer and a draw buffer. This is needed 255680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent 256680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * function. 257680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 258680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \bug This function calls \c driCreateNewDrawable in two places with the 259680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \c renderType hard-coded to \c GLX_WINDOW_BIT. Some checking might 260680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * be needed in those places when support for pbuffers and / or pixmaps 261680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * is added. Is it safe to assume that the drawable is a window? 262680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 2637c46033130b1b4d6098647d85c2710367572e079Ian Romanickstatic GLboolean DoBindContext(__DRInativeDisplay *dpy, 2640521ab46c1340d785ecfe64f4041c86912bc86afIan Romanick __DRIid draw, __DRIid read, 26574d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell __DRIcontext *ctx, const __GLcontextModes * modes, 26674d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell __DRIscreenPrivate *psp) 267680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 268680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIdrawable *pdraw; 269680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIdrawablePrivate *pdp; 270680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIdrawable *pread; 271680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIdrawablePrivate *prp; 27274d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell __DRIcontextPrivate * const pcp = ctx->private; 273680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 274680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 2750521ab46c1340d785ecfe64f4041c86912bc86afIan Romanick /* Find the _DRIdrawable which corresponds to the writing drawable. */ 276680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdraw = __driFindDrawable(psp->drawHash, draw); 277680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (!pdraw) { 278680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* Allocate a new drawable */ 2797c46033130b1b4d6098647d85c2710367572e079Ian Romanick pdraw = (__DRIdrawable *)_mesa_malloc(sizeof(__DRIdrawable)); 280680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (!pdraw) { 281680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* ERROR!!! */ 282680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return GL_FALSE; 283680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 284680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 285680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* Create a new drawable */ 286680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell driCreateNewDrawable(dpy, modes, draw, pdraw, GLX_WINDOW_BIT, 287680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell empty_attribute_list); 288680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (!pdraw->private) { 289680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* ERROR!!! */ 2907c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pdraw); 291680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return GL_FALSE; 292680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 293680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 294680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 295680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp = (__DRIdrawablePrivate *) pdraw->private; 296680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 2970521ab46c1340d785ecfe64f4041c86912bc86afIan Romanick /* Find the _DRIdrawable which corresponds to the reading drawable. */ 298680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (read == draw) { 299680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* read buffer == draw buffer */ 300680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell prp = pdp; 301680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 302680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell else { 303680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pread = __driFindDrawable(psp->drawHash, read); 304680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (!pread) { 305680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* Allocate a new drawable */ 3067c46033130b1b4d6098647d85c2710367572e079Ian Romanick pread = (__DRIdrawable *)_mesa_malloc(sizeof(__DRIdrawable)); 307680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (!pread) { 308680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* ERROR!!! */ 309680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return GL_FALSE; 310680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 311680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 312680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* Create a new drawable */ 313680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell driCreateNewDrawable(dpy, modes, read, pread, GLX_WINDOW_BIT, 314680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell empty_attribute_list); 315680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (!pread->private) { 316680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* ERROR!!! */ 3177c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pread); 318680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return GL_FALSE; 319680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 320680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 321680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell prp = (__DRIdrawablePrivate *) pread->private; 322680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 323680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 324680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* Bind the drawable to the context */ 325680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pcp->driDrawablePriv = pdp; 3267b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick pcp->driReadablePriv = prp; 327680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->driContextPriv = pcp; 328680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->refcount++; 329680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if ( pdp != prp ) { 330680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell prp->refcount++; 331680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 332680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 333680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* 334680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** Now that we have a context associated with this drawable, we can 335680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** initialize the drawable information if has not been done before. 336680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 337680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) { 338680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); 339680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __driUtilUpdateDrawableInfo(pdp); 340680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); 341680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 342680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 3437b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick if ((pdp != prp) && (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp)) { 3447b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); 3457b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick __driUtilUpdateDrawableInfo(prp); 3467b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); 3477b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick } 3487b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick 349680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* Call device-specific MakeCurrent */ 350680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell (*psp->DriverAPI.MakeCurrent)(pcp, pdp, prp); 351680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 352680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return GL_TRUE; 353680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 354680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 355680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 35674d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell/** 35774d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell * This function takes both a read buffer and a draw buffer. This is needed 35874d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent 35974d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell * function. 36074d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell */ 361c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanickstatic GLboolean driBindContext(__DRInativeDisplay *dpy, int scrn, 3620521ab46c1340d785ecfe64f4041c86912bc86afIan Romanick __DRIid draw, __DRIid read, 36374d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell __DRIcontext * ctx) 36474d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell{ 36574d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell __DRIscreen *pDRIScreen; 36674d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell 36774d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell /* 36874d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell ** Assume error checking is done properly in glXMakeCurrent before 36974d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell ** calling driBindContext. 37074d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell */ 37174d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell 37274d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell if (ctx == NULL || draw == None || read == None) { 37374d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell /* ERROR!!! */ 37474d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell return GL_FALSE; 37574d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell } 37674d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell 3775f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick pDRIScreen = (*dri_interface->getScreen)(dpy, scrn); 37874d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { 37974d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell /* ERROR!!! */ 38074d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell return GL_FALSE; 38174d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell } 38274d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell 38374d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell return DoBindContext( dpy, draw, read, ctx, ctx->mode, 38474d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell (__DRIscreenPrivate *)pDRIScreen->private ); 38574d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell} 386680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/ 387680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 388680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 389680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 390680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Drawable handling functions */ 391680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 392680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/ 393680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 394680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 395680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Update private drawable information. 396680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 397680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param pdp pointer to the private drawable information to update. 398680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 399680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function basically updates the __DRIdrawablePrivate struct's 4005f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick * cliprect information by calling \c __DRIinterfaceMethods::getDrawableInfo. 4015f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick * This is usually called by the DRI_VALIDATE_DRAWABLE_INFO macro which 402680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * compares the __DRIdrwablePrivate pStamp and lastStamp values. If 403680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * the values are different that means we have to update the clipping 404680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * info. 405680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 406680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellvoid 407680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell__driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) 408680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 409680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIscreenPrivate *psp; 410680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIcontextPrivate *pcp = pdp->driContextPriv; 411680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 4127b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick if (!pcp 4137b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick || ((pdp != pcp->driDrawablePriv) && (pdp != pcp->driReadablePriv))) { 414682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström /* ERROR!!! 415682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström * ...but we must ignore it. There can be many contexts bound to a 416682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström * drawable. 417682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström */ 418680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 419680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 420680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp = pdp->driScreenPriv; 421680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (!psp) { 422680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* ERROR!!! */ 4233528d61820e9ae1aafb12fb90849155f3cab6d2cPanagiotis Papadakos _mesa_problem(NULL, "Warning! Possible infinite loop due to bug " 424682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström "in file %s, line %d\n", 425682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström __FILE__, __LINE__); 426680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return; 427680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 428680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 429680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (pdp->pClipRects) { 4307c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pdp->pClipRects); 431680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 432680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 433680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (pdp->pBackClipRects) { 4347c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pdp->pBackClipRects); 435680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 436680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 437680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); 438680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 439680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (!__driFindDrawable(psp->drawHash, pdp->draw) || 4405f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick ! (*dri_interface->getDrawableInfo)(pdp->display, pdp->screen, pdp->draw, 441680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell &pdp->index, &pdp->lastStamp, 442680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell &pdp->x, &pdp->y, &pdp->w, &pdp->h, 443680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell &pdp->numClipRects, &pdp->pClipRects, 444680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell &pdp->backX, 445680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell &pdp->backY, 446680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell &pdp->numBackClipRects, 447680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell &pdp->pBackClipRects )) { 448680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* Error -- eg the window may have been destroyed. Keep going 449680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * with no cliprects. 450680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 451680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->pStamp = &pdp->lastStamp; /* prevent endless loop */ 452680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->numClipRects = 0; 453680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->pClipRects = NULL; 454680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->numBackClipRects = 0; 455680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->pBackClipRects = NULL; 456680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 457680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell else 458680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp); 459680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 460680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); 461680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 462680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 463680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 464680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/ 465680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 466680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 467680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name GLX callbacks */ 468680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 469680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/ 470680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 471680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 472680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Swap buffers. 473680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 474680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dpy the display handle. 475680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param drawablePrivate opaque pointer to the per-drawable private info. 476680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 477680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal 478680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DRIdrawablePrivate::swapBuffers. 479680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 480680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Is called directly from glXSwapBuffers(). 481680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 48260b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic void driSwapBuffers( __DRInativeDisplay *dpy, void *drawablePrivate ) 483680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 484680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate; 485c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt drm_clip_rect_t rect; 486c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt 487680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell dPriv->swapBuffers(dPriv); 488c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt 489c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt /* Check that we actually have the new damage report method */ 490c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt if (api_ver < 20070105 || dri_interface->reportDamage == NULL) 491c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt return; 492c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt 493c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt /* Assume it's affecting the whole drawable for now */ 494c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt rect.x1 = 0; 495c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt rect.y1 = 0; 496c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt rect.x2 = rect.x1 + dPriv->w; 497c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt rect.y2 = rect.y1 + dPriv->h; 498c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt 499c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt /* Report the damage. Currently, all our drivers draw directly to the 500c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt * front buffer, so we report the damage there rather than to the backing 501c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt * store (if any). 502c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt */ 503c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt (*dri_interface->reportDamage)(dpy, dPriv->screen, dPriv->draw, 504c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt dPriv->x, dPriv->y, 505c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt &rect, 1, GL_TRUE); 506680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 507680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 508680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 509680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Called directly from a number of higher-level GLX functions. 510680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 511680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic int driGetMSC( void *screenPrivate, int64_t *msc ) 512680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 513680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIscreenPrivate *sPriv = (__DRIscreenPrivate *) screenPrivate; 514680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 515680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return sPriv->DriverAPI.GetMSC( sPriv, msc ); 516680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 517680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 518680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 519680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Called directly from a number of higher-level GLX functions. 520680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 52160b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic int driGetSBC( __DRInativeDisplay *dpy, void *drawablePrivate, int64_t *sbc ) 522680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 523680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate; 524680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIswapInfo sInfo; 525680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int status; 526680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 527680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 528680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo ); 529680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *sbc = sInfo.swap_count; 530680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 531680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return status; 532680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 533680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 53460b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic int driWaitForSBC( __DRInativeDisplay * dpy, void *drawablePriv, 535680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int64_t target_sbc, 536680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int64_t * msc, int64_t * sbc ) 537680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 538680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv; 539680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 540680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return dPriv->driScreenPriv->DriverAPI.WaitForSBC( dPriv, target_sbc, 541680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell msc, sbc ); 542680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 543680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 54460b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic int driWaitForMSC( __DRInativeDisplay * dpy, void *drawablePriv, 545680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int64_t target_msc, 546680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int64_t divisor, int64_t remainder, 547680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int64_t * msc, int64_t * sbc ) 548680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 549680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv; 550680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIswapInfo sInfo; 551680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int status; 552680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 553680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 554680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell status = dPriv->driScreenPriv->DriverAPI.WaitForMSC( dPriv, target_msc, 555680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell divisor, remainder, 556680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell msc ); 557680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 558680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* GetSwapInfo() may not be provided by the driver if GLX_SGI_video_sync 559680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * is supported but GLX_OML_sync_control is not. Therefore, don't return 560680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * an error value if GetSwapInfo() is not implemented. 561680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 562680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if ( status == 0 563680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell && dPriv->driScreenPriv->DriverAPI.GetSwapInfo ) { 564680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo ); 565680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *sbc = sInfo.swap_count; 566680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 567680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 568680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return status; 569680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 570680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 57160b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic int64_t driSwapBuffersMSC( __DRInativeDisplay * dpy, void *drawablePriv, 572680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int64_t target_msc, 573680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int64_t divisor, int64_t remainder ) 574680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 575680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv; 576680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 577680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return dPriv->driScreenPriv->DriverAPI.SwapBuffersMSC( dPriv, target_msc, 578680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell divisor, 579680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell remainder ); 580680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 581680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 582f2ad1b60c0da11283b399008f491792790cea294Brian Paulstatic void driCopySubBuffer( __DRInativeDisplay *dpy, void *drawablePrivate, 583f2ad1b60c0da11283b399008f491792790cea294Brian Paul int x, int y, int w, int h) 584f2ad1b60c0da11283b399008f491792790cea294Brian Paul{ 585f2ad1b60c0da11283b399008f491792790cea294Brian Paul __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate; 586f2ad1b60c0da11283b399008f491792790cea294Brian Paul dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h); 587f2ad1b60c0da11283b399008f491792790cea294Brian Paul (void) dpy; 588f2ad1b60c0da11283b399008f491792790cea294Brian Paul} 589680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 590680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 591680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This is called via __DRIscreenRec's createNewDrawable pointer. 592680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 59360b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic void *driCreateNewDrawable(__DRInativeDisplay *dpy, 594680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell const __GLcontextModes *modes, 5950521ab46c1340d785ecfe64f4041c86912bc86afIan Romanick __DRIid draw, 596680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIdrawable *pdraw, 597680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int renderType, 598680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell const int *attrs) 599680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 6005f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick __DRIscreen * const pDRIScreen = (*dri_interface->getScreen)(dpy, modes->screen); 601680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIscreenPrivate *psp; 602680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIdrawablePrivate *pdp; 603680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 604680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 6051960182ece3f1eca06d2e439f64dd61be8a03ff5Ian Romanick pdraw->private = NULL; 6061960182ece3f1eca06d2e439f64dd61be8a03ff5Ian Romanick 607680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* Since pbuffers are not yet supported, no drawable attributes are 608680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * supported either. 609680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 610680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell (void) attrs; 611680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 612680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { 613680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return NULL; 614680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 615680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 6167c46033130b1b4d6098647d85c2710367572e079Ian Romanick pdp = (__DRIdrawablePrivate *)_mesa_malloc(sizeof(__DRIdrawablePrivate)); 617680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (!pdp) { 618680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return NULL; 619680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 620680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 6215f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick if (!(*dri_interface->createDrawable)(dpy, modes->screen, draw, &pdp->hHWDrawable)) { 6227c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pdp); 623680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return NULL; 624680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 625680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 626680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->draw = draw; 627680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->pdraw = pdraw; 628680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->refcount = 0; 629680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->pStamp = NULL; 630680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->lastStamp = 0; 631680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->index = 0; 632680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->x = 0; 633680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->y = 0; 634680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->w = 0; 635680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->h = 0; 636680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->numClipRects = 0; 637680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->numBackClipRects = 0; 638680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->pClipRects = NULL; 639680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->pBackClipRects = NULL; 640680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->display = dpy; 641680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->screen = modes->screen; 642680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 643680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp = (__DRIscreenPrivate *)pDRIScreen->private; 644680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->driScreenPriv = psp; 645680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->driContextPriv = &psp->dummyContextPriv; 646680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 647680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, modes, 648680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell renderType == GLX_PIXMAP_BIT)) { 6495f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick (void)(*dri_interface->destroyDrawable)(dpy, modes->screen, pdp->draw); 6507c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pdp); 651680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return NULL; 652680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 653680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 654680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdraw->private = pdp; 655680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdraw->destroyDrawable = driDestroyDrawable; 656680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdraw->swapBuffers = driSwapBuffers; /* called by glXSwapBuffers() */ 657680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 658c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick pdraw->getSBC = driGetSBC; 659c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick pdraw->waitForSBC = driWaitForSBC; 660c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick pdraw->waitForMSC = driWaitForMSC; 661c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick pdraw->swapBuffersMSC = driSwapBuffersMSC; 662c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick pdraw->frameTracking = NULL; 663c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick pdraw->queryFrameTracking = driQueryFrameTracking; 664c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick 665f2ad1b60c0da11283b399008f491792790cea294Brian Paul if (driCompareGLXAPIVersion (20060314) >= 0) 666f2ad1b60c0da11283b399008f491792790cea294Brian Paul pdraw->copySubBuffer = driCopySubBuffer; 667f2ad1b60c0da11283b399008f491792790cea294Brian Paul 668c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick /* This special default value is replaced with the configured 669c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick * default value when the drawable is first bound to a direct 670c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick * rendering context. 671c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick */ 672c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick pdraw->swap_interval = (unsigned)-1; 673680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 674680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->swapBuffers = psp->DriverAPI.SwapBuffers; 675680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 676680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* Add pdraw to drawable list */ 677680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (!__driAddDrawable(psp->drawHash, pdraw)) { 678680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* ERROR!!! */ 679680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell (*pdraw->destroyDrawable)(dpy, pdp); 6807c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pdp); 681680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp = NULL; 682680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdraw->private = NULL; 683680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 684680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 685680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return (void *) pdp; 686680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 687680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 688b4b040f7d83f5f4917c48bf5833394d550e30421Brian Paulstatic __DRIdrawable * 689b4b040f7d83f5f4917c48bf5833394d550e30421Brian PauldriGetDrawable(__DRInativeDisplay *dpy, __DRIid draw, void *screenPrivate) 690680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 691680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate; 692680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 693680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* 694680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** Make sure this routine returns NULL if the drawable is not bound 695680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** to a direct rendering context! 696680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 697680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return __driFindDrawable(psp->drawHash, draw); 698680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 699680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 700b4b040f7d83f5f4917c48bf5833394d550e30421Brian Paulstatic void 701b4b040f7d83f5f4917c48bf5833394d550e30421Brian PauldriDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate) 702680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 703680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *) drawablePrivate; 704eab896cc213157758d74a2f39b5e3b1e748c071fDave Airlie __DRIscreenPrivate *psp; 705eab896cc213157758d74a2f39b5e3b1e748c071fDave Airlie int scrn; 706680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 707680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (pdp) { 708eab896cc213157758d74a2f39b5e3b1e748c071fDave Airlie psp = pdp->driScreenPriv; 709eab896cc213157758d74a2f39b5e3b1e748c071fDave Airlie scrn = psp->myNum; 710680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell (*psp->DriverAPI.DestroyBuffer)(pdp); 7115f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick if ((*dri_interface->windowExists)(dpy, pdp->draw)) 7125f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick (void)(*dri_interface->destroyDrawable)(dpy, scrn, pdp->draw); 71396f216565e09032021bafa7a805aa7707777fda1Brian Paul drmHashDelete(psp->drawHash, pdp->draw); 714680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (pdp->pClipRects) { 7157c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pdp->pClipRects); 716680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->pClipRects = NULL; 717680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 718680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (pdp->pBackClipRects) { 7197c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pdp->pBackClipRects); 720680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->pBackClipRects = NULL; 721680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 7227c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pdp); 723680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 724680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 725680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 726680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/ 727680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 728680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 729680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 730680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Context handling functions */ 731680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 732680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/ 733680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 734680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 735680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Destroy the per-context private information. 736680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 737680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dpy the display handle. 738680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param scrn the screen number. 739680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param contextPrivate opaque pointer to the per-drawable private info. 740680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 741680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal 742680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls 743680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drmDestroyContext(), and finally frees \p contextPrivate. 744680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 745b4b040f7d83f5f4917c48bf5833394d550e30421Brian Paulstatic void 746b4b040f7d83f5f4917c48bf5833394d550e30421Brian PauldriDestroyContext(__DRInativeDisplay *dpy, int scrn, void *contextPrivate) 747680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 748680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIcontextPrivate *pcp = (__DRIcontextPrivate *) contextPrivate; 749680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 750680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (pcp) { 751680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell (*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp); 752680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash); 7535f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick (void) (*dri_interface->destroyContext)(dpy, scrn, pcp->contextID); 7547c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pcp); 755680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 756680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 757680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 758680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 759680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 760680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Create the per-drawable private driver information. 761680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 762680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dpy The display handle. 763680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param modes Mode used to create the new context. 764680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param render_type Type of rendering target. \c GLX_RGBA is the only 765680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * type likely to ever be supported for direct-rendering. 766680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param sharedPrivate The shared context dependent methods or \c NULL if 767680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * non-existent. 768680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param pctx DRI context to receive the context dependent methods. 769680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 770680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \returns An opaque pointer to the per-context private information on 771680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * success, or \c NULL on failure. 772680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 773680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal 774680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function allocates and fills a __DRIcontextPrivateRec structure. It 775680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * performs some device independent initialization and passes all the 776680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * relevent information to __DriverAPIRec::CreateContext to create the 777680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * context. 778680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 779680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 780680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic void * 78160b0e12830310e7c05b4043857ed277b28b1c781Ian RomanickdriCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes, 782680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int render_type, void *sharedPrivate, __DRIcontext *pctx) 783680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 784680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIscreen *pDRIScreen; 785680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIcontextPrivate *pcp; 786680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIcontextPrivate *pshare = (__DRIcontextPrivate *) sharedPrivate; 787680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIscreenPrivate *psp; 788680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell void * const shareCtx = (pshare != NULL) ? pshare->driverPrivate : NULL; 789680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 7905f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick pDRIScreen = (*dri_interface->getScreen)(dpy, modes->screen); 791680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { 792680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* ERROR!!! */ 793680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return NULL; 794680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 795680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 796680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp = (__DRIscreenPrivate *)pDRIScreen->private; 797680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 7987c46033130b1b4d6098647d85c2710367572e079Ian Romanick pcp = (__DRIcontextPrivate *)_mesa_malloc(sizeof(__DRIcontextPrivate)); 799680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (!pcp) { 800680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return NULL; 801680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 802680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 8035f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick if (! (*dri_interface->createContext)(dpy, modes->screen, modes->fbconfigID, 804680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell &pcp->contextID, &pcp->hHWContext)) { 8057c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pcp); 806680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return NULL; 807680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 808680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 809680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pcp->display = dpy; 810680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pcp->driScreenPriv = psp; 811680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pcp->driDrawablePriv = NULL; 812680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 813680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* When the first context is created for a screen, initialize a "dummy" 814680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * context. 815680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 816680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 817680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (!psp->dummyContextPriv.driScreenPriv) { 818680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->dummyContextPriv.contextID = 0; 819680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->dummyContextPriv.hHWContext = psp->pSAREA->dummy_context; 820680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->dummyContextPriv.driScreenPriv = psp; 821680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->dummyContextPriv.driDrawablePriv = NULL; 822680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->dummyContextPriv.driverPrivate = NULL; 823680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* No other fields should be used! */ 824680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 825680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 826680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pctx->destroyContext = driDestroyContext; 827c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick pctx->bindContext = driBindContext; 828c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick pctx->unbindContext = driUnbindContext; 82974d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell 830680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if ( !(*psp->DriverAPI.CreateContext)(modes, pcp, shareCtx) ) { 8315f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick (void) (*dri_interface->destroyContext)(dpy, modes->screen, 8325f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick pcp->contextID); 8337c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pcp); 834680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return NULL; 835680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 836680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 837680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash); 838680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 839680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return pcp; 840680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 841680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/ 842680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 843680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 844680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 845680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Screen handling functions */ 846680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 847680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/ 848680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 849680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 850680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Destroy the per-screen private information. 851680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 852680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dpy the display handle. 853680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param scrn the screen number. 854680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param screenPrivate opaque pointer to the per-screen private information. 855680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 856680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal 857680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls 858680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drmClose(), and finally frees \p screenPrivate. 859680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 86060b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPrivate) 861680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 862680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate; 863680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 864680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (psp) { 865680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* No interaction with the X-server is possible at this point. This 866680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * routine is called after XCloseDisplay, so there is no protocol 867680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * stream open to the X-server anymore. 868680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 869680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 870680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (psp->DriverAPI.DestroyScreen) 871680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell (*psp->DriverAPI.DestroyScreen)(psp); 872680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 873680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX); 874680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize); 8757c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(psp->pDevPriv); 8765ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell (void)drmCloseOnce(psp->fd); 877680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if ( psp->modes != NULL ) { 87882e3ecf413704440ea64b3b582d68f82f7b83704Ian Romanick (*dri_interface->destroyContextModes)( psp->modes ); 879680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 880e5c28321b2047418ba960c5f9c3aa86cf2514bbbTilman Sauerbeck 881e5c28321b2047418ba960c5f9c3aa86cf2514bbbTilman Sauerbeck assert(psp->drawHash); 882e5c28321b2047418ba960c5f9c3aa86cf2514bbbTilman Sauerbeck drmHashDestroy(psp->drawHash); 883e5c28321b2047418ba960c5f9c3aa86cf2514bbbTilman Sauerbeck 8847c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(psp); 885680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 886680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 887680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 888680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 889680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 890680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Utility function used to create a new driver-private screen structure. 891680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 892680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dpy Display pointer 893680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param scrn Index of the screen 894680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param psc DRI screen data (not driver private) 895680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param modes Linked list of known display modes. This list is, at a 896680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * minimum, a list of modes based on the current display mode. 897680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * These roughly match the set of available X11 visuals, but it 898680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * need not be limited to X11! The calling libGL should create 899680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * a list that will inform the driver of the current display 900680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * mode (i.e., color buffer depth, depth buffer depth, etc.). 901680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param ddx_version Version of the 2D DDX. This may not be meaningful for 902680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * all drivers. 903680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dri_version Version of the "server-side" DRI. 904680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param drm_version Version of the kernel DRM. 905680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param frame_buffer Data describing the location and layout of the 906680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * framebuffer. 907680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param pSAREA Pointer the the SAREA. 908680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param fd Device handle for the DRM. 909680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param internal_api_version Version of the internal interface between the 910680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * driver and libGL. 911680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param driverAPI Driver API functions used by other routines in dri_util.c. 912c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick * 913c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick * \note 914c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick * There is no need to check the minimum API version in this function. Since 915c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick * the \c __driCreateNewScreen function is versioned, it is impossible for a 916c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick * loader that is too old to even load this driver. 917680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 918680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell__DRIscreenPrivate * 91960b0e12830310e7c05b4043857ed277b28b1c781Ian Romanick__driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, 920680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __GLcontextModes * modes, 921680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell const __DRIversion * ddx_version, 922680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell const __DRIversion * dri_version, 923680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell const __DRIversion * drm_version, 924680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell const __DRIframebuffer * frame_buffer, 925ffb36d57a5f6359b5b91b73af60482a0016dd431Jon Smirl drm_sarea_t *pSAREA, 926680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int fd, 927680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int internal_api_version, 928680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell const struct __DriverAPIRec *driverAPI) 929680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 930680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIscreenPrivate *psp; 931680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 932680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 933680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell api_ver = internal_api_version; 934680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 9357c46033130b1b4d6098647d85c2710367572e079Ian Romanick psp = (__DRIscreenPrivate *)_mesa_malloc(sizeof(__DRIscreenPrivate)); 936680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (!psp) { 937680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return NULL; 938680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 939680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 940680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* Create the hash table */ 941680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->drawHash = drmHashCreate(); 942680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if ( psp->drawHash == NULL ) { 9437c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free( psp ); 944680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return NULL; 945680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 946680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 947680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->display = dpy; 948680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->myNum = scrn; 949680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->psc = psc; 950680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->modes = modes; 951680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 952680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* 953680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** NOT_DONE: This is used by the X server to detect when the client 954680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** has died while holding the drawable lock. The client sets the 955680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** drawable lock to this value. 956680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 957680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->drawLockID = 1; 958680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 959680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->drmMajor = drm_version->major; 960680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->drmMinor = drm_version->minor; 961680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->drmPatch = drm_version->patch; 962680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->ddxMajor = ddx_version->major; 963680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->ddxMinor = ddx_version->minor; 964680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->ddxPatch = ddx_version->patch; 965680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->driMajor = dri_version->major; 966680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->driMinor = dri_version->minor; 967680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->driPatch = dri_version->patch; 968680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 969680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* install driver's callback functions */ 970680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell memcpy( &psp->DriverAPI, driverAPI, sizeof(struct __DriverAPIRec) ); 971680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 972680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->pSAREA = pSAREA; 973680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 974680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->pFB = frame_buffer->base; 975680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->fbSize = frame_buffer->size; 976680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->fbStride = frame_buffer->stride; 977680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->fbWidth = frame_buffer->width; 978680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->fbHeight = frame_buffer->height; 979680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->devPrivSize = frame_buffer->dev_priv_size; 980680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->pDevPriv = frame_buffer->dev_priv; 981fd4f7064e24654c89248be6d76f39c7baf22fce4Jon Smirl psp->fbBPP = psp->fbStride * 8 / frame_buffer->width; 982680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 983680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->fd = fd; 984680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 985680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* 986680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** Do not init dummy context here; actual initialization will be 987680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** done when the first DRI context is created. Init screen priv ptr 988680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** to NULL to let CreateContext routine that it needs to be inited. 989680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 990680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->dummyContextPriv.driScreenPriv = NULL; 991680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 992680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psc->destroyScreen = driDestroyScreen; 993680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psc->createNewDrawable = driCreateNewDrawable; 994680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psc->getDrawable = driGetDrawable; 99574d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell psc->getMSC = driGetMSC; 99674d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell psc->createNewContext = driCreateNewContext; 997680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 998680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if ( (psp->DriverAPI.InitDriver != NULL) 999680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell && !(*psp->DriverAPI.InitDriver)(psp) ) { 10007c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free( psp ); 1001680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return NULL; 1002680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 1003680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1004680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1005680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return psp; 1006680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 1007680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1008680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1009680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 1010680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Compare the current GLX API version with a driver supplied required version. 1011680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1012680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * The minimum required version is compared with the API version exported by 1013680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * the \c __glXGetInternalVersion function (in libGL.so). 1014680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1015680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param required_version Minimum required internal GLX API version. 1016680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \return A tri-value return, as from strcmp is returned. A value less 1017680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * than, equal to, or greater than zero will be returned if the 1018680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * internal GLX API version is less than, equal to, or greater 1019680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * than \c required_version. 1020680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1021680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \sa __glXGetInternalVersion(). 1022680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 10238d12a6d537ca346291bc3e3bc90cc73509f4b419Dave Airlieint driCompareGLXAPIVersion( GLint required_version ) 1024680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 1025680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if ( api_ver > required_version ) { 1026680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return 1; 1027680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 1028680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell else if ( api_ver == required_version ) { 1029680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return 0; 1030680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 1031680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1032680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return -1; 1033680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 1034680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1035680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1036680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic int 103760b0e12830310e7c05b4043857ed277b28b1c781Ian RomanickdriQueryFrameTracking( __DRInativeDisplay * dpy, void * priv, 1038680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int64_t * sbc, int64_t * missedFrames, 1039680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell float * lastMissedUsage, float * usage ) 1040680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 1041680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIswapInfo sInfo; 1042680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int status; 1043680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int64_t ust; 1044680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIdrawablePrivate * dpriv = (__DRIdrawablePrivate *) priv; 1045680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1046680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1047680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo ); 1048680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if ( status == 0 ) { 1049680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *sbc = sInfo.swap_count; 1050680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *missedFrames = sInfo.swap_missed_count; 1051680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *lastMissedUsage = sInfo.swap_missed_usage; 1052680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 10535f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick (*dri_interface->getUST)( & ust ); 1054680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *usage = driCalculateSwapUsage( dpriv, sInfo.swap_ust, ust ); 1055680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 1056680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1057680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return status; 1058680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 1059680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1060680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1061680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 1062680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Calculate amount of swap interval used between GLX buffer swaps. 1063680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1064680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * The usage value, on the range [0,max], is the fraction of total swap 1065680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * interval time used between GLX buffer swaps is calculated. 1066680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1067680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \f$p = t_d / (i * t_r)\f$ 1068680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1069680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Where \f$t_d\f$ is the time since the last GLX buffer swap, \f$i\f$ is the 1070680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * swap interval (as set by \c glXSwapIntervalSGI), and \f$t_r\f$ time 1071680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * required for a single vertical refresh period (as returned by \c 1072680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * glXGetMscRateOML). 1073680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1074680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * See the documentation for the GLX_MESA_swap_frame_usage extension for more 1075680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * details. 1076680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1077680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dPriv Pointer to the private drawable structure. 1078680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \return If less than a single swap interval time period was required 1079680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * between GLX buffer swaps, a number greater than 0 and less than 1080680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1.0 is returned. If exactly one swap interval time period is 1081680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * required, 1.0 is returned, and if more than one is required then 1082680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * a number greater than 1.0 will be returned. 1083680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1084680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \sa glXSwapIntervalSGI glXGetMscRateOML 1085680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1086680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \todo Instead of caching the \c glXGetMscRateOML function pointer, would it 1087680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * be possible to cache the sync rate? 1088680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 1089680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellfloat 1090680ec7f85158eae58fd5ab56da8c66a645883cb0Keith WhitwelldriCalculateSwapUsage( __DRIdrawablePrivate *dPriv, int64_t last_swap_ust, 1091680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int64_t current_ust ) 1092680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 1093680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int32_t n; 1094680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int32_t d; 1095680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int interval; 1096680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell float usage = 1.0; 1097680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1098680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 10995f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick if ( (*dri_interface->getMSCRate)( dPriv->display, dPriv->draw, &n, &d ) ) { 1100680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell interval = (dPriv->pdraw->swap_interval != 0) 1101680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ? dPriv->pdraw->swap_interval : 1; 1102680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1103680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1104680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* We want to calculate 1105680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * (current_UST - last_swap_UST) / (interval * us_per_refresh). We get 1106680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * current_UST by calling __glXGetUST. last_swap_UST is stored in 1107680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * dPriv->swap_ust. interval has already been calculated. 1108680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1109680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * The only tricky part is us_per_refresh. us_per_refresh is 1110680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1000000 / MSC_rate. We know the MSC_rate is n / d. We can flip it 1111680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * around and say us_per_refresh = 1000000 * d / n. Since this goes in 1112680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * the denominator of the final calculation, we calculate 1113680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * (interval * 1000000 * d) and move n into the numerator. 1114680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 1115680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1116680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell usage = (current_ust - last_swap_ust); 1117680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell usage *= n; 1118680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell usage /= (interval * d); 1119680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell usage /= 1000000.0; 1120680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 1121680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1122680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return usage; 1123680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 1124680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1125680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/ 1126