| 203 | |
| 204 | |
| 205 | static bool buildVisAttribTable(Display *dpy, int screen) |
| 206 | { |
| 207 | int clientGLX = 0, majorOpcode = -1, firstEvent = -1, firstError = -1, |
| 208 | nVisuals = 0; |
| 209 | XVisualInfo *visuals = NULL, vtemp; |
| 210 | VisAttrib *va = NULL; |
| 211 | XEDataObject obj; |
| 212 | XExtData *extData; |
| 213 | obj.screen = XScreenOfDisplay(dpy, screen); |
| 214 | |
| 215 | if(!fconfig.egl && dpy == faker::dpy3D) |
| 216 | THROW("glxvisual::buildVisAttribTable() called with 3D X server handle (this should never happen)"); |
| 217 | |
| 218 | try |
| 219 | { |
| 220 | CriticalSection::SafeLock l(faker::getDisplayCS(dpy)); |
| 221 | |
| 222 | int minExtensionNumber = |
| 223 | XFindOnExtensionList(XEHeadOfExtensionList(obj), 0) ? 0 : 1; |
| 224 | extData = XFindOnExtensionList(XEHeadOfExtensionList(obj), |
| 225 | minExtensionNumber + 2); |
| 226 | if(extData && extData->private_data) return true; |
| 227 | |
| 228 | fconfig_setprobeglxfromdpy(dpy); |
| 229 | if(fconfig.probeglx |
| 230 | && _XQueryExtension(dpy, "GLX", &majorOpcode, &firstEvent, &firstError) |
| 231 | && majorOpcode >= 0 && firstEvent >= 0 && firstError >= 0) |
| 232 | { |
| 233 | if(fconfig.verbose) |
| 234 | vglout.println("[VGL] NOTICE: Probing 2D X server for stereo visuals"); |
| 235 | clientGLX = 1; |
| 236 | } |
| 237 | vtemp.screen = screen; |
| 238 | if(!(visuals = XGetVisualInfo(dpy, VisualScreenMask, &vtemp, &nVisuals)) |
| 239 | || nVisuals == 0) |
| 240 | THROW("No visuals found on display"); |
| 241 | |
| 242 | if(!(va = (VisAttrib *)calloc(nVisuals, sizeof(VisAttrib)))) |
| 243 | THROW("Memory allocation error"); |
| 244 | |
| 245 | for(int i = 0; i < nVisuals; i++) |
| 246 | { |
| 247 | va[i].visualID = visuals[i].visualid; |
| 248 | va[i].depth = visuals[i].depth; |
| 249 | va[i].c_class = visuals[i].c_class; |
| 250 | va[i].bpc = visuals[i].bits_per_rgb; |
| 251 | va[i].nVisuals = nVisuals; |
| 252 | va[i].score = -1; |
| 253 | |
| 254 | if(clientGLX) |
| 255 | { |
| 256 | _glXGetConfig(dpy, &visuals[i], GLX_DOUBLEBUFFER, &va[i].isDB); |
| 257 | _glXGetConfig(dpy, &visuals[i], GLX_USE_GL, &va[i].isGL); |
| 258 | _glXGetConfig(dpy, &visuals[i], GLX_STEREO, &va[i].isStereo); |
| 259 | // Simulate Chrome's ARGB visual selection mechanism, which |
| 260 | // unfortunately uses raw GLX requests/replies that VirtualGL cannot |
| 261 | // interpose. |
| 262 | if(fconfig.chromeHack && va[i].depth == 32 && va[i].bpc == 8 |
no test coverage detected