summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Courtney Goeltzenleuchter <courtneygo@google.com> 2017-04-26 15:07:51 -0600
committer Courtney Goeltzenleuchter <courtneygo@google.com> 2017-05-02 11:33:43 -0600
commit378365716852e0474899f968810ca1df7d30d7f6 (patch)
tree08193f9b8ca7300f0e95dcf8eed2fa33c2accda6
parentc9c0075bda100a08b1ee17f328d8567b462fcc28 (diff)
Apply and Track EGL_GL_COLORSPACE_KHR
As part of implementing EGL_KHR_gl_colorspace we need to keep track of the EGL_GL_COLORSPACE_KHR so that eqlQuerySurface gets the value the application set. Do the work in the EGL layer because colorspace information is not handled in the driver. Test: adb shell /data/nativetest/EGL_test/EGL_test Bug: 37709988 Change-Id: Ic92e717a46769144d724f4a84fb3560df076da4f
-rw-r--r--opengl/libs/EGL/eglApi.cpp94
-rw-r--r--opengl/libs/EGL/egl_object.cpp15
-rw-r--r--opengl/libs/EGL/egl_object.h7
3 files changed, 92 insertions, 24 deletions
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index f9229adf4d..7c4bdf91b2 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -473,6 +473,45 @@ static android_dataspace modifyBufferDataspace( android_dataspace dataSpace,
return dataSpace;
}
+static EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, const EGLint* attrib_list,
+ EGLint& colorSpace, android_dataspace& dataSpace) {
+ colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR;
+ dataSpace = HAL_DATASPACE_UNKNOWN;
+ 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) {
+ colorSpace = attr[1];
+ bool found = false;
+ // Verify that color space is allowed
+ if (colorSpace == EGL_GL_COLORSPACE_SRGB_KHR ||
+ colorSpace == EGL_GL_COLORSPACE_LINEAR_KHR) {
+ found = true;
+ } else if (colorSpace == EGL_EXT_gl_colorspace_bt2020_linear &&
+ dp->haveExtension("EGL_EXT_gl_colorspace_bt2020_linear")) {
+ found = true;
+ } else if (colorSpace == EGL_EXT_gl_colorspace_bt2020_pq &&
+ dp->haveExtension("EGL_EXT_gl_colorspace_bt2020_pq")) {
+ found = true;
+ } else if (colorSpace == EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT &&
+ dp->haveExtension("EGL_EXT_gl_colorspace_scrgb_linear")) {
+ found = true;
+ } else if (colorSpace == EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT &&
+ dp->haveExtension("EGL_EXT_gl_colorspace_display_p3_linear")) {
+ found = true;
+ } else if (colorSpace == EGL_GL_COLORSPACE_DISPLAY_P3_EXT &&
+ dp->haveExtension("EGL_EXT_gl_colorspace_display_p3")) {
+ found = true;
+ }
+ if (!found) {
+ return false;
+ }
+ }
+ }
+ dataSpace = modifyBufferDataspace(dataSpace, colorSpace);
+ }
+ return true;
+}
+
EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
NativeWindowType window,
const EGLint *attrib_list)
@@ -513,7 +552,8 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
&componentType);
EGLint format;
- android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
+ EGLint colorSpace;
+ android_dataspace dataSpace;
EGLint a = 0;
EGLint r, g, b;
r = g = b = 0;
@@ -550,12 +590,9 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
}
// now select a corresponding sRGB format if needed
- 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) {
- dataSpace = modifyBufferDataspace(dataSpace, *(attr+1));
- }
- }
+ if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) {
+ ALOGE("error invalid colorspace: %d", colorSpace);
+ return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
}
if (format != 0) {
@@ -586,8 +623,8 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
EGLSurface surface = cnx->egl.eglCreateWindowSurface(
iDpy, config, window, attrib_list);
if (surface != EGL_NO_SURFACE) {
- egl_surface_t* s = new egl_surface_t(dp.get(), config, window,
- surface, cnx);
+ egl_surface_t* s =
+ new egl_surface_t(dp.get(), config, window, surface, colorSpace, cnx);
return s;
}
@@ -606,12 +643,19 @@ EGLSurface eglCreatePixmapSurface( EGLDisplay dpy, EGLConfig config,
egl_connection_t* cnx = NULL;
egl_display_ptr dp = validate_display_connection(dpy, cnx);
+ EGLint colorSpace;
+ android_dataspace dataSpace;
if (dp) {
+ // now select a corresponding sRGB format if needed
+ if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) {
+ ALOGE("error invalid colorspace: %d", colorSpace);
+ return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ }
+
EGLSurface surface = cnx->egl.eglCreatePixmapSurface(
dp->disp.dpy, config, pixmap, attrib_list);
if (surface != EGL_NO_SURFACE) {
- egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL,
- surface, cnx);
+ egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, colorSpace, cnx);
return s;
}
}
@@ -625,12 +669,19 @@ EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config,
egl_connection_t* cnx = NULL;
egl_display_ptr dp = validate_display_connection(dpy, cnx);
+ EGLint colorSpace;
+ android_dataspace dataSpace;
if (dp) {
+ // now select a corresponding sRGB format if needed
+ if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) {
+ ALOGE("error invalid colorspace: %d", colorSpace);
+ return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ }
+
EGLSurface surface = cnx->egl.eglCreatePbufferSurface(
dp->disp.dpy, config, attrib_list);
if (surface != EGL_NO_SURFACE) {
- egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL,
- surface, cnx);
+ egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, colorSpace, cnx);
return s;
}
}
@@ -669,6 +720,10 @@ EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface,
return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE);
egl_surface_t const * const s = get_surface(surface);
+ if (attribute == EGL_GL_COLORSPACE_KHR) {
+ *value = s->getColorSpace();
+ return EGL_TRUE;
+ }
return s->cnx->egl.eglQuerySurface(
dp->disp.dpy, s->surface, attribute, value);
}
@@ -1708,13 +1763,22 @@ EGLSurface eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy, EGLConfig config,
egl_display_ptr dp = validate_display(dpy);
if (!dp) return EGL_NO_SURFACE;
+ EGLint colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR;
+ android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
+ // TODO: Probably need to update EGL_KHR_stream_producer_eglsurface to
+ // indicate support for EGL_GL_COLORSPACE_KHR.
+ // now select a corresponding sRGB format if needed
+ if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) {
+ ALOGE("error invalid colorspace: %d", colorSpace);
+ return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ }
+
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso && cnx->egl.eglCreateStreamProducerSurfaceKHR) {
EGLSurface surface = cnx->egl.eglCreateStreamProducerSurfaceKHR(
dp->disp.dpy, config, stream, attrib_list);
if (surface != EGL_NO_SURFACE) {
- egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL,
- surface, cnx);
+ egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, colorSpace, cnx);
return s;
}
}
diff --git a/opengl/libs/EGL/egl_object.cpp b/opengl/libs/EGL/egl_object.cpp
index 623878062b..837cfa92ca 100644
--- a/opengl/libs/EGL/egl_object.cpp
+++ b/opengl/libs/EGL/egl_object.cpp
@@ -55,12 +55,15 @@ bool egl_object_t::get(egl_display_t const* display, egl_object_t* object) {
// ----------------------------------------------------------------------------
-egl_surface_t::egl_surface_t(egl_display_t* dpy, EGLConfig config,
- EGLNativeWindowType win, EGLSurface surface,
- egl_connection_t const* cnx) :
- egl_object_t(dpy), surface(surface), config(config), win(win), cnx(cnx),
- connected(true)
-{
+egl_surface_t::egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win,
+ EGLSurface surface, EGLint colorSpace, egl_connection_t const* cnx)
+ : egl_object_t(dpy),
+ surface(surface),
+ config(config),
+ win(win),
+ cnx(cnx),
+ connected(true),
+ colorSpace(colorSpace) {
if (win) {
win->incStrong(this);
}
diff --git a/opengl/libs/EGL/egl_object.h b/opengl/libs/EGL/egl_object.h
index 8988905a25..7c3075c9fc 100644
--- a/opengl/libs/EGL/egl_object.h
+++ b/opengl/libs/EGL/egl_object.h
@@ -131,12 +131,12 @@ protected:
public:
typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref;
- egl_surface_t(egl_display_t* dpy, EGLConfig config,
- EGLNativeWindowType win, EGLSurface surface,
- egl_connection_t const* cnx);
+ egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win, EGLSurface surface,
+ EGLint colorSpace, egl_connection_t const* cnx);
ANativeWindow* getNativeWindow() { return win; }
ANativeWindow* getNativeWindow() const { return win; }
+ EGLint getColorSpace() const { return colorSpace; }
// Try to keep the order of these fields and size unchanged. It's not public API, but
// it's not hard to imagine native games accessing them.
@@ -149,6 +149,7 @@ public:
private:
bool connected;
void disconnect();
+ EGLint colorSpace;
};
class egl_context_t: public egl_object_t {