/*
 * Copyright (C) 2009 Splitted-Desktop Systems. All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#define _GNU_SOURCE 1
#include "sysdeps.h"
#include "va_glx_private.h"
#include "va_glx_impl.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <assert.h>
#include <dlfcn.h>

static void va_glx_error_message(const char *format, ...)
{
    va_list args;
    va_start(args, format);
    fprintf(stderr, "libva-glx error: ");
    vfprintf(stderr, format, args);
    va_end(args);
}

// X error trap
static int x11_error_code = 0;
static int (*old_error_handler)(Display *, XErrorEvent *);

static int error_handler(Display *dpy, XErrorEvent *error)
{
    x11_error_code = error->error_code;
    return 0;
}

static void x11_trap_errors(void)
{
    x11_error_code    = 0;
    old_error_handler = XSetErrorHandler(error_handler);
}

static int x11_untrap_errors(void)
{
    XSetErrorHandler(old_error_handler);
    return x11_error_code;
}

// Returns a string representation of an OpenGL error
static const char *gl_get_error_string(GLenum error)
{
    static const struct {
        GLenum val;
        const char *str;
    }
    gl_errors[] = {
        { GL_NO_ERROR,          "no error" },
        { GL_INVALID_ENUM,      "invalid enumerant" },
        { GL_INVALID_VALUE,     "invalid value" },
        { GL_INVALID_OPERATION, "invalid operation" },
        { GL_STACK_OVERFLOW,    "stack overflow" },
        { GL_STACK_UNDERFLOW,   "stack underflow" },
        { GL_OUT_OF_MEMORY,     "out of memory" },
#ifdef GL_INVALID_FRAMEBUFFER_OPERATION_EXT
        { GL_INVALID_FRAMEBUFFER_OPERATION_EXT, "invalid framebuffer operation" },
#endif
        { ~0, NULL }
    };

    int i;
    for (i = 0; gl_errors[i].str; i++) {
        if (gl_errors[i].val == error)
            return gl_errors[i].str;
    }
    return "unknown";
}

static inline int gl_do_check_error(int report)
{
    GLenum error;
    int is_error = 0;
    while ((error = glGetError()) != GL_NO_ERROR) {
        if (report)
            va_glx_error_message("glError: %s caught\n",
                                 gl_get_error_string(error));
        is_error = 1;
    }
    return is_error;
}

static inline void gl_purge_errors(void)
{
    gl_do_check_error(0);
}

static inline int gl_check_error(void)
{
    return gl_do_check_error(1);
}

// glGetTexLevelParameteriv() wrapper
static int gl_get_texture_param(GLenum param, unsigned int *pval)
{
    GLint val;

    gl_purge_errors();
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, param, &val);
    if (gl_check_error())
        return 0;
    if (pval)
        *pval = val;
    return 1;
}

// Returns the OpenGL VTable
static inline VAOpenGLVTableP gl_get_vtable(VADriverContextP ctx)
{
    return &VA_DRIVER_CONTEXT_GLX(ctx)->gl_vtable;
}

// Lookup for a GLX function
typedef void (*GLFuncPtr)(void);
typedef GLFuncPtr (*GLXGetProcAddressProc)(const char *);

static GLFuncPtr get_proc_address_default(const char *name)
{
    return NULL;
}

static GLXGetProcAddressProc get_proc_address_func(void)
{
    GLXGetProcAddressProc get_proc_func;

    dlerror();
    get_proc_func = (GLXGetProcAddressProc)
        dlsym(RTLD_DEFAULT, "glXGetProcAddress");
    if (!dlerror())
        return get_proc_func;

    get_proc_func = (GLXGetProcAddressProc)
        dlsym(RTLD_DEFAULT, "glXGetProcAddressARB");
    if (!dlerror())
        return get_proc_func;

    return get_proc_address_default;
}

static inline GLFuncPtr get_proc_address(const char *name)
{
    static GLXGetProcAddressProc get_proc_func = NULL;
    if (!get_proc_func)
        get_proc_func = get_proc_address_func();
    return get_proc_func(name);
}

// Check for GLX extensions (TFP, FBO)
static int check_extension(const char *name, const char *ext)
{
    const char *end;
    int name_len, n;

    if (!name || !ext)
        return 0;

    end = ext + strlen(ext);
    name_len = strlen(name);
    while (ext < end) {
        n = strcspn(ext, " ");
        if (n == name_len && strncmp(name, ext, n) == 0)
            return 1;
        ext += (n + 1);
    }
    return 0;
}

static int check_extension3(const char *name)
{
    int nbExtensions, i;
    PFNGLGETSTRINGIPROC glGetStringi = 0;

    glGetStringi = (PFNGLGETSTRINGIPROC) get_proc_address("glGetStringi");
    if(!glGetStringi)
        return 0;


    glGetIntegerv(GL_NUM_EXTENSIONS, &nbExtensions);
    for(i = 0; i < nbExtensions; i++)
    {
        const GLubyte *strExtension = glGetStringi(GL_EXTENSIONS, i);
        if(strcmp((const char *) strExtension, name) == 0)
            return 1;
    }

    return 0;
}

static int check_tfp_extensions(VADriverContextP ctx)
{
    const char *gl_extensions;
    const char *glx_extensions;

    gl_extensions = (const char *)glGetString(GL_EXTENSIONS);
    if (!check_extension("GL_ARB_texture_non_power_of_two", gl_extensions) && !check_extension3("GL_ARB_texture_non_power_of_two"))
        return 0;

    glx_extensions = glXQueryExtensionsString(ctx->native_dpy, ctx->x11_screen);
    if (!check_extension("GLX_EXT_texture_from_pixmap", glx_extensions))
        return 0;

    return 1;
}

static int check_fbo_extensions(VADriverContextP ctx)
{
    const char *gl_extensions;

    gl_extensions = (const char *)glGetString(GL_EXTENSIONS);
    if (check_extension("GL_ARB_framebuffer_object", gl_extensions) || check_extension3("GL_ARB_framebuffer_object"))
        return 1;
    if (check_extension("GL_EXT_framebuffer_object", gl_extensions) || check_extension3("GL_EXT_framebuffer_object"))
        return 1;

    return 0;
}

// Load GLX extensions
static int load_tfp_extensions(VADriverContextP ctx)
{
    VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);

    pOpenGLVTable->glx_create_pixmap = (PFNGLXCREATEPIXMAPPROC)
        get_proc_address("glXCreatePixmap");
    if (!pOpenGLVTable->glx_create_pixmap)
        return 0;
    pOpenGLVTable->glx_destroy_pixmap = (PFNGLXDESTROYPIXMAPPROC)
        get_proc_address("glXDestroyPixmap");
    if (!pOpenGLVTable->glx_destroy_pixmap)
        return 0;
    pOpenGLVTable->glx_bind_tex_image = (PFNGLXBINDTEXIMAGEEXTPROC)
        get_proc_address("glXBindTexImageEXT");
    if (!pOpenGLVTable->glx_bind_tex_image)
        return 0;
    pOpenGLVTable->glx_release_tex_image = (PFNGLXRELEASETEXIMAGEEXTPROC)
        get_proc_address("glXReleaseTexImageEXT");
    if (!pOpenGLVTable->glx_release_tex_image)
        return 0;
    return 1;
}

static int load_fbo_extensions(VADriverContextP ctx)
{
    VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);

    pOpenGLVTable->gl_gen_framebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC)
        get_proc_address("glGenFramebuffersEXT");
    if (!pOpenGLVTable->gl_gen_framebuffers)
        return 0;
    pOpenGLVTable->gl_delete_framebuffers = (PFNGLDELETEFRAMEBUFFERSEXTPROC)
        get_proc_address("glDeleteFramebuffersEXT");
    if (!pOpenGLVTable->gl_delete_framebuffers)
        return 0;
    pOpenGLVTable->gl_bind_framebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC)
        get_proc_address("glBindFramebufferEXT");
    if (!pOpenGLVTable->gl_bind_framebuffer)
        return 0;
    pOpenGLVTable->gl_gen_renderbuffers = (PFNGLGENRENDERBUFFERSEXTPROC)
        get_proc_address("glGenRenderbuffersEXT");
    if (!pOpenGLVTable->gl_gen_renderbuffers)
        return 0;
    pOpenGLVTable->gl_delete_renderbuffers = (PFNGLDELETERENDERBUFFERSEXTPROC)
        get_proc_address("glDeleteRenderbuffersEXT");
    if (!pOpenGLVTable->gl_delete_renderbuffers)
        return 0;
    pOpenGLVTable->gl_bind_renderbuffer = (PFNGLBINDRENDERBUFFEREXTPROC)
        get_proc_address("glBindRenderbufferEXT");
    if (!pOpenGLVTable->gl_bind_renderbuffer)
        return 0;
    pOpenGLVTable->gl_renderbuffer_storage = (PFNGLRENDERBUFFERSTORAGEEXTPROC)
        get_proc_address("glRenderbufferStorageEXT");
    if (!pOpenGLVTable->gl_renderbuffer_storage)
        return 0;
    pOpenGLVTable->gl_framebuffer_renderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)
        get_proc_address("glFramebufferRenderbufferEXT");
    if (!pOpenGLVTable->gl_framebuffer_renderbuffer)
        return 0;
    pOpenGLVTable->gl_framebuffer_texture_2d = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)
        get_proc_address("glFramebufferTexture2DEXT");
    if (!pOpenGLVTable->gl_framebuffer_texture_2d)
        return 0;
    pOpenGLVTable->gl_check_framebuffer_status = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
        get_proc_address("glCheckFramebufferStatusEXT");
    if (!pOpenGLVTable->gl_check_framebuffer_status)
        return 0;
    return 1;
}


/* ========================================================================= */
/* === VA/GLX helpers                                                    === */
/* ========================================================================= */

