Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/*
2
 * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
3
 * All Rights Reserved.
4
 * Copyright 2010 George Sapountzis 
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
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
 * OTHER DEALINGS IN THE SOFTWARE.
23
 */
24
 
25
/**
26
 * \file drisw_util.c
27
 *
28
 * DRISW utility functions, i.e. dri_util.c stripped from drm-specific bits.
29
 */
30
 
31
#include "dri_util.h"
32
#include "utils.h"
33
 
34
 
35
/**
36
 * Screen functions
37
 */
38
 
39
static void
40
setupLoaderExtensions(__DRIscreen *psp,
41
		      const __DRIextension **extensions)
42
{
43
    int i;
44
 
45
    for (i = 0; extensions[i]; i++) {
46
	if (strcmp(extensions[i]->name, __DRI_SWRAST_LOADER) == 0)
47
	    psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i];
48
    }
49
}
50
 
51
static __DRIscreen *
52
driCreateNewScreen(int scrn, const __DRIextension **extensions,
53
		   const __DRIconfig ***driver_configs, void *data)
54
{
55
    static const __DRIextension *emptyExtensionList[] = { NULL };
56
    __DRIscreen *psp;
57
 
58
    psp = CALLOC_STRUCT(__DRIscreenRec);
59
    if (!psp)
60
	return NULL;
61
 
62
    setupLoaderExtensions(psp, extensions);
63
 
64
    psp->loaderPrivate = data;
65
 
66
    psp->extensions = emptyExtensionList;
67
    psp->fd = -1;
68
    psp->myNum = scrn;
69
 
70
    *driver_configs = driDriverAPI.InitScreen(psp);
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
	free(psp);
84
    }
85
}
86
 
87
static const __DRIextension **driGetExtensions(__DRIscreen *psp)
88
{
89
    return psp->extensions;
90
}
91
 
92
 
93
/**
94
 * Context functions
95
 */
96
 
97
static __DRIcontext *
98
driCreateContextAttribs(__DRIscreen *screen, int api,
99
			const __DRIconfig *config,
100
			__DRIcontext *shared,
101
			unsigned num_attribs,
102
			const uint32_t *attribs,
103
			unsigned *error,
104
			void *data)
105
{
106
    __DRIcontext *pcp;
107
    const struct gl_config *modes = (config != NULL) ? &config->modes : NULL;
108
    void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
109
    gl_api mesa_api;
110
    unsigned major_version = 1;
111
    unsigned minor_version = 0;
112
    uint32_t flags = 0;
113
 
114
    /* Either num_attribs is zero and attribs is NULL, or num_attribs is not
115
     * zero and attribs is not NULL.
116
     */
117
    assert((num_attribs == 0) == (attribs == NULL));
118
 
119
    switch (api) {
120
    case __DRI_API_OPENGL:
121
            mesa_api = API_OPENGL_COMPAT;
122
            break;
123
    case __DRI_API_GLES:
124
            mesa_api = API_OPENGLES;
125
            break;
126
    case __DRI_API_GLES2:
127
    case __DRI_API_GLES3:
128
            mesa_api = API_OPENGLES2;
129
            break;
130
    case __DRI_API_OPENGL_CORE:
131
            mesa_api = API_OPENGL_CORE;
132
            break;
133
    default:
134
            *error = __DRI_CTX_ERROR_BAD_API;
135
            return NULL;
136
    }
137
 
138
    for (unsigned i = 0; i < num_attribs; i++) {
139
	switch (attribs[i * 2]) {
140
	case __DRI_CTX_ATTRIB_MAJOR_VERSION:
141
	    major_version = attribs[i * 2 + 1];
142
	    break;
143
	case __DRI_CTX_ATTRIB_MINOR_VERSION:
144
	    minor_version = attribs[i * 2 + 1];
145
	    break;
146
	case __DRI_CTX_ATTRIB_FLAGS:
147
	    flags = attribs[i * 2 + 1];
148
	    break;
149
	default:
150
	    /* We can't create a context that satisfies the requirements of an
151
	     * attribute that we don't understand.  Return failure.
152
	     */
153
	    return NULL;
154
	}
155
    }
156
 
157
    /* Mesa does not support the GL_ARB_compatibilty extension or the
158
     * compatibility profile.  This means that we treat a API_OPENGL_COMPAT 3.1 as
159
     * API_OPENGL_CORE and reject API_OPENGL_COMPAT 3.2+.
160
     */
161
    if (mesa_api == API_OPENGL_COMPAT && major_version == 3 && minor_version == 1)
162
       mesa_api = API_OPENGL_CORE;
163
 
164
    if (mesa_api == API_OPENGL_COMPAT
165
        && ((major_version > 3)
166
            || (major_version == 3 && minor_version >= 2))) {
167
       *error = __DRI_CTX_ERROR_BAD_API;
168
       return NULL;
169
    }
170
    /* There are no forward-compatible contexts before OpenGL 3.0.  The
171
     * GLX_ARB_create_context spec says:
172
     *
173
     *     "Forward-compatible contexts are defined only for OpenGL versions
174
     *     3.0 and later."
175
     *
176
     * Moreover, Mesa can't fulfill the requirements of a forward-looking
177
     * context.  Return failure if a forward-looking context is requested.
178
     *
179
     * In Mesa, a debug context is the same as a regular context.
180
     */
181
    if (major_version >= 3) {
182
	if ((flags & ~__DRI_CTX_FLAG_DEBUG) != 0)
183
	    return NULL;
184
    }
185
 
186
    pcp = CALLOC_STRUCT(__DRIcontextRec);
187
    if (!pcp)
188
        return NULL;
189
 
190
    pcp->loaderPrivate = data;
191
 
192
    pcp->driScreenPriv = screen;
193
    pcp->driDrawablePriv = NULL;
194
    pcp->driReadablePriv = NULL;
195
 
196
    if (!driDriverAPI.CreateContext(mesa_api, modes, pcp,
197
				    major_version, minor_version,
198
				    flags, error, shareCtx)) {
199
        free(pcp);
200
        return NULL;
201
    }
202
 
203
    return pcp;
204
}
205
 
