本文介绍了eglCreateWindowSurface:native_window_api_connect失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题,只有当android:hardwareAccelerated设置为false进入清单文件时,才使用最新的三星Galaxy系列

I have a problem that occours only with the latest Samsung Galaxy series when android:hardwareAccelerated is set to false into manifest file

据我所知(我自己尝试过),它发生在Galaxy S9,J6和Note 8上,例如发生在Galaxy S8上.其他电话似乎根本没有受到影响.

As far as i know (tried by myself) it happens on Galaxy S9, J6 and Note 8 but not on Galaxy S8 for example. Other phones seem not affected at all.

问题是我得到了一个GLSurfaceView,它什么也不显示(黑屏),但是如果我在活动之间进行切换,它将重新开始工作,我猜是因为它可以无错误地更新视图.

The problem is that i got a GLSurfaceView that shows nothing (black screen) but if i switch between activities, it start to work again, i guess because it renews the View with no errors.

这是我发现的可疑日志行

This is the suspect log lines i've found

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)

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

and these are the crucial part of my code:

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总是在具有有意义(至少我认为)日志的事件序列发生之后发生

the EGL_BAD_ALLOC occours always after this sequence of events with meaningful (at least i think) logs

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秒.关于发生了什么的任何想法?

Please note that above events occour with no user interaction and in a span of 1-2 seconds. Any idea about what's going on?

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

For completion of infos, the following is the sequence of a working phone (e.g. my nexus 6)

onCreate
onResume
onSurfaceCreated
... working screen

编辑1月16日:

有关此问题的新信息:

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

编辑1月18日

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

我也发现了错误的原因

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

Don't know why, but i just changed this part of code

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

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

与此

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

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

and everything went ok. A bug in Samsung drivers? Maybe...

我希望这对某人有用

推荐答案

从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.recreate()的注释块/WindowSurface.java"rel =" nofollow noreferrer> WindowSurface.java 方法显示:

Here is a comment block from the WindowSurface.recreate() from WindowSurface.java method that says:

/*
 * 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错误EGL_BAD_ALLOC来自 Jitesh Dalsaniya :

Related problem

Opengls eglCreateWindowSurface GL Error EGL_BAD_ALLOC from Jitesh Dalsaniya:

活动生命周期

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

A GLSurfaceView must be notified when to pause and resume rendering. GLSurfaceView clients are required to call onPause() when the activity stops and onResume() when the activity starts. These calls allow GLSurfaceView to pause and resume the rendering thread, and also allow GLSurfaceView to release and recreate the OpenGL display.

EGL上下文丢失

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

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

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

So your Activity's onPause() should look like this:

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

您将GLSurfaceView还原到层次结构不是从 onResume()而是从onWindowFocusChanged()还原:

And you restore your GLSurfaceView to the hierarchy not from onResume() but from onWindowFocusChanged() :

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

其他可以尝试的东西

  1. 您需要进行调试以弄清为什么不满意.
  2. 尝试使用OpenglView始终可见,并且在获得权限时使用startPreview.隐形持有人对opengl无效,这可能会导致您崩溃.
  3. Opengl的发布不完善吗?
  4. TextureViewGLActivity中处理onSurfaceTextureSizeChanged吗?
  5. EGL_BAD_ALLOCeglSwapBuffers failed: EGL_BAD_SURFACE是一个重要线索...
  6. !readyToDraw()删除并重新创建Surface?
  1. You'd need to debug to figure out why it's unhappy.
  2. Try use OpenglView Visible always and startPreview when you get permissions. An invisible holder is not valid for opengl and this could cause your crash.
  3. Bad release of Opengl ?
  4. Handle onSurfaceTextureSizeChanged in TextureViewGLActivity ?
  5. EGL_BAD_ALLOC and eglSwapBuffers failed: EGL_BAD_SURFACE is a big clue...
  6. !readyToDraw() delete and recreate the Surface ?

更多

观察:

启用了硬件加速 is >=14,但也可以显式启用(在应用程序活动级别).

Hardware acceleration is enabled by default if your Target API level is >=14, but can also be explicitly enabled (at the Application or Activity level).

文档链接

GLSurfaceView GLSurfaceView.Renderer 硬件加速

这篇关于eglCreateWindowSurface:native_window_api_connect失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-27 00:25