bool cInterfaceEGL::ChooseAndCreate(void *window_handle, bool core, bool use565) { int attribs32[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Keep this first! EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 16, EGL_STENCIL_SIZE, 8, EGL_TRANSPARENT_TYPE, EGL_NONE, EGL_NONE, 0 }; int attribs16[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Keep this first! EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_ALPHA_SIZE, 0, EGL_DEPTH_SIZE, 16, EGL_STENCIL_SIZE, 8, EGL_TRANSPARENT_TYPE, EGL_NONE, EGL_NONE, 0 }; int attribsFallback32[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Keep this first! EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 16, EGL_NONE, 0 }; int attribsFallback16[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Keep this first! EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_ALPHA_SIZE, 0, EGL_DEPTH_SIZE, 16, EGL_NONE, 0 }; int *attribs = attribs32; int *attribsFallback = attribsFallback32; if (use565) { attribs = attribs16; attribsFallback = attribsFallback16; } EGLint ctx_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, 0 }; switch (s_opengl_mode) { case MODE_OPENGL: EGL_ILOG("Setting RENDERABLE_TYPE to EGL_OPENGL_BIT"); attribs[1] = EGL_OPENGL_BIT; ctx_attribs[0] = EGL_NONE; break; case MODE_OPENGLES2: EGL_ILOG("Setting RENDERABLE_TYPE to EGL_OPENGL_ES2_BIT"); attribs[1] = EGL_OPENGL_ES2_BIT; ctx_attribs[1] = 2; break; case MODE_OPENGLES3: EGL_ILOG("Setting RENDERABLE_TYPE to EGL_OPENGL_ES3_BIT_KHR"); attribs[1] = (1 << 6); /* EGL_OPENGL_ES3_BIT_KHR */ ctx_attribs[1] = 3; break; default: EGL_ELOG("Unknown OpenGL mode set\n"); return false; break; } EGL_ILOG("Calling eglChooseConfig to get number of configs (use16bit=%d)...", (int)use565); EGLConfig *configs; EGLint num_configs; if (!eglChooseConfig(egl_dpy, attribs, NULL, 0, &num_configs) || num_configs == 0) { EGL_ILOG("Error: couldn't get a number of configs. Trying with fallback config (no stencil, not specifying transparent:none)\n"); attribsFallback[1] = attribs[1]; attribs = attribsFallback; if (!eglChooseConfig(egl_dpy, attribs, NULL, 0, &num_configs) || num_configs == 0) { eglTerminate(egl_dpy); return false; } } EGL_ILOG("Got %d configs. Now choosing...", num_configs); configs = new EGLConfig[num_configs]; if (!eglChooseConfig(egl_dpy, attribs, configs, num_configs, &num_configs)) { EGL_ELOG("Error: couldn't get an EGL visual config (num_configs=%d)! Terminating EGL.\n", num_configs); eglTerminate(egl_dpy); return false; } int chosenConfig = -1; // Find our ideal config in the list. If it's there, use it, otherwise pick whatever the device wanted (#0) int wantedAlpha = 8; // Requiring alpha seems to be a problem on older devices. Let's see if this helps... if (attribs[1] == EGL_OPENGL_ES2_BIT) wantedAlpha = 0; for (int i = 0; i < num_configs; i++) { EGL_ILOG("Config %d:", i); LogEGLConfig(egl_dpy, configs[i]); int red, green, blue, alpha, depth, stencil; eglGetConfigAttrib(egl_dpy, configs[i], EGL_RED_SIZE, &red); eglGetConfigAttrib(egl_dpy, configs[i], EGL_GREEN_SIZE, &green); eglGetConfigAttrib(egl_dpy, configs[i], EGL_BLUE_SIZE, &blue); eglGetConfigAttrib(egl_dpy, configs[i], EGL_ALPHA_SIZE, &alpha); eglGetConfigAttrib(egl_dpy, configs[i], EGL_DEPTH_SIZE, &depth); eglGetConfigAttrib(egl_dpy, configs[i], EGL_STENCIL_SIZE, &stencil); if (chosenConfig == -1 && red == 8 && green == 8 && blue == 8 && alpha == wantedAlpha && depth == 24 && stencil == 8) { chosenConfig = i; } } if (chosenConfig == -1) chosenConfig = 0; EGL_ILOG("eglChooseConfig successful: num_configs=%d, choosing config %d", num_configs, chosenConfig); if (s_opengl_mode == MODE_OPENGL) { EGL_ILOG("eglBindAPI(OPENGL)"); eglBindAPI(EGL_OPENGL_API); } else { EGL_ILOG("eglBindAPI(OPENGL_ES)"); eglBindAPI(EGL_OPENGL_ES_API); } EGLNativeWindowType host_window = (EGLNativeWindowType)window_handle; EGLNativeWindowType native_window = InitializePlatform(host_window, configs[chosenConfig]); const char *s = eglQueryString(egl_dpy, EGL_VERSION); EGL_ILOG("EGL_VERSION = %s\n", s); s = eglQueryString(egl_dpy, EGL_VENDOR); EGL_ILOG("EGL_VENDOR = %s\n", s); s = eglQueryString(egl_dpy, EGL_EXTENSIONS); EGL_ILOG("EGL_EXTENSIONS = %s\n", s); s = eglQueryString(egl_dpy, EGL_CLIENT_APIS); EGL_ILOG("EGL_CLIENT_APIS = %s\n", s); egl_ctx = eglCreateContext(egl_dpy, configs[chosenConfig], EGL_NO_CONTEXT, ctx_attribs); if (!egl_ctx) { EGL_ILOG("Error: eglCreateContext failed: %s\n", EGLGetErrorString(eglGetError())); delete[] configs; return false; } EGL_ILOG("Successfully created EGL context.\n"); egl_surf = eglCreateWindowSurface(egl_dpy, configs[chosenConfig], native_window, nullptr); if (!egl_surf) { EGL_ILOG("Error: eglCreateWindowSurface failed: native_window=%p error=%s ctx_attribs[1]==%d\n", native_window, EGLGetErrorString(eglGetError()), ctx_attribs[1]); eglDestroyContext(egl_dpy, egl_ctx); delete[] configs; return false; } EGL_ILOG("Successfully created EGL window surface (window=%p).\n", native_window); delete[] configs; return true; }
// Create rendering window. bool cInterfaceEGL::Create(void *window_handle, bool core, bool use16bit) { const char *s; EGLint egl_major, egl_minor; egl_dpy = OpenDisplay(); if (!egl_dpy) { INFO_LOG(G3D, "Error: eglGetDisplay() failed\n"); return false; } if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) { INFO_LOG(G3D, "Error: eglInitialize() failed\n"); return false; } INFO_LOG(G3D, "eglInitialize() succeeded\n"); if (s_opengl_mode == MODE_DETECT || s_opengl_mode == MODE_DETECT_ES) DetectMode(); int attribs32[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Keep this first! EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 16, EGL_STENCIL_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_TRANSPARENT_TYPE, EGL_NONE, EGL_SAMPLES, 0, EGL_NONE, 0 }; int attribs16[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Keep this first! EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_ALPHA_SIZE, 0, EGL_DEPTH_SIZE, 16, EGL_STENCIL_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_TRANSPARENT_TYPE, EGL_NONE, EGL_SAMPLES, 0, EGL_NONE, 0 }; int *attribs = attribs32; if (use16bit) { attribs = attribs16; } EGLint ctx_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, 0 }; switch (s_opengl_mode) { case MODE_OPENGL: attribs[1] = EGL_OPENGL_BIT; ctx_attribs[0] = EGL_NONE; break; case MODE_OPENGLES2: attribs[1] = EGL_OPENGL_ES2_BIT; ctx_attribs[1] = 2; break; case MODE_OPENGLES3: attribs[1] = (1 << 6); /* EGL_OPENGL_ES3_BIT_KHR */ ctx_attribs[1] = 3; break; default: ERROR_LOG(G3D, "Unknown OpenGL mode set\n"); return false; break; } EGLConfig *configs; EGLint num_configs; if (!eglChooseConfig(egl_dpy, attribs, NULL, 0, &num_configs) || num_configs == 0) { INFO_LOG(G3D, "Error: couldn't get a number of configs\n"); eglTerminate(egl_dpy); return false; } configs = new EGLConfig[num_configs]; if (!eglChooseConfig(egl_dpy, attribs, configs, num_configs, &num_configs)) { INFO_LOG(G3D, "Error: couldn't get an EGL visual config\n"); eglTerminate(egl_dpy); return false; } INFO_LOG(G3D, "eglChooseConfig successful: num_configs=%d, choosing config 0", num_configs); for (int i = 0; i < num_configs; i++) { INFO_LOG(G3D, "Config %d:", i); LogEGLConfig(egl_dpy, configs[i]); } if (s_opengl_mode == MODE_OPENGL) eglBindAPI(EGL_OPENGL_API); else eglBindAPI(EGL_OPENGL_ES_API); EGLNativeWindowType host_window = (EGLNativeWindowType) window_handle; EGLNativeWindowType native_window = InitializePlatform(host_window, configs[0]); s = eglQueryString(egl_dpy, EGL_VERSION); INFO_LOG(G3D, "EGL_VERSION = %s\n", s); s = eglQueryString(egl_dpy, EGL_VENDOR); INFO_LOG(G3D, "EGL_VENDOR = %s\n", s); s = eglQueryString(egl_dpy, EGL_EXTENSIONS); INFO_LOG(G3D, "EGL_EXTENSIONS = %s\n", s); s = eglQueryString(egl_dpy, EGL_CLIENT_APIS); INFO_LOG(G3D, "EGL_CLIENT_APIS = %s\n", s); egl_ctx = eglCreateContext(egl_dpy, configs[0], EGL_NO_CONTEXT, ctx_attribs); if (!egl_ctx) { INFO_LOG(G3D, "Error: eglCreateContext failed: %s\n", EGLGetErrorString(eglGetError())); eglTerminate(egl_dpy); delete[] configs; return false; } egl_surf = eglCreateWindowSurface(egl_dpy, configs[0], native_window, nullptr); if (!egl_surf) { INFO_LOG(G3D, "Error: eglCreateWindowSurface failed: native_window=%p error=%s ctx_attribs[1]==%d\n", native_window, EGLGetErrorString(eglGetError()), ctx_attribs[1]); eglDestroyContext(egl_dpy, egl_ctx); eglTerminate(egl_dpy); delete[] configs; return false; } delete[] configs; return true; }