2 * Copyright (c) 2007 Intel Corporation. All Rights Reserved.
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:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
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.
26 * Initial EGL backend, and subject to change
28 * Gstreamer gst-gltexture has a framework to support associating a buffer
29 * to a texture via EGL_KHR_image_base and GL_OES_EGL_image_external.
32 * EGLImageKHR eglCreateImageKHR(
36 * EGLClientBuffer buffer,
37 * const EGLint *attrib_list)
39 * GL_OES_EGL_image_external:
40 * This extension provides a mechanism for creating EGLImage texture targets
41 * from EGLImages. This extension defines a new texture target TEXTURE_EXTERNAL_OES.
42 * This texture target can only be specified using an EGLImage.
43 * The first eglCreateImageKHR will create an EGLImage from an EGLClientBufferm, and with
44 * an EGLImage, gst-gltexture can use GL_OES_EGL_image_external extension to create textures.
46 * eglCreateImageKHR and GL_OES_EGL_image_external are all called directly from gst-gltexture,
47 * thus the simplest way to support gst-gltexture is defining a new API to pass EGLClientBuffer
50 * EGLClientBuffer is gfx/video driver implementation specific (?). It means we need to pass up
51 * the low-level buffer ID (or handle) of the decoded surface to gst-gltexture, and gst-gltexture
52 * then pass down it to gfx driver.
54 * Bellow API vaGetEGLClientBufferFromSurface is for this purpose
56 #include "va_egl_private.h"
57 #include "va_egl_impl.h"
59 #define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext)
60 #define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; }
62 #define INIT_CONTEXT(ctx, dpy) do { \
63 if (!vaDisplayIsValid(dpy)) \
64 return VA_STATUS_ERROR_INVALID_DISPLAY; \
66 ctx = ((VADisplayContextP)(dpy))->pDriverContext; \
68 return VA_STATUS_ERROR_INVALID_DISPLAY; \
70 status = va_egl_init_context(dpy); \
71 if (status != VA_STATUS_SUCCESS) \
75 #define INVOKE(ctx, func, args) do { \
76 VADriverVTablePrivEGLP vtable; \
77 vtable = &VA_DRIVER_CONTEXT_EGL(ctx)->vtable; \
78 if (!vtable->va##func##EGL) \
79 return VA_STATUS_ERROR_UNIMPLEMENTED; \
80 status = vtable->va##func##EGL args; \
84 VAStatus vaGetEGLClientBufferFromSurface (
87 EGLClientBuffer *buffer /* out*/
91 struct VADriverVTableEGL *va_egl;
95 va_egl = (struct VADriverVTableEGL *)ctx->vtable_egl;
96 if (va_egl && va_egl->vaGetEGLClientBufferFromSurface) {
97 return va_egl->vaGetEGLClientBufferFromSurface(ctx, surface, buffer);
99 return VA_STATUS_ERROR_UNIMPLEMENTED;
102 // Destroy VA/EGL display context
103 static void va_DisplayContextDestroy(VADisplayContextP pDisplayContext)
105 VADisplayContextEGLP pDisplayContextEGL;
106 VADriverContextP pDriverContext;
107 VADriverContextEGLP pDriverContextEGL;
109 if (!pDisplayContext)
112 pDriverContext = pDisplayContext->pDriverContext;
113 pDriverContextEGL = pDriverContext->egl;
114 if (pDriverContextEGL) {
115 free(pDriverContextEGL);
116 pDriverContext->egl = NULL;
119 pDisplayContextEGL = pDisplayContext->opaque;
120 if (pDisplayContextEGL) {
121 vaDestroyFunc vaDestroy = pDisplayContextEGL->vaDestroy;
122 free(pDisplayContextEGL);
123 pDisplayContext->opaque = NULL;
125 vaDestroy(pDisplayContext);
129 // Return a suitable VADisplay for VA API
130 VADisplay vaGetDisplayEGL(VANativeDisplay native_dpy,
133 VADisplay dpy = NULL;
134 VADisplayContextP pDisplayContext = NULL;
135 VADisplayContextEGLP pDisplayContextEGL = NULL;
136 VADriverContextP pDriverContext;
137 VADriverContextEGLP pDriverContextEGL = NULL;
139 dpy = vaGetDisplay(native_dpy);
144 if (egl_dpy == EGL_NO_DISPLAY)
147 pDisplayContext = (VADisplayContextP)dpy;
148 pDriverContext = pDisplayContext->pDriverContext;
150 pDisplayContextEGL = calloc(1, sizeof(*pDisplayContextEGL));
151 if (!pDisplayContextEGL)
154 pDriverContextEGL = calloc(1, sizeof(*pDriverContextEGL));
155 if (!pDriverContextEGL)
158 pDisplayContextEGL->vaDestroy = pDisplayContext->vaDestroy;
159 pDisplayContext->vaDestroy = va_DisplayContextDestroy;
160 pDisplayContext->opaque = pDisplayContextEGL;
161 pDriverContextEGL->egl_display = egl_dpy;
162 pDriverContext->egl = pDriverContextEGL;
166 free(pDriverContextEGL);
167 free(pDisplayContextEGL);
168 pDisplayContext->vaDestroy(pDisplayContext);
172 int vaMaxNumSurfaceTargetsEGL(
176 VADriverContextP ctx;
177 struct VADriverVTableEGL *va_egl;
181 va_egl = (struct VADriverVTableEGL *)ctx->vtable_egl;
184 return va_egl->max_egl_surface_targets;
186 return IMPL_MAX_EGL_SURFACE_TARGETS;
189 int vaMaxNumSurfaceAttributesEGL(
193 VADriverContextP ctx;
194 struct VADriverVTableEGL *va_egl;
198 va_egl = (struct VADriverVTableEGL *)ctx->vtable_egl;
201 return va_egl->max_egl_surface_attributes;
203 return IMPL_MAX_EGL_SURFACE_ATTRIBUTES;
206 VAStatus vaQuerySurfaceTargetsEGL(
208 EGLenum *target_list, /* out */
209 int *num_targets /* out */
212 VADriverContextP ctx;
215 INIT_CONTEXT(ctx, dpy);
217 INVOKE(ctx, QuerySurfaceTargets, (dpy, target_list, num_targets));
221 VAStatus vaCreateSurfaceEGL(
226 VASurfaceEGL *gl_surface
229 VADriverContextP ctx;
232 INIT_CONTEXT(ctx, dpy);
234 INVOKE(ctx, CreateSurface, (dpy, target, width, height, gl_surface));
238 // Destroy a VA/EGL surface
239 VAStatus vaDestroySurfaceEGL(
241 VASurfaceEGL egl_surface
244 VADriverContextP ctx;
247 INIT_CONTEXT(ctx, dpy);
249 INVOKE(ctx, DestroySurface, (dpy, egl_surface));
253 VAStatus vaAssociateSurfaceEGL(
255 VASurfaceEGL egl_surface,
260 VADriverContextP ctx;
263 INIT_CONTEXT(ctx, dpy);
265 INVOKE(ctx, AssociateSurface, (dpy, egl_surface, surface, flags));
269 VAStatus vaSyncSurfaceEGL(
271 VASurfaceEGL egl_surface
274 VADriverContextP ctx;
277 INIT_CONTEXT(ctx, dpy);
279 INVOKE(ctx, SyncSurface, (dpy, egl_surface));
283 VAStatus vaGetSurfaceInfoEGL(
285 VASurfaceEGL egl_surface,
286 EGLenum *target, /* out, the type of <buffer> */
287 EGLClientBuffer *buffer, /* out */
288 EGLint *attrib_list, /* out, the last attribute must be EGL_NONE */
289 int *num_attribs /* in/out */
292 VADriverContextP ctx;
295 INIT_CONTEXT(ctx, dpy);
297 INVOKE(ctx, GetSurfaceInfo, (dpy, egl_surface, target, buffer, attrib_list, num_attribs));
301 VAStatus vaDeassociateSurfaceEGL(
303 VASurfaceEGL egl_surface
306 VADriverContextP ctx;
309 INIT_CONTEXT(ctx, dpy);
311 INVOKE(ctx, DeassociateSurface, (dpy, egl_surface));