206
static __DRIcontext *
207
driCreateNewContextForAPI(__DRIscreen *psp, int api,
208
                          const __DRIconfig *config,
209
                          __DRIcontext *shared, void *data)
210
{
211
    unsigned error;
212
 
213
    return driCreateContextAttribs(psp, api, config, shared, 0, NULL,
214
				   &error, data);
215
}
216
 
217
static __DRIcontext *
218
driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
219
		    __DRIcontext *shared, void *data)
220
{
221
    return driCreateNewContextForAPI(psp, __DRI_API_OPENGL,
222
				     config, shared, data);
223
}
224
 
225
static void
226
driDestroyContext(__DRIcontext *pcp)
227
{
228
    if (pcp) {
229
	driDriverAPI.DestroyContext(pcp);
230
	free(pcp);
231
    }
232
}
233
 
234
static int
235
driCopyContext(__DRIcontext *dst, __DRIcontext *src, unsigned long mask)
236
{
237
    return GL_FALSE;
238
}
239
 
240
static void dri_get_drawable(__DRIdrawable *pdp);
241
static void dri_put_drawable(__DRIdrawable *pdp);
242
 
243
static int driBindContext(__DRIcontext *pcp,
244
			  __DRIdrawable *pdp,
245
			  __DRIdrawable *prp)
246
{
247
    /* Bind the drawable to the context */
248
    if (pcp) {
249
	pcp->driDrawablePriv = pdp;
250
	pcp->driReadablePriv = prp;
251
	if (pdp) {
252
	    pdp->driContextPriv = pcp;
253
	    dri_get_drawable(pdp);
254
	}
255
	if (prp && pdp != prp) {
256
	    dri_get_drawable(prp);
257
	}
258
    }
259
 
260
    return driDriverAPI.MakeCurrent(pcp, pdp, prp);
261
}
262
 
263
static int driUnbindContext(__DRIcontext *pcp)
264
{
265
    __DRIdrawable *pdp;
266
    __DRIdrawable *prp;
267
 
268
    if (pcp == NULL)
269
	return GL_FALSE;
270
 
271
    pdp = pcp->driDrawablePriv;
272
    prp = pcp->driReadablePriv;
273
 
274
    /* already unbound */
275
    if (!pdp && !prp)
276
	return GL_TRUE;
277
 
278
    driDriverAPI.UnbindContext(pcp);
279
 
280
    dri_put_drawable(pdp);
281
 
282
    if (prp != pdp) {
283
	dri_put_drawable(prp);
284
    }
285
 
286
    pcp->driDrawablePriv = NULL;
287
    pcp->driReadablePriv = NULL;
288
 
289
    return GL_TRUE;
290
}
291
 
292
 
293
/**
294
 * Drawable functions
295
 */
296
 
297
static void dri_get_drawable(__DRIdrawable *pdp)
298
{
299
    pdp->refcount++;
300
}
301
 
302
static void dri_put_drawable(__DRIdrawable *pdp)
303
{
304
    if (pdp) {
305
	pdp->refcount--;
306
	if (pdp->refcount)
307
	    return;
308
 
309
	driDriverAPI.DestroyBuffer(pdp);
310
	free(pdp);
311
    }
312
}
313
 
314
static __DRIdrawable *
315
driCreateNewDrawable(__DRIscreen *psp,
316
		     const __DRIconfig *config, void *data)
317
{
318
    __DRIdrawable *pdp;
319
 
320
    pdp = CALLOC_STRUCT(__DRIdrawableRec);
321
    if (!pdp)
322
	return NULL;
323
 
324
    pdp->loaderPrivate = data;
325
 
326
    pdp->driScreenPriv = psp;
327
    pdp->driContextPriv = NULL;
328
 
329
    dri_get_drawable(pdp);
330
 
331
    if (!driDriverAPI.CreateBuffer(psp, pdp, &config->modes, GL_FALSE)) {
332
	free(pdp);
333
	return NULL;
334
    }
335
 
336
    pdp->lastStamp = 1; /* const */
337
 
338
    return pdp;
339
}
340
 
341
static void
342
driDestroyDrawable(__DRIdrawable *pdp)
343
{
344
    dri_put_drawable(pdp);
345
}
346
 
347
static void driSwapBuffers(__DRIdrawable *pdp)
348
{
349
    driDriverAPI.SwapBuffers(pdp);
350
}
351
 
352
const __DRIcoreExtension driCoreExtension = {
353
    { __DRI_CORE, __DRI_CORE_VERSION },
354
    NULL, /* driCreateNewScreen */
355
    driDestroyScreen,
356
    driGetExtensions,
357
    driGetConfigAttrib,
358
    driIndexConfigAttrib,
359
    NULL, /* driCreateNewDrawable */
360
    driDestroyDrawable,
361
    driSwapBuffers,
362
    driCreateNewContext,
363
    driCopyContext,
364
    driDestroyContext,
365
    driBindContext,
366
    driUnbindContext
367
};
368
 
369
const __DRIswrastExtension driSWRastExtension = {
370
    { __DRI_SWRAST, __DRI_SWRAST_VERSION },
371
    driCreateNewScreen,
372
    driCreateNewDrawable,
373
    driCreateNewContextForAPI,
374
    driCreateContextAttribs
375
};