// OpenGL context state
typedef struct OpenGLContextState *OpenGLContextStateP;

struct OpenGLContextState {
    Display     *display;
    Window       window;
    GLXContext   context;
};

static void
gl_destroy_context(OpenGLContextStateP cs)
{
    if (!cs)
        return;

    if (cs->display && cs->context) {
        if (glXGetCurrentContext() == cs->context)
            glXMakeCurrent(cs->display, None, NULL);
        glXDestroyContext(cs->display, cs->context);
        cs->display = NULL;
        cs->context = NULL;
    }
    free(cs);
}

static OpenGLContextStateP
gl_create_context(VADriverContextP ctx, OpenGLContextStateP parent)
{
    OpenGLContextStateP cs;
    GLXFBConfig *fbconfigs = NULL;
    int fbconfig_id, val, n, n_fbconfigs;
    Status status;

    static GLint fbconfig_attrs[] = {
        GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
        GLX_RENDER_TYPE,   GLX_RGBA_BIT,
        GLX_DOUBLEBUFFER,  True,
        GLX_RED_SIZE,      8,
        GLX_GREEN_SIZE,    8, 
        GLX_BLUE_SIZE,     8,
        None
    };

    cs = malloc(sizeof(*cs));
    if (!cs)
        goto error;

    if (parent) {
        cs->display = parent->display;
        cs->window  = parent->window;
    }
    else {
        cs->display = ctx->native_dpy;
        cs->window  = None;
    }
    cs->context = NULL;

    if (parent && parent->context) {
        status = glXQueryContext(
            parent->display,
            parent->context,
            GLX_FBCONFIG_ID, &fbconfig_id
        );
        if (status != Success)
            goto error;

        if (fbconfig_id == GLX_DONT_CARE)
            goto choose_fbconfig;

        fbconfigs = glXGetFBConfigs(
            parent->display,
            DefaultScreen(parent->display),
            &n_fbconfigs
        );
        if (!fbconfigs)
            goto error;

        /* Find out a GLXFBConfig compatible with the parent context */
        for (n = 0; n < n_fbconfigs; n++) {
            status = glXGetFBConfigAttrib(
                cs->display,
                fbconfigs[n],
                GLX_FBCONFIG_ID, &val
            );
            if (status == Success && val == fbconfig_id)
                break;
        }
        if (n == n_fbconfigs)
            goto error;
    }
    else {
    choose_fbconfig:
        fbconfigs = glXChooseFBConfig(
            ctx->native_dpy,
            ctx->x11_screen,
            fbconfig_attrs, &n_fbconfigs
        );
        if (!fbconfigs)
            goto error;

        /* Select the first one */
        n = 0;
    }

    cs->context = glXCreateNewContext(
        cs->display,
        fbconfigs[n],
        GLX_RGBA_TYPE,
        parent ? parent->context : NULL,
        True
    );
    if (cs->context)
        goto end;

error:
    gl_destroy_context(cs);
    cs = NULL;
end:
    if (fbconfigs)
        XFree(fbconfigs);
    return cs;
}

