00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "glxGraphicsStateGuardian.h"
00016 #include "config_glxdisplay.h"
00017 #include "config_glgsg.h"
00018 #include "lightReMutexHolder.h"
00019
00020 #include <dlfcn.h>
00021
00022
00023 TypeHandle glxGraphicsStateGuardian::_type_handle;
00024
00025
00026
00027
00028
00029
00030 glxGraphicsStateGuardian::
00031 glxGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
00032 glxGraphicsStateGuardian *share_with) :
00033 PosixGraphicsStateGuardian(engine, pipe)
00034 {
00035 _share_context=0;
00036 _context=0;
00037 _display=0;
00038 _screen=0;
00039 _visual=0;
00040 _visuals=0;
00041 _fbconfig=0;
00042 _context_has_pbuffer = false;
00043 _context_has_pixmap = false;
00044 _slow = false;
00045
00046 _supports_swap_control = false;
00047 _supports_fbconfig = false;
00048 _supports_pbuffer = false;
00049 _uses_sgix_pbuffer = false;
00050
00051 if (share_with != (glxGraphicsStateGuardian *)NULL) {
00052 _prepared_objects = share_with->get_prepared_objects();
00053 _share_context = share_with->_context;
00054 }
00055
00056 _checked_get_proc_address = false;
00057 _glXGetProcAddress = NULL;
00058 _temp_context = (GLXContext)NULL;
00059 _temp_xwindow = (X11_Window)NULL;
00060 _temp_colormap = (Colormap)NULL;
00061 }
00062
00063
00064
00065
00066
00067
00068 glxGraphicsStateGuardian::
00069 ~glxGraphicsStateGuardian() {
00070 destroy_temp_xwindow();
00071 if (_visuals != (XVisualInfo *)NULL) {
00072 XFree(_visuals);
00073 }
00074 if (_context != (GLXContext)NULL) {
00075 glXDestroyContext(_display, _context);
00076 _context = (GLXContext)NULL;
00077 }
00078 }
00079
00080
00081
00082
00083
00084
00085
00086 void glxGraphicsStateGuardian::
00087 get_properties(FrameBufferProperties &properties, XVisualInfo *visual) {
00088
00089 int use_gl, render_mode, double_buffer, stereo,
00090 red_size, green_size, blue_size,
00091 alpha_size, ared_size, agreen_size, ablue_size, aalpha_size,
00092 depth_size, stencil_size;
00093
00094 glXGetConfig(_display, visual, GLX_USE_GL, &use_gl);
00095 glXGetConfig(_display, visual, GLX_RGBA, &render_mode);
00096 glXGetConfig(_display, visual, GLX_DOUBLEBUFFER, &double_buffer);
00097 glXGetConfig(_display, visual, GLX_STEREO, &stereo);
00098 glXGetConfig(_display, visual, GLX_RED_SIZE, &red_size);
00099 glXGetConfig(_display, visual, GLX_GREEN_SIZE, &green_size);
00100 glXGetConfig(_display, visual, GLX_BLUE_SIZE, &blue_size);
00101 glXGetConfig(_display, visual, GLX_ALPHA_SIZE, &alpha_size);
00102 glXGetConfig(_display, visual, GLX_ACCUM_RED_SIZE, &ared_size);
00103 glXGetConfig(_display, visual, GLX_ACCUM_GREEN_SIZE, &agreen_size);
00104 glXGetConfig(_display, visual, GLX_ACCUM_BLUE_SIZE, &ablue_size);
00105 glXGetConfig(_display, visual, GLX_ACCUM_ALPHA_SIZE, &aalpha_size);
00106 glXGetConfig(_display, visual, GLX_DEPTH_SIZE, &depth_size);
00107 glXGetConfig(_display, visual, GLX_STENCIL_SIZE, &stencil_size);
00108
00109 properties.clear();
00110
00111 if (use_gl == 0) {
00112
00113
00114
00115 return;
00116 }
00117
00118 if (double_buffer) {
00119 properties.set_back_buffers(1);
00120 }
00121 if (stereo) {
00122 properties.set_stereo(1);
00123 }
00124 if (render_mode) {
00125 properties.set_rgb_color(1);
00126 } else {
00127 properties.set_indexed_color(1);
00128 }
00129 properties.set_color_bits(red_size+green_size+blue_size);
00130 properties.set_stencil_bits(stencil_size);
00131 properties.set_depth_bits(depth_size);
00132 properties.set_alpha_bits(alpha_size);
00133 properties.set_accum_bits(ared_size+agreen_size+ablue_size+aalpha_size);
00134
00135
00136 properties.set_force_software(1);
00137 properties.set_force_hardware(1);
00138 }
00139
00140
00141
00142
00143
00144
00145
00146 void glxGraphicsStateGuardian::
00147 get_properties_advanced(FrameBufferProperties &properties,
00148 bool &context_has_pbuffer, bool &context_has_pixmap,
00149 bool &slow, GLXFBConfig config) {
00150 properties.clear();
00151
00152 if (_supports_fbconfig) {
00153
00154 int render_type, double_buffer, stereo, red_size, green_size, blue_size,
00155 alpha_size, ared_size, agreen_size, ablue_size, aalpha_size,
00156 depth_size, stencil_size, samples, drawable_type, caveat;
00157
00158 _glXGetFBConfigAttrib(_display, config, GLX_RENDER_TYPE, &render_type);
00159 _glXGetFBConfigAttrib(_display, config, GLX_DOUBLEBUFFER, &double_buffer);
00160 _glXGetFBConfigAttrib(_display, config, GLX_STEREO, &stereo);
00161 _glXGetFBConfigAttrib(_display, config, GLX_RED_SIZE, &red_size);
00162 _glXGetFBConfigAttrib(_display, config, GLX_GREEN_SIZE, &green_size);
00163 _glXGetFBConfigAttrib(_display, config, GLX_BLUE_SIZE, &blue_size);
00164 _glXGetFBConfigAttrib(_display, config, GLX_ALPHA_SIZE, &alpha_size);
00165 _glXGetFBConfigAttrib(_display, config, GLX_ACCUM_RED_SIZE, &ared_size);
00166 _glXGetFBConfigAttrib(_display, config, GLX_ACCUM_GREEN_SIZE, &agreen_size);
00167 _glXGetFBConfigAttrib(_display, config, GLX_ACCUM_BLUE_SIZE, &ablue_size);
00168 _glXGetFBConfigAttrib(_display, config, GLX_ACCUM_ALPHA_SIZE, &aalpha_size);
00169 _glXGetFBConfigAttrib(_display, config, GLX_DEPTH_SIZE, &depth_size);
00170 _glXGetFBConfigAttrib(_display, config, GLX_STENCIL_SIZE, &stencil_size);
00171 _glXGetFBConfigAttrib(_display, config, GLX_SAMPLES, &samples);
00172 _glXGetFBConfigAttrib(_display, config, GLX_DRAWABLE_TYPE, &drawable_type);
00173 _glXGetFBConfigAttrib(_display, config, GLX_CONFIG_CAVEAT, &caveat);
00174
00175 context_has_pbuffer = false;
00176 if ((drawable_type & GLX_PBUFFER_BIT)!=0) {
00177 context_has_pbuffer = true;
00178 }
00179
00180 context_has_pixmap = false;
00181 if ((drawable_type & GLX_PIXMAP_BIT)!=0) {
00182 context_has_pixmap = true;
00183 }
00184
00185 slow = false;
00186 if (caveat == GLX_SLOW_CONFIG) {
00187 slow = true;
00188 }
00189
00190 if ((drawable_type & GLX_WINDOW_BIT)==0) {
00191
00192 return;
00193 }
00194
00195 if (double_buffer) {
00196 properties.set_back_buffers(1);
00197 }
00198 if (stereo) {
00199 properties.set_stereo(1);
00200 }
00201
00202 if ((render_type & GLX_RGBA_BIT)!=0) {
00203 properties.set_rgb_color(1);
00204 }
00205 if ((render_type & GLX_COLOR_INDEX_BIT)!=0) {
00206 properties.set_indexed_color(1);
00207 }
00208 properties.set_color_bits(red_size+green_size+blue_size);
00209 properties.set_stencil_bits(stencil_size);
00210 properties.set_depth_bits(depth_size);
00211 properties.set_alpha_bits(alpha_size);
00212 properties.set_accum_bits(ared_size+agreen_size+ablue_size+aalpha_size);
00213 properties.set_multisamples(samples);
00214
00215
00216 properties.set_force_software(1);
00217 properties.set_force_hardware(1);
00218 }
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228 void glxGraphicsStateGuardian::
00229 choose_pixel_format(const FrameBufferProperties &properties,
00230 X11_Display *display,
00231 int screen, bool need_pbuffer, bool need_pixmap) {
00232
00233 _display = display;
00234 _screen = screen;
00235 _context = 0;
00236 _fbconfig = 0;
00237 _visual = 0;
00238 if (_visuals != (XVisualInfo *)NULL) {
00239 XFree(_visuals);
00240 _visuals = NULL;
00241 }
00242
00243 _fbprops.clear();
00244
00245
00246
00247
00248
00249 destroy_temp_xwindow();
00250 choose_temp_visual(properties);
00251 if (_temp_context == NULL) {
00252
00253 return;
00254 }
00255
00256
00257
00258
00259
00260 init_temp_context();
00261
00262 if (!_supports_fbconfig) {
00263
00264
00265 glxdisplay_cat.debug()
00266 <<" No FBConfig supported; using XVisual only.\n"
00267 << _fbprops << "\n";
00268
00269 _context = _temp_context;
00270 _temp_context = (GLXContext)NULL;
00271
00272
00273
00274
00275 _context_has_pixmap = !glXIsDirect(_display, _context);
00276
00277
00278 _context_has_pbuffer = false;
00279 return;
00280 }
00281
00282
00283
00284
00285
00286
00287 int best_quality = 0;
00288 int best_result = 0;
00289 FrameBufferProperties best_props;
00290
00291 static const int max_attrib_list = 32;
00292 int attrib_list[max_attrib_list];
00293 int n = 0;
00294 attrib_list[n++] = GLX_STEREO;
00295 attrib_list[n++] = GLX_DONT_CARE;
00296 attrib_list[n++] = GLX_RENDER_TYPE;
00297 attrib_list[n++] = GLX_DONT_CARE;
00298 attrib_list[n++] = GLX_DRAWABLE_TYPE;
00299 attrib_list[n++] = GLX_DONT_CARE;
00300 attrib_list[n] = (int)None;
00301
00302 int num_configs = 0;
00303 GLXFBConfig *configs =
00304 _glXChooseFBConfig(_display, _screen, attrib_list, &num_configs);
00305
00306 if (configs != 0) {
00307 bool context_has_pbuffer, context_has_pixmap, slow;
00308 int quality, i;
00309 for (i = 0; i < num_configs; ++i) {
00310 FrameBufferProperties fbprops;
00311 get_properties_advanced(fbprops, context_has_pbuffer, context_has_pixmap,
00312 slow, configs[i]);
00313 quality = fbprops.get_quality(properties);
00314 if ((quality > 0)&&(slow)) quality -= 10000000;
00315 if (glxdisplay_cat.is_debug()) {
00316 const char *pbuffertext = context_has_pbuffer ? " (pbuffer)" : "";
00317 const char *pixmaptext = context_has_pixmap ? " (pixmap)" : "";
00318 const char *slowtext = slow ? " (slow)" : "";
00319 glxdisplay_cat.debug()
00320 << i << ": " << fbprops << " quality=" << quality << pbuffertext << pixmaptext << slowtext << "\n";
00321 }
00322 if (need_pbuffer && !context_has_pbuffer) {
00323 continue;
00324 }
00325 if (need_pixmap && !context_has_pixmap) {
00326 continue;
00327 }
00328
00329 if (quality > best_quality) {
00330 best_quality = quality;
00331 best_result = i;
00332 best_props = fbprops;
00333 }
00334 }
00335 }
00336
00337 if (best_quality > 0) {
00338 _fbconfig = configs[best_result];
00339 _context =
00340 _glXCreateNewContext(_display, _fbconfig, GLX_RGBA_TYPE, _share_context,
00341 GL_TRUE);
00342 if (_context) {
00343 if (_visuals != (XVisualInfo *)NULL) {
00344 XFree(_visuals);
00345 _visuals = NULL;
00346 }
00347 _visuals = _glXGetVisualFromFBConfig(_display, _fbconfig);
00348 _visual = _visuals;
00349
00350 if (_visual) {
00351 get_properties_advanced(_fbprops, _context_has_pbuffer, _context_has_pixmap,
00352 _slow, _fbconfig);
00353
00354 if (glxdisplay_cat.is_debug()) {
00355 glxdisplay_cat.debug()
00356 << "Selected context " << best_result << ": " << _fbprops << "\n";
00357 glxdisplay_cat.debug()
00358 << "context_has_pbuffer = " << _context_has_pbuffer
00359 << ", context_has_pixmap = " << _context_has_pixmap << "\n";
00360 }
00361
00362 return;
00363 }
00364 }
00365
00366 glxdisplay_cat.error()
00367 << "Could not create FBConfig context!\n";
00368 _fbconfig = 0;
00369 _context = 0;
00370 _visual = 0;
00371 _visuals = 0;
00372 }
00373
00374 glxdisplay_cat.warning()
00375 << "No suitable FBConfig contexts available; using XVisual only.\n"
00376 << _fbprops << "\n";
00377
00378 _context = _temp_context;
00379 _temp_context = (GLXContext)NULL;
00380
00381
00382
00383
00384 _context_has_pixmap = !glXIsDirect(_display, _context);
00385
00386
00387 _context_has_pbuffer = false;
00388 }
00389
00390
00391
00392
00393
00394
00395
00396 void glxGraphicsStateGuardian::
00397 reset() {
00398 PosixGraphicsStateGuardian::reset();
00399
00400 _supports_swap_control = has_extension("GLX_SGI_swap_control");
00401
00402 if (_supports_swap_control) {
00403 _glXSwapIntervalSGI =
00404 (PFNGLXSWAPINTERVALSGIPROC)get_extension_func("glX", "SwapIntervalSGI");
00405 if (_glXSwapIntervalSGI == NULL) {
00406 glxdisplay_cat.error()
00407 << "Driver claims to support GLX_SGI_swap_control extension, but does not define all functions.\n";
00408 _supports_swap_control = false;
00409 }
00410 }
00411
00412 if (_supports_swap_control) {
00413
00414
00415 _glXSwapIntervalSGI(sync_video ? 1 : 0);
00416 }
00417
00418 if (glx_support_fbconfig) {
00419 if (glx_is_at_least_version(1, 3)) {
00420
00421 _supports_fbconfig = true;
00422
00423 _glXChooseFBConfig =
00424 (PFNGLXCHOOSEFBCONFIGPROC)get_extension_func("glX", "ChooseFBConfig");
00425 _glXCreateNewContext =
00426 (PFNGLXCREATENEWCONTEXTPROC)get_extension_func("glX", "CreateNewContext");
00427 _glXGetVisualFromFBConfig =
00428 (PFNGLXGETVISUALFROMFBCONFIGPROC)get_extension_func("glX", "GetVisualFromFBConfig");
00429 _glXGetFBConfigAttrib =
00430 (PFNGLXGETFBCONFIGATTRIBPROC)get_extension_func("glX", "GetFBConfigAttrib");
00431 _glXCreatePixmap =
00432 (PFNGLXCREATEPIXMAPPROC)get_extension_func("glX", "CreatePixmap");
00433
00434 if (_glXChooseFBConfig == NULL ||
00435 _glXCreateNewContext == NULL ||
00436 _glXGetVisualFromFBConfig == NULL ||
00437 _glXGetFBConfigAttrib == NULL ||
00438 _glXCreatePixmap == NULL) {
00439 glxdisplay_cat.error()
00440 << "Driver claims to support GLX_fbconfig extension, but does not define all functions.\n";
00441 _supports_fbconfig = false;
00442 }
00443 } else if (has_extension("GLX_SGIX_fbconfig")) {
00444
00445
00446
00447 _supports_fbconfig = true;
00448
00449 _glXChooseFBConfig =
00450 (PFNGLXCHOOSEFBCONFIGPROC)get_extension_func("glX", "ChooseFBConfigSGIX");
00451 _glXCreateNewContext =
00452 (PFNGLXCREATENEWCONTEXTPROC)get_extension_func("glX", "CreateContextWithConfigSGIX");
00453 _glXGetVisualFromFBConfig =
00454 (PFNGLXGETVISUALFROMFBCONFIGPROC)get_extension_func("glX", "GetVisualFromFBConfigSGIX");
00455 _glXGetFBConfigAttrib =
00456 (PFNGLXGETFBCONFIGATTRIBPROC)get_extension_func("glX", "GetFBConfigAttribSGIX");
00457 _glXCreatePixmap =
00458 (PFNGLXCREATEPIXMAPPROC)get_extension_func("glX", "CreateGLXPixmapWithConfigSGIX");
00459
00460 if (_glXChooseFBConfig == NULL ||
00461 _glXCreateNewContext == NULL ||
00462 _glXGetVisualFromFBConfig == NULL ||
00463 _glXGetFBConfigAttrib == NULL ||
00464 _glXCreatePixmap == NULL) {
00465 glxdisplay_cat.error()
00466 << "Driver claims to support GLX_SGIX_fbconfig extension, but does not define all functions.\n";
00467 _supports_fbconfig = false;
00468 }
00469 }
00470
00471 if (glx_is_at_least_version(1, 3)) {
00472
00473 _supports_pbuffer = true;
00474 _uses_sgix_pbuffer = false;
00475
00476 _glXCreatePbuffer =
00477 (PFNGLXCREATEPBUFFERPROC)get_extension_func("glX", "CreatePbuffer");
00478 _glXCreateGLXPbufferSGIX = NULL;
00479 _glXDestroyPbuffer =
00480 (PFNGLXDESTROYPBUFFERPROC)get_extension_func("glX", "DestroyPbuffer");
00481 if (_glXCreatePbuffer == NULL ||
00482 _glXDestroyPbuffer == NULL) {
00483 glxdisplay_cat.error()
00484 << "Driver claims to support GLX_pbuffer extension, but does not define all functions.\n";
00485 _supports_pbuffer = false;
00486 }
00487
00488 } else if (has_extension("GLX_SGIX_pbuffer")) {
00489
00490 _uses_sgix_pbuffer = true;
00491
00492
00493
00494
00495 _glXCreatePbuffer = NULL;
00496 _glXCreateGLXPbufferSGIX =
00497 (PFNGLXCREATEGLXPBUFFERSGIXPROC)get_extension_func("glX", "CreateGLXPbufferSGIX");
00498 _glXDestroyPbuffer =
00499 (PFNGLXDESTROYPBUFFERPROC)get_extension_func("glX", "DestroyGLXPbufferSGIX");
00500 if (_glXCreateGLXPbufferSGIX == NULL ||
00501 _glXDestroyPbuffer == NULL) {
00502 glxdisplay_cat.error()
00503 << "Driver claims to support GLX_SGIX_pbuffer extension, but does not define all functions.\n";
00504 _supports_pbuffer = false;
00505 }
00506 }
00507 }
00508
00509
00510 if (glxdisplay_cat.is_debug()) {
00511 glxdisplay_cat.debug()
00512 << "supports_swap_control = " << _supports_swap_control << "\n";
00513 glxdisplay_cat.debug()
00514 << "supports_fbconfig = " << _supports_fbconfig << "\n";
00515 glxdisplay_cat.debug()
00516 << "supports_pbuffer = " << _supports_pbuffer
00517 << " sgix = " << _uses_sgix_pbuffer << "\n";
00518 }
00519
00520
00521
00522
00523 if (_gl_renderer.find("Mesa") != string::npos &&
00524 _gl_renderer.find("Mesa DRI") == string::npos) {
00525
00526 _fbprops.set_force_software(1);
00527 _fbprops.set_force_hardware(0);
00528 } else {
00529 _fbprops.set_force_hardware(1);
00530 _fbprops.set_force_software(0);
00531 }
00532 }
00533
00534
00535
00536
00537
00538
00539
00540 bool glxGraphicsStateGuardian::
00541 glx_is_at_least_version(int major_version, int minor_version) const {
00542 if (_glx_version_major < major_version) {
00543 return false;
00544 }
00545 if (_glx_version_major > major_version) {
00546 return true;
00547 }
00548 if (_glx_version_minor < minor_version) {
00549 return false;
00550 }
00551 return true;
00552 }
00553
00554
00555
00556
00557
00558
00559 void glxGraphicsStateGuardian::
00560 gl_flush() const {
00561
00562 LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
00563 PosixGraphicsStateGuardian::gl_flush();
00564 }
00565
00566
00567
00568
00569
00570
00571 GLenum glxGraphicsStateGuardian::
00572 gl_get_error() const {
00573
00574 LightReMutexHolder holder(glxGraphicsPipe::_x_mutex);
00575 return PosixGraphicsStateGuardian::gl_get_error();
00576 }
00577
00578
00579
00580
00581
00582
00583 void glxGraphicsStateGuardian::
00584 query_gl_version() {
00585 PosixGraphicsStateGuardian::query_gl_version();
00586
00587 show_glx_client_string("GLX_VENDOR", GLX_VENDOR);
00588 show_glx_client_string("GLX_VERSION", GLX_VERSION);
00589 show_glx_server_string("GLX_VENDOR", GLX_VENDOR);
00590 show_glx_server_string("GLX_VERSION", GLX_VERSION);
00591
00592 glXQueryVersion(_display, &_glx_version_major, &_glx_version_minor);
00593
00594
00595
00596
00597 if (glgsg_cat.is_debug()) {
00598 glgsg_cat.debug()
00599 << "GLX_VERSION = " << _glx_version_major << "." << _glx_version_minor
00600 << "\n";
00601 }
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612 void glxGraphicsStateGuardian::
00613 get_extra_extensions() {
00614 save_extensions(glXQueryExtensionsString(_display, _screen));
00615 }
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627 void *glxGraphicsStateGuardian::
00628 do_get_extension_func(const char *prefix, const char *name) {
00629 nassertr(prefix != NULL, NULL);
00630 nassertr(name != NULL, NULL);
00631 string fullname = string(prefix) + string(name);
00632
00633 if (glx_get_proc_address) {
00634
00635
00636
00637 #if defined(LINK_IN_GLXGETPROCADDRESS) && defined(HAVE_GLXGETPROCADDRESS)
00638
00639
00640
00641
00642
00643 return (void *)glXGetProcAddress((const GLubyte *)fullname.c_str());
00644
00645 #elif defined(LINK_IN_GLXGETPROCADDRESS) && defined(HAVE_GLXGETPROCADDRESSARB)
00646
00647
00648 return (void *)glXGetProcAddressARB((const GLubyte *)fullname.c_str());
00649
00650 #else
00651
00652
00653 if (!_checked_get_proc_address) {
00654 const char *funcName = NULL;
00655
00656 if (glx_is_at_least_version(1, 4)) {
00657 funcName = "glXGetProcAddress";
00658
00659 } else if (has_extension("GLX_ARB_get_proc_address")) {
00660 funcName = "glXGetProcAddressARB";
00661 }
00662
00663 if (funcName != NULL) {
00664 _glXGetProcAddress = (PFNGLXGETPROCADDRESSPROC)get_system_func(funcName);
00665 if (_glXGetProcAddress == NULL) {
00666 glxdisplay_cat.warning()
00667 << "Couldn't load function " << funcName
00668 << ", GL extensions may be unavailable.\n";
00669 }
00670 }
00671
00672 _checked_get_proc_address = true;
00673 }
00674
00675
00676 if (_glXGetProcAddress != NULL) {
00677 return (void *)_glXGetProcAddress((const GLubyte *)fullname.c_str());
00678 }
00679 #endif // HAVE_GLXGETPROCADDRESS
00680 }
00681
00682
00683 return PosixGraphicsStateGuardian::do_get_extension_func(prefix, name);
00684 }
00685
00686
00687
00688
00689
00690
00691
00692 void glxGraphicsStateGuardian::
00693 show_glx_client_string(const string &name, int id) {
00694 if (glgsg_cat.is_debug()) {
00695 const char *text = glXGetClientString(_display, id);
00696 if (text == (const char *)NULL) {
00697 glgsg_cat.debug()
00698 << "Unable to query " << name << " (client)\n";
00699 } else {
00700 glgsg_cat.debug()
00701 << name << " (client) = " << (const char *)text << "\n";
00702 }
00703 }
00704 }
00705
00706
00707
00708
00709
00710
00711
00712 void glxGraphicsStateGuardian::
00713 show_glx_server_string(const string &name, int id) {
00714 if (glgsg_cat.is_debug()) {
00715 const char *text = glXQueryServerString(_display, _screen, id);
00716 if (text == (const char *)NULL) {
00717 glgsg_cat.debug()
00718 << "Unable to query " << name << " (server)\n";
00719 } else {
00720 glgsg_cat.debug()
00721 << name << " (server) = " << (const char *)text << "\n";
00722 }
00723 }
00724 }
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735 void glxGraphicsStateGuardian::
00736 choose_temp_visual(const FrameBufferProperties &properties) {
00737 nassertv(_temp_context == (GLXContext)NULL);
00738
00739 int best_quality = 0;
00740 int best_result = 0;
00741 FrameBufferProperties best_props;
00742
00743
00744 if (_visuals != (XVisualInfo *)NULL) {
00745 XFree(_visuals);
00746 _visuals = NULL;
00747 }
00748 int nvisuals = 0;
00749 _visuals = XGetVisualInfo(_display, 0, 0, &nvisuals);
00750 if (_visuals != 0) {
00751 for (int i = 0; i < nvisuals; i++) {
00752 FrameBufferProperties fbprops;
00753 get_properties(fbprops, _visuals + i);
00754 int quality = fbprops.get_quality(properties);
00755 if (quality > best_quality) {
00756 best_quality = quality;
00757 best_result = i;
00758 best_props = fbprops;
00759 }
00760 }
00761 }
00762
00763 if (best_quality > 0) {
00764 _visual = _visuals + best_result;
00765 _temp_context = glXCreateContext(_display, _visual, None, GL_TRUE);
00766 if (_temp_context) {
00767 _fbprops = best_props;
00768 return;
00769 }
00770 }
00771
00772 glxdisplay_cat.error()
00773 << "Could not find a usable pixel format.\n";
00774 }
00775
00776
00777
00778
00779
00780
00781
00782
00783 void glxGraphicsStateGuardian::
00784 init_temp_context() {
00785 x11GraphicsPipe *x11_pipe;
00786 DCAST_INTO_V(x11_pipe, get_pipe());
00787 X11_Window root_window = x11_pipe->get_root();
00788
00789
00790 Visual *visual = _visual->visual;
00791 nassertv(visual->c_class == DirectColor || visual->c_class == TrueColor);
00792 _temp_colormap = XCreateColormap(_display, root_window,
00793 visual, AllocNone);
00794 XSetWindowAttributes wa;
00795 wa.colormap = _temp_colormap;
00796 unsigned long attrib_mask = CWColormap;
00797
00798 _temp_xwindow = XCreateWindow
00799 (_display, root_window, 0, 0, 100, 100,
00800 0, _visual->depth, InputOutput,
00801 visual, attrib_mask, &wa);
00802 if (_temp_xwindow == (X11_Window)NULL) {
00803 glxdisplay_cat.error()
00804 << "Could not create temporary window for context\n";
00805 return;
00806 }
00807
00808 glXMakeCurrent(_display, _temp_xwindow, _temp_context);
00809 reset();
00810 }
00811
00812
00813
00814
00815
00816
00817
00818 void glxGraphicsStateGuardian::
00819 destroy_temp_xwindow() {
00820 glXMakeCurrent(_display, None, NULL);
00821
00822 if (_temp_colormap != (Colormap)NULL) {
00823 XFreeColormap(_display, _temp_colormap);
00824 _temp_colormap = (Colormap)NULL;
00825 }
00826 if (_temp_xwindow != (X11_Window)NULL) {
00827 XDestroyWindow(_display, _temp_xwindow);
00828 _temp_xwindow = (X11_Window)NULL;
00829 }
00830
00831 if (_temp_context != (GLXContext)NULL){
00832 glXDestroyContext(_display, _temp_context);
00833 _temp_context = (GLXContext)NULL;
00834 }
00835 }