36 #define CASE_CODE_RETURN_STR(code) \
67 return "The last function succeeded without error.";
69 case EGL_NOT_INITIALIZED:
71 "EGL is not initialized, or could not be initialized, "
72 "for the specified EGL display connection.");
76 "EGL cannot access a requested resource "
77 "(for example a context is bound in another thread).");
80 return "EGL failed to allocate resources for the requested operation.";
82 case EGL_BAD_ATTRIBUTE:
83 return "An unrecognized attribute or attribute value was passed in the attribute list.";
86 return "An EGLContext argument does not name a valid EGL rendering context.";
89 return "An EGLConfig argument does not name a valid EGL frame buffer configuration.";
91 case EGL_BAD_CURRENT_SURFACE:
93 "The current surface of the calling thread is a window, "
94 "pixel buffer or pixmap that is no longer valid.");
97 return "An EGLDisplay argument does not name a valid EGL display connection.";
101 "An EGLSurface argument does not name a valid surface "
102 "(window, pixel buffer or pixmap) configured for GL rendering.");
106 "Arguments are inconsistent "
107 "(for example, a valid context requires buffers not supplied by a valid surface).");
109 case EGL_BAD_PARAMETER:
110 return "One or more argument values are invalid.";
112 case EGL_BAD_NATIVE_PIXMAP:
113 return "A NativePixmapType argument does not refer to a valid native pixmap.";
115 case EGL_BAD_NATIVE_WINDOW:
116 return "A NativeWindowType argument does not refer to a valid native window.";
118 case EGL_CONTEXT_LOST:
120 "A power management event has occurred. "
121 "The application must destroy all contexts and reinitialize OpenGL ES state "
122 "and objects to continue rendering.");
132 const EGLint
error = eglGetError();
139 "%s(%d):[%s] -> EGL Error (0x%04X): %s: %s\n",
143 static_cast<unsigned int>(
error),
144 code ? code :
"<Unknown>",
145 msg ? msg :
"<Unknown>");
148 "EGL Error (0x%04X): %s: %s\n",
149 static_cast<unsigned int>(
error),
150 code ? code :
"<Unknown>",
151 msg ? msg :
"<Unknown>");
159 # define EGL_CHK(x) egl_chk((x), __FILE__, __LINE__, # x)
161 # define EGL_CHK(x) egl_chk(x)
166 if (EGLEW_VERSION_1_2) {
167 return (
EGL_CHK(eglBindAPI(api)) == EGL_TRUE);
174 HMODULE GHOST_ContextEGL::s_d3dcompiler =
NULL;
177 EGLContext GHOST_ContextEGL::s_gl_sharedContext = EGL_NO_CONTEXT;
178 EGLint GHOST_ContextEGL::s_gl_sharedCount = 0;
180 EGLContext GHOST_ContextEGL::s_gles_sharedContext = EGL_NO_CONTEXT;
181 EGLint GHOST_ContextEGL::s_gles_sharedCount = 0;
183 EGLContext GHOST_ContextEGL::s_vg_sharedContext = EGL_NO_CONTEXT;
184 EGLint GHOST_ContextEGL::s_vg_sharedCount = 0;
186 #pragma warning(disable : 4715)
193 case EGL_OPENGL_ES_API:
203 EGLNativeWindowType nativeWindow,
204 EGLNativeDisplayType nativeDisplay,
205 EGLint contextProfileMask,
206 EGLint contextMajorVersion,
207 EGLint contextMinorVersion,
209 EGLint contextResetNotificationStrategy,
212 m_nativeDisplay(nativeDisplay),
213 m_nativeWindow(nativeWindow),
214 m_contextProfileMask(contextProfileMask),
215 m_contextMajorVersion(contextMajorVersion),
216 m_contextMinorVersion(contextMinorVersion),
217 m_contextFlags(contextFlags),
218 m_contextResetNotificationStrategy(contextResetNotificationStrategy),
220 m_context(EGL_NO_CONTEXT),
221 m_surface(EGL_NO_SURFACE),
222 m_display(EGL_NO_DISPLAY),
225 choose_api(api, s_gl_sharedContext, s_gles_sharedContext, s_vg_sharedContext)),
226 m_sharedCount(
choose_api(api, s_gl_sharedCount, s_gles_sharedCount, s_vg_sharedCount))
232 if (m_display != EGL_NO_DISPLAY) {
236 if (m_context != EGL_NO_CONTEXT) {
237 if (m_context == ::eglGetCurrentContext())
238 EGL_CHK(::eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
240 if (m_context != m_sharedContext || m_sharedCount == 1) {
241 assert(m_sharedCount > 0);
245 if (m_sharedCount == 0)
246 m_sharedContext = EGL_NO_CONTEXT;
248 EGL_CHK(::eglDestroyContext(m_display, m_context));
252 if (m_surface != EGL_NO_SURFACE)
253 EGL_CHK(::eglDestroySurface(m_display, m_surface));
264 if (EGLEW_VERSION_1_1) {
265 if (
EGL_CHK(::eglSwapInterval(m_display, interval))) {
266 m_swap_interval = interval;
283 intervalOut = m_swap_interval;
306 return EGL_CHK(::eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) ?
315 bool GHOST_ContextEGL::initContextEGLEW()
320 eglGetDisplay = (PFNEGLGETDISPLAYPROC)eglGetProcAddress(
"eglGetDisplay");
321 if (eglGetDisplay ==
NULL) {
325 if (!
EGL_CHK((m_display = ::eglGetDisplay(m_nativeDisplay)) != EGL_NO_DISPLAY)) {
329 if (
GLEW_CHK(eglewInit(m_display)) != GLEW_OK) {
330 fprintf(stderr,
"Warning! EGLEW failed to initialize properly.\n");
339 static const std::string
a(
"OpenGL");
340 static const std::string b(
"OpenGL ES");
341 static const std::string
c(
"OpenVG");
349 std::vector<EGLint> attrib_list;
350 EGLint num_config = 0;
353 fprintf(stderr,
"Warning! Stereo OpenGL ES contexts are not supported.\n");
357 if (!initContextEGLEW()) {
363 if (s_d3dcompiler ==
NULL) {
364 s_d3dcompiler = LoadLibrary(D3DCOMPILER);
366 WIN32_CHK(s_d3dcompiler !=
NULL);
368 if (s_d3dcompiler ==
NULL) {
369 fprintf(stderr,
"LoadLibrary(\"" D3DCOMPILER
"\") failed!\n");
375 EGLDisplay prev_display = eglGetCurrentDisplay();
376 EGLSurface prev_draw = eglGetCurrentSurface(EGL_DRAW);
377 EGLSurface prev_read = eglGetCurrentSurface(EGL_READ);
378 EGLContext prev_context = eglGetCurrentContext();
380 EGLint egl_major, egl_minor;
382 if (!
EGL_CHK(::eglInitialize(m_display, &egl_major, &egl_minor)))
385 fprintf(stderr,
"EGL Version %d.%d\n", egl_major, egl_minor);
387 if (!
EGL_CHK(::eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)))
395 attrib_list.reserve(20);
397 if (m_api == EGL_OPENGL_ES_API && EGLEW_VERSION_1_2) {
401 if (m_contextMajorVersion == 1) {
402 attrib_list.push_back(EGL_RENDERABLE_TYPE);
403 attrib_list.push_back(EGL_OPENGL_ES_BIT);
405 else if (m_contextMajorVersion == 2) {
406 attrib_list.push_back(EGL_RENDERABLE_TYPE);
407 attrib_list.push_back(EGL_OPENGL_ES2_BIT);
409 else if (m_contextMajorVersion == 3) {
410 attrib_list.push_back(EGL_RENDERABLE_TYPE);
411 attrib_list.push_back(EGL_OPENGL_ES3_BIT_KHR);
415 "Warning! Unable to request an ES context of version %d.%d\n",
416 m_contextMajorVersion,
417 m_contextMinorVersion);
420 if (!((m_contextMajorVersion == 1) || (m_contextMajorVersion == 2 && EGLEW_VERSION_1_3) ||
421 (m_contextMajorVersion == 3 && EGLEW_KHR_create_context) ||
422 (m_contextMajorVersion == 3 && EGLEW_VERSION_1_5))) {
424 "Warning! May not be able to create a version %d.%d ES context with version %d.%d "
426 m_contextMajorVersion,
427 m_contextMinorVersion,
433 attrib_list.push_back(EGL_RENDERABLE_TYPE);
434 attrib_list.push_back(EGL_OPENGL_BIT);
437 attrib_list.push_back(EGL_RED_SIZE);
438 attrib_list.push_back(8);
440 attrib_list.push_back(EGL_GREEN_SIZE);
441 attrib_list.push_back(8);
443 attrib_list.push_back(EGL_BLUE_SIZE);
444 attrib_list.push_back(8);
446 #ifdef GHOST_OPENGL_ALPHA
447 attrib_list.push_back(EGL_ALPHA_SIZE);
448 attrib_list.push_back(8);
451 if (m_nativeWindow == 0) {
453 attrib_list.push_back(EGL_SURFACE_TYPE);
454 attrib_list.push_back(EGL_PBUFFER_BIT);
457 attrib_list.push_back(EGL_NONE);
461 if (!
EGL_CHK(::eglChooseConfig(m_display, &(attrib_list[0]), &config, 1, &num_config)))
468 if (m_nativeWindow != 0) {
469 m_surface = ::eglCreateWindowSurface(m_display, config, m_nativeWindow,
NULL);
472 static const EGLint pb_attrib_list[] = {
479 m_surface = ::eglCreatePbufferSurface(m_display, config, pb_attrib_list);
482 if (!
EGL_CHK(m_surface != EGL_NO_SURFACE))
487 if (EGLEW_VERSION_1_5 || EGLEW_KHR_create_context) {
488 if (m_api == EGL_OPENGL_API || m_api == EGL_OPENGL_ES_API) {
489 if (m_contextMajorVersion != 0) {
490 attrib_list.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR);
491 attrib_list.push_back(m_contextMajorVersion);
494 if (m_contextMinorVersion != 0) {
495 attrib_list.push_back(EGL_CONTEXT_MINOR_VERSION_KHR);
496 attrib_list.push_back(m_contextMinorVersion);
499 if (m_contextFlags != 0) {
500 attrib_list.push_back(EGL_CONTEXT_FLAGS_KHR);
501 attrib_list.push_back(m_contextFlags);
505 if (m_contextMajorVersion != 0 || m_contextMinorVersion != 0) {
507 "Warning! Cannot request specific versions of %s contexts.",
511 if (m_contextFlags != 0) {
512 fprintf(stderr,
"Warning! Flags cannot be set on %s contexts.",
api_string(m_api).c_str());
516 if (m_api == EGL_OPENGL_API) {
517 if (m_contextProfileMask != 0) {
518 attrib_list.push_back(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR);
519 attrib_list.push_back(m_contextProfileMask);
523 if (m_contextProfileMask != 0)
525 stderr,
"Warning! Cannot select profile for %s contexts.",
api_string(m_api).c_str());
528 if (m_api == EGL_OPENGL_API || EGLEW_VERSION_1_5) {
529 if (m_contextResetNotificationStrategy != 0) {
530 attrib_list.push_back(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR);
531 attrib_list.push_back(m_contextResetNotificationStrategy);
535 if (m_contextResetNotificationStrategy != 0) {
537 "Warning! EGL %d.%d cannot set the reset notification strategy on %s contexts.",
545 if (m_api == EGL_OPENGL_ES_API) {
546 if (m_contextMajorVersion != 0) {
547 attrib_list.push_back(EGL_CONTEXT_CLIENT_VERSION);
548 attrib_list.push_back(m_contextMajorVersion);
552 if (m_contextMajorVersion != 0 || m_contextMinorVersion != 0) {
554 "Warning! EGL %d.%d is unable to select between versions of %s.",
561 if (m_contextFlags != 0) {
562 fprintf(stderr,
"Warning! EGL %d.%d is unable to set context flags.", egl_major, egl_minor);
564 if (m_contextProfileMask != 0) {
566 "Warning! EGL %d.%d is unable to select between profiles.",
570 if (m_contextResetNotificationStrategy != 0) {
572 "Warning! EGL %d.%d is unable to set the reset notification strategies.",
578 attrib_list.push_back(EGL_NONE);
580 m_context = ::eglCreateContext(m_display, config, m_sharedContext, &(attrib_list[0]));
582 if (!
EGL_CHK(m_context != EGL_NO_CONTEXT))
585 if (m_sharedContext == EGL_NO_CONTEXT)
586 m_sharedContext = m_context;
590 if (!
EGL_CHK(::eglMakeCurrent(m_display, m_surface, m_surface, m_context)))
596 ::eglSwapBuffers(m_display, m_surface);
601 if (prev_display != EGL_NO_DISPLAY)
602 EGL_CHK(eglMakeCurrent(prev_display, prev_draw, prev_read, prev_context));
610 m_nativeDisplay =
NULL;
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=NULL, int line=0, const char *text=NULL)
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)
GHOST_ContextEGL(bool stereoVisual, EGLNativeWindowType nativeWindow, EGLNativeDisplayType nativeDisplay, EGLint contextProfileMask, EGLint contextMajorVersion, EGLint contextMinorVersion, EGLint contextFlags, EGLint contextResetNotificationStrategy, EGLenum api)
GHOST_TSuccess releaseNativeHandles()
GHOST_TSuccess swapBuffers()
static void initClearGL()
static void error(const char *str)