dri_util.c revision a7a9a91d7b28e5b5faed509d00f0f951e3136b1b
1680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
2680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \file dri_util.c
3680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * DRI utility functions.
4680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
5680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This module acts as glue between GLX and the actual hardware driver.  A DRI
6680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * driver doesn't really \e have to use any of this - it's optional.  But, some
7680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * useful stuff is done here that otherwise would have to be duplicated in most
8680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drivers.
9680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
10680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Basically, these utility functions take care of some of the dirty details of
11680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * screen initialization, context creation, context binding, DRM setup, etc.
12680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
13680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * These functions are compiled into each DRI driver so libGL.so knows nothing
14680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * about them.
15680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
16680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
17680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
18680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <assert.h>
19680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <stdarg.h>
20680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <unistd.h>
21680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <sys/mman.h>
22680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <stdio.h>
237c46033130b1b4d6098647d85c2710367572e079Ian Romanick
2438b317d508a2a3a4cc6d700ebca80c3b06c913e2Alan Hourihane#ifndef MAP_FAILED
2538b317d508a2a3a4cc6d700ebca80c3b06c913e2Alan Hourihane#define MAP_FAILED ((void *)-1)
2638b317d508a2a3a4cc6d700ebca80c3b06c913e2Alan Hourihane#endif
2738b317d508a2a3a4cc6d700ebca80c3b06c913e2Alan Hourihane
28ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/imports.h"
29c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick#define None 0
307c46033130b1b4d6098647d85c2710367572e079Ian Romanick
317c46033130b1b4d6098647d85c2710367572e079Ian Romanick#include "dri_util.h"
32ffb36d57a5f6359b5b91b73af60482a0016dd431Jon Smirl#include "drm_sarea.h"
33c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis#include "utils.h"
34680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
35c604e457d1ebe9a884b0a1fb08af38a0ce486699Ian Romanick#ifndef GLX_OML_sync_control
36aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsbergtypedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRIdrawable *drawable, int32_t *numerator, int32_t *denominator);
378cdccc82d7948daee256e092a5253d49e277ef75Ian Romanick#endif
388cdccc82d7948daee256e092a5253d49e277ef75Ian Romanick
393264352c577ce1d6681e70abd76624ede906df71Dave Airliestatic void dri_get_drawable(__DRIdrawable *pdp);
403264352c577ce1d6681e70abd76624ede906df71Dave Airliestatic void dri_put_drawable(__DRIdrawable *pdp);
413264352c577ce1d6681e70abd76624ede906df71Dave Airlie
42680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
43f968f67e6214416f04b8875ce59a94a02f464c81Kristian Høgsberg * This is just a token extension used to signal that the driver
44f968f67e6214416f04b8875ce59a94a02f464c81Kristian Høgsberg * supports setting a read drawable.
45f968f67e6214416f04b8875ce59a94a02f464c81Kristian Høgsberg */
46f968f67e6214416f04b8875ce59a94a02f464c81Kristian Høgsbergconst __DRIextension driReadDrawableExtension = {
47ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg    __DRI_READ_DRAWABLE, __DRI_READ_DRAWABLE_VERSION
48f968f67e6214416f04b8875ce59a94a02f464c81Kristian Høgsberg};
49f968f67e6214416f04b8875ce59a94a02f464c81Kristian Høgsberg
50c95e66120be049ee51ff84868b1da3379b312fabGeorge SapountzisGLint
51c95e66120be049ee51ff84868b1da3379b312fabGeorge SapountzisdriIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 )
52c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis{
53c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis   if (rect2.x1 > rect1.x1) rect1.x1 = rect2.x1;
54c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis   if (rect2.x2 < rect1.x2) rect1.x2 = rect2.x2;
55c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis   if (rect2.y1 > rect1.y1) rect1.y1 = rect2.y1;
56c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis   if (rect2.y2 < rect1.y2) rect1.y2 = rect2.y2;
57c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis
58c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis   if (rect1.x1 > rect1.x2 || rect1.y1 > rect1.y2) return 0;
59c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis
60c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis   return (rect1.x2 - rect1.x1) * (rect1.y2 - rect1.y1);
61c95e66120be049ee51ff84868b1da3379b312fabGeorge Sapountzis}
62680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
63680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
64680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Context (un)binding functions                          */
65680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
66680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
67680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
68680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
69680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Unbind context.
70680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
71aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsberg * \param scrn the screen.
72680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param gc context.
73680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
74680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \return \c GL_TRUE on success, or \c GL_FALSE on failure.
75680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
76680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
77680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::UnbindContext, and then decrements
78d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg * __DRIdrawableRec::refcount which must be non-zero for a successful
79680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * return.
80680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
81680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * While casting the opaque private pointers associated with the parameters
82680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * into their respective real types it also assures they are not \c NULL.
83680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
84e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int driUnbindContext(__DRIcontext *pcp)
85680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
86e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIscreen *psp;
87418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    __DRIdrawable *pdp;
88418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    __DRIdrawable *prp;
89680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
90680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /*
91680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** Assume error checking is done properly in glXMakeCurrent before
92c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick    ** calling driUnbindContext.
93680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
94680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
95e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (pcp == NULL)
96aceccda56b08338e217991e54607f1c9f18fc3e6Kristian Høgsberg        return GL_FALSE;
97680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
98e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    psp = pcp->driScreenPriv;
99418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    pdp = pcp->driDrawablePriv;
100418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    prp = pcp->driReadablePriv;
101680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
102418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    /* already unbound */
103418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    if (!pdp && !prp)
104418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen      return GL_TRUE;
105418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    /* Let driver unbind drawable from context */
106680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    (*psp->DriverAPI.UnbindContext)(pcp);
107680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
108cab77711b3e8d398393677bcefcd413f50503a64Vinson Lee    assert(pdp);
109418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    if (pdp->refcount == 0) {
110418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	/* ERROR!!! */
111418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	return GL_FALSE;
112418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    }
113418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
114418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    dri_put_drawable(pdp);
115418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
116418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    if (prp != pdp) {
117418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen        if (prp->refcount == 0) {
118418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	    /* ERROR!!! */
119418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	    return GL_FALSE;
120418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	}
121418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
122418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    	dri_put_drawable(prp);
123418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    }
124418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
125418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
126418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    /* XXX this is disabled so that if we call SwapBuffers on an unbound
127418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen     * window we can determine the last context bound to the window and
128418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen     * use that context's lock. (BrianP, 2-Dec-2000)
129418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen     */
130418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    pcp->driDrawablePriv = pcp->driReadablePriv = NULL;
131418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen
132680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return GL_TRUE;
133680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
134680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
135680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
136680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function takes both a read buffer and a draw buffer.  This is needed
137680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
138680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * function.
139680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
140e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int driBindContext(__DRIcontext *pcp,
141e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg			  __DRIdrawable *pdp,
142e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg			  __DRIdrawable *prp)
143680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
144d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg    __DRIscreen *psp = NULL;
145680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
146680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* Bind the drawable to the context */
1478e753d04045a82062ac34d3b2622eb9dba8af374Thomas Hellstrom
148418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    if (pcp) {
149c994f08eb1ec2a4bbaa44fbd6d35e7ff033d5c3cVinson Lee	psp = pcp->driScreenPriv;
150418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	pcp->driDrawablePriv = pdp;
151418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	pcp->driReadablePriv = prp;
152418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	if (pdp) {
153418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	    pdp->driContextPriv = pcp;
154418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    	    dri_get_drawable(pdp);
1558e753d04045a82062ac34d3b2622eb9dba8af374Thomas Hellstrom	}
156418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	if ( prp && pdp != prp ) {
157418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    	    dri_get_drawable(prp);
158418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen	}
159418cdc66ec10c1f3005320ab46404b907c30e37dPauli Nieminen    }
160680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
161680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /*
162680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** Now that we have a context associated with this drawable, we can
163680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** initialize the drawable information if has not been done before.
164680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
165680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
166e63f532d26d82c06281840a84c73e2e36d7b3e1eVinson Lee    assert(psp);
167f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    if (!psp->dri2.enabled) {
1688e753d04045a82062ac34d3b2622eb9dba8af374Thomas Hellstrom	if (pdp && !pdp->pStamp) {
1697da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
1707da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    __driUtilUpdateDrawableInfo(pdp);
1717da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
1727da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	}
1738e753d04045a82062ac34d3b2622eb9dba8af374Thomas Hellstrom	if (prp && pdp != prp && !prp->pStamp) {
1747da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
1757da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    __driUtilUpdateDrawableInfo(prp);
1767da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	    DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
1778e753d04045a82062ac34d3b2622eb9dba8af374Thomas Hellstrom        }
1787b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick    }
1797b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick
180680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* Call device-specific MakeCurrent */
181680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
182c952b3e907ab31cd5f95157c18ce2f81626aafe4Thomas Hellstrom    return (*psp->DriverAPI.MakeCurrent)(pcp, pdp, prp);
183680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
184680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
185680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
186680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
187680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
188680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
189680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Drawable handling functions                            */
190680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
191680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
192680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
193680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
194680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Update private drawable information.
195680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
196680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param pdp pointer to the private drawable information to update.
197680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
198d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg * This function basically updates the __DRIdrawable struct's
1995f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick * cliprect information by calling \c __DRIinterfaceMethods::getDrawableInfo.
2005f1ba3e21b62cee1a4f900a2e6964728f3eeea9bIan Romanick * This is usually called by the DRI_VALIDATE_DRAWABLE_INFO macro which
201680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * compares the __DRIdrwablePrivate pStamp and lastStamp values.  If
202680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * the values are different that means we have to update the clipping
203680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * info.
204680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
205680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellvoid
206d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg__driUtilUpdateDrawableInfo(__DRIdrawable *pdp)
207680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
208d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg    __DRIscreen *psp = pdp->driScreenPriv;
209d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg    __DRIcontext *pcp = pdp->driContextPriv;
210680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
2117b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick    if (!pcp
2127b1ff326071658d5bd6e7feb2ad78d0e0209211dIan Romanick	|| ((pdp != pcp->driDrawablePriv) && (pdp != pcp->driReadablePriv))) {
213682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström	/* ERROR!!!
214682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström	 * ...but we must ignore it. There can be many contexts bound to a
215682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström	 * drawable.
216682393944c72ecfabe8df674af0b48975e90b98cThomas Hellström	 */
217680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
218680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
219680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pdp->pClipRects) {
22032f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(pdp->pClipRects);
221a903749b246fce26038c66d06fe7eb77daf815abMichel Dänzer	pdp->pClipRects = NULL;
222680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
223680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
224680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pdp->pBackClipRects) {
22532f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(pdp->pBackClipRects);
226a903749b246fce26038c66d06fe7eb77daf815abMichel Dänzer	pdp->pBackClipRects = NULL;
227680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
228680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
229680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
230680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
231e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (! (*psp->getDrawableInfo->getDrawableInfo)(pdp,
232680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->index, &pdp->lastStamp,
233680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->x, &pdp->y, &pdp->w, &pdp->h,
234680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->numClipRects, &pdp->pClipRects,
235680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->backX,
236680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->backY,
237680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->numBackClipRects,
238e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg			  &pdp->pBackClipRects,
239e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg			  pdp->loaderPrivate)) {
240680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* Error -- eg the window may have been destroyed.  Keep going
241680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 * with no cliprects.
242680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 */
243680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        pdp->pStamp = &pdp->lastStamp; /* prevent endless loop */
244680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->numClipRects = 0;
245680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->pClipRects = NULL;
246680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->numBackClipRects = 0;
247680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->pBackClipRects = NULL;
248680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
249680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    else
250680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp);
251680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
252680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
253680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
254680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
255680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
256680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
257680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
258680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name GLX callbacks                                          */
259680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
260680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
261680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
262e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driReportDamage(__DRIdrawable *pdp,
263e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg			    struct drm_clip_rect *pClipRects, int numClipRects)
264e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
265e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIscreen *psp = pdp->driScreenPriv;
266e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
267e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    /* Check that we actually have the new damage report method */
268f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    if (psp->damage) {
269e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg	/* Report the damage.  Currently, all our drivers draw
270e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg	 * directly to the front buffer, so we report the damage there
271e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg	 * rather than to the backing storein (if any).
272e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg	 */
273e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg	(*psp->damage->reportDamage)(pdp,
274e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg				     pdp->x, pdp->y,
275e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg				     pClipRects, numClipRects,
276e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg				     GL_TRUE, pdp->loaderPrivate);
277e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    }
278e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
279e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
280e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
281680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
282680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Swap buffers.
283680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
284680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param drawablePrivate opaque pointer to the per-drawable private info.
285680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
286680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
287d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg * This function calls __DRIdrawable::swapBuffers.
288680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
289680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Is called directly from glXSwapBuffers().
290680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
291e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driSwapBuffers(__DRIdrawable *dPriv)
292680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
293e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIscreen *psp = dPriv->driScreenPriv;
2947627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao    drm_clip_rect_t *rects;
2957627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao    int i;
2962407e48f2805e27e76e2e1d7083926c4077d9032Xiang, Haihao
297e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    psp->DriverAPI.SwapBuffers(dPriv);
298c2b185cff82a6cdb723cda4e05ffe1a213a9de3eEric Anholt
29943c7ffaea635f949fd4803c4f594cf53e4b98f24Younes Manton    if (!dPriv->numClipRects)
30043c7ffaea635f949fd4803c4f594cf53e4b98f24Younes Manton        return;
30143c7ffaea635f949fd4803c4f594cf53e4b98f24Younes Manton
30232f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg    rects = malloc(sizeof(*rects) * dPriv->numClipRects);
3037627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao
3047627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao    if (!rects)
3057627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao        return;
3067627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao
3077627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao    for (i = 0; i < dPriv->numClipRects; i++) {
3087627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao        rects[i].x1 = dPriv->pClipRects[i].x1 - dPriv->x;
3097627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao        rects[i].y1 = dPriv->pClipRects[i].y1 - dPriv->y;
3107627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao        rects[i].x2 = dPriv->pClipRects[i].x2 - dPriv->x;
3117627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao        rects[i].y2 = dPriv->pClipRects[i].y2 - dPriv->y;
3127627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao    }
3137627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao
3147627c7f5dfa3b1bc7be9d1670668a81a70d9f64aXiang, Haihao    driReportDamage(dPriv, rects, dPriv->numClipRects);
31532f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg    free(rects);
316680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
317680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
318e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int driDrawableGetMSC( __DRIscreen *sPriv, __DRIdrawable *dPriv,
31938fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes			      int64_t *msc )
32038fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes{
3216e8d21d72f35767e07081a8bee4323aaaf5e2aaeKristian Høgsberg    return sPriv->DriverAPI.GetDrawableMSC(sPriv, dPriv, msc);
322680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
323680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
3243f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul
325e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc,
3265987a03f994af2bb413d1cf984ab01aa095c0943Kristian Høgsberg			 int64_t divisor, int64_t remainder,
3275987a03f994af2bb413d1cf984ab01aa095c0943Kristian Høgsberg			 int64_t * msc, int64_t * sbc)
328680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
329680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIswapInfo  sInfo;
330680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    int  status;
331680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
332680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    status = dPriv->driScreenPriv->DriverAPI.WaitForMSC( dPriv, target_msc,
333680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                                                         divisor, remainder,
334680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                                                         msc );
335680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
336680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* GetSwapInfo() may not be provided by the driver if GLX_SGI_video_sync
337680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     * is supported but GLX_OML_sync_control is not.  Therefore, don't return
338680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     * an error value if GetSwapInfo() is not implemented.
339680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
340680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( status == 0
341680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell         && dPriv->driScreenPriv->DriverAPI.GetSwapInfo ) {
342680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo );
343680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        *sbc = sInfo.swap_count;
344680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
345680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
346680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return status;
347680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
348680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
3493f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul
350106a6f29bbdc71982afd629bdf89369cefd1459eKristian Høgsbergconst __DRImediaStreamCounterExtension driMediaStreamCounterExtension = {
351ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg    { __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION },
352106a6f29bbdc71982afd629bdf89369cefd1459eKristian Høgsberg    driWaitForMSC,
35338fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes    driDrawableGetMSC,
354106a6f29bbdc71982afd629bdf89369cefd1459eKristian Høgsberg};
355680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
3563f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul
357e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driCopySubBuffer(__DRIdrawable *dPriv,
358f2ad1b60c0da11283b399008f491792790cea294Brian Paul			      int x, int y, int w, int h)
359f2ad1b60c0da11283b399008f491792790cea294Brian Paul{
360e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    drm_clip_rect_t rect;
361e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
362e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    rect.x1 = x;
363377016d728ace47c9eeb3ac2f01191608ab060f6Dennis Kasprzyk    rect.y1 = dPriv->h - y - h;
364e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    rect.x2 = x + w;
365377016d728ace47c9eeb3ac2f01191608ab060f6Dennis Kasprzyk    rect.y2 = rect.y1 + h;
366e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driReportDamage(dPriv, &rect, 1);
3673a94b25538c647df965a93cd7734b841257ef203Peter Hutterer
3683a94b25538c647df965a93cd7734b841257ef203Peter Hutterer    dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h);
369f2ad1b60c0da11283b399008f491792790cea294Brian Paul}
370680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
371ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsbergconst __DRIcopySubBufferExtension driCopySubBufferExtension = {
372ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg    { __DRI_COPY_SUB_BUFFER, __DRI_COPY_SUB_BUFFER_VERSION },
373ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg    driCopySubBuffer
374ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsberg};
375ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsberg
376e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driSetSwapInterval(__DRIdrawable *dPriv, unsigned int interval)
377efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg{
378e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    dPriv->swap_interval = interval;
379efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg}
380efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg
381e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic unsigned int driGetSwapInterval(__DRIdrawable *dPriv)
382efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg{
383e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return dPriv->swap_interval;
384efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg}
385efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg
386efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsbergconst __DRIswapControlExtension driSwapControlExtension = {
387ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg    { __DRI_SWAP_CONTROL, __DRI_SWAP_CONTROL_VERSION },
388efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg    driSetSwapInterval,
389efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg    driGetSwapInterval
390efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg};
391efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg
392efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg
393680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
394680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This is called via __DRIscreenRec's createNewDrawable pointer.
395680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
396e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIdrawable *
397e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
398e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		     drm_drawable_t hwDrawable, int renderType,
399e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		     const int *attrs, void *data)
400680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
401e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIdrawable *pdp;
4021960182ece3f1eca06d2e439f64dd61be8a03ff5Ian Romanick
403680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* Since pbuffers are not yet supported, no drawable attributes are
404680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     * supported either.
405680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     */
406680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    (void) attrs;
407680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
40832f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg    pdp = malloc(sizeof *pdp);
409680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!pdp) {
410680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
411680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
412680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
413e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    pdp->loaderPrivate = data;
4144ff95e78e19e5902352ea3759d32d9f013255f42Kristian Høgsberg    pdp->hHWDrawable = hwDrawable;
4153264352c577ce1d6681e70abd76624ede906df71Dave Airlie    pdp->refcount = 1;
416680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->pStamp = NULL;
417680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->lastStamp = 0;
418680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->index = 0;
419680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->x = 0;
420680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->y = 0;
421680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->w = 0;
422680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->h = 0;
423680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->numClipRects = 0;
424680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->numBackClipRects = 0;
425680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->pClipRects = NULL;
426680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->pBackClipRects = NULL;
42738fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes    pdp->vblSeq = 0;
42838fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes    pdp->vblFlags = 0;
429680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
430680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->driScreenPriv = psp;
431680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
432e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes,
433680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell					renderType == GLX_PIXMAP_BIT)) {
43432f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg       free(pdp);
435680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       return NULL;
436680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
437680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
43838fdb47d26055e19d50cd407266b56ed4317ae0aJesse Barnes    pdp->msc_base = 0;
439680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
440c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick    /* This special default value is replaced with the configured
441c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick     * default value when the drawable is first bound to a direct
442c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick     * rendering context.
443c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick     */
444efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg    pdp->swap_interval = (unsigned)-1;
445680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
446e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return pdp;
447e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
448680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
4493f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul
450e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIdrawable *
451f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsbergdri2CreateNewDrawable(__DRIscreen *screen,
452f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg		      const __DRIconfig *config,
453f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg		      void *loaderPrivate)
454e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
455e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIdrawable *pdraw;
4567da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
457f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    pdraw = driCreateNewDrawable(screen, config, 0, 0, NULL, loaderPrivate);
4585cf69fe511a67a7bcf6787974becf6a143abb507Alan Hourihane    if (!pdraw)
4595cf69fe511a67a7bcf6787974becf6a143abb507Alan Hourihane    	return NULL;
460e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
461925b901ba313a3ddd7567eca088951be39414430Kristian Høgsberg    pdraw->pClipRects = &pdraw->dri2.clipRect;
462925b901ba313a3ddd7567eca088951be39414430Kristian Høgsberg    pdraw->pBackClipRects = &pdraw->dri2.clipRect;
463e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
46461d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez    pdraw->pStamp = &pdraw->dri2.stamp;
46561d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez    *pdraw->pStamp = pdraw->lastStamp + 1;
46661d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez
467e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return pdraw;
468680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
469680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
4703264352c577ce1d6681e70abd76624ede906df71Dave Airliestatic void dri_get_drawable(__DRIdrawable *pdp)
4713264352c577ce1d6681e70abd76624ede906df71Dave Airlie{
4723264352c577ce1d6681e70abd76624ede906df71Dave Airlie    pdp->refcount++;
4733264352c577ce1d6681e70abd76624ede906df71Dave Airlie}
4743264352c577ce1d6681e70abd76624ede906df71Dave Airlie
4753264352c577ce1d6681e70abd76624ede906df71Dave Airliestatic void dri_put_drawable(__DRIdrawable *pdp)
476680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
477d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg    __DRIscreen *psp;
478680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
479680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pdp) {
480f622b649fb0c55b1640997f9d32ea327743519a1Vinson Lee	pdp->refcount--;
481f622b649fb0c55b1640997f9d32ea327743519a1Vinson Lee	if (pdp->refcount)
482f622b649fb0c55b1640997f9d32ea327743519a1Vinson Lee	    return;
483f622b649fb0c55b1640997f9d32ea327743519a1Vinson Lee
484eab896cc213157758d74a2f39b5e3b1e748c071fDave Airlie	psp = pdp->driScreenPriv;
485680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        (*psp->DriverAPI.DestroyBuffer)(pdp);
486925b901ba313a3ddd7567eca088951be39414430Kristian Høgsberg	if (pdp->pClipRects && pdp->pClipRects != &pdp->dri2.clipRect) {
48732f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	    free(pdp->pClipRects);
488680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    pdp->pClipRects = NULL;
489680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
490925b901ba313a3ddd7567eca088951be39414430Kristian Høgsberg	if (pdp->pBackClipRects && pdp->pClipRects != &pdp->dri2.clipRect) {
49132f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	    free(pdp->pBackClipRects);
492680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    pdp->pBackClipRects = NULL;
493680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
49432f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(pdp);
495680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
496680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
497680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
4983264352c577ce1d6681e70abd76624ede906df71Dave Airliestatic void
4993264352c577ce1d6681e70abd76624ede906df71Dave AirliedriDestroyDrawable(__DRIdrawable *pdp)
5003264352c577ce1d6681e70abd76624ede906df71Dave Airlie{
5013264352c577ce1d6681e70abd76624ede906df71Dave Airlie    dri_put_drawable(pdp);
5023264352c577ce1d6681e70abd76624ede906df71Dave Airlie}
5033264352c577ce1d6681e70abd76624ede906df71Dave Airlie
504680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
505680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
506680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
507680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
508680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Context handling functions                             */
509680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
510680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
511680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
512680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
513680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Destroy the per-context private information.
514680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
515680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
516680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls
517680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drmDestroyContext(), and finally frees \p contextPrivate.
518680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
519b4b040f7d83f5f4917c48bf5833394d550e30421Brian Paulstatic void
520e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriDestroyContext(__DRIcontext *pcp)
521680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
522680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pcp) {
523680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	(*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp);
52432f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(pcp);
525680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
526680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
527680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
528680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
529680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
530680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Create the per-drawable private driver information.
531680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
532680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param render_type   Type of rendering target.  \c GLX_RGBA is the only
533680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *                      type likely to ever be supported for direct-rendering.
5343f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul * \param shared        Context with which to share textures, etc. or NULL
535680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
536680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \returns An opaque pointer to the per-context private information on
537680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          success, or \c NULL on failure.
538680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
539680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
540d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg * This function allocates and fills a __DRIcontextRec structure.  It
541680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * performs some device independent initialization and passes all the
542680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * relevent information to __DriverAPIRec::CreateContext to create the
543680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * context.
544680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
545680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
546e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIcontext *
547e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
548ecdb45cb29e3209287cc297081596126e955ff2bKristian Høgsberg		    int render_type, __DRIcontext *shared,
549e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		    drm_context_t hwContext, void *data)
550680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
551e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIcontext *pcp;
552e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
553680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
55432f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg    pcp = malloc(sizeof *pcp);
555e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (!pcp)
556680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
557680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
558680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pcp->driScreenPriv = psp;
559680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pcp->driDrawablePriv = NULL;
56093931d9e684cd5a5659c3f28f8da7294ac174542Kristian Høgsberg    pcp->loaderPrivate = data;
56193931d9e684cd5a5659c3f28f8da7294ac174542Kristian Høgsberg
562d449627829e1a4a3250a1a723af2f4e3cd5fd194Kristian Høgsberg    pcp->dri2.draw_stamp = 0;
563d449627829e1a4a3250a1a723af2f4e3cd5fd194Kristian Høgsberg    pcp->dri2.read_stamp = 0;
564680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
565e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    pcp->hHWContext = hwContext;
56674d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
567a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    if ( !(*psp->DriverAPI.CreateContext)(API_OPENGL,
568a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg					  &config->modes, pcp, shareCtx) ) {
56932f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg        free(pcp);
570680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        return NULL;
571680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
572680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
573680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return pcp;
574680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
575ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsberg
576a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsbergstatic unsigned int
577a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsbergdri2GetAPIMask(__DRIscreen *screen)
578a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg{
579a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    return screen->api_mask;
580a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg}
581a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
582a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsbergstatic __DRIcontext *
583a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsbergdri2CreateNewContextForAPI(__DRIscreen *screen, int api,
584a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg			   const __DRIconfig *config,
585a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg			   __DRIcontext *shared, void *data)
586a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg{
587a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    __DRIcontext *context;
588a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    void *shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
589a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    gl_api mesa_api;
590a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
591a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    if (!(screen->api_mask & (1 << api)))
592a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	return NULL;
593a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
594a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    switch (api) {
595a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    case __DRI_API_OPENGL:
596a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	    mesa_api = API_OPENGL;
597a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	    break;
598a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    case __DRI_API_GLES:
599a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	    mesa_api = API_OPENGLES;
600a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	    break;
601a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    case __DRI_API_GLES2:
602a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	    mesa_api = API_OPENGLES2;
603a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	    break;
604a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    }
605a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
606a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    context = malloc(sizeof *context);
607a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    if (!context)
608a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg	return NULL;
609a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
610a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    context->driScreenPriv = screen;
611a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    context->driDrawablePriv = NULL;
612a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    context->loaderPrivate = data;
613a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
614a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    if (!(*screen->DriverAPI.CreateContext)(api, &config->modes,
615a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg					    context, shareCtx) ) {
616a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg        free(context);
617a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg        return NULL;
618a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    }
619a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
620a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    return context;
621a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg}
622a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg
6233f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul
624e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIcontext *
625e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergdri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
626e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		      __DRIcontext *shared, void *data)
627f616a263a25eda135800bea7d3a863c569b93e30Kristian Høgsberg{
628a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg   return dri2CreateNewContextForAPI(screen, __DRI_API_OPENGL,
629a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg				     config, shared, data);
630f616a263a25eda135800bea7d3a863c569b93e30Kristian Høgsberg}
631680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
632e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic int
633e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
634e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
635e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return GL_FALSE;
636e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
637e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
638e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg/*@}*/
639e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
640e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
641680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
642680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Screen handling functions                              */
643680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
644680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
645680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
646680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
647680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Destroy the per-screen private information.
648680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
649680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
650680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls
651680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drmClose(), and finally frees \p screenPrivate.
652680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
653e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic void driDestroyScreen(__DRIscreen *psp)
654680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
655680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (psp) {
656680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* No interaction with the X-server is possible at this point.  This
657680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 * routine is called after XCloseDisplay, so there is no protocol
658680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 * stream open to the X-server anymore.
659680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 */
660680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
661680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if (psp->DriverAPI.DestroyScreen)
662680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    (*psp->DriverAPI.DestroyScreen)(psp);
663680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
664f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg	if (!psp->dri2.enabled) {
6657da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	   (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
6667da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	   (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
6677da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	   (void)drmCloseOnce(psp->fd);
6687da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	}
669e5c28321b2047418ba960c5f9c3aa86cf2514bbbTilman Sauerbeck
67032f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(psp);
671680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
672680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
673680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
6746cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsbergstatic void
675e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergsetupLoaderExtensions(__DRIscreen *psp,
6766cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg		      const __DRIextension **extensions)
6776cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg{
6786cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    int i;
6796cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg
6806cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    for (i = 0; extensions[i]; i++) {
6816cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_GET_DRAWABLE_INFO) == 0)
6826cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	    psp->getDrawableInfo = (__DRIgetDrawableInfoExtension *) extensions[i];
6836cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_DAMAGE) == 0)
6846cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	    psp->damage = (__DRIdamageExtension *) extensions[i];
6856cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_SYSTEM_TIME) == 0)
6866cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg	    psp->systemTime = (__DRIsystemTimeExtension *) extensions[i];
687f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_DRI2_LOADER) == 0)
688f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg	    psp->dri2.loader = (__DRIdri2LoaderExtension *) extensions[i];
689c26247100bfd453a7ec013f630abe366c12fbd8bKristian Høgsberg	if (strcmp(extensions[i]->name, __DRI_IMAGE_LOOKUP) == 0)
690c26247100bfd453a7ec013f630abe366c12fbd8bKristian Høgsberg	    psp->dri2.image = (__DRIimageLookupExtension *) extensions[i];
6916cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    }
6926cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg}
6936cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg
694680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
69564106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * This is the bootstrap function for the driver.  libGL supplies all of the
69664106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * requisite information about the system, and the driver initializes itself.
69764106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * This routine also fills in the linked list pointed to by \c driver_modes
69864106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * with the \c __GLcontextModes that the driver can support for windows or
69964106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * pbuffers.
7003f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul *
7013f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul * For legacy DRI.
702680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
703680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param scrn  Index of the screen
704680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param ddx_version Version of the 2D DDX.  This may not be meaningful for
705680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *                    all drivers.
706680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dri_version Version of the "server-side" DRI.
707680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param drm_version Version of the kernel DRM.
708680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param frame_buffer Data describing the location and layout of the
709680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *                     framebuffer.
710fab1f07d6ad01463897ae792f4b33738afb07369Jeff Smith * \param pSAREA       Pointer to the SAREA.
711680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param fd           Device handle for the DRM.
7123f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul * \param extensions   ??
7133f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul * \param driver_modes  Returns modes suppoted by the driver
7143f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul * \param loaderPrivate  ??
715c39bf5e273a4995a279ae2af59fc29e06ab47e29Ian Romanick *
71664106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * \note There is no need to check the minimum API version in this
71764106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * function.  Since the name of this function is versioned, it is
71864106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg * impossible for a loader that is too old to even load this driver.
719680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
720e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIscreen *
721e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriCreateNewScreen(int scrn,
722e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   const __DRIversion *ddx_version,
723e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   const __DRIversion *dri_version,
724e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   const __DRIversion *drm_version,
725e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   const __DRIframebuffer *frame_buffer,
726e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   drmAddress pSAREA, int fd,
727e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   const __DRIextension **extensions,
728e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   const __DRIconfig ***driver_modes,
729e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		   void *loaderPrivate)
730680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
731efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg    static const __DRIextension *emptyExtensionList[] = { NULL };
732e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIscreen *psp;
733680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
73432f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg    psp = calloc(1, sizeof *psp);
73564106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg    if (!psp)
736680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
737680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
7386cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    setupLoaderExtensions(psp, extensions);
7396cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg
740680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /*
741680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** NOT_DONE: This is used by the X server to detect when the client
742680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** has died while holding the drawable lock.  The client sets the
743680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** drawable lock to this value.
744680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
745680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->drawLockID = 1;
746680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
747efd03a278ae55b454509e9659c42899133983ebdKristian Høgsberg    psp->drm_version = *drm_version;
748efd03a278ae55b454509e9659c42899133983ebdKristian Høgsberg    psp->ddx_version = *ddx_version;
749efd03a278ae55b454509e9659c42899133983ebdKristian Høgsberg    psp->dri_version = *dri_version;
750680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
751680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->pSAREA = pSAREA;
7527da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->lock = (drmLock *) &psp->pSAREA->lock;
753680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
754680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->pFB = frame_buffer->base;
755680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fbSize = frame_buffer->size;
756680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fbStride = frame_buffer->stride;
757680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fbWidth = frame_buffer->width;
758680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fbHeight = frame_buffer->height;
759680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->devPrivSize = frame_buffer->dev_priv_size;
760680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->pDevPriv = frame_buffer->dev_priv;
761fd4f7064e24654c89248be6d76f39c7baf22fce4Jon Smirl    psp->fbBPP = psp->fbStride * 8 / frame_buffer->width;
762680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
763ac3e838fa748c8c8a6ffc04d1ab13da71f75f103Kristian Høgsberg    psp->extensions = emptyExtensionList;
764680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fd = fd;
76564106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg    psp->myNum = scrn;
7667da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->dri2.enabled = GL_FALSE;
767680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
768e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    psp->DriverAPI = driDriverAPI;
769a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    psp->api_mask = (1 << __DRI_API_OPENGL);
770680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
771e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    *driver_modes = driDriverAPI.InitScreen(psp);
77264106d0d9aeefa6974317042b6bc3e5eaabac5a2Kristian Høgsberg    if (*driver_modes == NULL) {
77332f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(psp);
774680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
775680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
776680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
777680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return psp;
778680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
779680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
7803f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul/**
7813f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul * DRI2
7823f3e4f645d389672e6d72215e60b812a887cc66dBrian Paul */
783e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic __DRIscreen *
784f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsbergdri2CreateNewScreen(int scrn, int fd,
785e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		    const __DRIextension **extensions,
786e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg		    const __DRIconfig ***driver_configs, void *data)
7877da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg{
7887da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    static const __DRIextension *emptyExtensionList[] = { NULL };
789e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    __DRIscreen *psp;
79016242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg    drmVersionPtr version;
791129b9ad16f95421d12f77c1bd3eca915d8768b78Kristian Høgsberg
792e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (driDriverAPI.InitScreen2 == NULL)
793129b9ad16f95421d12f77c1bd3eca915d8768b78Kristian Høgsberg        return NULL;
7947da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
79532f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg    psp = calloc(1, sizeof(*psp));
7967da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    if (!psp)
7977da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	return NULL;
7987da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
7996cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg    setupLoaderExtensions(psp, extensions);
8006cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg
80116242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg    version = drmGetVersion(fd);
80216242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg    if (version) {
80316242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg	psp->drm_version.major = version->version_major;
80416242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg	psp->drm_version.minor = version->version_minor;
80516242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg	psp->drm_version.patch = version->version_patchlevel;
80616242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg	drmFreeVersion(version);
80716242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg    }
80816242a8007f41ab63f9a28bb9a750857c8cdb8afKristian Høgsberg
8097da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->extensions = emptyExtensionList;
8107da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->fd = fd;
8117da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->myNum = scrn;
8127da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    psp->dri2.enabled = GL_TRUE;
8137da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
814e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    psp->DriverAPI = driDriverAPI;
815a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    psp->api_mask = (1 << __DRI_API_OPENGL);
816e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    *driver_configs = driDriverAPI.InitScreen2(psp);
817e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    if (*driver_configs == NULL) {
81832f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	free(psp);
8197da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg	return NULL;
8207da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    }
8217da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
822e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    psp->DriverAPI = driDriverAPI;
823e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
8247da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg    return psp;
8257da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg}
8267da5705b090d9c97a9b765d786c5e89afe9d1f25Kristian Høgsberg
827e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergstatic const __DRIextension **driGetExtensions(__DRIscreen *psp)
828e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg{
829e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    return psp->extensions;
830e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg}
831e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
832f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg/** Core interface */
833e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsbergconst __DRIcoreExtension driCoreExtension = {
834e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    { __DRI_CORE, __DRI_CORE_VERSION },
835f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    NULL,
836e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driDestroyScreen,
837e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driGetExtensions,
838e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driGetConfigAttrib,
839e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driIndexConfigAttrib,
840f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    NULL,
841e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driDestroyDrawable,
842e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driSwapBuffers,
843f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    NULL,
844e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driCopyContext,
845e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driDestroyContext,
846e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driBindContext,
847e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg    driUnbindContext
848e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg};
849e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg
850f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg/** Legacy DRI interface */
851f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsbergconst __DRIlegacyExtension driLegacyExtension = {
852f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    { __DRI_LEGACY, __DRI_LEGACY_VERSION },
853f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    driCreateNewScreen,
854f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    driCreateNewDrawable,
855f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    driCreateNewContext,
856f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg};
857f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg
85839a0e4e7de379a182c1544fa24d5cb2a7687ec72Kristian Høgsberg/** DRI2 interface */
859f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsbergconst __DRIdri2Extension driDRI2Extension = {
860f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    { __DRI_DRI2, __DRI_DRI2_VERSION },
861f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    dri2CreateNewScreen,
862f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    dri2CreateNewDrawable,
863f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg    dri2CreateNewContext,
864a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    dri2GetAPIMask,
865a7a9a91d7b28e5b5faed509d00f0f951e3136b1bKristian Høgsberg    dri2CreateNewContextForAPI
866f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg};
867f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg
868680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic int
869a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian HøgsbergdriFrameTracking(__DRIdrawable *drawable, GLboolean enable)
870a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg{
871a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg    return GLX_BAD_CONTEXT;
872a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg}
873a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg
874a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsbergstatic int
875e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian HøgsbergdriQueryFrameTracking(__DRIdrawable *dpriv,
8765987a03f994af2bb413d1cf984ab01aa095c0943Kristian Høgsberg		      int64_t * sbc, int64_t * missedFrames,
8775987a03f994af2bb413d1cf984ab01aa095c0943Kristian Høgsberg		      float * lastMissedUsage, float * usage)
878680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
879680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   __DRIswapInfo   sInfo;
880680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int             status;
881680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int64_t         ust;
882d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg   __DRIscreen *psp = dpriv->driScreenPriv;
883680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
884680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo );
885680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   if ( status == 0 ) {
886680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      *sbc = sInfo.swap_count;
887680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      *missedFrames = sInfo.swap_missed_count;
888680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      *lastMissedUsage = sInfo.swap_missed_usage;
889680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
8906cb3f5c4d8618a14bb7ad1d9df10ed7e648a7b2bKristian Høgsberg      (*psp->systemTime->getUST)( & ust );
891680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      *usage = driCalculateSwapUsage( dpriv, sInfo.swap_ust, ust );
892680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   }
893680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
894680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   return status;
895680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
896680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
897a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsbergconst __DRIframeTrackingExtension driFrameTrackingExtension = {
898ccff0cb26378ce370fc8697a2a2ada138d2e119eKristian Høgsberg    { __DRI_FRAME_TRACKING, __DRI_FRAME_TRACKING_VERSION },
899a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg    driFrameTracking,
900a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg    driQueryFrameTracking
901a7a0a2beb54dcb78d7e0ab64cf2f5a6ede8191a4Kristian Høgsberg};
902680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
903680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
904680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Calculate amount of swap interval used between GLX buffer swaps.
905680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
906680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * The usage value, on the range [0,max], is the fraction of total swap
907680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * interval time used between GLX buffer swaps is calculated.
908680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
909680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *            \f$p = t_d / (i * t_r)\f$
910680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
911680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Where \f$t_d\f$ is the time since the last GLX buffer swap, \f$i\f$ is the
912680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * swap interval (as set by \c glXSwapIntervalSGI), and \f$t_r\f$ time
913680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * required for a single vertical refresh period (as returned by \c
914680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * glXGetMscRateOML).
915680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
916680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * See the documentation for the GLX_MESA_swap_frame_usage extension for more
917680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * details.
918680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
919680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param   dPriv  Pointer to the private drawable structure.
920680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \return  If less than a single swap interval time period was required
921680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          between GLX buffer swaps, a number greater than 0 and less than
922680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          1.0 is returned.  If exactly one swap interval time period is
923680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          required, 1.0 is returned, and if more than one is required then
924680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          a number greater than 1.0 will be returned.
925680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
926680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \sa glXSwapIntervalSGI glXGetMscRateOML
927680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
928680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \todo Instead of caching the \c glXGetMscRateOML function pointer, would it
929680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *       be possible to cache the sync rate?
930680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
931680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellfloat
932d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian HøgsbergdriCalculateSwapUsage( __DRIdrawable *dPriv, int64_t last_swap_ust,
933680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		       int64_t current_ust )
934680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
935680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int32_t   n;
936680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int32_t   d;
937680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int       interval;
938680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   float     usage = 1.0;
939d61f07318c8678901b948fdaa8ccdf37aa3203e9Kristian Høgsberg   __DRIscreen *psp = dPriv->driScreenPriv;
940680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
941e82dd8c6e1fa2fff5b960de26961080ba5e9651dKristian Høgsberg   if ( (*psp->systemTime->getMSCRate)(dPriv, &n, &d, dPriv->loaderPrivate) ) {
942efaf90b03e8b69e04909bce071f8ef6b65cc0e9dKristian Høgsberg      interval = (dPriv->swap_interval != 0) ? dPriv->swap_interval : 1;
943680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
944680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
945680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      /* We want to calculate
946680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * (current_UST - last_swap_UST) / (interval * us_per_refresh).  We get
947680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * current_UST by calling __glXGetUST.  last_swap_UST is stored in
948680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * dPriv->swap_ust.  interval has already been calculated.
949680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       *
950680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * The only tricky part is us_per_refresh.  us_per_refresh is
951680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * 1000000 / MSC_rate.  We know the MSC_rate is n / d.  We can flip it
952680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * around and say us_per_refresh = 1000000 * d / n.  Since this goes in
953680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * the denominator of the final calculation, we calculate
954680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * (interval * 1000000 * d) and move n into the numerator.
955680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       */
956680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
957680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage = (current_ust - last_swap_ust);
958680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage *= n;
959680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage /= (interval * d);
960680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage /= 1000000.0;
961680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   }
962680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
963680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   return usage;
964680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
965680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
96661d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerezvoid
96761d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerezdri2InvalidateDrawable(__DRIdrawable *drawable)
96861d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez{
96961d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez    drawable->dri2.stamp++;
97061d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez}
97161d26bc82e7c4100acfb551cbb0ba9d84bbc4ba5Francisco Jerez
972680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
973