Blame va/glx/va_glx.c

Packit 38d9dc
/*
Packit 38d9dc
 * Copyright (C) 2009 Splitted-Desktop Systems. All Rights Reserved.
Packit 38d9dc
 *
Packit 38d9dc
 * Permission is hereby granted, free of charge, to any person obtaining a
Packit 38d9dc
 * copy of this software and associated documentation files (the
Packit 38d9dc
 * "Software"), to deal in the Software without restriction, including
Packit 38d9dc
 * without limitation the rights to use, copy, modify, merge, publish,
Packit 38d9dc
 * distribute, sub license, and/or sell copies of the Software, and to
Packit 38d9dc
 * permit persons to whom the Software is furnished to do so, subject to
Packit 38d9dc
 * the following conditions:
Packit 38d9dc
 * 
Packit 38d9dc
 * The above copyright notice and this permission notice (including the
Packit 38d9dc
 * next paragraph) shall be included in all copies or substantial portions
Packit 38d9dc
 * of the Software.
Packit 38d9dc
 * 
Packit 38d9dc
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
Packit 38d9dc
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Packit 38d9dc
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
Packit 38d9dc
 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
Packit 38d9dc
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
Packit 38d9dc
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
Packit 38d9dc
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Packit 38d9dc
 */
Packit 38d9dc
Packit 38d9dc
#include "sysdeps.h"
Packit 38d9dc
#include <stdlib.h>
Packit 38d9dc
#include "va_glx_private.h"
Packit 38d9dc
#include "va_glx_impl.h"
Packit 38d9dc
Packit 38d9dc
#define INIT_CONTEXT(ctx, dpy) do {                             \
Packit 38d9dc
        if (!vaDisplayIsValid(dpy))                             \
Packit 38d9dc
            return VA_STATUS_ERROR_INVALID_DISPLAY;             \
Packit 38d9dc
                                                                \
Packit 38d9dc
        ctx = ((VADisplayContextP)(dpy))->pDriverContext;       \
Packit 38d9dc
        if (!(ctx))                                             \
Packit 38d9dc
            return VA_STATUS_ERROR_INVALID_DISPLAY;             \
Packit 38d9dc
                                                                \
Packit 38d9dc
        VAStatus status = va_glx_init_context(ctx);             \
Packit 38d9dc
        if (status != VA_STATUS_SUCCESS)                        \
Packit 38d9dc
            return status;                                      \
Packit 38d9dc
    } while (0)
Packit 38d9dc
Packit 38d9dc
#define INVOKE(ctx, func, args) do {                            \
Packit 38d9dc
        VADriverVTableGLXP vtable;                              \
Packit 38d9dc
        vtable = &VA_DRIVER_CONTEXT_GLX(ctx)->vtable;           \
Packit 38d9dc
        if (!vtable->va##func##GLX)                             \
Packit 38d9dc
            return VA_STATUS_ERROR_UNIMPLEMENTED;               \
Packit 38d9dc
        status = vtable->va##func##GLX args;                    \
Packit 38d9dc
    } while (0)
