Skip to content

Commit

Permalink
Support OpenGL on EGL and allow headless context creation (#3110)
Browse files Browse the repository at this point in the history
* allow headless context creation using EGL

* Fixed dynamic lib import

---------

Co-authored-by: Dahmen issam <[email protected]>
  • Loading branch information
issam3105 and Dahmen issam authored Jun 23, 2023
1 parent 6c8700d commit 47345a3
Showing 1 changed file with 32 additions and 4 deletions.
36 changes: 32 additions & 4 deletions src/glcontext_egl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ namespace bgfx { namespace gl
typedef EGLBoolean (EGLAPIENTRY* PFNEGLSWAPBUFFERSPROC)(EGLDisplay dpy, EGLSurface surface);
typedef EGLBoolean (EGLAPIENTRY* PFNEGLSWAPINTERVALPROC)(EGLDisplay dpy, EGLint interval);
typedef EGLBoolean (EGLAPIENTRY* PFNEGLTERMINATEPROC)(EGLDisplay dpy);
typedef EGLSurface (EGLAPIENTRY* PFNEGLCREATEPBUFFERSURFACEPROC)(EGLDisplay display, EGLConfig config, EGLint const * attrib_list);
typedef EGLSurface (EGLAPIENTRY* PFNEGLGETCURRENTSURFACEPROC)(EGLint readdraw);
typedef EGLContext (EGLAPIENTRY* PFNEGLGETCURRENTCONTEXTPROC)(void);

#define EGL_IMPORT \
EGL_IMPORT_FUNC(PFNEGLCHOOSECONFIGPROC, eglChooseConfig); \
Expand All @@ -54,7 +57,10 @@ namespace bgfx { namespace gl
EGL_IMPORT_FUNC(PGNEGLQUERYSTRINGPROC, eglQueryString); \
EGL_IMPORT_FUNC(PFNEGLSWAPBUFFERSPROC, eglSwapBuffers); \
EGL_IMPORT_FUNC(PFNEGLSWAPINTERVALPROC, eglSwapInterval); \
EGL_IMPORT_FUNC(PFNEGLTERMINATEPROC, eglTerminate);
EGL_IMPORT_FUNC(PFNEGLTERMINATEPROC, eglTerminate); \
EGL_IMPORT_FUNC(PFNEGLCREATEPBUFFERSURFACEPROC,eglCreatePbufferSurface);\
EGL_IMPORT_FUNC(PFNEGLGETCURRENTSURFACEPROC ,eglGetCurrentSurface); \
EGL_IMPORT_FUNC(PFNEGLGETCURRENTCONTEXTPROC ,eglGetCurrentContext);

#define EGL_IMPORT_FUNC(_proto, _func) _proto _func
EGL_IMPORT
Expand Down Expand Up @@ -109,7 +115,16 @@ EGL_IMPORT
{
EGLSurface defaultSurface = eglGetCurrentSurface(EGL_DRAW);

m_surface = eglCreateWindowSurface(m_display, _config, _nwh, NULL);
if(NULL == _nwh)
{
// Create an EGL pbuffer surface
m_surface = eglCreatePbufferSurface(m_display, _config, NULL);
}
else
{
m_surface = eglCreateWindowSurface(m_display, _config, _nwh, NULL);
}

BGFX_FATAL(m_surface != EGL_NO_SURFACE, Fatal::UnableToInitialize, "Failed to create surface.");

m_context = eglCreateContext(m_display, _config, _context, s_contextAttrs);
Expand Down Expand Up @@ -180,7 +195,7 @@ EGL_IMPORT
}
# endif // BX_PLATFORM_WINDOWS

m_display = eglGetDisplay(ndt);
m_display = eglGetDisplay(NULL == ndt ? EGL_DEFAULT_DISPLAY : ndt);
BGFX_FATAL(m_display != EGL_NO_DISPLAY, Fatal::UnableToInitialize, "Failed to create display %p", m_display);

EGLint major = 0;
Expand Down Expand Up @@ -212,11 +227,15 @@ EGL_IMPORT
uint32_t msaaSamples = msaa == 0 ? 0 : 1<<msaa;
m_msaaContext = true;
#endif // BX_PLATFORM_ANDROID

bool headless = NULL == nwh;

EGLint attrs[] =
{
EGL_RENDERABLE_TYPE, (gles >= 30) ? EGL_OPENGL_ES3_BIT_KHR : EGL_OPENGL_ES2_BIT,

EGL_SURFACE_TYPE, headless ? EGL_PBUFFER_BIT : EGL_WINDOW_BIT,

EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
Expand Down Expand Up @@ -274,7 +293,16 @@ EGL_IMPORT
vc_dispmanx_update_submit_sync(dispmanUpdate);
# endif // BX_PLATFORM_ANDROID

m_surface = eglCreateWindowSurface(m_display, m_config, nwh, NULL);
if(headless)
{
// Create an EGL pbuffer surface
EGLint pbAttribs[] = { EGL_WIDTH, static_cast<EGLint>(_width), EGL_HEIGHT, static_cast<EGLint>(_height), EGL_NONE };
m_surface = eglCreatePbufferSurface(m_display, m_config, pbAttribs);
}
else
{
m_surface = eglCreateWindowSurface(m_display, m_config, nwh, NULL);
}
BGFX_FATAL(m_surface != EGL_NO_SURFACE, Fatal::UnableToInitialize, "Failed to create surface.");

const bool hasEglKhrCreateContext = !bx::findIdentifierMatch(extensions, "EGL_KHR_create_context").isEmpty();
Expand Down

0 comments on commit 47345a3

Please sign in to comment.