/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "eglDisplay.h"
#include "HostConnection.h"
#include <dlfcn.h>

#include <string>

static const int systemEGLVersionMajor = 1;
static const int systemEGLVersionMinor = 4;
static const char systemEGLVendor[] = "Google Android emulator";

// list of extensions supported by this EGL implementation
//  NOTE that each extension name should be suffixed with space
static const char systemStaticEGLExtensions[] =
            "EGL_ANDROID_image_native_buffer "
            "EGL_KHR_fence_sync "
            "EGL_KHR_image_base "
            "EGL_KHR_gl_texture_2d_image ";

// extensions to add dynamically depending on host-side support
static const char kDynamicEGLExtNativeSync[] = "EGL_ANDROID_native_fence_sync ";
static const char kDynamicEGLExtWaitSync[] = "EGL_KHR_wait_sync ";

static void *s_gles_lib = NULL;
static void *s_gles2_lib = NULL;

// The following function will be called when we (libEGL)
// gets unloaded
// At this point we want to unload the gles libraries we
// might have loaded during initialization
static void __attribute__ ((destructor)) do_on_unload(void)
{
    if (s_gles_lib) {
        dlclose(s_gles_lib);
    }

    if (s_gles2_lib) {
        dlclose(s_gles2_lib);
    }
}

eglDisplay::eglDisplay() :
    m_initialized(false),
    m_major(0),
    m_minor(0),
    m_hostRendererVersion(0),
    m_numConfigs(0),
    m_numConfigAttribs(0),
    m_attribs(DefaultKeyedVector<EGLint, EGLint>(ATTRIBUTE_NONE)),
    m_configs(NULL),
    m_gles_iface(NULL),
    m_gles2_iface(NULL),
    m_versionString(NULL),
    m_vendorString(NULL),
    m_extensionString(NULL)
{
    pthread_mutex_init(&m_lock, NULL);
    pthread_mutex_init(&m_ctxLock, NULL);
    pthread_mutex_init(&m_surfaceLock, NULL);
}

eglDisplay::~eglDisplay()
{
    terminate();
    pthread_mutex_destroy(&m_lock);
    pthread_mutex_destroy(&m_ctxLock);
    pthread_mutex_destroy(&m_surfaceLock);
}

#if PLATFORM_SDK_VERSION >= 26
#define PARTITION "/vendor"
#else
#define PARTITION "/system"
#endif

