| /* |
| * 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. |
| */ |
| |
| #include "sysdeps.h" |
| #include <stdlib.h> |
| #include "va_glx_private.h" |
| #include "va_glx_impl.h" |
| |
| #define INIT_CONTEXT(ctx, dpy) do { \ |
| if (!vaDisplayIsValid(dpy)) \ |
| return VA_STATUS_ERROR_INVALID_DISPLAY; \ |
| \ |
| ctx = ((VADisplayContextP)(dpy))->pDriverContext; \ |
| if (!(ctx)) \ |
| return VA_STATUS_ERROR_INVALID_DISPLAY; \ |
| \ |
| VAStatus status = va_glx_init_context(ctx); \ |
| if (status != VA_STATUS_SUCCESS) \ |
| return status; \ |
| } while (0) |
| |
| #define INVOKE(ctx, func, args) do { \ |
| VADriverVTableGLXP vtable; \ |
| vtable = &VA_DRIVER_CONTEXT_GLX(ctx)->vtable; \ |
| if (!vtable->va##func##GLX) \ |
| return VA_STATUS_ERROR_UNIMPLEMENTED; \ |
| status = vtable->va##func##GLX args; \ |
| } while (0) |
| |
| |
| // Destroy VA/GLX display context |
| static void va_DisplayContextDestroy(VADisplayContextP pDisplayContext) |
| { |
| VADisplayContextGLXP pDisplayContextGLX; |
| VADriverContextP pDriverContext; |
| VADriverContextGLXP pDriverContextGLX; |
| |
| if (!pDisplayContext) |
| return; |
| |
| pDriverContext = pDisplayContext->pDriverContext; |
| pDriverContextGLX = pDriverContext->glx; |
| if (pDriverContextGLX) { |
| free(pDriverContextGLX); |
| pDriverContext->glx = NULL; |
| } |
| |
| pDisplayContextGLX = pDisplayContext->opaque; |
| if (pDisplayContextGLX) { |
| vaDestroyFunc vaDestroy = pDisplayContextGLX->vaDestroy; |
| free(pDisplayContextGLX); |
| pDisplayContext->opaque = NULL; |
| if (vaDestroy) |
| vaDestroy(pDisplayContext); |
| } |
| } |
| |
| // Return a suitable VADisplay for VA API |
| VADisplay vaGetDisplayGLX(Display *native_dpy) |
| { |
| VADisplay dpy = NULL; |
| VADisplayContextP pDisplayContext = NULL; |
| VADisplayContextGLXP pDisplayContextGLX = NULL; |
| VADriverContextP pDriverContext; |
| VADriverContextGLXP pDriverContextGLX = NULL; |
| |
| dpy = vaGetDisplay(native_dpy); |
| if (!dpy) |
| return NULL; |
| pDisplayContext = (VADisplayContextP)dpy; |
| pDriverContext = pDisplayContext->pDriverContext; |
| |
| pDisplayContextGLX = calloc(1, sizeof(*pDisplayContextGLX)); |
| if (!pDisplayContextGLX) |
| goto error; |
| |
| pDriverContextGLX = calloc(1, sizeof(*pDriverContextGLX)); |
| if (!pDriverContextGLX) |
| goto error; |
| |
| pDriverContext->display_type = VA_DISPLAY_GLX; |
| pDisplayContextGLX->vaDestroy = pDisplayContext->vaDestroy; |
| pDisplayContext->vaDestroy = va_DisplayContextDestroy; |
| pDisplayContext->opaque = pDisplayContextGLX; |
| pDriverContext->glx = pDriverContextGLX; |
| return dpy; |
| |
| error: |
| free(pDriverContextGLX); |
| free(pDisplayContextGLX); |
| pDisplayContext->vaDestroy(pDisplayContext); |
| return NULL; |
| } |
| |
| // Create a surface used for display to OpenGL |
| VAStatus vaCreateSurfaceGLX( |
| VADisplay dpy, |
| GLenum target, |
| GLuint texture, |
| void **gl_surface |
| ) |
| { |
| VADriverContextP ctx; |
| VAStatus status; |
| |
| /* Make sure it is a valid GL texture object */ |
| if (!glIsTexture(texture)) |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| |
| INIT_CONTEXT(ctx, dpy); |
| |
| INVOKE(ctx, CreateSurface, (ctx, target, texture, gl_surface)); |
| return status; |
| } |
| |
| // Destroy a VA/GLX surface |
| VAStatus vaDestroySurfaceGLX( |
| VADisplay dpy, |
| void *gl_surface |
| ) |
| { |
| VADriverContextP ctx; |
| VAStatus status; |
| |
| INIT_CONTEXT(ctx, dpy); |
| |
| INVOKE(ctx, DestroySurface, (ctx, gl_surface)); |
| return status; |
| } |
| |
| // Copy a VA surface to a VA/GLX surface |
| VAStatus vaCopySurfaceGLX( |
| VADisplay dpy, |
| void *gl_surface, |
| VASurfaceID surface, |
| unsigned int flags |
| ) |
| { |
| VADriverContextP ctx; |
| VAStatus status; |
| |
| INIT_CONTEXT(ctx, dpy); |
| |
| INVOKE(ctx, CopySurface, (ctx, gl_surface, surface, flags)); |
| return status; |
| } |