static void gl_get_current_context(OpenGLContextStateP cs)
{
    cs->display = glXGetCurrentDisplay();
    cs->window  = glXGetCurrentDrawable();
    cs->context = glXGetCurrentContext();
}

static int
gl_set_current_context(OpenGLContextStateP new_cs, OpenGLContextStateP old_cs)
{
    /* If display is NULL, this could be that new_cs was retrieved from
       gl_get_current_context() with none set previously. If that case,
       the other fields are also NULL and we don't return an error */
    if (!new_cs->display)
        return !new_cs->window && !new_cs->context;

    if (old_cs) {
        if (old_cs == new_cs)
            return 1;
        gl_get_current_context(old_cs);
        if (old_cs->display == new_cs->display &&
            old_cs->window  == new_cs->window  &&
            old_cs->context == new_cs->context)
            return 1;
    }
    return glXMakeCurrent(new_cs->display, new_cs->window, new_cs->context);
}

/** Unique VASurfaceGLX identifier */
#define VA_SURFACE_GLX_MAGIC VA_FOURCC('V','A','G','L')

struct VASurfaceGLX {
    uint32_t            magic;      ///< Magic number identifying a VASurfaceGLX
    GLenum              target;     ///< GL target to which the texture is bound
    GLuint              texture;    ///< GL texture
    VASurfaceID         surface;    ///< Associated VA surface
    unsigned int        width;
    unsigned int        height;
    OpenGLContextStateP gl_context;
    int                 is_bound;
    Pixmap              pixmap;
    GLuint              pix_texture;
    GLXPixmap           glx_pixmap;
    GLuint              fbo;
};

