Browse Source

Platform: expose GL forward compatibility flag also in windowless apps.

Similar change to the windowed apps, also resetting it when core context
creation fails or when the workaround is applied. This change is not
done for CGL, iOS and Windows EGL apps, as these are either GLES-only
or, in case of macOS, such flag is not available.
pull/268/merge
Vladimír Vondruš 8 years ago
parent
commit
7ba24c813c
  1. 7
      doc/changelog.dox
  2. 8
      src/Magnum/Platform/WindowlessEglApplication.cpp
  3. 54
      src/Magnum/Platform/WindowlessEglApplication.h
  4. 13
      src/Magnum/Platform/WindowlessGlxApplication.cpp
  5. 50
      src/Magnum/Platform/WindowlessGlxApplication.h
  6. 17
      src/Magnum/Platform/WindowlessWglApplication.cpp
  7. 51
      src/Magnum/Platform/WindowlessWglApplication.h
  8. 28
      src/Magnum/Platform/WindowlessWindowsEglApplication.h

7
doc/changelog.dox

@ -143,6 +143,13 @@ See also:
added @ref Platform::Sdl2Application::GLConfiguration::addFlags() "GLConfiguration::addFlags()"
and @ref Platform::Sdl2Application::GLConfiguration::clearFlags() "GLConfiguration::clearFlags()"
for easier flag handling
- Exposed enabled-by-default @ref Platform::WindowlessEglApplication::Configuration::Flag::ForwardCompatible "Configuration::Flag::ForwardCompatible"
flag in @ref Platform::WindowlessEglApplication,
@ref Platform::WindowlessGlxApplication and
@ref Platform::WindowlessWglApplication,
added @ref Platform::WindowlessEglApplication::Configuration::addFlags() "Configuration::addFlags()"
and @ref Platform::WindowlessEglApplication::Configuration::clearFlags() "Configuration::clearFlags()"
for easier flag handling
@subsubsection changelog-latest-new-primitives Primitives library

8
src/Magnum/Platform/WindowlessEglApplication.cpp

@ -188,6 +188,14 @@ bool WindowlessEglContext::makeCurrent() {
return false;
}
WindowlessEglContext::Configuration::Configuration()
#ifndef MAGNUM_TARGET_GLES
: _flags{Flag::ForwardCompatible}
#elif !defined(MAGNUM_TARGET_WEBGL)
: _flags{}
#endif
{}
#ifndef DOXYGEN_GENERATING_OUTPUT
WindowlessEglApplication::WindowlessEglApplication(const Arguments& arguments): WindowlessEglApplication{arguments, Configuration{}} {}
#endif

54
src/Magnum/Platform/WindowlessEglApplication.h