bool eglDisplay::initialize(EGLClient_eglInterface *eglIface)
{
    pthread_mutex_lock(&m_lock);
    if (!m_initialized) {

        //
        // load GLES client API
        //
#if __LP64__
        m_gles_iface = loadGLESClientAPI(PARTITION "/lib64/egl/libGLESv1_CM_emulation.so",
                                         eglIface,
                                         &s_gles_lib);
#else
        m_gles_iface = loadGLESClientAPI(PARTITION "/lib/egl/libGLESv1_CM_emulation.so",
                                         eglIface,
                                         &s_gles_lib);
#endif
        if (!m_gles_iface) {
            pthread_mutex_unlock(&m_lock);
            ALOGE("Failed to load gles1 iface");
            return false;
        }

#ifdef WITH_GLES2
#if __LP64__
        m_gles2_iface = loadGLESClientAPI(PARTITION "/lib64/egl/libGLESv2_emulation.so",
                                          eglIface,
                                          &s_gles2_lib);
#else
        m_gles2_iface = loadGLESClientAPI(PARTITION "/lib/egl/libGLESv2_emulation.so",
                                          eglIface,
                                          &s_gles2_lib);
#endif
        // Note that if loading gles2 failed, we can still run with no
        // GLES2 support, having GLES2 is not mandatory.
#endif

        //
        // establish connection with the host
        //
        HostConnection *hcon = HostConnection::get();
        if (!hcon) {
            pthread_mutex_unlock(&m_lock);
            ALOGE("Failed to establish connection with the host\n");
            return false;
        }
        hcon->setGrallocOnly(false);

        //
        // get renderControl encoder instance
        //
        renderControl_encoder_context_t *rcEnc = hcon->rcEncoder();
        if (!rcEnc) {
            pthread_mutex_unlock(&m_lock);
            ALOGE("Failed to get renderControl encoder instance");
            return false;
        }

        //
        // Query host reneder and EGL version
        //
        m_hostRendererVersion = rcEnc->rcGetRendererVersion(rcEnc);
        EGLint status = rcEnc->rcGetEGLVersion(rcEnc, &m_major, &m_minor);
        if (status != EGL_TRUE) {
            // host EGL initialization failed !!
            pthread_mutex_unlock(&m_lock);
            return false;
        }

        //
        // Take minimum version beween what we support and what the host support
        //
        if (m_major > systemEGLVersionMajor) {
            m_major = systemEGLVersionMajor;
            m_minor = systemEGLVersionMinor;
        }
        else if (m_major == systemEGLVersionMajor &&
                 m_minor > systemEGLVersionMinor) {
            m_minor = systemEGLVersionMinor;
        }

        //
        // Query the host for the set of configs
        //
        m_numConfigs = rcEnc->rcGetNumConfigs(rcEnc, (uint32_t*)&m_numConfigAttribs);
        if (m_numConfigs <= 0 || m_numConfigAttribs <= 0) {
            // just sanity check - should never happen
            pthread_mutex_unlock(&m_lock);
            return false;
        }

        uint32_t nInts = m_numConfigAttribs * (m_numConfigs + 1);
        EGLint tmp_buf[nInts];
        m_configs = new EGLint[nInts-m_numConfigAttribs];
        if (!m_configs) {
            pthread_mutex_unlock(&m_lock);
            return false;
        }

        //EGLint n = rcEnc->rcGetConfigs(rcEnc, nInts*sizeof(EGLint), m_configs);
        EGLint n = rcEnc->rcGetConfigs(rcEnc, nInts*sizeof(EGLint), (GLuint*)tmp_buf);
        if (n != m_numConfigs) {
            pthread_mutex_unlock(&m_lock);
            return false;
        }

        //Fill the attributes vector.
        //The first m_numConfigAttribs values of tmp_buf are the actual attributes enums.
        for (int i=0; i<m_numConfigAttribs; i++) {
            m_attribs.add(tmp_buf[i], i);
        }

        //Copy the actual configs data to m_configs
        memcpy(m_configs, tmp_buf + m_numConfigAttribs, m_numConfigs*m_numConfigAttribs*sizeof(EGLint));

        m_initialized = true;
    }
    pthread_mutex_unlock(&m_lock);

    processConfigs();

    return true;
}

void eglDisplay::processConfigs()
{
    for (intptr_t i=0; i<m_numConfigs; i++) {
        EGLConfig config = (EGLConfig)i;
        //Setup the EGL_NATIVE_VISUAL_ID attribute
        PixelFormat format;
        if (getConfigNativePixelFormat(config, &format)) {
            setConfigAttrib(config, EGL_NATIVE_VISUAL_ID, format);
        }
    }
}

void eglDisplay::terminate()
{
    pthread_mutex_lock(&m_lock);
    if (m_initialized) {
        // Cannot use the for loop in the following code because
        // eglDestroyContext may erase elements.
        EGLContextSet::iterator ctxIte = m_contexts.begin();
        while (ctxIte != m_contexts.end()) {
            EGLContextSet::iterator ctxToDelete = ctxIte;
            ctxIte ++;
            eglDestroyContext(static_cast<EGLDisplay>(this), *ctxToDelete);
        }
        EGLSurfaceSet::iterator surfaceIte = m_surfaces.begin();
        while (surfaceIte != m_surfaces.end()) {
            EGLSurfaceSet::iterator surfaceToDelete = surfaceIte;
            surfaceIte ++;
            eglDestroySurface(static_cast<EGLDisplay>(this), *surfaceToDelete);
        }
        m_initialized = false;
        delete [] m_configs;
        m_configs = NULL;

        if (m_versionString) {
            free(m_versionString);
            m_versionString = NULL;
        }
        if (m_vendorString) {
            free(m_vendorString);
            m_vendorString = NULL;
        }
        if (m_extensionString) {
            free(m_extensionString);
            m_extensionString = NULL;
        }
    }
    pthread_mutex_unlock(&m_lock);
}

