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