Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c2e41222 authored by Jesse Hall's avatar Jesse Hall
Browse files

Add support for EGL_KHR_gl_colorspace

Change-Id: I684d0b8556cd6c84ee4b4d67e1bb95c3b96fccfb
parent 6f23562e
Loading
Loading
Loading
Loading
+55 −11
Original line number Original line Diff line number Diff line
@@ -82,6 +82,7 @@ extern char const * const gExtensionString =
        "EGL_KHR_image_base "                   // mandatory
        "EGL_KHR_image_base "                   // mandatory
        "EGL_KHR_image_pixmap "
        "EGL_KHR_image_pixmap "
        "EGL_KHR_lock_surface "
        "EGL_KHR_lock_surface "
        "EGL_KHR_gl_colorspace "
        "EGL_KHR_gl_texture_2D_image "
        "EGL_KHR_gl_texture_2D_image "
        "EGL_KHR_gl_texture_cubemap_image "
        "EGL_KHR_gl_texture_cubemap_image "
        "EGL_KHR_gl_renderbuffer_image "
        "EGL_KHR_gl_renderbuffer_image "
@@ -365,6 +366,33 @@ EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
// surfaces
// 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,
EGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,
                                    NativeWindowType window,
                                    NativeWindowType window,
                                    const EGLint *attrib_list)
                                    const EGLint *attrib_list)
@@ -375,7 +403,6 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
    egl_display_ptr dp = validate_display_connection(dpy, cnx);
    egl_display_ptr dp = validate_display_connection(dpy, cnx);
    if (dp) {
    if (dp) {
        EGLDisplay iDpy = dp->disp.dpy;
        EGLDisplay iDpy = dp->disp.dpy;
        EGLint format;


        if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) != OK) {
        if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) != OK) {
            ALOGE("EGLNativeWindowType %p already connected to another API",
            ALOGE("EGLNativeWindowType %p already connected to another API",
@@ -383,9 +410,27 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
            return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
            return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
        }
        }


        // set the native window's buffers format to match this config
        // Set the native window's buffers format to match this config.
        if (cnx->egl.eglGetConfigAttrib(iDpy,
        // Whether to use sRGB gamma is not part of the EGLconfig, but is part
                config, EGL_NATIVE_VISUAL_ID, &format)) {
        // 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) {
        if (format != 0) {
            int err = native_window_set_buffers_format(window, format);
            int err = native_window_set_buffers_format(window, format);
            if (err != 0) {
            if (err != 0) {
@@ -395,7 +440,6 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
                return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
                return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
            }
            }
        }
        }
        }


        // the EGL spec requires that a new EGLSurface default to swap interval
        // the EGL spec requires that a new EGLSurface default to swap interval
        // 1, so explicitly set that on the window here.
        // 1, so explicitly set that on the window here.
+20 −8
Original line number Original line Diff line number Diff line
@@ -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::sDisplay[NUM_DISPLAYS];


egl_display_t::egl_display_t() :
egl_display_t::egl_display_t() :
@@ -196,16 +206,11 @@ EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
            if (len) {
            if (len) {
                // NOTE: we could avoid the copy if we had strnstr.
                // NOTE: we could avoid the copy if we had strnstr.
                const String8 ext(start, len);
                const String8 ext(start, len);
                // now look for this extension
                if (findExtension(disp.queryString.extensions, ext.string(),
                if (disp.queryString.extensions) {
                        len)) {
                    // 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);
                    mExtensionString.append(start, len+1);
                }
                }
            }
            }
            }
            // process the next extension string, and skip the space.
            // process the next extension string, and skip the space.
            start = end + 1;
            start = end + 1;
        }
        }
@@ -367,6 +372,13 @@ EGLBoolean egl_display_t::makeCurrent(egl_context_t* c, egl_context_t* cur_c,
    return result;
    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) {
bool egl_display_t::HibernationMachine::incWakeCount(WakeRefStrength strength) {
+2 −0
Original line number Original line Diff line number Diff line
@@ -99,6 +99,8 @@ public:
    char const * getClientApiString() const { return mClientApiString.string(); }
    char const * getClientApiString() const { return mClientApiString.string(); }
    char const * getExtensionString() const { return mExtensionString.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; }
    inline uint32_t getRefsCount() const { return refs; }


    struct strings_t {
    struct strings_t {
+1 −0
Original line number Original line Diff line number Diff line
@@ -582,6 +582,7 @@ bool Layer::getOpacityForFormat(uint32_t format) {
    switch (format) {
    switch (format) {
        case HAL_PIXEL_FORMAT_RGBA_8888:
        case HAL_PIXEL_FORMAT_RGBA_8888:
        case HAL_PIXEL_FORMAT_BGRA_8888:
        case HAL_PIXEL_FORMAT_BGRA_8888:
        case HAL_PIXEL_FORMAT_sRGB_A_8888:
            return false;
            return false;
    }
    }
    // in all other case, we have no blending (also for unknown formats)
    // in all other case, we have no blending (also for unknown formats)