* commit '3b835a8db09e59321da2c42972690edd5cae9714': Add support for EGL_KHR_gl_colorspace
This commit is contained in:
commit
ddb7ae4258
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -572,6 +572,7 @@ bool Layer::getOpacityForFormat(uint32_t format) {
|
||||
switch (format) {
|
||||
case HAL_PIXEL_FORMAT_RGBA_8888:
|
||||
case HAL_PIXEL_FORMAT_BGRA_8888:
|
||||
case HAL_PIXEL_FORMAT_sRGB_A_8888:
|
||||
return false;
|
||||
}
|
||||
// in all other case, we have no blending (also for unknown formats)
|
||||
|
Loading…
Reference in New Issue
Block a user