diff --git a/filament/backend/src/opengl/platforms/PlatformEGL.cpp b/filament/backend/src/opengl/platforms/PlatformEGL.cpp index df13526d3c3..59f5a89054f 100644 --- a/filament/backend/src/opengl/platforms/PlatformEGL.cpp +++ b/filament/backend/src/opengl/platforms/PlatformEGL.cpp @@ -115,10 +115,14 @@ Driver* PlatformEGL::createDriver(void* sharedContext, const Platform::DriverCon auto extensions = GLUtils::split(eglQueryString(mEGLDisplay, EGL_EXTENSIONS)); ext.egl.ANDROID_recordable = extensions.has("EGL_ANDROID_recordable"); - ext.egl.KHR_create_context = extensions.has("EGL_KHR_create_context"); ext.egl.KHR_gl_colorspace = extensions.has("EGL_KHR_gl_colorspace"); + ext.egl.KHR_create_context = extensions.has("EGL_KHR_create_context"); ext.egl.KHR_no_config_context = extensions.has("EGL_KHR_no_config_context"); ext.egl.KHR_surfaceless_context = extensions.has("KHR_surfaceless_context"); + if (ext.egl.KHR_create_context) { + // KHR_create_context implies KHR_surfaceless_context for ES3.x contexts + ext.egl.KHR_surfaceless_context = true; + } eglCreateSyncKHR = (PFNEGLCREATESYNCKHRPROC) eglGetProcAddress("eglCreateSyncKHR"); eglDestroySyncKHR = (PFNEGLDESTROYSYNCKHRPROC) eglGetProcAddress("eglDestroySyncKHR"); @@ -182,15 +186,6 @@ Driver* PlatformEGL::createDriver(void* sharedContext, const Platform::DriverCon eglConfig = mEGLConfig; } - if (UTILS_UNLIKELY(!ext.egl.KHR_surfaceless_context)) { - // create the dummy surface, just for being able to make the context current. - mEGLDummySurface = eglCreatePbufferSurface(mEGLDisplay, mEGLConfig, pbufferAttribs); - if (UTILS_UNLIKELY(mEGLDummySurface == EGL_NO_SURFACE)) { - logEglError("eglCreatePbufferSurface"); - goto error; - } - } - for (size_t tries = 0; tries < 3; tries++) { mEGLContext = eglCreateContext(mEGLDisplay, eglConfig, (EGLContext)sharedContext, contextAttribs.data()); @@ -223,6 +218,26 @@ Driver* PlatformEGL::createDriver(void* sharedContext, const Platform::DriverCon goto error; } + if (ext.egl.KHR_surfaceless_context) { + // Adreno 306 driver advertises KHR_create_context but doesn't support passing + // EGL_NO_SURFACE to eglMakeCurrent with a 3.0 context. + if (UTILS_UNLIKELY(!eglMakeCurrent(mEGLDisplay, + EGL_NO_SURFACE, EGL_NO_SURFACE, mEGLContext))) { + if (eglGetError() == EGL_BAD_MATCH) { + ext.egl.KHR_surfaceless_context = false; + } + } + } + + if (UTILS_UNLIKELY(!ext.egl.KHR_surfaceless_context)) { + // create the dummy surface, just for being able to make the context current. + mEGLDummySurface = eglCreatePbufferSurface(mEGLDisplay, mEGLConfig, pbufferAttribs); + if (UTILS_UNLIKELY(mEGLDummySurface == EGL_NO_SURFACE)) { + logEglError("eglCreatePbufferSurface"); + goto error; + } + } + if (UTILS_UNLIKELY(!makeCurrent(mEGLDummySurface, mEGLDummySurface))) { // eglMakeCurrent failed logEglError("eglMakeCurrent");