SHARE
TWEET

EglContext.cpp

a guest Jan 10th, 2019 127 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ////////////////////////////////////////////////////////////
  2. //
  3. // SFML - Simple and Fast Multimedia Library
  4. // Copyright (C) 2013 Jonathan De Wachter (dewachter.jonathan@gmail.com)
  5. //
  6. // This software is provided 'as-is', without any express or implied warranty.
  7. // In no event will the authors be held liable for any damages arising from the use of this software.
  8. //
  9. // Permission is granted to anyone to use this software for any purpose,
  10. // including commercial applications, and to alter it and redistribute it freely,
  11. // subject to the following restrictions:
  12. //
  13. // 1. The origin of this software must not be misrepresented;
  14. //    you must not claim that you wrote the original software.
  15. //    If you use this software in a product, an acknowledgment
  16. //    in the product documentation would be appreciated but is not required.
  17. //
  18. // 2. Altered source versions must be plainly marked as such,
  19. //    and must not be misrepresented as being the original software.
  20. //
  21. // 3. This notice may not be removed or altered from any source distribution.
  22. //
  23. ////////////////////////////////////////////////////////////
  24.  
  25.  
  26. ////////////////////////////////////////////////////////////
  27. // Headers
  28. ////////////////////////////////////////////////////////////
  29. #include <SFML/Window/EglContext.hpp>
  30. #include <SFML/Window/WindowImpl.hpp>
  31. #include <SFML/OpenGL.hpp>
  32. #include <SFML/System/Err.hpp>
  33. #include <SFML/System/Sleep.hpp>
  34. #include <SFML/System/Mutex.hpp>
  35. #include <SFML/System/Lock.hpp>
  36. #ifdef SFML_SYSTEM_ANDROID
  37.     #include <SFML/System/Android/Activity.hpp>
  38. #endif
  39. //#ifdef SFML_SYSTEM_LINUX
  40. //    #include <X11/Xlib.h>
  41. //#endif
  42.  
  43. namespace
  44. {
  45.     EGLDisplay getInitializedDisplay()
  46.     {
  47. #if defined(SFML_SYSTEM_LINUX)
  48.  
  49.         static EGLDisplay display = EGL_NO_DISPLAY;
  50.  
  51.         if (display == EGL_NO_DISPLAY)
  52.         {
  53.             display = eglCheck(eglGetDisplay(EGL_DEFAULT_DISPLAY));
  54.             eglCheck(eglInitialize(display, NULL, NULL));
  55.         }
  56.  
  57.         return display;
  58.  
  59. #elif defined(SFML_SYSTEM_ANDROID)
  60.  
  61.     // On Android, its native activity handles this for us
  62.     sf::priv::ActivityStates* states = sf::priv::getActivity(NULL);
  63.     sf::Lock lock(states->mutex);
  64.  
  65.     return states->display;
  66.  
  67. #endif
  68.     }
  69. }
  70.  
  71.  
  72. namespace sf
  73. {
  74. namespace priv
  75. {
  76. ////////////////////////////////////////////////////////////
  77. EglContext::EglContext(EglContext* shared) :
  78. m_display (EGL_NO_DISPLAY),
  79. m_context (EGL_NO_CONTEXT),
  80. m_surface (EGL_NO_SURFACE),
  81. m_config  (NULL)
  82. {
  83.     // Get the initialized EGL display
  84.     m_display = getInitializedDisplay();
  85.  
  86.     // Get the best EGL config matching the default video settings
  87.     m_config = getBestConfig(m_display, VideoMode::getDesktopMode().bitsPerPixel, ContextSettings());
  88.     updateSettings();
  89.  
  90.     // Note: The EGL specs say that attrib_list can be NULL when passed to eglCreatePbufferSurface,
  91.     // but this is resulting in a segfault. Bug in Android?
  92.     EGLint attrib_list[] = {
  93.         EGL_WIDTH, 1,
  94.         EGL_HEIGHT,1,
  95.         EGL_NONE
  96.     };
  97.  
  98.     m_surface = eglCheck(eglCreatePbufferSurface(m_display, m_config, attrib_list));
  99.  
  100.     // Create EGL context
  101.     createContext(shared);
  102. }
  103.  
  104.  
  105. ////////////////////////////////////////////////////////////
  106. EglContext::EglContext(EglContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel) :
  107. m_display (EGL_NO_DISPLAY),
  108. m_context (EGL_NO_CONTEXT),
  109. m_surface (EGL_NO_SURFACE),
  110. m_config  (NULL)
  111. {
  112. #ifdef SFML_SYSTEM_ANDROID
  113.  
  114.     // On Android, we must save the created context
  115.     ActivityStates* states = getActivity(NULL);
  116.     Lock lock(states->mutex);
  117.  
  118.     states->context = this;
  119.  
  120. #endif
  121.  
  122.     // Get the initialized EGL display
  123.     m_display = getInitializedDisplay();
  124.  
  125.     // Get the best EGL config matching the requested video settings
  126.     m_config = getBestConfig(m_display, bitsPerPixel, settings);
  127.     updateSettings();
  128.  
  129.     // Create EGL context
  130.     createContext(shared);
  131.  
  132. #if !defined(SFML_SYSTEM_ANDROID)
  133.     // Create EGL surface (except on Android because the window is created
  134.     // asynchronously, its activity manager will call it for us)
  135.     createSurface((EGLNativeWindowType)owner->getSystemHandle());
  136. #endif
  137. }
  138.  
  139.  
  140. ////////////////////////////////////////////////////////////
  141. EglContext::EglContext(EglContext* shared, const ContextSettings& settings, unsigned int width, unsigned int height) :
  142. m_display (EGL_NO_DISPLAY),
  143. m_context (EGL_NO_CONTEXT),
  144. m_surface (EGL_NO_SURFACE),
  145. m_config  (NULL)
  146. {
  147. }
  148.  
  149.  
  150. ////////////////////////////////////////////////////////////
  151. EglContext::~EglContext()
  152. {
  153.     // Notify unshared OpenGL resources of context destruction
  154.     cleanupUnsharedResources();
  155.  
  156.     // Deactivate the current context
  157.     EGLContext currentContext = eglCheck(eglGetCurrentContext());
  158.  
  159.     if (currentContext == m_context)
  160.     {
  161.         eglCheck(eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
  162.     }
  163.  
  164.     // Destroy context
  165.     if (m_context != EGL_NO_CONTEXT)
  166.     {
  167.         eglCheck(eglDestroyContext(m_display, m_context));
  168.     }
  169.  
  170.     // Destroy surface
  171.     if (m_surface != EGL_NO_SURFACE)
  172.     {
  173.         eglCheck(eglDestroySurface(m_display, m_surface));
  174.     }
  175. }
  176.  
  177.  
  178. ////////////////////////////////////////////////////////////
  179. bool EglContext::makeCurrent(bool current)
  180. {
  181.     if (current)
  182.         return m_surface != EGL_NO_SURFACE && eglCheck(eglMakeCurrent(m_display, m_surface, m_surface, m_context));
  183.  
  184.     return m_surface != EGL_NO_SURFACE && eglCheck(eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
  185. }
  186.  
  187.  
  188. ////////////////////////////////////////////////////////////
  189. void EglContext::display()
  190. {
  191.     if (m_surface != EGL_NO_SURFACE)
  192.         eglCheck(eglSwapBuffers(m_display, m_surface));
  193. }
  194.  
  195.  
  196. ////////////////////////////////////////////////////////////
  197. void EglContext::setVerticalSyncEnabled(bool enabled)
  198. {
  199.     eglCheck(eglSwapInterval(m_display, enabled ? 1 : 0));
  200. }
  201.  
  202.  
  203. ////////////////////////////////////////////////////////////
  204. void EglContext::createContext(EglContext* shared)
  205. {
  206.     const EGLint contextVersion[] = {
  207.         EGL_CONTEXT_CLIENT_VERSION, 1,
  208.         EGL_NONE
  209.     };
  210.  
  211.     EGLContext toShared;
  212.  
  213.     if (shared)
  214.         toShared = shared->m_context;
  215.     else
  216.         toShared = EGL_NO_CONTEXT;
  217.  
  218.     if (toShared != EGL_NO_CONTEXT)
  219.         eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
  220.  
  221.     // Create EGL context
  222.     m_context = eglCheck(eglCreateContext(m_display, m_config, toShared, contextVersion));
  223. }
  224.  
  225.  
  226. ////////////////////////////////////////////////////////////
  227. void EglContext::createSurface(EGLNativeWindowType window)
  228. {
  229.     m_surface = eglCheck(eglCreateWindowSurface(m_display, m_config, window, NULL));
  230. }
  231.  
  232.  
  233. ////////////////////////////////////////////////////////////
  234. void EglContext::destroySurface()
  235. {
  236.     // Ensure that this context is no longer active since our surface is going to be destroyed
  237.     setActive(false);
  238.  
  239.     eglCheck(eglDestroySurface(m_display, m_surface));
  240.     m_surface = EGL_NO_SURFACE;
  241. }
  242.  
  243.  
  244. ////////////////////////////////////////////////////////////
  245. EGLConfig EglContext::getBestConfig(EGLDisplay display, unsigned int bitsPerPixel, const ContextSettings& settings)
  246. {
  247.     // Set our video settings constraint
  248.     const EGLint attributes[] = {
  249.         EGL_BUFFER_SIZE, static_cast<EGLint>(bitsPerPixel),
  250.         EGL_DEPTH_SIZE, static_cast<EGLint>(settings.depthBits),
  251.         EGL_STENCIL_SIZE, static_cast<EGLint>(settings.stencilBits),
  252.         EGL_SAMPLE_BUFFERS, static_cast<EGLint>(settings.antialiasingLevel ? 1 : 0),
  253.         EGL_SAMPLES, static_cast<EGLint>(settings.antialiasingLevel),
  254.         EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
  255.         EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
  256.         EGL_NONE
  257.     };
  258.  
  259.     EGLint configCount;
  260.     EGLConfig configs[1];
  261.  
  262.     // Ask EGL for the best config matching our video settings
  263.     eglCheck(eglChooseConfig(display, attributes, configs, 1, &configCount));
  264.  
  265.     // TODO: This should check EGL_CONFORMANT and pick the first conformant configuration.
  266.  
  267.     return configs[0];
  268. }
  269.  
  270.  
  271. ////////////////////////////////////////////////////////////
  272. void EglContext::updateSettings()
  273. {
  274.     EGLint tmp;
  275.    
  276.     // Update the internal context settings with the current config
  277.     eglCheck(eglGetConfigAttrib(m_display, m_config, EGL_DEPTH_SIZE, &tmp));
  278.     m_settings.depthBits = tmp;
  279.    
  280.     eglCheck(eglGetConfigAttrib(m_display, m_config, EGL_STENCIL_SIZE, &tmp));
  281.     m_settings.stencilBits = tmp;
  282.    
  283.     eglCheck(eglGetConfigAttrib(m_display, m_config, EGL_SAMPLES, &tmp));
  284.     m_settings.antialiasingLevel = tmp;
  285.    
  286.     m_settings.majorVersion = 1;
  287.     m_settings.minorVersion = 1;
  288.     m_settings.attributeFlags = ContextSettings::Default;
  289. }
  290.  
  291.  
  292. #if 0
  293. #ifdef SFML_SYSTEM_LINUX
  294. ////////////////////////////////////////////////////////////
  295. XVisualInfo EglContext::selectBestVisual(::Display* XDisplay, unsigned int bitsPerPixel, const ContextSettings& settings)
  296. {
  297.     // Get the initialized EGL display
  298.     EGLDisplay display = getInitializedDisplay();
  299.  
  300.     // Get the best EGL config matching the default video settings
  301.     EGLConfig config = getBestConfig(display, bitsPerPixel, settings);
  302.  
  303.     // Retrieve the visual id associated with this EGL config
  304.     EGLint nativeVisualId;
  305.  
  306.     eglCheck(eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &nativeVisualId));
  307.  
  308.     if (nativeVisualId == 0)
  309.     {
  310.         // Should never happen...
  311.         err() << "No EGL visual found. You should check your graphics driver" << std::endl;
  312.  
  313.         return XVisualInfo();
  314.     }
  315.  
  316.     XVisualInfo vTemplate;
  317.     vTemplate.visualid = static_cast<VisualID>(nativeVisualId);
  318.  
  319.     // Get X11 visuals compatible with this EGL config
  320.     XVisualInfo *availableVisuals, bestVisual;
  321.     int visualCount = 0;
  322.  
  323.     availableVisuals = XGetVisualInfo(XDisplay, VisualIDMask, &vTemplate, &visualCount);
  324.  
  325.     if (visualCount == 0)
  326.     {
  327.         // Can't happen...
  328.         err() << "No X11 visual found. Bug in your EGL implementation ?" << std::endl;
  329.  
  330.         return XVisualInfo();
  331.     }
  332.  
  333.     // Pick up the best one
  334.     bestVisual = availableVisuals[0];
  335.     XFree(availableVisuals);
  336.  
  337.     return bestVisual;
  338. }
  339. #endif
  340. #endif
  341. } // namespace priv
  342.  
  343. } // namespace sf
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top