dri_util.c revision c95e66120be049ee51ff84868b1da3379b312fab
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" 34c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis#include "utils.h" 35680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 36c604e457d1ebe9a884b0a1fb08af38a0ce486699Ian Romanick#ifndef GLX_OML_sync_control 37aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsbergtypedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRIdrawable *drawable, int32_t *numerator, int32_t *denominator); 388cdccc82d7948daee256e092a5253d49e277ef75Ian Romanick#endif 398cdccc82d7948daee256e092a5253d49e277ef75Ian Romanick 40680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 41f968f67e6214416f04b8875ce59a94a02f464c81Kristian Høgsberg * This is just a token extension used to signal that the driver 42f968f67e6214416f04b8875ce59a94a02f464c81Kristian Høgsberg * supports setting a read drawable. 43f968f67e6214416f04b8875ce59a94a02f464c81Kristian Høgsberg */ 44f968f67e6214416f04b8875ce59a94a02f464c81Kristian Høgsbergconst __DRIextension driReadDrawableExtension = { 45ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg __DRI_READ_DRAWABLE, __DRI_READ_DRAWABLE_VERSION 46f968f67e6214416f04b8875ce59a94a02f464c81Kristian Høgsberg}; 47f968f67e6214416f04b8875ce59a94a02f464c81Kristian Høgsberg 48680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 49680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Print message to \c stderr if the \c LIBGL_DEBUG environment variable 50680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * is set. 51680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 52680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Is called from the drivers. 53680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 54680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param f \c printf like format string. 55680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 56680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellvoid 57680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell__driUtilMessage(const char *f, ...) 58680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 59680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell va_list args; 60680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 61680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (getenv("LIBGL_DEBUG")) { 62680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell fprintf(stderr, "libGL error: \n"); 63680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell va_start(args, f); 64680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell vfprintf(stderr, f, args); 65680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell va_end(args); 66680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell fprintf(stderr, "\n"); 67680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 68680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 69680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 70c95e66120be049ee51ff84868b1da3379b312fabGeorge SapountzisGLint 71c95e66120be049ee51ff84868b1da3379b312fabGeorge SapountzisdriIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 ) 72c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis{ 73c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis if (rect2.x1 > rect1.x1) rect1.x1 = rect2.x1; 74c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis if (rect2.x2 < rect1.x2) rect1.x2 = rect2.x2; 75c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis if (rect2.y1 > rect1.y1) rect1.y1 = rect2.y1; 76c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis if (rect2.y2 < rect1.y2) rect1.y2 = rect2.y2; 77c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis 78c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis if (rect1.x1 > rect1.x2 || rect1.y1 > rect1.y2) return 0; 79c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis 80c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis return (rect1.x2 - rect1.x1) * (rect1.y2 - rect1.y1); 81c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis} 82680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 83680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 84680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Context (un)binding functions */ 85680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 86680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/ 87680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 88680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 89680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Unbind context. 90680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 91aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsberg * \param scrn the screen. 92680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param gc context. 93680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 94680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \return \c GL_TRUE on success, or \c GL_FALSE on failure. 95680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 96680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal 97680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::UnbindContext, and then decrements 98680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * __DRIdrawablePrivateRec::refcount which must be non-zero for a successful 99680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * return. 100680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 101680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * While casting the opaque private pointers associated with the parameters 102680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * into their respective real types it also assures they are not \c NULL. 103680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 104e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int driUnbindContext(__DRIcontext *pcp) 105680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 106e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg __DRIscreen *psp; 107e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg __DRIdrawable *pdp; 108e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg __DRIdrawable *prp; 109680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 110680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* 111680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** Assume error checking is done properly in glXMakeCurrent before 112c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick ** calling driUnbindContext. 113680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 114680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 115e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg if (pcp == NULL) 116aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsberg return GL_FALSE; 117680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 118e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg psp = pcp->driScreenPriv; 119e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg pdp = pcp->driDrawablePriv; 120e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg prp = pcp->driReadablePriv; 121680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 122680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* Let driver unbind drawable from context */ 123680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell (*psp->DriverAPI.UnbindContext)(pcp); 124680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 125680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (pdp->refcount == 0) { 126680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* ERROR!!! */ 127680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return GL_FALSE; 128680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 129680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 130680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->refcount--; 131680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 132680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (prp != pdp) { 133680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (prp->refcount == 0) { 134680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* ERROR!!! */ 135680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return GL_FALSE; 136680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 137680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 138680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell prp->refcount--; 139680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 140680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 141680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 142680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* XXX this is disabled so that if we call SwapBuffers on an unbound 143680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * window we can determine the last context bound to the window and 144680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * use that context's lock. (BrianP, 2-Dec-2000) 145680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 146680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#if 0 147680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* Unbind the drawable */ 148680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pcp->driDrawablePriv = NULL; 149680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->driContextPriv = &psp->dummyContextPriv; 150680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#endif 151680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 152680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return GL_TRUE; 153680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 154680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 155680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 156680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 157680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function takes both a read buffer and a draw buffer. This is needed 158680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent 159680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * function. 160680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 161e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int driBindContext(__DRIcontext *pcp, 162e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg __DRIdrawable *pdp, 163e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg __DRIdrawable *prp) 164680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 165aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsberg __DRIscreenPrivate *psp = pcp->driScreenPriv; 166680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 167f1139e4c662c47357ee054c2e004b13c9f74ffe1Kristian Høgsberg /* 168f1139e4c662c47357ee054c2e004b13c9f74ffe1Kristian Høgsberg ** Assume error checking is done properly in glXMakeCurrent before 169f1139e4c662c47357ee054c2e004b13c9f74ffe1Kristian Høgsberg ** calling driBindContext. 170f1139e4c662c47357ee054c2e004b13c9f74ffe1Kristian Høgsberg */ 171f1139e4c662c47357ee054c2e004b13c9f74ffe1Kristian Høgsberg 172e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg if (pcp == NULL || pdp == None || prp == None) 173f1139e4c662c47357ee054c2e004b13c9f74ffe1Kristian Høgsberg return GL_FALSE; 174f1139e4c662c47357ee054c2e004b13c9f74ffe1Kristian Høgsberg 175680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* Bind the drawable to the context */ 176680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pcp->driDrawablePriv = pdp; 1777b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick pcp->driReadablePriv = prp; 178680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->driContextPriv = pcp; 179680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->refcount++; 180680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if ( pdp != prp ) { 181680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell prp->refcount++; 182680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 183680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 184680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* 185680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** Now that we have a context associated with this drawable, we can 186680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** initialize the drawable information if has not been done before. 187680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 188680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1897da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg if (psp->dri2.enabled) { 1902d5ea175f7fcd65de71b7589435b9a908f998d51Kristian Høgsberg __driParseEvents(pcp, pdp); 1912d5ea175f7fcd65de71b7589435b9a908f998d51Kristian Høgsberg __driParseEvents(pcp, prp); 1927da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg } else { 1937da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) { 1947da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); 1957da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg __driUtilUpdateDrawableInfo(pdp); 1967da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); 1977da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg } 1987da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 1997da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg if ((pdp != prp) && (!prp->pStamp || *prp->pStamp != prp->lastStamp)) { 2007da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); 2017da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg __driUtilUpdateDrawableInfo(prp); 2027da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); 2037da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg } 2047b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick } 2057b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick 206680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* Call device-specific MakeCurrent */ 207680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell (*psp->DriverAPI.MakeCurrent)(pcp, pdp, prp); 208680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 209680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return GL_TRUE; 210680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 211680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 212680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/ 213680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 214680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 215680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 216680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Drawable handling functions */ 217680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 218680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/ 219680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 220680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 221680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Update private drawable information. 222680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 223680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param pdp pointer to the private drawable information to update. 224680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 225680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function basically updates the __DRIdrawablePrivate struct's 2265f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick * cliprect information by calling \c __DRIinterfaceMethods::getDrawableInfo. 2275f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick * This is usually called by the DRI_VALIDATE_DRAWABLE_INFO macro which 228680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * compares the __DRIdrwablePrivate pStamp and lastStamp values. If 229680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * the values are different that means we have to update the clipping 230680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * info. 231680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 232680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellvoid 233680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell__driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) 234680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 2356cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg __DRIscreenPrivate *psp = pdp->driScreenPriv; 236680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIcontextPrivate *pcp = pdp->driContextPriv; 237680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 2387b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick if (!pcp 2397b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick || ((pdp != pcp->driDrawablePriv) && (pdp != pcp->driReadablePriv))) { 240682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström /* ERROR!!! 241682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström * ...but we must ignore it. There can be many contexts bound to a 242682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström * drawable. 243682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström */ 244680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 245680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 246680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (pdp->pClipRects) { 2477c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pdp->pClipRects); 248a903749b246fce26038c66d06fe7eb77daf815abMichel Dänzer pdp->pClipRects = NULL; 249680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 250680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 251680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (pdp->pBackClipRects) { 2527c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pdp->pBackClipRects); 253a903749b246fce26038c66d06fe7eb77daf815abMichel Dänzer pdp->pBackClipRects = NULL; 254680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 255680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 256680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); 257680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 258e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg if (! (*psp->getDrawableInfo->getDrawableInfo)(pdp, 259680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell &pdp->index, &pdp->lastStamp, 260680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell &pdp->x, &pdp->y, &pdp->w, &pdp->h, 261680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell &pdp->numClipRects, &pdp->pClipRects, 262680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell &pdp->backX, 263680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell &pdp->backY, 264680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell &pdp->numBackClipRects, 265e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg &pdp->pBackClipRects, 266e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg pdp->loaderPrivate)) { 267680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* Error -- eg the window may have been destroyed. Keep going 268680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * with no cliprects. 269680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 270680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->pStamp = &pdp->lastStamp; /* prevent endless loop */ 271680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->numClipRects = 0; 272680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->pClipRects = NULL; 273680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->numBackClipRects = 0; 274680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->pBackClipRects = NULL; 275680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 276680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell else 277680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp); 278680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 279680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); 280680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 281680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 282680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 2837da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsbergint 2842d5ea175f7fcd65de71b7589435b9a908f998d51Kristian Høgsberg__driParseEvents(__DRIcontextPrivate *pcp, __DRIdrawablePrivate *pdp) 2857da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg{ 2862d5ea175f7fcd65de71b7589435b9a908f998d51Kristian Høgsberg __DRIscreenPrivate *psp = pcp->driScreenPriv; 2874f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg __DRIDrawableConfigEvent *dc, *last_dc; 2884f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg __DRIBufferAttachEvent *ba, *last_ba; 2897da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg unsigned int tail, mask, *p, end, total, size, changed; 2907da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg unsigned char *data; 2917da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg size_t rect_size; 2927da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 2937da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg /* Check for wraparound. */ 2947da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg if (psp->dri2.buffer->prealloc - pdp->dri2.tail > psp->dri2.buffer->size) { 2957da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg /* If prealloc overlaps into what we just parsed, the 2967da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg * server overwrote it and we have to reset our tail 2977da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg * pointer. */ 2987da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg DRM_UNLOCK(psp->fd, psp->lock, pcp->hHWContext); 299e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg (*psp->dri2.loader->reemitDrawableInfo)(pdp, &pdp->dri2.tail, 300e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg pdp->loaderPrivate); 3017da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg DRM_LIGHT_LOCK(psp->fd, psp->lock, pcp->hHWContext); 3027da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg } 3037da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 3047da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg total = psp->dri2.buffer->head - pdp->dri2.tail; 3057da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg mask = psp->dri2.buffer->size - 1; 3067da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg end = psp->dri2.buffer->head; 3077da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg data = psp->dri2.buffer->data; 3084f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg 3097da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg changed = 0; 3104f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg last_dc = NULL; 3114f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg last_ba = NULL; 3127da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 3134f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg for (tail = pdp->dri2.tail; tail != end; tail += size) { 3147da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg p = (unsigned int *) (data + (tail & mask)); 3157da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg size = DRI2_EVENT_SIZE(*p); 3167da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg if (size > total || (tail & mask) + size > psp->dri2.buffer->size) { 3177da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg /* illegal data, bail out. */ 3187da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg fprintf(stderr, "illegal event size\n"); 3197da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg break; 3207da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg } 3217da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 3227da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg switch (DRI2_EVENT_TYPE(*p)) { 3237da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg case DRI2_EVENT_DRAWABLE_CONFIG: 3247da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg dc = (__DRIDrawableConfigEvent *) p; 325e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg if (dc->drawable == pdp->dri2.drawable_id) 3264f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg last_dc = dc; 3277da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg break; 3287da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 3297da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg case DRI2_EVENT_BUFFER_ATTACH: 3307da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg ba = (__DRIBufferAttachEvent *) p; 331e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg if (ba->drawable == pdp->dri2.drawable_id && 3324f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg ba->buffer.attachment == DRI_DRAWABLE_BUFFER_FRONT_LEFT) 3334f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg last_ba = ba; 3344f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg break; 3354f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg } 3364f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg } 3374f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg 3384f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg if (last_dc) { 3394f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg if (pdp->w != last_dc->width || pdp->h != last_dc->height) 3404f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg changed = 1; 3414f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg 3424f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg pdp->x = last_dc->x; 3434f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg pdp->y = last_dc->y; 3444f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg pdp->w = last_dc->width; 3454f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg pdp->h = last_dc->height; 3464f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg 3474f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg pdp->backX = 0; 3484f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg pdp->backY = 0; 3494f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg pdp->numBackClipRects = 1; 3504f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg pdp->pBackClipRects[0].x1 = 0; 3514f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg pdp->pBackClipRects[0].y1 = 0; 3524f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg pdp->pBackClipRects[0].x2 = pdp->w; 3534f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg pdp->pBackClipRects[0].y2 = pdp->h; 3544f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg 3554f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg pdp->numClipRects = last_dc->num_rects; 3564f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg _mesa_free(pdp->pClipRects); 3574f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg rect_size = last_dc->num_rects * sizeof last_dc->rects[0]; 3584f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg pdp->pClipRects = _mesa_malloc(rect_size); 3594f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg memcpy(pdp->pClipRects, last_dc->rects, rect_size); 3604f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg } 3617da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 362e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg /* We only care about the most recent drawable config. */ 363e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg if (last_dc && changed) 364e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg (*psp->DriverAPI.HandleDrawableConfig)(pdp, pcp, last_dc); 365e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 3664f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg /* Front buffer attachments are special, they typically mean that 3674f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg * we're rendering to a redirected window (or a child window of a 3684f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg * redirected window) and that it got resized. Resizing the root 3694f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg * window on randr events is a special case of this. Other causes 3704f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg * may be a window transitioning between redirected and 3714f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg * non-redirected, or a window getting reparented between parents 3724f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg * with different window pixmaps (eg two redirected windows). 3734f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg * These events are special in that the X server allocates the 3744f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg * buffer and that the buffer may be shared by other child 3754f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg * windows. When our window share the window pixmap with its 3764f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg * parent, drawable config events doesn't affect the front buffer. 3774f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg * We only care about the last such event in the buffer; in fact, 3784f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg * older events will refer to invalid buffer objects.*/ 3794f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg if (last_ba) 380180b41594c669574355b54ceb2c2ff96889bf336Kristian Høgsberg (*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, last_ba); 3814f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg 3824f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg /* If there was a drawable config event in the buffer and it 3834f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg * changed the size of the window, all buffer auxillary buffer 3844f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg * attachments prior to that are invalid (as opposed to the front 3854f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg * buffer case discussed above). In that case we can start 3864f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg * looking for buffer attachment after the last drawable config 3874f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg * event. If there is no drawable config event in this batch of 3884f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg * events, we have to assume that the last batch might have had 3894f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg * one and process all buffer attach events.*/ 3904f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg if (last_dc && changed) 3914f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg tail = (unsigned char *) last_dc - data; 3924f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg else 3934f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg tail = pdp->dri2.tail; 3947da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 3954f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg for ( ; tail != end; tail += size) { 3964f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg ba = (__DRIBufferAttachEvent *) (data + (tail & mask)); 3974f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg size = DRI2_EVENT_SIZE(ba->event_header); 3987da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 3994f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg if (DRI2_EVENT_TYPE(ba->event_header) != DRI2_EVENT_BUFFER_ATTACH) 4004f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg continue; 401e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg if (ba->drawable != pdp->dri2.drawable_id) 4024f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg continue; 4034f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg if (last_ba == ba) 4044f7a75cc8a6cee7763b2d92e3d34858c3de7bd4fKristian Høgsberg continue; 4057da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 406180b41594c669574355b54ceb2c2ff96889bf336Kristian Høgsberg (*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, ba); 407e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg changed = 1; 4087da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg } 4097da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 4107da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg pdp->dri2.tail = tail; 4117da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 412e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg return changed || last_ba; 4137da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg} 4147da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 415680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/ 416680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 417680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 418680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name GLX callbacks */ 419680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 420680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/ 421680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 422e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driReportDamage(__DRIdrawable *pdp, 423e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg struct drm_clip_rect *pClipRects, int numClipRects) 424e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{ 425e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg __DRIscreen *psp = pdp->driScreenPriv; 426e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 427e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg /* Check that we actually have the new damage report method */ 428e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg if (psp->dri2.enabled) { 429e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg (*psp->dri2.loader->postDamage)(pdp, 430e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg pClipRects, 431e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg numClipRects, 432e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg pdp->loaderPrivate); 433e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg } else if (psp->damage) { 434e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg /* Report the damage. Currently, all our drivers draw 435e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * directly to the front buffer, so we report the damage there 436e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * rather than to the backing storein (if any). 437e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg */ 438e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg (*psp->damage->reportDamage)(pdp, 439e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg pdp->x, pdp->y, 440e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg pClipRects, numClipRects, 441e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg GL_TRUE, pdp->loaderPrivate); 442e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg } 443e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg} 444e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 445e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 446680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 447680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Swap buffers. 448680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 449680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param drawablePrivate opaque pointer to the per-drawable private info. 450680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 451680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal 452680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DRIdrawablePrivate::swapBuffers. 453680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 454680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Is called directly from glXSwapBuffers(). 455680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 456e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driSwapBuffers(__DRIdrawable *dPriv) 457680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 458e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg __DRIscreen *psp = dPriv->driScreenPriv; 459c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt 4602407e48f2805e27e76e2e1d7083926c4077d9032Xiang, Haihao if (!dPriv->numClipRects) 4612407e48f2805e27e76e2e1d7083926c4077d9032Xiang, Haihao return; 4622407e48f2805e27e76e2e1d7083926c4077d9032Xiang, Haihao 463e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg psp->DriverAPI.SwapBuffers(dPriv); 464c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt 465e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg driReportDamage(dPriv, dPriv->pClipRects, dPriv->numClipRects); 466680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 467680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 468e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int driDrawableGetMSC( __DRIscreen *sPriv, __DRIdrawable *dPriv, 46938fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes int64_t *msc ) 47038fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes{ 4716e8d21d72f35767e07081a8bee4323aaaf5e2aaeKristian Høgsberg return sPriv->DriverAPI.GetDrawableMSC(sPriv, dPriv, msc); 472680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 473680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 474e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc, 4755987a03f994af2bb413d1cf984ab01aa095c0943Kristian Høgsberg int64_t divisor, int64_t remainder, 4765987a03f994af2bb413d1cf984ab01aa095c0943Kristian Høgsberg int64_t * msc, int64_t * sbc) 477680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 478680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIswapInfo sInfo; 479680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int status; 480680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 481680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 482680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell status = dPriv->driScreenPriv->DriverAPI.WaitForMSC( dPriv, target_msc, 483680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell divisor, remainder, 484680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell msc ); 485680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 486680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* GetSwapInfo() may not be provided by the driver if GLX_SGI_video_sync 487680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * is supported but GLX_OML_sync_control is not. Therefore, don't return 488680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * an error value if GetSwapInfo() is not implemented. 489680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 490680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if ( status == 0 491680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell && dPriv->driScreenPriv->DriverAPI.GetSwapInfo ) { 492680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo ); 493680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *sbc = sInfo.swap_count; 494680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 495680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 496680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return status; 497680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 498680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 499106a6f29bbdc71982afd629bdf89369cefd1459eKristian Høgsbergconst __DRImediaStreamCounterExtension driMediaStreamCounterExtension = { 500ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg { __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION }, 501106a6f29bbdc71982afd629bdf89369cefd1459eKristian Høgsberg driWaitForMSC, 50238fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes driDrawableGetMSC, 503106a6f29bbdc71982afd629bdf89369cefd1459eKristian Høgsberg}; 504680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 505e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driCopySubBuffer(__DRIdrawable *dPriv, 506f2ad1b60c0da11283b399008f491792790cea294Brian Paul int x, int y, int w, int h) 507f2ad1b60c0da11283b399008f491792790cea294Brian Paul{ 508e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg drm_clip_rect_t rect; 509e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 510f2ad1b60c0da11283b399008f491792790cea294Brian Paul dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h); 511e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 512e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg rect.x1 = x; 513e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg rect.y1 = y; 514e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg rect.x2 = x + w; 515e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg rect.y2 = y + w; 516e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg driReportDamage(dPriv, &rect, 1); 517f2ad1b60c0da11283b399008f491792790cea294Brian Paul} 518680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 519ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsbergconst __DRIcopySubBufferExtension driCopySubBufferExtension = { 520ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg { __DRI_COPY_SUB_BUFFER, __DRI_COPY_SUB_BUFFER_VERSION }, 521ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg driCopySubBuffer 522ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsberg}; 523ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsberg 524e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driSetSwapInterval(__DRIdrawable *dPriv, unsigned int interval) 525efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg{ 526e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg dPriv->swap_interval = interval; 527efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg} 528efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg 529e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic unsigned int driGetSwapInterval(__DRIdrawable *dPriv) 530efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg{ 531e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg return dPriv->swap_interval; 532efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg} 533efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg 534efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsbergconst __DRIswapControlExtension driSwapControlExtension = { 535ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg { __DRI_SWAP_CONTROL, __DRI_SWAP_CONTROL_VERSION }, 536efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg driSetSwapInterval, 537efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg driGetSwapInterval 538efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg}; 539efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg 540efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg 541680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 542680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This is called via __DRIscreenRec's createNewDrawable pointer. 543680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 544e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIdrawable * 545e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config, 546e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg drm_drawable_t hwDrawable, int renderType, 547e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg const int *attrs, void *data) 548680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 549e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg __DRIdrawable *pdp; 5501960182ece3f1eca06d2e439f64dd61be8a03ff5Ian Romanick 551680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* Since pbuffers are not yet supported, no drawable attributes are 552680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * supported either. 553680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 554680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell (void) attrs; 555680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 556e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg pdp = _mesa_malloc(sizeof *pdp); 557680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (!pdp) { 558680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return NULL; 559680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 560680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 561e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg pdp->loaderPrivate = data; 5624ff95e78e19e5902352ea3759d32d9f013255f42Kristian Høgsberg pdp->hHWDrawable = hwDrawable; 563680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->refcount = 0; 564680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->pStamp = NULL; 565680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->lastStamp = 0; 566680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->index = 0; 567680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->x = 0; 568680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->y = 0; 569680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->w = 0; 570680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->h = 0; 571680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->numClipRects = 0; 572680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->numBackClipRects = 0; 573680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->pClipRects = NULL; 574680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->pBackClipRects = NULL; 57538fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes pdp->vblSeq = 0; 57638fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes pdp->vblFlags = 0; 577680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 578680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->driScreenPriv = psp; 579680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->driContextPriv = &psp->dummyContextPriv; 580680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 581e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes, 582680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell renderType == GLX_PIXMAP_BIT)) { 5837c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pdp); 584680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return NULL; 585680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 586680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 58738fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes pdp->msc_base = 0; 588680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 589c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick /* This special default value is replaced with the configured 590c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick * default value when the drawable is first bound to a direct 591c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick * rendering context. 592c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick */ 593efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg pdp->swap_interval = (unsigned)-1; 594680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 595e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg return pdp; 596e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg} 597680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 598e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIdrawable * 599e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergdri2CreateNewDrawable(__DRIscreen *screen, const __DRIconfig *config, 600e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg unsigned int drawable_id, unsigned int head, void *data) 601e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{ 602e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg __DRIdrawable *pdraw; 6037da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 604e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg pdraw = driCreateNewDrawable(screen, config, 0, 0, NULL, data); 605e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 606e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg pdraw->dri2.drawable_id = drawable_id; 607e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg pdraw->dri2.tail = head; 608e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg pdraw->pBackClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects); 609e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 610e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg return pdraw; 611680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 612680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 613e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 614b4b040f7d83f5f4917c48bf5833394d550e30421Brian Paulstatic void 615e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriDestroyDrawable(__DRIdrawable *pdp) 616680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 617eab896cc213157758d74a2f39b5e3b1e748c071fDave Airlie __DRIscreenPrivate *psp; 618680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 619680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (pdp) { 620eab896cc213157758d74a2f39b5e3b1e748c071fDave Airlie psp = pdp->driScreenPriv; 621680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell (*psp->DriverAPI.DestroyBuffer)(pdp); 622680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (pdp->pClipRects) { 6237c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pdp->pClipRects); 624680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->pClipRects = NULL; 625680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 626680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (pdp->pBackClipRects) { 6277c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pdp->pBackClipRects); 628680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pdp->pBackClipRects = NULL; 629680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 6307c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pdp); 631680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 632680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 633680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 634680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/ 635680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 636680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 637680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 638680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Context handling functions */ 639680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 640680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/ 641680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 642680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 643680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Destroy the per-context private information. 644680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 645680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param contextPrivate opaque pointer to the per-drawable private info. 646680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 647680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal 648680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls 649680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drmDestroyContext(), and finally frees \p contextPrivate. 650680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 651b4b040f7d83f5f4917c48bf5833394d550e30421Brian Paulstatic void 652e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriDestroyContext(__DRIcontext *pcp) 653680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 654680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (pcp) { 655680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell (*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp); 6567c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pcp); 657680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 658680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 659680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 660680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 661680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 662680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Create the per-drawable private driver information. 663680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 664680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dpy The display handle. 665680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param modes Mode used to create the new context. 666680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param render_type Type of rendering target. \c GLX_RGBA is the only 667680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * type likely to ever be supported for direct-rendering. 668ecdb45cb29e3209287cc297081596126e955ff2bKristian Høgsberg * \param shared The shared context dependent methods or \c NULL if 669680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * non-existent. 670680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param pctx DRI context to receive the context dependent methods. 671680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 672680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \returns An opaque pointer to the per-context private information on 673680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * success, or \c NULL on failure. 674680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 675680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal 676680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function allocates and fills a __DRIcontextPrivateRec structure. It 677680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * performs some device independent initialization and passes all the 678680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * relevent information to __DriverAPIRec::CreateContext to create the 679680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * context. 680680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 681680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 682e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIcontext * 683e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriCreateNewContext(__DRIscreen *psp, const __DRIconfig *config, 684ecdb45cb29e3209287cc297081596126e955ff2bKristian Høgsberg int render_type, __DRIcontext *shared, 685e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg drm_context_t hwContext, void *data) 686680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 687e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg __DRIcontext *pcp; 688e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL; 689680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 690e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg pcp = _mesa_malloc(sizeof *pcp); 691e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg if (!pcp) 692680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return NULL; 693680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 694680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pcp->driScreenPriv = psp; 695680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell pcp->driDrawablePriv = NULL; 696680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 697680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* When the first context is created for a screen, initialize a "dummy" 698680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * context. 699680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 700680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 7017da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg if (!psp->dri2.enabled && !psp->dummyContextPriv.driScreenPriv) { 702680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->dummyContextPriv.hHWContext = psp->pSAREA->dummy_context; 703680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->dummyContextPriv.driScreenPriv = psp; 704680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->dummyContextPriv.driDrawablePriv = NULL; 705680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->dummyContextPriv.driverPrivate = NULL; 706680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* No other fields should be used! */ 707680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 708680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 709e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg pcp->hHWContext = hwContext; 71074d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell 711e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg if ( !(*psp->DriverAPI.CreateContext)(&config->modes, pcp, shareCtx) ) { 7127c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(pcp); 713680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return NULL; 714680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 715680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 716680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return pcp; 717680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 718ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsberg 719e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIcontext * 720e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergdri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config, 721e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg __DRIcontext *shared, void *data) 722f616a263a25eda135800bea7d3a863c569b93e30Kristian Høgsberg{ 723e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg drm_context_t hwContext; 724e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg DRM_CAS_RESULT(ret); 725f616a263a25eda135800bea7d3a863c569b93e30Kristian Høgsberg 726e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg /* DRI2 doesn't use kernel with context IDs, we just need an ID that's 727e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg * different from the kernel context ID to make drmLock() happy. */ 728e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 729e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg do { 730e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg hwContext = screen->dri2.lock->next_id; 731e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg DRM_CAS(&screen->dri2.lock->next_id, hwContext, hwContext + 1, ret); 732e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg } while (ret); 733e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 734e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg return driCreateNewContext(screen, config, 0, shared, hwContext, data); 735f616a263a25eda135800bea7d3a863c569b93e30Kristian Høgsberg} 736680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 737e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int 738e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask) 739e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{ 740e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg return GL_FALSE; 741e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg} 742e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 743e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg/*@}*/ 744e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 745e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 746680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 747680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Screen handling functions */ 748680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/ 749680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/ 750680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 751680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 752680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Destroy the per-screen private information. 753680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 754680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dpy the display handle. 755680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param scrn the screen number. 756680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param screenPrivate opaque pointer to the per-screen private information. 757680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 758680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal 759680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls 760680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drmClose(), and finally frees \p screenPrivate. 761680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 762e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driDestroyScreen(__DRIscreen *psp) 763680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 764680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (psp) { 765680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* No interaction with the X-server is possible at this point. This 766680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * routine is called after XCloseDisplay, so there is no protocol 767680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * stream open to the X-server anymore. 768680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 769680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 770680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if (psp->DriverAPI.DestroyScreen) 771680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell (*psp->DriverAPI.DestroyScreen)(psp); 772680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 7737da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg if (psp->dri2.enabled) { 7747da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg drmBOUnmap(psp->fd, &psp->dri2.sareaBO); 7757da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg drmBOUnreference(psp->fd, &psp->dri2.sareaBO); 7767da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg } else { 7777da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX); 7787da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize); 7797da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg (void)drmCloseOnce(psp->fd); 7807da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg } 781e5c28321b2047418ba960c5f9c3aa86cf2514bbbTilman Sauerbeck 7827c46033130b1b4d6098647d85c2710367572e079Ian Romanick _mesa_free(psp); 783680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 784680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 785680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 7866cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsbergstatic void 787e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergsetupLoaderExtensions(__DRIscreen *psp, 7886cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg const __DRIextension **extensions) 7896cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg{ 7906cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg int i; 7916cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg 7926cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg for (i = 0; extensions[i]; i++) { 7936cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg if (strcmp(extensions[i]->name, __DRI_GET_DRAWABLE_INFO) == 0) 7946cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg psp->getDrawableInfo = (__DRIgetDrawableInfoExtension *) extensions[i]; 7956cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg if (strcmp(extensions[i]->name, __DRI_DAMAGE) == 0) 7966cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg psp->damage = (__DRIdamageExtension *) extensions[i]; 7976cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg if (strcmp(extensions[i]->name, __DRI_SYSTEM_TIME) == 0) 7986cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg psp->systemTime = (__DRIsystemTimeExtension *) extensions[i]; 799e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg if (strcmp(extensions[i]->name, __DRI_LOADER) == 0) 800e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg psp->dri2.loader = (__DRIloaderExtension *) extensions[i]; 8016cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg } 8026cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg} 8036cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg 804680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 80564106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * This is the bootstrap function for the driver. libGL supplies all of the 80664106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * requisite information about the system, and the driver initializes itself. 80764106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * This routine also fills in the linked list pointed to by \c driver_modes 80864106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * with the \c __GLcontextModes that the driver can support for windows or 80964106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * pbuffers. 810680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 811680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param scrn Index of the screen 812680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param psc DRI screen data (not driver private) 813680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param modes Linked list of known display modes. This list is, at a 814680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * minimum, a list of modes based on the current display mode. 815680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * These roughly match the set of available X11 visuals, but it 816680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * need not be limited to X11! The calling libGL should create 817680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * a list that will inform the driver of the current display 818680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * mode (i.e., color buffer depth, depth buffer depth, etc.). 819680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param ddx_version Version of the 2D DDX. This may not be meaningful for 820680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * all drivers. 821680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dri_version Version of the "server-side" DRI. 822680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param drm_version Version of the kernel DRM. 823680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param frame_buffer Data describing the location and layout of the 824680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * framebuffer. 825680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param pSAREA Pointer the the SAREA. 826680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param fd Device handle for the DRM. 827680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param internal_api_version Version of the internal interface between the 828680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * driver and libGL. 829680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param driverAPI Driver API functions used by other routines in dri_util.c. 830c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick * 83164106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * \note There is no need to check the minimum API version in this 83264106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * function. Since the name of this function is versioned, it is 83364106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * impossible for a loader that is too old to even load this driver. 834680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 835e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIscreen * 836e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriCreateNewScreen(int scrn, 837e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg const __DRIversion *ddx_version, 838e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg const __DRIversion *dri_version, 839e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg const __DRIversion *drm_version, 840e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg const __DRIframebuffer *frame_buffer, 841e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg drmAddress pSAREA, int fd, 842e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg const __DRIextension **extensions, 843e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg const __DRIconfig ***driver_modes, 844e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg void *loaderPrivate) 845680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 846efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg static const __DRIextension *emptyExtensionList[] = { NULL }; 847e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg __DRIscreen *psp; 848680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 849e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg psp = _mesa_malloc(sizeof *psp); 85064106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg if (!psp) 851680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return NULL; 852680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 8536cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg setupLoaderExtensions(psp, extensions); 8546cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg 855680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* 856680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** NOT_DONE: This is used by the X server to detect when the client 857680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** has died while holding the drawable lock. The client sets the 858680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** drawable lock to this value. 859680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 860680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->drawLockID = 1; 861680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 862efd03a278ae55b454509e9659c42899133983ebdKristian Høgsberg psp->drm_version = *drm_version; 863efd03a278ae55b454509e9659c42899133983ebdKristian Høgsberg psp->ddx_version = *ddx_version; 864efd03a278ae55b454509e9659c42899133983ebdKristian Høgsberg psp->dri_version = *dri_version; 865680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 866680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->pSAREA = pSAREA; 8677da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg psp->lock = (drmLock *) &psp->pSAREA->lock; 868680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 869680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->pFB = frame_buffer->base; 870680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->fbSize = frame_buffer->size; 871680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->fbStride = frame_buffer->stride; 872680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->fbWidth = frame_buffer->width; 873680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->fbHeight = frame_buffer->height; 874680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->devPrivSize = frame_buffer->dev_priv_size; 875680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->pDevPriv = frame_buffer->dev_priv; 876fd4f7064e24654c89248be6d76f39c7baf22fce4Jon Smirl psp->fbBPP = psp->fbStride * 8 / frame_buffer->width; 877680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 878ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsberg psp->extensions = emptyExtensionList; 879680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->fd = fd; 88064106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg psp->myNum = scrn; 8817da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg psp->dri2.enabled = GL_FALSE; 882680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 883680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* 884680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** Do not init dummy context here; actual initialization will be 885680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** done when the first DRI context is created. Init screen priv ptr 886680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell ** to NULL to let CreateContext routine that it needs to be inited. 887680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 888680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell psp->dummyContextPriv.driScreenPriv = NULL; 889680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 890e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg psp->DriverAPI = driDriverAPI; 891680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 892e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg *driver_modes = driDriverAPI.InitScreen(psp); 89364106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg if (*driver_modes == NULL) { 89464106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg _mesa_free(psp); 895680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return NULL; 896680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 897680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 898680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return psp; 899680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 900680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 901e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 902e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIscreen * 903e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergdri2CreateNewScreen(int scrn, int fd, unsigned int sarea_handle, 904e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg const __DRIextension **extensions, 905e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg const __DRIconfig ***driver_configs, void *data) 9067da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg{ 9077da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg static const __DRIextension *emptyExtensionList[] = { NULL }; 908e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg __DRIscreen *psp; 9097da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg unsigned int *p; 91016242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg drmVersionPtr version; 911129b9ad16f95421d12f77c1bd3eca915d8768b78Kristian Høgsberg 912e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg if (driDriverAPI.InitScreen2 == NULL) 913129b9ad16f95421d12f77c1bd3eca915d8768b78Kristian Høgsberg return NULL; 9147da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 9157da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg psp = _mesa_malloc(sizeof(*psp)); 9167da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg if (!psp) 9177da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg return NULL; 9187da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 9196cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg setupLoaderExtensions(psp, extensions); 9206cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg 92116242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg version = drmGetVersion(fd); 92216242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg if (version) { 92316242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg psp->drm_version.major = version->version_major; 92416242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg psp->drm_version.minor = version->version_minor; 92516242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg psp->drm_version.patch = version->version_patchlevel; 92616242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg drmFreeVersion(version); 92716242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg } 92816242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg 9297da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg psp->extensions = emptyExtensionList; 9307da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg psp->fd = fd; 9317da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg psp->myNum = scrn; 9327da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg psp->dri2.enabled = GL_TRUE; 9337da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 9347da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg if (drmBOReference(psp->fd, sarea_handle, &psp->dri2.sareaBO)) { 9357da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg fprintf(stderr, "Failed to reference DRI2 sarea BO\n"); 9367da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg _mesa_free(psp); 9377da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg return NULL; 9387da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg } 9397da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 9407da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg if (drmBOMap(psp->fd, &psp->dri2.sareaBO, 9417da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &psp->dri2.sarea)) { 9427da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg drmBOUnreference(psp->fd, &psp->dri2.sareaBO); 9437da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg _mesa_free(psp); 9447da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg return NULL; 9457da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg } 9467da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 9477da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg p = psp->dri2.sarea; 9487da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg while (DRI2_SAREA_BLOCK_TYPE(*p)) { 9497da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg switch (DRI2_SAREA_BLOCK_TYPE(*p)) { 9507da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg case DRI2_SAREA_BLOCK_LOCK: 9517da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg psp->dri2.lock = (__DRILock *) p; 9527da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg break; 9537da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg case DRI2_SAREA_BLOCK_EVENT_BUFFER: 9547da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg psp->dri2.buffer = (__DRIEventBuffer *) p; 9557da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg break; 9567da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg } 9577da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg p = DRI2_SAREA_BLOCK_NEXT(p); 9587da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg } 9597da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 9607da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg psp->lock = (drmLock *) &psp->dri2.lock->lock; 9617da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 962e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg psp->DriverAPI = driDriverAPI; 963e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg *driver_configs = driDriverAPI.InitScreen2(psp); 964e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg if (*driver_configs == NULL) { 9657da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg drmBOUnmap(psp->fd, &psp->dri2.sareaBO); 9667da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg drmBOUnreference(psp->fd, &psp->dri2.sareaBO); 9677da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg _mesa_free(psp); 9687da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg return NULL; 9697da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg } 9707da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 971e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg psp->DriverAPI = driDriverAPI; 972e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 9737da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg return psp; 9747da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg} 9757da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg 976e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic const __DRIextension **driGetExtensions(__DRIscreen *psp) 977e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{ 978e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg return psp->extensions; 979e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg} 980e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 981e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergconst __DRIlegacyExtension driLegacyExtension = { 982e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg { __DRI_LEGACY, __DRI_LEGACY_VERSION }, 983e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg driCreateNewScreen, 984e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg driCreateNewDrawable, 985e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg driCreateNewContext 986e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}; 987e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 988e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergconst __DRIcoreExtension driCoreExtension = { 989e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg { __DRI_CORE, __DRI_CORE_VERSION }, 990e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg dri2CreateNewScreen, 991e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg driDestroyScreen, 992e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg driGetExtensions, 993e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg driGetConfigAttrib, 994e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg driIndexConfigAttrib, 995e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg dri2CreateNewDrawable, 996e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg driDestroyDrawable, 997e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg driSwapBuffers, 998e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg dri2CreateNewContext, 999e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg driCopyContext, 1000e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg driDestroyContext, 1001e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg driBindContext, 1002e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg driUnbindContext 1003e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}; 1004e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 1005e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg/* This is the table of extensions that the loader will dlsym() for. */ 1006e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergPUBLIC const __DRIextension *__driDriverExtensions[] = { 1007e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg &driCoreExtension.base, 1008e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg &driLegacyExtension.base, 1009e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg NULL 1010e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}; 1011e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg 1012680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic int 1013a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian HøgsbergdriFrameTracking(__DRIdrawable *drawable, GLboolean enable) 1014a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg{ 1015a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg return GLX_BAD_CONTEXT; 1016a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg} 1017a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg 1018a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsbergstatic int 1019e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriQueryFrameTracking(__DRIdrawable *dpriv, 10205987a03f994af2bb413d1cf984ab01aa095c0943Kristian Høgsberg int64_t * sbc, int64_t * missedFrames, 10215987a03f994af2bb413d1cf984ab01aa095c0943Kristian Høgsberg float * lastMissedUsage, float * usage) 1022680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 1023680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell __DRIswapInfo sInfo; 1024680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int status; 1025680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int64_t ust; 10266cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg __DRIscreenPrivate *psp = dpriv->driScreenPriv; 1027680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1028680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo ); 1029680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell if ( status == 0 ) { 1030680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *sbc = sInfo.swap_count; 1031680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *missedFrames = sInfo.swap_missed_count; 1032680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *lastMissedUsage = sInfo.swap_missed_usage; 1033680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 10346cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg (*psp->systemTime->getUST)( & ust ); 1035680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *usage = driCalculateSwapUsage( dpriv, sInfo.swap_ust, ust ); 1036680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 1037680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1038680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return status; 1039680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 1040680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1041a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsbergconst __DRIframeTrackingExtension driFrameTrackingExtension = { 1042ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg { __DRI_FRAME_TRACKING, __DRI_FRAME_TRACKING_VERSION }, 1043a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg driFrameTracking, 1044a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg driQueryFrameTracking 1045a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg}; 1046680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1047680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** 1048680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Calculate amount of swap interval used between GLX buffer swaps. 1049680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1050680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * The usage value, on the range [0,max], is the fraction of total swap 1051680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * interval time used between GLX buffer swaps is calculated. 1052680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1053680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \f$p = t_d / (i * t_r)\f$ 1054680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1055680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Where \f$t_d\f$ is the time since the last GLX buffer swap, \f$i\f$ is the 1056680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * swap interval (as set by \c glXSwapIntervalSGI), and \f$t_r\f$ time 1057680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * required for a single vertical refresh period (as returned by \c 1058680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * glXGetMscRateOML). 1059680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1060680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * See the documentation for the GLX_MESA_swap_frame_usage extension for more 1061680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * details. 1062680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1063680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dPriv Pointer to the private drawable structure. 1064680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \return If less than a single swap interval time period was required 1065680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * between GLX buffer swaps, a number greater than 0 and less than 1066680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1.0 is returned. If exactly one swap interval time period is 1067680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * required, 1.0 is returned, and if more than one is required then 1068680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * a number greater than 1.0 will be returned. 1069680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1070680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \sa glXSwapIntervalSGI glXGetMscRateOML 1071680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1072680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \todo Instead of caching the \c glXGetMscRateOML function pointer, would it 1073680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * be possible to cache the sync rate? 1074680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 1075680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellfloat 1076680ec7f85158eae58fd5ab56da8c66a645883cb0Keith WhitwelldriCalculateSwapUsage( __DRIdrawablePrivate *dPriv, int64_t last_swap_ust, 1077680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int64_t current_ust ) 1078680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{ 1079680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int32_t n; 1080680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int32_t d; 1081680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell int interval; 1082680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell float usage = 1.0; 10836cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg __DRIscreenPrivate *psp = dPriv->driScreenPriv; 1084680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1085e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg if ( (*psp->systemTime->getMSCRate)(dPriv, &n, &d, dPriv->loaderPrivate) ) { 1086efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg interval = (dPriv->swap_interval != 0) ? dPriv->swap_interval : 1; 1087680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1088680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1089680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell /* We want to calculate 1090680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * (current_UST - last_swap_UST) / (interval * us_per_refresh). We get 1091680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * current_UST by calling __glXGetUST. last_swap_UST is stored in 1092680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * dPriv->swap_ust. interval has already been calculated. 1093680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1094680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * The only tricky part is us_per_refresh. us_per_refresh is 1095680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * 1000000 / MSC_rate. We know the MSC_rate is n / d. We can flip it 1096680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * around and say us_per_refresh = 1000000 * d / n. Since this goes in 1097680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * the denominator of the final calculation, we calculate 1098680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * (interval * 1000000 * d) and move n into the numerator. 1099680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */ 1100680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1101680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell usage = (current_ust - last_swap_ust); 1102680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell usage *= n; 1103680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell usage /= (interval * d); 1104680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell usage /= 1000000.0; 1105680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell } 1106680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1107680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell return usage; 1108680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell} 1109680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell 1110680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/ 1111