Browse Source

GL,Platform: introduce GL::Context::Configuration::Flag::Windowless.

With this flag set (which is done implicitly for all windowless apps
and, conversely, not done for all windowed apps), the default
framebuffer state isn't touched in any way, which should avoid potential
race conditions with default framebuffer on another thread.
euler-xxx
Vladimír Vondruš 5 years ago
parent
commit
46df57f6d5
  1. 7
      doc/changelog.dox
  2. 12
      src/Magnum/GL/Context.cpp
  3. 14
      src/Magnum/GL/Context.h
  4. 19
      src/Magnum/GL/Framebuffer.cpp
  5. 4
      src/Magnum/Platform/AbstractXApplication.h
  6. 4
      src/Magnum/Platform/AndroidApplication.h
  7. 4
      src/Magnum/Platform/EmscriptenApplication.h
  8. 4
      src/Magnum/Platform/GlfwApplication.h
  9. 4
      src/Magnum/Platform/Sdl2Application.h
  10. 4
      src/Magnum/Platform/WindowlessCglApplication.cpp
  11. 6
      src/Magnum/Platform/WindowlessCglApplication.h
  12. 1
      src/Magnum/Platform/WindowlessEglApplication.cpp
  13. 4
      src/Magnum/Platform/WindowlessEglApplication.h
  14. 1
      src/Magnum/Platform/WindowlessGlxApplication.cpp
  15. 4
      src/Magnum/Platform/WindowlessGlxApplication.h
  16. 6
      src/Magnum/Platform/WindowlessIosApplication.h
  17. 4
      src/Magnum/Platform/WindowlessIosApplication.mm
  18. 1
      src/Magnum/Platform/WindowlessWglApplication.cpp
  19. 4
      src/Magnum/Platform/WindowlessWglApplication.h
  20. 4
      src/Magnum/Platform/WindowlessWindowsEglApplication.cpp
  21. 6
      src/Magnum/Platform/WindowlessWindowsEglApplication.h

7
doc/changelog.dox

