eglCreateWindowSurface:native_window_api_connect失败

Dav*_*rra 6 android opengl-es egl

当清单文件中 android:hardwareAccelerated 设置为 false 时,我遇到的问题仅出现在最新的 Samsung Galaxy 系列中

据我所知(我自己尝试过),它会发生在 Galaxy S9、J6 和 Note 8 上,但不会发生在 Galaxy S8 上。其他手机似乎根本不受影响。

问题是我的 GLSurfaceView 不显示任何内容(黑屏),但如果我在活动之间切换,它会再次开始工作,我猜是因为它更新了视图而没有错误。

这是我发现的可疑日志行

01-13 14:39:47.813 25013 25080 E libEGL  : eglCreateWindowSurface: native_window_api_connect (win=0xc166b808) failed (0xffffffed) (already connected to another API?)
01-13 14:39:47.813 25013 25080 E libEGL  : eglCreateWindowSurface:679 error 3003 (EGL_BAD_ALLOC)
Run Code Online (Sandbox Code Playgroud)

这些是我的代码的关键部分:

GLSurf glsurf;

public void onPause() {
    super.onPause();

    // stop
    if (glsurf != null) {
        glsurf.onPause();
    }
}

@Override
public void onResume() {
    super.onResume();

    if (glsurf != null)
        glsurf.onResume();
}

public class GLSurf extends GLSurfaceView {

    public GLSurf(Context context) {
        super(context);

        /* Create an OpenGL ES 2.0 context. */
        setEGLContextClientVersion(2);
        setEGLConfigChooser(8, 8, 8, 8, 16, 0);

        // Set the Renderer for drawing on the GLSurfaceView
        mRenderer = new GLRenderer(context);
        setRenderer(mRenderer);

        setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
    }
}

public class GLRenderer implements Renderer {

    GLRenderer(Context c){
        // does nothing
    }

    @Override
    public void onDrawFrame(GL10 unused) {

        // i've copied it but it's not even reached

        // call jni function updating the single texture filling the screen
        nativeGLRender();

        // Draw the triangles
        GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length,
                GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {

        // We need to know the current width and height.
        mScreenWidth = width;
        mScreenHeight = height;

        // Redo the Viewport.
        GLES20.glViewport(0, 0, (int)mScreenWidth, (int)mScreenHeight);

    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {

        // Set the clear color to black
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1);
    }

}
Run Code Online (Sandbox Code Playgroud)

更多一些信息:

EGL_BAD_ALLOC 总是在这一系列事件之后发生,并具有有意义的(至少我认为)日志

onCreate
onResume
onPause

GLSurfaceView: Warning, !readyToDraw() but waiting for draw finished! Early reporting draw finished.

onResume 

libEGL  : eglCreateWindowSurface: native_window_api_connect (win=0xc166b808) failed (0xffffffed) (already connected to another API?)
libEGL  : eglCreateWindowSurface:679 error 3003 (EGL_BAD_ALLOC)

onPause
onStop
onDestroy
onCreate 
onResume
onSurfaceCreated

        : NULL == surf->write_back_color_buffer
        : NULL == surf->write_back_color_buffer
GLThread: eglSwapBuffers failed: EGL_BAD_SURFACE

... black screen ...
Run Code Online (Sandbox Code Playgroud)

请注意,上述事件在没有用户交互的情况下发生,并且持续时间为 1-2 秒。知道发生了什么事吗?

为了完成信息,以下是工作手机的序列(例如我的 Nexus 6)

onCreate
onResume
onSurfaceCreated
... working screen
Run Code Online (Sandbox Code Playgroud)

1月16日编辑:

有关该问题的新信息:

  • 当应用程序第一次启动时,它可以工作
  • 永远不要在接下来的尝试中工作
  • 如果放入后台并恢复它就可以工作
  • 如果我将 android:hardwareAccelerated 设置为 true,则永远不会发生错误(但由于其他原因我无法打开它)

1月18日编辑

