36 #define USE_GLXEW_INIT_WORKAROUND
38 #ifdef USE_GLXEW_INIT_WORKAROUND
40 static GLboolean
_glewSearchExtension(
const char *name,
const GLubyte *start,
const GLubyte *end);
43 GLXContext GHOST_ContextGLX::s_sharedContext = None;
44 int GHOST_ContextGLX::s_sharedCount = 0;
50 int contextProfileMask,
51 int contextMajorVersion,
52 int contextMinorVersion,
54 int contextResetNotificationStrategy)
59 m_contextProfileMask(contextProfileMask),
60 m_contextMajorVersion(contextMajorVersion),
61 m_contextMinorVersion(contextMinorVersion),
62 m_contextFlags(contextFlags),
63 m_contextResetNotificationStrategy(contextResetNotificationStrategy),
66 assert(m_display !=
NULL);
71 if (m_display !=
NULL) {
72 if (m_context != None) {
73 if (m_window != 0 && m_context == ::glXGetCurrentContext())
74 ::glXMakeCurrent(m_display, None,
NULL);
76 if (m_context != s_sharedContext || s_sharedCount == 1) {
77 assert(s_sharedCount > 0);
81 if (s_sharedCount == 0)
82 s_sharedContext =
NULL;
84 ::glXDestroyContext(m_display, m_context);
92 ::glXSwapBuffers(m_display, m_window);
117 void GHOST_ContextGLX::initContextGLXEW()
129 #ifdef USE_GLXEW_INIT_WORKAROUND
130 const GLubyte *extStart = (GLubyte *)
"";
131 const GLubyte *extEnd;
132 if (glXQueryExtension(m_display,
NULL,
NULL)) {
133 extStart = (
const GLubyte *)glXGetClientString(m_display, GLX_EXTENSIONS);
134 if ((extStart ==
NULL) ||
135 (glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddressARB(
136 (
const GLubyte *)
"glXChooseFBConfig")) ==
NULL ||
137 (glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddressARB(
138 (
const GLubyte *)
"glXCreateContextAttribsARB")) ==
NULL ||
139 (glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC)glXGetProcAddressARB(
140 (
const GLubyte *)
"glXCreatePbuffer")) ==
NULL) {
141 extStart = (GLubyte *)
"";
146 # undef GLXEW_ARB_create_context
148 "GLX_ARB_create_context", extStart, extEnd);
149 # undef GLXEW_ARB_create_context_profile
151 "GLX_ARB_create_context_profile", extStart, extEnd);
152 # undef GLXEW_ARB_create_context_robustness
154 "GLX_ARB_create_context_robustness", extStart, extEnd);
156 # undef GLXEW_EXT_create_context_es_profile
158 "GLX_EXT_create_context_es_profile", extStart, extEnd);
159 # undef GLXEW_EXT_create_context_es2_profile
161 "GLX_EXT_create_context_es2_profile", extStart, extEnd);
172 if (GLXEW_ARB_create_context) {
173 int profileBitCore = m_contextProfileMask & GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
174 int profileBitCompat = m_contextProfileMask & GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
177 int profileBitES = m_contextProfileMask & GLX_CONTEXT_ES_PROFILE_BIT_EXT;
180 if (!GLXEW_ARB_create_context_profile && profileBitCore)
181 fprintf(stderr,
"Warning! OpenGL core profile not available.\n");
183 if (!GLXEW_ARB_create_context_profile && profileBitCompat)
184 fprintf(stderr,
"Warning! OpenGL compatibility profile not available.\n");
187 if (!GLXEW_EXT_create_context_es_profile && profileBitES && m_contextMajorVersion == 1)
188 fprintf(stderr,
"Warning! OpenGL ES profile not available.\n");
190 if (!GLXEW_EXT_create_context_es2_profile && profileBitES && m_contextMajorVersion == 2)
191 fprintf(stderr,
"Warning! OpenGL ES2 profile not available.\n");
196 if (GLXEW_ARB_create_context_profile && profileBitCore)
197 profileMask |= profileBitCore;
199 if (GLXEW_ARB_create_context_profile && profileBitCompat)
200 profileMask |= profileBitCompat;
203 if (GLXEW_EXT_create_context_es_profile && profileBitES)
204 profileMask |= profileBitES;
207 if (profileMask != m_contextProfileMask)
208 fprintf(stderr,
"Warning! Ignoring untested OpenGL context profile mask bits.");
215 attribs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB;
216 attribs[i++] = profileMask;
219 if (m_contextMajorVersion != 0) {
220 attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB;
221 attribs[i++] = m_contextMajorVersion;
222 attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB;
223 attribs[i++] = m_contextMinorVersion;
226 if (m_contextFlags != 0) {
227 attribs[i++] = GLX_CONTEXT_FLAGS_ARB;
228 attribs[i++] = m_contextFlags;
231 if (m_contextResetNotificationStrategy != 0) {
232 if (GLXEW_ARB_create_context_robustness) {
233 attribs[i++] = GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB;
234 attribs[i++] = m_contextResetNotificationStrategy;
237 fprintf(stderr,
"Warning! Cannot set the reset notification strategy.");
245 int pbuffer_attribs[] = {GLX_PBUFFER_WIDTH, 1, GLX_PBUFFER_HEIGHT, 1, None};
249 m_context = glXCreateContextAttribsARB(
250 m_display, m_fbconfig, s_sharedContext,
true, attribs);
253 m_window = (Window)glXCreatePbuffer(m_display, m_fbconfig, pbuffer_attribs);
257 GLXFBConfig *framebuffer_config =
NULL;
264 framebuffer_config = glXChooseFBConfig(
265 m_display, DefaultScreen(m_display), glx_attribs, &fbcount);
268 if (framebuffer_config) {
269 m_context = glXCreateContextAttribsARB(
270 m_display, framebuffer_config[0], s_sharedContext, True, attribs);
273 m_window = (Window)glXCreatePbuffer(m_display, framebuffer_config[0], pbuffer_attribs);
276 m_fbconfig = framebuffer_config[0];
277 XFree(framebuffer_config);
283 fprintf(stderr,
"Error! GLX_ARB_create_context not available.\n");
288 if (m_context !=
NULL) {
289 const unsigned char *version;
291 if (!s_sharedContext)
292 s_sharedContext = m_context;
296 glXMakeCurrent(m_display, m_window, m_context);
304 ::glXSwapBuffers(m_display, m_window);
310 version = glGetString(GL_VERSION);
312 if (!version || version[0] <
'3' || ((version[0] ==
'3') && (version[2] <
'3'))) {
338 if (GLXEW_EXT_swap_control) {
339 ::glXSwapIntervalEXT(m_display, m_window, interval);
350 if (GLXEW_EXT_swap_control) {
351 unsigned int interval = 0;
353 ::glXQueryDrawable(m_display, m_window, GLX_SWAP_INTERVAL_EXT, &interval);
355 intervalOut =
static_cast<int>(interval);
373 int *attribs,
int attribs_max,
bool is_stereo_visual,
bool need_alpha,
bool for_fb_config)
377 if (is_stereo_visual) {
378 attribs[i++] = GLX_STEREO;
385 attribs[i++] = GLX_RENDER_TYPE;
386 attribs[i++] = GLX_RGBA_BIT;
389 attribs[i++] = GLX_RGBA;
392 attribs[i++] = GLX_DOUBLEBUFFER;
397 attribs[i++] = GLX_RED_SIZE;
400 attribs[i++] = GLX_BLUE_SIZE;
403 attribs[i++] = GLX_GREEN_SIZE;
407 attribs[i++] = GLX_ALPHA_SIZE;
413 GHOST_ASSERT(i <= attribs_max,
"attribute size too small");
421 #ifdef USE_GLXEW_INIT_WORKAROUND
437 while (s[i] !=
'\0' && s[i] !=
c)
439 return (s[i] ==
'\0' || s[i] ==
c) ? i : 0;
446 return (
a ==
NULL && b ==
NULL && n == 0) ? GL_TRUE : GL_FALSE;
447 while (i < n &&
a[i] !=
'\0' && b[i] !=
'\0' &&
a[i] == b[i])
449 return i == n ? GL_TRUE : GL_FALSE;
int GHOST_X11_GL_GetAttributes(int *attribs, int attribs_max, bool is_stereo_visual, bool need_alpha, bool for_fb_config)
static GLboolean _glewSearchExtension(const char *name, const GLubyte *start, const GLubyte *end)
static GLboolean _glewStrSame(const GLubyte *a, const GLubyte *b, GLuint n)
static GLuint _glewStrLen(const GLubyte *s)
static GLuint _glewStrCLen(const GLubyte *s, GLubyte c)
#define GHOST_ASSERT(x, info)
#define GHOST_X11_ERROR_HANDLERS_OVERRIDE(var)
#define GHOST_X11_ERROR_HANDLERS_RESTORE(var)
GHOST_TSuccess releaseDrawingContext()
GHOST_TSuccess getSwapInterval(int &intervalOut)
GHOST_TSuccess initializeDrawingContext()
GHOST_TSuccess activateDrawingContext()
GHOST_TSuccess setSwapInterval(int interval)
GHOST_TSuccess releaseNativeHandles()
GHOST_TSuccess swapBuffers()
GHOST_ContextGLX(bool stereoVisual, Window window, Display *display, GLXFBConfig fbconfig, int contextProfileMask, int contextMajorVersion, int contextMinorVersion, int contextFlags, int contextResetNotificationStrategy)
static void initClearGL()