/*
 ** Copyright 2007, 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 <ctype.h>
#include <stdlib.h>
#include <string.h>

#include <hardware/gralloc.h>
#include <system/window.h>

#include <EGL/egl.h>
#include <EGL/eglext.h>

#include <cutils/log.h>
#include <cutils/atomic.h>
#include <cutils/properties.h>

#include <utils/CallStack.h>
#include <utils/String8.h>

#include "../egl_impl.h"
#include "../glestrace.h"

#include "egl_tls.h"
#include "egldefs.h"
#include "Loader.h"

#include "egl_display.h"
#include "egl_object.h"

typedef __eglMustCastToProperFunctionPointerType EGLFuncPointer;

// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------

egl_connection_t gEGLImpl;
gl_hooks_t gHooks[2];
gl_hooks_t gHooksNoContext;
pthread_key_t gGLWrapperKey = -1;

// ----------------------------------------------------------------------------

#if EGL_TRACE

EGLAPI pthread_key_t gGLTraceKey = -1;

// ----------------------------------------------------------------------------

/**
 * There are three different tracing methods:
 * 1. libs/EGL/trace.cpp: Traces all functions to systrace.
 *    To enable:
 *      - set system property "debug.egl.trace" to "systrace" to trace all apps.
 * 2. libs/EGL/trace.cpp: Logs a stack trace for GL errors after each function call.
 *    To enable:
 *      - set system property "debug.egl.trace" to "error" to trace all apps.
 * 3. libs/EGL/trace.cpp: Traces all functions to logcat.
 *    To enable:
 *      - set system property "debug.egl.trace" to 1 to trace all apps.
 *      - or call setGLTraceLevel(1) from an app to enable tracing for that app.
 * 4. libs/GLES_trace: Traces all functions via protobuf to host.
 *    To enable:
 *        - set system property "debug.egl.debug_proc" to the application name.
 *      - or call setGLDebugLevel(1) from the app.
 */
static int sEGLTraceLevel;
static int sEGLApplicationTraceLevel;

static bool sEGLSystraceEnabled;
static bool sEGLGetErrorEnabled;

static volatile int sEGLDebugLevel;

extern gl_hooks_t gHooksTrace;
extern gl_hooks_t gHooksSystrace;
extern gl_hooks_t gHooksErrorTrace;

int getEGLDebugLevel() {
    return sEGLDebugLevel;
}

void setEGLDebugLevel(int level) {
    sEGLDebugLevel = level;
}

static inline void setGlTraceThreadSpecific(gl_hooks_t const *value) {
    pthread_setspecific(gGLTraceKey, value);
}

gl_hooks_t const* getGLTraceThreadSpecific() {
    return static_cast<gl_hooks_t*>(pthread_getspecific(gGLTraceKey));
}

void initEglTraceLevel() {
    char value[PROPERTY_VALUE_MAX];
    property_get("debug.egl.trace", value, "0");

    sEGLGetErrorEnabled = !strcasecmp(value, "error");
    if (sEGLGetErrorEnabled) {
        sEGLSystraceEnabled = false;
        sEGLTraceLevel = 0;
        return;
    }

    sEGLSystraceEnabled = !strcasecmp(value, "systrace");
    if (sEGLSystraceEnabled) {
        sEGLTraceLevel = 0;
        return;
    }

    int propertyLevel = atoi(value);
    int applicationLevel = sEGLApplicationTraceLevel;
    sEGLTraceLevel = propertyLevel > applicationLevel ? propertyLevel : applicationLevel;
}

void initEglDebugLevel() {
    if (getEGLDebugLevel() == 0) {
        char value[PROPERTY_VALUE_MAX];

        // check system property only on userdebug or eng builds
        property_get("ro.debuggable", value, "0");
        if (value[0] == '0')
            return;

        property_get("debug.egl.debug_proc", value, "");
        if (strlen(value) > 0) {
            FILE * file = fopen("/proc/self/cmdline", "r");
            if (file) {
                char cmdline[256];
                if (fgets(cmdline, sizeof(cmdline), file)) {
                    if (!strncmp(value, cmdline, strlen(value))) {
                        // set EGL debug if the "debug.egl.debug_proc" property
                        // matches the prefix of this application's command line
                        setEGLDebugLevel(1);
                    }
                }
                fclose(file);
            }
        }
    }

    if (getEGLDebugLevel() > 0) {
        if (GLTrace_start() < 0) {
            ALOGE("Error starting Tracer for OpenGL ES. Disabling..");
            setEGLDebugLevel(0);
        }
    }
}