@ -196,6 +196,13 @@ See also:
now advertised as a @cpp "intel-windows-chatty-shader-compiler" @ce
workaround, instead of being done silently. See @ref opengl-workarounds for
more information.
- @ref Platform::WindowlessEglApplication "Platform::Windowless*Application"
instances no longer touch default framebuffer state in order to avoid
potential race conditions with a windowed context on another thread. This
is also exposed via a new @ref GL::Context::Configuration::Flag::Windowless
flag for integration with custom-created OpenGL contexts. See also
[mosra/magnum#493](https://github.com/mosra/magnum/pull/493) and
[mosra/magnum#494](https://github.com/mosra/magnum/pull/494).
@subsubsection changelog-latest-changes-math Math library

12
src/Magnum/GL/Context.cpp

@ -785,6 +785,10 @@ bool Context::tryCreate(const Configuration& configuration) {
if(configuration.flags() & Configuration::Flag::GpuValidation)
_configurationFlags |= Configuration::Flag::GpuValidation;
/* Same for windowless */
if(configuration.flags() & Configuration::Flag::Windowless)
_configurationFlags |= Configuration::Flag::Windowless;
/* Driver workarounds get merged. Not using disableDriverWorkaround() here
since the Configuration already contains the internal string views. */
for(const Containers::StringView workaround: configuration.disabledWorkarounds())
@ -974,9 +978,13 @@ bool Context::tryCreate(const Configuration& configuration) {
if(!workaround.second) Debug(output) << " " << workaround.first;
}
/* Initialize functionality based on current OpenGL version and extensions */
/** @todo Get rid of these */
DefaultFramebuffer::initializeContextBasedFunctionality(*this);
/* Initialize functionality based on current OpenGL version and extensions.
If we are on a windowless context don't touch the default framebuffer
to avoid potential race conditions with default framebuffer on another
thread. */
if(!(_configurationFlags & Configuration::Flag::Windowless))
DefaultFramebuffer::initializeContextBasedFunctionality(*this);
Renderer::initializeContextBasedFunctionality();
/* Enable GPU validation, if requested */

14
src/Magnum/GL/Context.h

@ -70,6 +70,7 @@ namespace Implementation {
Context before the Configuration class is defined, it has to be here */
enum class ContextConfigurationFlag: UnsignedLong {
/* Keeping the 32-bit range reserved for actual GL context flags */
Windowless = 1ull << 60,
QuietLog = 1ull << 61,
VerboseLog = 1ull << 62,
GpuValidation = 1ull << 63
@ -914,6 +915,19 @@ class MAGNUM_GL_EXPORT Context::Configuration {
/* Docs only, keep in sync with
Implementation::ContextConfigurationFlag please */
/**
* Treat the context as windowless, assume there's no default
* framebuffer and thus don't touch @ref defaultFramebuffer in any
* way. Useful for preventing race conditions when creating OpenGL
* contexts in background threads.
*
* This flag is implicitly enabled in all
* @ref Platform::WindowlessEglContext::Configuration "Platform::Windowless*Application::Configuration",
* and, conversely, not possible to enable in any
* @ref Platform::Sdl2Application::GLConfiguration::Flag "Platform::*Application::GLConfiguration".
*/
Windowless = 1ull << 60,
/**
* Print only warnings and errors instead of the usual startup log
* listing used extensions and workarounds. Ignored if

19
src/Magnum/GL/Framebuffer.cpp

@ -120,18 +120,23 @@ Framebuffer::~Framebuffer() {
if(!_id || !(_flags & ObjectFlag::DeleteOnDestruction)) return;
/* If bound, remove itself from state */
Implementation::FramebufferState& state = Context::current().state().framebuffer;
Context& context = Context::current();
Implementation::FramebufferState& state = context.state().framebuffer;
if(state.readBinding == _id) state.readBinding = 0;
/* For draw binding reset also viewport */
/* For draw binding reset also viewport. Don't do that for windowless
contexts to avoid potential race conditions with default framebuffer on
another thread. */
if(state.drawBinding == _id) {
state.drawBinding = 0;
/**
* @todo Less ugly solution (need to call setViewportInternal() to
* reset the viewport to size of default framebuffer)
*/
defaultFramebuffer.bind();
if(!(context.configurationFlags() & Context::Configuration::Flag::Windowless)) {
/**
* @todo Less ugly solution (need to call setViewportInternal() to
* reset the viewport to size of default framebuffer)
*/
defaultFramebuffer.bind();
}
}
glDeleteFramebuffers(1, &_id);

4
src/Magnum/Platform/AbstractXApplication.h

@ -343,7 +343,9 @@ class AbstractXApplication::GLConfiguration: public GL::Context::Configuration {
/**
* @brief Context flag
*
* Includes also everything from @ref GL::Context::Configuration::Flag.
* Includes also everything from @ref GL::Context::Configuration::Flag
* except for @relativeref{GL::Context::Configuration,Flag::Windowless},
* which is not meant to be enabled for windowed apps.
* @see @ref Flags, @ref setFlags(), @ref GL::Context::Flag
*/
enum class Flag: UnsignedLong {

4
src/Magnum/Platform/AndroidApplication.h

@ -456,7 +456,9 @@ class AndroidApplication::GLConfiguration: public GL::Context::Configuration {
/**
* @brief Context flag
*
* Includes also everything from @ref GL::Context::Configuration::Flag.
* Includes also everything from @ref GL::Context::Configuration::Flag
* except for @relativeref{GL::Context::Configuration,Flag::Windowless},
* which is not meant to be enabled for windowed apps.
* @see @ref Flags, @ref setFlags(), @ref GL::Context::Flag
*/
enum class Flag: UnsignedLong {

4
src/Magnum/Platform/EmscriptenApplication.h

@ -942,7 +942,9 @@ class EmscriptenApplication::GLConfiguration: public GL::Context::Configuration
/**
* @brief Context flag
*
* Includes also everything from @ref GL::Context::Configuration::Flag.
* Includes also everything from @ref GL::Context::Configuration::Flag
* except for @relativeref{GL::Context::Configuration,Flag::Windowless},
* which is not meant to be enabled for windowed apps.
* @see @ref Flags, @ref setFlags(), @ref GL::Context::Flag
*/
enum class Flag: UnsignedLong {

4
src/Magnum/Platform/GlfwApplication.h

@ -784,7 +784,9 @@ class GlfwApplication::GLConfiguration: public GL::Context::Configuration {
/**
* @brief Context flag
*
* Includes also everything from @ref GL::Context::Configuration::Flag.
* Includes also everything from @ref GL::Context::Configuration::Flag
* except for @relativeref{GL::Context::Configuration,Flag::Windowless},
* which is not meant to be enabled for windowed apps.
* @see @ref Flags, @ref setFlags(), @ref GL::Context::Flag
*/
enum class Flag: UnsignedLong {

4
src/Magnum/Platform/Sdl2Application.h

@ -1236,7 +1236,9 @@ class Sdl2Application::GLConfiguration: public GL::Context::Configuration {
/**
* @brief Context flag
*
* Includes also everything from @ref GL::Context::Configuration::Flag.
* Includes also everything from @ref GL::Context::Configuration::Flag
* except for @relativeref{GL::Context::Configuration,Flag::Windowless},
* which is not meant to be enabled for windowed apps.
* @see @ref Flags, @ref setFlags(), @ref GL::Context::Flag
*/
enum class Flag: UnsignedLong {

4
src/Magnum/Platform/WindowlessCglApplication.cpp

@ -105,6 +105,10 @@ bool WindowlessCglContext::release() {
return false;
}
WindowlessCglContext::Configuration::Configuration() {
GL::Context::Configuration::addFlags(GL::Context::Configuration::Flag::Windowless);
}
#ifndef DOXYGEN_GENERATING_OUTPUT
WindowlessCglApplication::WindowlessCglApplication(const Arguments& arguments): WindowlessCglApplication{arguments, Configuration{}} {}
#endif

6
src/Magnum/Platform/WindowlessCglApplication.h

@ -166,7 +166,9 @@ class WindowlessCglContext::Configuration: public GL::Context::Configuration {
/**
* @brief Context flag
*
* Includes also everything from @ref GL::Context::Configuration::Flag.
* Includes also everything from @ref GL::Context::Configuration::Flag
* except for @relativeref{GL::Context::Configuration,Flag::Windowless},
* which is enabled implicitly by default.
* @see @ref Flags, @ref setFlags(), @ref GL::Context::Flag
*/
enum class Flag: UnsignedLong {
@ -196,6 +198,8 @@ class WindowlessCglContext::Configuration: public GL::Context::Configuration {
*/
typedef Containers::EnumSet<Flag> Flags;
/*implicit*/ Configuration();
/** @brief Context flags */
Flags flags() const {
return Flag(UnsignedLong(GL::Context::Configuration::flags()));

1
src/Magnum/Platform/WindowlessEglApplication.cpp

@ -533,6 +533,7 @@ WindowlessEglContext::Configuration::Configuration()
: _device{}
#endif
{
GL::Context::Configuration::addFlags(GL::Context::Configuration::Flag::Windowless);
#ifndef MAGNUM_TARGET_GLES
addFlags(Flag::ForwardCompatible);
#endif

4
src/Magnum/Platform/WindowlessEglApplication.h

@ -183,7 +183,9 @@ class WindowlessEglContext::Configuration: public GL::Context::Configuration {
/**
* @brief Context flag
*
* Includes also everything from @ref GL::Context::Configuration::Flag.
* Includes also everything from @ref GL::Context::Configuration::Flag
* except for @relativeref{GL::Context::Configuration,Flag::Windowless},
* which is enabled implicitly by default.
* @see @ref Flags, @ref setFlags(), @ref GL::Context::Flag
*/
enum class Flag: UnsignedLong {

1
src/Magnum/Platform/WindowlessGlxApplication.cpp

@ -274,6 +274,7 @@ bool WindowlessGlxContext::release() {
}
WindowlessGlxContext::Configuration::Configuration() {
GL::Context::Configuration::addFlags(GL::Context::Configuration::Flag::Windowless);
#ifndef MAGNUM_TARGET_GLES
addFlags(Flag::ForwardCompatible);
#endif

4
src/Magnum/Platform/WindowlessGlxApplication.h

@ -188,7 +188,9 @@ class WindowlessGlxContext::Configuration: public GL::Context::Configuration {
/**
* @brief Context flag
*
* Includes also everything from @ref GL::Context::Configuration::Flag.
* Includes also everything from @ref GL::Context::Configuration::Flag
* except for @relativeref{GL::Context::Configuration,Flag::Windowless},
* which is enabled implicitly by default.
* @see @ref Flags, @ref setFlags(), @ref GL::Context::Flag
*/
enum class Flag: UnsignedLong {

6
src/Magnum/Platform/WindowlessIosApplication.h

@ -157,7 +157,9 @@ class WindowlessIosContext::Configuration: public GL::Context::Configuration {
/**
* @brief Context flag
*
* Includes also everything from @ref GL::Context::Configuration::Flag.
* Includes also everything from @ref GL::Context::Configuration::Flag
* except for @relativeref{GL::Context::Configuration,Flag::Windowless},
* which is enabled implicitly by default.
* @see @ref Flags, @ref setFlags(), @ref GL::Context::Flag
*/
enum class Flag: UnsignedLong {
@ -187,6 +189,8 @@ class WindowlessIosContext::Configuration: public GL::Context::Configuration {
*/
typedef Containers::EnumSet<Flag> Flags;
/*implicit*/ Configuration();
/** @brief Context flags */
Flags flags() const {
return Flag(UnsignedLong(GL::Context::Configuration::flags()));

4
src/Magnum/Platform/WindowlessIosApplication.mm

@ -82,6 +82,10 @@ bool WindowlessIosContext::release() {
return false;
}
WindowlessIosContext::Configuration::Configuration() {
GL::Context::Configuration::addFlags(GL::Context::Configuration::Flag::Windowless);
}
#ifndef DOXYGEN_GENERATING_OUTPUT
WindowlessIosApplication::WindowlessIosApplication(const Arguments& arguments): WindowlessIosApplication{arguments, Configuration{}} {}
#endif

1
src/Magnum/Platform/WindowlessWglApplication.cpp

@ -259,6 +259,7 @@ bool WindowlessWglContext::release() {
}
WindowlessWglContext::Configuration::Configuration() {
GL::Context::Configuration::addFlags(GL::Context::Configuration::Flag::Windowless);
#ifndef MAGNUM_TARGET_GLES
addFlags(Flag::ForwardCompatible);
#endif

4
src/Magnum/Platform/WindowlessWglApplication.h

@ -175,7 +175,9 @@ class WindowlessWglContext::Configuration: public GL::Context::Configuration {
/**
* @brief Context flag
*
* Includes also everything from @ref GL::Context::Configuration::Flag.
* Includes also everything from @ref GL::Context::Configuration::Flag
* except for @relativeref{GL::Context::Configuration,Flag::Windowless},
* which is enabled implicitly by default.
* @see @ref Flags, @ref setFlags(), @ref GL::Context::Flag
*/
enum class Flag: UnsignedLong {

4
src/Magnum/Platform/WindowlessWindowsEglApplication.cpp

@ -182,6 +182,10 @@ bool WindowlessWindowsEglContext::release() {
return false;
}
WindowlessWindowsEglContext::Configuration::Configuration() {
GL::Context::Configuration::addFlags(GL::Context::Configuration::Flag::Windowless);
}
#ifndef DOXYGEN_GENERATING_OUTPUT
WindowlessWindowsEglApplication::WindowlessWindowsEglApplication(const Arguments& arguments): WindowlessWindowsEglApplication{arguments, Configuration{}} {}
#endif

6
src/Magnum/Platform/WindowlessWindowsEglApplication.h

@ -161,7 +161,9 @@ class WindowlessWindowsEglContext::Configuration: public GL::Context::Configurat
/**
* @brief Context flag
*
* Includes also everything from @ref GL::Context::Configuration::Flag.
* Includes also everything from @ref GL::Context::Configuration::Flag
* except for @relativeref{GL::Context::Configuration,Flag::Windowless},
* which is enabled implicitly by default.
* @see @ref Flags, @ref setFlags(), @ref GL::Context::Flag
*/
enum class Flag: UnsignedLong {
@ -199,6 +201,8 @@ class WindowlessWindowsEglContext::Configuration: public GL::Context::Configurat
*/
typedef Containers::EnumSet<Flag> Flags;
/*implicit*/ Configuration();
/** @brief Context flags */
Flags flags() const {
return Flag(UnsignedLong(GL::Context::Configuration::flags()));

Loading…
Cancel
Save