2828
2929
3030#include " opengl/opengl_util.h"
31- #include " opengl/opengl_util_glx .h"
31+ #include " opengl/opengl_util_egl .h"
3232
3333#include < glog/logging.h>
3434
3535namespace opengl {
3636
3737OpenGLContext::OpenGLContext () { impl.reset (new OpenGLContextImpl ()); }
3838
39- int XErrorHandler (Display* dsp, XErrorEvent* error) {
40- constexpr int kBufferSize = 512 ;
41- char error_string[kBufferSize ];
42- XGetErrorText (dsp, error->error_code , error_string, kBufferSize );
39+ bool InitializeEGL (OpenGLContext* result) {
40+ CHECK_NOTNULL (result);
4341
44- LOG (FATAL) << " X Error: \n " << error_string;
45- return 0 ;
46- }
42+ // taken from
43+ // https://developer.nvidia.com/blog/egl-eye-opengl-visualization-without-x-server/
44+ // Note that it also works for non-nvidia backend
4745
48- // Code adapted from
49- // http://stackoverflow.com/questions/2896879/windowless-opengl
50- bool InitializeOpenGLWindowlessGLX (GLXContext sharing_context,
51- OpenGLContext* result) {
52- CHECK_NOTNULL (result);
53- GLint attributes[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24 , None};
46+ PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT =
47+ (PFNEGLQUERYDEVICESEXTPROC)
48+ eglGetProcAddress (" eglQueryDevicesEXT" );
5449
55- int (*old_error_handler)(Display*, XErrorEvent*) =
56- XSetErrorHandler (XErrorHandler);
50+ PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT =
51+ (PFNEGLGETPLATFORMDISPLAYEXTPROC)
52+ eglGetProcAddress (" eglGetPlatformDisplayEXT" );
5753
58- Display* display = XOpenDisplay (NULL );
59- if (!display) {
60- LOG (FATAL) << " Cannot connect to X server." ;
61- }
54+ static const int MAX_DEVICES = 4 ;
55+ EGLDeviceEXT eglDevs[MAX_DEVICES];
56+ EGLint numDevices;
6257
63- Window root_window = DefaultRootWindow (display);
64- XVisualInfo* visual = glXChooseVisual (display, 0 , attributes);
65- if (!visual) {
66- LOG (FATAL) << " No appropriate visual found." ;
67- }
58+ eglQueryDevicesEXT (MAX_DEVICES, eglDevs, &numDevices);
6859
69- GLXContext glx_context =
70- glXCreateContext (display, visual, sharing_context, GL_TRUE);
71- if (!glx_context) {
72- LOG (FATAL) << " Cannot create GLX context." ;
73- }
74- XFree (visual);
60+ EGLDisplay eglDpy = eglGetPlatformDisplayEXT (EGL_PLATFORM_DEVICE_EXT,
61+ eglDevs[0 ], 0 );
7562
76- result->impl ->display = display;
77- result->impl ->drawable = root_window;
78- result->impl ->context = glx_context;
79- result->impl ->needs_glew_initialization = true ;
63+ EGLint major, minor;
64+
65+ eglInitialize (eglDpy, &major, &minor);
66+
67+ // 2. Select an appropriate configuration
68+ EGLint numConfigs;
69+ EGLConfig eglCfg;
70+
71+ eglChooseConfig (eglDpy, configAttribs, &eglCfg, 1 , &numConfigs);
8072
81- XSetErrorHandler (old_error_handler);
73+
74+ // 3. Bind the API
75+ eglBindAPI (EGL_OPENGL_API);
76+ EGLContext eglCtx = eglCreateContext (eglDpy, eglCfg, EGL_NO_CONTEXT,
77+ NULL );
78+
79+
80+ eglMakeCurrent (eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, eglCtx);
81+
82+ // Note : here, don't use surface because shaders
83+ // already take care of creating a Frame buffer object
84+
85+ result->impl ->display = eglDpy;
86+ result->impl ->surface_draw = EGL_NO_SURFACE;
87+ result->impl ->surface_read = EGL_NO_SURFACE;
88+ result->impl ->context = eglCtx;
89+ result->impl ->needs_glew_initialization = true ;
8290 return true ;
8391}
8492
85- OpenGLContext SwitchOpenGLContextGLX (const OpenGLContext& context) {
86- int (*old_error_handler)(Display*, XErrorEvent*) =
87- XSetErrorHandler (XErrorHandler);
88-
93+ OpenGLContext SwitchOpenGLContextEGL (const OpenGLContext& context) {
94+ if (glXGetCurrentContext () != NULL ){
95+ glXMakeCurrent (glXGetCurrentDisplay (), None, NULL );
96+ }
97+
8998 OpenGLContext current_context;
90- current_context.impl ->display = glXGetCurrentDisplay ();
99+ current_context.impl ->display = eglGetCurrentDisplay ();
91100 if (!current_context.impl ->display ) {
92- // We need a display, otherwise glXMakeCurrent() will segfault.
93101 current_context.impl ->display = context.impl ->display ;
94102 }
95- current_context.impl ->drawable = glXGetCurrentDrawable ();
96- current_context.impl ->context = glXGetCurrentContext ();
103+ current_context.impl ->surface_read = eglGetCurrentSurface (EGL_READ);
104+ current_context.impl ->surface_draw = eglGetCurrentSurface (EGL_DRAW);
105+ current_context.impl ->context = eglGetCurrentContext ();
97106 current_context.impl ->needs_glew_initialization = false ;
98107
99- if (glXMakeCurrent (context.impl ->display , context.impl ->drawable ,
100- context.impl ->context ) == GL_FALSE) {
101- LOG (FATAL) << " Cannot make GLX context current." ;
108+ if (eglMakeCurrent (context.impl ->display , context.impl ->surface_read ,
109+ context.impl ->surface_draw , context. impl -> context ) == GL_FALSE) {
110+ LOG (FATAL) << " Cannot make EGL context current." ;
102111 }
103112
104113 if (context.impl ->needs_glew_initialization ) {
@@ -110,39 +119,41 @@ OpenGLContext SwitchOpenGLContextGLX(const OpenGLContext& context) {
110119 context.impl ->needs_glew_initialization = false ;
111120 }
112121
113- XSetErrorHandler (old_error_handler);
114122 return current_context;
115123}
116124
117- bool IsOpenGLContextAvailableGLX () {
118- return (glXGetCurrentContext () != nullptr );
125+ bool IsOpenGLContextAvailableEGL () {
126+ return (eglGetCurrentContext () != nullptr );
119127}
120128
121- void DeinitializeOpenGLGLX (OpenGLContext* context) {
122- glXDestroyContext (context->impl ->display , context->impl ->context );
123- XCloseDisplay (context->impl ->display );
129+ void DeinitializeOpenGLEGL (OpenGLContext* context) {
130+ eglDestroyContext (context->impl ->display , context->impl ->context );
124131
125- context->impl ->drawable = None;
132+ context->impl ->surface_read = None;
133+ context->impl ->surface_draw = None;
126134 context->impl ->context = nullptr ;
127135}
128136
129137bool InitializeOpenGLWindowless (int /* version*/ , OpenGLContext* result) {
130138 CHECK_NOTNULL (result);
131- GLXContext sharing_context = nullptr ;
132- return InitializeOpenGLWindowlessGLX (sharing_context, result);
139+ return InitializeEGL (result);
133140}
134141
135142OpenGLContext SwitchOpenGLContext (const OpenGLContext& context) {
136- return SwitchOpenGLContextGLX (context);
143+ return SwitchOpenGLContextEGL (context);
137144}
138145
139146bool IsOpenGLContextAvailable () {
140- return IsOpenGLContextAvailableGLX ();
147+ return IsOpenGLContextAvailableEGL ();
148+ }
149+
150+ void releaseOpenGLContext (){
151+ eglMakeCurrent (eglGetCurrentDisplay (), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
141152}
142153
143154void DeinitializeOpenGL (OpenGLContext* context) {
144155 CHECK_NOTNULL (context);
145- DeinitializeOpenGLGLX (context);
156+ DeinitializeOpenGLEGL (context);
146157}
147158
148159} // namespace opengl
0 commit comments