Skip to content

Commit

Permalink
Platform: make GPU context options application-global.
Browse files Browse the repository at this point in the history
Instead of per-window. It's just too complicated to allow some windows
with GL context, some with Vulkan, some with neither and some with
both. For now at least.
  • Loading branch information
mosra committed Feb 5, 2024
1 parent a902b84 commit e192be5
Show file tree
Hide file tree
Showing 3 changed files with 216 additions and 27 deletions.
4 changes: 4 additions & 0 deletions doc/changelog.dox
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,10 @@ See also:
performance and a default, use @relativeref{Platform::EmscriptenApplication::GLConfiguration,Flag::PowerPreferenceLowPower}
or @relativeref{Platform::EmscriptenApplication::GLConfiguration,Flag::PowerPreferenceHighPerformance}
instead
- GPU-context-related flags were moved from
@ref Platform::Sdl2Application::Configuration::WindowFlag to a new
@ref Platform::Sdl2Application::Configuration::Flag enum, as they're set
globally for all application windows and can't differ per-window
- @cpp Shaders::DistanceFieldVector @ce, @cpp Shaders::Flat @ce,
@cpp Shaders::Generic @ce, @cpp Shaders::MeshVisualizer2D @ce,
@cpp Shaders::MeshVisualizer3D @ce, @cpp Shaders::Phong @ce,
Expand Down
59 changes: 55 additions & 4 deletions src/Magnum/Platform/Sdl2Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ void Sdl2Application::create(const Configuration& configuration, const GLConfigu

bool Sdl2Application::tryCreate(const Configuration& configuration) {
#ifdef MAGNUM_TARGET_GL
if(!(configuration.windowFlags() & Configuration::WindowFlag::Contextless))
if(!(configuration.flags() & Configuration::Flag::Contextless))
return tryCreate(configuration, GLConfiguration{});
#endif

Expand All @@ -584,7 +584,7 @@ bool Sdl2Application::tryCreate(const Configuration& configuration) {
#endif
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
scaledWindowSize.x(), scaledWindowSize.y(),
SDL_WINDOW_ALLOW_HIGHDPI|SDL_WINDOW_OPENGL|Uint32(configuration.windowFlags() & ~Configuration::WindowFlag::Contextless))))
SDL_WINDOW_ALLOW_HIGHDPI|SDL_WINDOW_OPENGL|Uint32(configuration.windowFlags()))))
{
Error() << "Platform::Sdl2Application::tryCreate(): cannot create window:" << SDL_GetError();
return false;
Expand Down Expand Up @@ -641,8 +641,8 @@ bool Sdl2Application::tryCreate(const Configuration& configuration) {

#ifdef MAGNUM_TARGET_GL
bool Sdl2Application::tryCreate(const Configuration& configuration, const GLConfiguration& glConfiguration) {
CORRADE_ASSERT(!(configuration.windowFlags() & Configuration::WindowFlag::Contextless),
"Platform::Sdl2Application::tryCreate(): cannot pass Configuration::WindowFlag::Contextless when creating an OpenGL context", false);
CORRADE_ASSERT(!(configuration.flags() & Configuration::Flag::Contextless),
"Platform::Sdl2Application::tryCreate(): cannot pass Configuration::Flag::Contextless when creating an OpenGL context", false);
CORRADE_ASSERT(_context->version() == GL::Version::None,
"Platform::Sdl2Application::tryCreate(): context already created", false);

Expand Down Expand Up @@ -1248,6 +1248,57 @@ Sdl2ApplicationWindow::Configuration::Configuration():

Sdl2ApplicationWindow::Configuration::~Configuration() = default;

#ifdef MAGNUM_BUILD_DEPRECATED
namespace {
CORRADE_IGNORE_DEPRECATED_PUSH
constexpr Sdl2ApplicationWindow::Configuration::WindowFlags DeprecatedWindowFlags = Sdl2ApplicationWindow::Configuration::WindowFlag::Contextless|Sdl2ApplicationWindow::Configuration::WindowFlag::OpenGL|Sdl2ApplicationWindow::Configuration::WindowFlag::Vulkan;
CORRADE_IGNORE_DEPRECATED_POP
}
#endif

Sdl2Application::Configuration& Sdl2Application::Configuration::setWindowFlags(WindowFlags flags) {
/* If deprecated flags are present, reset these bits in the application
flags instead and remove them from the to-be-set window flags */
#ifdef MAGNUM_BUILD_DEPRECATED
if(const WindowFlags deprecatedFlags = flags & DeprecatedWindowFlags) {
_flags &= ~Flags(Uint32(DeprecatedWindowFlags));
_flags |= Flags(Uint32(deprecatedFlags));
flags &= ~deprecatedFlags;
}
#endif

Sdl2ApplicationWindow::Configuration::setWindowFlags(flags);
return *this;
}

Sdl2Application::Configuration& Sdl2Application::Configuration::addWindowFlags(WindowFlags flags) {
/* If deprecated flags are present, add these bits in the application
flags instead and remove them from the to-be-added window flags */
#ifdef MAGNUM_BUILD_DEPRECATED
if(const WindowFlags deprecatedFlags = flags & DeprecatedWindowFlags) {
_flags |= Flags(Uint32(deprecatedFlags));
flags &= ~deprecatedFlags;
}
#endif

Sdl2ApplicationWindow::Configuration::addWindowFlags(flags);
return *this;
}

Sdl2Application::Configuration& Sdl2Application::Configuration::clearWindowFlags(WindowFlags flags) {
/* If deprecated flags are present, add these bits in the application
flags instead and remove them from the to-be-cleared window flags */
#ifdef MAGNUM_BUILD_DEPRECATED
if(const WindowFlags deprecatedFlags = flags & DeprecatedWindowFlags) {
_flags &= ~Flags(Uint32(deprecatedFlags));
flags &= ~deprecatedFlags;
}
#endif

Sdl2ApplicationWindow::Configuration::clearWindowFlags(flags);
return *this;
}

Containers::StringView Sdl2ApplicationWindow::KeyEvent::keyName(const Key key) {
return SDL_GetKeyName(SDL_Keycode(key));
}
Expand Down
180 changes: 157 additions & 23 deletions src/Magnum/Platform/Sdl2Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,7 @@ class Sdl2Application: public Sdl2ApplicationWindow {
char** argv; /**< @brief Argument values */
};

class Configuration;
#ifdef MAGNUM_TARGET_GL
class GLConfiguration;
#endif
Expand Down Expand Up @@ -1667,8 +1668,10 @@ namespace Implementation {
}

/**
@brief Configuration
@brief Window configuration
Inherited by @ref Sdl2Application::Configuration which adds global options for
all windows.
@see @ref Sdl2ApplicationWindow(),
@ref Sdl2Application::Sdl2Application(const Arguments&, const Configuration&, const GLConfiguration&),
@ref Sdl2Application::GLConfiguration, @ref Sdl2Application::create(),
Expand Down Expand Up @@ -1805,38 +1808,34 @@ class Sdl2ApplicationWindow::Configuration {
#endif
#endif

#ifdef MAGNUM_BUILD_DEPRECATED
/**
* Do not create any GPU context. Use together with
* @ref Sdl2Application::Sdl2Application(const Arguments&, const Configuration&),
* @ref Sdl2Application::create(const Configuration&) or
* @ref Sdl2Application::tryCreate(const Configuration&) to prevent
* implicit creation of an OpenGL context. Can't be used with
* @ref Sdl2Application::Sdl2Application(const Arguments&, const Configuration&, const GLConfiguration&),
* @ref Sdl2Application::create(const Configuration&, const GLConfiguration&) or
* @ref Sdl2Application::tryCreate(const Configuration&, const GLConfiguration&).
* Do not create any GPU context.
* @m_deprecated_since_latest Use the application-global
* @ref Sdl2Application::Configuration::Flag::Contextless
* instead.
*/
Contextless = 1u << 31, /* Hope this won't ever conflict with anything */
Contextless CORRADE_DEPRECATED_ENUM("use Sdl2Application::Configuration::Flag::Contextless instead") = 1u << 31,

/**
* Request a window for use with OpenGL. Useful in combination with
* @ref WindowFlag::Contextless, otherwise enabled implicitly when
* creating an OpenGL context using
* @ref Sdl2Application::Sdl2Application(const Arguments&, const Configuration&, const GLConfiguration&),
* @ref Sdl2Application::create(const Configuration&, const GLConfiguration&)
* or @ref Sdl2Application::tryCreate(const Configuration&, const GLConfiguration&).
* @m_since{2019,10}
* Request a window for use with OpenGL.
* @m_deprecated_since_latest Use the application-global
* @ref Sdl2Application::Configuration::Flag::OpenGL
* instead.
*/
OpenGL = SDL_WINDOW_OPENGL,
OpenGL CORRADE_DEPRECATED_ENUM("use Sdl2Application::Configuration::Flag::OpenGL instead") = SDL_WINDOW_OPENGL,

#if !defined(CORRADE_TARGET_EMSCRIPTEN) && (SDL_MAJOR_VERSION*1000 + SDL_MINOR_VERSION*100 + SDL_PATCHLEVEL >= 2006 || defined(DOXYGEN_GENERATING_OUTPUT))
/**
* Request a window for use with Vulkan. Useful in combination with
* @ref WindowFlag::Contextless.
* Request a window for use with Vulkan.
* @m_deprecated_since_latest Use the application-global
* @ref Sdl2Application::Configuration::Flag::Vulkan
* instead.
* @note Available since SDL 2.0.6, not available on
* @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten".
* @m_since{2019,10}
*/
Vulkan = SDL_WINDOW_VULKAN
Vulkan CORRADE_DEPRECATED_ENUM("use Sdl2Application::Configuration::Flag::Vulkan instead") = SDL_WINDOW_VULKAN
#endif
#endif
};

Expand Down Expand Up @@ -2056,6 +2055,142 @@ class Sdl2ApplicationWindow::Configuration {
Vector2 _dpiScaling;
};

CORRADE_ENUMSET_OPERATORS(Sdl2ApplicationWindow::Configuration::WindowFlags)

/**
@brief Application configuration
Inherits @ref Sdl2ApplicationWindow::Configuration.
@see @ref Sdl2Application(), @ref create(), @ref tryCreate()
*/
class Sdl2Application::Configuration: public Sdl2ApplicationWindow::Configuration {
public:
/**
* @brief Application flag
* @m_since_latest
*
* @see @ref Flags, @ref setFlags()
*/
enum class Flag: Uint32 {
/**
* Do not create any GPU context. Use together with
* @ref Sdl2Application(const Arguments&, const Configuration&),
* @ref create(const Configuration&) or
* @ref tryCreate(const Configuration&) to prevent implicit
* creation of an OpenGL context. Can't be used with
* @ref Sdl2Application(const Arguments&, const Configuration&, const GLConfiguration&),
* @ref create(const Configuration&, const GLConfiguration&) or
* @ref tryCreate(const Configuration&, const GLConfiguration&).
*/
Contextless = 1u << 31, /* Hope this won't ever conflict with anything */

/**
* Request a window for use with OpenGL. Useful in combination with
* @ref Flag::Contextless, otherwise enabled implicitly when
* creating an OpenGL context using
* @ref Sdl2Application(const Arguments&, const Configuration&, const GLConfiguration&),
* @ref create(const Configuration&, const GLConfiguration&)
* or @ref tryCreate(const Configuration&, const GLConfiguration&).
* @m_since{2019,10}
*/
OpenGL = SDL_WINDOW_OPENGL,

#if !defined(CORRADE_TARGET_EMSCRIPTEN) && (SDL_MAJOR_VERSION*1000 + SDL_MINOR_VERSION*100 + SDL_PATCHLEVEL >= 2006 || defined(DOXYGEN_GENERATING_OUTPUT))
/**
* Request a window for use with Vulkan. Useful in combination with
* @ref Flag::Contextless.
* @note Available since SDL 2.0.6, not available on
* @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten".
* @m_since{2019,10}
*/
Vulkan = SDL_WINDOW_VULKAN
#endif
};

/**
* @brief Application flags
* @m_since_latest
*
* @see @ref setFlags()
*/
typedef Containers::EnumSet<Flag> Flags;

explicit Configuration() = default;

/**
* @brief Application flags
* @m_since_latest
*/
Flags flags() const { return _flags; }

/**
* @brief Set application flags
* @return Reference to self (for method chaining)
* @m_since_latest
*
* Default are none. To avoid clearing default flags by accident,
* prefer to use @ref addFlags() and @ref clearFlags() instead.
*/
Configuration& setFlags(Flags flags) {
_flags = flags;
return *this;
}

/**
* @brief Add application flags
* @return Reference to self (for method chaining)
* @m_since_latest
*
* 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 application flags
* @return Reference to self (for method chaining)
* @m_since_latest
*
* 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;
}

/* Overloads to remove a WTF factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
Configuration& setTitle(Containers::StringView title) {
Sdl2ApplicationWindow::Configuration::setTitle(title);
return *this;
}
Configuration& setSize(const Vector2i& size, DpiScalingPolicy dpiScalingPolicy = DpiScalingPolicy::Default) {
Sdl2ApplicationWindow::Configuration::setSize(size, dpiScalingPolicy);
return *this;
}
Configuration& setSize(const Vector2i& size, const Vector2& dpiScaling) {
Sdl2ApplicationWindow::Configuration::setSize(size, dpiScaling);
return *this;
}
/* On deprecated builds these propagate the appropriate context flags
to setFlags() / addFlags() / clearFlags() */
Configuration& setWindowFlags(WindowFlags flags);
Configuration& addWindowFlags(WindowFlags flags);
Configuration& clearWindowFlags(WindowFlags flags);
#endif

private:
Flags _flags;
};

CORRADE_ENUMSET_OPERATORS(Sdl2Application::Configuration::Flags)

/**
@brief Exit event
Expand Down Expand Up @@ -3032,7 +3167,6 @@ typedef BasicScreenedApplication<Sdl2Application> ScreenedApplication;
#endif
#endif

CORRADE_ENUMSET_OPERATORS(Sdl2ApplicationWindow::Configuration::WindowFlags)
CORRADE_ENUMSET_OPERATORS(Sdl2ApplicationWindow::InputEvent::Modifiers)
CORRADE_ENUMSET_OPERATORS(Sdl2ApplicationWindow::MouseMoveEvent::Buttons)

Expand Down

0 comments on commit e192be5

Please sign in to comment.