Android EGLSWAPBuffer上的应用程序崩溃

Android EGLSWAPBuffer上的应用程序崩溃,android,c++,native-activity,Android,C++,Native Activity,我试图在本机活动中用红色填充屏幕,但它在eglSwapBuffers上崩溃 07-19 10:36:40.497 3197-3232/com.contedevel.davinci A/libc: Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0xf4169e90 in tid 3232 (tedevel.davinci), pid 3197 (tedevel.davinci) 这是我的本机活动代码: #include &

我试图在本机活动中用红色填充屏幕,但它在
eglSwapBuffers
上崩溃

07-19 10:36:40.497 3197-3232/com.contedevel.davinci A/libc: Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0xf4169e90 in tid 3232 (tedevel.davinci), pid 3197 (tedevel.davinci)
这是我的本机活动代码:

#include <initializer_list>
#include <memory>
#include <cstdlib>
#include <cstring>
#include <jni.h>
#include <errno.h>
#include <cassert>
#include <dlfcn.h>

#include <EGL/egl.h>
#include <GLES/gl.h>

#include <android/sensor.h>
#include <android/log.h>
#include <android_native_app_glue.h>

#include "../include/window.h"

#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "camera-activity", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "camera-activity", __VA_ARGS__))

/**
 * Shared state for our app.
 */
struct engine {
    struct android_app *app;
    davinci::window *wnd = nullptr;

    ~engine() {
        if (wnd) { delete wnd; }
    }
};

/**
 * Initialize an EGL context for the current display.
 */
static int engine_init_display(struct engine *engine) {
    const EGLint attrs[] = {
            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
            EGL_BLUE_SIZE, 8,
            EGL_GREEN_SIZE, 8,
            EGL_RED_SIZE, 8,
            EGL_NONE
    };
    EGLint w, h, format;
    EGLint numConfigs;
    EGLConfig config;
    EGLSurface surface;
    EGLContext context;

    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

    eglInitialize(display, 0, 0);

    eglChooseConfig(display, attrs, nullptr, 0, &numConfigs);
    std::unique_ptr<EGLConfig[]> supportedConfigs(new EGLConfig[numConfigs]);
    assert(supportedConfigs);
    eglChooseConfig(display, attrs, supportedConfigs.get(), numConfigs, &numConfigs);
    assert(numConfigs);
    auto i = 0;
    for (; i < numConfigs; i++) {
        auto& cfg = supportedConfigs[i];
        EGLint r, g, b, d;
        if (eglGetConfigAttrib(display, cfg, EGL_RED_SIZE, &r)   &&
            eglGetConfigAttrib(display, cfg, EGL_GREEN_SIZE, &g) &&
            eglGetConfigAttrib(display, cfg, EGL_BLUE_SIZE, &b)  &&
            eglGetConfigAttrib(display, cfg, EGL_DEPTH_SIZE, &d) &&
            r == 8 && g == 8 && b == 8 && d == 0 ) {

            config = supportedConfigs[i];
            break;
        }
    }
    if (i == numConfigs) {
        config = supportedConfigs[0];
    }

    eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
    surface = eglCreateWindowSurface(display, config, engine->app->window, NULL);
    context = eglCreateContext(display, config, NULL, NULL);

    if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {
        LOGW("Unable to eglMakeCurrent");
        return -1;
    }

    eglQuerySurface(display, surface, EGL_WIDTH, &w);
    eglQuerySurface(display, surface, EGL_HEIGHT, &h);

    engine->wnd = new davinci::window(display, context, surface, w, h);

    // Check openGL on the system
    auto opengl_info = {GL_VENDOR, GL_RENDERER, GL_VERSION, GL_EXTENSIONS};
    for (auto name : opengl_info) {
        auto info = glGetString(name);
        LOGI("OpenGL Info: %s", info);
    }
    // Initialize GL state.
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
    glEnable(GL_CULL_FACE);
    glShadeModel(GL_SMOOTH);
    glDisable(GL_DEPTH_TEST);

    return 0;
}

/**
 * Just the current frame in the display.
 */