  • 我忘了提及,仅当 android:hardwareAccelerated 设置为 false 时才会出现此问题

我也找到了BUG的原因

不知道为什么,但我只是改变了这部分代码

@Override
public void onAttachedToWindow() {
    super.onAttachedToWindow();

    getWindow().setFormat(PixelFormat.RGB_565);
}
Run Code Online (Sandbox Code Playgroud)

有了这个

@Override
public void onAttachedToWindow() {
    super.onAttachedToWindow();
}
Run Code Online (Sandbox Code Playgroud)

一切都很顺利。三星驱动程序有错误吗?或许...

我希望这对某人有用

Jon*_*win 2

eglCreateWindowSurface:native_window_api_connect失败知道发生了什么吗

从logcat角度看问题

eglApi.cpp中调用的函数是:

/*
 * native_window_api_connect(..., int api)
 * connects an API to this window. only one API can be connected at a time.
 * Returns -EINVAL if for some reason the window cannot be connected, which
 * can happen if it's connected to some other API.
 */
static inline int native_window_api_connect(
        struct ANativeWindow* window, int api)
{
    return window->perform(window, NATIVE_WINDOW_API_CONNECT, api);
}
Run Code Online (Sandbox Code Playgroud)

WindowSurface.recreate()这是来自WindowSurface.java方法的注释块,内容如下:

/*
 * If the previous EGLSurface isn't fully destroyed, e.g. it's still current on a
 * context somewhere, the create call will fail with complaints from the Surface
 * about already being connected.
*/
Run Code Online (Sandbox Code Playgroud)

相关问题

Opengls eglCreateWindowSurface GL 错误 EGL_BAD_ALLOC 来自Jitesh Dalsaniya

我解决了错误 GL Error EGL_BAD_ALLOC。发生此错误是由于我没有在活动生命周期中正确处理渲染器。

活动生命周期

GLSurfaceView 必须通知A何时暂停恢复渲染。当活动停止和活动开始时,GLSurfaceView客户端需要调用。这些调用允许暂停和恢复渲染线程,还允许释放和重新创建显示。onPause()onResume()GLSurfaceViewGLSurfaceViewOpenGL

EGL 上下文丢失

在某些情况下,EGL渲染上下文将会丢失。当设备进入睡眠状态后唤醒时,通常会发生这种情况。当EGL上下文丢失时,OpenGL与其关联的所有资源(例如纹理)context将被自动删除。为了保持正确渲染,渲染器必须重新创建它仍然需要的任何丢失的资源。(GL10, EGLConfig)方法onSurfaceCreated是执行此操作的便捷位置。

android 暂停时丢失 opengl 上下文的解决方法

所以你的Activity's onPause()应该看起来像这样:

@Override
public void onPause() {
    glsurf.setVisibility(View.GONE);
    super.onPause();
    ...
}
Run Code Online (Sandbox Code Playgroud)

并且您将您的GLSurfaceView层次结构恢复到不是来自 onResume()而是来自onWindowFocusChanged()

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if (hasFocus && glsurf.getVisibility() == View.GONE) {
         glsurf.setVisibility(View.VISIBLE);
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

其他值得尝试的事情

  1. 您需要进行调试才能找出它不高兴的原因。
  2. 当您获得权限时,尝试OpenglView始终使用Visible。startPreview隐形支架对 opengl 无效,这可能会导致您的崩溃。
  3. Opengl 发布错误?
  4. 处理onSurfaceTextureSizeChangedTextureViewGLActivity
  5. EGL_BAD_ALLOCeglSwapBuffers failed: EGL_BAD_SURFACE是一个很大的线索...
  6. !readyToDraw()删除并重新创建表面?

更远

观察:

android:hardwareAccelerated如果我设置为 true,则不会发生错误

如果您的级别 为 ,则默认启用硬件加速,但也可以显式启用(在应用程序活动级别)。Target APIis >=14

文档链接

GLSurfaceViewGLSurfaceView.Renderer硬件加速