Browse Source

User must now provide EGLDisplay also to build a WindowlessEGL shared context

pull/437/head
aspioupiou 6 years ago
parent
commit
b383badf6d
  1. 36
      src/Magnum/Platform/WindowlessEglApplication.cpp
  2. 18
      src/Magnum/Platform/WindowlessEglApplication.h

36
src/Magnum/Platform/WindowlessEglApplication.cpp

@ -84,6 +84,23 @@ bool extensionSupported(const char* const extensions, Containers::ArrayView<cons
WindowlessEglContext::WindowlessEglContext(const Configuration& configuration, GLContext* const magnumContext) {
#ifndef MAGNUM_TARGET_WEBGL
/**
* The user provided a shared context and its associated display, so we don't query the display
*/
if(configuration.sharedContext() != EGL_NO_CONTEXT &&
configuration.sharedDisplay() != EGL_NO_DISPLAY)
{
_display = configuration.sharedDisplay();
_sharedContext = true;
}
/**
* The user provided only the shared context or display, or provided both but one of them is wrong
*/
else if (configuration.sharedContext() == EGL_NO_CONTEXT && configuration.sharedDisplay() != EGL_NO_DISPLAY ||
configuration.sharedContext() != EGL_NO_CONTEXT && configuration.sharedDisplay() == EGL_NO_DISPLAY)
{
Error{} << "Platform::WindowlessEglContext: Either context or display is not valid. Context is " << configuration.sharedContext() << " Display is " << configuration.sharedDisplay();
}
/* If relevant extensions are supported, try to find some display using
those APIs, as that works reliably also when running headless. This
@ -152,7 +169,7 @@ WindowlessEglContext::WindowlessEglContext(const Configuration& configuration, G
Containers::Array<EGLDeviceEXT> devices{configuration.device() + 1};
CORRADE_INTERNAL_ASSERT_OUTPUT(eglQueryDevices(configuration.device() + 1, devices, &count));
if(!(_display = reinterpret_cast<EGLDisplay(*)(EGLenum, void*, const EGLint*)>(eglGetProcAddress("eglGetPlatformDisplayEXT"))(EGL_PLATFORM_DEVICE_EXT, devices[configuration.device()], nullptr))) {
if(!_sharedContext && !(_display = reinterpret_cast<EGLDisplay(*)(EGLenum, void*, const EGLint*)>(eglGetProcAddress("eglGetPlatformDisplayEXT"))(EGL_PLATFORM_DEVICE_EXT, devices[configuration.device()], nullptr))) {
Error{} << "Platform::WindowlessEglApplication::tryCreateContext(): cannot get platform display for a device:" << Implementation::eglErrorString(eglGetError());
return;
}
@ -168,16 +185,19 @@ WindowlessEglContext::WindowlessEglContext(const Configuration& configuration, G
}
#endif
if(!(_display = eglGetDisplay(EGL_DEFAULT_DISPLAY))) {
if(!_sharedContext && !(_display = eglGetDisplay(EGL_DEFAULT_DISPLAY))) {
Error{} << "Platform::WindowlessEglApplication::tryCreateContext(): cannot get default EGL display:" << Implementation::eglErrorString(eglGetError());
return;
}
}
if(!eglInitialize(_display, nullptr, nullptr)) {
Error() << "Platform::WindowlessEglApplication::tryCreateContext(): cannot initialize EGL:" << Implementation::eglErrorString(eglGetError());
return;
}
/**
* We must initialize the display if and only if we don't use a shared context
*/
if(!_sharedContext && !eglInitialize(_display, nullptr, nullptr)) {
Error() << "Platform::WindowlessEglApplication::tryCreateContext(): cannot initialize EGL:" << Implementation::eglErrorString(eglGetError());
return;
}
const EGLenum api =
#ifndef MAGNUM_TARGET_GLES
@ -274,9 +294,7 @@ WindowlessEglContext::WindowlessEglContext(const Configuration& configuration, G
contextFlags = EGL_NONE;
}
#endif
if(configuration.sharedContext() != EGL_NO_CONTEXT) _sharedContext = true;
if(!(_context = eglCreateContext(_display, config,
#ifndef MAGNUM_TARGET_WEBGL
configuration.sharedContext(),

18
src/Magnum/Platform/WindowlessEglApplication.h

@ -276,16 +276,21 @@ class WindowlessEglContext::Configuration {
* @m_since_latest
*
* When set, the created context will share a subset of OpenGL objects
* with @p context, instead of being independent. Many caveats and
* with @p context whose associated display is @p display, instead of being independent.
* Many caveats and
* limitations apply to shared OpenGL contexts, please consult the
* OpenGL specification for details. Default is `EGL_NO_CONTEXT`, i.e.
* no sharing.
*
* @note @p display must be provided to avoid errors on destruction, since
* the display is shared among shared-context on EGL.
* @see @ref WindowlessEglContext::glContext(),
* @ref WindowlessEglApplication::glContext()
* @requires_gles Context sharing is not available in WebGL.
*/
Configuration& setSharedContext(EGLContext context) {
Configuration& setSharedContext(EGLContext context, EGLDisplay display) {
_sharedContext = context;
_sharedDisplay = display;
return *this;
}
@ -296,6 +301,14 @@ class WindowlessEglContext::Configuration {
* @requires_gles Context sharing is not available in WebGL.
*/
EGLContext sharedContext() const { return _sharedContext; }
/**
* @brief Shared display
* @m_since_latest
*
* @requires_gles Context sharing is not available in WebGL.
*/
EGLContext sharedDisplay() const { return _sharedDisplay; }
#endif
private:
@ -303,6 +316,7 @@ class WindowlessEglContext::Configuration {
Flags _flags;
UnsignedInt _device;
EGLContext _sharedContext = EGL_NO_CONTEXT;
EGLDisplay _sharedDisplay = EGL_NO_DISPLAY;
#endif
};

Loading…
Cancel
Save