/*
 * DIB driver OpenGL support
 *
 * Copyright 2012 Alexandre Julliard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"

#include "gdi_private.h"
#include "dibdrv.h"

#include "wine/library.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(dib);

#ifdef SONAME_LIBOSMESA

#include "wine/wgl.h"
#include "wine/wgl_driver.h"

#define OSMESA_COLOR_INDEX	GL_COLOR_INDEX
#define OSMESA_RGBA		GL_RGBA
#define OSMESA_BGRA		0x1
#define OSMESA_ARGB		0x2
#define OSMESA_RGB		GL_RGB
#define OSMESA_BGR		0x4
#define OSMESA_RGB_565		0x5
#define OSMESA_ROW_LENGTH	0x10
#define OSMESA_Y_UP		0x11

typedef struct osmesa_context *OSMesaContext;

extern BOOL WINAPI GdiSetPixelFormat( HDC hdc, INT fmt, const PIXELFORMATDESCRIPTOR *pfd );

struct wgl_context
{
    OSMesaContext context;
    int           format;
};

static struct opengl_funcs opengl_funcs;

#define USE_GL_FUNC(name) #name,
static const char *opengl_func_names[] = { ALL_WGL_FUNCS };
#undef USE_GL_FUNC

static OSMesaContext (*pOSMesaCreateContextExt)( GLenum format, GLint depthBits, GLint stencilBits,
                                                 GLint accumBits, OSMesaContext sharelist );
static void (*pOSMesaDestroyContext)( OSMesaContext ctx );
static void * (*pOSMesaGetProcAddress)( const char *funcName );
static GLboolean (*pOSMesaMakeCurrent)( OSMesaContext ctx, void *buffer, GLenum type,
                                        GLsizei width, GLsizei height );
static void (*pOSMesaPixelStore)( GLint pname, GLint value );

static const struct
{
    UINT mesa;
    BYTE color_bits;
    BYTE red_bits, red_shift;
    BYTE green_bits, green_shift;
    BYTE blue_bits, blue_shift;
    BYTE alpha_bits, alpha_shift;
    BYTE accum_bits;
    BYTE depth_bits;
    BYTE stencil_bits;
} pixel_formats[] =
{
    { OSMESA_BGRA,     32,  8, 16, 8, 8,  8, 0,  8, 24,  16, 32, 8 },
    { OSMESA_BGRA,     32,  8, 16, 8, 8,  8, 0,  8, 24,  16, 16, 8 },
    { OSMESA_RGBA,     32,  8, 0,  8, 8,  8, 16, 8, 24,  16, 32, 8 },
    { OSMESA_RGBA,     32,  8, 0,  8, 8,  8, 16, 8, 24,  16, 16, 8 },
    { OSMESA_ARGB,     32,  8, 8,  8, 16, 8, 24, 8, 0,   16, 32, 8 },
    { OSMESA_ARGB,     32,  8, 8,  8, 16, 8, 24, 8, 0,   16, 16, 8 },
    { OSMESA_RGB,      24,  8, 0,  8, 8,  8, 16, 0, 0,   16, 32, 8 },
    { OSMESA_RGB,      24,  8, 0,  8, 8,  8, 16, 0, 0,   16, 16, 8 },
    { OSMESA_BGR,      24,  8, 16, 8, 8,  8, 0,  0, 0,   16, 32, 8 },
    { OSMESA_BGR,      24,  8, 16, 8, 8,  8, 0,  0, 0,   16, 16, 8 },
    { OSMESA_RGB_565,  16,  5, 0,  6, 5,  5, 11, 0, 0,   16, 32, 8 },
    { OSMESA_RGB_565,  16,  5, 0,  6, 5,  5, 11, 0, 0,   16, 16, 8 },
};
static const int nb_formats = sizeof(pixel_formats) / sizeof(pixel_formats[0]);

static BOOL init_opengl(void)
{
    static BOOL init_done = FALSE;
    static void *osmesa_handle;
    char buffer[200];
    unsigned int i;

    if (init_done) return (osmesa_handle != NULL);
    init_done = TRUE;

    osmesa_handle = wine_dlopen( SONAME_LIBOSMESA, RTLD_NOW, buffer, sizeof(buffer) );
    if (osmesa_handle == NULL)
    {
        ERR( "Failed to load OSMesa: %s\n", buffer );
        return FALSE;
    }

    for (i = 0; i < sizeof(opengl_func_names)/sizeof(opengl_func_names[0]); i++)
    {
        if (!(((void **)&opengl_funcs.gl)[i] = wine_dlsym( osmesa_handle, opengl_func_names[i], buffer, sizeof(buffer) )))
        {
            ERR( "%s not found in %s (%s), disabling.\n", opengl_func_names[i], SONAME_LIBOSMESA, buffer );
            goto failed;
        }
    }
#define LOAD_FUNCPTR(f) do if (!(p##f = wine_dlsym( osmesa_handle, #f, buffer, sizeof(buffer) ))) \
    { \
        ERR( "%s not found in %s (%s), disabling.\n", #f, SONAME_LIBOSMESA, buffer ); \
        goto failed; \
    } while(0)

    LOAD_FUNCPTR(OSMesaCreateContextExt);
    LOAD_FUNCPTR(OSMesaDestroyContext);
    LOAD_FUNCPTR(OSMesaGetProcAddress);
    LOAD_FUNCPTR(OSMesaMakeCurrent);
    LOAD_FUNCPTR(OSMesaPixelStore);
#undef LOAD_FUNCPTR

    return TRUE;

failed:
    wine_dlclose( osmesa_handle, NULL, 0 );
    osmesa_handle = NULL;
    return FALSE;
}

/**********************************************************************
 *	     dibdrv_wglDescribePixelFormat
 */
