Skip to content

Commit e3ad047

Browse files
authored
Android: add the possibility to request a specific OpenGL ES version (#1478)
* Android: add the possibility to request a specific OpenGL ES version with al_set_new_display_option(). Fixes #1476
1 parent aa8bdde commit e3ad047

File tree

3 files changed

+82
-14
lines changed

3 files changed

+82
-14
lines changed

android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroEGL.java

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ class AllegroEGL
1010
{
1111
private static final String TAG = "AllegroEGL";
1212

13-
private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
13+
private static final int EGL_CONTEXT_MAJOR_VERSION = 0x3098;
14+
private static final int EGL_CONTEXT_MINOR_VERSION = 0x30fb;
1415
private static final int EGL_OPENGL_ES_BIT = 1;
1516
private static final int EGL_OPENGL_ES2_BIT = 4;
1617

@@ -184,11 +185,26 @@ void egl_getConfigAttribs(int index, int ret[])
184185
}
185186
}
186187

188+
private int[] versionAttribList(int major, int minor)
189+
{
190+
return new int[] {
191+
EGL_CONTEXT_MAJOR_VERSION, major,
192+
EGL_CONTEXT_MINOR_VERSION, minor,
193+
EGL10.EGL_NONE
194+
};
195+
}
196+
197+
private int versionCode(int major, int minor)
198+
{
199+
return (major << 8) | minor;
200+
}
201+
187202
/* Return values:
188203
* 0 - failure
189204
* 1 - success
190205
*/
191-
int egl_createContext(int configIndex, boolean programmable_pipeline)
206+
int egl_createContext(int configIndex, boolean programmable_pipeline,
207+
int major, int minor, boolean isRequiredMajor, boolean isRequiredMinor)
192208
{
193209
Log.d(TAG, "egl_createContext");
194210

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

201-
int version = (programmable_pipeline) ? 2 : 1;
202-
int[] attribs = {
203-
EGL_CONTEXT_CLIENT_VERSION, version,
204-
EGL10.EGL_NONE
205-
};
217+
// we'll attempt to create a GLES context of version major.minor.
218+
// if major == minor == 0, then the user did not request a specific version.
219+
// minMajor.minMinor is the minimum acceptable version.
220+
221+
int minMajor = (programmable_pipeline || major >= 2) ? 2 : 1;
222+
int minMinor = 0;
223+
224+
if (isRequiredMajor && major > minMajor)
225+
minMajor = major;
226+
if (isRequiredMinor && minor > minMinor)
227+
minMinor = minor;
228+
229+
int minVersion = versionCode(minMajor, minMinor);
230+
int wantedVersion = versionCode(major, minor);
231+
if (wantedVersion < minVersion) {
232+
if(isRequiredMajor || isRequiredMinor) {
233+
Log.d(TAG, "Can't require OpenGL ES version " + major + "." + minor);
234+
return 0;
235+
}
206236

237+
major = minMajor;
238+
minor = minMinor;
239+
wantedVersion = minVersion;
240+
}
241+
242+
Log.d(TAG, "egl_createContext: requesting OpenGL ES " + major + "." + minor);
243+
244+
// request a GLES context version major.minor
207245
EGLContext ctx = egl.eglCreateContext(egl_Display, chosenConfig,
208-
EGL10.EGL_NO_CONTEXT, attribs);
246+
EGL10.EGL_NO_CONTEXT, versionAttribList(major, minor));
209247
if (ctx == EGL10.EGL_NO_CONTEXT) {
248+
// failed to create a GLES context of the requested version
210249
checkEglError("eglCreateContext", egl);
211-
Log.d(TAG, "egl_createContext no context");
212-
return 0;
250+
Log.d(TAG, "egl_createContext failed. min version is " +
251+
minMajor + "." + minMinor);
252+
253+
// try the min version instead, unless the user required the failed version
254+
if ((wantedVersion == minVersion) || (EGL10.EGL_NO_CONTEXT == (ctx =
255+
egl.eglCreateContext(egl_Display, chosenConfig, EGL10.EGL_NO_CONTEXT,
256+
versionAttribList(minMajor, minMinor))
257+
))) {
258+
// failed again
259+
checkEglError("eglCreateContext", egl);
260+
Log.d(TAG, "egl_createContext no context");
261+
return 0;
262+
}
213263
}
214264

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

217267
egl_Context = ctx;
218268
return 1;

android/gradle_project/allegro/src/main/java/org/liballeg/android/AllegroSurface.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@ void egl_getConfigAttribs(int index, int ret[])
4747
egl.egl_getConfigAttribs(index, ret);
4848
}
4949

50-
int egl_createContext(int configIndex, boolean programmable_pipeline)
50+
int egl_createContext(int configIndex, boolean programmable_pipeline,
51+
int major, int minor, boolean isRequiredMajor, boolean isRequiredMinor)
5152
{
52-
return egl.egl_createContext(configIndex, programmable_pipeline);
53+
return egl.egl_createContext(configIndex, programmable_pipeline,
54+
major, minor, isRequiredMajor, isRequiredMinor);
5355
}
5456

5557
boolean egl_createSurface()

src/android/android_display.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,12 @@ static bool _al_android_init_display(JNIEnv *env,
241241
{
242242
ALLEGRO_SYSTEM_ANDROID *system = (void *)al_get_system_driver();
243243
ALLEGRO_DISPLAY *d = (ALLEGRO_DISPLAY *)display;
244+
const ALLEGRO_EXTRA_DISPLAY_SETTINGS *extras = &main_thread_display_settings;
244245
int config_index;
245246
bool programmable_pipeline;
247+
int major_version, minor_version;
248+
bool is_required_major, is_required_minor;
249+
bool is_suggested_major, is_suggested_minor;
246250
int ret;
247251

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

270274
programmable_pipeline = (d->flags & ALLEGRO_PROGRAMMABLE_PIPELINE);
275+
major_version = extras->settings[ALLEGRO_OPENGL_MAJOR_VERSION];
276+
minor_version = extras->settings[ALLEGRO_OPENGL_MINOR_VERSION];
277+
is_required_major = (extras->required & ((int64_t)1 << ALLEGRO_OPENGL_MAJOR_VERSION));
278+
is_required_minor = (extras->required & ((int64_t)1 << ALLEGRO_OPENGL_MINOR_VERSION));
279+
is_suggested_major = (extras->suggested & ((int64_t)1 << ALLEGRO_OPENGL_MAJOR_VERSION));
280+
is_suggested_minor = (extras->suggested & ((int64_t)1 << ALLEGRO_OPENGL_MINOR_VERSION));
281+
282+
if (!is_required_major && !is_suggested_major) // "don't care"
283+
major_version = 0;
284+
if (!is_required_minor && !is_suggested_minor)
285+
minor_version = 0;
271286

272287
ALLEGRO_DEBUG("calling egl_createContext");
273288
ret = _jni_callIntMethodV(env, display->surface_object,
274-
"egl_createContext", "(IZ)I", config_index, programmable_pipeline);
289+
"egl_createContext", "(IZIIZZ)I", config_index, programmable_pipeline,
290+
major_version, minor_version, is_required_major, is_required_minor);
275291
if (!ret) {
276292
// XXX should probably destroy the AllegroSurface here
277293
ALLEGRO_ERROR("failed to create egl context!");

0 commit comments

Comments
 (0)