eglCreateWindowSurface:native_window_api_connect失败。

6

我遇到了一个问题,只有在最新的三星Galaxy系列中出现,即当manifest文件中设置android:hardwareAccelerated为false时。

据我所知(我自己尝试过),这种情况发生在Galaxy S9、J6和Note 8上,但例如Galaxy S8就没有。其他手机似乎完全没有受到影响。

问题是我有一个GLSurfaceView,它什么也不显示(黑屏),但如果我在活动之间切换,它就会重新开始工作,我猜这是因为它没有错误地更新了View。

这是我发现的可疑日志行。

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时才会出现问题

我也找到了BUG的原因

不知道为什么,但我刚刚更改了代码的这部分内容

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

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

使用此功能

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

一切都顺利进行。三星驱动程序有bug吗?也许是...

希望这对某人有用

2个回答

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

这里是来自于 WindowSurface.javaWindowSurface.recreate() 的注释块:

/** * Release the EGL surface. */

/*
 * 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 Error EGL_BAD_ALLOC错误。这个错误是由于我没有正确处理渲染器的活动生命周期而导致的。

活动生命周期

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

EGL上下文丢失

有些情况下,EGL渲染上下文会丢失。通常发生在设备从休眠中唤醒后。当EGL上下文丢失时,与该上下文相关联的所有OpenGL资源(如纹理)都将自动删除。为了保持正确的渲染,渲染器必须重新创建任何仍然需要的丢失资源。onSurfaceCreated(GL10,EGLConfig)方法是一个方便的地方来执行此操作。

避免Android暂停时OpenGL上下文丢失的解决方法

因此,您的ActivityonPause()应该像这样:

@Override
public void onPause() {
    glsurf.setVisibility(View.GONE);
    super.onPause();
    ...
}

您需要将GLSurfaceView恢复到层次结构中,但不是从onResume()方法中进行,而是从onWindowFocusChanged()方法中进行:

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

其他尝试

  1. 您需要进行调试以找出原因。
  2. 尝试使用OpenglView Visible始终可见,并在获得权限时使用startPreview。不可见的持有者对于opengl无效,这可能会导致崩溃。
  3. Opengl释放不当?
  4. TextureViewGLActivity中处理onSurfaceTextureSizeChanged
  5. EGL_BAD_ALLOCeglSwapBuffers failed:EGL_BAD_SURFACE是一个很大的线索...
  6. !readyToDraw()删除并重新创建Surface?

更多信息

观察:

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

如果您的Target API级别为>=14,则硬件加速默认情况下已启用,但也可以在应用程序或活动级别上明确启用。

文档链接

GLSurfaceViewGLSurfaceView.Renderer硬件加速


抱歉,我忘了提到当hardwareAccelerated为false时出现的问题。 - Davide Berra
@Davide Berra 是的,我看到了并理解了。我可以查看当hardwareAccelerated为false时会发生什么(以及为什么当hardwareAccelerated为true时不会出现问题),但是你真的希望/需要它为false吗?你现在满意了吗(或者你还有问题)? - Jon Goodwin

0

在我的应用程序中,在onPause()中调用glsurf.setVisibility(View.GONE)是有效的,但是当我在onWindowFocusChanged()中调用glsurf.setVisibility(View.VISIBLE)时它不起作用。

当我在onResume()中调用glsurf.setVisibility(View.VISIBLE)时它对我有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接