#include <hardware/gralloc.h>
#include <system/window.h>
+#include <sys/mman.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
using namespace android;
+// This extension has not been ratified yet, so can't be shipped.
+// Implementation is incomplete and untested.
+#define ENABLE_EGL_KHR_GL_COLORSPACE 0
+
// ----------------------------------------------------------------------------
namespace android {
"EGL_KHR_image_base " // mandatory
"EGL_KHR_image_pixmap "
"EGL_KHR_lock_surface "
+#if (ENABLE_EGL_KHR_GL_COLORSPACE != 0)
"EGL_KHR_gl_colorspace "
+#endif
"EGL_KHR_gl_texture_2D_image "
"EGL_KHR_gl_texture_cubemap_image "
"EGL_KHR_gl_renderbuffer_image "
"EGL_NV_system_time "
"EGL_ANDROID_image_native_buffer " // mandatory
"EGL_KHR_wait_sync " // strongly recommended
+ "EGL_ANDROID_recordable " // mandatory
;
// extensions not exposed to applications but used by the ANDROID system
// "EGL_IMG_hibernate_process " // optional
// "EGL_ANDROID_native_fence_sync " // strongly recommended
// "EGL_ANDROID_framebuffer_target " // mandatory for HWC 1.1
-// "EGL_ANDROID_recordable " // mandatory
-
+// "EGL_ANDROID_image_crop " // optional
/*
* EGL Extensions entry-points exposed to 3rd party applications
}
// ----------------------------------------------------------------------------
+// Utility procedure to test a NativeWindowType for validity before referencing
+// through the pointer. It's not feasible to test for deliberate forgeries,
+// but this heuristic is good enough to test for basic accidental cases, using
+// the special "magic" value placed in a native-window structure.
+// ----------------------------------------------------------------------------
+EGLBoolean isValidNativeWindow(NativeWindowType window)
+{
+ ANativeWindow *nwindow = static_cast<ANativeWindow*>(window);
+ // the msync system call returns with ENOMEM error for unmapped memory
+ // pages. This is used here as a way to test whether we can read through a
+ // pointer without getting a segfault.
+ uintptr_t pagesize = (uintptr_t) sysconf(_SC_PAGESIZE);
+ uintptr_t addr = ((uintptr_t)(&nwindow->common.magic)) & (~(pagesize - 1));
+ int rc = msync((void *)addr, pagesize, MS_ASYNC);
+ if (0 == rc) {
+ if (nwindow->common.magic == ANDROID_NATIVE_WINDOW_MAGIC)
+ return EGL_TRUE;
+ else
+ return EGL_FALSE;
+ }
+ if (ENOMEM == errno)
+ return EGL_FALSE;
+ ALOGE("error unexpected msync error: %s (%d)",
+ strerror(-errno), errno);
+ return EGL_FALSE;
+}
+
+
+// ----------------------------------------------------------------------------
// surfaces
// ----------------------------------------------------------------------------
-// The EGL_KHR_gl_colorspace spec hasn't been published yet, so these haven't
+// The EGL_KHR_gl_colorspace spec hasn't been ratified yet, so these haven't
// been added to the Khronos egl.h.
#define EGL_GL_COLORSPACE_KHR EGL_VG_COLORSPACE
#define EGL_GL_COLORSPACE_SRGB_KHR EGL_VG_COLORSPACE_sRGB
if (dp) {
EGLDisplay iDpy = dp->disp.dpy;
+ if (!isValidNativeWindow(window)) {
+ ALOGE("EGLNativeWindow %p invalid", window);
+ return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+ }
if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) != OK) {
ALOGE("EGLNativeWindowType %p already connected to another API",
window);
attr += 2) {
if (*attr == EGL_GL_COLORSPACE_KHR &&
dp->haveExtension("EGL_KHR_gl_colorspace")) {
- format = modifyFormatColorspace(format, *(attr+1));
+ if (ENABLE_EGL_KHR_GL_COLORSPACE) {
+ format = modifyFormatColorspace(format, *(attr+1));
+ } else {
+ // Normally we'd pass through unhandled attributes to
+ // the driver. But in case the driver implements this
+ // extension but we're disabling it, we want to prevent
+ // it getting through -- support will be broken without
+ // our help.
+ ALOGE("sRGB window surfaces not supported");
+ return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ }
}
}
}
if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) {
for (const EGLint* attr = attrib_list; *attr != EGL_NONE; attr += 2) {
if (*attr == EGL_GL_COLORSPACE_KHR) {
- format = modifyFormatColorspace(format, attr[1]);
+ if (ENABLE_EGL_KHR_GL_COLORSPACE) {
+ format = modifyFormatColorspace(format, *(attr+1));
+ } else {
+ // Normally we'd pass through unhandled attributes to
+ // the driver. But in case the driver implements this
+ // extension but we're disabling it, we want to prevent
+ // it getting through -- support will be broken without
+ // our help.
+ ALOGE("sRGB window surfaces not supported");
+ return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ }
}
}
}