eglCreateWindowSurface:native_window_api_connect失败

时间:2019-01-14 14:09:09

标签: 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)

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

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);
    }

}

更多信息:

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

请注意,上述事件在没有用户交互的情况下发生,并且发生时间为1-2秒。关于发生了什么的任何想法?

为完成信息,以下是可正常使用的电话的序列(例如我的nexus 6)

onCreate
onResume
onSurfaceCreated
... working screen

编辑1月16日:

有关此问题的新信息:

  • 该应用首次启动时可以运行
  • 从不尝试下一次尝试
  • 如果放在后台并恢复,则可以正常工作
  • 如果我将android:hardwareAccelerated设置为true(但由于其他原因我无法将其打开),则错误永远不会发生

编辑1月18日

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

我也发现了错误的原因

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

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

    getWindow().setFormat(PixelFormat.RGB_565);
}

与此

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

,一切顺利。三星驱动程序中的错误?也许...

我希望这对某人有用

2 个答案:

答案 0 :(得分:1)

  

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);
}

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

/*
 * 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.
*/

相关问题

Opengls eglCreateWindowSurface GL Error EGL_BAD_ALLOC 来自Jitesh Dalsaniya

  

我解决了错误GL错误EGL_BAD_ALLOC。由于我是   在活动生命周期中无法正确处理Renderer。

     

活动生命周期

     

GLSurfaceView 必须何时暂停和   恢复渲染。活动停止时,GLSurfaceView个客户端必须呼叫onPause(),活动结束时,{@ 1}   开始。这些呼叫允许onResume()暂停并恢复   渲染线程,还允许GLSurfaceView释放和   重新创建GLSurfaceView显示。

EGL上下文丢失

  

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

Workaround-to-losing-the-opengl-context-when-android-pauses

因此,您的onSurfaceCreated Activity's应该如下所示:

onPause()

然后将@Override public void onPause() { glsurf.setVisibility(View.GONE); super.onPause(); ... } 还原到层次结构不是从 GLSurfaceView而是从onResume()还原:

onWindowFocusChanged()

其他可以尝试的东西

  1. 您需要进行调试以弄清为什么不满意。
  2. 尝试始终使用@Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (hasFocus && glsurf.getVisibility() == View.GONE) { glsurf.setVisibility(View.VISIBLE); } ... } 可见,并在获得权限时使用OpenglView。隐形持有人不适用于opengl,这可能会导致您崩溃。
  3. Opengl的发布不完善吗?
  4. startPreview中处理onSurfaceTextureSizeChanged吗?
  5. TextureViewGLActivityEGL_BAD_ALLOC eglSwapBuffers failed:是一个重要线索...
  6. EGL_BAD_SURFACE删除并重新创建Surface?

更多

观察:

  

如果我将!readyToDraw()设为true,则错误永远不会发生

     如果您的android:hardwareAccelerated级别,默认情况下

启用了硬件加速功能   Target API,但也可以显式启用(在应用程序活动级别)。

文档链接

GLSurfaceViewGLSurfaceView.Rendererhardware-acceleration

答案 1 :(得分:0)

glsurf.setVisibility(View.GONE)中调用onPause()适用于我的应用程序,但是当我在glsurf.setVisibility(View.VISIBLE)中调用onWindowFocusChanged()时则无效。

当我在glsurf.setVisibility(View.VISIBLE)中呼叫onResume()时,它对我有用。