情況1:
最近線上Android 線上App有大量用戶報(bào)
Failed to create EGL context: 0x3003
opengl context 創(chuàng)建代碼碗暗,崩潰的地為 Failed to create EGL context: 0x
處:
// Return an EGLConfig, or die trying.
private static EGLContext createEglContext(
@Nullable Context sharedContext, EGLDisplay eglDisplay, EGLConfig eglConfig) {
if (sharedContext != null && sharedContext.egl14Context == EGL14.EGL_NO_CONTEXT) {
throw new RuntimeException("Invalid sharedContext");
}
int[] contextAttributes = {EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE};
EGLContext rootContext =
sharedContext == null ? EGL14.EGL_NO_CONTEXT : sharedContext.egl14Context;
final EGLContext eglContext;
synchronized (lock) {
eglContext = EGL14.eglCreateContext(eglDisplay, eglConfig, rootContext, contextAttributes, 0);
}
if (eglContext == EGL14.EGL_NO_CONTEXT) {
throw new RuntimeException(
"Failed to create EGL context: 0x" + Integer.toHexString(EGL14.eglGetError()));
}
return eglContext;
}
查了下該錯(cuò)誤:
0x3003 is EGL_BAD_ALLOC.
SO 上有人也遇到相同問題, 認(rèn)為是opengl context 創(chuàng)建太多睦授,沒有釋放造成:
https://stackoverflow.com/questions/45392309/failed-to-create-egl-context/57312500#57312500
The problem is related with the number of contexts created. Creating egl context several times leads to this crash on EglBase.create() method when the limit point is reached. Make sure you're not creating so many eglContexts. The limit seems to be 30 on my device.
According to WebRTC's documentation calling .release() should handle that problem, but it unfortunately does not.
改問題解決剃允,并且經(jīng)歷一個(gè)線上版本驗(yàn)證,確實(shí)因?yàn)閛pengl的context申請過多芬迄,使用后未釋放造成
opengl context release的邏輯如下:
public void release() {
checkIsNotReleased();
releaseSurface();
detachCurrent();
EGL14.eglDestroyContext(eglDisplay, eglContext);
EGL14.eglReleaseThread();
EGL14.eglTerminate(eglDisplay);
-- inst_count;
// Logging.d(TAG, instid + " release all:" +inst_count + " curr:" +eglContext);
Logging.e("qqq", instid + " release all:" +inst_count + " curr:" +eglContext);
eglContext = EGL14.EGL_NO_CONTEXT;
eglDisplay = EGL14.EGL_NO_DISPLAY;
eglConfig = null;
}
情況2:
下面代碼大量用戶手機(jī)拋出 Failed to create window surface:0x3003
// Create EGLSurface from either Surface or SurfaceTexture.
private void createSurfaceInternal(Object surface) {
if (!(surface instanceof Surface) && !(surface instanceof SurfaceTexture)) {
throw new IllegalStateException("Input must be either a Surface or SurfaceTexture");
}
checkIsNotReleased();
if (eglSurface != EGL14.EGL_NO_SURFACE) {
throw new RuntimeException("Already has an EGLSurface");
}
int[] surfaceAttribs = {EGL14.EGL_NONE};
eglSurface = EGL14.eglCreateWindowSurface(eglDisplay, eglConfig, surface, surfaceAttribs, 0);
if (eglSurface == EGL14.EGL_NO_SURFACE) {
throw new RuntimeException(
"Failed to create window surface: 0x" + Integer.toHexString(EGL14.eglGetError()));
}
}
對應(yīng)的也調(diào)用了surface的釋放接口:
@Override
public void releaseSurface() {
if (eglSurface != EGL14.EGL_NO_SURFACE) {
EGL14.eglDestroySurface(eglDisplay, eglSurface);
eglSurface = EGL14.EGL_NO_SURFACE;
}
}
依然崩潰報(bào) EGL_BAD_ALLOC
同樣參考 https://stackoverflow.com/questions/36312209/opengls-eglcreatewindowsurface-gl-error-egl-bad-alloc
egl.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)
接口調(diào)用后又厉,調(diào)用EGL14.eglDestroySurface
接口是不能真正釋放相關(guān)OpenGL資源的,必須如下調(diào)用
egl.eglMakeCurrent(eglDisplay, EGL10.EGL_NO_SURFACE,
EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
之后調(diào)用EGL14.eglDestroySurface
才可將相關(guān)資源釋放稻励;
OK父阻,到這問題基本解決完了,第二個(gè)崩潰還沒上線驗(yàn)證望抽,驗(yàn)證完更新結(jié)果