// Create Pixmaps for GLX texture-from-pixmap extension
static int create_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
{
    VAOpenGLVTableP const pOpenGLVTable = gl_get_vtable(ctx);
    const unsigned int    width         = pSurfaceGLX->width;
    const unsigned int    height        = pSurfaceGLX->height;
    Pixmap                pixmap        = None;
    GLXFBConfig          *fbconfig      = NULL;
    GLXPixmap             glx_pixmap    = None;
    Window                root_window;
    XWindowAttributes     wattr;
    int                  *attrib;
    int                   n_fbconfig_attrs;

    root_window = RootWindow(ctx->native_dpy, ctx->x11_screen);
    XGetWindowAttributes(ctx->native_dpy, root_window, &wattr);
    if (wattr.depth != 24 && wattr.depth != 32)
        return 0;
    pixmap = XCreatePixmap(
        ctx->native_dpy,
        root_window,
        width,
        height,
        wattr.depth
    );
    if (!pixmap)
        return 0;
    pSurfaceGLX->pixmap = pixmap;

    int fbconfig_attrs[32] = {
        GLX_DRAWABLE_TYPE,      GLX_PIXMAP_BIT,
        GLX_DOUBLEBUFFER,       GL_TRUE,
        GLX_RENDER_TYPE,        GLX_RGBA_BIT,
        GLX_X_RENDERABLE,       GL_TRUE,
        GLX_Y_INVERTED_EXT,     GL_TRUE,
        GLX_RED_SIZE,           8,
        GLX_GREEN_SIZE,         8,
        GLX_BLUE_SIZE,          8,
        /*
         * depth test isn't enabled in the implementaion of VA GLX,
         * so depth buffer is unnecessary. However to workaround a
         * bug in older verson of xorg-server, always require a depth
         * buffer.
         *
         * See https://bugs.freedesktop.org/show_bug.cgi?id=76755
         */
        GLX_DEPTH_SIZE,         1,
        GL_NONE,
    };
    for (attrib = fbconfig_attrs; *attrib != GL_NONE; attrib += 2)
        ;
    if (wattr.depth == 32) {
    *attrib++ = GLX_ALPHA_SIZE;                 *attrib++ = 8;
    *attrib++ = GLX_BIND_TO_TEXTURE_RGBA_EXT;   *attrib++ = GL_TRUE;
    }
    else {
    *attrib++ = GLX_BIND_TO_TEXTURE_RGB_EXT;    *attrib++ = GL_TRUE;
    }
    *attrib++ = GL_NONE;

    fbconfig = glXChooseFBConfig(
        ctx->native_dpy,
        ctx->x11_screen,
        fbconfig_attrs,
        &n_fbconfig_attrs
    );
    if (!fbconfig)
        return 0;

    int pixmap_attrs[10] = {
        GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
        GLX_MIPMAP_TEXTURE_EXT, GL_FALSE,
        GL_NONE,
    };
    for (attrib = pixmap_attrs; *attrib != GL_NONE; attrib += 2)
        ;
    *attrib++ = GLX_TEXTURE_FORMAT_EXT;
    if (wattr.depth == 32)
    *attrib++ = GLX_TEXTURE_FORMAT_RGBA_EXT;
    else
    *attrib++ = GLX_TEXTURE_FORMAT_RGB_EXT;
    *attrib++ = GL_NONE;

    x11_trap_errors();
    glx_pixmap = pOpenGLVTable->glx_create_pixmap(
        ctx->native_dpy,
        fbconfig[0],
        pixmap,
        pixmap_attrs
    );
    free(fbconfig);
    if (x11_untrap_errors() != 0)
        return 0;
    pSurfaceGLX->glx_pixmap = glx_pixmap;

    glGenTextures(1, &pSurfaceGLX->pix_texture);
    glBindTexture(GL_TEXTURE_2D, pSurfaceGLX->pix_texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    return 1;
}

// Destroy Pixmaps used for TFP
static void destroy_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
{
    VAOpenGLVTableP const pOpenGLVTable = gl_get_vtable(ctx);

    if (pSurfaceGLX->pix_texture) {
        glDeleteTextures(1, &pSurfaceGLX->pix_texture);
        pSurfaceGLX->pix_texture = 0;
    }

    if (pSurfaceGLX->glx_pixmap) {
        pOpenGLVTable->glx_destroy_pixmap(ctx->native_dpy, pSurfaceGLX->glx_pixmap);
        pSurfaceGLX->glx_pixmap = None;
    }

    if (pSurfaceGLX->pixmap) {
        XFreePixmap(ctx->native_dpy, pSurfaceGLX->pixmap);
        pSurfaceGLX->pixmap = None;
    }
}

// Bind GLX Pixmap to texture
static int bind_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
{
    VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);

    if (pSurfaceGLX->is_bound)
        return 1;

    glBindTexture(GL_TEXTURE_2D, pSurfaceGLX->pix_texture);

    x11_trap_errors();
    pOpenGLVTable->glx_bind_tex_image(
        ctx->native_dpy,
        pSurfaceGLX->glx_pixmap,
        GLX_FRONT_LEFT_EXT,
        NULL
    );
    XSync(ctx->native_dpy, False);
    if (x11_untrap_errors() != 0) {
        va_glx_error_message("failed to bind pixmap\n");
        return 0;
    }

    pSurfaceGLX->is_bound = 1;
    return 1;
}

