summaryrefslogtreecommitdiffstats
path: root/src/egl/drivers/dri2
diff options
context:
space:
mode:
authorChad Versace <[email protected]>2017-06-16 19:11:21 -0700
committerAndres Gomez <[email protected]>2017-06-28 20:15:04 +0300
commit83c15002fbc9bf3938411c65fec87d16d24e1501 (patch)
treea3e6627219cd61cf3bd4b80037fd54c8e1ec6649 /src/egl/drivers/dri2
parenta49cad48966f48be26ad0e8596922bda3e365711 (diff)
egl/android: Change order of EGLConfig generation (v2)
Many Android apps (such as Google's official NDK GLES2 example app), and even portions the core framework code (such as SystemServiceManager in Nougat), incorrectly choose their EGLConfig. They neglect to match the EGLConfig's EGL_NATIVE_VISUAL_ID against the window's native format, and instead choose the first EGLConfig whose channel sizes match those of the native window format while ignoring the channel *ordering*. We can detect such buggy clients in logcat when they call eglCreateSurface, by detecting the mismatch between the EGLConfig's format and the window's format. As a workaround, this patch changes the order of EGLConfig generation such that all EGLConfigs for HAL pixel format i precede those for HAL pixel format i+1. In my (chadversary) testing on Android Nougat, this was good enough to pacify the buggy clients. v2: Rebase to make patch cherry-pickable to stable. Cc: [email protected] Cc: Tomasz Figa <[email protected]> Cc: Rob Herring <[email protected]> Reviewed-by: Emil Velikov <[email protected]> (cherry picked from commit 5e884353e647261ac815c85724fc108e86dd1d85)
Diffstat (limited to 'src/egl/drivers/dri2')
-rw-r--r--src/egl/drivers/dri2/platform_android.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
index 2713b1f566e..d5c9d38853f 100644
--- a/src/egl/drivers/dri2/platform_android.c
+++ b/src/egl/drivers/dri2/platform_android.c
@@ -1005,20 +1005,38 @@ droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy)
unsigned int format_count[ARRAY_SIZE(visuals)] = { 0 };
int count, i, j;
+ /* The nesting of loops is significant here. Also significant is the order
+ * of the HAL pixel formats. Many Android apps (such as Google's official
+ * NDK GLES2 example app), and even portions the core framework code (such
+ * as SystemServiceManager in Nougat), incorrectly choose their EGLConfig.
+ * They neglect to match the EGLConfig's EGL_NATIVE_VISUAL_ID against the
+ * window's native format, and instead choose the first EGLConfig whose
+ * channel sizes match those of the native window format while ignoring the
+ * channel *ordering*.
+ *
+ * We can detect such buggy clients in logcat when they call
+ * eglCreateSurface, by detecting the mismatch between the EGLConfig's
+ * format and the window's format.
+ *
+ * As a workaround, we generate EGLConfigs such that all EGLConfigs for HAL
+ * pixel format i precede those for HAL pixel format i+1. In my
+ * (chadversary) testing on Android Nougat, this was good enough to pacify
+ * the buggy clients.
+ */
count = 0;
- for (i = 0; dri2_dpy->driver_configs[i]; i++) {
+ for (i = 0; i < ARRAY_SIZE(visuals); i++) {
const EGLint surface_type = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
struct dri2_egl_config *dri2_conf;
- for (j = 0; j < ARRAY_SIZE(visuals); j++) {
- config_attrs[1] = visuals[j].format;
- config_attrs[3] = visuals[j].format;
+ for (j = 0; dri2_dpy->driver_configs[j]; j++) {
+ config_attrs[1] = visuals[i].format;
+ config_attrs[3] = visuals[i].format;
- dri2_conf = dri2_add_config(dpy, dri2_dpy->driver_configs[i],
- count + 1, surface_type, config_attrs, visuals[j].rgba_masks);
+ dri2_conf = dri2_add_config(dpy, dri2_dpy->driver_configs[j],
+ count + 1, surface_type, config_attrs, visuals[i].rgba_masks);
if (dri2_conf) {
count++;
- format_count[j]++;
+ format_count[i]++;
}
}
}