Browse Source

Platform: ability to request context version in *X*Application.

pull/51/head
Vladimír Vondruš 13 years ago
parent
commit
cadaed853e
  1. 6
      src/Platform/AbstractXApplication.cpp
  2. 18
      src/Platform/AbstractXApplication.h
  3. 4
      src/Platform/Implementation/AbstractContextHandler.h
  4. 46
      src/Platform/Implementation/EglContextHandler.cpp
  5. 7
      src/Platform/Implementation/EglContextHandler.h
  6. 47
      src/Platform/Implementation/GlxContextHandler.cpp
  7. 7
      src/Platform/Implementation/GlxContextHandler.h

6
src/Platform/AbstractXApplication.cpp

@ -38,11 +38,11 @@ namespace Magnum { namespace Platform {
/** @todo Delegating constructor when support for GCC 4.6 is dropped */ /** @todo Delegating constructor when support for GCC 4.6 is dropped */
AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler<Display*, VisualID, Window>* contextHandler, const Arguments&, const Configuration& configuration): contextHandler(contextHandler), c(nullptr), flags(Flag::Redraw) { AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler<Configuration, Display*, VisualID, Window>* contextHandler, const Arguments&, const Configuration& configuration): contextHandler(contextHandler), c(nullptr), flags(Flag::Redraw) {
createContext(configuration); createContext(configuration);
} }
AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler<Display*, VisualID, Window>* contextHandler, const Arguments&, std::nullptr_t): contextHandler(contextHandler), c(nullptr), flags(Flag::Redraw) {} AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler<Configuration, Display*, VisualID, Window>* contextHandler, const Arguments&, std::nullptr_t): contextHandler(contextHandler), c(nullptr), flags(Flag::Redraw) {}
void AbstractXApplication::createContext() { createContext({}); } void AbstractXApplication::createContext() { createContext({}); }
@ -88,7 +88,7 @@ bool AbstractXApplication::tryCreateContext(const Configuration& configuration)
XSetWMProtocols(display, window, &deleteWindow, 1); XSetWMProtocols(display, window, &deleteWindow, 1);
/* Create context */ /* Create context */
contextHandler->createContext(window); contextHandler->createContext(configuration, window);
/* Capture exposure, keyboard and mouse button events */ /* Capture exposure, keyboard and mouse button events */
XSelectInput(display, window, INPUT_MASK); XSelectInput(display, window, INPUT_MASK);

18
src/Platform/AbstractXApplication.h

