1 |
|
---|
2 | #include "chromium.h"
|
---|
3 | #include "cr_spu.h"
|
---|
4 | #include "cr_error.h"
|
---|
5 | #include "cr_string.h"
|
---|
6 |
|
---|
7 |
|
---|
8 | /**
|
---|
9 | * Wrappers for glXChooseVisual/etc.
|
---|
10 | *
|
---|
11 | * By using this function, the fake GLX, render SPU, tilesort SPU,
|
---|
12 | * etc can be assured of getting the same GLX visual for a set of CR_*_BIT
|
---|
13 | * visual flags. This helps ensure that render_to_app_window will work
|
---|
14 | * properly.
|
---|
15 | */
|
---|
16 |
|
---|
17 |
|
---|
18 | #if defined(WINDOWS)
|
---|
19 | int
|
---|
20 | crChooseVisual(const crOpenGLInterface *ws, int visBits)
|
---|
21 | {
|
---|
22 | /* placeholder */
|
---|
23 | return 0;
|
---|
24 | }
|
---|
25 | #endif
|
---|
26 |
|
---|
27 |
|
---|
28 | #if defined(DARWIN)
|
---|
29 | int
|
---|
30 | crChooseVisual(const crOpenGLInterface *ws, int visBits)
|
---|
31 | {
|
---|
32 | /* placeholder */
|
---|
33 | return 0;
|
---|
34 | }
|
---|
35 | #endif
|
---|
36 |
|
---|
37 |
|
---|
38 | #if defined(GLX)
|
---|
39 |
|
---|
40 | XVisualInfo *
|
---|
41 | crChooseVisual(const crOpenGLInterface *ws, Display *dpy, int screen,
|
---|
42 | GLboolean directColor, int visBits)
|
---|
43 | {
|
---|
44 | XVisualInfo *vis;
|
---|
45 | int errorBase, eventBase;
|
---|
46 |
|
---|
47 | if (ws->glXQueryExtension(dpy, &errorBase, &eventBase))
|
---|
48 | {
|
---|
49 |
|
---|
50 | if (ws->glXChooseVisual)
|
---|
51 | {
|
---|
52 | /* Use the real OpenGL's glXChooseVisual function */
|
---|
53 | int attribList[100];
|
---|
54 | int i = 0;
|
---|
55 |
|
---|
56 | /* Build the attribute list */
|
---|
57 | if (visBits & CR_RGB_BIT)
|
---|
58 | {
|
---|
59 | attribList[i++] = GLX_RGBA;
|
---|
60 | attribList[i++] = GLX_RED_SIZE;
|
---|
61 | attribList[i++] = 1;
|
---|
62 | attribList[i++] = GLX_GREEN_SIZE;
|
---|
63 | attribList[i++] = 1;
|
---|
64 | attribList[i++] = GLX_BLUE_SIZE;
|
---|
65 | attribList[i++] = 1;
|
---|
66 | }
|
---|
67 |
|
---|
68 | if (visBits & CR_ALPHA_BIT)
|
---|
69 | {
|
---|
70 | attribList[i++] = GLX_ALPHA_SIZE;
|
---|
71 | attribList[i++] = 1;
|
---|
72 | }
|
---|
73 |
|
---|
74 | if (visBits & CR_DOUBLE_BIT)
|
---|
75 | {
|
---|
76 | attribList[i++] = GLX_DOUBLEBUFFER;
|
---|
77 | }
|
---|
78 |
|
---|
79 | if (visBits & CR_STEREO_BIT)
|
---|
80 | {
|
---|
81 | attribList[i++] = GLX_STEREO;
|
---|
82 | }
|
---|
83 |
|
---|
84 | if (visBits & CR_DEPTH_BIT)
|
---|
85 | {
|
---|
86 | attribList[i++] = GLX_DEPTH_SIZE;
|
---|
87 | attribList[i++] = 1;
|
---|
88 | }
|
---|
89 |
|
---|
90 | if (visBits & CR_STENCIL_BIT)
|
---|
91 | {
|
---|
92 | attribList[i++] = GLX_STENCIL_SIZE;
|
---|
93 | attribList[i++] = 1;
|
---|
94 | }
|
---|
95 |
|
---|
96 | if (visBits & CR_ACCUM_BIT)
|
---|
97 | {
|
---|
98 | attribList[i++] = GLX_ACCUM_RED_SIZE;
|
---|
99 | attribList[i++] = 1;
|
---|
100 | attribList[i++] = GLX_ACCUM_GREEN_SIZE;
|
---|
101 | attribList[i++] = 1;
|
---|
102 | attribList[i++] = GLX_ACCUM_BLUE_SIZE;
|
---|
103 | attribList[i++] = 1;
|
---|
104 | if (visBits & CR_ALPHA_BIT)
|
---|
105 | {
|
---|
106 | attribList[i++] = GLX_ACCUM_ALPHA_SIZE;
|
---|
107 | attribList[i++] = 1;
|
---|
108 | }
|
---|
109 | }
|
---|
110 |
|
---|
111 | if (visBits & CR_MULTISAMPLE_BIT)
|
---|
112 | {
|
---|
113 | attribList[i++] = GLX_SAMPLE_BUFFERS_SGIS;
|
---|
114 | attribList[i++] = 1;
|
---|
115 | attribList[i++] = GLX_SAMPLES_SGIS;
|
---|
116 | attribList[i++] = 4;
|
---|
117 | }
|
---|
118 |
|
---|
119 | if (visBits & CR_OVERLAY_BIT)
|
---|
120 | {
|
---|
121 | attribList[i++] = GLX_LEVEL;
|
---|
122 | attribList[i++] = 1;
|
---|
123 | }
|
---|
124 |
|
---|
125 | if (directColor)
|
---|
126 | {
|
---|
127 | /*
|
---|
128 | * See if we have have GLX_EXT_visual_info so we
|
---|
129 | * can grab a Direct Color visual
|
---|
130 | */
|
---|
131 | #ifdef GLX_EXT_visual_info
|
---|
132 | if (crStrstr(ws->glXQueryExtensionsString(dpy, screen),
|
---|
133 | "GLX_EXT_visual_info"))
|
---|
134 | {
|
---|
135 | attribList[i++] = GLX_X_VISUAL_TYPE_EXT;
|
---|
136 | attribList[i++] = GLX_DIRECT_COLOR_EXT;
|
---|
137 | }
|
---|
138 | #endif
|
---|
139 | }
|
---|
140 |
|
---|
141 | /* End the list */
|
---|
142 | attribList[i++] = None;
|
---|
143 |
|
---|
144 | vis = ws->glXChooseVisual(dpy, screen, attribList);
|
---|
145 | return vis;
|
---|
146 | }
|
---|
147 | else
|
---|
148 | {
|
---|
149 | /* Don't use glXChooseVisual, use glXGetConfig.
|
---|
150 | *
|
---|
151 | * Here's the deal:
|
---|
152 | * Some (all?) versions of the libGL.so that's shipped with ATI's
|
---|
153 | * drivers aren't built with the -Bsymbolic flag. That's bad.
|
---|
154 | *
|
---|
155 | * If we call the glXChooseVisual() function that's built into ATI's
|
---|
156 | * libGL, it in turn calls the glXGetConfig() function. Now, there's
|
---|
157 | * a glXGetConfig function in libGL.so **AND** there's a glXGetConfig
|
---|
158 | * function in Chromium's libcrfaker.so library. Unfortunately, the
|
---|
159 | * later one gets called instead of the former. At this point, things
|
---|
160 | * go haywire. If -Bsymbolic were used, this would not happen.
|
---|
161 | */
|
---|
162 | XVisualInfo templateVis;
|
---|
163 | long templateFlags;
|
---|
164 | int count, i, visType;
|
---|
165 |
|
---|
166 | visType = directColor ? DirectColor : TrueColor;
|
---|
167 |
|
---|
168 | /* Get list of candidate visuals */
|
---|
169 | templateFlags = VisualScreenMask | VisualClassMask;
|
---|
170 | templateVis.screen = screen;
|
---|
171 | #if defined(__cplusplus) || defined(c_plusplus)
|
---|
172 | templateVis.c_class = visType;
|
---|
173 | #else
|
---|
174 | templateVis.class = visType;
|
---|
175 | #endif
|
---|
176 |
|
---|
177 | vis = XGetVisualInfo(dpy, templateFlags, &templateVis, &count);
|
---|
178 | /* find first visual that's good enough */
|
---|
179 | for (i = 0; i < count; i++)
|
---|
180 | {
|
---|
181 | int val;
|
---|
182 |
|
---|
183 | /* Need exact match on RGB, DOUBLEBUFFER, STEREO, LEVEL, MULTISAMPLE */
|
---|
184 | ws->glXGetConfig(dpy, vis + i, GLX_RGBA, &val);
|
---|
185 | if (((visBits & CR_RGB_BIT) && !val) ||
|
---|
186 | (((visBits & CR_RGB_BIT) == 0) && val))
|
---|
187 | {
|
---|
188 | continue;
|
---|
189 | }
|
---|
190 |
|
---|
191 | ws->glXGetConfig(dpy, vis + i, GLX_DOUBLEBUFFER, &val);
|
---|
192 | if (((visBits & CR_DOUBLE_BIT) && !val) ||
|
---|
193 | (((visBits & CR_DOUBLE_BIT) == 0) && val))
|
---|
194 | {
|
---|
195 | continue;
|
---|
196 | }
|
---|
197 |
|
---|
198 | ws->glXGetConfig(dpy, vis + i, GLX_STEREO, &val);
|
---|
199 | if (((visBits & CR_STEREO_BIT) && !val) ||
|
---|
200 | (((visBits & CR_STEREO_BIT) == 0) && val))
|
---|
201 | {
|
---|
202 | continue;
|
---|
203 | }
|
---|
204 |
|
---|
205 | ws->glXGetConfig(dpy, vis + i, GLX_LEVEL, &val);
|
---|
206 | if (((visBits & CR_OVERLAY_BIT) && !val) ||
|
---|
207 | (((visBits & CR_OVERLAY_BIT) == 0) && val))
|
---|
208 | {
|
---|
209 | continue;
|
---|
210 | }
|
---|
211 |
|
---|
212 | ws->glXGetConfig(dpy, vis + i, GLX_SAMPLE_BUFFERS_SGIS, &val);
|
---|
213 | if (visBits & CR_MULTISAMPLE_BIT)
|
---|
214 | {
|
---|
215 | if (!val)
|
---|
216 | continue;
|
---|
217 | ws->glXGetConfig(dpy, vis + i, GLX_SAMPLES_SGIS, &val);
|
---|
218 | if (val < 4)
|
---|
219 | continue;
|
---|
220 | }
|
---|
221 | else {
|
---|
222 | /* don't want multisample */
|
---|
223 | if (val)
|
---|
224 | continue;
|
---|
225 | }
|
---|
226 |
|
---|
227 | /* Need good enough for ALPHA, DEPTH, STENCIL, ACCUM */
|
---|
228 | if (visBits & CR_ALPHA_BIT)
|
---|
229 | {
|
---|
230 | ws->glXGetConfig(dpy, vis + i, GLX_ALPHA_SIZE, &val);
|
---|
231 | if (!val)
|
---|
232 | continue;
|
---|
233 | }
|
---|
234 |
|
---|
235 | if (visBits & CR_DEPTH_BIT)
|
---|
236 | {
|
---|
237 | ws->glXGetConfig(dpy, vis + i, GLX_DEPTH_SIZE, &val);
|
---|
238 | if (!val)
|
---|
239 | continue;
|
---|
240 | }
|
---|
241 |
|
---|
242 | if (visBits & CR_STENCIL_BIT)
|
---|
243 | {
|
---|
244 | ws->glXGetConfig(dpy, vis + i, GLX_STENCIL_SIZE, &val);
|
---|
245 | if (!val)
|
---|
246 | continue;
|
---|
247 | }
|
---|
248 |
|
---|
249 | if (visBits & CR_ACCUM_BIT)
|
---|
250 | {
|
---|
251 | ws->glXGetConfig(dpy, vis + i, GLX_ACCUM_RED_SIZE, &val);
|
---|
252 | if (!val)
|
---|
253 | continue;
|
---|
254 | if (visBits & CR_ALPHA_BIT)
|
---|
255 | {
|
---|
256 | ws->glXGetConfig(dpy, vis + i, GLX_ACCUM_ALPHA_SIZE, &val);
|
---|
257 | if (!val)
|
---|
258 | continue;
|
---|
259 | }
|
---|
260 | }
|
---|
261 |
|
---|
262 | /* If we get here, we found a good visual.
|
---|
263 | * Now, we need to get a new XVisualInfo pointer in case the caller
|
---|
264 | * calls XFree on it.
|
---|
265 | */
|
---|
266 | templateFlags = VisualScreenMask | VisualIDMask;
|
---|
267 | templateVis.screen = screen;
|
---|
268 | templateVis.visualid = vis[i].visual->visualid;
|
---|
269 | XFree(vis); /* free the list */
|
---|
270 | vis = XGetVisualInfo(dpy, templateFlags, &templateVis, &count);
|
---|
271 | return vis;
|
---|
272 | }
|
---|
273 |
|
---|
274 | /* if we get here, we failed to find a sufficient visual */
|
---|
275 | return NULL;
|
---|
276 | }
|
---|
277 | }
|
---|
278 | else
|
---|
279 | {
|
---|
280 | /* use Xlib instead of GLX */
|
---|
281 | XVisualInfo templateVis, *best;
|
---|
282 | long templateFlags;
|
---|
283 | int i, count, visType;
|
---|
284 |
|
---|
285 | if (visBits & CR_RGB_BIT)
|
---|
286 | visType = directColor ? DirectColor : TrueColor;
|
---|
287 | else
|
---|
288 | visType = PseudoColor;
|
---|
289 |
|
---|
290 | /* Get list of candidate visuals */
|
---|
291 | templateFlags = VisualScreenMask | VisualClassMask;
|
---|
292 | templateVis.screen = screen;
|
---|
293 | #if defined(__cplusplus) || defined(c_plusplus)
|
---|
294 | templateVis.c_class = visType;
|
---|
295 | #else
|
---|
296 | templateVis.class = visType;
|
---|
297 | #endif
|
---|
298 |
|
---|
299 | vis = XGetVisualInfo(dpy, templateFlags, &templateVis, &count);
|
---|
300 | if (!vis)
|
---|
301 | return NULL;
|
---|
302 |
|
---|
303 | /* okay, select the RGB visual with the most depth */
|
---|
304 | best = vis + 0;
|
---|
305 | for (i = 1; i < count; i++)
|
---|
306 | {
|
---|
307 | if (vis[i].depth > best->depth &&
|
---|
308 | vis[i].bits_per_rgb > best->bits_per_rgb )
|
---|
309 | best = vis + i;
|
---|
310 | }
|
---|
311 |
|
---|
312 | if (best)
|
---|
313 | {
|
---|
314 | /* If we get here, we found a good visual.
|
---|
315 | * Now, we need to get a new XVisualInfo pointer in case the caller
|
---|
316 | * calls XFree on it.
|
---|
317 | */
|
---|
318 | templateFlags = VisualScreenMask | VisualIDMask;
|
---|
319 | templateVis.screen = screen;
|
---|
320 | templateVis.visualid = best->visualid;
|
---|
321 | XFree(vis); /* free the list */
|
---|
322 | best = XGetVisualInfo(dpy, templateFlags, &templateVis, &count);
|
---|
323 | }
|
---|
324 |
|
---|
325 | return best;
|
---|
326 | }
|
---|
327 | }
|
---|
328 |
|
---|
329 | #endif /* GLX */
|
---|