我用下面的代码将数据复制到GraphicBuffer:调用eglDestroyImageKHR出故障在某些设备和其他一些人不是当Android的崩溃使用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);
而问题就来了。这是回溯:
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- > lock()失败并显示内存不足错误消息。
崩溃例如在星系S4,S2星系,XPERIA Z1和不以的Nexus 4,Nexus 7和星系王牌2崩溃...等
我希望得到任何帮助。
-EDITED-
我发现的唯一的解决方法是减少引用计数器为0,这样GraphicBuffer析构函数被调用,并释放内存。
if(gBuffer->getStrongCount() > 0){
gBuffer->decStrong(gBuffer->handle);
}
嗨我不能销毁gbuffer作为它在android中是私有的析构函数。 graphicBuffer通过eglImageDestroyKHR递减引用计数而被破坏。我会尝试你的解决方案,看看我得到了什么。 –
啊,那很烦人。我不知道我复制的代码是否有帮助,除非你还想销毁上下文(也就是它的Java,对于你必须修改的C等价物)。在黑暗中只是一个狂野的刺:在摧毁图像之前解开纹理有帮助吗?用于复制到GraphicsBuffer的指针是否仍然指向有效内存?你能粘贴整个崩溃日志,特别是寄存器和被捕获的信号吗? –
是的ptr和clientBuffer地址仍然有效。解除绑定根本没有帮助。信号是segv_mapper,这意味着如果我没有误认为某个空指针...我已经包含了几个完整的日志。谢谢 –