@ -48,7 +48,7 @@ class Context;
namespace Platform { namespace Platform {
namespace Implementation { namespace Implementation {
template<class, class, class> class AbstractContextHandler; template<class, class, class, class> class AbstractContextHandler;
} }
/** @nosubgrouping /** @nosubgrouping
@ -160,9 +160,9 @@ class AbstractXApplication {
#else #else
protected: protected:
#endif #endif
explicit AbstractXApplication(Implementation::AbstractContextHandler<Display*, VisualID, Window>* contextHandler, const Arguments& arguments, const Configuration& configuration); explicit AbstractXApplication(Implementation::AbstractContextHandler<Configuration, Display*, VisualID, Window>* contextHandler, const Arguments& arguments, const Configuration& configuration);
explicit AbstractXApplication(Implementation::AbstractContextHandler<Display*, VisualID, Window>* contextHandler, const Arguments& arguments, std::nullptr_t); explicit AbstractXApplication(Implementation::AbstractContextHandler<Configuration, Display*, VisualID, Window>* contextHandler, const Arguments& arguments, std::nullptr_t);
private: private:
enum class Flag: unsigned int { enum class Flag: unsigned int {
@ -177,7 +177,7 @@ class AbstractXApplication {
Window window; Window window;
Atom deleteWindow; Atom deleteWindow;
Implementation::AbstractContextHandler<Display*, VisualID, Window>* contextHandler; Implementation::AbstractContextHandler<Configuration, Display*, VisualID, Window>* contextHandler;
Context* c; Context* c;
@ -225,9 +225,19 @@ class AbstractXApplication::Configuration {
return *this; return *this;
} }
/** @copydoc GlutApplication::Configuration::version() */
Version version() const { return _version; }
/** @copydoc GlutApplication::Configuration::setVersion() */
Configuration& setVersion(Version version) {
_version = version;
return *this;
}
private: private:
std::string _title; std::string _title;
Vector2i _size; Vector2i _size;
Version _version;
}; };
/** /**

4
src/Platform/Implementation/AbstractContextHandler.h

@ -31,7 +31,7 @@ namespace Magnum { namespace Platform { namespace Implementation {
@todo GLX_MESA_query_renderer, EGL_MESA_query_renderer @todo GLX_MESA_query_renderer, EGL_MESA_query_renderer
*/ */
template<class Display, class VisualId, class Window> class AbstractContextHandler { template<class Configuration, class Display, class VisualId, class Window> class AbstractContextHandler {
public: public:
/** /**
* @brief Get visual ID * @brief Get visual ID
@ -50,7 +50,7 @@ template<class Display, class VisualId, class Window> class AbstractContextHandl
virtual ~AbstractContextHandler() {} virtual ~AbstractContextHandler() {}
/** @brief Create context */ /** @brief Create context */
virtual void createContext(Window nativeWindow) = 0; virtual void createContext(const Configuration& configuration, Window nativeWindow) = 0;
/** @brief Make the context current */ /** @brief Make the context current */
virtual void makeCurrent() = 0; virtual void makeCurrent() = 0;

46
src/Platform/Implementation/EglContextHandler.cpp

@ -24,9 +24,12 @@
#include "EglContextHandler.h" #include "EglContextHandler.h"
#include <tuple>
#include <EGL/eglext.h>
#include <Utility/Debug.h> #include <Utility/Debug.h>
#include "Context.h" #include "Context.h"
#include "Version.h"
namespace Magnum { namespace Platform { namespace Implementation { namespace Magnum { namespace Platform { namespace Implementation {
@ -88,14 +91,45 @@ VisualId EglContextHandler::getVisualId(EGLNativeDisplayType nativeDisplay) {
return visualId; return visualId;
} }
void EglContextHandler::createContext(EGLNativeWindowType window) { void EglContextHandler::createContext(const AbstractXApplication::Configuration& configuration, EGLNativeWindowType window) {
static const EGLint contextAttributes[] = { EGLint attributes[] = {
#ifdef MAGNUM_TARGET_GLES /* Leave some space for optional attributes below */
EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE,
#endif EGL_NONE, EGL_NONE,
EGL_NONE, EGL_NONE,
EGL_NONE EGL_NONE
}; };
if(!eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes)) {
/* Set context version, if requested. On desktop needs
EGL_KHR_create_context. */
/** @todo Test for presence of EGL_KHR_create_context extension */
if(configuration.version() != Version::None) {
Int major, minor;
std::tie(major, minor) = version(configuration.version());
attributes[0] = EGL_CONTEXT_MAJOR_VERSION_KHR;
attributes[1] = major;
attributes[2] = EGL_CONTEXT_MINOR_VERSION_KHR;
attributes[3] = minor;
#ifndef MAGNUM_TARGET_GLES
if(configuration.version() >= Version::GL310) {
attributes[4] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
attributes[5] = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
}
#endif
}
/* We need this to run ES (default is desktop GL) */
#ifdef MAGNUM_TARGET_GLES
else {
attributes[0] = EGL_CONTEXT_CLIENT_VERSION;
attributes[1] = 2;
}
#endif
if(!eglCreateContext(display, config, EGL_NO_CONTEXT, attributes)) {
Error() << "Cannot create EGL context:" << errorString(eglGetError()); Error() << "Cannot create EGL context:" << errorString(eglGetError());
std::exit(1); std::exit(1);
} }

7
src/Platform/Implementation/EglContextHandler.h

@ -34,7 +34,8 @@
/* undef Xlib nonsense to avoid conflicts */ /* undef Xlib nonsense to avoid conflicts */
#undef None #undef None
#include "AbstractContextHandler.h" #include "Platform/AbstractXApplication.h"
#include "Platform/Implementation/AbstractContextHandler.h"
#include "corradeCompatibility.h" #include "corradeCompatibility.h"
@ -54,13 +55,13 @@ typedef EGLInt VisualId;
Used in XEglApplication. Used in XEglApplication.
*/ */
class EglContextHandler: public AbstractContextHandler<EGLNativeDisplayType, VisualId, EGLNativeWindowType> { class EglContextHandler: public AbstractContextHandler<AbstractXApplication::Configuration, EGLNativeDisplayType, VisualId, EGLNativeWindowType> {
public: public:
explicit EglContextHandler() = default; explicit EglContextHandler() = default;
~EglContextHandler(); ~EglContextHandler();
VisualId getVisualId(EGLNativeDisplayType nativeDisplay) override; VisualId getVisualId(EGLNativeDisplayType nativeDisplay) override;
void createContext(EGLNativeWindowType nativeWindow) override; void createContext(const AbstractXApplication::Configuration& configuration, EGLNativeWindowType nativeWindow) override;
void makeCurrent() override { void makeCurrent() override {
eglMakeCurrent(display, surface, surface, context); eglMakeCurrent(display, surface, surface, context);

47
src/Platform/Implementation/GlxContextHandler.cpp

@ -25,10 +25,12 @@
#include "GlxContextHandler.h" #include "GlxContextHandler.h"
#include <cstdlib> #include <cstdlib>
#include <tuple>
#include <GL/glxext.h> #include <GL/glxext.h>
#include <Utility/Debug.h> #include <Utility/Debug.h>
#include "Context.h" #include "Context.h"
#include "Version.h"
namespace Magnum { namespace Platform { namespace Implementation { namespace Magnum { namespace Platform { namespace Implementation {
@ -69,18 +71,51 @@ VisualID GlxContextHandler::getVisualId(Display* nativeDisplay) {
return visualId; return visualId;
} }
void GlxContextHandler::createContext(Window nativeWindow) { void GlxContextHandler::createContext(const AbstractXApplication::Configuration& configuration, Window nativeWindow) {
window = nativeWindow; window = nativeWindow;
GLint attributes[] = { GLint attributes[] = {
#ifdef MAGNUM_TARGET_GLES /* Leave some space for optional attributes below */
GLX_CONTEXT_MAJOR_VERSION_ARB, 2, 0, 0,
GLX_CONTEXT_MINOR_VERSION_ARB, 0, 0, 0,
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, 0, 0,
#endif
0 0
}; };
/* Set context version, if requested */
if(configuration.version() != Version::None) {
Int major, minor;
std::tie(major, minor) = version(configuration.version());
attributes[0] = GLX_CONTEXT_MAJOR_VERSION_ARB;
attributes[1] = major;
attributes[2] = GLX_CONTEXT_MINOR_VERSION_ARB;
attributes[3] = minor;
#ifndef MAGNUM_TARGET_GLES
if(configuration.version() >= Version::GL310) {
attributes[4] = GLX_CONTEXT_PROFILE_MASK_ARB;
attributes[5] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
}
#else
attributes[4] = GLX_CONTEXT_PROFILE_MASK_ARB;
attributes[5] = GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
#endif
}
/* We need this to run ES (default is desktop GL) */
#ifdef MAGNUM_TARGET_GLES
else {
attributes[0] = GLX_CONTEXT_MAJOR_VERSION_ARB;
attributes[1] = 2;
attributes[2] = GLX_CONTEXT_MINOR_VERSION_ARB;
attributes[3] = 0;
attributes[4] = GLX_CONTEXT_PROFILE_MASK_ARB;
attributes[5] = GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
}
#endif
/** @todo Use some extension wrangler for this, not GLEW, as it apparently needs context to create context, yo dawg wtf. */ /** @todo Use some extension wrangler for this, not GLEW, as it apparently needs context to create context, yo dawg wtf. */
PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB"); PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
context = glXCreateContextAttribsARB(display, configs[0], nullptr, True, attributes); context = glXCreateContextAttribsARB(display, configs[0], nullptr, True, attributes);

7
src/Platform/Implementation/GlxContextHandler.h

@ -31,7 +31,8 @@
#undef None #undef None
#undef Always #undef Always
#include "AbstractContextHandler.h" #include "Platform/AbstractXApplication.h"
#include "Platform/Implementation/AbstractContextHandler.h"
#include "corradeCompatibility.h" #include "corradeCompatibility.h"
@ -43,13 +44,13 @@ namespace Magnum { namespace Platform { namespace Implementation {
Creates OpenGL or OpenGL ES 2.0 context, if targeting OpenGL ES. Used in Creates OpenGL or OpenGL ES 2.0 context, if targeting OpenGL ES. Used in
GlxApplication. GlxApplication.
*/ */
class GlxContextHandler: public AbstractContextHandler<Display*, VisualID, Window> { class GlxContextHandler: public AbstractContextHandler<AbstractXApplication::Configuration, Display*, VisualID, Window> {
public: public:
explicit GlxContextHandler() = default; explicit GlxContextHandler() = default;
~GlxContextHandler(); ~GlxContextHandler();
VisualID getVisualId(Display* nativeDisplay) override; VisualID getVisualId(Display* nativeDisplay) override;
void createContext(Window nativeWindow) override; void createContext(const AbstractXApplication::Configuration& configuration, Window nativeWindow) override;
void makeCurrent() override { void makeCurrent() override {
glXMakeCurrent(display, window, context); glXMakeCurrent(display, window, context);

Loading…
Cancel
Save