static void engine_draw_frame(struct engine* engine) {
    if (engine->wnd->display() == NULL) { return; }
    glClearColor(1, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    engine->wnd->swap_buffers();
}

/**
 * Tear down the EGL context currently associated with the display.
 */
static void engine_term_display(struct engine* engine) {
    if (engine->wnd->display() != EGL_NO_DISPLAY) {
        eglMakeCurrent(engine->wnd->display(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        if (engine->wnd->context() != EGL_NO_CONTEXT) {
            eglDestroyContext(engine->wnd->display(), engine->wnd->context());
        }
        if (engine->wnd->surface() != EGL_NO_SURFACE) {
            eglDestroySurface(engine->wnd->display(), engine->wnd->surface());
        }
        eglTerminate(engine->wnd->display());
    }
    engine->wnd->display(EGL_NO_DISPLAY);
    engine->wnd->context(EGL_NO_CONTEXT);
    engine->wnd->surface(EGL_NO_SURFACE);
}

/**
 * Process the next main command.
 */
static void engine_handle_cmd(struct android_app* app, int32_t cmd) {
    struct engine* engine = (struct engine*)app->userData;
    switch (cmd) {
        case APP_CMD_INIT_WINDOW:
            // The window is being shown, get it ready.
            if (engine->app->window != NULL) {
                engine_init_display(engine);
                engine_draw_frame(engine);
            }
            break;
        case APP_CMD_TERM_WINDOW:
            // The window is being hidden or closed, clean it up.
            engine_term_display(engine);
            break;
    }
}

void android_main(struct android_app* state) {
    struct engine engine;

    memset(&engine, 0, sizeof(engine));
    state->userData = &engine;
    state->onAppCmd = engine_handle_cmd;
    engine.app = state;

    // loop waiting for stuff to do.
    while (1) {
        // Read all pending events.
        int ident;
        int events;
        struct android_poll_source* source;

        while ((ident=ALooper_pollAll(0, NULL, &events, (void**)&source)) >= 0) {

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

            // Check if we are exiting.
            if (state->destroyRequested != 0) {
                engine_term_display(&engine);
                return;
            }
        }
    }
}
window.cpp

#include <EGL/egl.h>

namespace davinci {
    class window {
        EGLDisplay m_display;
        EGLSurface m_surface;
        EGLContext m_context;
        int32_t m_width;
        int32_t m_height;
    public:
        window(EGLDisplay display, EGLSurface surface, EGLContext ctx,
               int32_t width, int32_t height);
        ~window();
        // Getters
        EGLDisplay display() const;
        EGLSurface surface() const;
        EGLContext context() const;
        int32_t width() const;
        int32_t height() const;
        // Setters
        void display(EGLDisplay d);
        void surface(EGLSurface s);
        void context(EGLContext ctx);
        // Methods
        void swap_buffers();
    };
};
#include "../include/window.h"

using namespace davinci;

window::window(EGLDisplay display, EGLSurface surface, EGLContext ctx,
               int32_t width, int32_t height) :
    m_display{display}, m_surface{surface}, m_context{ctx}, m_width{width}, m_height{height}
{

}

window::~window() {

}

EGLDisplay window::display() const { return m_display; }
EGLSurface window::surface() const { return m_surface; }
EGLContext window::context() const { return m_context; }
int32_t window::width() const { return m_width; }
int32_t window::height() const { return m_height; }

void window::display(EGLDisplay d) { m_display = d; }
void window::surface(EGLSurface s) { m_surface = s; }
void window::context(EGLContext ctx) { m_context = ctx; }

void window::swap_buffers() { eglSwapBuffers(m_display, m_surface); }

我做错了什么?

“我做错了什么?”您必须进行调试。确定崩溃的位置,确定上下文(变量值、调用堆栈等),比较IS状态和SHOULD状态。调试器工具会很有用。@Jodocus,我有一个调试器,但在调试模式下它会在
上崩溃,而((ident=ALooper\u pollAll(0,NULL,&events,(void**)&source))>=0)
。但这似乎不是由于错误,只是我的调试器无法在某些断点上停止。老实说,它的工作非常奇怪,似乎调试器无法在我的Android Studio中正常工作。另外,我知道如何使用调试器。。。对于本机代码来说,它的工作方式真的很奇怪。我只是把日志一行一行地放进去,以定位哪里有错误。如果我删除
eglSwapBuffers
app工作。