void setGLHooksThreadSpecific(gl_hooks_t const *value) {
    if (sEGLGetErrorEnabled) {
        setGlTraceThreadSpecific(value);
        setGlThreadSpecific(&gHooksErrorTrace);
    } else if (sEGLSystraceEnabled) {
        setGlTraceThreadSpecific(value);
        setGlThreadSpecific(&gHooksSystrace);
    } else if (sEGLTraceLevel > 0) {
        setGlTraceThreadSpecific(value);
        setGlThreadSpecific(&gHooksTrace);
    } else if (getEGLDebugLevel() > 0 && value != &gHooksNoContext) {
        setGlTraceThreadSpecific(value);
        setGlThreadSpecific(GLTrace_getGLHooks());
    } else {
        setGlTraceThreadSpecific(NULL);
        setGlThreadSpecific(value);
    }
}

/*
 * Global entry point to allow applications to modify their own trace level.
 * The effective trace level is the max of this level and the value of debug.egl.trace.
 */
extern "C"
void setGLTraceLevel(int level) {
    sEGLApplicationTraceLevel = level;
}

/*
 * Global entry point to allow applications to modify their own debug level.
 * Debugging is enabled if either the application requested it, or if the system property
 * matches the application's name.
 * Note that this only sets the debug level. The value is read and used either in
 * initEglDebugLevel() if the application hasn't initialized its display yet, or when
 * eglSwapBuffers() is called next.
 */
void EGLAPI setGLDebugLevel(int level) {
    setEGLDebugLevel(level);
}

#else

void setGLHooksThreadSpecific(gl_hooks_t const *value) {
    setGlThreadSpecific(value);
}

#endif

/*****************************************************************************/

static int gl_no_context() {
    if (egl_tls_t::logNoContextCall()) {
        char const* const error = "call to OpenGL ES API with "
                "no current context (logged once per thread)";
        if (LOG_NDEBUG) {
            ALOGE(error);
        } else {
            LOG_ALWAYS_FATAL(error);
        }
        char value[PROPERTY_VALUE_MAX];
        property_get("debug.egl.callstack", value, "0");
        if (atoi(value)) {
            CallStack stack(LOG_TAG);
        }
    }
    return 0;
}

static void early_egl_init(void)
{
#if EGL_TRACE
    pthread_key_create(&gGLTraceKey, NULL);
    initEglTraceLevel();
#endif
    int numHooks = sizeof(gHooksNoContext) / sizeof(EGLFuncPointer);
    EGLFuncPointer *iter = reinterpret_cast<EGLFuncPointer*>(&gHooksNoContext);
    for (int hook = 0; hook < numHooks; ++hook) {
        *(iter++) = reinterpret_cast<EGLFuncPointer>(gl_no_context);
    }

    setGLHooksThreadSpecific(&gHooksNoContext);
}

static pthread_once_t once_control = PTHREAD_ONCE_INIT;
static int sEarlyInitState = pthread_once(&once_control, &early_egl_init);

// ----------------------------------------------------------------------------

egl_display_ptr validate_display(EGLDisplay dpy) {
    egl_display_ptr dp = get_display(dpy);
    if (!dp)
        return setError(EGL_BAD_DISPLAY, egl_display_ptr(NULL));
    if (!dp->isReady())
        return setError(EGL_NOT_INITIALIZED, egl_display_ptr(NULL));

    return dp;
}

egl_display_ptr validate_display_connection(EGLDisplay dpy,
        egl_connection_t*& cnx) {
    cnx = NULL;
    egl_display_ptr dp = validate_display(dpy);
    if (!dp)
        return dp;
    cnx = &gEGLImpl;
    if (cnx->dso == 0) {
        return setError(EGL_BAD_CONFIG, egl_display_ptr(NULL));
    }
    return dp;
}

// ----------------------------------------------------------------------------

const GLubyte * egl_get_string_for_current_context(GLenum name) {
    // NOTE: returning NULL here will fall-back to the default
    // implementation.

    EGLContext context = egl_tls_t::getContext();
    if (context == EGL_NO_CONTEXT)
        return NULL;

    egl_context_t const * const c = get_context(context);
    if (c == NULL) // this should never happen, by construction
        return NULL;

    if (name != GL_EXTENSIONS)
        return NULL;

    return (const GLubyte *)c->gl_extensions.string();
}

