Blame src/EGL/libeglerror.c

Packit Service 9e77c8
/*
Packit Service 9e77c8
 * Copyright (c) 2016, NVIDIA CORPORATION.
Packit Service 9e77c8
 *
Packit Service 9e77c8
 * Permission is hereby granted, free of charge, to any person obtaining a
Packit Service 9e77c8
 * copy of this software and/or associated documentation files (the
Packit Service 9e77c8
 * "Materials"), to deal in the Materials without restriction, including
Packit Service 9e77c8
 * without limitation the rights to use, copy, modify, merge, publish,
Packit Service 9e77c8
 * distribute, sublicense, and/or sell copies of the Materials, and to
Packit Service 9e77c8
 * permit persons to whom the Materials are furnished to do so, subject to
Packit Service 9e77c8
 * the following conditions:
Packit Service 9e77c8
 *
Packit Service 9e77c8
 * The above copyright notice and this permission notice shall be included
Packit Service 9e77c8
 * unaltered in all copies or substantial portions of the Materials.
Packit Service 9e77c8
 * Any additions, deletions, or changes to the original source files
Packit Service 9e77c8
 * must be clearly indicated in accompanying documentation.
Packit Service 9e77c8
 *
Packit Service 9e77c8
 * If only executable code is distributed, then the accompanying
Packit Service 9e77c8
 * documentation must state that "this software is based in part on the
Packit Service 9e77c8
 * work of the Khronos Group."
Packit Service 9e77c8
 *
Packit Service 9e77c8
 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Packit Service 9e77c8
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Packit Service 9e77c8
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Packit Service 9e77c8
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
Packit Service 9e77c8
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
Packit Service 9e77c8
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
Packit Service 9e77c8
 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
Packit Service 9e77c8
 */
Packit Service 9e77c8
Packit Service 9e77c8
#include "libeglerror.h"
Packit Service 9e77c8
Packit Service 9e77c8
#include <string.h>
Packit Service 9e77c8
#include <assert.h>
Packit Service 9e77c8
Packit Service 9e77c8
#include <EGL/egl.h>
Packit Service 9e77c8
#include <EGL/eglext.h>
Packit Service 9e77c8
Packit Service 9e77c8
#include "glvnd_pthread.h"
Packit Service 9e77c8
#include "libeglmapping.h"
Packit Service 9e77c8
#include "libeglcurrent.h"
Packit Service 9e77c8
#include "utils_misc.h"
Packit Service 9e77c8
Packit Service 9e77c8
enum
Packit Service 9e77c8
{
Packit Service 9e77c8
    __EGL_DEBUG_BIT_CRITICAL = 0x1,
Packit Service 9e77c8
    __EGL_DEBUG_BIT_ERROR = 0x2,
Packit Service 9e77c8
    __EGL_DEBUG_BIT_WARN = 0x4,
Packit Service 9e77c8
    __EGL_DEBUG_BIT_INFO = 0x8,
Packit Service 9e77c8
};
Packit Service 9e77c8
Packit Service 9e77c8
static inline unsigned int DebugBitFromType(GLenum type);
Packit Service 9e77c8
Packit Service 9e77c8
static EGLDEBUGPROCKHR debugCallback = NULL;
Packit Service 9e77c8
static unsigned int debugTypeEnabled = __EGL_DEBUG_BIT_CRITICAL | __EGL_DEBUG_BIT_ERROR;
Packit Service 9e77c8
static glvnd_rwlock_t debugLock = GLVND_RWLOCK_INITIALIZER;
Packit Service 9e77c8
Packit Service 9e77c8
static inline unsigned int DebugBitFromType(EGLenum type)
Packit Service 9e77c8
{
Packit Service 9e77c8
    assert(type >= EGL_DEBUG_MSG_CRITICAL_KHR &&
Packit Service 9e77c8
            type <= EGL_DEBUG_MSG_INFO_KHR);
Packit Service 9e77c8
    return (1 << (type - EGL_DEBUG_MSG_CRITICAL_KHR));
Packit Service 9e77c8
}
Packit Service 9e77c8
Packit Service 9e77c8
EGLint eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback,
Packit Service 9e77c8
        const EGLAttrib *attrib_list)
