Commit | Line | Data |
---|---|---|
a09e091a JB |
1 | /* |
2 | * Copyright (c) 2007, 2008 Apple Inc. | |
3 | * Copyright (c) 2004 Torrey T. Lyons. All Rights Reserved. | |
4 | * Copyright (c) 2002 Greg Parker. All Rights Reserved. | |
5 | * | |
6 | * Portions of this file are copied from Mesa's xf86glx.c, | |
7 | * which contains the following copyright: | |
8 | * | |
9 | * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. | |
10 | * All Rights Reserved. | |
11 | * | |
12 | * Permission is hereby granted, free of charge, to any person obtaining a | |
13 | * copy of this software and associated documentation files (the "Software"), | |
14 | * to deal in the Software without restriction, including without limitation | |
15 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
16 | * and/or sell copies of the Software, and to permit persons to whom the | |
17 | * Software is furnished to do so, subject to the following conditions: | |
18 | * | |
19 | * The above copyright notice and this permission notice shall be included in | |
20 | * all copies or substantial portions of the Software. | |
21 | * | |
22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
24 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
25 | * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
26 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
27 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
28 | * DEALINGS IN THE SOFTWARE. | |
29 | */ | |
30 | ||
31 | #ifdef HAVE_DIX_CONFIG_H | |
32 | #include <dix-config.h> | |
33 | #endif | |
34 | ||
35 | #include "dri.h" | |
36 | ||
37 | #include <OpenGL/OpenGL.h> | |
38 | #include <OpenGL/gl.h> | |
39 | #include <OpenGL/glext.h> | |
40 | #include <OpenGL/CGLContext.h> | |
41 | ||
42 | #include <GL/glxproto.h> | |
43 | #include <windowstr.h> | |
44 | #include <resource.h> | |
45 | #include <GL/glxint.h> | |
46 | #include <GL/glxtokens.h> | |
47 | #include <scrnintstr.h> | |
48 | #include <glxserver.h> | |
49 | #include <glxscreens.h> | |
50 | #include <glxdrawable.h> | |
51 | #include <glxcontext.h> | |
52 | #include <glxext.h> | |
53 | #include <glxutil.h> | |
54 | #include <GL/internal/glcore.h> | |
55 | ||
56 | #include "capabilities.h" | |
57 | #include "visualConfigs.h" | |
58 | #include "darwinfb.h" | |
59 | ||
60 | /* Based originally on code from indirect.c which was based on code from i830_dri.c. */ | |
61 | __GLXconfig *__glXAquaCreateVisualConfigs(int *numConfigsPtr, int screenNumber) { | |
62 | int numConfigs = 0; | |
63 | __GLXconfig *visualConfigs, *c; | |
64 | struct glCapabilities caps; | |
65 | struct glCapabilitiesConfig *conf; | |
66 | int stereo, depth, aux, buffers, stencil, accum, color, msample; | |
67 | ||
68 | if(getGlCapabilities(&caps)) { | |
69 | ErrorF("error from getGlCapabilities()!\n"); | |
70 | return NULL; | |
71 | } | |
72 | ||
73 | /* | |
74 | conf->stereo is 0 or 1, but we need at least 1 iteration of the loop, | |
75 | so we treat a true conf->stereo as 2. | |
76 | ||
77 | The depth size is 0 or 24. Thus we do 2 iterations for that. | |
78 | ||
79 | conf->aux_buffers (when available/non-zero) result in 2 iterations instead of 1. | |
80 | ||
81 | conf->buffers indicates whether we have single or double buffering. | |
82 | ||
83 | conf->total_stencil_bit_depths | |
84 | ||
85 | conf->total_color_buffers indicates the RGB/RGBA color depths. | |
86 | ||
87 | conf->total_accum_buffers iterations for accum (with at least 1 if equal to 0) | |
88 | ||
89 | conf->total_depth_buffer_depths | |
90 | ||
91 | conf->multisample_buffers iterations (with at least 1 if equal to 0). We add 1 | |
92 | for the 0 multisampling config. | |
93 | ||
94 | */ | |
95 | ||
96 | assert(NULL != caps.configurations); | |
97 | ||
98 | numConfigs = 0; | |
99 | ||
100 | for(conf = caps.configurations; conf; conf = conf->next) { | |
101 | if(conf->total_color_buffers <= 0) | |
102 | continue; | |
103 | ||
104 | numConfigs += (conf->stereo ? 2 : 1) | |
105 | * (conf->aux_buffers ? 2 : 1) | |
106 | * conf->buffers | |
107 | * ((conf->total_stencil_bit_depths > 0) ? conf->total_stencil_bit_depths : 1) | |
108 | * conf->total_color_buffers | |
109 | * ((conf->total_accum_buffers > 0) ? conf->total_accum_buffers : 1) | |
110 | * conf->total_depth_buffer_depths | |
111 | * (conf->multisample_buffers + 1); | |
112 | } | |
113 | ||
114 | if(numConfigsPtr) | |
115 | *numConfigsPtr = numConfigs; | |
116 | ||
117 | visualConfigs = calloc(sizeof(*visualConfigs), numConfigs); | |
118 | ||
119 | if(NULL == visualConfigs) { | |
120 | ErrorF("xcalloc failure when allocating visualConfigs\n"); | |
121 | freeGlCapabilities(&caps); | |
122 | return NULL; | |
123 | } | |
124 | ||
125 | c = visualConfigs; /* current buffer */ | |
126 | for(conf = caps.configurations; conf; conf = conf->next) { | |
127 | for(stereo = 0; stereo < (conf->stereo ? 2 : 1); ++stereo) { | |
128 | for(aux = 0; aux < (conf->aux_buffers ? 2 : 1); ++aux) { | |
129 | for(buffers = 0; buffers < conf->buffers; ++buffers) { | |
130 | for(stencil = 0; stencil < ((conf->total_stencil_bit_depths > 0) ? | |
131 | conf->total_stencil_bit_depths : 1); ++stencil) { | |
132 | for(color = 0; color < conf->total_color_buffers; ++color) { | |
133 | for(accum = 0; accum < ((conf->total_accum_buffers > 0) ? | |
134 | conf->total_accum_buffers : 1); ++accum) { | |
135 | for(depth = 0; depth < conf->total_depth_buffer_depths; ++depth) { | |
136 | for(msample = 0; msample < (conf->multisample_buffers + 1); ++msample) { | |
137 | ||
138 | // Global | |
139 | c->visualID = -1; | |
140 | c->visualType = GLX_TRUE_COLOR; | |
141 | c->next = c + 1; | |
142 | ||
143 | c->level = 0; | |
144 | c->indexBits = 0; | |
145 | ||
146 | if(conf->accelerated) { | |
147 | c->visualRating = GLX_NONE; | |
148 | } else { | |
149 | c->visualRating = GLX_SLOW_VISUAL_EXT; | |
150 | } | |
151 | ||
152 | c->transparentPixel = GLX_NONE; | |
153 | c->transparentRed = GLX_NONE; | |
154 | c->transparentGreen = GLX_NONE; | |
155 | c->transparentBlue = GLX_NONE; | |
156 | c->transparentAlpha = GLX_NONE; | |
157 | c->transparentIndex = GLX_NONE; | |
158 | ||
159 | c->visualSelectGroup = 0; | |
160 | ||
161 | c->swapMethod = GLX_SWAP_UNDEFINED_OML; | |
162 | ||
163 | // Stereo | |
164 | c->stereoMode = stereo ? TRUE : FALSE; | |
165 | ||
166 | // Aux buffers | |
167 | c->numAuxBuffers = aux ? conf->aux_buffers : 0; | |
168 | ||
169 | // Double Buffered | |
170 | c->doubleBufferMode = buffers ? TRUE : FALSE; | |
171 | ||
172 | // Stencil Buffer | |
173 | if(conf->total_stencil_bit_depths > 0) { | |
174 | c->stencilBits = conf->stencil_bit_depths[stencil]; | |
175 | } else { | |
176 | c->stencilBits = 0; | |
177 | } | |
178 | ||
179 | // Color | |
180 | if(GLCAPS_COLOR_BUF_INVALID_VALUE != conf->color_buffers[color].a) { | |
181 | c->alphaBits = conf->color_buffers[color].a; | |
182 | } else { | |
183 | c->alphaBits = 0; | |
184 | } | |
185 | c->redBits = conf->color_buffers[color].r; | |
186 | c->greenBits = conf->color_buffers[color].g; | |
187 | c->blueBits = conf->color_buffers[color].b; | |
188 | ||
189 | c->rgbBits = c->alphaBits + c->redBits + c->greenBits + c->blueBits; | |
190 | ||
191 | c->alphaMask = AM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits); | |
192 | c->redMask = RM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits); | |
193 | c->greenMask = GM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits); | |
194 | c->blueMask = BM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits); | |
195 | ||
196 | // Accumulation Buffers | |
197 | if(conf->total_accum_buffers > 0) { | |
198 | c->accumRedBits = conf->accum_buffers[accum].r; | |
199 | c->accumGreenBits = conf->accum_buffers[accum].g; | |
200 | c->accumBlueBits = conf->accum_buffers[accum].b; | |
201 | if(GLCAPS_COLOR_BUF_INVALID_VALUE != conf->accum_buffers[accum].a) { | |
202 | c->accumAlphaBits = conf->accum_buffers[accum].a; | |
203 | } else { | |
204 | c->accumAlphaBits = 0; | |
205 | } | |
206 | } else { | |
207 | c->accumRedBits = 0; | |
208 | c->accumGreenBits = 0; | |
209 | c->accumBlueBits = 0; | |
210 | c->accumAlphaBits = 0; | |
211 | } | |
212 | ||
213 | // Depth | |
214 | c->depthBits = conf->depth_buffers[depth]; | |
215 | ||
216 | // MultiSample | |
217 | if(msample > 0) { | |
218 | c->samples = conf->multisample_samples; | |
219 | c->sampleBuffers = conf->multisample_buffers; | |
220 | } else { | |
221 | c->samples = 0; | |
222 | c->sampleBuffers = 0; | |
223 | } | |
224 | ||
225 | /* | |
226 | * The Apple libGL supports GLXPixmaps and | |
227 | * GLXPbuffers in direct mode. | |
228 | */ | |
229 | /* SGIX_fbconfig / GLX 1.3 */ | |
230 | c->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; | |
231 | c->renderType = GLX_RGBA_BIT; | |
232 | c->xRenderable = GL_TRUE; | |
233 | c->fbconfigID = -1; | |
234 | ||
235 | /* SGIX_pbuffer / GLX 1.3 */ | |
236 | ||
237 | /* | |
238 | * The CGL layer provides a way of retrieving | |
239 | * the maximum pbuffer width/height, but only | |
240 | * if we create a context and call glGetIntegerv. | |
241 | * | |
242 | * The following values are from a test program | |
243 | * that does so. | |
244 | */ | |
245 | c->maxPbufferWidth = 8192; | |
246 | c->maxPbufferHeight = 8192; | |
247 | c->maxPbufferPixels = /*Do we need this?*/ 0; | |
248 | /* | |
249 | * There is no introspection for this sort of thing | |
250 | * with CGL. What should we do realistically? | |
251 | */ | |
252 | c->optimalPbufferWidth = 0; | |
253 | c->optimalPbufferHeight = 0; | |
254 | ||
255 | /* EXT_texture_from_pixmap */ | |
256 | c->bindToTextureRgb = 0; | |
257 | c->bindToTextureRgba = 0; | |
258 | c->bindToMipmapTexture = 0; | |
259 | c->bindToTextureTargets = 0; | |
260 | c->yInverted = 0; | |
261 | ||
262 | /* EXT_framebuffer_sRGB */ | |
263 | c->sRGBCapable = GL_FALSE; | |
264 | ||
265 | c = c->next; | |
266 | } | |
267 | } | |
268 | } | |
269 | } | |
270 | } | |
271 | } | |
272 | } | |
273 | } | |
274 | } | |
275 | ||
276 | (c-1)->next = NULL; | |
277 | ||
278 | if (c - visualConfigs != numConfigs) { | |
279 | FatalError("numConfigs calculation error in setVisualConfigs! numConfigs is %d i is %d\n", numConfigs, (int)(c - visualConfigs)); | |
280 | } | |
281 | ||
282 | freeGlCapabilities(&caps); | |
283 | return visualConfigs; | |
284 | } |