20 #define CASE_CODE_RETURN_STR(code) \
51 return "The last function succeeded without error.";
53 case EGL_NOT_INITIALIZED:
55 "EGL is not initialized, or could not be initialized, "
56 "for the specified EGL display connection.");
60 "EGL cannot access a requested resource "
61 "(for example a context is bound in another thread).");
64 return "EGL failed to allocate resources for the requested operation.";
66 case EGL_BAD_ATTRIBUTE:
67 return "An unrecognized attribute or attribute value was passed in the attribute list.";
70 return "An EGLContext argument does not name a valid EGL rendering context.";
73 return "An EGLConfig argument does not name a valid EGL frame buffer configuration.";
75 case EGL_BAD_CURRENT_SURFACE:
77 "The current surface of the calling thread is a window, "
78 "pixel buffer or pixmap that is no longer valid.");
81 return "An EGLDisplay argument does not name a valid EGL display connection.";
85 "An EGLSurface argument does not name a valid surface "
86 "(window, pixel buffer or pixmap) configured for GL rendering.");
90 "Arguments are inconsistent "
91 "(for example, a valid context requires buffers not supplied by a valid surface).");
93 case EGL_BAD_PARAMETER:
94 return "One or more argument values are invalid.";
96 case EGL_BAD_NATIVE_PIXMAP:
97 return "A NativePixmapType argument does not refer to a valid native pixmap.";
99 case EGL_BAD_NATIVE_WINDOW:
100 return "A NativeWindowType argument does not refer to a valid native window.";
102 case EGL_CONTEXT_LOST:
104 "A power management event has occurred. "
105 "The application must destroy all contexts and reinitialize OpenGL ES state "
106 "and objects to continue rendering.");
114 const char *
file =
nullptr,
116 const char *text =
nullptr)
119 const EGLint
error = eglGetError();
126 "%s(%d):[%s] -> EGL Error (0x%04X): %s: %s\n",
130 static_cast<unsigned int>(
error),
131 code ? code :
"<Unknown>",
132 msg ? msg :
"<Unknown>");
135 "EGL Error (0x%04X): %s: %s\n",
136 static_cast<unsigned int>(
error),
137 code ? code :
"<Unknown>",
138 msg ? msg :
"<Unknown>");
149 # define EGL_CHK(x) egl_chk((x), __FILE__, __LINE__, # x)
151 # define EGL_CHK(x) egl_chk(x)
156 if (EGLEW_VERSION_1_2) {
157 return (
EGL_CHK(eglBindAPI(api)) == EGL_TRUE);
164 HMODULE GHOST_ContextEGL::s_d3dcompiler =
nullptr;
167 EGLContext GHOST_ContextEGL::s_gl_sharedContext = EGL_NO_CONTEXT;
168 EGLint GHOST_ContextEGL::s_gl_sharedCount = 0;
170 EGLContext GHOST_ContextEGL::s_gles_sharedContext = EGL_NO_CONTEXT;
171 EGLint GHOST_ContextEGL::s_gles_sharedCount = 0;
173 EGLContext GHOST_ContextEGL::s_vg_sharedContext = EGL_NO_CONTEXT;
174 EGLint GHOST_ContextEGL::s_vg_sharedCount = 0;
177 # pragma warning(disable : 4715)
185 case EGL_OPENGL_ES_API:
196 EGLNativeWindowType nativeWindow,
197 EGLNativeDisplayType nativeDisplay,
198 EGLint contextProfileMask,
199 EGLint contextMajorVersion,
200 EGLint contextMinorVersion,
202 EGLint contextResetNotificationStrategy,
206 m_nativeDisplay(nativeDisplay),
207 m_nativeWindow(nativeWindow),
208 m_contextProfileMask(contextProfileMask),
209 m_contextMajorVersion(contextMajorVersion),
210 m_contextMinorVersion(contextMinorVersion),
211 m_contextFlags(contextFlags),
212 m_contextResetNotificationStrategy(contextResetNotificationStrategy),
214 m_context(EGL_NO_CONTEXT),
215 m_surface(EGL_NO_SURFACE),
216 m_display(EGL_NO_DISPLAY),
219 choose_api(api, s_gl_sharedContext, s_gles_sharedContext, s_vg_sharedContext)),
220 m_sharedCount(
choose_api(api, s_gl_sharedCount, s_gles_sharedCount, s_vg_sharedCount))
226 if (m_display != EGL_NO_DISPLAY) {
230 if (m_context != EGL_NO_CONTEXT) {
231 if (m_context == ::eglGetCurrentContext()) {
232 EGL_CHK(::eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
234 if (m_context != m_sharedContext || m_sharedCount == 1) {
235 assert(m_sharedCount > 0);
239 if (m_sharedCount == 0) {
240 m_sharedContext = EGL_NO_CONTEXT;
242 EGL_CHK(::eglDestroyContext(m_display, m_context));
246 if (m_surface != EGL_NO_SURFACE) {
247 EGL_CHK(::eglDestroySurface(m_display, m_surface));
259 if (EGLEW_VERSION_1_1) {
260 if (
EGL_CHK(::eglSwapInterval(m_display, interval))) {
261 m_swap_interval = interval;
274 intervalOut = m_swap_interval;
309 return EGL_CHK(::eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) ?
316 bool GHOST_ContextEGL::initContextEGLEW()
321 eglGetDisplay = (PFNEGLGETDISPLAYPROC)eglGetProcAddress(
"eglGetDisplay");
322 if (eglGetDisplay ==
nullptr) {
326 if (!
EGL_CHK((m_display = ::eglGetDisplay(m_nativeDisplay)) != EGL_NO_DISPLAY)) {
330 if (
GLEW_CHK(eglewInit(m_display)) != GLEW_OK) {
331 fprintf(stderr,
"Warning! EGLEW failed to initialize properly.\n");
340 static const std::string
a(
"OpenGL");
341 static const std::string
b(
"OpenGL ES");
342 static const std::string
c(
"OpenVG");
350 std::vector<EGLint> attrib_list;
351 EGLint num_config = 0;
354 fprintf(stderr,
"Warning! Stereo OpenGL ES contexts are not supported.\n");
358 if (!initContextEGLEW()) {
364 if (s_d3dcompiler ==
nullptr) {
365 s_d3dcompiler = LoadLibrary(D3DCOMPILER);
367 WIN32_CHK(s_d3dcompiler !=
nullptr);
369 if (s_d3dcompiler ==
nullptr) {
370 fprintf(stderr,
"LoadLibrary(\"" D3DCOMPILER
"\") failed!\n");
376 EGLDisplay prev_display = eglGetCurrentDisplay();
377 EGLSurface prev_draw = eglGetCurrentSurface(EGL_DRAW);
378 EGLSurface prev_read = eglGetCurrentSurface(EGL_READ);
379 EGLContext prev_context = eglGetCurrentContext();
381 EGLint egl_major, egl_minor;
383 if (!
EGL_CHK(::eglInitialize(m_display, &egl_major, &egl_minor))) {
386 #ifdef WITH_GHOST_DEBUG
387 fprintf(stderr,
"EGL Version %d.%d\n", egl_major, egl_minor);
390 if (!
EGL_CHK(::eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))) {
399 attrib_list.reserve(20);
401 if (m_api == EGL_OPENGL_ES_API && EGLEW_VERSION_1_2) {
405 if (m_contextMajorVersion == 1) {
406 attrib_list.push_back(EGL_RENDERABLE_TYPE);
407 attrib_list.push_back(EGL_OPENGL_ES_BIT);
409 else if (m_contextMajorVersion == 2) {
410 attrib_list.push_back(EGL_RENDERABLE_TYPE);
411 attrib_list.push_back(EGL_OPENGL_ES2_BIT);
413 else if (m_contextMajorVersion == 3) {
414 attrib_list.push_back(EGL_RENDERABLE_TYPE);
415 attrib_list.push_back(EGL_OPENGL_ES3_BIT_KHR);
419 "Warning! Unable to request an ES context of version %d.%d\n",
420 m_contextMajorVersion,
421 m_contextMinorVersion);
424 if (!((m_contextMajorVersion == 1) || (m_contextMajorVersion == 2 && EGLEW_VERSION_1_3) ||
425 (m_contextMajorVersion == 3 && EGLEW_KHR_create_context) ||
426 (m_contextMajorVersion == 3 && EGLEW_VERSION_1_5))) {
428 "Warning! May not be able to create a version %d.%d ES context with version %d.%d "
430 m_contextMajorVersion,
431 m_contextMinorVersion,
437 attrib_list.push_back(EGL_RENDERABLE_TYPE);
438 attrib_list.push_back(EGL_OPENGL_BIT);
441 attrib_list.push_back(EGL_RED_SIZE);
442 attrib_list.push_back(8);
444 attrib_list.push_back(EGL_GREEN_SIZE);
445 attrib_list.push_back(8);
447 attrib_list.push_back(EGL_BLUE_SIZE);
448 attrib_list.push_back(8);
450 #ifdef GHOST_OPENGL_ALPHA
451 attrib_list.push_back(EGL_ALPHA_SIZE);
452 attrib_list.push_back(8);
455 if (m_nativeWindow == 0) {
457 attrib_list.push_back(EGL_SURFACE_TYPE);
458 attrib_list.push_back(EGL_PBUFFER_BIT);
461 attrib_list.push_back(EGL_NONE);
463 if (!
EGL_CHK(::eglChooseConfig(m_display, &(attrib_list[0]), &m_config, 1, &num_config))) {
468 if (num_config != 1) {
472 if (m_nativeWindow != 0) {
473 m_surface = ::eglCreateWindowSurface(m_display, m_config, m_nativeWindow,
nullptr);
476 static const EGLint pb_attrib_list[] = {
483 m_surface = ::eglCreatePbufferSurface(m_display, m_config, pb_attrib_list);
486 if (!
EGL_CHK(m_surface != EGL_NO_SURFACE)) {
491 if (EGLEW_VERSION_1_5 || EGLEW_KHR_create_context) {
492 if (m_api == EGL_OPENGL_API || m_api == EGL_OPENGL_ES_API) {
493 if (m_contextMajorVersion != 0) {
494 attrib_list.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR);
495 attrib_list.push_back(m_contextMajorVersion);
498 if (m_contextMinorVersion != 0) {
499 attrib_list.push_back(EGL_CONTEXT_MINOR_VERSION_KHR);
500 attrib_list.push_back(m_contextMinorVersion);
503 if (m_contextFlags != 0) {
504 attrib_list.push_back(EGL_CONTEXT_FLAGS_KHR);
505 attrib_list.push_back(m_contextFlags);
509 if (m_contextMajorVersion != 0 || m_contextMinorVersion != 0) {
511 "Warning! Cannot request specific versions of %s contexts.",
515 if (m_contextFlags != 0) {
516 fprintf(stderr,
"Warning! Flags cannot be set on %s contexts.",
api_string(m_api).c_str());
520 if (m_api == EGL_OPENGL_API) {
521 if (m_contextProfileMask != 0) {
522 attrib_list.push_back(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR);
523 attrib_list.push_back(m_contextProfileMask);
527 if (m_contextProfileMask != 0) {
529 stderr,
"Warning! Cannot select profile for %s contexts.",
api_string(m_api).c_str());
533 if (m_api == EGL_OPENGL_API || EGLEW_VERSION_1_5) {
534 if (m_contextResetNotificationStrategy != 0) {
535 attrib_list.push_back(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR);
536 attrib_list.push_back(m_contextResetNotificationStrategy);
540 if (m_contextResetNotificationStrategy != 0) {
542 "Warning! EGL %d.%d cannot set the reset notification strategy on %s contexts.",
550 if (m_api == EGL_OPENGL_ES_API) {
551 if (m_contextMajorVersion != 0) {
552 attrib_list.push_back(EGL_CONTEXT_CLIENT_VERSION);
553 attrib_list.push_back(m_contextMajorVersion);
557 if (m_contextMajorVersion != 0 || m_contextMinorVersion != 0) {
559 "Warning! EGL %d.%d is unable to select between versions of %s.",
566 if (m_contextFlags != 0) {
567 fprintf(stderr,
"Warning! EGL %d.%d is unable to set context flags.", egl_major, egl_minor);
569 if (m_contextProfileMask != 0) {
571 "Warning! EGL %d.%d is unable to select between profiles.",
575 if (m_contextResetNotificationStrategy != 0) {
577 "Warning! EGL %d.%d is unable to set the reset notification strategies.",
583 attrib_list.push_back(EGL_NONE);
585 m_context = ::eglCreateContext(m_display, m_config, m_sharedContext, &(attrib_list[0]));
587 if (!
EGL_CHK(m_context != EGL_NO_CONTEXT)) {
591 if (m_sharedContext == EGL_NO_CONTEXT) {
592 m_sharedContext = m_context;
597 if (!
EGL_CHK(::eglMakeCurrent(m_display, m_surface, m_surface, m_context))) {
604 ::eglSwapBuffers(m_display, m_surface);
609 if (prev_display != EGL_NO_DISPLAY) {
610 EGL_CHK(eglMakeCurrent(prev_display, prev_draw, prev_read, prev_context));
618 m_nativeDisplay =
nullptr;
static const char * get_egl_error_message_string(EGLint error)
T & choose_api(EGLenum api, T &a, T &b, T &c)
static const std::string & api_string(EGLenum api)
static const char * get_egl_error_enum_string(EGLint error)
static bool egl_chk(bool result, const char *file=nullptr, int line=0, const char *text=nullptr)
static bool bindAPI(EGLenum api)
#define CASE_CODE_RETURN_STR(code)
GHOST_TSuccess releaseDrawingContext()
GHOST_TSuccess activateDrawingContext()
GHOST_TSuccess getSwapInterval(int &intervalOut)
GHOST_TSuccess initializeDrawingContext()
GHOST_TSuccess setSwapInterval(int interval)
EGLConfig getConfig() const
GHOST_ContextEGL(const GHOST_System *const system, bool stereoVisual, EGLNativeWindowType nativeWindow, EGLNativeDisplayType nativeDisplay, EGLint contextProfileMask, EGLint contextMajorVersion, EGLint contextMinorVersion, EGLint contextFlags, EGLint contextResetNotificationStrategy, EGLenum api)
EGLDisplay getDisplay() const
GHOST_TSuccess releaseNativeHandles()
EGLContext getContext() const
GHOST_TSuccess swapBuffers()
static void initClearGL()
SyclQueue void void size_t num_bytes void
static void error(const char *str)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)