BsLinuxContext.cpp 3.2 KB

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