EGLClient_glesInterface *eglDisplay::loadGLESClientAPI(const char *libName,
                                                       EGLClient_eglInterface *eglIface,
                                                       void **libHandle)
{
    void *lib = dlopen(libName, RTLD_NOW);
    if (!lib) {
        ALOGE("Failed to dlopen %s", libName);
        return NULL;
    }

    init_emul_gles_t init_gles_func = (init_emul_gles_t)dlsym(lib,"init_emul_gles");
    if (!init_gles_func) {
        ALOGE("Failed to find init_emul_gles");
        dlclose((void*)lib);
        return NULL;
    }

    *libHandle = lib;
    return (*init_gles_func)(eglIface);
}

static char *queryHostEGLString(EGLint name)
{
    HostConnection *hcon = HostConnection::get();
    if (hcon) {
        renderControl_encoder_context_t *rcEnc = hcon->rcEncoder();
        if (rcEnc) {
            int n = rcEnc->rcQueryEGLString(rcEnc, name, NULL, 0);
            if (n < 0) {
                // allocate space for the string.
                char *str = (char *)malloc(-n);
                n = rcEnc->rcQueryEGLString(rcEnc, name, str, -n);
                if (n > 0) {
                    return str;
                }

                free(str);
            }
        }
    }

    return NULL;
}

static bool findExtInList(const char* token, int tokenlen, const char* list)
{
    const char* p = list;
    while (*p != '\0') {
        const char* q = strchr(p, ' ');
        if (q == NULL) {
            /* should not happen, list must be space-terminated */
            break;
        }
        if (tokenlen == (q - p) && !memcmp(token, p, tokenlen)) {
            return true;  /* found it */
        }
        p = q+1;
    }
    return false;  /* not found */
}

static char *buildExtensionString()
{
    //Query host extension string
    char *hostExt = queryHostEGLString(EGL_EXTENSIONS);
    if (!hostExt || (hostExt[1] == '\0')) {
        // no extensions on host - only static extension list supported
        return strdup(systemStaticEGLExtensions);
    }

    int n = strlen(hostExt);
    if (n > 0) {
        char *initialEGLExts;
        char *finalEGLExts;

        HostConnection *hcon = HostConnection::get();
        // If we got here, we must have succeeded in queryHostEGLString
        // and we thus should have a valid connection
        assert(hcon);

        asprintf(&initialEGLExts,"%s%s", systemStaticEGLExtensions, hostExt);

        std::string dynamicEGLExtensions;

        if (hcon->rcEncoder()->hasNativeSync() &&
            !strstr(initialEGLExts, kDynamicEGLExtNativeSync)) {
            dynamicEGLExtensions += kDynamicEGLExtNativeSync;

            if (hcon->rcEncoder()->hasNativeSyncV3()) {
                dynamicEGLExtensions += kDynamicEGLExtWaitSync;
            }
        }

        asprintf(&finalEGLExts, "%s%s", initialEGLExts, dynamicEGLExtensions.c_str());

        free((char*)hostExt);
        return finalEGLExts;
    }
    else {
        free((char*)hostExt);
        return strdup(systemStaticEGLExtensions);
    }
}

const char *eglDisplay::queryString(EGLint name)
{
    if (name == EGL_CLIENT_APIS) {
        return "OpenGL_ES";
    }
    else if (name == EGL_VERSION) {
        pthread_mutex_lock(&m_lock);
        if (m_versionString) {
            pthread_mutex_unlock(&m_lock);
            return m_versionString;
        }

        // build version string
        asprintf(&m_versionString, "%d.%d", m_major, m_minor);
        pthread_mutex_unlock(&m_lock);

        return m_versionString;
    }
    else if (name == EGL_VENDOR) {
        pthread_mutex_lock(&m_lock);
        if (m_vendorString) {
            pthread_mutex_unlock(&m_lock);
            return m_vendorString;
        }

        // build vendor string
        const char *hostVendor = queryHostEGLString(EGL_VENDOR);

        if (hostVendor) {
            asprintf(&m_vendorString, "%s Host: %s",
                                     systemEGLVendor, hostVendor);
            free((char*)hostVendor);
        }
        else {
            m_vendorString = (char *)systemEGLVendor;
        }
        pthread_mutex_unlock(&m_lock);

        return m_vendorString;
    }
    else if (name == EGL_EXTENSIONS) {
        pthread_mutex_lock(&m_lock);
        if (m_extensionString) {
            pthread_mutex_unlock(&m_lock);
            return m_extensionString;
        }

        // build extension string
        m_extensionString = buildExtensionString();
        pthread_mutex_unlock(&m_lock);

        return m_extensionString;
    }
    else {
        ALOGE("[%s] Unknown name %d\n", __FUNCTION__, name);
        return NULL;
    }
}