static int dibdrv_wglDescribePixelFormat( HDC hdc, int fmt, UINT size, PIXELFORMATDESCRIPTOR *descr )
{
    int ret = sizeof(pixel_formats) / sizeof(pixel_formats[0]);

    if (!descr) return ret;
    if (fmt <= 0 || fmt > ret) return 0;
    if (size < sizeof(*descr)) return 0;

    memset( descr, 0, sizeof(*descr) );
    descr->nSize            = sizeof(*descr);
    descr->nVersion         = 1;
    descr->dwFlags          = PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_BITMAP | PFD_GENERIC_FORMAT;
    descr->iPixelType       = PFD_TYPE_RGBA;
    descr->cColorBits       = pixel_formats[fmt - 1].color_bits;
    descr->cRedBits         = pixel_formats[fmt - 1].red_bits;
    descr->cRedShift        = pixel_formats[fmt - 1].red_shift;
    descr->cGreenBits       = pixel_formats[fmt - 1].green_bits;
    descr->cGreenShift      = pixel_formats[fmt - 1].green_shift;
    descr->cBlueBits        = pixel_formats[fmt - 1].blue_bits;
    descr->cBlueShift       = pixel_formats[fmt - 1].blue_shift;
    descr->cAlphaBits       = pixel_formats[fmt - 1].alpha_bits;
    descr->cAlphaShift      = pixel_formats[fmt - 1].alpha_shift;
    descr->cAccumBits       = pixel_formats[fmt - 1].accum_bits;
    descr->cAccumRedBits    = pixel_formats[fmt - 1].accum_bits / 4;
    descr->cAccumGreenBits  = pixel_formats[fmt - 1].accum_bits / 4;
    descr->cAccumBlueBits   = pixel_formats[fmt - 1].accum_bits / 4;
    descr->cAccumAlphaBits  = pixel_formats[fmt - 1].accum_bits / 4;
    descr->cDepthBits       = pixel_formats[fmt - 1].depth_bits;
    descr->cStencilBits     = pixel_formats[fmt - 1].stencil_bits;
    descr->cAuxBuffers      = 0;
    descr->iLayerType       = PFD_MAIN_PLANE;
    return ret;
}

/***********************************************************************
 *		dibdrv_wglCopyContext
 */
static BOOL dibdrv_wglCopyContext( struct wgl_context *src, struct wgl_context *dst, UINT mask )
{
    FIXME( "not supported yet\n" );
    return FALSE;
}

/***********************************************************************
 *		dibdrv_wglCreateContext
 */
static struct wgl_context *dibdrv_wglCreateContext( HDC hdc )
{
    struct wgl_context *context;

    if (!(context = HeapAlloc( GetProcessHeap(), 0, sizeof( *context )))) return NULL;
    context->format = GetPixelFormat( hdc );
    if (!context->format || context->format > nb_formats) context->format = 1;

    if (!(context->context = pOSMesaCreateContextExt( pixel_formats[context->format - 1].mesa,
                                                      pixel_formats[context->format - 1].depth_bits,
                                                      pixel_formats[context->format - 1].stencil_bits,
                                                      pixel_formats[context->format - 1].accum_bits, 0 )))
    {
        HeapFree( GetProcessHeap(), 0, context );
        return NULL;
    }
    return context;
}

/***********************************************************************
 *		dibdrv_wglDeleteContext
 */
static void dibdrv_wglDeleteContext( struct wgl_context *context )
{
    pOSMesaDestroyContext( context->context );
    HeapFree( GetProcessHeap(), 0, context );
}

/***********************************************************************
 *		dibdrv_wglGetPixelFormat
 */
static int dibdrv_wglGetPixelFormat( HDC hdc )
{
    DC *dc = get_dc_ptr( hdc );
    int ret = 0;

    if (dc)
    {
        ret = dc->pixel_format;
        release_dc_ptr( dc );
    }
    return ret;
}

/***********************************************************************
 *		dibdrv_wglGetProcAddress
 */