// Release GLX Pixmap from texture
static int unbind_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
{
    VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);

    if (!pSurfaceGLX->is_bound)
        return 1;

    x11_trap_errors();
    pOpenGLVTable->glx_release_tex_image(
        ctx->native_dpy,
        pSurfaceGLX->glx_pixmap,
        GLX_FRONT_LEFT_EXT
    );
    XSync(ctx->native_dpy, False);
    if (x11_untrap_errors() != 0) {
        va_glx_error_message("failed to release pixmap\n");
        return 0;
    }

    glBindTexture(GL_TEXTURE_2D, 0);

    pSurfaceGLX->is_bound = 0;
    return 1;
}

// Render GLX Pixmap to texture
static void render_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
{
    const unsigned int w = pSurfaceGLX->width;
    const unsigned int h = pSurfaceGLX->height;

    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
    glBegin(GL_QUADS);
    {
        glTexCoord2f(0.0f, 0.0f); glVertex2i(0, 0);
        glTexCoord2f(0.0f, 1.0f); glVertex2i(0, h);
        glTexCoord2f(1.0f, 1.0f); glVertex2i(w, h);
        glTexCoord2f(1.0f, 0.0f); glVertex2i(w, 0);
    }
    glEnd();
}

// Create offscreen surface
static int create_fbo_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
{
    VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
    GLuint fbo;
    GLenum status;

    pOpenGLVTable->gl_gen_framebuffers(1, &fbo);
    pOpenGLVTable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, fbo);
    pOpenGLVTable->gl_framebuffer_texture_2d(
        GL_FRAMEBUFFER_EXT,
        GL_COLOR_ATTACHMENT0_EXT,
        GL_TEXTURE_2D,
        pSurfaceGLX->texture,
        0
    );

    status = pOpenGLVTable->gl_check_framebuffer_status(GL_DRAW_FRAMEBUFFER_EXT);
    pOpenGLVTable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, 0);
    if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
        return 0;

    pSurfaceGLX->fbo = fbo;
    return 1;
}

