Ошибка сегментации с использованием собственного окна в Android - PullRequest
0 голосов
/ 13 марта 2012

Мы пытаемся перенести приложение C ++ на Android.Мы считаем, что использование NativeActivity должно быть самым простым, и пусть все OpenGL / EGL-вещи выполняются нативно.

Прямо сейчас мы передаем ANativeWindow-указатель, который мы получаем из структуры android_app в android_native_app_glue.h черезприложение, чтобы его можно было использовать при инициализации окна.Вот несколько соответствующих строк из этого кода (вырезанных из кода отладки):

bool OpenGLWindowES::Initialize(EGLNativeWindowType wnd, EGLNativeDisplayType dsp,
                            EGLint redSize, EGLint greenSize, EGLint blueSize, EGLint             alphaSize, EGLint depthSize, bool bMultiSample)
{
    m_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if(m_display == EGL_NO_DISPLAY)
    {
        return false;
    }

    EGLint iMajorVersion, iMinorVersion;
    if (!eglInitialize(m_display, &iMajorVersion, &iMinorVersion))
    {
        return false;
    }

    eglBindAPI(EGL_OPENGL_ES_API);
    bool ecc = eglChooseConfig(m_display, attribs, &m_config, 1, &iConfigs);
    if (!ecc || (iConfigs != 1))
    {
        return false;
    }

    EGLint format;
    eglGetConfigAttrib(m_display, m_config, EGL_NATIVE_VISUAL_ID, &format);
    ANativeWindow_setBuffersGeometry(wnd, 0, 0, format);
    m_windowSurface = eglCreateWindowSurface(m_display, m_config, wnd, NULL);
    //etc
}    

Этот код приступает к созданию контекста, makecurrent и т. Д., Но мы не заходим так далеко.Мы получаем ошибку сегментации на eglCreateWindowSurface, и поскольку отображение и конфигурация кажутся правильно инициализированными, это может означать только проблему с ANativeWindow * (tyepdef'd для EGLNativeWindowType).Сообщение об ошибке:

signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000058

Мы также получаем ошибку сегментации, если мы вызываем, например:

ANativeWindow_getHeight(wnd);

Итак, вопрос в том, что может вызвать ошибку сегментации в этой точке?wnd не равен null, мы проверяли это раньше, поэтому он должен быть как-то инициализирован и готов к использованию.Мы что-то пропустили до вызова этой функции, или может быть какая-то проблема с указателем?

РЕДАКТИРОВАТЬ: В настоящее время мы задаемся вопросом, может ли это быть связано с тем, что команда APP_CMD_INIT_WINDOW не была отправлена ​​или получена должным образом (мы еще не реализовали никакой обработки команд, поэтому мы изучаем это).

Ответы [ 2 ]

1 голос
/ 12 сентября 2018

Проблема в wnd, передайте state->window из основной функции: void android_main(struct android_app* state) в ваш bool OpenGLWindowES::Initialize(...) метод в качестве первого параметра:

void android_main(struct android_app* state) {
    Initialize(state->window /*, other arguments here... */);
}
1 голос
/ 15 марта 2012

Вы полностью уверены, что окно правильно инициализировано?

Указатель ANativeWindow в структуре приложения не устанавливается автоматически при передаче в собственную точку входа.Позже он будет предоставлен основным потоком Android, а затем будет отправлен в приложение через систему обратного вызова, которую настроил app_glue.

Вы должны обрабатывать вызовы, отправленные в android_app самостоятельно, вПример native_activity в NDK делает это следующим образом:

int ident;
int events;
struct android_poll_source* source;

// If not animating, we will block forever waiting for events.
// If animating, we loop until all events are read, then continue
// to draw the next frame of animation.
while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, NULL, &events,
        (void**)&source)) >= 0) {

    // Process this event.
    if (source != NULL) {
        source->process(state, source);
    }
    ....
}

Возможно, вам нужно что-то подобное в вашем основном цикле рендеринга, это позволит app_glue автоматически устанавливать окно правильно, когда оно получает его из основного потока.

...