Packit Service 9e77c8
{
Packit Service 9e77c8
    unsigned int newEnabled = debugTypeEnabled;
Packit Service 9e77c8
    struct glvnd_list *vendorList;
Packit Service 9e77c8
    __EGLvendorInfo *vendor;
Packit Service 9e77c8
    int i;
Packit Service 9e77c8
Packit Service 9e77c8
    __eglEntrypointCommon();
Packit Service 9e77c8
Packit Service 9e77c8
    // Parse the attribute list. Note that if (callback != NULL), then we'll
Packit Service 9e77c8
    // check for errors even though we otherwise ignore it.
Packit Service 9e77c8
    if (attrib_list != NULL) {
Packit Service 9e77c8
        for (i = 0; attrib_list[i] != EGL_NONE; i += 2) {
Packit Service 9e77c8
            if (attrib_list[i] >= EGL_DEBUG_MSG_CRITICAL_KHR &&
Packit Service 9e77c8
                    attrib_list[i] <= EGL_DEBUG_MSG_INFO_KHR) {
Packit Service 9e77c8
                if (attrib_list[i + 1]) {
Packit Service 9e77c8
                    newEnabled |= DebugBitFromType(attrib_list[i]);
Packit Service 9e77c8
                } else {
Packit Service 9e77c8
                    newEnabled &= ~DebugBitFromType(attrib_list[i]);
Packit Service 9e77c8
                }
Packit Service 9e77c8
            } else {
Packit Service 9e77c8
                // On error, set the last error code, call the current
Packit Service 9e77c8
                // debug callback, and return the error code.
Packit Service 9e77c8
                __eglReportError(EGL_BAD_ATTRIBUTE, "eglDebugMessageControlKHR", NULL,
Packit Service 9e77c8
                        "Invalid attribute 0x%04lx", (unsigned long) attrib_list[i]);
Packit Service 9e77c8
                return EGL_BAD_ATTRIBUTE;
Packit Service 9e77c8
            }
Packit Service 9e77c8
        }
Packit Service 9e77c8
    }
Packit Service 9e77c8
Packit Service 9e77c8
    __glvndPthreadFuncs.rwlock_wrlock(&debugLock);
Packit Service 9e77c8
Packit Service 9e77c8
    if (callback != NULL) {
Packit Service 9e77c8
        debugCallback = callback;
Packit Service 9e77c8
        debugTypeEnabled = newEnabled;
Packit Service 9e77c8
    } else {
Packit Service 9e77c8
        debugCallback = NULL;
Packit Service 9e77c8
        debugTypeEnabled = __EGL_DEBUG_BIT_CRITICAL | __EGL_DEBUG_BIT_ERROR;
Packit Service 9e77c8
    }
Packit Service 9e77c8
Packit Service 9e77c8
    // Call into each vendor library.
Packit Service 9e77c8
    vendorList = __eglLoadVendors();
Packit Service 9e77c8
    glvnd_list_for_each_entry(vendor, vendorList, entry) {
Packit Service 9e77c8
        if (vendor->staticDispatch.debugMessageControlKHR != NULL) {
Packit Service 9e77c8
            EGLint result = vendor->staticDispatch.debugMessageControlKHR(callback, attrib_list);
Packit Service 9e77c8
            if (result != EGL_SUCCESS && (debugTypeEnabled & __EGL_DEBUG_BIT_WARN) && callback != NULL) {
Packit Service 9e77c8
                char buf[200];
Packit Service 9e77c8
                snprintf(buf, sizeof(buf), "eglDebugMessageControlKHR failed in vendor library with error 0x%04x. Error reporting may not work correctly.", result);
Packit Service 9e77c8
                callback(EGL_SUCCESS, "eglDebugMessageControlKHR", EGL_DEBUG_MSG_WARN_KHR,
Packit Service 9e77c8
                        __eglGetThreadLabel(), NULL, buf);
Packit Service 9e77c8
            }
Packit Service 9e77c8
        } else if ((debugTypeEnabled & __EGL_DEBUG_BIT_WARN) && callback != NULL) {
Packit Service 9e77c8
            callback(EGL_SUCCESS, "eglDebugMessageControlKHR", EGL_DEBUG_MSG_WARN_KHR,
Packit Service 9e77c8
                    __eglGetThreadLabel(), NULL,
Packit Service 9e77c8
                    "eglDebugMessageControlKHR is not supported by vendor library. Error reporting may not work correctly.");
Packit Service 9e77c8
        }
Packit Service 9e77c8
    }
Packit Service 9e77c8
Packit Service 9e77c8
    __glvndPthreadFuncs.rwlock_unlock(&debugLock);
Packit Service 9e77c8
    return EGL_SUCCESS;
Packit Service 9e77c8
}
Packit Service 9e77c8
Packit Service 9e77c8
EGLBoolean eglQueryDebugKHR(EGLint attribute, EGLAttrib *value)
Packit Service 9e77c8
{
Packit Service 9e77c8
    __eglEntrypointCommon();
Packit Service 9e77c8
Packit Service 9e77c8
    __glvndPthreadFuncs.rwlock_rdlock(&debugLock);
Packit Service 9e77c8
    if (attribute >= EGL_DEBUG_MSG_CRITICAL_KHR &&
Packit Service 9e77c8
            attribute <= EGL_DEBUG_MSG_INFO_KHR) {
Packit Service 9e77c8
        if (debugTypeEnabled & DebugBitFromType(attribute)) {
Packit Service 9e77c8
            *value = EGL_TRUE;
Packit Service 9e77c8
        } else {
Packit Service 9e77c8
            *value = EGL_FALSE;
Packit Service 9e77c8
        }
Packit Service 9e77c8
    } else if (attribute == EGL_DEBUG_CALLBACK_KHR) {
Packit Service 9e77c8
        *value = (EGLAttrib) debugCallback;
Packit Service 9e77c8
    } else {
Packit Service 9e77c8
        __glvndPthreadFuncs.rwlock_unlock(&debugLock);
Packit Service 9e77c8
        __eglReportError(EGL_BAD_ATTRIBUTE, "eglQueryDebugKHR", NULL,
Packit Service 9e77c8
                "Invalid attribute 0x%04lx", (unsigned long) attribute);
Packit Service 9e77c8
        return EGL_FALSE;
Packit Service 9e77c8
    }
Packit Service 9e77c8
    __glvndPthreadFuncs.rwlock_unlock(&debugLock);
Packit Service 9e77c8
    return EGL_TRUE;
Packit Service 9e77c8
}
Packit Service 9e77c8
Packit Service 9e77c8
EGLint eglLabelObjectKHR(
Packit Service 9e77c8
        EGLDisplay display,
Packit Service 9e77c8
        EGLenum objectType,
Packit Service 9e77c8
        EGLObjectKHR object,
Packit Service 9e77c8
        EGLLabelKHR label)
