summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/src/glcontext_egl.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/src/glcontext_egl.cpp')
-rw-r--r--3rdparty/bgfx/src/glcontext_egl.cpp308
1 files changed, 188 insertions, 120 deletions
diff --git a/3rdparty/bgfx/src/glcontext_egl.cpp b/3rdparty/bgfx/src/glcontext_egl.cpp
index 93990746c5b..2850121e5e4 100644
--- a/3rdparty/bgfx/src/glcontext_egl.cpp
+++ b/3rdparty/bgfx/src/glcontext_egl.cpp
@@ -14,48 +14,46 @@
# include <bcm_host.h>
# endif // BX_PLATFORM_RPI
-#ifndef EGL_CONTEXT_MAJOR_VERSION_KHR
-# define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION
-#endif // EGL_CONTEXT_MAJOR_VERSION_KHR
-
-#ifndef EGL_CONTEXT_MINOR_VERSION_KHR
-# define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB
-#endif // EGL_CONTEXT_MINOR_VERSION_KHR
-
namespace bgfx { namespace gl
{
+#ifndef EGL_CONTEXT_FLAG_NO_ERROR_BIT_KHR
+# define EGL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008
+#endif // EGL_CONTEXT_FLAG_NO_ERROR_BIT_KHR
+
#if BGFX_USE_GL_DYNAMIC_LIB
typedef void (*EGLPROC)(void);
- typedef EGLPROC (EGLAPIENTRY* PFNEGLGETPROCADDRESSPROC)(const char *procname);
- typedef EGLBoolean (EGLAPIENTRY* PFNEGLSWAPINTERVALPROC)(EGLDisplay dpy, EGLint interval);
- typedef EGLBoolean (EGLAPIENTRY* PFNEGLMAKECURRENTPROC)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
- typedef EGLContext (EGLAPIENTRY* PFNEGLCREATECONTEXTPROC)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
- typedef EGLSurface (EGLAPIENTRY* PFNEGLCREATEWINDOWSURFACEPROC)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
- typedef EGLBoolean (EGLAPIENTRY* PFNEGLCHOOSECONFIGPROC)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
- typedef EGLBoolean (EGLAPIENTRY* PFNEGLINITIALIZEPROC)(EGLDisplay dpy, EGLint *major, EGLint *minor);
- typedef EGLint (EGLAPIENTRY* PFNEGLGETERRORPROC)(void);
- typedef EGLDisplay (EGLAPIENTRY* PFNEGLGETDISPLAYPROC)(EGLNativeDisplayType display_id);
- typedef EGLBoolean (EGLAPIENTRY* PFNEGLTERMINATEPROC)(EGLDisplay dpy);
- typedef EGLBoolean (EGLAPIENTRY* PFNEGLDESTROYSURFACEPROC)(EGLDisplay dpy, EGLSurface surface);
- typedef EGLBoolean (EGLAPIENTRY* PFNEGLDESTROYCONTEXTPROC)(EGLDisplay dpy, EGLContext ctx);
- typedef EGLBoolean (EGLAPIENTRY* PFNEGLSWAPBUFFERSPROC)(EGLDisplay dpy, EGLSurface surface);
+ typedef EGLBoolean (EGLAPIENTRY* PFNEGLCHOOSECONFIGPROC)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+ typedef EGLContext (EGLAPIENTRY* PFNEGLCREATECONTEXTPROC)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
+ typedef EGLSurface (EGLAPIENTRY* PFNEGLCREATEWINDOWSURFACEPROC)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
+ typedef EGLint (EGLAPIENTRY* PFNEGLGETERRORPROC)(void);
+ typedef EGLDisplay (EGLAPIENTRY* PFNEGLGETDISPLAYPROC)(EGLNativeDisplayType display_id);
+ typedef EGLPROC (EGLAPIENTRY* PFNEGLGETPROCADDRESSPROC)(const char *procname);
+ typedef EGLBoolean (EGLAPIENTRY* PFNEGLINITIALIZEPROC)(EGLDisplay dpy, EGLint *major, EGLint *minor);
+ typedef EGLBoolean (EGLAPIENTRY* PFNEGLMAKECURRENTPROC)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+ typedef EGLBoolean (EGLAPIENTRY* PFNEGLDESTROYCONTEXTPROC)(EGLDisplay dpy, EGLContext ctx);
+ typedef EGLBoolean (EGLAPIENTRY* PFNEGLDESTROYSURFACEPROC)(EGLDisplay dpy, EGLSurface surface);
+ typedef const char* (EGLAPIENTRY* PGNEGLQUERYSTRINGPROC)(EGLDisplay dpy, EGLint name);
+ typedef EGLBoolean (EGLAPIENTRY* PFNEGLSWAPBUFFERSPROC)(EGLDisplay dpy, EGLSurface surface);
+ typedef EGLBoolean (EGLAPIENTRY* PFNEGLSWAPINTERVALPROC)(EGLDisplay dpy, EGLint interval);
+ typedef EGLBoolean (EGLAPIENTRY* PFNEGLTERMINATEPROC)(EGLDisplay dpy);
#define EGL_IMPORT \
- EGL_IMPORT_FUNC(PFNEGLGETPROCADDRESSPROC, eglGetProcAddress); \
- EGL_IMPORT_FUNC(PFNEGLSWAPINTERVALPROC, eglSwapInterval); \
- EGL_IMPORT_FUNC(PFNEGLMAKECURRENTPROC, eglMakeCurrent); \
+ EGL_IMPORT_FUNC(PFNEGLCHOOSECONFIGPROC, eglChooseConfig); \
EGL_IMPORT_FUNC(PFNEGLCREATECONTEXTPROC, eglCreateContext); \
EGL_IMPORT_FUNC(PFNEGLCREATEWINDOWSURFACEPROC, eglCreateWindowSurface); \
- EGL_IMPORT_FUNC(PFNEGLCHOOSECONFIGPROC, eglChooseConfig); \
- EGL_IMPORT_FUNC(PFNEGLINITIALIZEPROC, eglInitialize); \
- EGL_IMPORT_FUNC(PFNEGLGETERRORPROC, eglGetError); \
EGL_IMPORT_FUNC(PFNEGLGETDISPLAYPROC, eglGetDisplay); \
- EGL_IMPORT_FUNC(PFNEGLTERMINATEPROC, eglTerminate); \
- EGL_IMPORT_FUNC(PFNEGLDESTROYSURFACEPROC, eglDestroySurface); \
+ EGL_IMPORT_FUNC(PFNEGLGETERRORPROC, eglGetError); \
+ EGL_IMPORT_FUNC(PFNEGLGETPROCADDRESSPROC, eglGetProcAddress); \
EGL_IMPORT_FUNC(PFNEGLDESTROYCONTEXTPROC, eglDestroyContext); \
- EGL_IMPORT_FUNC(PFNEGLSWAPBUFFERSPROC, eglSwapBuffers);
+ EGL_IMPORT_FUNC(PFNEGLDESTROYSURFACEPROC, eglDestroySurface); \
+ EGL_IMPORT_FUNC(PFNEGLINITIALIZEPROC, eglInitialize); \
+ EGL_IMPORT_FUNC(PFNEGLMAKECURRENTPROC, eglMakeCurrent); \
+ EGL_IMPORT_FUNC(PGNEGLQUERYSTRINGPROC, eglQueryString); \
+ EGL_IMPORT_FUNC(PFNEGLSWAPBUFFERSPROC, eglSwapBuffers); \
+ EGL_IMPORT_FUNC(PFNEGLSWAPINTERVALPROC, eglSwapInterval); \
+ EGL_IMPORT_FUNC(PFNEGLTERMINATEPROC, eglTerminate);
#define EGL_IMPORT_FUNC(_proto, _func) _proto _func
EGL_IMPORT
@@ -100,22 +98,7 @@ EGL_IMPORT
# define GL_IMPORT(_optional, _proto, _func, _import) _proto _func = NULL
# include "glimports.h"
- static const EGLint s_contextAttrs[] =
- {
-# if BGFX_CONFIG_RENDERER_OPENGLES >= 30
- EGL_CONTEXT_MAJOR_VERSION_KHR, 3,
-# if BGFX_CONFIG_RENDERER_OPENGLES >= 31
- EGL_CONTEXT_MINOR_VERSION_KHR, 1,
-# else
- // EGL_CONTEXT_MINOR_VERSION_KHR, 0,
-# endif // BGFX_CONFIG_RENDERER_OPENGLES >= 31
-# elif BGFX_CONFIG_RENDERER_OPENGLES
- EGL_CONTEXT_MAJOR_VERSION_KHR, 2,
- // EGL_CONTEXT_MINOR_VERSION_KHR, 0,
-# endif // BGFX_CONFIG_RENDERER_
-
- EGL_NONE
- };
+ static EGLint s_contextAttrs[16];
struct SwapChainGL
{
@@ -178,85 +161,154 @@ EGL_IMPORT
m_eglLibrary = eglOpen();
- BX_UNUSED(_width, _height);
- EGLNativeDisplayType ndt = EGL_DEFAULT_DISPLAY;
- EGLNativeWindowType nwh = (EGLNativeWindowType)NULL;
+ if (NULL == g_platformData.context)
+ {
+ BX_UNUSED(_width, _height);
+ EGLNativeDisplayType ndt = (EGLNativeDisplayType)g_platformData.ndt;
+ EGLNativeWindowType nwh = (EGLNativeWindowType )g_platformData.nwh;
+
# if BX_PLATFORM_WINDOWS
- ndt = GetDC(g_bgfxHwnd);
- nwh = g_bgfxHwnd;
-# elif BX_PLATFORM_LINUX
- ndt = (EGLNativeDisplayType)g_bgfxX11Display;
- nwh = (EGLNativeWindowType)g_bgfxX11Window;
-# endif // BX_PLATFORM_
- m_display = eglGetDisplay(ndt);
- BGFX_FATAL(m_display != EGL_NO_DISPLAY, Fatal::UnableToInitialize, "Failed to create display %p", m_display);
+ if (NULL == g_platformData.ndt)
+ {
+ ndt = GetDC( (HWND)g_platformData.nwh);
+ }
+# endif // BX_PLATFORM_WINDOWS
- EGLint major = 0;
- EGLint minor = 0;
- EGLBoolean success = eglInitialize(m_display, &major, &minor);
- BGFX_FATAL(success && major >= 1 && minor >= 3, Fatal::UnableToInitialize, "Failed to initialize %d.%d", major, minor);
+ m_display = eglGetDisplay(ndt);
+ BGFX_FATAL(m_display != EGL_NO_DISPLAY, Fatal::UnableToInitialize, "Failed to create display %p", m_display);
- EGLint attrs[] =
- {
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGLint major = 0;
+ EGLint minor = 0;
+ EGLBoolean success = eglInitialize(m_display, &major, &minor);
+ BGFX_FATAL(success && major >= 1 && minor >= 3, Fatal::UnableToInitialize, "Failed to initialize %d.%d", major, minor);
+
+ BX_TRACE("EGL info:");
+ const char* clientApis = eglQueryString(m_display, EGL_CLIENT_APIS);
+ BX_TRACE(" APIs: %s", clientApis); BX_UNUSED(clientApis);
+
+ const char* vendor = eglQueryString(m_display, EGL_VENDOR);
+ BX_TRACE(" Vendor: %s", vendor); BX_UNUSED(vendor);
+
+ const char* version = eglQueryString(m_display, EGL_VERSION);
+ BX_TRACE("Version: %s", version); BX_UNUSED(version);
+
+ const char* extensions = eglQueryString(m_display, EGL_EXTENSIONS);
+ BX_TRACE("Supported EGL extensions:");
+ dumpExtensions(extensions);
+
+ EGLint attrs[] =
+ {
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
# if BX_PLATFORM_ANDROID
- EGL_DEPTH_SIZE, 16,
+ EGL_DEPTH_SIZE, 16,
# else
- EGL_DEPTH_SIZE, 24,
+ EGL_DEPTH_SIZE, 24,
# endif // BX_PLATFORM_
- EGL_STENCIL_SIZE, 8,
+ EGL_STENCIL_SIZE, 8,
- EGL_NONE
- };
+ EGL_NONE
+ };
- EGLint numConfig = 0;
- success = eglChooseConfig(m_display, attrs, &m_config, 1, &numConfig);
- BGFX_FATAL(success, Fatal::UnableToInitialize, "eglChooseConfig");
+ EGLint numConfig = 0;
+ success = eglChooseConfig(m_display, attrs, &m_config, 1, &numConfig);
+ BGFX_FATAL(success, Fatal::UnableToInitialize, "eglChooseConfig");
# if BX_PLATFORM_ANDROID
- EGLint format;
- eglGetConfigAttrib(m_display, m_config, EGL_NATIVE_VISUAL_ID, &format);
- ANativeWindow_setBuffersGeometry(g_bgfxAndroidWindow, _width, _height, format);
- nwh = g_bgfxAndroidWindow;
+
+ EGLint format;
+ eglGetConfigAttrib(m_display, m_config, EGL_NATIVE_VISUAL_ID, &format);
+ ANativeWindow_setBuffersGeometry( (ANativeWindow*)g_platformData.nwh, _width, _height, format);
+
# elif BX_PLATFORM_RPI
- DISPMANX_DISPLAY_HANDLE_T dispmanDisplay = vc_dispmanx_display_open(0);
- DISPMANX_UPDATE_HANDLE_T dispmanUpdate = vc_dispmanx_update_start(0);
-
- VC_RECT_T dstRect = { 0, 0, _width, _height };
- VC_RECT_T srcRect = { 0, 0, _width << 16, _height << 16 };
-
- DISPMANX_ELEMENT_HANDLE_T dispmanElement = vc_dispmanx_element_add(dispmanUpdate
- , dispmanDisplay
- , 0
- , &dstRect
- , 0
- , &srcRect
- , DISPMANX_PROTECTION_NONE
- , NULL
- , NULL
- , DISPMANX_NO_ROTATE
- );
-
- s_dispmanWindow.element = dispmanElement;
- s_dispmanWindow.width = _width;
- s_dispmanWindow.height = _height;
- nwh = &s_dispmanWindow;
-
- vc_dispmanx_update_submit_sync(dispmanUpdate);
+ DISPMANX_DISPLAY_HANDLE_T dispmanDisplay = vc_dispmanx_display_open(0);
+ DISPMANX_UPDATE_HANDLE_T dispmanUpdate = vc_dispmanx_update_start(0);
+
+ VC_RECT_T dstRect = { 0, 0, _width, _height };
+ VC_RECT_T srcRect = { 0, 0, _width << 16, _height << 16 };
+
+ DISPMANX_ELEMENT_HANDLE_T dispmanElement = vc_dispmanx_element_add(dispmanUpdate
+ , dispmanDisplay
+ , 0
+ , &dstRect
+ , 0
+ , &srcRect
+ , DISPMANX_PROTECTION_NONE
+ , NULL
+ , NULL
+ , DISPMANX_NO_ROTATE
+ );
+
+ s_dispmanWindow.element = dispmanElement;
+ s_dispmanWindow.width = _width;
+ s_dispmanWindow.height = _height;
+ nwh = &s_dispmanWindow;
+
+ vc_dispmanx_update_submit_sync(dispmanUpdate);
# endif // BX_PLATFORM_ANDROID
- m_surface = eglCreateWindowSurface(m_display, m_config, nwh, NULL);
- BGFX_FATAL(m_surface != EGL_NO_SURFACE, Fatal::UnableToInitialize, "Failed to create surface.");
+ 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");
+ const bool hasEglKhrNoError = !!bx::findIdentifierMatch(extensions, "EGL_KHR_create_context_no_error");
+
+ for (uint32_t ii = 0; ii < 2; ++ii)
+ {
+ bx::StaticMemoryBlockWriter writer(s_contextAttrs, sizeof(s_contextAttrs) );
+
+ EGLint flags = 0;
+
+ if (hasEglKhrCreateContext)
+ {
+ bx::write(&writer, EGLint(EGL_CONTEXT_MAJOR_VERSION_KHR) );
+ bx::write(&writer, EGLint(BGFX_CONFIG_RENDERER_OPENGLES / 10) );
+
+ bx::write(&writer, EGLint(EGL_CONTEXT_MINOR_VERSION_KHR) );
+ bx::write(&writer, EGLint(BGFX_CONFIG_RENDERER_OPENGLES % 10) );
+
+ flags |= BGFX_CONFIG_DEBUG && hasEglKhrNoError ? 0
+ | EGL_CONTEXT_FLAG_NO_ERROR_BIT_KHR
+ : 0
+ ;
+
+ if (0 == ii)
+ {
+ flags |= BGFX_CONFIG_DEBUG ? 0
+ | EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
+// | EGL_OPENGL_ES3_BIT_KHR
+ : 0
+ ;
+
+ bx::write(&writer, EGLint(EGL_CONTEXT_FLAGS_KHR) );
+ bx::write(&writer, flags);
+ }
+ }
+ else
+ {
+ bx::write(&writer, EGLint(EGL_CONTEXT_CLIENT_VERSION) );
+ bx::write(&writer, 2);
+ }
+
+ bx::write(&writer, EGLint(EGL_NONE) );
+
+ m_context = eglCreateContext(m_display, m_config, EGL_NO_CONTEXT, s_contextAttrs);
+ if (NULL != m_context)
+ {
+ break;
+ }
+
+ BX_TRACE("Failed to create EGL context with EGL_CONTEXT_FLAGS_KHR (%08x).", flags);
+ }
- m_context = eglCreateContext(m_display, m_config, EGL_NO_CONTEXT, s_contextAttrs);
- BGFX_FATAL(m_context != EGL_NO_CONTEXT, Fatal::UnableToInitialize, "Failed to create context.");
+ BGFX_FATAL(m_context != EGL_NO_CONTEXT, Fatal::UnableToInitialize, "Failed to create context.");
- success = eglMakeCurrent(m_display, m_surface, m_surface, m_context);
- BGFX_FATAL(success, Fatal::UnableToInitialize, "Failed to set context.");
- m_current = NULL;
+ success = eglMakeCurrent(m_display, m_surface, m_surface, m_context);
+ BGFX_FATAL(success, Fatal::UnableToInitialize, "Failed to set context.");
+ m_current = NULL;
- eglSwapInterval(m_display, 0);
+ eglSwapInterval(m_display, 0);
+ }
# if BX_PLATFORM_EMSCRIPTEN
emscripten_set_canvas_size(_width, _height);
@@ -267,11 +319,14 @@ EGL_IMPORT
void GlContext::destroy()
{
- eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- eglDestroyContext(m_display, m_context);
- eglDestroySurface(m_display, m_surface);
- eglTerminate(m_display);
- m_context = NULL;
+ if (NULL != m_display)
+ {
+ eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglDestroyContext(m_display, m_context);
+ eglDestroySurface(m_display, m_surface);
+ eglTerminate(m_display);
+ m_context = NULL;
+ }
eglClose(m_eglLibrary);
@@ -283,14 +338,21 @@ EGL_IMPORT
void GlContext::resize(uint32_t _width, uint32_t _height, uint32_t _flags)
{
BX_UNUSED(_width, _height);
+
# if BX_PLATFORM_ANDROID
- EGLint format;
- eglGetConfigAttrib(m_display, m_config, EGL_NATIVE_VISUAL_ID, &format);
- ANativeWindow_setBuffersGeometry(g_bgfxAndroidWindow, _width, _height, format);
+ if (NULL != m_display)
+ {
+ EGLint format;
+ eglGetConfigAttrib(m_display, m_config, EGL_NATIVE_VISUAL_ID, &format);
+ ANativeWindow_setBuffersGeometry( (ANativeWindow*)g_platformData.nwh, _width, _height, format);
+ }
# endif // BX_PLATFORM_ANDROID
- bool vsync = !!(_flags&BGFX_RESET_VSYNC);
- eglSwapInterval(m_display, vsync ? 1 : 0);
+ if (NULL != m_display)
+ {
+ bool vsync = !!(_flags&BGFX_RESET_VSYNC);
+ eglSwapInterval(m_display, vsync ? 1 : 0);
+ }
}
bool GlContext::isSwapChainSupported()
@@ -317,7 +379,10 @@ EGL_IMPORT
if (NULL == _swapChain)
{
- eglSwapBuffers(m_display, m_surface);
+ if (NULL != m_display)
+ {
+ eglSwapBuffers(m_display, m_surface);
+ }
}
else
{
@@ -333,7 +398,10 @@ EGL_IMPORT
if (NULL == _swapChain)
{
- eglMakeCurrent(m_display, m_surface, m_surface, m_context);
+ if (NULL != m_display)
+ {
+ eglMakeCurrent(m_display, m_surface, m_surface, m_context);
+ }
}
else
{