BsLinuxContext.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Linux/BsLinuxContext.h"
  4. #include "Linux/BsLinuxPlatform.h"
  5. #include "Linux/BsLinuxGLSupport.h"
  6. namespace bs { namespace ct
  7. {
  8. typedef int(*ErrorHandlerProc)(::Display*, XErrorEvent*);
  9. int contextErrorHandler(::Display* display, XErrorEvent* error)
  10. {
  11. // Do nothing
  12. }
  13. LinuxContext::LinuxContext(::Display* display, XVisualInfo& visualInfo)
  14. : mDisplay(display), mContext(None)
  15. {
  16. LinuxPlatform::lockX();
  17. INT32 dummy;
  18. XVisualInfo* windowVisualInfo = XGetVisualInfo(display, VisualIDMask | VisualScreenMask, &visualInfo, &dummy);
  19. INT32 majorVersion, minorVersion;
  20. glXQueryVersion(display, &majorVersion, &minorVersion);
  21. GLXContext context = 0;
  22. // createContextAttrib was added in GLX version 1.3
  23. bool hasCreateContextAttrib = extGLX_ARB_create_context && (majorVersion > 1 || minorVersion >= 3);
  24. if(hasCreateContextAttrib)
  25. {
  26. // Find the config used to create the window's visual
  27. GLXFBConfig* windowConfig = nullptr;
  28. INT32 numConfigs;
  29. GLXFBConfig* configs = glXChooseFBConfig(display, DefaultScreen(display), nullptr, &numConfigs);
  30. for (INT32 i = 0; i < numConfigs; ++i)
  31. {
  32. XVisualInfo* configVisualInfo = glXGetVisualFromFBConfig(display, configs[i]);
  33. if(!configVisualInfo)
  34. continue;
  35. if(windowVisualInfo->visualid == configVisualInfo->visualid)
  36. {
  37. windowConfig = &configs[i];
  38. break;
  39. }
  40. }
  41. if(windowConfig)
  42. {
  43. int32_t attributes[] =
  44. {
  45. GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
  46. GLX_CONTEXT_MINOR_VERSION_ARB, 5,
  47. 0, 0, // Core profile
  48. 0, 0, // Debug flags
  49. 0 // Terminator
  50. };
  51. if(extGLX_ARB_create_context_profile)
  52. {
  53. attributes[4] = GLX_CONTEXT_PROFILE_MASK_ARB;
  54. attributes[5] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
  55. }
  56. #if BS_DEBUG_MODE
  57. attributes[6] = GLX_CONTEXT_FLAGS_ARB;
  58. attributes[7] = GLX_CONTEXT_DEBUG_BIT_ARB;
  59. #endif
  60. // Add error handler so the application doesn't crash on error
  61. ErrorHandlerProc oldErrorHandler = XSetErrorHandler(&contextErrorHandler);
  62. context = glXCreateContextAttribsARB(display, *windowConfig, 0, True, attributes);
  63. XSetErrorHandler(oldErrorHandler);
  64. }
  65. XFree(configs);
  66. }
  67. // If createContextAttribs failed or isn't supported, fall back to glXCreateContext
  68. if(!context)
  69. context = glXCreateContext(display, windowVisualInfo, 0, True);
  70. XFree(windowVisualInfo);
  71. mContext = context;
  72. LinuxPlatform::unlockX();
  73. }
  74. LinuxContext::~LinuxContext()
  75. {
  76. releaseContext();
  77. }
  78. void LinuxContext::setCurrent()
  79. {
  80. LinuxPlatform::lockX();
  81. glXMakeCurrent(mDisplay, LinuxPlatform::getMainXWindow(), mContext);
  82. LinuxPlatform::unlockX();
  83. }
  84. void LinuxContext::endCurrent()
  85. {
  86. LinuxPlatform::lockX();
  87. glXMakeCurrent(mDisplay, None, None);
  88. LinuxPlatform::unlockX();
  89. }
  90. void LinuxContext::releaseContext()
  91. {
  92. if (mContext)
  93. {
  94. LinuxPlatform::lockX();
  95. glXDestroyContext(mDisplay, mContext);
  96. mContext = None;
  97. LinuxPlatform::unlockX();
  98. }
  99. }
  100. }}