/*
 * va_wayland.c - Wayland API
 *
 * Copyright (c) 2012 Intel Corporation. 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 INTEL 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.
 */

#include "sysdeps.h"
#include <stdarg.h>
#include "va_wayland.h"
#include "va_wayland_drm.h"
#include "va_wayland_emgd.h"
#include "va_wayland_private.h"
#include "va_backend.h"
#include "va_backend_wayland.h"
#include "va_internal.h"

static inline VADriverContextP
get_driver_context(VADisplay dpy)
{
    if (!vaDisplayIsValid(dpy))
        return NULL;
    return ((VADisplayContextP)dpy)->pDriverContext;
}

void
va_wayland_error(const char *format, ...)
{
    va_list args;

    va_start(args, format);
    fprintf(stderr, "VA error: wayland: ");
    vfprintf(stderr, format, args);
    fprintf(stderr, "\n");
    va_end(args);
}

static int
va_DisplayContextIsValid(VADisplayContextP pDisplayContext)
{
    VADriverContextP const pDriverContext = pDisplayContext->pDriverContext;

    return (pDriverContext &&
            pDriverContext->display_type == VA_DISPLAY_WAYLAND);
}

static void
va_DisplayContextDestroy(VADisplayContextP pDisplayContext)
{
    VADriverContextP pDriverContext;
    VADisplayContextWaylandP pDisplayContextWl;

    if (!pDisplayContext)
        return;

    pDisplayContextWl = pDisplayContext->opaque;
    if (pDisplayContextWl && pDisplayContextWl->destroy)
        pDisplayContextWl->destroy(pDisplayContext);

    pDriverContext = pDisplayContext->pDriverContext;
    if (pDriverContext) {
        free(pDriverContext->vtable_wayland);
        pDriverContext->vtable_wayland = NULL;
        free(pDriverContext);
        pDisplayContext->pDriverContext = NULL;
    }

    free(pDisplayContext->opaque);
    pDisplayContext->opaque = NULL;
    free(pDisplayContext);
}

static VAStatus
va_DisplayContextGetDriverName(VADisplayContextP pDisplayContext, char **name)
{
    *name = NULL;
    return VA_STATUS_ERROR_UNKNOWN;
}

/* -------------------------------------------------------------------------- */
/* --- Public interface                                                   --- */
/* -------------------------------------------------------------------------- */

struct va_wayland_backend {
    VADisplayContextCreateFunc  create;
    VADisplayContextDestroyFunc destroy;
};

static const struct va_wayland_backend g_backends[] = {
    { va_wayland_drm_create,
      va_wayland_drm_destroy },
    { va_wayland_emgd_create,
      va_wayland_emgd_destroy },
    { NULL, }
};

VADisplay
vaGetDisplayWl(struct wl_display *display)
{
    VADisplayContextP pDisplayContext = NULL;
    VADriverContextP pDriverContext;
    struct VADriverVTableWayland *vtable;
    unsigned int i;

    pDisplayContext = va_newDisplayContext();
    if (!pDisplayContext)
        return NULL;

    pDisplayContext->vaIsValid          = va_DisplayContextIsValid;
    pDisplayContext->vaDestroy          = va_DisplayContextDestroy;
    pDisplayContext->vaGetDriverName    = va_DisplayContextGetDriverName;

    pDriverContext = va_newDriverContext(pDisplayContext);
    if (!pDriverContext)
        goto error;

    pDriverContext->native_dpy          = display;
    pDriverContext->display_type        = VA_DISPLAY_WAYLAND;

    vtable = calloc(1, sizeof(*vtable));
    if (!vtable)
        goto error;
    pDriverContext->vtable_wayland      = vtable;

    vtable->version                     = VA_WAYLAND_API_VERSION;

    for (i = 0; g_backends[i].create != NULL; i++) {
        if (g_backends[i].create(pDisplayContext))
            break;
        g_backends[i].destroy(pDisplayContext);
    }

    return (VADisplay)pDisplayContext;

error:
    va_DisplayContextDestroy(pDisplayContext);
    return NULL;
}

VAStatus
vaGetSurfaceBufferWl(
    VADisplay           dpy,
    VASurfaceID         surface,
    unsigned int        flags,
    struct wl_buffer  **out_buffer
)
{
    VADriverContextP const ctx = get_driver_context(dpy);

    if (!ctx)
        return VA_STATUS_ERROR_INVALID_DISPLAY;
    if (!ctx->vtable_wayland || !ctx->vtable_wayland->vaGetSurfaceBufferWl)
        return VA_STATUS_ERROR_UNIMPLEMENTED;
    return ctx->vtable_wayland->vaGetSurfaceBufferWl(ctx, surface, flags,
                                                     out_buffer);
}

VAStatus
vaGetImageBufferWl(
    VADisplay           dpy,
    VAImageID           image,
    unsigned int        flags,
    struct wl_buffer  **out_buffer
)
{
    VADriverContextP const ctx = get_driver_context(dpy);

    if (!ctx)
        return VA_STATUS_ERROR_INVALID_DISPLAY;
    if (!ctx->vtable_wayland || !ctx->vtable_wayland->vaGetImageBufferWl)
        return VA_STATUS_ERROR_UNIMPLEMENTED;
    return ctx->vtable_wayland->vaGetImageBufferWl(ctx, image, flags,
                                                   out_buffer);
}
