Я пытаюсь заполнить экран красным цветом в моей родной деятельности, но он падает на 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
учебный класс:
window.h:
#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:
#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); }
Что я делаю неправильно?
Задача ещё не решена.
Других решений пока нет …