(Android) Use EGL context file

This commit is contained in:
twinaphex 2012-10-15 19:33:57 +02:00
parent d30d345d84
commit 8ac8b16d34
3 changed files with 47 additions and 157 deletions

View File

@ -1,9 +1,6 @@
#ifndef _ANDROID_GENERAL_H #ifndef _ANDROID_GENERAL_H
#define _ANDROID_GENERAL_H #define _ANDROID_GENERAL_H
#include <EGL/egl.h>
#include <GLES/gl.h>
#include <android/sensor.h> #include <android/sensor.h>
#include <android_native_app_glue.h> #include <android_native_app_glue.h>
@ -22,12 +19,9 @@ struct droid
const ASensor* accelerometerSensor; const ASensor* accelerometerSensor;
ASensorEventQueue* sensorEventQueue; ASensorEventQueue* sensorEventQueue;
int animating; unsigned animating;
EGLDisplay display; unsigned width;
EGLSurface surface; unsigned height;
EGLContext context;
int32_t width;
int32_t height;
struct saved_state state; struct saved_state state;
}; };

View File

@ -18,9 +18,18 @@
#include <jni.h> #include <jni.h>
#include <errno.h> #include <errno.h>
#include <EGL/egl.h> /* Requires NDK r5 or newer */
#include <GLES/gl.h>
#include "android-general.h" #include "android-general.h"
#include "../../../general.h" #include "../../../general.h"
//forward declarations
void gfx_ctx_swap_buffers(void);
void gfx_ctx_clear(void);
void gfx_ctx_destroy(void);
bool gfx_ctx_init(void);
JNIEXPORT jint JNICALL JNI_OnLoad( JavaVM *vm, void *pvt) JNIEXPORT jint JNICALL JNI_OnLoad( JavaVM *vm, void *pvt)
{ {
RARCH_LOG("JNI_OnLoad.\n" ); RARCH_LOG("JNI_OnLoad.\n" );
@ -33,108 +42,17 @@ JNIEXPORT void JNICALL JNI_OnUnLoad( JavaVM *vm, void *pvt)
RARCH_LOG("JNI_OnUnLoad.\n" ); RARCH_LOG("JNI_OnUnLoad.\n" );
} }
/**
* Initialize an EGL context for the current display.
*/
static int engine_init_display(void)
{
// initialize OpenGL ES and EGL
const EGLint attribs[] =
{
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_NONE
};
EGLint w, h, dummy, format;
EGLint numConfigs;
EGLConfig config;
EGLSurface surface;
EGLContext context;
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display, 0, 0);
/* Here, the application chooses the configuration it desires. In this
* sample, we have a very simplified selection process, where we pick
* the first EGLConfig that matches our criteria */
eglChooseConfig(display, attribs, &config, 1, &numConfigs);
/* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
* guaranteed to be accepted by ANativeWindow_setBuffersGeometry().
* As soon as we picked a EGLConfig, we can safely reconfigure the
* ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
ANativeWindow_setBuffersGeometry(g_android.app->window, 0, 0, format);
surface = eglCreateWindowSurface(display, config, g_android.app->window, NULL);
context = eglCreateContext(display, config, NULL, NULL);
if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
{
RARCH_ERR("Unable to eglMakeCurrent.\n");
return -1;
}
eglQuerySurface(display, surface, EGL_WIDTH, &w);
eglQuerySurface(display, surface, EGL_HEIGHT, &h);
g_android.display = display;
g_android.context = context;
g_android.surface = surface;
g_android.width = w;
g_android.height = h;
g_android.state.angle = 0;
// Initialize GL state.
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
glEnable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
return 0;
}
/** /**
* Just the current frame in the display. * Just the current frame in the display.
*/ */
static void engine_draw_frame(void) static void engine_draw_frame(void)
{ {
if (g_android.display == NULL)
return;
// Just fill the screen with a color. // Just fill the screen with a color.
glClearColor(((float)g_android.state.x)/g_android.width, g_android.state.angle, glClearColor(((float)g_android.state.x)/g_android.width, g_android.state.angle,
((float)g_android.state.y)/g_android.height, 1); ((float)g_android.state.y)/g_android.height, 1);
glClear(GL_COLOR_BUFFER_BIT); gfx_ctx_clear();
gfx_ctx_swap_buffers();
eglSwapBuffers(g_android.display, g_android.surface);
}
/**
* Tear down the EGL context currently associated with the display.
*/
static void engine_term_display(void)
{
if (g_android.display != EGL_NO_DISPLAY)
{
eglMakeCurrent(g_android.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (g_android.context != EGL_NO_CONTEXT)
eglDestroyContext(g_android.display, g_android.context);
if (g_android.surface != EGL_NO_SURFACE)
eglDestroySurface(g_android.display, g_android.surface);
eglTerminate(g_android.display);
}
g_android.animating = 0;
g_android.display = EGL_NO_DISPLAY;
g_android.context = EGL_NO_CONTEXT;
g_android.surface = EGL_NO_SURFACE;
} }
/** /**
@ -169,13 +87,13 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd)
// The window is being shown, get it ready. // The window is being shown, get it ready.
if (g_android.app->window != NULL) if (g_android.app->window != NULL)
{ {
engine_init_display(); gfx_ctx_init();
engine_draw_frame(); engine_draw_frame();
} }
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(); gfx_ctx_destroy();
break; break;
case APP_CMD_GAINED_FOCUS: case APP_CMD_GAINED_FOCUS:
// When our app gains focus, we start monitoring the accelerometer. // When our app gains focus, we start monitoring the accelerometer.
@ -260,7 +178,7 @@ void android_main(struct android_app* state)
// Check if we are exiting. // Check if we are exiting.
if (state->destroyRequested != 0) if (state->destroyRequested != 0)
{ {
engine_term_display(); gfx_ctx_destroy();
return; return;
} }
} }

View File

@ -20,6 +20,8 @@
#include <EGL/egl.h> /* Requires NDK r5 or newer */ #include <EGL/egl.h> /* Requires NDK r5 or newer */
#include <GLES/gl.h> #include <GLES/gl.h>
#include "../../android/native/jni/android-general.h"
#include <stdint.h> #include <stdint.h>
enum RenderThreadMessage { enum RenderThreadMessage {
@ -28,17 +30,11 @@ enum RenderThreadMessage {
MSG_RENDER_LOOP_EXIT MSG_RENDER_LOOP_EXIT
}; };
enum RenderThreadMessage _msg;
ANativeWindow *window; /* Requires NDK r5 or newer */
static EGLContext g_egl_ctx; static EGLContext g_egl_ctx;
static EGLSurface g_egl_surf; static EGLSurface g_egl_surf;
static EGLDisplay g_egl_dpy; static EGLDisplay g_egl_dpy;
static EGLConfig g_config; static EGLConfig g_config;
int _width;
int _height;
GLfloat _angle; GLfloat _angle;
static enum gfx_ctx_api g_api; static enum gfx_ctx_api g_api;
@ -74,7 +70,7 @@ static void gfx_ctx_set_swap_interval(unsigned interval)
eglSwapInterval(g_egl_dpy, interval); eglSwapInterval(g_egl_dpy, interval);
} }
static void gfx_ctx_destroy(void) void gfx_ctx_destroy(void)
{ {
eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(g_egl_dpy, g_egl_ctx); eglDestroyContext(g_egl_dpy, g_egl_ctx);
@ -86,11 +82,12 @@ static void gfx_ctx_destroy(void)
g_egl_ctx = EGL_NO_CONTEXT; g_egl_ctx = EGL_NO_CONTEXT;
g_config = 0; g_config = 0;
_width = 0; g_android.width = 0;
_height = 0; g_android.height = 0;
g_android.animating = 0;
} }
static bool gfx_ctx_init(void) bool gfx_ctx_init(void)
{ {
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
@ -134,9 +131,9 @@ static bool gfx_ctx_init(void)
return false; return false;
} }
ANativeWindow_setBuffersGeometry(window, 0, 0, format); ANativeWindow_setBuffersGeometry(g_android.app->window, 0, 0, format);
if (!(g_egl_surf = eglCreateWindowSurface(g_egl_dpy, config, window, 0))) { if (!(g_egl_surf = eglCreateWindowSurface(g_egl_dpy, config, g_android.app->window, 0))) {
RARCH_ERR("eglCreateWindowSurface() returned error %d.\n", eglGetError()); RARCH_ERR("eglCreateWindowSurface() returned error %d.\n", eglGetError());
gfx_ctx_destroy(); gfx_ctx_destroy();
return false; return false;
@ -161,24 +158,14 @@ static bool gfx_ctx_init(void)
return false; return false;
} }
_width = width; g_android.width = width;
_height = height; g_android.height = height;
g_android.state.angle = 0;
/* // Initialize GL state.
glDisable(GL_DITHER); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); glEnable(GL_CULL_FACE);
glClearColor(0, 0, 0, 0); glDisable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glViewport(0, 0, width, height);
ratio = (GLfloat) width / height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustumf(-ratio, ratio, -1, 1, 1, 10);
*/
return true; return true;
} }
@ -191,33 +178,28 @@ void gfx_ctx_check_window(bool *quit,
(void)width; (void)width;
(void)height; (void)height;
(void)frame_count; (void)frame_count;
// process incoming messages
switch (_msg)
{
case MSG_WINDOW_SET:
gfx_ctx_init();
break;
case MSG_RENDER_LOOP_EXIT:
*quit = false;
gfx_ctx_destroy();
break;
default:
break;
}
_msg = MSG_NONE;
} }
static void gfx_ctx_swap_buffers(void) void gfx_ctx_swap_buffers(void)
{ {
eglSwapBuffers(g_egl_dpy, g_egl_surf); eglSwapBuffers(g_egl_dpy, g_egl_surf);
} }
static void gfx_ctx_clear(void) void gfx_ctx_clear(void)
{} {
glClear(GL_COLOR_BUFFER_BIT);
}
static void gfx_ctx_set_blend(bool enable) static void gfx_ctx_set_blend(bool enable)
{} {
if(enable)
{
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
}
else
glDisable(GL_BLEND);
}
static void gfx_ctx_set_resize(unsigned width, unsigned height) static void gfx_ctx_set_resize(unsigned width, unsigned height)
{ {
@ -283,9 +265,6 @@ static void gfx_ctx_set_aspect_ratio(void *data, unsigned aspectratio_index)
static void gfx_ctx_set_overscan(void) static void gfx_ctx_set_overscan(void)
{} {}
// Enforce void (*)(void) as it's not really legal to cast void* to fn-pointer.
// POSIX allows this, but strict C99 doesn't.
#ifndef __PSL1GHT__
static gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol) static gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol)
{ {
rarch_assert(sizeof(void*) == sizeof(void (*)(void))); rarch_assert(sizeof(void*) == sizeof(void (*)(void)));
@ -296,7 +275,6 @@ static gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol)
return ret; return ret;
} }
#endif
static bool gfx_ctx_bind_api(enum gfx_ctx_api api) static bool gfx_ctx_bind_api(enum gfx_ctx_api api)
{ {