dri_util.c revision 6186e7a20676c5df30b1b4bffeec87afa1550e25
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
29ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/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 * This function takes both a read buffer and a draw buffer.  This is needed
157680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
158680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * function.
159680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
160e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int driBindContext(__DRIcontext *pcp,
161e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg			  __DRIdrawable *pdp,
162e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg			  __DRIdrawable *prp)
163680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
164aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsberg    __DRIscreenPrivate *psp = pcp->driScreenPriv;
165680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
166f1139e4c662c47357ee054c2e004b13c9f74ffe1Kristian Høgsberg    /*
167f1139e4c662c47357ee054c2e004b13c9f74ffe1Kristian Høgsberg    ** Assume error checking is done properly in glXMakeCurrent before
168f1139e4c662c47357ee054c2e004b13c9f74ffe1Kristian Høgsberg    ** calling driBindContext.
169f1139e4c662c47357ee054c2e004b13c9f74ffe1Kristian Høgsberg    */
170f1139e4c662c47357ee054c2e004b13c9f74ffe1Kristian Høgsberg
171e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (pcp == NULL || pdp == None || prp == None)
172f1139e4c662c47357ee054c2e004b13c9f74ffe1Kristian Høgsberg	return GL_FALSE;
173f1139e4c662c47357ee054c2e004b13c9f74ffe1Kristian Høgsberg
174680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* Bind the drawable to the context */
175680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pcp->driDrawablePriv = pdp;
1767b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick    pcp->driReadablePriv = prp;
177680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->driContextPriv = pcp;
178680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->refcount++;
179680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( pdp != prp ) {
180680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	prp->refcount++;
181680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
182680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
183680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /*
184680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** Now that we have a context associated with this drawable, we can
185680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** initialize the drawable information if has not been done before.
186680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
187680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
188f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    if (!psp->dri2.enabled) {
1897da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) {
1907da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
1917da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    __driUtilUpdateDrawableInfo(pdp);
1927da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
1937da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	}
1947da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
1957da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	if ((pdp != prp) && (!prp->pStamp || *prp->pStamp != prp->lastStamp)) {
1967da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
1977da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    __driUtilUpdateDrawableInfo(prp);
1987da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
1997da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	}
2007b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick    }
2017b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick
202680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* Call device-specific MakeCurrent */
203680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    (*psp->DriverAPI.MakeCurrent)(pcp, pdp, prp);
204680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
205680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return GL_TRUE;
206680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
207680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
208680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
209680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
210680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
211680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
212680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Drawable handling functions                            */
213680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
214680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
215680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
216680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
217680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Update private drawable information.
218680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
219680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param pdp pointer to the private drawable information to update.
220680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
221680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function basically updates the __DRIdrawablePrivate struct's
2225f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick * cliprect information by calling \c __DRIinterfaceMethods::getDrawableInfo.
2235f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick * This is usually called by the DRI_VALIDATE_DRAWABLE_INFO macro which
224680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * compares the __DRIdrwablePrivate pStamp and lastStamp values.  If
225680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * the values are different that means we have to update the clipping
226680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * info.
227680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
228680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellvoid
229680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell__driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
230680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
2316cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    __DRIscreenPrivate *psp = pdp->driScreenPriv;
232680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIcontextPrivate *pcp = pdp->driContextPriv;
233680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
2347b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick    if (!pcp
2357b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick	|| ((pdp != pcp->driDrawablePriv) && (pdp != pcp->driReadablePriv))) {
236682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström	/* ERROR!!!
237682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström	 * ...but we must ignore it. There can be many contexts bound to a
238682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström	 * drawable.
239682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström	 */
240680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
241680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
242680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pdp->pClipRects) {
2437c46033130b1b4d6098647d85c2710367572e079Ian Romanick	_mesa_free(pdp->pClipRects);
244a903749b246fce26038c66d06fe7eb77daf815abMichel Dänzer	pdp->pClipRects = NULL;
245680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
246680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
247680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pdp->pBackClipRects) {
2487c46033130b1b4d6098647d85c2710367572e079Ian Romanick	_mesa_free(pdp->pBackClipRects);
249a903749b246fce26038c66d06fe7eb77daf815abMichel Dänzer	pdp->pBackClipRects = NULL;
250680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
251680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
252680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
253680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
254e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (! (*psp->getDrawableInfo->getDrawableInfo)(pdp,
255680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->index, &pdp->lastStamp,
256680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->x, &pdp->y, &pdp->w, &pdp->h,
257680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->numClipRects, &pdp->pClipRects,
258680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->backX,
259680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->backY,
260680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->numBackClipRects,
261e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg			  &pdp->pBackClipRects,
262e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg			  pdp->loaderPrivate)) {
263680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* Error -- eg the window may have been destroyed.  Keep going
264680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 * with no cliprects.
265680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 */
266680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        pdp->pStamp = &pdp->lastStamp; /* prevent endless loop */
267680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->numClipRects = 0;
268680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->pClipRects = NULL;
269680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->numBackClipRects = 0;
270680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->pBackClipRects = NULL;
271680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
272680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    else
273680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp);
274680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
275680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
276680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
277680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
278680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
279680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
280680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
281680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name GLX callbacks                                          */
282680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
283680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
284680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
285e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driReportDamage(__DRIdrawable *pdp,
286e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg			    struct drm_clip_rect *pClipRects, int numClipRects)
287e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
288e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIscreen *psp = pdp->driScreenPriv;
289e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
290e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    /* Check that we actually have the new damage report method */
291f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    if (psp->damage) {
292e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg	/* Report the damage.  Currently, all our drivers draw
293e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg	 * directly to the front buffer, so we report the damage there
294e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg	 * rather than to the backing storein (if any).
295e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg	 */
296e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg	(*psp->damage->reportDamage)(pdp,
297e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg				     pdp->x, pdp->y,
298e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg				     pClipRects, numClipRects,
299e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg				     GL_TRUE, pdp->loaderPrivate);
300e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    }
301e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
302e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
303e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
304680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
305680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Swap buffers.
306680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
307680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param drawablePrivate opaque pointer to the per-drawable private info.
308680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
309680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
310680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DRIdrawablePrivate::swapBuffers.
311680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
312680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Is called directly from glXSwapBuffers().
313680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
314e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driSwapBuffers(__DRIdrawable *dPriv)
315680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
316e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIscreen *psp = dPriv->driScreenPriv;
317c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt
3182407e48f2805e27e76e2e1d7083926c4077d9032Xiang, Haihao    if (!dPriv->numClipRects)
3192407e48f2805e27e76e2e1d7083926c4077d9032Xiang, Haihao        return;
3202407e48f2805e27e76e2e1d7083926c4077d9032Xiang, Haihao
321e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    psp->DriverAPI.SwapBuffers(dPriv);
322c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt
323e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driReportDamage(dPriv, dPriv->pClipRects, dPriv->numClipRects);
324680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
325680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
326e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int driDrawableGetMSC( __DRIscreen *sPriv, __DRIdrawable *dPriv,
32738fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes			      int64_t *msc )
32838fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes{
3296e8d21d72f35767e07081a8bee4323aaaf5e2aaeKristian Høgsberg    return sPriv->DriverAPI.GetDrawableMSC(sPriv, dPriv, msc);
330680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
331680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
3323f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul
333e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc,
3345987a03f994af2bb413d1cf984ab01aa095c0943Kristian Høgsberg			 int64_t divisor, int64_t remainder,
3355987a03f994af2bb413d1cf984ab01aa095c0943Kristian Høgsberg			 int64_t * msc, int64_t * sbc)
336680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
337680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIswapInfo  sInfo;
338680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    int  status;
339680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
340680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    status = dPriv->driScreenPriv->DriverAPI.WaitForMSC( dPriv, target_msc,
341680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                                                         divisor, remainder,
342680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                                                         msc );
343680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
344680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* GetSwapInfo() may not be provided by the driver if GLX_SGI_video_sync
345680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     * is supported but GLX_OML_sync_control is not.  Therefore, don't return
346680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     * an error value if GetSwapInfo() is not implemented.
347680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
348680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( status == 0
349680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell         && dPriv->driScreenPriv->DriverAPI.GetSwapInfo ) {
350680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo );
351680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        *sbc = sInfo.swap_count;
352680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
353680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
354680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return status;
355680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
356680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
3573f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul
358106a6f29bbdc71982afd629bdf89369cefd1459eKristian Høgsbergconst __DRImediaStreamCounterExtension driMediaStreamCounterExtension = {
359ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg    { __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION },
360106a6f29bbdc71982afd629bdf89369cefd1459eKristian Høgsberg    driWaitForMSC,
36138fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes    driDrawableGetMSC,
362106a6f29bbdc71982afd629bdf89369cefd1459eKristian Høgsberg};
363680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
3643f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul
365e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driCopySubBuffer(__DRIdrawable *dPriv,
366f2ad1b60c0da11283b399008f491792790cea294Brian Paul			      int x, int y, int w, int h)
367f2ad1b60c0da11283b399008f491792790cea294Brian Paul{
368e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    drm_clip_rect_t rect;
369e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
370e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    rect.x1 = x;
371377016d728ace47c9eeb3ac2f01191608ab060f6Dennis Kasprzyk    rect.y1 = dPriv->h - y - h;
372e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    rect.x2 = x + w;
373377016d728ace47c9eeb3ac2f01191608ab060f6Dennis Kasprzyk    rect.y2 = rect.y1 + h;
374e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driReportDamage(dPriv, &rect, 1);
3753a94b25538c647df965a93cd7734b841257ef203Peter Hutterer
3763a94b25538c647df965a93cd7734b841257ef203Peter Hutterer    dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h);
377f2ad1b60c0da11283b399008f491792790cea294Brian Paul}
378680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
379ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsbergconst __DRIcopySubBufferExtension driCopySubBufferExtension = {
380ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg    { __DRI_COPY_SUB_BUFFER, __DRI_COPY_SUB_BUFFER_VERSION },
381ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg    driCopySubBuffer
382ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsberg};
383ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsberg
384e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driSetSwapInterval(__DRIdrawable *dPriv, unsigned int interval)
385efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg{
386e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    dPriv->swap_interval = interval;
387efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg}
388efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg
389e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic unsigned int driGetSwapInterval(__DRIdrawable *dPriv)
390efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg{
391e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return dPriv->swap_interval;
392efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg}
393efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg
394efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsbergconst __DRIswapControlExtension driSwapControlExtension = {
395ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg    { __DRI_SWAP_CONTROL, __DRI_SWAP_CONTROL_VERSION },
396efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg    driSetSwapInterval,
397efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg    driGetSwapInterval
398efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg};
399efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg
400efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg
401680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
402680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This is called via __DRIscreenRec's createNewDrawable pointer.
403680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
404e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIdrawable *
405e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
406e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		     drm_drawable_t hwDrawable, int renderType,
407e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		     const int *attrs, void *data)
408680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
409e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIdrawable *pdp;
4101960182ece3f1eca06d2e439f64dd61be8a03ff5Ian Romanick
411680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* Since pbuffers are not yet supported, no drawable attributes are
412680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     * supported either.
413680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     */
414680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    (void) attrs;
415680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
416e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    pdp = _mesa_malloc(sizeof *pdp);
417680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!pdp) {
418680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
419680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
420680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
421e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    pdp->loaderPrivate = data;
4224ff95e78e19e5902352ea3759d32d9f013255f42Kristian Høgsberg    pdp->hHWDrawable = hwDrawable;
423680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->refcount = 0;
424680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->pStamp = NULL;
425680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->lastStamp = 0;
426680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->index = 0;
427680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->x = 0;
428680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->y = 0;
429680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->w = 0;
430680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->h = 0;
431680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->numClipRects = 0;
432680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->numBackClipRects = 0;
433680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->pClipRects = NULL;
434680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->pBackClipRects = NULL;
43538fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes    pdp->vblSeq = 0;
43638fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes    pdp->vblFlags = 0;
437680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
438680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->driScreenPriv = psp;
439680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->driContextPriv = &psp->dummyContextPriv;
440680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
441e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes,
442680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell					renderType == GLX_PIXMAP_BIT)) {
4437c46033130b1b4d6098647d85c2710367572e079Ian Romanick       _mesa_free(pdp);
444680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       return NULL;
445680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
446680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
44738fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes    pdp->msc_base = 0;
448680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
449c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick    /* This special default value is replaced with the configured
450c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick     * default value when the drawable is first bound to a direct
451c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick     * rendering context.
452c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick     */
453efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg    pdp->swap_interval = (unsigned)-1;
454680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
455e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return pdp;
456e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
457680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
4583f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul
459e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIdrawable *
460f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsbergdri2CreateNewDrawable(__DRIscreen *screen,
461f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg		      const __DRIconfig *config,
462f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg		      void *loaderPrivate)
463e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
464e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIdrawable *pdraw;
4657da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
466f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    pdraw = driCreateNewDrawable(screen, config, 0, 0, NULL, loaderPrivate);
4675cf69fe511a67a7bcf6787974becf6a143abb507Alan Hourihane    if (!pdraw)
4685cf69fe511a67a7bcf6787974becf6a143abb507Alan Hourihane    	return NULL;
469e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
470f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    pdraw->pClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects);
471e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    pdraw->pBackClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects);
472e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
473e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return pdraw;
474680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
475680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
476e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
477b4b040f7d83f5f4917c48bf5833394d550e30421Brian Paulstatic void
478e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriDestroyDrawable(__DRIdrawable *pdp)
479680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
480eab896cc213157758d74a2f39b5e3b1e748c071fDave Airlie    __DRIscreenPrivate *psp;
481680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
482680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pdp) {
483eab896cc213157758d74a2f39b5e3b1e748c071fDave Airlie	psp = pdp->driScreenPriv;
484680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        (*psp->DriverAPI.DestroyBuffer)(pdp);
485680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if (pdp->pClipRects) {
4867c46033130b1b4d6098647d85c2710367572e079Ian Romanick	    _mesa_free(pdp->pClipRects);
487680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    pdp->pClipRects = NULL;
488680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
489680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if (pdp->pBackClipRects) {
4907c46033130b1b4d6098647d85c2710367572e079Ian Romanick	    _mesa_free(pdp->pBackClipRects);
491680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    pdp->pBackClipRects = NULL;
492680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
4937c46033130b1b4d6098647d85c2710367572e079Ian Romanick	_mesa_free(pdp);
494680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
495680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
496680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
497680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
498680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
499680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
500680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
501680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Context handling functions                             */
502680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
503680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
504680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
505680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
506680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Destroy the per-context private information.
507680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
508680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
509680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls
510680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drmDestroyContext(), and finally frees \p contextPrivate.
511680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
512b4b040f7d83f5f4917c48bf5833394d550e30421Brian Paulstatic void
513e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriDestroyContext(__DRIcontext *pcp)
514680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
515680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pcp) {
516680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	(*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp);
5177c46033130b1b4d6098647d85c2710367572e079Ian Romanick	_mesa_free(pcp);
518680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
519680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
520680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
521680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
522680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
523680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Create the per-drawable private driver information.
524680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
525680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param render_type   Type of rendering target.  \c GLX_RGBA is the only
526680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *                      type likely to ever be supported for direct-rendering.
5273f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul * \param shared        Context with which to share textures, etc. or NULL
528680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
529680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \returns An opaque pointer to the per-context private information on
530680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          success, or \c NULL on failure.
531680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
532680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
533680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function allocates and fills a __DRIcontextPrivateRec structure.  It
534680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * performs some device independent initialization and passes all the
535680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * relevent information to __DriverAPIRec::CreateContext to create the
536680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * context.
537680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
538680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
539e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIcontext *
540e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
541ecdb45cb29e3209287cc297081596126e955ff2bKristian Høgsberg		    int render_type, __DRIcontext *shared,
542e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		    drm_context_t hwContext, void *data)
543680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
544e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIcontext *pcp;
545e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
546680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
547e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    pcp = _mesa_malloc(sizeof *pcp);
548e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (!pcp)
549680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
550680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
551680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pcp->driScreenPriv = psp;
552680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pcp->driDrawablePriv = NULL;
553680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
554680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* When the first context is created for a screen, initialize a "dummy"
555680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     * context.
556680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     */
557680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
5587da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    if (!psp->dri2.enabled && !psp->dummyContextPriv.driScreenPriv) {
559680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        psp->dummyContextPriv.hHWContext = psp->pSAREA->dummy_context;
560680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        psp->dummyContextPriv.driScreenPriv = psp;
561680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        psp->dummyContextPriv.driDrawablePriv = NULL;
562680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        psp->dummyContextPriv.driverPrivate = NULL;
563680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* No other fields should be used! */
564680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
565680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
566e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    pcp->hHWContext = hwContext;
56774d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
568e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if ( !(*psp->DriverAPI.CreateContext)(&config->modes, pcp, shareCtx) ) {
5697c46033130b1b4d6098647d85c2710367572e079Ian Romanick        _mesa_free(pcp);
570680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        return NULL;
571680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
572680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
573680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return pcp;
574680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
575ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsberg
5763f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul
577e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIcontext *
578e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergdri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
579e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		      __DRIcontext *shared, void *data)
580f616a263a25eda135800bea7d3a863c569b93e30Kristian Høgsberg{
581f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    return driCreateNewContext(screen, config, 0, shared, 0, data);
582f616a263a25eda135800bea7d3a863c569b93e30Kristian Høgsberg}
583680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
5843f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul
585e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int
586e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
587e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
588e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return GL_FALSE;
589e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
590e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
591e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg/*@}*/
592e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
593e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
594680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
595680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Screen handling functions                              */
596680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
597680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
598680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
599680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
600680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Destroy the per-screen private information.
601680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
602680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
603680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls
604680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drmClose(), and finally frees \p screenPrivate.
605680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
606e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driDestroyScreen(__DRIscreen *psp)
607680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
608680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (psp) {
609680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* No interaction with the X-server is possible at this point.  This
610680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 * routine is called after XCloseDisplay, so there is no protocol
611680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 * stream open to the X-server anymore.
612680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 */
613680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
614680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if (psp->DriverAPI.DestroyScreen)
615680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    (*psp->DriverAPI.DestroyScreen)(psp);
616680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
617f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg	if (!psp->dri2.enabled) {
6187da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	   (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
6197da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	   (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
6207da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	   (void)drmCloseOnce(psp->fd);
6217da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	}
622e5c28321b2047418ba960c5f9c3aa86cf2514bbbTilman Sauerbeck
6237c46033130b1b4d6098647d85c2710367572e079Ian Romanick	_mesa_free(psp);
624680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
625680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
626680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
6276cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsbergstatic void
628e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergsetupLoaderExtensions(__DRIscreen *psp,
6296cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg		      const __DRIextension **extensions)
6306cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg{
6316cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    int i;
6326cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg
6336cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    for (i = 0; extensions[i]; i++) {
6346cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_GET_DRAWABLE_INFO) == 0)
6356cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	    psp->getDrawableInfo = (__DRIgetDrawableInfoExtension *) extensions[i];
6366cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_DAMAGE) == 0)
6376cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	    psp->damage = (__DRIdamageExtension *) extensions[i];
6386cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_SYSTEM_TIME) == 0)
6396cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	    psp->systemTime = (__DRIsystemTimeExtension *) extensions[i];
640f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_DRI2_LOADER) == 0)
641f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg	    psp->dri2.loader = (__DRIdri2LoaderExtension *) extensions[i];
6426cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    }
6436cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg}
6446cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg
645680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
64664106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * This is the bootstrap function for the driver.  libGL supplies all of the
64764106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * requisite information about the system, and the driver initializes itself.
64864106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * This routine also fills in the linked list pointed to by \c driver_modes
64964106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * with the \c __GLcontextModes that the driver can support for windows or
65064106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * pbuffers.
6513f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul *
6523f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul * For legacy DRI.
653680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
654680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param scrn  Index of the screen
655680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param ddx_version Version of the 2D DDX.  This may not be meaningful for
656680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *                    all drivers.
657680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dri_version Version of the "server-side" DRI.
658680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param drm_version Version of the kernel DRM.
659680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param frame_buffer Data describing the location and layout of the
660680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *                     framebuffer.
661680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param pSAREA       Pointer the the SAREA.
662680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param fd           Device handle for the DRM.
6633f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul * \param extensions   ??
6643f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul * \param driver_modes  Returns modes suppoted by the driver
6653f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul * \param loaderPrivate  ??
666c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick *
66764106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * \note There is no need to check the minimum API version in this
66864106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * function.  Since the name of this function is versioned, it is
66964106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * impossible for a loader that is too old to even load this driver.
670680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
671e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIscreen *
672e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriCreateNewScreen(int scrn,
673e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   const __DRIversion *ddx_version,
674e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   const __DRIversion *dri_version,
675e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   const __DRIversion *drm_version,
676e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   const __DRIframebuffer *frame_buffer,
677e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   drmAddress pSAREA, int fd,
678e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   const __DRIextension **extensions,
679e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   const __DRIconfig ***driver_modes,
680e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   void *loaderPrivate)
681680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
682efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg    static const __DRIextension *emptyExtensionList[] = { NULL };
683e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIscreen *psp;
684680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
6856186e7a20676c5df30b1b4bffeec87afa1550e25Brian Paul    psp = _mesa_calloc(sizeof *psp);
68664106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg    if (!psp)
687680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
688680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
6896cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    setupLoaderExtensions(psp, extensions);
6906cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg
691680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /*
692680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** NOT_DONE: This is used by the X server to detect when the client
693680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** has died while holding the drawable lock.  The client sets the
694680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** drawable lock to this value.
695680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
696680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->drawLockID = 1;
697680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
698efd03a278ae55b454509e9659c42899133983ebdKristian Høgsberg    psp->drm_version = *drm_version;
699efd03a278ae55b454509e9659c42899133983ebdKristian Høgsberg    psp->ddx_version = *ddx_version;
700efd03a278ae55b454509e9659c42899133983ebdKristian Høgsberg    psp->dri_version = *dri_version;
701680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
702680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->pSAREA = pSAREA;
7037da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->lock = (drmLock *) &psp->pSAREA->lock;
704680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
705680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->pFB = frame_buffer->base;
706680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fbSize = frame_buffer->size;
707680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fbStride = frame_buffer->stride;
708680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fbWidth = frame_buffer->width;
709680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fbHeight = frame_buffer->height;
710680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->devPrivSize = frame_buffer->dev_priv_size;
711680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->pDevPriv = frame_buffer->dev_priv;
712fd4f7064e24654c89248be6d76f39c7baf22fce4Jon Smirl    psp->fbBPP = psp->fbStride * 8 / frame_buffer->width;
713680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
714ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsberg    psp->extensions = emptyExtensionList;
715680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fd = fd;
71664106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg    psp->myNum = scrn;
7177da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->dri2.enabled = GL_FALSE;
718680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
719680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /*
720680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** Do not init dummy context here; actual initialization will be
721680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** done when the first DRI context is created.  Init screen priv ptr
722680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** to NULL to let CreateContext routine that it needs to be inited.
723680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
724680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->dummyContextPriv.driScreenPriv = NULL;
725680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
726e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    psp->DriverAPI = driDriverAPI;
727680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
728e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    *driver_modes = driDriverAPI.InitScreen(psp);
72964106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg    if (*driver_modes == NULL) {
73064106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg	_mesa_free(psp);
731680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
732680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
733680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
734680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return psp;
735680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
736680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
7373f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul/**
7383f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul * DRI2
7393f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul */
740e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIscreen *
741f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsbergdri2CreateNewScreen(int scrn, int fd,
742e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		    const __DRIextension **extensions,
743e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		    const __DRIconfig ***driver_configs, void *data)
7447da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg{
7457da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    static const __DRIextension *emptyExtensionList[] = { NULL };
746e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIscreen *psp;
74716242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg    drmVersionPtr version;
748129b9ad16f95421d12f77c1bd3eca915d8768b78Kristian Høgsberg
749e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (driDriverAPI.InitScreen2 == NULL)
750129b9ad16f95421d12f77c1bd3eca915d8768b78Kristian Høgsberg        return NULL;
7517da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
7527da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp = _mesa_malloc(sizeof(*psp));
7537da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    if (!psp)
7547da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	return NULL;
7557da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
7566cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    setupLoaderExtensions(psp, extensions);
7576cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg
75816242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg    version = drmGetVersion(fd);
75916242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg    if (version) {
76016242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg	psp->drm_version.major = version->version_major;
76116242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg	psp->drm_version.minor = version->version_minor;
76216242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg	psp->drm_version.patch = version->version_patchlevel;
76316242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg	drmFreeVersion(version);
76416242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg    }
76516242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg
7667da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->extensions = emptyExtensionList;
7677da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->fd = fd;
7687da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->myNum = scrn;
7697da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->dri2.enabled = GL_TRUE;
7707da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
771e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    psp->DriverAPI = driDriverAPI;
772e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    *driver_configs = driDriverAPI.InitScreen2(psp);
773e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (*driver_configs == NULL) {
7747da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	_mesa_free(psp);
7757da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	return NULL;
7767da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    }
7777da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
778e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    psp->DriverAPI = driDriverAPI;
779e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
7807da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    return psp;
7817da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg}
7827da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
783e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic const __DRIextension **driGetExtensions(__DRIscreen *psp)
784e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
785e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return psp->extensions;
786e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
787e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
788f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg/** Core interface */
789e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergconst __DRIcoreExtension driCoreExtension = {
790e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    { __DRI_CORE, __DRI_CORE_VERSION },
791f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    NULL,
792e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driDestroyScreen,
793e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driGetExtensions,
794e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driGetConfigAttrib,
795e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driIndexConfigAttrib,
796f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    NULL,
797e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driDestroyDrawable,
798e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driSwapBuffers,
799f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    NULL,
800e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driCopyContext,
801e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driDestroyContext,
802e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driBindContext,
803e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driUnbindContext
804e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg};
805e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
806f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg/** Legacy DRI interface */
807f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsbergconst __DRIlegacyExtension driLegacyExtension = {
808f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    { __DRI_LEGACY, __DRI_LEGACY_VERSION },
809f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    driCreateNewScreen,
810f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    driCreateNewDrawable,
811f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    driCreateNewContext,
812f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg};
813f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg
814f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg/** Legacy DRI interface */
815f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsbergconst __DRIdri2Extension driDRI2Extension = {
816f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    { __DRI_DRI2, __DRI_DRI2_VERSION },
817f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    dri2CreateNewScreen,
818f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    dri2CreateNewDrawable,
819f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    dri2CreateNewContext,
820f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg};
821f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg
822e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg/* This is the table of extensions that the loader will dlsym() for. */
823e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergPUBLIC const __DRIextension *__driDriverExtensions[] = {
824e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    &driCoreExtension.base,
825e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    &driLegacyExtension.base,
826f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    &driDRI2Extension.base,
827e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    NULL
828e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg};
829e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
830680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic int
831a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian HøgsbergdriFrameTracking(__DRIdrawable *drawable, GLboolean enable)
832a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg{
833a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg    return GLX_BAD_CONTEXT;
834a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg}
835a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg
836a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsbergstatic int
837e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriQueryFrameTracking(__DRIdrawable *dpriv,
8385987a03f994af2bb413d1cf984ab01aa095c0943Kristian Høgsberg		      int64_t * sbc, int64_t * missedFrames,
8395987a03f994af2bb413d1cf984ab01aa095c0943Kristian Høgsberg		      float * lastMissedUsage, float * usage)
840680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
841680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   __DRIswapInfo   sInfo;
842680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int             status;
843680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int64_t         ust;
8446cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg   __DRIscreenPrivate *psp = dpriv->driScreenPriv;
845680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
846680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo );
847680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   if ( status == 0 ) {
848680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      *sbc = sInfo.swap_count;
849680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      *missedFrames = sInfo.swap_missed_count;
850680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      *lastMissedUsage = sInfo.swap_missed_usage;
851680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
8526cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg      (*psp->systemTime->getUST)( & ust );
853680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      *usage = driCalculateSwapUsage( dpriv, sInfo.swap_ust, ust );
854680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   }
855680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
856680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   return status;
857680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
858680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
859a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsbergconst __DRIframeTrackingExtension driFrameTrackingExtension = {
860ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg    { __DRI_FRAME_TRACKING, __DRI_FRAME_TRACKING_VERSION },
861a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg    driFrameTracking,
862a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg    driQueryFrameTracking
863a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg};
864680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
865680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
866680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Calculate amount of swap interval used between GLX buffer swaps.
867680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
868680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * The usage value, on the range [0,max], is the fraction of total swap
869680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * interval time used between GLX buffer swaps is calculated.
870680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
871680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *            \f$p = t_d / (i * t_r)\f$
872680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
873680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Where \f$t_d\f$ is the time since the last GLX buffer swap, \f$i\f$ is the
874680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * swap interval (as set by \c glXSwapIntervalSGI), and \f$t_r\f$ time
875680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * required for a single vertical refresh period (as returned by \c
876680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * glXGetMscRateOML).
877680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
878680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * See the documentation for the GLX_MESA_swap_frame_usage extension for more
879680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * details.
880680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
881680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param   dPriv  Pointer to the private drawable structure.
882680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \return  If less than a single swap interval time period was required
883680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          between GLX buffer swaps, a number greater than 0 and less than
884680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          1.0 is returned.  If exactly one swap interval time period is
885680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          required, 1.0 is returned, and if more than one is required then
886680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          a number greater than 1.0 will be returned.
887680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
888680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \sa glXSwapIntervalSGI glXGetMscRateOML
889680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
890680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \todo Instead of caching the \c glXGetMscRateOML function pointer, would it
891680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *       be possible to cache the sync rate?
892680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
893680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellfloat
894680ec7f85158eae58fd5ab56da8c66a645883cb0Keith WhitwelldriCalculateSwapUsage( __DRIdrawablePrivate *dPriv, int64_t last_swap_ust,
895680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		       int64_t current_ust )
896680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
897680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int32_t   n;
898680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int32_t   d;
899680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int       interval;
900680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   float     usage = 1.0;
9016cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg   __DRIscreenPrivate *psp = dPriv->driScreenPriv;
902680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
903e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg   if ( (*psp->systemTime->getMSCRate)(dPriv, &n, &d, dPriv->loaderPrivate) ) {
904efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg      interval = (dPriv->swap_interval != 0) ? dPriv->swap_interval : 1;
905680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
906680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
907680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      /* We want to calculate
908680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * (current_UST - last_swap_UST) / (interval * us_per_refresh).  We get
909680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * current_UST by calling __glXGetUST.  last_swap_UST is stored in
910680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * dPriv->swap_ust.  interval has already been calculated.
911680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       *
912680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * The only tricky part is us_per_refresh.  us_per_refresh is
913680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * 1000000 / MSC_rate.  We know the MSC_rate is n / d.  We can flip it
914680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * around and say us_per_refresh = 1000000 * d / n.  Since this goes in
915680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * the denominator of the final calculation, we calculate
916680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * (interval * 1000000 * d) and move n into the numerator.
917680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       */
918680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
919680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage = (current_ust - last_swap_ust);
920680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage *= n;
921680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage /= (interval * d);
922680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage /= 1000000.0;
923680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   }
924680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
925680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   return usage;
926680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
927680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
928680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
929