Browse Source

GL: added Context::makeCurrent().

pull/362/head
Vladimír Vondruš 7 years ago
parent
commit
11a94c16a3
  1. 3
      doc/changelog.dox
  2. 29
      doc/snippets/MagnumGL-framebuffer.cpp
  3. 2
      src/Magnum/GL/Context.cpp
  4. 30
      src/Magnum/GL/Context.h
  5. 18
      src/Magnum/GL/Test/ContextGLTest.cpp
  6. 10
      src/Magnum/GL/Test/ContextTest.cpp

3
doc/changelog.dox

@ -122,6 +122,9 @@ See also:
- It's now possible to pass @ref std::initializer_list to
@ref GL::Buffer::setData() / @ref GL::Buffer::setSubData() for a succint
upload of basic types
- Added an ability to use Magnum with multiple OpenGL contexts using
@ref GL::Context::makeCurrent(), see @ref GL-Context-multiple for more
information
@subsubsection changelog-latest-new-math Math library

29
doc/snippets/MagnumGL-framebuffer.cpp

@ -23,9 +23,11 @@
DEALINGS IN THE SOFTWARE.
*/
#include "Magnum/GL/Buffer.h"
#include "Magnum/GL/DefaultFramebuffer.h"
#include "Magnum/GL/Framebuffer.h"
#include "Magnum/Platform/Sdl2Application.h"
#include "Magnum/Platform/GLContext.h"
using namespace Magnum;
@ -69,3 +71,30 @@ void drawEvent() override {
}
/* [Framebuffer-usage-draw] */
};
int main() {
{
SDL_Window* _window{};
SDL_GLContext* _otherGLContext{};
/* [Context-makeCurrent-nullptr] */
Platform::GLContext context;
SDL_GL_MakeCurrent(_window, _otherGLContext); // or other platform-specific API
Platform::GLContext::makeCurrent(nullptr);
Platform::GLContext other;
/* [Context-makeCurrent-nullptr] */
/* [Context-makeCurrent] */
Platform::GLContext::makeCurrent(&context);
GL::Buffer a; // implicitly tied to `context`
Platform::GLContext::makeCurrent(&other);
GL::Buffer b; // implicitly tied to `other`
/* [Context-makeCurrent] */
}
}

2
src/Magnum/GL/Context.cpp

@ -456,6 +456,8 @@ Context& Context::current() {
return *currentContext;
}
void Context::makeCurrent(Context* context) { currentContext = context; }
Context::Context(NoCreateT, Int argc, const char** argv, void functionLoader(Context&)): Context{NoCreate, Utility::Arguments{"magnum"}, argc, argv, functionLoader} {}
Context::Context(NoCreateT, Utility::Arguments& args, Int argc, const char** argv, void functionLoader(Context&)): _functionLoader{functionLoader}, _version{Version::None} {

30
src/Magnum/GL/Context.h

@ -154,6 +154,28 @@ If Corrade is compiled with @ref CORRADE_BUILD_MULTITHREADED (the default), the
OpenGL context thread locality. This might cause some performance penalties ---
if you are sure that you never need to have multiple independent thread-local
Magnum context, build Corrade with the option disabled.
@section GL-Context-multiple Using multiple OpenGL contexts
By default, Magnum assumes you have one OpenGL context active at all times, and
all state tracking is done by the @ref Context instance that's associated with
it. When you are using multiple OpenGL contexts, each of them needs to have a
corresponding @ref Context instance active at the same time, and you need to
ensure you only access OpenGL objects that were created by the same context as
is currently active.
To prevent accidents in common cases, the @ref Context class expects that no
other instance is active during its creation. In order to create additional
instances for other OpenGL contexts, *first* you need to "unset" the current one
with @ref makeCurrent() and *then* create another instance, which will then
become implicitly active:
@snippet MagnumGL-framebuffer.cpp Context-makeCurrent-nullptr
Once all needed instances are created, switch between them right after making
the underlying GL context current:
@snippet MagnumGL-framebuffer.cpp Context-makeCurrent
*/
class MAGNUM_GL_EXPORT Context {
public:
@ -420,6 +442,14 @@ class MAGNUM_GL_EXPORT Context {
*/
static Context& current();
/**
* @brief Make a context current
*
* To be used when you need to manage multiple OpenGL contexts. See
* @ref GL-Context-multiple for more information.
*/
static void makeCurrent(Context* context);
/** @brief Copying is not allowed */
Context(const Context&) = delete;

18
src/Magnum/GL/Test/ContextGLTest.cpp

@ -38,6 +38,8 @@ namespace Magnum { namespace GL { namespace Test { namespace {
struct ContextGLTest: OpenGLTester {
explicit ContextGLTest();
void makeCurrent();
#ifndef CORRADE_TARGET_EMSCRIPTEN
void multithreaded();
#endif
@ -53,6 +55,8 @@ struct ContextGLTest: OpenGLTester {
ContextGLTest::ContextGLTest() {
addTests({
&ContextGLTest::makeCurrent,
#ifndef CORRADE_TARGET_EMSCRIPTEN
&ContextGLTest::multithreaded,
#endif
@ -66,6 +70,20 @@ ContextGLTest::ContextGLTest() {
&ContextGLTest::isExtensionDisabled});
}
void ContextGLTest::makeCurrent() {
CORRADE_VERIFY(Context::hasCurrent());
Context& current = Context::current();
Context::makeCurrent(nullptr);
CORRADE_VERIFY(!Context::hasCurrent());
Context::makeCurrent(&current);
CORRADE_VERIFY(Context::hasCurrent());
CORRADE_COMPARE(&Context::current(), &current);
}
#ifndef CORRADE_TARGET_EMSCRIPTEN
void ContextGLTest::multithreaded() {
CORRADE_VERIFY(Context::hasCurrent());

10
src/Magnum/GL/Test/ContextTest.cpp

@ -38,6 +38,8 @@ struct ContextTest: TestSuite::Tester {
void constructNoCreate();
void constructCopyMove();
void makeCurrentNoOp();
void extensions();
void debugFlag();
@ -51,6 +53,8 @@ ContextTest::ContextTest() {
addTests({&ContextTest::constructNoCreate,
&ContextTest::constructCopyMove,
&ContextTest::makeCurrentNoOp,
&ContextTest::extensions,
&ContextTest::debugFlag,
@ -82,6 +86,12 @@ void ContextTest::constructCopyMove() {
CORRADE_VERIFY(!(std::is_assignable<Context, Context&&>{}));
}
void ContextTest::makeCurrentNoOp() {
CORRADE_VERIFY(!Context::hasCurrent());
Context::makeCurrent(nullptr);
CORRADE_VERIFY(!Context::hasCurrent());
}
void ContextTest::extensions() {
const char* used[GL::Implementation::ExtensionCount]{};

Loading…
Cancel
Save