Advertisement
Guest User

EglContext.cpp

a guest
Jan 10th, 2019
381
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.30 KB | None | 0 0
  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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement