Skip to content

Commit a2223be

Browse files
Merge pull request #10 from ClementPinard/generate_for_video
Use EGL whenever possible
2 parents d769924 + 34933df commit a2223be

File tree

12 files changed

+180
-144
lines changed

12 files changed

+180
-144
lines changed

CMakeLists.txt

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ endif()
1919
find_package(GMP REQUIRED)
2020
include_directories(${GMP_INCLUDE_DIRS})
2121

22+
#OpenGL
23+
find_package(OpenGL REQUIRED)
24+
include_directories(${OPENGL_INCLUDE_DIRS})
25+
link_directories(${OPENGL_LIBRARY_DIRS})
26+
2227
# GLEW
2328
find_package(GLEW REQUIRED)
2429
include_directories(${GLEW_INCLUDE_DIRS})
@@ -113,7 +118,7 @@ add_library(BaseLib
113118
src/opengl/renderer.cc
114119
src/opengl/mesh.cc
115120
src/opengl/opengl_util.cc
116-
src/opengl/opengl_util_glx.cc
121+
src/opengl/opengl_util_egl.cc
117122
src/opengl/shader_program_opengl.cc
118123

119124
src/opt/color_optimizer.cc
@@ -131,7 +136,9 @@ add_library(BaseLib
131136
src/opt/visibility_estimator.cc
132137
)
133138
target_link_libraries(BaseLib
134-
${OpenCV_LIBS})
139+
${OpenCV_LIBS}
140+
OpenGL::OpenGL
141+
OpenGL::EGL)
135142
target_compile_options(BaseLib PRIVATE -Wno-sign-compare)
136143
set(BASE_LIB_LIBRARIES
137144
BaseLib
@@ -140,8 +147,8 @@ set(BASE_LIB_LIBRARIES
140147
${PCL_LIBRARIES}
141148
glog
142149
${GLEW_LIBRARIES}
143-
GL
144-
X11
150+
OpenGL::OpenGL
151+
OpenGL::EGL
145152
)
146153

147154

@@ -363,4 +370,4 @@ target_link_libraries(Test_IntrinsicsAndPoseOptimizer
363370
target_compile_options(Test_IntrinsicsAndPoseOptimizer PRIVATE -Wno-sign-compare)
364371
add_test(Test_IntrinsicsAndPoseOptimizer
365372
Test_IntrinsicsAndPoseOptimizer
366-
)
373+
)

Dockerfile

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,13 @@ RUN rm -rf build \
3333
ENV PIPELINE_PATH=/dataset-pipeline/build
3434

3535
# Tests
36-
# Test_Alignment and Test_Renderer need an X server
37-
# so we cannot run the tests on docker
3836

39-
# RUN ${PIPELINE_PATH}/Test_Alignment
37+
RUN cd ${PIPELINE_PATH} && ./Test_Alignment
4038
RUN ${PIPELINE_PATH}/Test_Camera
4139
RUN ${PIPELINE_PATH}/Test_ICP
4240
RUN ${PIPELINE_PATH}/Test_Interpolation
4341
RUN ${PIPELINE_PATH}/Test_IntrinsicsAndPoseOptimizer
4442
RUN ${PIPELINE_PATH}/Test_MultiScalePointCloud
4543
RUN ${PIPELINE_PATH}/Test_Problem
46-
# RUN ${PIPELINE_PATH}/Test_Renderer
44+
RUN ${PIPELINE_PATH}/Test_Renderer
4745

src/opengl/opengl_util.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
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

src/opengl/opengl_util.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,14 @@ struct OpenGLContext {
5353
// versions 1, 2, and 3. On Linux, no specific version is requested.
5454
bool InitializeOpenGLWindowless(int version, OpenGLContext* result);
5555

56-
// Switches the current thread's OpenGL context to the given context, and
56+
// Switches the current thread's OpenGL context to the given EGL context, and
5757
// returns the previously active context. One context can be current to only
5858
// one thread at a time.
5959
OpenGLContext SwitchOpenGLContext(const OpenGLContext& context);
6060

61+
// Make a void EGL context, so that a GLX context can take over, e.g. in a QOpenGLWidget
62+
void releaseOpenGLContext();
63+
6164
// Tests whether a valid OpenGL context is current.
6265
bool IsOpenGLContextAvailable();
6366

src/opengl/opengl_util_glx.cc renamed to src/opengl/opengl_util_egl.cc

Lines changed: 70 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -28,77 +28,86 @@
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

3535
namespace opengl {
3636

3737
OpenGLContext::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

129137
bool 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

135142
OpenGLContext SwitchOpenGLContext(const OpenGLContext& context) {
136-
return SwitchOpenGLContextGLX(context);
143+
return SwitchOpenGLContextEGL(context);
137144
}
138145

139146
bool 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

143154
void DeinitializeOpenGL(OpenGLContext* context) {
144155
CHECK_NOTNULL(context);
145-
DeinitializeOpenGLGLX(context);
156+
DeinitializeOpenGLEGL(context);
146157
}
147158

148159
} // namespace opengl

src/opengl/opengl_util_glx.h renamed to src/opengl/opengl_util_egl.h

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,38 @@
2626
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2727
// POSSIBILITY OF SUCH DAMAGE.
2828

29-
#include <GL/glew.h>
29+
#define EGL_EGLEXT_PROTOTYPES
30+
#include <EGL/egl.h>
3031
#include <GL/glx.h>
31-
#include <X11/Xlib.h>
32-
#include <X11/Xutil.h>
32+
#include <EGL/eglext.h>
33+
#include <EGL/eglplatform.h>
3334

3435
namespace opengl {
3536

37+
static const EGLint configAttribs[] = {
38+
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
39+
EGL_BLUE_SIZE, 8,
40+
EGL_GREEN_SIZE, 8,
41+
EGL_RED_SIZE, 8,
42+
EGL_DEPTH_SIZE, 8,
43+
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
44+
EGL_NONE
45+
};
46+
47+
static const int pbufferWidth = 9;
48+
static const int pbufferHeight = 9;
49+
50+
static const EGLint pbufferAttribs[] = {
51+
EGL_WIDTH, pbufferWidth,
52+
EGL_HEIGHT, pbufferHeight,
53+
EGL_NONE,
54+
};
55+
3656
struct OpenGLContextImpl {
37-
Display* display;
38-
GLXDrawable drawable;
39-
GLXContext context;
57+
EGLDisplay display;
58+
EGLContext context;
59+
EGLSurface surface_read;
60+
EGLSurface surface_draw;
4061
bool needs_glew_initialization;
4162
};
4263

src/opt/occlusion_geometry.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ bool OcclusionGeometry::AddMesh(pcl::PolygonMesh& cpu_mesh,
154154
return false;
155155
}
156156
opengl_context_initialized_ = true;
157+
opengl::releaseOpenGLContext();
157158
}
158159

159160
// Transfer the mesh to the GPU.

0 commit comments

Comments
 (0)