/* To get the value of attribute <a> of config <c> use the following formula:
 * value = *(m_configs + (int)c*m_numConfigAttribs + a);
 */
EGLBoolean eglDisplay::getAttribValue(EGLConfig config, EGLint attribIdx, EGLint * value)
{
    if (attribIdx == ATTRIBUTE_NONE)
    {
        ALOGE("[%s] Bad attribute idx\n", __FUNCTION__);
        return EGL_FALSE;
    }
    *value = *(m_configs + (intptr_t)config*m_numConfigAttribs + attribIdx);
    return EGL_TRUE;
}

#define EGL_COLOR_COMPONENT_TYPE_EXT 0x3339
#define EGL_COLOR_COMPONENT_TYPE_FIXED_EXT 0x333A

EGLBoolean eglDisplay::getConfigAttrib(EGLConfig config, EGLint attrib, EGLint * value)
{
    if (attrib == EGL_FRAMEBUFFER_TARGET_ANDROID) {
        *value = EGL_TRUE;
        return EGL_TRUE;
    }
    if (attrib == EGL_COVERAGE_SAMPLES_NV ||
        attrib == EGL_COVERAGE_BUFFERS_NV) {
        *value = 0;
        return EGL_TRUE;
    }
    if (attrib == EGL_DEPTH_ENCODING_NV) {
        *value = EGL_DEPTH_ENCODING_NONE_NV;
        return EGL_TRUE;
    }
    if  (attrib == EGL_COLOR_COMPONENT_TYPE_EXT) {
        *value = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
        return EGL_TRUE;
    }
    //Though it seems that valueFor() is thread-safe, we don't take chanses
    pthread_mutex_lock(&m_lock);
    EGLBoolean ret = getAttribValue(config, m_attribs.valueFor(attrib), value);
    pthread_mutex_unlock(&m_lock);
    return ret;
}

void eglDisplay::dumpConfig(EGLConfig config)
{
    EGLint value = 0;
    DBG("^^^^^^^^^^ dumpConfig %d ^^^^^^^^^^^^^^^^^^", (int)config);
    for (int i=0; i<m_numConfigAttribs; i++) {
        getAttribValue(config, i, &value);
        DBG("{%d}[%d] %d\n", (int)config, i, value);
    }
}

/* To set the value of attribute <a> of config <c> use the following formula:
 * *(m_configs + (int)c*m_numConfigAttribs + a) = value;
 */
EGLBoolean eglDisplay::setAttribValue(EGLConfig config, EGLint attribIdx, EGLint value)
{
    if (attribIdx == ATTRIBUTE_NONE)
    {
        ALOGE("[%s] Bad attribute idx\n", __FUNCTION__);
        return EGL_FALSE;
    }
    *(m_configs + (intptr_t)config*m_numConfigAttribs + attribIdx) = value;
    return EGL_TRUE;
}

EGLBoolean eglDisplay::setConfigAttrib(EGLConfig config, EGLint attrib, EGLint value)
{
    //Though it seems that valueFor() is thread-safe, we don't take chanses
    pthread_mutex_lock(&m_lock);
    EGLBoolean ret = setAttribValue(config, m_attribs.valueFor(attrib), value);
    pthread_mutex_unlock(&m_lock);
    return ret;
}