// Destroy offscreen surface
static void destroy_fbo_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
{
    VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);

    if (pSurfaceGLX->fbo) {
        pOpenGLVTable->gl_delete_framebuffers(1, &pSurfaceGLX->fbo);
        pSurfaceGLX->fbo = 0;
    }
}

// Setup matrices to match the FBO texture dimensions
static void fbo_enter(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
{
    VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
    const unsigned int width  = pSurfaceGLX->width;
    const unsigned int height = pSurfaceGLX->height;

    pOpenGLVTable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, pSurfaceGLX->fbo);
    glPushAttrib(GL_VIEWPORT_BIT);
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glViewport(0, 0, width, height);
    glTranslatef(-1.0f, -1.0f, 0.0f);
    glScalef(2.0f / width, 2.0f / height, 1.0f);
}

// Restore original OpenGL matrices
static void fbo_leave(VADriverContextP ctx)
{
    VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);

    glPopAttrib();
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
    pOpenGLVTable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, 0);
}

// Check internal texture format is supported
static int is_supported_internal_format(GLenum format)
{
    /* XXX: we don't support other textures than RGBA */
    switch (format) {
    case 4:
    case GL_RGBA:
    case GL_RGBA8:
        return 1;
    }
    return 0;
}

// Destroy VA/GLX surface
static void
destroy_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
{
    unbind_pixmap(ctx, pSurfaceGLX);
    destroy_fbo_surface(ctx, pSurfaceGLX);
    destroy_tfp_surface(ctx, pSurfaceGLX);
    free(pSurfaceGLX);
}

// Create VA/GLX surface
static VASurfaceGLXP
create_surface(VADriverContextP ctx, GLenum target, GLuint texture)
{
    VASurfaceGLXP pSurfaceGLX = NULL;
    unsigned int internal_format, border_width, width, height;
    int is_error = 1;

    pSurfaceGLX = malloc(sizeof(*pSurfaceGLX));
    if (!pSurfaceGLX)
        goto end;

    pSurfaceGLX->magic          = VA_SURFACE_GLX_MAGIC;
    pSurfaceGLX->target         = target;
    pSurfaceGLX->texture        = texture;
    pSurfaceGLX->surface        = VA_INVALID_SURFACE;
    pSurfaceGLX->gl_context     = NULL;
    pSurfaceGLX->is_bound       = 0;
    pSurfaceGLX->pixmap         = None;
    pSurfaceGLX->pix_texture    = 0;
    pSurfaceGLX->glx_pixmap     = None;
    pSurfaceGLX->fbo            = 0;

    glEnable(target);
    glBindTexture(target, texture);
    if (!gl_get_texture_param(GL_TEXTURE_INTERNAL_FORMAT, &internal_format))
        goto end;
    if (!is_supported_internal_format(internal_format))
        goto end;

    /* Check texture dimensions */
    if (!gl_get_texture_param(GL_TEXTURE_BORDER, &border_width))
        goto end;
    if (!gl_get_texture_param(GL_TEXTURE_WIDTH, &width))
        goto end;
    if (!gl_get_texture_param(GL_TEXTURE_HEIGHT, &height))
        goto end;

    width  -= 2 * border_width;
    height -= 2 * border_width;
    if (width == 0 || height == 0)
        goto end;

    pSurfaceGLX->width  = width;
    pSurfaceGLX->height = height;

    /* Create TFP objects */
    if (!create_tfp_surface(ctx, pSurfaceGLX))
        goto end;

    /* Create FBO objects */
    if (!create_fbo_surface(ctx, pSurfaceGLX))
        goto end;

    is_error = 0;
end:
    if (is_error && pSurfaceGLX) {
        destroy_surface(ctx, pSurfaceGLX);
        pSurfaceGLX = NULL;
    }
    return pSurfaceGLX;
}


/* ========================================================================= */
/* === VA/GLX implementation from the driver (fordward calls)            === */
/* ========================================================================= */

#define INVOKE(ctx, func, args) do {                    \
        VADriverVTableGLXP vtable = (ctx)->vtable_glx;  \
        if (!vtable->va##func##GLX)                     \
            return VA_STATUS_ERROR_UNIMPLEMENTED;       \
                                                        \
        VAStatus status = vtable->va##func##GLX args;   \
        if (status != VA_STATUS_SUCCESS)                \
            return status;                              \
    } while (0)

static VAStatus
vaCreateSurfaceGLX_impl_driver(
    VADriverContextP    ctx,
    GLenum              target,
    GLuint              texture,
    void              **gl_surface
)
{
    INVOKE(ctx, CreateSurface, (ctx, target, texture, gl_surface));
    return VA_STATUS_SUCCESS;
}

