Merge remote branch 'origin/7.8'
[mesa.git] / src / mesa / drivers / dri / common / drisw_util.c
1 /*
2 * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
3 * All Rights Reserved.
4 * Copyright 2010 George Sapountzis <gsapountzis@gmail.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24 /**
25 * \file drisw_util.c
26 *
27 * DRISW utility functions, i.e. dri_util.c stripped from drm-specific bits.
28 */
29
30 #include "drisw_util.h"
31 #include "utils.h"
32
33
34 /**
35 * Screen functions
36 */
37
38 static void
39 setupLoaderExtensions(__DRIscreen *psp,
40 const __DRIextension **extensions)
41 {
42 int i;
43
44 for (i = 0; extensions[i]; i++) {
45 if (strcmp(extensions[i]->name, __DRI_SWRAST_LOADER) == 0)
46 psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i];
47 }
48 }
49
50 static __DRIscreen *
51 driCreateNewScreen(int scrn, const __DRIextension **extensions,
52 const __DRIconfig ***driver_configs, void *data)
53 {
54 static const __DRIextension *emptyExtensionList[] = { NULL };
55 __DRIscreen *psp;
56
57 (void) data;
58
59 psp = CALLOC_STRUCT(__DRIscreenRec);
60 if (!psp)
61 return NULL;
62
63 setupLoaderExtensions(psp, extensions);
64
65 psp->extensions = emptyExtensionList;
66 psp->fd = -1;
67 psp->myNum = scrn;
68
69 *driver_configs = driDriverAPI.InitScreen(psp);
70
71 if (*driver_configs == NULL) {
72 FREE(psp);
73 return NULL;
74 }
75
76 return psp;
77 }
78
79 static void driDestroyScreen(__DRIscreen *psp)
80 {
81 if (psp) {
82 driDriverAPI.DestroyScreen(psp);
83
84 FREE(psp);
85 }
86 }
87
88 static const __DRIextension **driGetExtensions(__DRIscreen *psp)
89 {
90 return psp->extensions;
91 }
92
93
94 /**
95 * Context functions
96 */
97
98 static __DRIcontext *
99 driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
100 __DRIcontext *shared, void *data)
101 {
102 __DRIcontext *pcp;
103 void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
104
105 pcp = CALLOC_STRUCT(__DRIcontextRec);
106 if (!pcp)
107 return NULL;
108
109 pcp->loaderPrivate = data;
110
111 pcp->driScreenPriv = psp;
112 pcp->driDrawablePriv = NULL;
113 pcp->driReadablePriv = NULL;
114
115 if (!driDriverAPI.CreateContext(&config->modes, pcp, shareCtx)) {
116 FREE(pcp);
117 return NULL;
118 }
119
120 return pcp;
121 }
122
123 static void
124 driDestroyContext(__DRIcontext *pcp)
125 {
126 if (pcp) {
127 driDriverAPI.DestroyContext(pcp);
128 FREE(pcp);
129 }
130 }
131
132 static int
133 driCopyContext(__DRIcontext *dst, __DRIcontext *src, unsigned long mask)
134 {
135 return GL_FALSE;
136 }
137
138 static void dri_get_drawable(__DRIdrawable *pdp);
139 static void dri_put_drawable(__DRIdrawable *pdp);
140
141 static int driBindContext(__DRIcontext *pcp,
142 __DRIdrawable *pdp,
143 __DRIdrawable *prp)
144 {
145 /* Bind the drawable to the context */
146 if (pcp) {
147 pcp->driDrawablePriv = pdp;
148 pcp->driReadablePriv = prp;
149 if (pdp) {
150 pdp->driContextPriv = pcp;
151 dri_get_drawable(pdp);
152 }
153 if ( prp && pdp != prp ) {
154 dri_get_drawable(prp);
155 }
156 }
157
158 return driDriverAPI.MakeCurrent(pcp, pdp, prp);
159 }
160
161 static int driUnbindContext(__DRIcontext *pcp)
162 {
163 __DRIdrawable *pdp;
164 __DRIdrawable *prp;
165
166 if (pcp == NULL)
167 return GL_FALSE;
168
169 pdp = pcp->driDrawablePriv;
170 prp = pcp->driReadablePriv;
171
172 /* already unbound */
173 if (!pdp && !prp)
174 return GL_TRUE;
175
176 driDriverAPI.UnbindContext(pcp);
177
178 dri_put_drawable(pdp);
179
180 if (prp != pdp) {
181 dri_put_drawable(prp);
182 }
183
184 pcp->driDrawablePriv = NULL;
185 pcp->driReadablePriv = NULL;
186
187 return GL_TRUE;
188 }
189
190
191 /**
192 * Drawable functions
193 */
194
195 static void dri_get_drawable(__DRIdrawable *pdp)
196 {
197 pdp->refcount++;
198 }
199
200 static void dri_put_drawable(__DRIdrawable *pdp)
201 {
202 if (pdp) {
203 pdp->refcount--;
204 if (pdp->refcount)
205 return;
206
207 driDriverAPI.DestroyBuffer(pdp);
208
209 FREE(pdp);
210 }
211 }
212
213 static __DRIdrawable *
214 driCreateNewDrawable(__DRIscreen *psp,
215 const __DRIconfig *config, void *data)
216 {
217 __DRIdrawable *pdp;
218
219 pdp = CALLOC_STRUCT(__DRIdrawableRec);
220 if (!pdp)
221 return NULL;
222
223 pdp->loaderPrivate = data;
224
225 pdp->driScreenPriv = psp;
226 pdp->driContextPriv = NULL;
227
228 dri_get_drawable(pdp);
229
230 if (!driDriverAPI.CreateBuffer(psp, pdp, &config->modes, GL_FALSE)) {
231 FREE(pdp);
232 return NULL;
233 }
234
235 pdp->lastStamp = 1; /* const */
236
237 return pdp;
238 }
239
240 static void
241 driDestroyDrawable(__DRIdrawable *pdp)
242 {
243 dri_put_drawable(pdp);
244 }
245
246 static void driSwapBuffers(__DRIdrawable *pdp)
247 {
248 driDriverAPI.SwapBuffers(pdp);
249 }
250
251 const __DRIcoreExtension driCoreExtension = {
252 { __DRI_CORE, __DRI_CORE_VERSION },
253 NULL, /* driCreateNewScreen */
254 driDestroyScreen,
255 driGetExtensions,
256 driGetConfigAttrib,
257 driIndexConfigAttrib,
258 NULL, /* driCreateNewDrawable */
259 driDestroyDrawable,
260 driSwapBuffers,
261 driCreateNewContext,
262 driCopyContext,
263 driDestroyContext,
264 driBindContext,
265 driUnbindContext
266 };
267
268 const __DRIswrastExtension driSWRastExtension = {
269 { __DRI_SWRAST, __DRI_SWRAST_VERSION },
270 driCreateNewScreen,
271 driCreateNewDrawable
272 };