EGLBoolean eglDisplay::getConfigNativePixelFormat(EGLConfig config, PixelFormat * format)
{
    EGLint redSize, blueSize, greenSize, alphaSize;

    if ( !(getAttribValue(config, m_attribs.valueFor(EGL_RED_SIZE), &redSize) &&
        getAttribValue(config, m_attribs.valueFor(EGL_BLUE_SIZE), &blueSize) &&
        getAttribValue(config, m_attribs.valueFor(EGL_GREEN_SIZE), &greenSize) &&
        getAttribValue(config, m_attribs.valueFor(EGL_ALPHA_SIZE), &alphaSize)) )
    {
        ALOGE("Couldn't find value for one of the pixel format attributes");
        return EGL_FALSE;
    }

    //calculate the GL internal format
    if ((redSize==8)&&(greenSize==8)&&(blueSize==8)&&(alphaSize==8)) *format = PIXEL_FORMAT_RGBA_8888; //XXX: BGR?
    else if ((redSize==8)&&(greenSize==8)&&(blueSize==8)&&(alphaSize==0)) *format = PIXEL_FORMAT_RGBX_8888; //XXX or PIXEL_FORMAT_RGB_888
    else if ((redSize==5)&&(greenSize==6)&&(blueSize==5)&&(alphaSize==0)) *format = PIXEL_FORMAT_RGB_565;
    else if ((redSize==5)&&(greenSize==5)&&(blueSize==5)&&(alphaSize==1)) *format = PIXEL_FORMAT_RGBA_5551;
    else if ((redSize==4)&&(greenSize==4)&&(blueSize==4)&&(alphaSize==4)) *format = PIXEL_FORMAT_RGBA_4444;
    else {
        return EGL_FALSE;
    }
    return EGL_TRUE;
}
EGLBoolean eglDisplay::getConfigGLPixelFormat(EGLConfig config, GLenum * format)
{
    EGLint redSize, blueSize, greenSize, alphaSize;

    if ( !(getAttribValue(config, m_attribs.valueFor(EGL_RED_SIZE), &redSize) &&
        getAttribValue(config, m_attribs.valueFor(EGL_BLUE_SIZE), &blueSize) &&
        getAttribValue(config, m_attribs.valueFor(EGL_GREEN_SIZE), &greenSize) &&
        getAttribValue(config, m_attribs.valueFor(EGL_ALPHA_SIZE), &alphaSize)) )
    {
        ALOGE("Couldn't find value for one of the pixel format attributes");
        return EGL_FALSE;
    }

    //calculate the GL internal format
    if ((redSize == greenSize) && (redSize == blueSize) &&
        ((redSize == 8) || (redSize == 16) || (redSize == 32)))
    {
        if (alphaSize == 0) *format = GL_RGB;
        else *format = GL_RGBA;
    }
    else if ((redSize==5)&&(greenSize==6)&&(blueSize==5)&&(alphaSize==0)) *format = GL_RGB565_OES;
    else if ((redSize==5)&&(greenSize==5)&&(blueSize==5)&&(alphaSize==1)) *format = GL_RGB5_A1_OES;
    else if ((redSize==4)&&(greenSize==4)&&(blueSize==4)&&(alphaSize==4)) *format = GL_RGBA4_OES;
    else return EGL_FALSE;

    return EGL_TRUE;
}

void eglDisplay::onCreateContext(EGLContext ctx) {
    pthread_mutex_lock(&m_ctxLock);
    m_contexts.insert(ctx);
    pthread_mutex_unlock(&m_ctxLock);
}

void eglDisplay::onCreateSurface(EGLSurface surface) {
    pthread_mutex_lock(&m_surfaceLock);
    m_surfaces.insert(surface);
    pthread_mutex_unlock(&m_surfaceLock);
}

void eglDisplay::onDestroyContext(EGLContext ctx) {
    pthread_mutex_lock(&m_ctxLock);
    m_contexts.erase(ctx);
    pthread_mutex_unlock(&m_ctxLock);
}

void eglDisplay::onDestroySurface(EGLSurface surface) {
    pthread_mutex_lock(&m_surfaceLock);
    m_surfaces.erase(surface);
    pthread_mutex_unlock(&m_surfaceLock);
}

bool eglDisplay::isContext(EGLContext ctx) {
    pthread_mutex_lock(&m_ctxLock);
    bool res = m_contexts.find(ctx) != m_contexts.end();
    pthread_mutex_unlock(&m_ctxLock);
    return res;
}

bool eglDisplay::isSurface(EGLSurface surface) {
    pthread_mutex_lock(&m_surfaceLock);
    bool res = m_surfaces.find(surface) != m_surfaces.end();
    pthread_mutex_unlock(&m_surfaceLock);
    return res;
}
