summaryrefslogtreecommitdiffstats
path: root/opengl/libs
diff options
context:
space:
mode:
authorJesse Hall <jessehall@google.com>2013-08-08 13:40:22 -0700
committerJesse Hall <jessehall@google.com>2013-08-13 12:10:51 -0700
commitc2e41222bf02a6579763974f82d65875cfa43481 (patch)
tree357d0cb44ab16d7037cae33426191945727a8ef8 /opengl/libs
parent6f23562e0c112bc5c6159c745d8af755cc530d77 (diff)
downloadframeworks_native-c2e41222bf02a6579763974f82d65875cfa43481.zip
frameworks_native-c2e41222bf02a6579763974f82d65875cfa43481.tar.gz
frameworks_native-c2e41222bf02a6579763974f82d65875cfa43481.tar.bz2
Add support for EGL_KHR_gl_colorspace
Change-Id: I684d0b8556cd6c84ee4b4d67e1bb95c3b96fccfb
Diffstat (limited to 'opengl/libs')
-rw-r--r--opengl/libs/EGL/eglApi.cpp66
-rw-r--r--opengl/libs/EGL/egl_display.cpp28
-rw-r--r--opengl/libs/EGL/egl_display.h2
3 files changed, 77 insertions, 19 deletions
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index e5e2dc0..c01725d 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -82,6 +82,7 @@ extern char const * const gExtensionString =
"EGL_KHR_image_base " // mandatory
"EGL_KHR_image_pixmap "
"EGL_KHR_lock_surface "
+ "EGL_KHR_gl_colorspace "
"EGL_KHR_gl_texture_2D_image "
"EGL_KHR_gl_texture_cubemap_image "
"EGL_KHR_gl_renderbuffer_image "
@@ -365,6 +366,33 @@ EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
// surfaces
// ----------------------------------------------------------------------------
+// The EGL_KHR_gl_colorspace spec hasn't been published 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
+#define EGL_GL_COLORSPACE_LINEAR_KHR EGL_VG_COLORSPACE_LINEAR
+
+// Turn linear formats into corresponding sRGB formats when colorspace is
+// EGL_GL_COLORSPACE_SRGB_KHR, or turn sRGB formats into corresponding linear
+// formats when colorspace is EGL_GL_COLORSPACE_LINEAR_KHR. In any cases where
+// the modification isn't possible, the original format is returned.
+static int modifyFormatColorspace(int fmt, EGLint colorspace) {
+ if (colorspace == EGL_GL_COLORSPACE_LINEAR_KHR) {
+ switch (fmt) {
+ case HAL_PIXEL_FORMAT_sRGB_A_8888: return HAL_PIXEL_FORMAT_RGBA_8888;
+ case HAL_PIXEL_FORMAT_sRGB_888: return HAL_PIXEL_FORMAT_RGB_888;
+ }
+ } else if (colorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
+ switch (fmt) {
+ case HAL_PIXEL_FORMAT_RGBA_8888: return HAL_PIXEL_FORMAT_sRGB_A_8888;
+ case HAL_PIXEL_FORMAT_RGBX_8888: return HAL_PIXEL_FORMAT_sRGB_A_8888;
+ case HAL_PIXEL_FORMAT_BGRA_8888: return HAL_PIXEL_FORMAT_sRGB_A_8888;
+ case HAL_PIXEL_FORMAT_RGB_888: return HAL_PIXEL_FORMAT_sRGB_888;
+ }
+ }
+ return fmt;
+}
+
EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
NativeWindowType window,
const EGLint *attrib_list)
@@ -375,7 +403,6 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
egl_display_ptr dp = validate_display_connection(dpy, cnx);
if (dp) {
EGLDisplay iDpy = dp->disp.dpy;
- EGLint format;
if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) != OK) {
ALOGE("EGLNativeWindowType %p already connected to another API",
@@ -383,19 +410,36 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
- // set the native window's buffers format to match this config
- if (cnx->egl.eglGetConfigAttrib(iDpy,
- config, EGL_NATIVE_VISUAL_ID, &format)) {
- if (format != 0) {
- int err = native_window_set_buffers_format(window, format);
- if (err != 0) {
- ALOGE("error setting native window pixel format: %s (%d)",
- strerror(-err), err);
- native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
- return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+ // Set the native window's buffers format to match this config.
+ // Whether to use sRGB gamma is not part of the EGLconfig, but is part
+ // of our native format. So if sRGB gamma is requested, we have to
+ // modify the EGLconfig's format before setting the native window's
+ // format.
+ EGLint format;
+ if (!cnx->egl.eglGetConfigAttrib(iDpy, config, EGL_NATIVE_VISUAL_ID,
+ &format)) {
+ ALOGE("eglGetConfigAttrib(EGL_NATIVE_VISUAL_ID) failed: %#x",
+ eglGetError());
+ format = 0;
+ }
+ if (attrib_list) {
+ for (const EGLint* attr = attrib_list; *attr != EGL_NONE;
+ attr += 2) {
+ if (*attr == EGL_GL_COLORSPACE_KHR &&
+ dp->haveExtension("EGL_KHR_gl_colorspace")) {
+ format = modifyFormatColorspace(format, *(attr+1));
}
}
}
+ if (format != 0) {
+ int err = native_window_set_buffers_format(window, format);
+ if (err != 0) {
+ ALOGE("error setting native window pixel format: %s (%d)",
+ strerror(-err), err);
+ native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
+ return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+ }
+ }
// the EGL spec requires that a new EGLSurface default to swap interval
// 1, so explicitly set that on the window here.
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 8d7890b..0380521 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -44,6 +44,16 @@ extern void setGLHooksThreadSpecific(gl_hooks_t const *value);
// ----------------------------------------------------------------------------
+static bool findExtension(const char* exts, const char* name, size_t nameLen) {
+ if (exts) {
+ const char* match = strstr(exts, name);
+ if (match && (match[nameLen] == '\0' || match[nameLen] == ' ')) {
+ return true;
+ }
+ }
+ return false;
+}
+
egl_display_t egl_display_t::sDisplay[NUM_DISPLAYS];
egl_display_t::egl_display_t() :
@@ -196,14 +206,9 @@ EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
if (len) {
// NOTE: we could avoid the copy if we had strnstr.
const String8 ext(start, len);
- // now look for this extension
- if (disp.queryString.extensions) {
- // if we find it, add this extension string to our list
- // (and don't forget the space)
- const char* match = strstr(disp.queryString.extensions, ext.string());
- if (match && (match[len] == ' ' || match[len] == 0)) {
- mExtensionString.append(start, len+1);
- }
+ if (findExtension(disp.queryString.extensions, ext.string(),
+ len)) {
+ mExtensionString.append(start, len+1);
}
}
// process the next extension string, and skip the space.
@@ -367,6 +372,13 @@ EGLBoolean egl_display_t::makeCurrent(egl_context_t* c, egl_context_t* cur_c,
return result;
}
+bool egl_display_t::haveExtension(const char* name, size_t nameLen) const {
+ if (!nameLen) {
+ nameLen = strlen(name);
+ }
+ return findExtension(mExtensionString.string(), name, nameLen);
+}
+
// ----------------------------------------------------------------------------
bool egl_display_t::HibernationMachine::incWakeCount(WakeRefStrength strength) {
diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h
index 754085c..87f27f8 100644
--- a/opengl/libs/EGL/egl_display.h
+++ b/opengl/libs/EGL/egl_display.h
@@ -99,6 +99,8 @@ public:
char const * getClientApiString() const { return mClientApiString.string(); }
char const * getExtensionString() const { return mExtensionString.string(); }
+ bool haveExtension(const char* name, size_t nameLen = 0) const;
+
inline uint32_t getRefsCount() const { return refs; }
struct strings_t {