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

View File

@ -18,9 +18,18 @@
#include <jni.h>
#include <errno.h>
#include <EGL/egl.h> /* Requires NDK r5 or newer */
#include <GLES/gl.h>
#include "android-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)
{
RARCH_LOG("JNI_OnLoad.\n" );
@ -33,108 +42,17 @@ JNIEXPORT void JNICALL JNI_OnUnLoad( JavaVM *vm, void *pvt)
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.
*/
static void engine_draw_frame(void)
{
if (g_android.display == NULL)
return;
// Just fill the screen with a color.
glClearColor(((float)g_android.state.x)/g_android.width, g_android.state.angle,
((float)g_android.state.y)/g_android.height, 1);
glClear(GL_COLOR_BUFFER_BIT);
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;
gfx_ctx_clear();
gfx_ctx_swap_buffers();
}
/**
@ -169,13 +87,13 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd)
// The window is being shown, get it ready.
if (g_android.app->window != NULL)
{
engine_init_display();
gfx_ctx_init();
engine_draw_frame();
}
break;
case APP_CMD_TERM_WINDOW:
// The window is being hidden or closed, clean it up.
engine_term_display();
gfx_ctx_destroy();
break;
case APP_CMD_GAINED_FOCUS:
// 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.
if (state->destroyRequested != 0)
{
engine_term_display();
gfx_ctx_destroy();
return;
}
}

View File

@ -20,6 +20,8 @@
#include <EGL/egl.h> /* Requires NDK r5 or newer */
#include <GLES/gl.h>
#include "../../android/native/jni/android-general.h"
#include <stdint.h>
enum RenderThreadMessage {
@ -28,17 +30,11 @@ enum RenderThreadMessage {
MSG_RENDER_LOOP_EXIT
};
enum RenderThreadMessage _msg;
ANativeWindow *window; /* Requires NDK r5 or newer */
static EGLContext g_egl_ctx;
static EGLSurface g_egl_surf;
static EGLDisplay g_egl_dpy;
static EGLConfig g_config;
int _width;
int _height;
GLfloat _angle;
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);
}
static void gfx_ctx_destroy(void)
void gfx_ctx_destroy(void)
{
eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(g_egl_dpy, g_egl_ctx);
@ -86,11 +82,12 @@ static void gfx_ctx_destroy(void)
g_egl_ctx = EGL_NO_CONTEXT;
g_config = 0;
_width = 0;
_height = 0;
g_android.width = 0;
g_android.height = 0;
g_android.animating = 0;
}
static bool gfx_ctx_init(void)
bool gfx_ctx_init(void)
{
const EGLint attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
@ -134,9 +131,9 @@ static bool gfx_ctx_init(void)
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());
gfx_ctx_destroy();
return false;
@ -161,24 +158,14 @@ static bool gfx_ctx_init(void)
return false;
}
_width = width;
_height = height;
g_android.width = width;
g_android.height = height;
g_android.state.angle = 0;
/*
glDisable(GL_DITHER);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
glClearColor(0, 0, 0, 0);
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);
*/
// Initialize GL state.
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
glEnable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
return true;
}
@ -191,33 +178,28 @@ void gfx_ctx_check_window(bool *quit,
(void)width;
(void)height;
(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);
}
static void gfx_ctx_clear(void)
{}
void gfx_ctx_clear(void)
{
glClear(GL_COLOR_BUFFER_BIT);
}
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)
{
@ -283,9 +265,6 @@ static void gfx_ctx_set_aspect_ratio(void *data, unsigned aspectratio_index)
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)
{
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;
}
#endif
static bool gfx_ctx_bind_api(enum gfx_ctx_api api)
{