static VAStatus
vaDestroySurfaceGLX_impl_driver(VADriverContextP ctx, void *gl_surface)
{
    INVOKE(ctx, DestroySurface, (ctx, gl_surface));
    return VA_STATUS_SUCCESS;
}

static VAStatus
vaCopySurfaceGLX_impl_driver(
    VADriverContextP    ctx,
    void               *gl_surface,
    VASurfaceID         surface,
    unsigned int        flags
)
{
    INVOKE(ctx, CopySurface, (ctx, gl_surface, surface, flags));
    return VA_STATUS_SUCCESS;
}

#undef INVOKE


/* ========================================================================= */
/* === VA/GLX implementation from libVA (generic and suboptimal path)    === */
/* ========================================================================= */

#define INIT_SURFACE(surface, surface_arg) do {         \
        surface = (VASurfaceGLXP)(surface_arg);         \
        if (!check_surface(surface))                    \
            return VA_STATUS_ERROR_INVALID_SURFACE;     \
    } while (0)

// Check VASurfaceGLX is valid
static inline int check_surface(VASurfaceGLXP pSurfaceGLX)
{
    return pSurfaceGLX && pSurfaceGLX->magic == VA_SURFACE_GLX_MAGIC;
}

static VAStatus
vaCreateSurfaceGLX_impl_libva(
    VADriverContextP    ctx,
    GLenum              target,
    GLuint              texture,
    void              **gl_surface
)
{
    VASurfaceGLXP pSurfaceGLX;
    struct OpenGLContextState old_cs, *new_cs;

    gl_get_current_context(&old_cs);
    new_cs = gl_create_context(ctx, &old_cs);
    if (!new_cs)
        goto error;
    if (!gl_set_current_context(new_cs, NULL))
        goto error;

    pSurfaceGLX = create_surface(ctx, target, texture);
    if (!pSurfaceGLX)
        goto error;

    pSurfaceGLX->gl_context = new_cs;
    *gl_surface = pSurfaceGLX;

    gl_set_current_context(&old_cs, NULL);
    return VA_STATUS_SUCCESS;

error:
    if (new_cs)
        gl_destroy_context(new_cs);

    return VA_STATUS_ERROR_ALLOCATION_FAILED;    
}

static VAStatus
vaDestroySurfaceGLX_impl_libva(VADriverContextP ctx, void *gl_surface)
{
    VASurfaceGLXP pSurfaceGLX;
    struct OpenGLContextState old_cs = {0}, *new_cs;

    INIT_SURFACE(pSurfaceGLX, gl_surface);

    new_cs = pSurfaceGLX->gl_context;
    if (!gl_set_current_context(new_cs, &old_cs))
        return VA_STATUS_ERROR_OPERATION_FAILED;

    destroy_surface(ctx, pSurfaceGLX);

    gl_destroy_context(new_cs);
    gl_set_current_context(&old_cs, NULL);
    return VA_STATUS_SUCCESS;
}

static inline VAStatus
deassociate_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
{
    if (!unbind_pixmap(ctx, pSurfaceGLX))
        return VA_STATUS_ERROR_OPERATION_FAILED;

    pSurfaceGLX->surface = VA_INVALID_SURFACE;
    return VA_STATUS_SUCCESS;
}

static VAStatus
associate_surface(
    VADriverContextP    ctx,
    VASurfaceGLXP       pSurfaceGLX,
    VASurfaceID         surface,
    unsigned int        flags
)
{
    VAStatus status;

    /* XXX: optimise case where we are associating the same VA surface
       as before an no changed occurred to it */
    status = deassociate_surface(ctx, pSurfaceGLX);
    if (status != VA_STATUS_SUCCESS)
        return status;

    x11_trap_errors();
    status = ctx->vtable->vaPutSurface(
        ctx,
        surface,
        (void *)pSurfaceGLX->pixmap,
        0, 0, pSurfaceGLX->width, pSurfaceGLX->height,
        0, 0, pSurfaceGLX->width, pSurfaceGLX->height,
        NULL, 0,
        flags
    );
    XSync(ctx->native_dpy, False);
    if (x11_untrap_errors() != 0)
        return VA_STATUS_ERROR_OPERATION_FAILED;
    if (status != VA_STATUS_SUCCESS)
        return status;

    pSurfaceGLX->surface = surface;
    return VA_STATUS_SUCCESS;
}