Packit Service 9e77c8
{
Packit Service 9e77c8
    __eglEntrypointCommon();
Packit Service 9e77c8
Packit Service 9e77c8
    if (objectType == EGL_OBJECT_THREAD_KHR) {
Packit Service 9e77c8
        struct glvnd_list *vendorList;
Packit Service 9e77c8
        __EGLThreadAPIState *state = __eglGetCurrentThreadAPIState(label != NULL);
Packit Service 9e77c8
        __EGLvendorInfo *vendor;
Packit Service 9e77c8
Packit Service 9e77c8
        if (state != NULL) {
Packit Service 9e77c8
            if (state->label == label) {
Packit Service 9e77c8
                return EGL_SUCCESS;
Packit Service 9e77c8
            }
Packit Service 9e77c8
            state->label = label;
Packit Service 9e77c8
        } else {
Packit Service 9e77c8
            if (label == NULL) {
Packit Service 9e77c8
                return EGL_SUCCESS;
Packit Service 9e77c8
            }
Packit Service 9e77c8
        }
Packit Service 9e77c8
Packit Service 9e77c8
        vendorList = __eglLoadVendors();
Packit Service 9e77c8
        glvnd_list_for_each_entry(vendor, vendorList, entry) {
Packit Service 9e77c8
            if (vendor->staticDispatch.labelObjectKHR != NULL) {
Packit Service 9e77c8
                EGLint result = vendor->staticDispatch.labelObjectKHR(NULL, objectType, NULL, label);
Packit Service 9e77c8
                if (result != EGL_SUCCESS) {
Packit Service 9e77c8
                    __eglReportWarn("eglLabelObjectKHR", NULL,
Packit Service 9e77c8
                            "eglLabelObjectKHR failed in vendor library with error 0x%04x. Thread label may not be reported correctly.",
Packit Service 9e77c8
                            result);
Packit Service 9e77c8
                }
Packit Service 9e77c8
            } else {
Packit Service 9e77c8
                __eglReportWarn("eglLabelObjectKHR", NULL,
Packit Service 9e77c8
                        "eglLabelObjectKHR is not supported by vendor library. Thread label may not be reported correctly.");
Packit Service 9e77c8
            }
Packit Service 9e77c8
        }
Packit Service 9e77c8
        return EGL_SUCCESS;
Packit Service 9e77c8
    } else {
Packit Service 9e77c8
        __EGLdisplayInfo *dpyInfo = __eglLookupDisplay(display);
Packit Service 9e77c8
        if (dpyInfo == NULL) {
Packit Service 9e77c8
            __eglReportError(EGL_BAD_DISPLAY, "eglLabelObjectKHR", NULL,
Packit Service 9e77c8
                    "Invalid display %p", display);
Packit Service 9e77c8
            return EGL_BAD_DISPLAY;
Packit Service 9e77c8
        }
Packit Service 9e77c8
Packit Service 9e77c8
        if (objectType == EGL_OBJECT_DISPLAY_KHR) {
Packit Service 9e77c8
            if (display != (EGLDisplay) object) {
Packit Service 9e77c8
                __eglReportError(EGL_BAD_PARAMETER, "eglLabelObjectKHR", NULL,
Packit Service 9e77c8
                        "Display %p and object %p do not match", display, object);
Packit Service 9e77c8
                return EGL_BAD_PARAMETER;
Packit Service 9e77c8
            }
Packit Service 9e77c8
        }
Packit Service 9e77c8
Packit Service 9e77c8
        if (dpyInfo->vendor->staticDispatch.labelObjectKHR != NULL) {
Packit Service 9e77c8
            __eglSetLastVendor(dpyInfo->vendor);
Packit Service 9e77c8
            return dpyInfo->vendor->staticDispatch.labelObjectKHR(display, objectType, object, label);
Packit Service 9e77c8
        } else {
Packit Service 9e77c8
            __eglReportError(EGL_BAD_PARAMETER, "eglLabelObjectKHR", NULL,
Packit Service 9e77c8
                    "eglLabelObjectKHR is not supported by vendor library. Object label may not be reported correctly.");
Packit Service 9e77c8
            return EGL_BAD_PARAMETER;
Packit Service 9e77c8
        }
Packit Service 9e77c8
    }
Packit Service 9e77c8
}
Packit Service 9e77c8
Packit Service 9e77c8
EGLLabelKHR __eglGetThreadLabel(void)
Packit Service 9e77c8
{
Packit Service 9e77c8
    __EGLThreadAPIState *state = __eglGetCurrentThreadAPIState(EGL_FALSE);
Packit Service 9e77c8
    if (state != NULL) {
Packit Service 9e77c8
        return state->label;
Packit Service 9e77c8
    } else {
Packit Service 9e77c8
        return NULL;
Packit Service 9e77c8
    }
Packit Service 9e77c8
}
Packit Service 9e77c8
Packit Service 9e77c8
void __eglDebugReport(EGLenum error, const char *command, EGLint type, EGLLabelKHR objectLabel, const char *message, ...)
Packit Service 9e77c8
{
Packit Service 9e77c8
    EGLDEBUGPROCKHR callback = NULL;
Packit Service 9e77c8
Packit Service 9e77c8
    __glvndPthreadFuncs.rwlock_rdlock(&debugLock);
Packit Service 9e77c8
    if (debugTypeEnabled & DebugBitFromType(type)) {
Packit Service 9e77c8
        callback = debugCallback;
Packit Service 9e77c8
    }
Packit Service 9e77c8
    __glvndPthreadFuncs.rwlock_unlock(&debugLock);
Packit Service 9e77c8
Packit Service 9e77c8
    if (callback != NULL) {
Packit Service 9e77c8
        char *buf = NULL;
Packit Service 9e77c8
Packit Service 9e77c8
        if (message != NULL) {
Packit Service 9e77c8
            va_list args;
Packit Service 9e77c8
            va_start(args, message);
Packit Service 9e77c8
            if (glvnd_vasprintf(&buf, message, args) < 0) {
Packit Service 9e77c8
                buf = NULL;
Packit Service 9e77c8
            }
Packit Service 9e77c8
            va_end(args);
Packit Service 9e77c8
        }
Packit Service 9e77c8
        callback(error, command, type, __eglGetThreadLabel(),
Packit Service 9e77c8
                objectLabel, buf);
Packit Service 9e77c8
        free(buf);
Packit Service 9e77c8
    }
Packit Service 9e77c8
Packit Service 9e77c8
    if (type == EGL_DEBUG_MSG_CRITICAL_KHR || type == EGL_DEBUG_MSG_ERROR_KHR) {
Packit Service 9e77c8
        __eglSetError(error);
Packit Service 9e77c8
    }
Packit Service 9e77c8
}
Packit Service 9e77c8