eglCreateWindowSurface: сбой native_window_api_connect - PullRequest
0 голосов
/ 14 января 2019

У меня проблема, которая возникает только в последней версии Samsung Galaxy , когда для android: hardwareAccelerated установлено значение false в файле манифеста

Насколько я знаю (попробовал сам), это происходит на 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

Редактировать 16 января:

Новые сведения о выпуске:

  • Когда приложение запускается в первый раз, оно работает
  • Никогда не работайте на следующих попытках
  • Работает, если положить в фоновом режиме и восстановить
  • Ошибка никогда не произойдет, если я поставлю android: hardwareAclelerated до true (но я не могу включить его по другим причинам)

Редактировать 18 января

  • Я забыл упомянуть, что проблема возникает, только если для android: hardwareAccelerated установлено значение false

Я ТАКЖЕ НАЙТИ ПРИЧИНУ ЖУКА

Не знаю почему, но я только что изменил эту часть кода

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

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

с этим

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

и все прошло нормально. Ошибка в драйверах Samsung? Может быть ...

Надеюсь, это кому-нибудь пригодится

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

Вызов glsurf.setVisibility(View.GONE) в onPause() работает для моего приложения, но не работает, когда я звоню glsurf.setVisibility(View.VISIBLE) в onWindowFocusChanged().

Это работает для меня, когда я звоню glsurf.setVisibility(View.VISIBLE) в onResume().

0 голосов
/ 17 января 2019

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

Схожая проблема

Opengls eglCreateWindowSurface GL Ошибка EGL_BAD_ALLOC из Джитеш Далсания :

Я решил ошибку GL Ошибка EGL_BAD_ALLOC. Эта ошибка возникает из-за Я неправильно обрабатывает Renderer с жизненным циклом действия.

Активность Жизненный цикл

A GLSurfaceView должны быть уведомлены, когда пауза и резюме рендеринг. GLSurfaceView клиенты обязаны звонить onPause(), когда действие прекращается, и onResume(), когда действие начинается. Эти вызовы позволяют GLSurfaceView приостановить и возобновить поток рендеринга, а также позволяют GLSurfaceView освободить и воссоздайте дисплей OpenGL.

Потерянный контекст EGL

В некоторых ситуациях контекст рендеринга EGL будет потерян. Обычно это происходит, когда устройство просыпается после сна. когда EGL контекст потерян, все OpenGL ресурсы (такие как текстуры) связанные с этим context будут автоматически удалены. Для правильного рендеринга рендерер должен воссоздать любой потерянные ресурсы, которые ему все еще нужны. onSurfaceCreated (GL10, EGLConfig) - удобное место для этого.

Обход к убыточной-The-OpenGL-контекста, когда-андроид-пауза

Итак, ваш Activity's onPause() должен выглядеть так:

@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 Видимо всегда и startPreview при получении разрешений. Невидимый держатель недействителен для opengl, и это может привести к сбою.
  3. Плохой выпуск Opengl?
  4. Ручка onSurfaceTextureSizeChanged в TextureViewGLActivity?
  5. EGL_BAD_ALLOC и eglSwapBuffers failed: EGL_BAD_SURFACE - большая подсказка ...
  6. !readyToDraw() удалить и заново создать поверхность?

Далее

Замечание:

Ошибка никогда не произойдет, если я установлю android:hardwareAccelerated в true

Аппаратное ускорение включено по умолчанию, если ваш уровень Target API is >=14, но также может быть явно включен (на уровне приложения или ).

Ссылки на документы

GLSurfaceView , GLSurfaceView.Renderer , аппаратное ускорение

...