Packit 38d9dc
Packit 38d9dc
Packit 38d9dc
// Destroy VA/GLX display context
Packit 38d9dc
static void va_DisplayContextDestroy(VADisplayContextP pDisplayContext)
Packit 38d9dc
{
Packit 38d9dc
    VADisplayContextGLXP pDisplayContextGLX;
Packit 38d9dc
    VADriverContextP     pDriverContext;
Packit 38d9dc
    VADriverContextGLXP  pDriverContextGLX;
Packit 38d9dc
Packit 38d9dc
    if (!pDisplayContext)
Packit 38d9dc
        return;
Packit 38d9dc
Packit 38d9dc
    pDriverContext     = pDisplayContext->pDriverContext;
Packit 38d9dc
    pDriverContextGLX  = pDriverContext->glx;
Packit 38d9dc
    if (pDriverContextGLX) {
Packit 38d9dc
        free(pDriverContextGLX);
Packit 38d9dc
        pDriverContext->glx = NULL;
Packit 38d9dc
    }
Packit 38d9dc
Packit 38d9dc
    pDisplayContextGLX = pDisplayContext->opaque;
Packit 38d9dc
    if (pDisplayContextGLX) {
Packit 38d9dc
        vaDestroyFunc vaDestroy = pDisplayContextGLX->vaDestroy;
Packit 38d9dc
        free(pDisplayContextGLX);
Packit 38d9dc
        pDisplayContext->opaque = NULL;
Packit 38d9dc
        if (vaDestroy)
Packit 38d9dc
            vaDestroy(pDisplayContext);
Packit 38d9dc
    }
Packit 38d9dc
}
Packit 38d9dc
Packit 38d9dc
// Return a suitable VADisplay for VA API
Packit 38d9dc
VADisplay vaGetDisplayGLX(Display *native_dpy)
Packit 38d9dc
{
Packit 38d9dc
    VADisplay            dpy                = NULL;
Packit 38d9dc
    VADisplayContextP    pDisplayContext    = NULL;
Packit 38d9dc
    VADisplayContextGLXP pDisplayContextGLX = NULL;
Packit 38d9dc
    VADriverContextP     pDriverContext;
Packit 38d9dc
    VADriverContextGLXP  pDriverContextGLX  = NULL;
Packit 38d9dc
Packit 38d9dc
    dpy = vaGetDisplay(native_dpy);
Packit 38d9dc
    if (!dpy)
Packit 38d9dc
        return NULL;
Packit 38d9dc
    pDisplayContext = (VADisplayContextP)dpy;
Packit 38d9dc
    pDriverContext  = pDisplayContext->pDriverContext;
Packit 38d9dc
Packit 38d9dc
    pDisplayContextGLX = calloc(1, sizeof(*pDisplayContextGLX));
Packit 38d9dc
    if (!pDisplayContextGLX)
Packit 38d9dc
        goto error;
Packit 38d9dc
Packit 38d9dc
    pDriverContextGLX = calloc(1, sizeof(*pDriverContextGLX));
Packit 38d9dc
    if (!pDriverContextGLX)
Packit 38d9dc
        goto error;
Packit 38d9dc
Packit 38d9dc
    pDriverContext->display_type  = VA_DISPLAY_GLX;
Packit 38d9dc
    pDisplayContextGLX->vaDestroy = pDisplayContext->vaDestroy;
Packit 38d9dc
    pDisplayContext->vaDestroy    = va_DisplayContextDestroy;
Packit 38d9dc
    pDisplayContext->opaque       = pDisplayContextGLX;
Packit 38d9dc
    pDriverContext->glx           = pDriverContextGLX;
Packit 38d9dc
    return dpy;
Packit 38d9dc
Packit 38d9dc
error:
Packit 38d9dc
    free(pDriverContextGLX);
Packit 38d9dc
    free(pDisplayContextGLX);
Packit 38d9dc
    pDisplayContext->vaDestroy(pDisplayContext);
Packit 38d9dc
    return NULL;
Packit 38d9dc
}
Packit 38d9dc
Packit 38d9dc
// Create a surface used for display to OpenGL
Packit 38d9dc
VAStatus vaCreateSurfaceGLX(
Packit 38d9dc
    VADisplay dpy,
Packit 38d9dc
    GLenum    target,
Packit 38d9dc
    GLuint    texture,
Packit 38d9dc
    void    **gl_surface
Packit 38d9dc
)
Packit 38d9dc
{
Packit 38d9dc
    VADriverContextP ctx;
Packit 38d9dc
    VAStatus status;
Packit 38d9dc
Packit 38d9dc
    /* Make sure it is a valid GL texture object */
Packit 38d9dc
    if (!glIsTexture(texture))
Packit 38d9dc
        return VA_STATUS_ERROR_INVALID_PARAMETER;
Packit 38d9dc
Packit 38d9dc
    INIT_CONTEXT(ctx, dpy);
Packit 38d9dc
Packit 38d9dc
    INVOKE(ctx, CreateSurface, (ctx, target, texture, gl_surface));
Packit 38d9dc
    return status;
Packit 38d9dc
}
Packit 38d9dc
Packit 38d9dc
// Destroy a VA/GLX surface
Packit 38d9dc
VAStatus vaDestroySurfaceGLX(
Packit 38d9dc
    VADisplay dpy,
Packit 38d9dc
    void     *gl_surface
Packit 38d9dc
)
Packit 38d9dc
{
Packit 38d9dc
    VADriverContextP ctx;
Packit 38d9dc
    VAStatus status;
Packit 38d9dc
Packit 38d9dc
    INIT_CONTEXT(ctx, dpy);
Packit 38d9dc
Packit 38d9dc
    INVOKE(ctx, DestroySurface, (ctx, gl_surface));
Packit 38d9dc
    return status;
Packit 38d9dc
}
Packit 38d9dc
Packit 38d9dc
// Copy a VA surface to a VA/GLX surface
Packit 38d9dc
VAStatus vaCopySurfaceGLX(
Packit 38d9dc
    VADisplay    dpy,
Packit 38d9dc
    void        *gl_surface,
Packit 38d9dc
    VASurfaceID  surface,
Packit 38d9dc
    unsigned int flags
Packit 38d9dc
)
Packit 38d9dc
{
Packit 38d9dc
    VADriverContextP ctx;
Packit 38d9dc
    VAStatus status;
Packit 38d9dc
Packit 38d9dc
    INIT_CONTEXT(ctx, dpy);
Packit 38d9dc
Packit 38d9dc
    INVOKE(ctx, CopySurface, (ctx, gl_surface, surface, flags));
Packit 38d9dc
    return status;
Packit 38d9dc
}