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 */
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);
}
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({}); }
@ -88,7 +88,7 @@ bool AbstractXApplication::tryCreateContext(const Configuration& configuration)
XSetWMProtocols(display, window, &deleteWindow, 1);
/* Create context */
contextHandler->createContext(window);
contextHandler->createContext(configuration, window);
/* Capture exposure, keyboard and mouse button events */
XSelectInput(display, window, INPUT_MASK);

18
src/Platform/AbstractXApplication.h

@ -48,7 +48,7 @@ class Context;
namespace Platform {
namespace Implementation {
template<class, class, class> class AbstractContextHandler;
template<class, class, class, class> class AbstractContextHandler;
}
/** @nosubgrouping
@ -160,9 +160,9 @@ class AbstractXApplication {
#else
protected:
#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:
enum class Flag: unsigned int {
@ -177,7 +177,7 @@ class AbstractXApplication {
Window window;
Atom deleteWindow;
Implementation::AbstractContextHandler<Display*, VisualID, Window>* contextHandler;
Implementation::AbstractContextHandler<Configuration, Display*, VisualID, Window>* contextHandler;
Context* c;
@ -225,9 +225,19 @@ class AbstractXApplication::Configuration {
return *this;
}
/** @copydoc GlutApplication::Configuration::version() */
Version version() const { return _version; }
/** @copydoc GlutApplication::Configuration::setVersion() */
Configuration& setVersion(Version version) {
_version = version;
return *this;
}
private:
std::string _title;
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
*/
template<class Display, class VisualId, class Window> class AbstractContextHandler {
template<class Configuration, class Display, class VisualId, class Window> class AbstractContextHandler {
public:
/**
* @brief Get visual ID
@ -50,7 +50,7 @@ template<class Display, class VisualId, class Window> class AbstractContextHandl
virtual ~AbstractContextHandler() {}
/** @brief Create context */
virtual void createContext(Window nativeWindow) = 0;
virtual void createContext(const Configuration& configuration, Window nativeWindow) = 0;
/** @brief Make the context current */
virtual void makeCurrent() = 0;

46
src/Platform/Implementation/EglContextHandler.cpp

@ -24,9 +24,12 @@
#include "EglContextHandler.h"
#include <tuple>
#include <EGL/eglext.h>
#include <Utility/Debug.h>
#include "Context.h"
#include "Version.h"
namespace Magnum { namespace Platform { namespace Implementation {
@ -88,14 +91,45 @@ VisualId EglContextHandler::getVisualId(EGLNativeDisplayType nativeDisplay) {
return visualId;
}
void EglContextHandler::createContext(EGLNativeWindowType window) {
static const EGLint contextAttributes[] = {
#ifdef MAGNUM_TARGET_GLES
EGL_CONTEXT_CLIENT_VERSION, 2,
#endif
void EglContextHandler::createContext(const AbstractXApplication::Configuration& configuration, EGLNativeWindowType window) {
EGLint attributes[] = {
/* Leave some space for optional attributes below */
EGL_NONE, 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());
std::exit(1);
}

7
src/Platform/Implementation/EglContextHandler.h

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

47
src/Platform/Implementation/GlxContextHandler.cpp

@ -25,10 +25,12 @@
#include "GlxContextHandler.h"
#include <cstdlib>
#include <tuple>
#include <GL/glxext.h>
#include <Utility/Debug.h>
#include "Context.h"
#include "Version.h"
namespace Magnum { namespace Platform { namespace Implementation {
@ -69,18 +71,51 @@ VisualID GlxContextHandler::getVisualId(Display* nativeDisplay) {
return visualId;
}
void GlxContextHandler::createContext(Window nativeWindow) {
void GlxContextHandler::createContext(const AbstractXApplication::Configuration& configuration, Window nativeWindow) {
window = nativeWindow;
GLint attributes[] = {
#ifdef MAGNUM_TARGET_GLES
GLX_CONTEXT_MAJOR_VERSION_ARB, 2,
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
#endif
/* Leave some space for optional attributes below */
0, 0,
0, 0,
0, 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. */
PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
context = glXCreateContextAttribsARB(display, configs[0], nullptr, True, attributes);

7
src/Platform/Implementation/GlxContextHandler.h

@ -31,7 +31,8 @@
#undef None
#undef Always
#include "AbstractContextHandler.h"
#include "Platform/AbstractXApplication.h"
#include "Platform/Implementation/AbstractContextHandler.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
GlxApplication.
*/
class GlxContextHandler: public AbstractContextHandler<Display*, VisualID, Window> {
class GlxContextHandler: public AbstractContextHandler<AbstractXApplication::Configuration, Display*, VisualID, Window> {
public:
explicit GlxContextHandler() = default;
~GlxContextHandler();
VisualID getVisualId(Display* nativeDisplay) override;
void createContext(Window nativeWindow) override;
void createContext(const AbstractXApplication::Configuration& configuration, Window nativeWindow) override;
void makeCurrent() override {
glXMakeCurrent(display, window, context);

Loading…
Cancel
Save