const GLubyte * egl_get_string_for_current_context(GLenum name, GLuint index) {
    // NOTE: returning NULL here will fall-back to the default
    // implementation.

    EGLContext context = egl_tls_t::getContext();
    if (context == EGL_NO_CONTEXT)
        return NULL;

    egl_context_t const * const c = get_context(context);
    if (c == NULL) // this should never happen, by construction
        return NULL;

    if (name != GL_EXTENSIONS)
        return NULL;

    // if index is out of bounds, assume it will be in the default
    // implementation too, so we don't have to generate a GL error here
    if (index >= c->tokenized_gl_extensions.size())
        return NULL;

    return (const GLubyte *)c->tokenized_gl_extensions.itemAt(index).string();
}

GLint egl_get_num_extensions_for_current_context() {
    // NOTE: returning -1 here will fall-back to the default
    // implementation.

    EGLContext context = egl_tls_t::getContext();
    if (context == EGL_NO_CONTEXT)
        return -1;

    egl_context_t const * const c = get_context(context);
    if (c == NULL) // this should never happen, by construction
        return -1;

    return (GLint)c->tokenized_gl_extensions.size();
}

// ----------------------------------------------------------------------------

// this mutex protects:
//    d->disp[]
//    egl_init_drivers_locked()
//
static EGLBoolean egl_init_drivers_locked() {
    if (sEarlyInitState) {
        // initialized by static ctor. should be set here.
        return EGL_FALSE;
    }

    // get our driver loader
    Loader& loader(Loader::getInstance());

    // dynamically load our EGL implementation
    egl_connection_t* cnx = &gEGLImpl;
    if (cnx->dso == 0) {
        cnx->hooks[egl_connection_t::GLESv1_INDEX] =
                &gHooks[egl_connection_t::GLESv1_INDEX];
        cnx->hooks[egl_connection_t::GLESv2_INDEX] =
                &gHooks[egl_connection_t::GLESv2_INDEX];
        cnx->dso = loader.open(cnx);
    }

    return cnx->dso ? EGL_TRUE : EGL_FALSE;
}

static pthread_mutex_t sInitDriverMutex = PTHREAD_MUTEX_INITIALIZER;

EGLBoolean egl_init_drivers() {
    EGLBoolean res;
    pthread_mutex_lock(&sInitDriverMutex);
    res = egl_init_drivers_locked();
    pthread_mutex_unlock(&sInitDriverMutex);
    return res;
}

static pthread_mutex_t sLogPrintMutex = PTHREAD_MUTEX_INITIALIZER;
static nsecs_t sLogPrintTime = 0;
#define NSECS_DURATION 1000000000

void gl_unimplemented() {
    bool printLog = false;
    nsecs_t now = systemTime();
    pthread_mutex_lock(&sLogPrintMutex);
    if ((now - sLogPrintTime) > NSECS_DURATION) {
        sLogPrintTime = now;
        printLog = true;
    }
    pthread_mutex_unlock(&sLogPrintMutex);
    if (printLog) {
        ALOGE("called unimplemented OpenGL ES API");
        char value[PROPERTY_VALUE_MAX];
        property_get("debug.egl.callstack", value, "0");
        if (atoi(value)) {
            CallStack stack(LOG_TAG);
        }
    }
}

void gl_noop() {
}

// ----------------------------------------------------------------------------

void setGlThreadSpecific(gl_hooks_t const *value) {
    gl_hooks_t const * volatile * tls_hooks = get_tls_hooks();
    tls_hooks[TLS_SLOT_OPENGL_API] = value;
}

// ----------------------------------------------------------------------------
// GL / EGL hooks
// ----------------------------------------------------------------------------

#undef GL_ENTRY
#undef EGL_ENTRY
#define GL_ENTRY(_r, _api, ...) #_api,
#define EGL_ENTRY(_r, _api, ...) #_api,

char const * const gl_names[] = {
    #include "../entries.in"
    NULL
};

char const * const egl_names[] = {
    #include "egl_entries.in"
    NULL
};

#undef GL_ENTRY
#undef EGL_ENTRY


// ----------------------------------------------------------------------------
}; // namespace android
// ----------------------------------------------------------------------------

