| @@ -70,25 +70,39 @@ struct SavedState | |||||
| class lol::AndroidAppData | class lol::AndroidAppData | ||||
| { | { | ||||
| public: | public: | ||||
| android_app* m_native_app; | |||||
| int CreateDisplay(); | |||||
| void DestroyDisplay(); | |||||
| void DrawFrame(); | |||||
| EGLDisplay display; | |||||
| EGLSurface surface; | |||||
| EGLContext context; | |||||
| static void StaticHandleCommand(android_app* native_app, int32_t cmd) | |||||
| { | |||||
| return ((AndroidAppData*)native_app->userData)->HandleCommand(cmd); | |||||
| } | |||||
| static int32_t StaticHandleInput(android_app* native_app, AInputEvent* ev) | |||||
| { | |||||
| return ((AndroidAppData*)native_app->userData)->HandleInput(ev); | |||||
| } | |||||
| android_app* m_native_app; | |||||
| SavedState m_state; | SavedState m_state; | ||||
| private: | |||||
| void HandleCommand(int32_t cmd); | |||||
| int32_t HandleInput(AInputEvent* event); | |||||
| EGLDisplay m_display; | |||||
| EGLSurface m_surface; | |||||
| EGLContext m_context; | |||||
| }; | }; | ||||
| /** | /** | ||||
| * Initialize an EGL context for the current display. | * Initialize an EGL context for the current display. | ||||
| */ | */ | ||||
| static int engine_init_display(struct AndroidAppData* engine) | |||||
| int lol::AndroidAppData::CreateDisplay() | |||||
| { | { | ||||
| /* | |||||
| * Here specify the attributes of the desired configuration. | |||||
| * Below, we select an EGLConfig with at least 8 bits per color | |||||
| * component compatible with on-screen windows | |||||
| */ | |||||
| /* FIXME: there is a lot of code common to eglapp.cpp here. */ | |||||
| const EGLint attribs[] = | const EGLint attribs[] = | ||||
| { | { | ||||
| EGL_SURFACE_TYPE, EGL_WINDOW_BIT, | EGL_SURFACE_TYPE, EGL_WINDOW_BIT, | ||||
| @@ -104,39 +118,33 @@ static int engine_init_display(struct AndroidAppData* engine) | |||||
| EGLint w, h, dummy, format; | EGLint w, h, dummy, format; | ||||
| EGLint numConfigs; | EGLint numConfigs; | ||||
| EGLConfig config; | EGLConfig config; | ||||
| EGLSurface surface; | |||||
| EGLContext context; | |||||
| EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | |||||
| m_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | |||||
| eglInitialize(display, 0, 0); | |||||
| eglChooseConfig(display, attribs, &config, 1, &numConfigs); | |||||
| eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format); | |||||
| eglInitialize(m_display, 0, 0); | |||||
| eglChooseConfig(m_display, attribs, &config, 1, &numConfigs); | |||||
| eglGetConfigAttrib(m_display, config, EGL_NATIVE_VISUAL_ID, &format); | |||||
| ANativeWindow_setBuffersGeometry(engine->m_native_app->window, | |||||
| ANativeWindow_setBuffersGeometry(m_native_app->window, | |||||
| 0, 0, format); | 0, 0, format); | ||||
| surface = eglCreateWindowSurface(display, config, | |||||
| engine->m_native_app->window, nullptr); | |||||
| m_surface = eglCreateWindowSurface(m_display, config, | |||||
| m_native_app->window, nullptr); | |||||
| EGLint ctxattr[] = | EGLint ctxattr[] = | ||||
| { | { | ||||
| EGL_CONTEXT_CLIENT_VERSION, 2, | EGL_CONTEXT_CLIENT_VERSION, 2, | ||||
| EGL_NONE | EGL_NONE | ||||
| }; | }; | ||||
| context = eglCreateContext(display, config, EGL_NO_CONTEXT, ctxattr); | |||||
| m_context = eglCreateContext(m_display, config, EGL_NO_CONTEXT, ctxattr); | |||||
| if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) | |||||
| if (eglMakeCurrent(m_display, m_surface, m_surface, m_context) == EGL_FALSE) | |||||
| { | { | ||||
| Log::Error("unable to eglMakeCurrent"); | Log::Error("unable to eglMakeCurrent"); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| eglQuerySurface(display, surface, EGL_WIDTH, &w); | |||||
| eglQuerySurface(display, surface, EGL_HEIGHT, &h); | |||||
| engine->display = display; | |||||
| engine->context = context; | |||||
| engine->surface = surface; | |||||
| eglQuerySurface(m_display, m_surface, EGL_WIDTH, &w); | |||||
| eglQuerySurface(m_display, m_surface, EGL_HEIGHT, &h); | |||||
| /* Launch our ticker */ | /* Launch our ticker */ | ||||
| Log::Info("Java layer initialising renderer at %g fps", 60.0f); | Log::Info("Java layer initialising renderer at %g fps", 60.0f); | ||||
| @@ -146,45 +154,44 @@ static int engine_init_display(struct AndroidAppData* engine) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| static void engine_draw_frame(AndroidAppData* engine) | |||||
| void lol::AndroidAppData::DrawFrame() | |||||
| { | { | ||||
| if (!engine->display) | |||||
| if (!m_display) | |||||
| return; | return; | ||||
| Ticker::TickDraw(); | Ticker::TickDraw(); | ||||
| eglSwapBuffers(engine->display, engine->surface); | |||||
| eglSwapBuffers(m_display, m_surface); | |||||
| } | } | ||||
| /** | /** | ||||
| * Tear down the EGL context currently associated with the display. | * Tear down the EGL context currently associated with the display. | ||||
| */ | */ | ||||
| static void engine_term_display(AndroidAppData* engine) | |||||
| void lol::AndroidAppData::DestroyDisplay() | |||||
| { | { | ||||
| if (engine->display != EGL_NO_DISPLAY) | |||||
| if (m_display != EGL_NO_DISPLAY) | |||||
| { | { | ||||
| eglMakeCurrent(engine->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); | |||||
| if (engine->context != EGL_NO_CONTEXT) | |||||
| eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); | |||||
| if (m_context != EGL_NO_CONTEXT) | |||||
| { | { | ||||
| eglDestroyContext(engine->display, engine->context); | |||||
| eglDestroyContext(m_display, m_context); | |||||
| } | } | ||||
| if (engine->surface != EGL_NO_SURFACE) | |||||
| if (m_surface != EGL_NO_SURFACE) | |||||
| { | { | ||||
| eglDestroySurface(engine->display, engine->surface); | |||||
| eglDestroySurface(m_display, m_surface); | |||||
| } | } | ||||
| eglTerminate(engine->display); | |||||
| eglTerminate(m_display); | |||||
| } | } | ||||
| engine->display = EGL_NO_DISPLAY; | |||||
| engine->context = EGL_NO_CONTEXT; | |||||
| engine->surface = EGL_NO_SURFACE; | |||||
| m_display = EGL_NO_DISPLAY; | |||||
| m_context = EGL_NO_CONTEXT; | |||||
| m_surface = EGL_NO_SURFACE; | |||||
| } | } | ||||
| /** | /** | ||||
| * Process the next input event. | * Process the next input event. | ||||
| */ | */ | ||||
| static int32_t engine_handle_input(android_app* native_app, AInputEvent* event) | |||||
| int32_t lol::AndroidAppData::HandleInput(AInputEvent* event) | |||||
| { | { | ||||
| AndroidAppData* engine = (AndroidAppData*)native_app->userData; | |||||
| switch (AInputEvent_getType(event)) | switch (AInputEvent_getType(event)) | ||||
| { | { | ||||
| case AINPUT_EVENT_TYPE_MOTION: | case AINPUT_EVENT_TYPE_MOTION: | ||||
| @@ -207,34 +214,33 @@ static int32_t engine_handle_input(android_app* native_app, AInputEvent* event) | |||||
| /** | /** | ||||
| * Process the next main command. | * Process the next main command. | ||||
| */ | */ | ||||
| static void engine_handle_cmd(android_app* native_app, int32_t cmd) | |||||
| void lol::AndroidAppData::HandleCommand(int32_t cmd) | |||||
| { | { | ||||
| AndroidAppData* engine = (AndroidAppData*)native_app->userData; | |||||
| switch (cmd) | switch (cmd) | ||||
| { | { | ||||
| case APP_CMD_SAVE_STATE: | case APP_CMD_SAVE_STATE: | ||||
| /* The system has asked us to save our current state. Do so. */ | /* The system has asked us to save our current state. Do so. */ | ||||
| engine->m_native_app->savedState = malloc(sizeof(SavedState)); | |||||
| *((SavedState*)engine->m_native_app->savedState) = engine->m_state; | |||||
| engine->m_native_app->savedStateSize = sizeof(SavedState); | |||||
| m_native_app->savedState = malloc(sizeof(SavedState)); | |||||
| *((SavedState*)m_native_app->savedState) = m_state; | |||||
| m_native_app->savedStateSize = sizeof(SavedState); | |||||
| break; | break; | ||||
| case APP_CMD_INIT_WINDOW: | case APP_CMD_INIT_WINDOW: | ||||
| /* The window is being shown, get it ready. */ | /* The window is being shown, get it ready. */ | ||||
| if (engine->m_native_app->window != nullptr) | |||||
| if (m_native_app->window != nullptr) | |||||
| { | { | ||||
| engine_init_display(engine); | |||||
| engine_draw_frame(engine); | |||||
| CreateDisplay(); | |||||
| DrawFrame(); | |||||
| } | } | ||||
| break; | break; | ||||
| case APP_CMD_TERM_WINDOW: | case APP_CMD_TERM_WINDOW: | ||||
| /* The window is being hidden or closed, clean it up. */ | /* The window is being hidden or closed, clean it up. */ | ||||
| engine_term_display(engine); | |||||
| DestroyDisplay(); | |||||
| break; | break; | ||||
| case APP_CMD_GAINED_FOCUS: | case APP_CMD_GAINED_FOCUS: | ||||
| break; | break; | ||||
| case APP_CMD_LOST_FOCUS: | case APP_CMD_LOST_FOCUS: | ||||
| /* FIXME: stop animating */ | /* FIXME: stop animating */ | ||||
| engine_draw_frame(engine); | |||||
| DrawFrame(); | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| @@ -245,14 +251,14 @@ AndroidAppData *g_data; | |||||
| void android_main(android_app* native_app) | void android_main(android_app* native_app) | ||||
| { | { | ||||
| g_data = new AndroidAppData(); | g_data = new AndroidAppData(); | ||||
| g_data->m_native_app = native_app; | |||||
| /* Make sure glue isn't stripped */ | /* Make sure glue isn't stripped */ | ||||
| app_dummy(); | app_dummy(); | ||||
| native_app->userData = g_data; | native_app->userData = g_data; | ||||
| native_app->onAppCmd = engine_handle_cmd; | |||||
| native_app->onInputEvent = engine_handle_input; | |||||
| g_data->m_native_app = native_app; | |||||
| native_app->onAppCmd = lol::AndroidAppData::StaticHandleCommand; | |||||
| native_app->onInputEvent = lol::AndroidAppData::StaticHandleInput; | |||||
| if (native_app->savedState != nullptr) | if (native_app->savedState != nullptr) | ||||
| { | { | ||||
| @@ -282,7 +288,7 @@ void lol::AndroidApp::ShowPointer(bool show) | |||||
| lol::AndroidApp::~AndroidApp() | lol::AndroidApp::~AndroidApp() | ||||
| { | { | ||||
| engine_term_display(m_data); | |||||
| m_data->DestroyDisplay(); | |||||
| delete m_data; | delete m_data; | ||||
| } | } | ||||
| @@ -307,7 +313,7 @@ void lol::AndroidApp::Tick() | |||||
| Ticker::Shutdown(); | Ticker::Shutdown(); | ||||
| } | } | ||||
| engine_draw_frame(m_data); | |||||
| m_data->DrawFrame(); | |||||
| } | } | ||||
| /* | /* | ||||