Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: third_party/libva/va/egl/va_egl_impl.c

Issue 10375035: Add libva to chromium third_party. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 #define _GNU_SOURCE 1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <stdarg.h>
5 #include <string.h>
6 #include <assert.h>
7 #include <dlfcn.h>
8
9 #include "va_egl_private.h"
10 #include "va_egl_impl.h"
11
12 static int
13 check_extension(const char *name, const char *exts)
14 {
15 const char *end;
16 int name_len, n;
17
18 if (!name || !exts)
19 return 0;
20
21 end = exts + strlen(exts);
22 name_len = strlen(name);
23
24 while (exts < end) {
25 n = strcspn(exts, " ");
26
27 if (n == name_len && strncmp(name, exts, n) == 0)
28 return 1;
29
30 exts += (n + 1);
31 }
32
33 return 0;
34 }
35
36 static int
37 check_pixmap_extensions(VADriverContextP ctx, EGLDisplay egl_display)
38 {
39 const char *exts;
40
41 exts = (const char *)eglQueryString(egl_display, EGL_EXTENSIONS);
42
43 if (!check_extension("EGL_KHR_image_pixmap", exts))
44 return 0;
45
46 return 1;
47 }
48
49 /* ========================================================================= */
50 /* === VA/EGL implementation from the driver (fordward calls) === */
51 /* ========================================================================= */
52 #ifdef INVOKE
53 #undef INVOKE
54 #endif
55
56 #define INVOKE(ctx, func, args) do { \
57 VADriverVTableEGLP vtable = (ctx)->vtable_egl; \
58 if (!vtable->va##func##EGL) \
59 return VA_STATUS_ERROR_UNIMPLEMENTED; \
60 \
61 VAStatus status = vtable->va##func##EGL args; \
62 if (status != VA_STATUS_SUCCESS) \
63 return status; \
64 } while (0)
65
66
67 static VAStatus
68 vaQuerySurfaceTargetsEGL_impl_driver(VADisplay dpy,
69 EGLenum *target_list,
70 int *num_targets)
71 {
72 VADriverContextP ctx = ((VADisplayContextP)(dpy))->pDriverContext;
73
74 INVOKE(ctx, QuerySurfaceTargets, (ctx, target_list, num_targets));
75
76 return VA_STATUS_SUCCESS;
77 }
78
79 static VAStatus
80 vaCreateSurfaceEGL_impl_driver(VADisplay dpy,
81 EGLenum target,
82 unsigned int width,
83 unsigned int height,
84 VASurfaceEGL *gl_surface)
85 {
86 VADriverContextP ctx = ((VADisplayContextP)(dpy))->pDriverContext;
87
88 INVOKE(ctx, CreateSurface, (ctx, target, width, height, gl_surface));
89
90 return VA_STATUS_SUCCESS;
91 }
92
93 static VAStatus
94 vaDestroySurfaceEGL_impl_driver(VADisplay dpy, VASurfaceEGL egl_surface)
95 {
96 VADriverContextP ctx = ((VADisplayContextP)(dpy))->pDriverContext;
97
98 INVOKE(ctx, DestroySurface, (ctx, egl_surface));
99
100 return VA_STATUS_SUCCESS;
101 }
102
103 static VAStatus
104 vaAssociateSurfaceEGL_impl_driver(VADisplay dpy,
105 VASurfaceEGL egl_surface,
106 VASurfaceID surface,
107 unsigned int flags)
108 {
109 VADriverContextP ctx = ((VADisplayContextP)(dpy))->pDriverContext;
110
111 INVOKE(ctx, AssociateSurface, (ctx, egl_surface, surface, flags));
112
113 return VA_STATUS_SUCCESS;
114 }
115
116 static VAStatus
117 vaSyncSurfaceEGL_impl_driver(VADisplay dpy,
118 VASurfaceEGL egl_surface)
119 {
120 VADriverContextP ctx = ((VADisplayContextP)(dpy))->pDriverContext;
121
122 INVOKE(ctx, SyncSurface, (ctx, egl_surface));
123
124 return VA_STATUS_SUCCESS;
125 }
126
127 static VAStatus
128 vaGetSurfaceInfoEGL_impl_driver(VADisplay dpy,
129 VASurfaceEGL egl_surface,
130 EGLenum *target,
131 EGLClientBuffer *buffer,
132 EGLint *attrib_list,
133 int *num_attribs)
134 {
135 VADriverContextP ctx = ((VADisplayContextP)(dpy))->pDriverContext;
136
137 INVOKE(ctx, GetSurfaceInfo, (ctx, egl_surface, target, buffer, attrib_list, num_attribs));
138
139 return VA_STATUS_SUCCESS;
140 }
141
142 static VAStatus
143 vaDeassociateSurfaceEGL_impl_driver(VADisplay dpy,
144 VASurfaceEGL egl_surface)
145 {
146 VADriverContextP ctx = ((VADisplayContextP)(dpy))->pDriverContext;
147
148 INVOKE(ctx, DeassociateSurface, (ctx, egl_surface));
149
150 return VA_STATUS_SUCCESS;
151 }
152
153 #undef INVOKE
154
155 /* ========================================================================= */
156 /* === VA/EGL helpers === */
157 /* ========================================================================= */
158 /** Unique VASurfaceImplEGL identifier */
159 #define VA_SURFACE_IMPL_EGL_MAGIC VA_FOURCC('V','E','G','L')
160
161 struct VASurfaceImplEGL {
162 uint32_t magic; ///< Magic number identifying a VASurfaceImp lEGL
163 VASurfaceID surface; ///< Associated VA surface
164 EGLenum target; ///< EGL target
165 EGLClientBuffer buffer;
166 unsigned int width;
167 unsigned int height;
168 unsigned int flags;
169 };
170
171 static void *
172 create_native_pixmap(VADisplay dpy, unsigned int width, unsigned int height)
173 {
174 VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
175 VAStatus status;
176 void *native_pixmap = NULL;
177
178 status = pDisplayContext->vaCreateNativePixmap(pDisplayContext, width, heigh t, &native_pixmap);
179
180 if (status != VA_STATUS_SUCCESS)
181 native_pixmap = NULL;
182
183 return native_pixmap;
184 }
185
186 static void
187 destroy_native_pixmap(VADisplay dpy, void *native_pixmap)
188 {
189 VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
190
191 pDisplayContext->vaFreeNativePixmap(pDisplayContext, native_pixmap);
192 }
193
194 // Check VASurfaceImplEGL is valid
195 static inline int check_surface(VASurfaceImplEGLP pSurfaceImplEGL)
196 {
197 return pSurfaceImplEGL && pSurfaceImplEGL->magic == VA_SURFACE_IMPL_EGL_MAGI C;
198 }
199
200 static inline VAStatus
201 deassociate_surface(VADriverContextP ctx, VASurfaceImplEGLP pSurfaceImplEGL)
202 {
203 pSurfaceImplEGL->surface = VA_INVALID_SURFACE;
204
205 return VA_STATUS_SUCCESS;
206 }
207
208 static VAStatus
209 associate_surface(VADriverContextP ctx,
210 VASurfaceImplEGLP pSurfaceImplEGL,
211 VASurfaceID surface,
212 unsigned int flags)
213 {
214 VAStatus status;
215 status = deassociate_surface(ctx, pSurfaceImplEGL);
216
217 if (status != VA_STATUS_SUCCESS)
218 return status;
219
220 pSurfaceImplEGL->surface = surface;
221 pSurfaceImplEGL->flags = flags;
222
223 return VA_STATUS_SUCCESS;
224 }
225
226 static inline VAStatus
227 sync_surface(VADriverContextP ctx, VASurfaceImplEGLP pSurfaceImplEGL)
228 {
229 if (pSurfaceImplEGL->surface == VA_INVALID_SURFACE)
230 return VA_STATUS_ERROR_INVALID_SURFACE;
231
232 return ctx->vtable->vaSyncSurface(ctx, pSurfaceImplEGL->surface);
233 }
234
235 static VAStatus
236 sync_associated_surface(VADriverContextP ctx, VASurfaceImplEGLP pSurfaceImplEGL)
237 {
238 VAStatus status;
239
240 status = sync_surface(ctx, pSurfaceImplEGL);
241
242 if (status != VA_STATUS_SUCCESS)
243 return status;
244
245 if (pSurfaceImplEGL->target != EGL_NATIVE_PIXMAP_KHR)
246 return VA_STATUS_ERROR_UNIMPLEMENTED;
247
248 status = ctx->vtable->vaPutSurface(
249 ctx,
250 pSurfaceImplEGL->surface,
251 (void *)pSurfaceImplEGL->buffer,
252 0, 0, pSurfaceImplEGL->width, pSurfaceImplEGL->height,
253 0, 0, pSurfaceImplEGL->width, pSurfaceImplEGL->height,
254 NULL, 0,
255 pSurfaceImplEGL->flags
256 );
257
258 if (status == VA_STATUS_SUCCESS) {
259 eglWaitNative(EGL_CORE_NATIVE_ENGINE);
260 }
261
262 return status;
263 }
264
265 /* ========================================================================= */
266 /* === VA/EGL implementation from libVA (generic and suboptimal path) === */
267 /* ========================================================================= */
268 #ifdef INIT_SURFACE
269 #undef INIT_SURFACE
270 #endif
271
272 #define INIT_SURFACE(surface, egl_surface) do { \
273 surface = (VASurfaceImplEGLP)(egl_surface); \
274 if (!check_surface(surface)) \
275 return VA_STATUS_ERROR_INVALID_SURFACE; \
276 } while (0)
277
278 static VAStatus
279 vaQuerySurfaceTargetsEGL_impl_libva(VADisplay dpy,
280 EGLenum *target_list,
281 int *num_targets)
282 {
283 int i = 0;
284
285 /* FIXME: support other targets ??? */
286 target_list[i++] = EGL_NATIVE_PIXMAP_KHR;
287 *num_targets = i;
288 assert(i <= IMPL_MAX_EGL_SURFACE_TARGETS);
289
290 return VA_STATUS_SUCCESS;
291 }
292
293 static VAStatus
294 vaCreateSurfaceEGL_impl_libva(VADisplay dpy,
295 EGLenum target,
296 unsigned int width,
297 unsigned int height,
298 VASurfaceEGL *egl_surface)
299 {
300 VASurfaceImplEGLP pSurfaceImplEGL = NULL;
301
302 /* So far only support for EGL_NATIVE_PIXMAP_KHR */
303 if (target != 0 && target != EGL_NATIVE_PIXMAP_KHR)
304 return VA_STATUS_ERROR_INVALID_PARAMETER;
305
306 pSurfaceImplEGL = calloc(1, sizeof(*pSurfaceImplEGL));
307
308 if (!pSurfaceImplEGL) {
309 *egl_surface = 0;
310 return VA_STATUS_ERROR_ALLOCATION_FAILED;
311 }
312
313 pSurfaceImplEGL->magic = VA_SURFACE_IMPL_EGL_MAGIC;
314 pSurfaceImplEGL->surface = VA_INVALID_SURFACE;
315 pSurfaceImplEGL->target = target == 0 ? EGL_NATIVE_PIXMAP_KHR : target;
316 pSurfaceImplEGL->buffer = 0;
317 pSurfaceImplEGL->width = width;
318 pSurfaceImplEGL->height = height;
319 *egl_surface = (VASurfaceEGL)pSurfaceImplEGL;
320
321 return VA_STATUS_SUCCESS;
322 }
323
324 static VAStatus
325 vaDestroySurfaceEGL_impl_libva(VADisplay dpy, VASurfaceEGL egl_surface)
326 {
327 VASurfaceImplEGLP pSurfaceImplEGL;
328
329 INIT_SURFACE(pSurfaceImplEGL, egl_surface);
330
331 if (pSurfaceImplEGL->target == EGL_NATIVE_PIXMAP_KHR) {
332 if (pSurfaceImplEGL->buffer) {
333 destroy_native_pixmap(dpy, pSurfaceImplEGL->buffer);
334 pSurfaceImplEGL->buffer = 0;
335 }
336 }
337
338 free(pSurfaceImplEGL);
339
340 return VA_STATUS_SUCCESS;
341 }
342
343 static VAStatus
344 vaAssociateSurfaceEGL_impl_libva(
345 VADisplay dpy,
346 VASurfaceEGL egl_surface,
347 VASurfaceID surface,
348 unsigned int flags
349 )
350 {
351 VADriverContextP ctx = ((VADisplayContextP)(dpy))->pDriverContext;
352 VASurfaceImplEGLP pSurfaceImplEGL;
353 VAStatus status;
354
355 INIT_SURFACE(pSurfaceImplEGL, egl_surface);
356
357 if (surface == VA_INVALID_SURFACE)
358 return VA_STATUS_ERROR_INVALID_SURFACE;
359
360 if (pSurfaceImplEGL->target == EGL_NATIVE_PIXMAP_KHR) {
361 if (pSurfaceImplEGL->buffer)
362 destroy_native_pixmap(dpy, pSurfaceImplEGL->buffer);
363
364 pSurfaceImplEGL->buffer = create_native_pixmap(dpy, pSurfaceImplEGL->wid th, pSurfaceImplEGL->height);
365 }
366
367 pSurfaceImplEGL->surface = surface;
368 pSurfaceImplEGL->flags = flags;
369
370 if (pSurfaceImplEGL->buffer)
371 return VA_STATUS_SUCCESS;
372
373 return VA_STATUS_ERROR_UNKNOWN;
374 }
375
376 static VAStatus
377 vaSyncSurfaceEGL_impl_libva(VADisplay dpy,
378 VASurfaceEGL egl_surface)
379 {
380 VADriverContextP ctx = ((VADisplayContextP)(dpy))->pDriverContext;
381 VASurfaceImplEGLP pSurfaceImplEGL;
382 VAStatus status;
383
384 INIT_SURFACE(pSurfaceImplEGL, egl_surface);
385
386 status = sync_associated_surface(ctx, pSurfaceImplEGL);
387
388 return status;
389 }
390
391 static VAStatus
392 vaGetSurfaceInfoEGL_impl_libva(VADisplay dpy,
393 VASurfaceEGL egl_surface,
394 EGLenum *target,
395 EGLClientBuffer *buffer,
396 EGLint *attrib_list,
397 int *num_attribs)
398 {
399 VADriverContextP ctx = ((VADisplayContextP)(dpy))->pDriverContext;
400 VASurfaceImplEGLP pSurfaceImplEGL;
401 VAStatus status;
402 int i = 0;
403
404 INIT_SURFACE(pSurfaceImplEGL, egl_surface);
405
406 if (pSurfaceImplEGL->surface == VA_INVALID_SURFACE)
407 return VA_STATUS_ERROR_INVALID_SURFACE;
408
409 if (*num_attribs < IMPL_MAX_EGL_SURFACE_ATTRIBUTES)
410 return VA_STATUS_ERROR_INVALID_PARAMETER;
411
412 *target = pSurfaceImplEGL->target;
413 *buffer = pSurfaceImplEGL->buffer;
414
415 if (pSurfaceImplEGL->target == EGL_NATIVE_PIXMAP_KHR) {
416 attrib_list[i++] = EGL_IMAGE_PRESERVED_KHR;
417 attrib_list[i + 1] = EGL_TRUE;
418 attrib_list[i++] = EGL_NONE;
419 } else {
420 /* FIXME later */
421 attrib_list[i++] = EGL_NONE;
422 }
423
424 *num_attribs = i;
425
426 return VA_STATUS_SUCCESS;
427 }
428
429 static VAStatus
430 vaDeassociateSurfaceEGL_impl_libva(
431 VADisplay dpy,
432 VASurfaceEGL egl_surface
433 )
434 {
435 VADriverContextP ctx = ((VADisplayContextP)(dpy))->pDriverContext;
436 VASurfaceImplEGLP pSurfaceImplEGL;
437 VAStatus status;
438
439 INIT_SURFACE(pSurfaceImplEGL, egl_surface);
440
441 if (pSurfaceImplEGL->target == EGL_NATIVE_PIXMAP_KHR) {
442 if (pSurfaceImplEGL->buffer)
443 destroy_native_pixmap(dpy, pSurfaceImplEGL->buffer);
444
445 pSurfaceImplEGL->buffer = 0;
446 }
447
448 pSurfaceImplEGL->surface = VA_INVALID_SURFACE;
449
450 return VA_STATUS_SUCCESS;
451 }
452
453 #undef INIT_SURFACE
454
455 /* ========================================================================= */
456 /* === Private VA/EGL vtable initialization === */
457 /* ========================================================================= */
458
459 // Initialize EGL driver context
460 VAStatus va_egl_init_context(VADisplay dpy)
461 {
462 VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
463 VADriverContextP ctx = pDisplayContext->pDriverContext;
464 VADriverContextEGLP egl_ctx = VA_DRIVER_CONTEXT_EGL(ctx);
465 VADriverVTablePrivEGLP vtable = &egl_ctx->vtable;
466
467 if (egl_ctx->is_initialized)
468 return VA_STATUS_SUCCESS;
469
470 if (ctx->vtable_egl && ctx->vtable_egl->vaCreateSurfaceEGL) {
471 vtable->vaQuerySurfaceTargetsEGL = vaQuerySurfaceTargetsEGL_impl_driver;
472 vtable->vaCreateSurfaceEGL = vaCreateSurfaceEGL_impl_driver;
473 vtable->vaDestroySurfaceEGL = vaDestroySurfaceEGL_impl_driver;
474 vtable->vaAssociateSurfaceEGL = vaAssociateSurfaceEGL_impl_driver;
475 vtable->vaSyncSurfaceEGL = vaSyncSurfaceEGL_impl_driver;
476 vtable->vaGetSurfaceInfoEGL = vaGetSurfaceInfoEGL_impl_driver;
477 vtable->vaDeassociateSurfaceEGL = vaDeassociateSurfaceEGL_impl_driver;
478 }
479 else {
480 if (pDisplayContext->vaCreateNativePixmap == NULL ||
481 pDisplayContext->vaFreeNativePixmap == NULL)
482 return VA_STATUS_ERROR_UNIMPLEMENTED;
483
484 if (!check_pixmap_extensions(ctx, egl_ctx->egl_display))
485 return VA_STATUS_ERROR_UNIMPLEMENTED;
486
487 vtable->vaQuerySurfaceTargetsEGL = vaQuerySurfaceTargetsEGL_impl_libva;
488 vtable->vaCreateSurfaceEGL = vaCreateSurfaceEGL_impl_libva;
489 vtable->vaDestroySurfaceEGL = vaDestroySurfaceEGL_impl_libva;
490 vtable->vaAssociateSurfaceEGL = vaAssociateSurfaceEGL_impl_libva;
491 vtable->vaSyncSurfaceEGL = vaSyncSurfaceEGL_impl_libva;
492 vtable->vaGetSurfaceInfoEGL = vaGetSurfaceInfoEGL_impl_libva;
493 vtable->vaDeassociateSurfaceEGL = vaDeassociateSurfaceEGL_impl_libva;
494 }
495
496 egl_ctx->is_initialized = 1;
497
498 return VA_STATUS_SUCCESS;
499 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698