首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >应用程序在eglSwapBuffers上崩溃

应用程序在eglSwapBuffers上崩溃
EN

Stack Overflow用户
提问于 2018-07-19 07:44:26
回答 1查看 547关注 0票数 1

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

代码语言:javascript
复制
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)

以下是我的本地活动代码:

代码语言:javascript
复制
#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课程:

window.h

代码语言:javascript
复制
#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();
    };
};

window.cpp

代码语言:javascript
复制
#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); }

我做错了什么?

EN

回答 1

Stack Overflow用户

发布于 2022-03-25 20:22:55

你是在用表面来交换上下文。在您的davinci::window的构造函数中,您将显示、面和上下文作为参数(注意顺序),但是在engine_init_display中实例化它们时,传递它们的顺序不同(显示、上下文和面)。您不会得到编译错误,因为在内部,它们都只是typedef空指针。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51417046

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档