我正在使用以下代码将数据复制到GraphicBuffer:
uint8_t *ptr;
sp<GraphicBuffer> gBuffer = new GraphicBuffer(width,height,format,usage);
gBuffer->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&ptr));
//Copy Data
gBuffer->unlock();
EGLClient clientBuffer = (EGLClientBuffer)gBuffer->getNativeBuffer();
EGLImageKHR img = eglCreateImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,clientBuffer, NULL);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureHandle);
glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)img);
//Finished using img, Crash Here:
eglDestroyImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), img);
问题来自调用eglDestroyImageKHR,它在某些设备中崩溃而其他一些设备没有崩溃。这是回溯:
00 pc 00006488 /system/lib/libui.so
01 pc 00006719 /system/lib/libui.so (android::GraphicBuffer::free_handle()+52)
02 pc 00006813 /system/lib/libui.so (android::GraphicBuffer::~GraphicBuffer()+22)
03 pc 00006841 /system/lib/libui.so (android::GraphicBuffer::~GraphicBuffer()+4)
04 pc 0000f823 /system/lib/libutils.so (android::RefBase::decStrong(void const*) const+40)
05 pc 00003bbb /system/vendor/lib/egl/eglsubAndroid.so
06 pc 0001b5f4 /system/vendor/lib/egl/libEGL_adreno.so (egliDoDestroyEGLImage+80)
07 pc 00006c88 /system/vendor/lib/egl/libEGL_adreno.so (eglDestroyImageKHR+16)
08 pc 0000e749 /system/lib/libEGL.so (eglDestroyImageKHR+44)
以下是一些完整的回溯:
不调用eglDestroyImageKHR会导致泄漏,当再次调用上述例程时,gbuffer-&gt; lock()会因内存不足错误消息而失败。
例如在星系S4,星系s2,xperia z1上坠毁,并且在连接4,连接7,星系王牌2等中不会崩溃
我将不胜感激。
-EDITED -
我找到的唯一解决方法是将引用计数器减少到0,以便调用GraphicBuffer析构函数并释放内存。
if(gBuffer->getStrongCount() > 0){
gBuffer->decStrong(gBuffer->handle);
}
答案 0 :(得分:2)
我对EGL曲面有同样的问题。由于4.3三星ROM在销毁任何一个时不会停用活动上下文和表面。代码现在看起来像这样:
// This line had to be added to prevent crashes:
mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
mEgl.eglDestroyContext(mEglDisplay, mEglContext);
mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
堆栈跟踪看起来非常相似。你有没有尝试在调用eglDestroyImageKHR之前销毁gBuffer?
答案 1 :(得分:2)
FWIW,在Mozilla AndroidGraphicBuffer.cpp
代码中,作者writes:
/**
* XXX: eglDestroyImageKHR crashes sometimes due to refcount badness (I think)
*
* If you look at egl.cpp (https://github.com/android/platform_frameworks_base/blob/master/opengl/libagl/egl.cpp#L2002)
* you can see that eglCreateImageKHR just refs the native buffer, and eglDestroyImageKHR
* just unrefs it. Somehow the ref count gets messed up and things are already destroyed
* by the time eglDestroyImageKHR gets called. For now, at least, just not calling
* eglDestroyImageKHR should be fine since we do free the GraphicBuffer below.
*
* Bug 712716
*/
并且基本上不会调用eglDestroyImageKHR()
,这在该上下文中显然是正常的。错误报告here。
James Willcox author of the Mozilla code也是the snorp blog post的作者。