Skip to content

Commit

Permalink
Android: add the possibility to request a specific OpenGL ES version (l…
Browse files Browse the repository at this point in the history
…iballeg#1478)

* Android: add the possibility to request a specific OpenGL ES version with al_set_new_display_option(). Fixes liballeg#1476
  • Loading branch information
alemart authored Oct 8, 2023
1 parent aa8bdde commit e3ad047
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ class AllegroEGL
{
private static final String TAG = "AllegroEGL";

private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
private static final int EGL_CONTEXT_MAJOR_VERSION = 0x3098;
private static final int EGL_CONTEXT_MINOR_VERSION = 0x30fb;
private static final int EGL_OPENGL_ES_BIT = 1;
private static final int EGL_OPENGL_ES2_BIT = 4;

Expand Down Expand Up @@ -184,11 +185,26 @@ void egl_getConfigAttribs(int index, int ret[])
}
}

private int[] versionAttribList(int major, int minor)
{
return new int[] {
EGL_CONTEXT_MAJOR_VERSION, major,
EGL_CONTEXT_MINOR_VERSION, minor,
EGL10.EGL_NONE
};
}

private int versionCode(int major, int minor)
{
return (major << 8) | minor;
}

/* Return values:
* 0 - failure
* 1 - success
*/
int egl_createContext(int configIndex, boolean programmable_pipeline)
int egl_createContext(int configIndex, boolean programmable_pipeline,
int major, int minor, boolean isRequiredMajor, boolean isRequiredMinor)
{
Log.d(TAG, "egl_createContext");

Expand All @@ -198,21 +214,55 @@ int egl_createContext(int configIndex, boolean programmable_pipeline)
matchingConfigs = null;
attribMap = null;

int version = (programmable_pipeline) ? 2 : 1;
int[] attribs = {
EGL_CONTEXT_CLIENT_VERSION, version,
EGL10.EGL_NONE
};
// we'll attempt to create a GLES context of version major.minor.
// if major == minor == 0, then the user did not request a specific version.
// minMajor.minMinor is the minimum acceptable version.

int minMajor = (programmable_pipeline || major >= 2) ? 2 : 1;
int minMinor = 0;

if (isRequiredMajor && major > minMajor)
minMajor = major;
if (isRequiredMinor && minor > minMinor)
minMinor = minor;

int minVersion = versionCode(minMajor, minMinor);
int wantedVersion = versionCode(major, minor);
if (wantedVersion < minVersion) {
if(isRequiredMajor || isRequiredMinor) {
Log.d(TAG, "Can't require OpenGL ES version " + major + "." + minor);
return 0;
}

major = minMajor;
minor = minMinor;
wantedVersion = minVersion;
}

Log.d(TAG, "egl_createContext: requesting OpenGL ES " + major + "." + minor);

// request a GLES context version major.minor
EGLContext ctx = egl.eglCreateContext(egl_Display, chosenConfig,
EGL10.EGL_NO_CONTEXT, attribs);
EGL10.EGL_NO_CONTEXT, versionAttribList(major, minor));
if (ctx == EGL10.EGL_NO_CONTEXT) {
// failed to create a GLES context of the requested version
checkEglError("eglCreateContext", egl);
Log.d(TAG, "egl_createContext no context");
return 0;
Log.d(TAG, "egl_createContext failed. min version is " +
minMajor + "." + minMinor);

// try the min version instead, unless the user required the failed version
if ((wantedVersion == minVersion) || (EGL10.EGL_NO_CONTEXT == (ctx =
egl.eglCreateContext(egl_Display, chosenConfig, EGL10.EGL_NO_CONTEXT,
versionAttribList(minMajor, minMinor))
))) {
// failed again
checkEglError("eglCreateContext", egl);
Log.d(TAG, "egl_createContext no context");
return 0;
}
}

Log.d(TAG, "EGL context (OpenGL ES " + version + ") created");
Log.d(TAG, "egl_createContext: success");

egl_Context = ctx;
return 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@ void egl_getConfigAttribs(int index, int ret[])
egl.egl_getConfigAttribs(index, ret);
}

int egl_createContext(int configIndex, boolean programmable_pipeline)
int egl_createContext(int configIndex, boolean programmable_pipeline,
int major, int minor, boolean isRequiredMajor, boolean isRequiredMinor)
{
return egl.egl_createContext(configIndex, programmable_pipeline);
return egl.egl_createContext(configIndex, programmable_pipeline,
major, minor, isRequiredMajor, isRequiredMinor);
}

boolean egl_createSurface()
Expand Down
18 changes: 17 additions & 1 deletion src/android/android_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,12 @@ static bool _al_android_init_display(JNIEnv *env,
{
ALLEGRO_SYSTEM_ANDROID *system = (void *)al_get_system_driver();
ALLEGRO_DISPLAY *d = (ALLEGRO_DISPLAY *)display;
const ALLEGRO_EXTRA_DISPLAY_SETTINGS *extras = &main_thread_display_settings;
int config_index;
bool programmable_pipeline;
int major_version, minor_version;
bool is_required_major, is_required_minor;
bool is_suggested_major, is_suggested_minor;
int ret;

ASSERT(system != NULL);
Expand All @@ -268,10 +272,22 @@ static bool _al_android_init_display(JNIEnv *env,
}

programmable_pipeline = (d->flags & ALLEGRO_PROGRAMMABLE_PIPELINE);
major_version = extras->settings[ALLEGRO_OPENGL_MAJOR_VERSION];
minor_version = extras->settings[ALLEGRO_OPENGL_MINOR_VERSION];
is_required_major = (extras->required & ((int64_t)1 << ALLEGRO_OPENGL_MAJOR_VERSION));
is_required_minor = (extras->required & ((int64_t)1 << ALLEGRO_OPENGL_MINOR_VERSION));
is_suggested_major = (extras->suggested & ((int64_t)1 << ALLEGRO_OPENGL_MAJOR_VERSION));
is_suggested_minor = (extras->suggested & ((int64_t)1 << ALLEGRO_OPENGL_MINOR_VERSION));

if (!is_required_major && !is_suggested_major) // "don't care"
major_version = 0;
if (!is_required_minor && !is_suggested_minor)
minor_version = 0;

ALLEGRO_DEBUG("calling egl_createContext");
ret = _jni_callIntMethodV(env, display->surface_object,
"egl_createContext", "(IZ)I", config_index, programmable_pipeline);
"egl_createContext", "(IZIIZZ)I", config_index, programmable_pipeline,
major_version, minor_version, is_required_major, is_required_minor);
if (!ret) {
// XXX should probably destroy the AllegroSurface here
ALLEGRO_ERROR("failed to create egl context!");
Expand Down

0 comments on commit e3ad047

Please sign in to comment.