Hi!
I'm trying to run opengl-gl2_basic.cpp, a native C++ Android OpenGL ES 2 test. Source here: https://android.googlesource.com/platform/frameworks/native/+/android-4.4.2_r1/opengl/tests/gl2_basic/
My platform is the Firefly RK3288 running Android 4.4.2 - 2015-04-18 build. It successfully displays the EGLConfigs and choosing one, however when attempting to call:
eglCreateWindowSurface
the app terminates with a Segmenation Fault (SIGSEGV).
pid: 1229, tid: 1229, name: test-opengl-gl2 >>> ./test-opengl-gl2_basic-debug <<< signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00001000 Stack frame #00 pc 00001000 <unknown> Stack frame #01 pc 0000e8ed /system/lib/libEGL.so (eglCreateWindowSurface+408) Stack frame #02 pc 000014d9 /data/local/tmp/test-opengl-gl2_basic-debug Stack frame #03 pc 0000e403 /system/lib/libc.so (__libc_init+50) Stack frame #04 pc 00000dc4 /data/local/tmp/test-opengl-gl2_basic-debug
I have sanity tested this binary on a Nexus 7 (2013), it runs successfully as the 'shell' user, however the screen does not seem to update as the device is not rooted.
Based on this, I ran the application as the 'shell' user in adb on Firefly, which causes it to fail earlier when attempting to choose a config:
EGLUtils::selectConfigForNativeWindow() returned -22
I'm unsure of how to proceed or what the issue might be, its either accessing a restricted memory address or a pointer to the wrong type. Any help would be appreciated.
What parameters are you actually passing in to the EGL call? It's hard to provide any tangible advice without more info on what you are actually trying.
It looks like it is failing relatively early in the call stack; the /system/lib/libEGL.so isn't actually the Mali EGL implementation, that's the meta-EGL provided by Android which will (eventually) call us to do something useful.
Cheers, Pete
Hi Pete, thanks for the quick reply!
The code that attempts to call it:
surface = eglCreateWindowSurface(dpy, myConfig, window, NULL);
dpy:
printf("EGLDisplay: %d\n", dpy); EGLDisplay: 1
myConfig:
printEGLConfiguration(dpy, myConfig); GL_BUFFER_SIZE: 32 (0x20) EGL_ALPHA_SIZE: 8 (0x8) EGL_BLUE_SIZE: 8 (0x8) EGL_GREEN_SIZE: 8 (0x8) EGL_RED_SIZE: 8 (0x8) EGL_DEPTH_SIZE: 24 (0x18) EGL_STENCIL_SIZE: 0 (0x0) EGL_CONFIG_CAVEAT: 12344 (0x3038) EGL_CONFIG_ID: 2 (0x2) EGL_LEVEL: 0 (0x0) EGL_MAX_PBUFFER_HEIGHT: 8192 (0x2000) EGL_MAX_PBUFFER_PIXELS: 67108864 (0x4000000) EGL_MAX_PBUFFER_WIDTH: 8192 (0x2000) EGL_NATIVE_RENDERABLE: 0 (0x0) EGL_NATIVE_VISUAL_ID: 1 (0x1) EGL_NATIVE_VISUAL_TYPE: 4 (0x4) EGL_SAMPLES: 0 (0x0) EGL_SAMPLE_BUFFERS: 0 (0x0) EGL_SURFACE_TYPE: 1029 (0x405) EGL_TRANSPARENT_TYPE: 12344 (0x3038) EGL_TRANSPARENT_RED_VALUE: 0 (0x0) EGL_TRANSPARENT_GREEN_VALUE: 0 (0x0) EGL_TRANSPARENT_BLUE_VALUE: 0 (0x0) EGL_BIND_TO_TEXTURE_RGB: 0 (0x0) EGL_BIND_TO_TEXTURE_RGBA: 1 (0x1) EGL_MIN_SWAP_INTERVAL: 0 (0x0) EGL_MAX_SWAP_INTERVAL: 1 (0x1) EGL_LUMINANCE_SIZE: 0 (0x0) EGL_ALPHA_MASK_SIZE: 8 (0x8) EGL_COLOR_BUFFER_TYPE: 12430 (0x308e) EGL_RENDERABLE_TYPE: 69 (0x45) EGL_CONFORMANT: 69 (0x45)
window () :
printf("NatveWindowType: %d\n", window); NativeWindowType: -1212996048
Seems the culprit is window.. From my understanding EGLNativeWindowType is a void* so the value should be a valid memory address to some struct. However, the code declaring/initializing it, doesn't result in an error
EGLNativeWindowType window = android_createDisplaySurface(); returnValue = EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &myConfig); if (returnValue) { printf("EGLUtils::selectConfigForNativeWindow() returned %d", returnValue); return 0; } checkEglError("EGLUtils::selectConfigForNativeWindow");
This is strange as android_createDisplaySurface() should return NULL, if allocation fails:
native/libs/ui/FramebufferNativeWindow.cpp:
EGLNativeWindowType android_createDisplaySurface(void) { FramebufferNativeWindow* w; w = new FramebufferNativeWindow(); if (w->getDevice() == NULL) { // get a ref so it can be destroyed when we exit this block sp<FramebufferNativeWindow> ref(w); return NULL; } return (EGLNativeWindowType)w; }
Even the call to EGLUtils::selectConfigForNativeWindow doesn't return an error.
native/opengl/tests/include/EGLUtils.h
status_t EGLUtils::selectConfigForNativeWindow( EGLDisplay dpy, EGLint const* attrs, EGLNativeWindowType window, EGLConfig* outConfig) { int err; int format; if (!window) return BAD_VALUE; if ((err = window->query(window, NATIVE_WINDOW_FORMAT, &format)) < 0) { return err; } return selectConfigForPixelFormat(dpy, attrs, format, outConfig); } status_t EGLUtils::selectConfigForPixelFormat( EGLDisplay dpy, EGLint const* attrs, int32_t format, EGLConfig* outConfig) { EGLint numConfigs = -1, n=0; if (!attrs) return BAD_VALUE; if (outConfig == NULL) return BAD_VALUE; // Get all the "potential match" configs... if (eglGetConfigs(dpy, NULL, 0, &numConfigs) == EGL_FALSE) return BAD_VALUE; EGLConfig* const configs = (EGLConfig*)malloc(sizeof(EGLConfig)*numConfigs); if (eglChooseConfig(dpy, attrs, configs, numConfigs, &n) == EGL_FALSE) { free(configs); return BAD_VALUE; } int i; EGLConfig config = NULL; for (i=0 ; i<n ; i++) { EGLint nativeVisualId = 0; eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId); if (nativeVisualId>0 && format == nativeVisualId) { config = configs[i]; break; } } free(configs); if (i<n) { *outConfig = config; return NO_ERROR; } return NAME_NOT_FOUND; }
This might be related: Google Groups, however since this is a pure binary executed from adb, it shouldn't be subject to getting a handle from an "app". The seg fault might be some other service (SurfaceFlinger) already own the handle to the NativeDisplay?