Blame src/wayland-eglhandle.c

Packit Service f6fdc3
/*
Packit Service f6fdc3
 * Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved.
Packit Service f6fdc3
 *
Packit Service f6fdc3
 * Permission is hereby granted, free of charge, to any person obtaining a
Packit Service f6fdc3
 * copy of this software and associated documentation files (the "Software"),
Packit Service f6fdc3
 * to deal in the Software without restriction, including without limitation
Packit Service f6fdc3
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
Packit Service f6fdc3
 * and/or sell copies of the Software, and to permit persons to whom the
Packit Service f6fdc3
 * Software is furnished to do so, subject to the following conditions:
Packit Service f6fdc3
 *
Packit Service f6fdc3
 * The above copyright notice and this permission notice shall be included in
Packit Service f6fdc3
 * all copies or substantial portions of the Software.
Packit Service f6fdc3
 *
Packit Service f6fdc3
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Packit Service f6fdc3
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Packit Service f6fdc3
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
Packit Service f6fdc3
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Packit Service f6fdc3
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
Packit Service f6fdc3
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
Packit Service f6fdc3
 * DEALINGS IN THE SOFTWARE.
Packit Service f6fdc3
 */
Packit Service f6fdc3
Packit Service f6fdc3
#include "wayland-eglhandle.h"
Packit Service f6fdc3
#include "wayland-egldisplay.h"
Packit Service f6fdc3
#include "wayland-eglsurface.h"
Packit Service f6fdc3
#include "wayland-thread.h"
Packit Service f6fdc3
#include <stdlib.h>
Packit Service f6fdc3
#include <errno.h>
Packit Service f6fdc3
#include <assert.h>
Packit Service f6fdc3
Packit Service f6fdc3
WlEglPlatformData*
Packit Service f6fdc3
wlEglCreatePlatformData(int apiMajor, int apiMinor, const EGLExtDriver *driver)
Packit Service f6fdc3
{
Packit Service f6fdc3
    const char        *exts = NULL;
Packit Service f6fdc3
    WlEglPlatformData *res  = NULL;
Packit Service f6fdc3
Packit Service f6fdc3
    assert((driver != NULL) && (driver->getProcAddress != NULL));
Packit Service f6fdc3
Packit Service f6fdc3
    /* Allocate platform data and fetch EGL functions */
Packit Service f6fdc3
    res = calloc(1, sizeof(WlEglPlatformData));
Packit Service f6fdc3
    if (res == NULL) {
Packit Service f6fdc3
        return NULL;
Packit Service f6fdc3
    }
Packit Service f6fdc3
Packit Service f6fdc3
    wl_list_init(&res->deviceDpyList);
Packit Service f6fdc3
Packit Service f6fdc3
    /* Cache the EGL driver version */
Packit Service f6fdc3
#if EGL_EXTERNAL_PLATFORM_HAS(DRIVER_VERSION)
Packit Service f6fdc3
    if (EGL_EXTERNAL_PLATFORM_SUPPORTS(apiMajor, apiMinor, DRIVER_VERSION)) {
Packit Service f6fdc3
        res->egl.major = driver->major;
Packit Service f6fdc3
        res->egl.minor = driver->minor;
Packit Service f6fdc3
    }
Packit Service f6fdc3
#endif
Packit Service f6fdc3
Packit Service f6fdc3
    /* Fetch all required driver functions */
Packit Service f6fdc3
#define GET_PROC(_FIELD_, _NAME_)                           \
Packit Service f6fdc3
    do {                                                    \
Packit Service f6fdc3
        res->egl._FIELD_ = driver->getProcAddress(#_NAME_); \
Packit Service f6fdc3
        if (res->egl._FIELD_ == NULL) {                     \
Packit Service f6fdc3
            goto fail;                                      \
Packit Service f6fdc3
        }                                                   \
Packit Service f6fdc3
    } while (0)
Packit Service f6fdc3
Packit Service f6fdc3
    /* Core and basic stream functionality */
Packit Service f6fdc3
    GET_PROC(queryString,                 eglQueryString);
Packit Service f6fdc3
    GET_PROC(queryDevices,                eglQueryDevicesEXT);
Packit Service f6fdc3
Packit Service f6fdc3
    /* TODO: use eglGetPlatformDisplay instead of eglGetPlatformDisplayEXT
Packit Service f6fdc3
             if EGL 1.5 is available                                      */
Packit Service f6fdc3
    GET_PROC(getPlatformDisplay,          eglGetPlatformDisplayEXT);
Packit Service f6fdc3
    GET_PROC(initialize,                  eglInitialize);
Packit Service f6fdc3
    GET_PROC(terminate,                   eglTerminate);
Packit Service f6fdc3
    GET_PROC(chooseConfig,                eglChooseConfig);
Packit Service f6fdc3
    GET_PROC(getConfigAttrib,             eglGetConfigAttrib);
Packit Service f6fdc3
Packit Service f6fdc3
    GET_PROC(getCurrentContext,           eglGetCurrentContext);
Packit Service f6fdc3
    GET_PROC(getCurrentSurface,           eglGetCurrentSurface);
Packit Service f6fdc3
    GET_PROC(makeCurrent,                 eglMakeCurrent);
Packit Service f6fdc3
Packit Service f6fdc3
    GET_PROC(createStream,                eglCreateStreamKHR);
Packit Service f6fdc3
    GET_PROC(createStreamFromFD,          eglCreateStreamFromFileDescriptorKHR);
Packit Service f6fdc3
    GET_PROC(createStreamAttrib,          eglCreateStreamAttribNV);
Packit Service f6fdc3
    GET_PROC(getStreamFileDescriptor,     eglGetStreamFileDescriptorKHR);
Packit Service f6fdc3
    GET_PROC(createStreamProducerSurface, eglCreateStreamProducerSurfaceKHR);
Packit Service f6fdc3
    GET_PROC(createPbufferSurface,        eglCreatePbufferSurface);
Packit Service f6fdc3
    GET_PROC(destroyStream,               eglDestroyStreamKHR);
Packit Service f6fdc3
    GET_PROC(destroySurface,              eglDestroySurface);
Packit Service f6fdc3
Packit Service f6fdc3
    GET_PROC(swapBuffers,                 eglSwapBuffers);
Packit Service f6fdc3
    GET_PROC(swapBuffersWithDamage,       eglSwapBuffersWithDamageKHR);
Packit Service f6fdc3
    GET_PROC(swapInterval,                eglSwapInterval);
Packit Service f6fdc3
Packit Service f6fdc3
    GET_PROC(getError,                    eglGetError);
Packit Service f6fdc3
    GET_PROC(releaseThread,               eglReleaseThread);
Packit Service f6fdc3
Packit Service f6fdc3
#undef GET_PROC
Packit Service f6fdc3
Packit Service f6fdc3
    /* Fetch all optional driver functions */
Packit Service f6fdc3
#define GET_PROC(_FIELD_, _NAME_) \
Packit Service f6fdc3
    res->egl._FIELD_ = driver->getProcAddress(#_NAME_)
Packit Service f6fdc3
Packit Service f6fdc3
    /* Used by damage thread */
Packit Service f6fdc3
    GET_PROC(queryStream,                 eglQueryStreamKHR);
Packit Service f6fdc3
    GET_PROC(queryStreamu64,              eglQueryStreamu64KHR);
Packit Service f6fdc3
    GET_PROC(createStreamSync,            eglCreateStreamSyncNV);
Packit Service f6fdc3
    GET_PROC(clientWaitSync,              eglClientWaitSyncKHR);
Packit Service f6fdc3
    GET_PROC(signalSync,                  eglSignalSyncKHR);
Packit Service f6fdc3
    GET_PROC(destroySync,                 eglDestroySyncKHR);
Packit Service f6fdc3
Packit Service f6fdc3
    /* Stream flush */
Packit Service f6fdc3
    GET_PROC(streamFlush,                 eglStreamFlushNV);
Packit Service f6fdc3
Packit Service f6fdc3
    GET_PROC(queryDisplayAttrib,          eglQueryDisplayAttribKHR);
Packit Service f6fdc3
Packit Service f6fdc3
#undef GET_PROC
Packit Service f6fdc3
Packit Service f6fdc3
    /* Check for required EGL client extensions */
Packit Service f6fdc3
    exts = res->egl.queryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
Packit Service f6fdc3
    if (exts == NULL) {
Packit Service f6fdc3
        goto fail;
Packit Service f6fdc3
    }
Packit Service f6fdc3
    if (!wlEglFindExtension("EGL_EXT_platform_base",   exts) ||
Packit Service f6fdc3
        !wlEglFindExtension("EGL_EXT_platform_device", exts)) {
Packit Service f6fdc3
        goto fail;
Packit Service f6fdc3
    }
Packit Service f6fdc3
    res->supportsDisplayReference = wlEglFindExtension("EGL_KHR_display_reference", exts);
Packit Service f6fdc3
Packit Service f6fdc3
    /* Cache driver imports */
Packit Service f6fdc3
    res->callbacks.setError           = driver->setError;
Packit Service f6fdc3
    res->callbacks.streamSwapInterval = driver->streamSwapInterval;
Packit Service f6fdc3
Packit Service f6fdc3
    return res;
Packit Service f6fdc3
Packit Service f6fdc3
fail:
Packit Service f6fdc3
    free(res);
Packit Service f6fdc3
    return NULL;
Packit Service f6fdc3
}
Packit Service f6fdc3
Packit Service f6fdc3
void wlEglDestroyPlatformData(WlEglPlatformData *data)
Packit Service f6fdc3
{
Packit Service f6fdc3
    free(data);
Packit Service f6fdc3
}
Packit Service f6fdc3
Packit Service f6fdc3
void* wlEglGetInternalHandleExport(EGLDisplay dpy, EGLenum type, void *handle)
Packit Service f6fdc3
{
Packit Service f6fdc3
    wlExternalApiLock();
Packit Service f6fdc3
Packit Service f6fdc3
    if ((type == EGL_OBJECT_DISPLAY_KHR) &&
Packit Service f6fdc3
        wlEglIsWlEglDisplay((WlEglDisplay *)handle)) {
Packit Service f6fdc3
        handle = (void *)(((WlEglDisplay *)handle)->devDpy->eglDisplay);
Packit Service f6fdc3
    } else if ((type == EGL_OBJECT_SURFACE_KHR) &&
Packit Service f6fdc3
               wlEglIsWlEglSurface((WlEglSurface *)handle)) {
Packit Service f6fdc3
        WlEglSurface *surface = (WlEglSurface *)handle;
Packit Service f6fdc3
        if (dpy == surface->wlEglDpy) {
Packit Service f6fdc3
            handle = (void *)(surface->ctx.eglSurface);
Packit Service f6fdc3
        } else {
Packit Service f6fdc3
            handle = NULL;
Packit Service f6fdc3
        }
Packit Service f6fdc3
    }
Packit Service f6fdc3
Packit Service f6fdc3
    wlExternalApiUnlock();
Packit Service f6fdc3
Packit Service f6fdc3
    return handle;
Packit Service f6fdc3
}