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