static PROC dibdrv_wglGetProcAddress( const char *proc )
{
    if (!strncmp( proc, "wgl", 3 )) return NULL;
    return (PROC)pOSMesaGetProcAddress( proc );
}

/***********************************************************************
 *		dibdrv_wglMakeCurrent
 */
static BOOL dibdrv_wglMakeCurrent( HDC hdc, struct wgl_context *context )
{
    HBITMAP bitmap;
    BITMAPOBJ *bmp;
    dib_info dib;
    GLenum type;
    BOOL ret = FALSE;

    if (!context)
    {
        pOSMesaMakeCurrent( NULL, NULL, GL_UNSIGNED_BYTE, 0, 0 );
        return TRUE;
    }

    if (GetPixelFormat( hdc ) != context->format)
        FIXME( "mismatched pixel formats %u/%u not supported yet\n",
               GetPixelFormat( hdc ), context->format );

    bitmap = GetCurrentObject( hdc, OBJ_BITMAP );
    bmp = GDI_GetObjPtr( bitmap, OBJ_BITMAP );
    if (!bmp) return FALSE;

    if (init_dib_info_from_bitmapobj( &dib, bmp ))
    {
        char *bits;
        int width = dib.rect.right - dib.rect.left;
        int height = dib.rect.bottom - dib.rect.top;

        if (dib.stride < 0)
            bits = (char *)dib.bits.ptr + (dib.rect.bottom - 1) * dib.stride;
        else
            bits = (char *)dib.bits.ptr + dib.rect.top * dib.stride;
        bits += dib.rect.left * dib.bit_count / 8;

        TRACE( "context %p bits %p size %ux%u\n", context, bits, width, height );

        if (pixel_formats[context->format - 1].mesa == OSMESA_RGB_565)
            type = GL_UNSIGNED_SHORT_5_6_5;
        else
            type = GL_UNSIGNED_BYTE;

        ret = pOSMesaMakeCurrent( context->context, bits, type, width, height );
        if (ret)
        {
            pOSMesaPixelStore( OSMESA_ROW_LENGTH, abs( dib.stride ) * 8 / dib.bit_count );
            pOSMesaPixelStore( OSMESA_Y_UP, 1 );  /* Windows seems to assume bottom-up */
        }
    }
    GDI_ReleaseObj( bitmap );
    return ret;
}

/**********************************************************************
 *	     dibdrv_wglSetPixelFormat
 */
static BOOL dibdrv_wglSetPixelFormat( HDC hdc, int fmt, const PIXELFORMATDESCRIPTOR *descr )
{
    if (fmt <= 0 || fmt > nb_formats) return FALSE;
    return GdiSetPixelFormat( hdc, fmt, descr );
}

/***********************************************************************
 *		dibdrv_wglShareLists
 */
static BOOL dibdrv_wglShareLists( struct wgl_context *org, struct wgl_context *dest )
{
    FIXME( "not supported yet\n" );
    return FALSE;
}

/***********************************************************************
 *		dibdrv_wglSwapBuffers
 */
static BOOL dibdrv_wglSwapBuffers( HDC hdc )
{
    return TRUE;
}

static struct opengl_funcs opengl_funcs =
{
    {
        dibdrv_wglCopyContext,        /* p_wglCopyContext */
        dibdrv_wglCreateContext,      /* p_wglCreateContext */
        dibdrv_wglDeleteContext,      /* p_wglDeleteContext */
        dibdrv_wglDescribePixelFormat,/* p_wglDescribePixelFormat */
        dibdrv_wglGetPixelFormat,     /* p_wglGetPixelFormat */
        dibdrv_wglGetProcAddress,     /* p_wglGetProcAddress */
        dibdrv_wglMakeCurrent,        /* p_wglMakeCurrent */
        dibdrv_wglSetPixelFormat,     /* p_wglSetPixelFormat */
        dibdrv_wglShareLists,         /* p_wglShareLists */
        dibdrv_wglSwapBuffers,        /* p_wglSwapBuffers */
    }
};

/**********************************************************************
 *	     dibdrv_wine_get_wgl_driver
 */
struct opengl_funcs *dibdrv_wine_get_wgl_driver( PHYSDEV dev, UINT version )
{
    if (version != WINE_WGL_DRIVER_VERSION)
    {
        ERR( "version mismatch, opengl32 wants %u but dibdrv has %u\n", version, WINE_WGL_DRIVER_VERSION );
        return NULL;
    }

    if (!init_opengl()) return (void *)-1;

    return &opengl_funcs;
}

#else  /* SONAME_LIBOSMESA */

/**********************************************************************
 *	     dibdrv_wine_get_wgl_driver
 */
struct opengl_funcs *dibdrv_wine_get_wgl_driver( PHYSDEV dev, UINT version )
{
    static int warned;
    if (!warned++) ERR( "OSMesa not compiled in, no OpenGL bitmap support\n" );
    return (void *)-1;
}

#endif  /* SONAME_LIBOSMESA */
