Home | History | Annotate | Download | only in glx
      1 /*
      2  * Copyright (C) 2009 Splitted-Desktop Systems. All Rights Reserved.
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the
      6  * "Software"), to deal in the Software without restriction, including
      7  * without limitation the rights to use, copy, modify, merge, publish,
      8  * distribute, sub license, and/or sell copies of the Software, and to
      9  * permit persons to whom the Software is furnished to do so, subject to
     10  * the following conditions:
     11  *
     12  * The above copyright notice and this permission notice (including the
     13  * next paragraph) shall be included in all copies or substantial portions
     14  * of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     19  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
     20  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     23  */
     24 
     25 #include <stdlib.h>
     26 #include "va_glx_private.h"
     27 #include "va_glx_impl.h"
     28 
     29 #define INIT_CONTEXT(ctx, dpy) do {                             \
     30         if (!vaDisplayIsValid(dpy))                             \
     31             return VA_STATUS_ERROR_INVALID_DISPLAY;             \
     32                                                                 \
     33         ctx = ((VADisplayContextP)(dpy))->pDriverContext;       \
     34         if (!(ctx))                                             \
     35             return VA_STATUS_ERROR_INVALID_DISPLAY;             \
     36                                                                 \
     37         VAStatus status = va_glx_init_context(ctx);             \
     38         if (status != VA_STATUS_SUCCESS)                        \
     39             return status;                                      \
     40     } while (0)
     41 
     42 #define INVOKE(ctx, func, args) do {                            \
     43         VADriverVTableGLXP vtable;                              \
     44         vtable = &VA_DRIVER_CONTEXT_GLX(ctx)->vtable;           \
     45         if (!vtable->va##func##GLX)                             \
     46             return VA_STATUS_ERROR_UNIMPLEMENTED;               \
     47         status = vtable->va##func##GLX args;                    \
     48     } while (0)
     49 
     50 
     51 // Destroy VA/GLX display context
     52 static void va_DisplayContextDestroy(VADisplayContextP pDisplayContext)
     53 {
     54     VADisplayContextGLXP pDisplayContextGLX;
     55     VADriverContextP     pDriverContext;
     56     VADriverContextGLXP  pDriverContextGLX;
     57 
     58     if (!pDisplayContext)
     59         return;
     60 
     61     pDriverContext     = pDisplayContext->pDriverContext;
     62     pDriverContextGLX  = pDriverContext->glx;
     63     if (pDriverContextGLX) {
     64         free(pDriverContextGLX);
     65         pDriverContext->glx = NULL;
     66     }
     67 
     68     pDisplayContextGLX = pDisplayContext->opaque;
     69     if (pDisplayContextGLX) {
     70         vaDestroyFunc vaDestroy = pDisplayContextGLX->vaDestroy;
     71         free(pDisplayContextGLX);
     72         pDisplayContext->opaque = NULL;
     73         if (vaDestroy)
     74             vaDestroy(pDisplayContext);
     75     }
     76 }
     77 
     78 // Return a suitable VADisplay for VA API
     79 VADisplay vaGetDisplayGLX(Display *native_dpy)
     80 {
     81     VADisplay            dpy                = NULL;
     82     VADisplayContextP    pDisplayContext    = NULL;
     83     VADisplayContextGLXP pDisplayContextGLX = NULL;
     84     VADriverContextP     pDriverContext;
     85     VADriverContextGLXP  pDriverContextGLX  = NULL;
     86 
     87     dpy = vaGetDisplay(native_dpy);
     88     if (!dpy)
     89         return NULL;
     90     pDisplayContext = (VADisplayContextP)dpy;
     91     pDriverContext  = pDisplayContext->pDriverContext;
     92 
     93     pDisplayContextGLX = calloc(1, sizeof(*pDisplayContextGLX));
     94     if (!pDisplayContextGLX)
     95         goto error;
     96 
     97     pDriverContextGLX = calloc(1, sizeof(*pDriverContextGLX));
     98     if (!pDriverContextGLX)
     99         goto error;
    100 
    101     pDriverContext->display_type  = VA_DISPLAY_GLX;
    102     pDisplayContextGLX->vaDestroy = pDisplayContext->vaDestroy;
    103     pDisplayContext->vaDestroy    = va_DisplayContextDestroy;
    104     pDisplayContext->opaque       = pDisplayContextGLX;
    105     pDriverContext->glx           = pDriverContextGLX;
    106     return dpy;
    107 
    108 error:
    109     free(pDriverContextGLX);
    110     free(pDisplayContextGLX);
    111     pDisplayContext->vaDestroy(pDisplayContext);
    112     return NULL;
    113 }
    114 
    115 // Create a surface used for display to OpenGL
    116 VAStatus vaCreateSurfaceGLX(
    117     VADisplay dpy,
    118     GLenum    target,
    119     GLuint    texture,
    120     void    **gl_surface
    121 )
    122 {
    123     VADriverContextP ctx;
    124     VAStatus status;
    125 
    126     /* Make sure it is a valid GL texture object */
    127     if (!glIsTexture(texture))
    128         return VA_STATUS_ERROR_INVALID_PARAMETER;
    129 
    130     INIT_CONTEXT(ctx, dpy);
    131 
    132     INVOKE(ctx, CreateSurface, (ctx, target, texture, gl_surface));
    133     return status;
    134 }
    135 
    136 // Destroy a VA/GLX surface
    137 VAStatus vaDestroySurfaceGLX(
    138     VADisplay dpy,
    139     void     *gl_surface
    140 )
    141 {
    142     VADriverContextP ctx;
    143     VAStatus status;
    144 
    145     INIT_CONTEXT(ctx, dpy);
    146 
    147     INVOKE(ctx, DestroySurface, (ctx, gl_surface));
    148     return status;
    149 }
    150 
    151 // Copy a VA surface to a VA/GLX surface
    152 VAStatus vaCopySurfaceGLX(
    153     VADisplay    dpy,
    154     void        *gl_surface,
    155     VASurfaceID  surface,
    156     unsigned int flags
    157 )
    158 {
    159     VADriverContextP ctx;
    160     VAStatus status;
    161 
    162     INIT_CONTEXT(ctx, dpy);
    163 
    164     INVOKE(ctx, CopySurface, (ctx, gl_surface, surface, flags));
    165     return status;
    166 }
    167