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.
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?