static inline VAStatus
sync_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
{
    if (pSurfaceGLX->surface == VA_INVALID_SURFACE)
        return VA_STATUS_ERROR_INVALID_SURFACE;

    return ctx->vtable->vaSyncSurface(ctx, pSurfaceGLX->surface);
}

static inline VAStatus
begin_render_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
{
    VAStatus status;

    status = sync_surface(ctx, pSurfaceGLX);
    if (status != VA_STATUS_SUCCESS)
        return status;

    if (!bind_pixmap(ctx, pSurfaceGLX))
        return VA_STATUS_ERROR_OPERATION_FAILED;

    return VA_STATUS_SUCCESS;
}

static inline VAStatus
end_render_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
{
    if (!unbind_pixmap(ctx, pSurfaceGLX))
        return VA_STATUS_ERROR_OPERATION_FAILED;

    return VA_STATUS_SUCCESS;
}

static VAStatus
copy_surface(
    VADriverContextP    ctx,
    VASurfaceGLXP       pSurfaceGLX,
    VASurfaceID         surface,
    unsigned int        flags
)
{
    VAStatus status;

    /* Associate VA surface */
    status = associate_surface(ctx, pSurfaceGLX, surface, flags);
    if (status != VA_STATUS_SUCCESS)
        return status;

    /* Render to FBO */
    fbo_enter(ctx, pSurfaceGLX);
    status = begin_render_surface(ctx, pSurfaceGLX);
    if (status == VA_STATUS_SUCCESS) {
        render_pixmap(ctx, pSurfaceGLX);
        status = end_render_surface(ctx, pSurfaceGLX);
    }
    fbo_leave(ctx);
    if (status != VA_STATUS_SUCCESS)
        return status;

    return deassociate_surface(ctx, pSurfaceGLX);
}

static VAStatus
vaCopySurfaceGLX_impl_libva(
    VADriverContextP    ctx,
    void               *gl_surface,
    VASurfaceID         surface,
    unsigned int        flags
)
{
    VASurfaceGLXP pSurfaceGLX;
    VAStatus status;
    struct OpenGLContextState old_cs = {0};

    INIT_SURFACE(pSurfaceGLX, gl_surface);

    if (!gl_set_current_context(pSurfaceGLX->gl_context, &old_cs))
        return VA_STATUS_ERROR_OPERATION_FAILED;

    status = copy_surface(ctx, pSurfaceGLX, surface, flags);

    gl_set_current_context(&old_cs, NULL);
    return status;
}

#undef INIT_SURFACE


/* ========================================================================= */
/* === Private VA/GLX vtable initialization                              === */
/* ========================================================================= */

// Initialize GLX driver context
VAStatus va_glx_init_context(VADriverContextP ctx)
{
    VADriverContextGLXP glx_ctx = VA_DRIVER_CONTEXT_GLX(ctx);
    VADriverVTableGLXP  vtable  = &glx_ctx->vtable;
    int glx_major, glx_minor;

    if (glx_ctx->is_initialized)
        return VA_STATUS_SUCCESS;

    if (ctx->vtable_glx && ctx->vtable_glx->vaCopySurfaceGLX) {
        vtable->vaCreateSurfaceGLX      = vaCreateSurfaceGLX_impl_driver;
        vtable->vaDestroySurfaceGLX     = vaDestroySurfaceGLX_impl_driver;
        vtable->vaCopySurfaceGLX        = vaCopySurfaceGLX_impl_driver;
    }
    else {
        vtable->vaCreateSurfaceGLX      = vaCreateSurfaceGLX_impl_libva;
        vtable->vaDestroySurfaceGLX     = vaDestroySurfaceGLX_impl_libva;
        vtable->vaCopySurfaceGLX        = vaCopySurfaceGLX_impl_libva;

        if (!glXQueryVersion(ctx->native_dpy, &glx_major, &glx_minor))
            return VA_STATUS_ERROR_UNIMPLEMENTED;

        if (!check_tfp_extensions(ctx) || !load_tfp_extensions(ctx))
            return VA_STATUS_ERROR_UNIMPLEMENTED;

        if (!check_fbo_extensions(ctx) || !load_fbo_extensions(ctx))
            return VA_STATUS_ERROR_UNIMPLEMENTED;
    }

    glx_ctx->is_initialized = 1;
    return VA_STATUS_SUCCESS;
}
