Hi, I'm trying to run a benchmarking tool on the Samsung Galaxy S5 to test some optimizations and perhaps start experimenting with the use of ASTC. It seems like the GL driver is failing to create a context without an associated window to render into. As you may know, opening a window on Android is a fairly involved process, so ideally I'd like to avoid it. I've attached the code that should be initializing the context and the results below:
EGLint error = EGL_SUCCESS; if (EGL_SUCCESS != (error = eglGetError())) { Debugf("Prior EGL error: %s\n", getEGLErrorStr(error)); return NULL; } fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (fDisplay == EGL_NO_DISPLAY || EGL_SUCCESS != (error = eglGetError())) { Debugf("eglGetDisplay failed -- error: %s\n", getEGLErrorStr(error)); return NULL; } EGLint majorVersion; EGLint minorVersion; if (EGL_TRUE != eglInitialize(fDisplay, &majorVersion, &minorVersion)) { if (EGL_SUCCESS != (error = eglGetError())) { Debugf("eglInitialize failed -- error: %s\n", getEGLErrorStr(error)); return NULL; } } Debugf("Major: %d, minor: %d\n", majorVersion, minorVersion); Debugf("VENDOR: %s\n", eglQueryString(fDisplay, EGL_VENDOR)); Debugf("APIS: %s\n", eglQueryString(fDisplay, EGL_CLIENT_APIS)); Debugf("VERSION: %s\n", eglQueryString(fDisplay, EGL_VERSION)); Debugf("EXTENSIONS %s\n", eglQueryString(fDisplay, EGL_EXTENSIONS)); if (!eglBindAPI(EGL_OPENGL_ES_API)) { return NULL; } if (EGL_SUCCESS != (error = eglGetError())) { Debugf("eglBindAPI failed -- error: %s\n", getEGLErrorStr(error)); return NULL; } EGLint numConfigs; const EGLint configAttribs[] = { EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, EGL_DONT_CARE, EGL_DEPTH_SIZE, EGL_DONT_CARE, EGL_STENCIL_SIZE, EGL_DONT_CARE, EGL_NONE }; EGLConfig surfaceConfig; if (!eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs)) { Debugf("eglChooseConfig failed. EGL Error: 0x%08x\n", eglGetError()); return NULL; }
The output:
Major: 1, minor: 4
VENDOR: Android
APIS: OpenGL_ES
VERSION: 1.4 Android META-EGL
EXTENSIONS EGL_KHR_get_all_proc_addresses EGL_ANDROID_presentation_time
eglChooseConfig failed. EGL Error: 0x00003001
I'm hesitant to say that this is a bug in the driver, but I'm not totally sure what I'm doing wrong in my initialization code. Any help would be appreciated . Also, if this isn't an appropriate forum for a question like this, I'd be glad to direct it to the right place.
Hi mokosha,
seems a bit strange. 0x3001 is EGL_NOT_INITIALIZED which according to the man page for eglChooseConfig() can be raised if display has not been initialized, yet you've only just executed other queries on that display.
Do you need the eglBindAPI()? It "affects the behavior of other EGL commands including ... eglGetCurrentDisplay" and "The initial value of the current rendering API is EGL_OPENGL_ES_API " so maybe it's unnecessary. Could you remove it and rule it out as causing problems with the display?
Do you get any output if you use eglGetConfigs() to query how many configs then grab that many configs?
Cheers, Pete
EGL Reference Pages
I'm hesitant to say that this is a bug in the driver, but I'm not totally sure what I'm doing wrong in my initialization code.
Do you know if the same code happens to work on other Android devices?
As the info strings you captured indicate, on Android you don't talk to our EGL implementation directly - Android itself provides a "meta EGL" layer which performs some processing before handing off to the underlying graphics hardware drivers - and in many cases that Android EGL layer is closely tied to the window system integration so there is some possibility that the call isn't even making it as far as the Mali drivers.
Cheers, A different Pete ;P
Hi Pete,
Thanks for your reply.
Do you need the eglBindAPI()? Could you remove it and rule it out as causing problems with the display?
Removing this function call has no effect. I still fail in the same place.
I added the following code:
static const EGLint kMaxConfigs = 1000; EGLConfig configs[kMaxConfigs]; if (EGL_FALSE == eglGetConfigs(fDisplay, configs, kMaxConfigs, &numConfigs)) { if (EGL_SUCCESS != (error = eglGetError())) { Debugf("eglGetConfigs failed -- error: %s\n", getEGLErrorStr(error)); return NULL; } }
This produced the following error:
eglGetConfigs failed -- error: EGL_NOT_INITIALIZED
Thanks for taking the time to look at this!
Hi different Pete,
Thanks for pointing out the bit about META-EGL. I hadn't noticed that. This code works on many many other android devices, so it came as a surprise to me that it didn't work on the S5. I will do a bit of digging to see if the interface between META-EGL and the driver code is causing any problems.
Thanks!
Thanks for confirming - we'll take a look our side too - if it works on other devices it's unlikely to be the fault of the meta layer, as that is common on all platforms.
Small update. The OpenGL ES Extensions supported on the device list
OES_surfaceless_context
This extension allows for the creation of surfaceless contexts (i.e. contexts without a window to render into), however, it seems like the accompanying EGL extension:
EGL_KHR_surfaceless_context
does not show up in the list of EGL extensions. The GLES extension is kind of useless without the accompanying EGL extension, but it does seem like there is some support and motivation for creating a context without an associated window. That being said, following the procedures in those extensions to create a context without a default framebuffer has largely resulted in the same errors as my OP.
Both GL_OES_surfaceless_context and EGL_KHR_surfaceless_context extensions are supported on our Midgard range of GPU's from r3p0 driver onwards.
The Samsung Galaxy S5 (Mali version - SM-G900H) I have here is running Android version 4.4.2, and has Mali driver version r4p0. I also can confirm I have both GL_OES_surfaceless_context and EGL_KHR_surfaceless_context with this device.
Can you first confirm the device name and model number, and what Android (and Mali Driver version) you have available to you?
You can find out this information by looking at the build.prop file on the device. For the driver version, please do the following:
adb pull /vendor/lib/egl/libGLES_mali.so strings libGLES_mali.so | grep "r[0-9]p[0-9]"
Thanks, and Kind Regards...
Michael McGeagh
We're seeing a similar bug resulting from a similar initialization snippet.
The line
SkDebugf("EXTENSIONS %s\n", eglQueryString(fDisplay, EGL_EXTENSIONS));
reports only
Grepping through the strings in libGLES_mali.so gives me:
1.4 Midgard-"r4p0-00dev0-wk51"
Hi tomhudson, mokosha,
After a bit of further investigation, we think we know the reason why this is happening.
The EGL and GLES driver from ARM Mali does indeed expose both extensions, as I stated before...
However, on Android devices, apps talk to Google's own EGL layer (Seen above as "1.4 Android META-EGL").
This layer is outside of ARM's control and owned by Android (google, or perhaps samsung in this case).
EGL_KHR_surfaceless_context isn't being exposed anywhere in Android 4.4.4 code that I can see, and http://gfxbench.com/ also doesn't report that extension being exposed on other non-Mali based devices.
I hope this helps further, and I apologise for not having a solution for you.
Kind Regards,