@ -139,6 +139,16 @@ class WindowlessEglContext::Configuration {
* @requires_gles Context flags are not available in WebGL.
*/
enum class Flag: int {
#ifndef MAGNUM_TARGET_GLES
/**
* Forward compatible context
*
* @requires_gl Core/compatibility profile distinction and forward
* compatibility applies only to desktop GL.
*/
ForwardCompatible = EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR,
#endif
Debug = EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR /**< Create debug context */
};
@ -149,13 +159,17 @@ class WindowlessEglContext::Configuration {
* @requires_gles Context flags are not available in WebGL.
*/
#ifndef DOXYGEN_GENERATING_OUTPUT
typedef Containers::EnumSet<Flag, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR> Flags;
typedef Containers::EnumSet<Flag, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
#ifndef MAGNUM_TARGET_GLES
|EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR
#endif
> Flags;
#else
typedef Containers::EnumSet<Flag> Flags;
#endif
#endif
constexpr /*implicit*/ Configuration() {}
/*implicit*/ Configuration();
#ifndef MAGNUM_TARGET_WEBGL
/**
@ -169,13 +183,43 @@ class WindowlessEglContext::Configuration {
* @brief Set context flags
* @return Reference to self (for method chaining)
*
* Default is no flag. See also @ref GL::Context::flags().
* Default is @ref Flag::ForwardCompatible on desktop GL and no flags
* on OpenGL ES.
* @see @ref addFlags(), @ref clearFlags(), @ref GL::Context::flags()
* @requires_gles Context flags are not available in WebGL.
*/
Configuration& setFlags(Flags flags) {
_flags = flags;
return *this;
}
/**
* @brief Add context flags
* @return Reference to self (for method chaining)
*
* Unlike @ref setFlags(), ORs the flags with existing instead of
* replacing them. Useful for preserving the defaults.
* @see @ref clearFlags()
* @requires_gles Context flags are not available in WebGL.
*/
Configuration& addFlags(Flags flags) {
_flags |= flags;
return *this;
}
/**
* @brief Clear context flags
* @return Reference to self (for method chaining)
*
* Unlike @ref setFlags(), ANDs the inverse of @p flags with existing
* instead of replacing them. Useful for removing default flags.
* @see @ref addFlags()
* @requires_gles Context flags are not available in WebGL.
*/
Configuration& clearFlags(Flags flags) {
_flags &= ~flags;
return *this;
}
#endif
private:
@ -184,6 +228,10 @@ class WindowlessEglContext::Configuration {
#endif
};
#ifndef MAGNUM_TARGET_WEBGL
CORRADE_ENUMSET_OPERATORS(WindowlessEglContext::Configuration::Flags)
#endif
/**
@brief Windowless EGL application

13
src/Magnum/Platform/WindowlessGlxApplication.cpp

@ -85,7 +85,7 @@ WindowlessGlxContext::WindowlessGlxContext(const WindowlessGlxContext::Configura
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 1,
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB|GLint(configuration.flags()),
GLX_CONTEXT_FLAGS_ARB, GLint(configuration.flags()),
#endif
0
};
@ -130,7 +130,8 @@ WindowlessGlxContext::WindowlessGlxContext(const WindowlessGlxContext::Configura
/* Destroy the core context and create a compatibility one */
glXDestroyContext(_display, _context);
const GLint fallbackContextAttributes[] = {
GLX_CONTEXT_FLAGS_ARB, GLint(configuration.flags()),
/** @todo keep the fwcompat? */
GLX_CONTEXT_FLAGS_ARB, GLint(configuration.flags() & ~Configuration::Flag::ForwardCompatible),
0
};
_context = glXCreateContextAttribsARB(_display, configs[0], nullptr, True, fallbackContextAttributes);
@ -180,6 +181,14 @@ bool WindowlessGlxContext::makeCurrent() {
return false;
}
WindowlessGlxContext::Configuration::Configuration():
#ifndef MAGNUM_TARGET_GLES
_flags{Flag::ForwardCompatible}
#else
_flags{}
#endif
{}
#ifndef DOXYGEN_GENERATING_OUTPUT
WindowlessGlxApplication::WindowlessGlxApplication(const Arguments& arguments): WindowlessGlxApplication{arguments, Configuration{}} {}
#endif

50
src/Magnum/Platform/WindowlessGlxApplication.h

@ -148,6 +148,16 @@ class WindowlessGlxContext::Configuration {
* @see @ref Flags, @ref setFlags(), @ref Context::Flag
*/
enum class Flag: int {
#ifndef MAGNUM_TARGET_GLES
/**
* Forward compatible context
*
* @requires_gl Core/compatibility profile distinction and forward
* compatibility applies only to desktop GL.
*/
ForwardCompatible = GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
#endif
Debug = GLX_CONTEXT_DEBUG_BIT_ARB /**< Create debug context */
};
@ -157,12 +167,16 @@ class WindowlessGlxContext::Configuration {
* @see @ref setFlags(), @ref Context::Flags
*/
#ifndef DOXYGEN_GENERATING_OUTPUT
typedef Containers::EnumSet<Flag, GLX_CONTEXT_DEBUG_BIT_ARB> Flags;
typedef Containers::EnumSet<Flag, GLX_CONTEXT_DEBUG_BIT_ARB
#ifndef MAGNUM_TARGET_GLES
|GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
#endif
> Flags;
#else
typedef Containers::EnumSet<Flag> Flags;
#endif
constexpr /*implicit*/ Configuration() {}
/*implicit*/ Configuration();
/** @brief Context flags */
Flags flags() const { return _flags; }
@ -171,17 +185,47 @@ class WindowlessGlxContext::Configuration {
* @brief Set context flags
* @return Reference to self (for method chaining)
*
* Default is no flag. See also @ref GL::Context::flags().
* Default is @ref Flag::ForwardCompatible on desktop GL and no flags
* on OpenGL ES.
* @see @ref addFlags(), @ref clearFlags(), @ref GL::Context::flags()
*/
Configuration& setFlags(Flags flags) {
_flags = flags;
return *this;
}
/**
* @brief Add context flags
* @return Reference to self (for method chaining)
*
* Unlike @ref setFlags(), ORs the flags with existing instead of
* replacing them. Useful for preserving the defaults.
* @see @ref clearFlags()
*/
Configuration& addFlags(Flags flags) {
_flags |= flags;
return *this;
}
/**
* @brief Clear context flags
* @return Reference to self (for method chaining)
*
* Unlike @ref setFlags(), ANDs the inverse of @p flags with existing
* instead of replacing them. Useful for removing default flags.
* @see @ref addFlags()
*/
Configuration& clearFlags(Flags flags) {
_flags &= ~flags;
return *this;
}
private:
Flags _flags;
};
CORRADE_ENUMSET_OPERATORS(WindowlessGlxContext::Configuration::Flags)
/**
@brief Windowless GLX application

17
src/Magnum/Platform/WindowlessWglApplication.cpp

@ -40,7 +40,6 @@
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
#endif
@ -137,7 +136,7 @@ WindowlessWglContext::WindowlessWglContext(const Configuration& configuration, G
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 1,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB|GLint(configuration.flags()),
WGL_CONTEXT_FLAGS_ARB, GLint(configuration.flags()),
#endif
0
};
@ -149,7 +148,8 @@ WindowlessWglContext::WindowlessWglContext(const Configuration& configuration, G
Warning() << "Platform::WindowlessWglContext: cannot create core context, falling back to compatibility context:" << GetLastError();
const int fallbackContextAttributes[] = {
WGL_CONTEXT_FLAGS_ARB, int(configuration.flags()),
/** @todo or keep the fwcompat? */
WGL_CONTEXT_FLAGS_ARB, GLint(configuration.flags() & ~Configuration::Flag::ForwardCompatible),
0
};
_context = wglCreateContextAttribsARB(_deviceContext, nullptr, fallbackContextAttributes);
@ -184,7 +184,8 @@ WindowlessWglContext::WindowlessWglContext(const Configuration& configuration, G
/* Destroy the core context and create a compatibility one */
wglDeleteContext(_context);
const int fallbackContextAttributes[] = {
WGL_CONTEXT_FLAGS_ARB, int(configuration.flags()),
/** @todo or keep the fwcompat? */
WGL_CONTEXT_FLAGS_ARB, GLint(configuration.flags() & ~Configuration::Flag::ForwardCompatible),
0
};
_context = wglCreateContextAttribsARB(_deviceContext, nullptr, fallbackContextAttributes);
@ -234,6 +235,14 @@ bool WindowlessWglContext::makeCurrent() {
return false;
}
WindowlessWglContext::Configuration::Configuration():
#ifndef MAGNUM_TARGET_GLES
_flags{Flag::ForwardCompatible}
#else
_flags{}
#endif
{}
#ifndef DOXYGEN_GENERATING_OUTPUT
WindowlessWglApplication::WindowlessWglApplication(const Arguments& arguments): WindowlessWglApplication{arguments, Configuration{}} {}
#endif

51
src/Magnum/Platform/WindowlessWglApplication.h

@ -46,6 +46,7 @@
/* Define stuff that we need because I can't be bothered with creating a new
header just for a few defines */
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
#endif
namespace Magnum { namespace Platform {
@ -147,6 +148,16 @@ class WindowlessWglContext::Configuration {
* @see @ref Flags, @ref setFlags(), @ref Context::Flag
*/
enum class Flag: int {
#ifndef MAGNUM_TARGET_GLES
/**
* Forward compatible context
*
* @requires_gl Core/compatibility profile distinction and forward
* compatibility applies only to desktop GL.
*/
ForwardCompatible = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
#endif
Debug = WGL_CONTEXT_DEBUG_BIT_ARB /**< Create debug context */
};
@ -156,12 +167,16 @@ class WindowlessWglContext::Configuration {
* @see @ref setFlags(), @ref Context::Flags
*/
#ifndef DOXYGEN_GENERATING_OUTPUT
typedef Containers::EnumSet<Flag, WGL_CONTEXT_DEBUG_BIT_ARB> Flags;
typedef Containers::EnumSet<Flag, WGL_CONTEXT_DEBUG_BIT_ARB
#ifndef MAGNUM_TARGET_GLES
|WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
#endif
> Flags;
#else
typedef Containers::EnumSet<Flag> Flags;
#endif
constexpr /*implicit*/ Configuration() {}
/*implicit*/ Configuration();
/** @brief Context flags */
Flags flags() const { return _flags; }
@ -170,17 +185,47 @@ class WindowlessWglContext::Configuration {
* @brief Set context flags
* @return Reference to self (for method chaining)
*
* Default is no flag. See also @ref GL::Context::flags().
* Default is @ref Flag::ForwardCompatible on desktop GL and no flags
* on OpenGL ES.
* @see @ref addFlags(), @ref clearFlags(), @ref GL::Context::flags()
*/
Configuration& setFlags(Flags flags) {
_flags = flags;
return *this;
}
/**
* @brief Add context flags
* @return Reference to self (for method chaining)
*
* Unlike @ref setFlags(), ORs the flags with existing instead of
* replacing them. Useful for preserving the defaults.
* @see @ref clearFlags()
*/
Configuration& addFlags(Flags flags) {
_flags |= flags;
return *this;
}
/**
* @brief Clear context flags
* @return Reference to self (for method chaining)
*
* Unlike @ref setFlags(), ANDs the inverse of @p flags with existing
* instead of replacing them. Useful for removing default flags.
* @see @ref addFlags()
*/
Configuration& clearFlags(Flags flags) {
_flags &= ~flags;
return *this;
}
private:
Flags _flags;
};
CORRADE_ENUMSET_OPERATORS(WindowlessWglContext::Configuration::Flags)
/**
@brief Windowless WGL application

28
src/Magnum/Platform/WindowlessWindowsEglApplication.h

@ -164,10 +164,38 @@ class WindowlessWindowsEglContext::Configuration {
return *this;
}
/**
* @brief Add context flags
* @return Reference to self (for method chaining)
*
* Unlike @ref setFlags(), ORs the flags with existing instead of
* replacing them. Useful for preserving the defaults.
* @see @ref clearFlags()
*/
Configuration& addFlags(Flags flags) {
_flags |= flags;
return *this;
}
/**
* @brief Clear context flags
* @return Reference to self (for method chaining)
*
* Unlike @ref setFlags(), ANDs the inverse of @p flags with existing
* instead of replacing them. Useful for removing default flags.
* @see @ref addFlags()
*/
Configuration& clearFlags(Flags flags) {
_flags &= ~flags;
return *this;
}
private:
Flags _flags;
};
CORRADE_ENUMSET_OPERATORS(WindowlessWindowsEglContext::Configuration::Flags)
/**
@brief Windowless Windows/EGL application

Loading…
Cancel
Save