20 #define USE_GLXEW_INIT_WORKAROUND
22 #ifdef USE_GLXEW_INIT_WORKAROUND
24 static GLboolean
_glewSearchExtension(
const char *name,
const GLubyte *start,
const GLubyte *end);
27 GLXContext GHOST_ContextGLX::s_sharedContext =
None;
28 int GHOST_ContextGLX::s_sharedCount = 0;
34 int contextProfileMask,
35 int contextMajorVersion,
36 int contextMinorVersion,
38 int contextResetNotificationStrategy)
43 m_contextProfileMask(contextProfileMask),
44 m_contextMajorVersion(contextMajorVersion),
45 m_contextMinorVersion(contextMinorVersion),
46 m_contextFlags(contextFlags),
47 m_contextResetNotificationStrategy(contextResetNotificationStrategy),
50 assert(m_display !=
nullptr);
55 if (m_display !=
nullptr) {
56 if (m_context !=
None) {
57 if (m_window != 0 && m_context == ::glXGetCurrentContext()) {
58 ::glXMakeCurrent(m_display,
None,
nullptr);
60 if (m_context != s_sharedContext || s_sharedCount == 1) {
61 assert(s_sharedCount > 0);
65 if (s_sharedCount == 0) {
66 s_sharedContext =
nullptr;
69 ::glXDestroyContext(m_display, m_context);
77 ::glXSwapBuffers(m_display, m_window);
84 if (m_display ==
nullptr) {
92 if (m_display ==
nullptr) {
98 void GHOST_ContextGLX::initContextGLXEW()
110 #ifdef USE_GLXEW_INIT_WORKAROUND
111 const GLubyte *extStart = (GLubyte *)
"";
112 const GLubyte *extEnd;
113 if (glXQueryExtension(m_display,
nullptr,
nullptr)) {
114 extStart = (
const GLubyte *)glXGetClientString(m_display, GLX_EXTENSIONS);
115 if ((extStart ==
nullptr) ||
116 (glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddressARB(
117 (
const GLubyte *)
"glXChooseFBConfig")) ==
nullptr ||
118 (glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddressARB(
119 (
const GLubyte *)
"glXCreateContextAttribsARB")) ==
nullptr ||
120 (glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC)glXGetProcAddressARB(
121 (
const GLubyte *)
"glXCreatePbuffer")) ==
nullptr) {
122 extStart = (GLubyte *)
"";
127 # undef GLXEW_ARB_create_context
129 "GLX_ARB_create_context", extStart, extEnd);
130 # undef GLXEW_ARB_create_context_profile
132 "GLX_ARB_create_context_profile", extStart, extEnd);
133 # undef GLXEW_ARB_create_context_robustness
135 "GLX_ARB_create_context_robustness", extStart, extEnd);
137 # undef GLXEW_EXT_create_context_es_profile
139 "GLX_EXT_create_context_es_profile", extStart, extEnd);
140 # undef GLXEW_EXT_create_context_es2_profile
142 "GLX_EXT_create_context_es2_profile", extStart, extEnd);
153 if (GLXEW_ARB_create_context) {
154 int profileBitCore = m_contextProfileMask & GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
155 int profileBitCompat = m_contextProfileMask & GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
158 int profileBitES = m_contextProfileMask & GLX_CONTEXT_ES_PROFILE_BIT_EXT;
161 if (!GLXEW_ARB_create_context_profile && profileBitCore) {
162 fprintf(stderr,
"Warning! OpenGL core profile not available.\n");
164 if (!GLXEW_ARB_create_context_profile && profileBitCompat) {
165 fprintf(stderr,
"Warning! OpenGL compatibility profile not available.\n");
169 if (!GLXEW_EXT_create_context_es_profile && profileBitES && m_contextMajorVersion == 1)
170 fprintf(stderr,
"Warning! OpenGL ES profile not available.\n");
172 if (!GLXEW_EXT_create_context_es2_profile && profileBitES && m_contextMajorVersion == 2)
173 fprintf(stderr,
"Warning! OpenGL ES2 profile not available.\n");
178 if (GLXEW_ARB_create_context_profile && profileBitCore) {
179 profileMask |= profileBitCore;
181 if (GLXEW_ARB_create_context_profile && profileBitCompat) {
182 profileMask |= profileBitCompat;
186 if (GLXEW_EXT_create_context_es_profile && profileBitES)
187 profileMask |= profileBitES;
190 if (profileMask != m_contextProfileMask) {
191 fprintf(stderr,
"Warning! Ignoring untested OpenGL context profile mask bits.");
198 attribs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB;
199 attribs[i++] = profileMask;
202 if (m_contextMajorVersion != 0) {
203 attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB;
204 attribs[i++] = m_contextMajorVersion;
205 attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB;
206 attribs[i++] = m_contextMinorVersion;
209 if (m_contextFlags != 0) {
210 attribs[i++] = GLX_CONTEXT_FLAGS_ARB;
211 attribs[i++] = m_contextFlags;
214 if (m_contextResetNotificationStrategy != 0) {
215 if (GLXEW_ARB_create_context_robustness) {
216 attribs[i++] = GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB;
217 attribs[i++] = m_contextResetNotificationStrategy;
220 fprintf(stderr,
"Warning! Cannot set the reset notification strategy.");
228 int pbuffer_attribs[] = {GLX_PBUFFER_WIDTH, 1, GLX_PBUFFER_HEIGHT, 1,
None};
232 m_context = glXCreateContextAttribsARB(
233 m_display, m_fbconfig, s_sharedContext,
true, attribs);
236 m_window = (
Window)glXCreatePbuffer(m_display, m_fbconfig, pbuffer_attribs);
240 GLXFBConfig *framebuffer_config =
nullptr;
247 framebuffer_config = glXChooseFBConfig(
248 m_display, DefaultScreen(m_display), glx_attribs, &fbcount);
251 if (framebuffer_config) {
252 m_context = glXCreateContextAttribsARB(
253 m_display, framebuffer_config[0], s_sharedContext, True, attribs);
256 m_window = (
Window)glXCreatePbuffer(m_display, framebuffer_config[0], pbuffer_attribs);
259 m_fbconfig = framebuffer_config[0];
260 XFree(framebuffer_config);
266 fprintf(stderr,
"Error! GLX_ARB_create_context not available.\n");
271 if (m_context !=
nullptr) {
272 const unsigned char *version;
274 if (!s_sharedContext) {
275 s_sharedContext = m_context;
279 glXMakeCurrent(m_display, m_window, m_context);
287 ::glXSwapBuffers(m_display, m_window);
293 version = glGetString(GL_VERSION);
295 if (!version || version[0] <
'3' || ((version[0] ==
'3') && (version[2] <
'3'))) {
321 if (GLXEW_EXT_swap_control) {
322 ::glXSwapIntervalEXT(m_display, m_window, interval);
330 if (GLXEW_EXT_swap_control) {
331 unsigned int interval = 0;
333 ::glXQueryDrawable(m_display, m_window, GLX_SWAP_INTERVAL_EXT, &interval);
335 intervalOut =
static_cast<int>(interval);
351 int *attribs,
int attribs_max,
bool is_stereo_visual,
bool need_alpha,
bool for_fb_config)
355 if (is_stereo_visual) {
356 attribs[i++] = GLX_STEREO;
363 attribs[i++] = GLX_RENDER_TYPE;
364 attribs[i++] = GLX_RGBA_BIT;
367 attribs[i++] = GLX_RGBA;
370 attribs[i++] = GLX_DOUBLEBUFFER;
375 attribs[i++] = GLX_RED_SIZE;
378 attribs[i++] = GLX_BLUE_SIZE;
381 attribs[i++] = GLX_GREEN_SIZE;
385 attribs[i++] = GLX_ALPHA_SIZE;
391 GHOST_ASSERT(i <= attribs_max,
"attribute size too small");
399 #ifdef USE_GLXEW_INIT_WORKAROUND
406 while (s[i] !=
'\0') {
418 while (s[i] !=
'\0' && s[i] !=
c) {
421 return (s[i] ==
'\0' || s[i] ==
c) ? i : 0;
427 if (
a ==
nullptr ||
b ==
nullptr) {
428 return (
a ==
nullptr &&
b ==
nullptr && n == 0) ? GL_TRUE : GL_FALSE;
430 while (i < n &&
a[i] !=
'\0' &&
b[i] !=
'\0' &&
a[i] ==
b[i]) {
433 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()
SyclQueue void void size_t num_bytes void
static const pxr::TfToken b("b", pxr::TfToken::Immortal)