Generate proper error for NULL display.
[profile/ivi/libva.git] / src / va.c
1 /*
2  * Copyright (c) 2007 Intel Corporation. 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 "X11/Xlib.h"
26 #include "va.h"
27 #include "va_backend.h"
28
29 #include "assert.h"
30 #include <stdarg.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <dlfcn.h>
34 #include <unistd.h>
35 #include "va_dri.h"
36
37 #define DEFAULT_DRIVER_DIR      "/usr/X11R6/lib/modules/dri"
38 #define DRIVER_EXTENSION        "_drv_video.so"
39 #define DRIVER_INIT_FUNC        "__vaDriverInit_0_26"
40
41 #define CTX(dpy) ((VADriverContextP) dpy );
42 #define CHECK_CONTEXT(dpy) if( !vaContextIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; }
43 #define ASSERT          assert
44 #define CHECK_VTABLE(s, ctx, func) if (!va_checkVtable(ctx->vtable.va##func, #func)) s = VA_STATUS_ERROR_UNKNOWN;
45 #define CHECK_MAXIMUM(s, ctx, var) if (!va_checkMaximum(ctx->max_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN;
46 #define CHECK_STRING(s, ctx, var) if (!va_checkString(ctx->str_##var, #var)) s = VA_STATUS_ERROR_UNKNOWN;
47
48 #define TRACE(func) if (va_debug_trace) va_infoMessage("[TR] %s\n", #func);
49
50 static VADriverContextP pDriverContexts = NULL;
51 static int va_debug_trace = 0;
52
53 static Bool vaContextIsValid(VADriverContextP arg_ctx)
54 {
55   VADriverContextP ctx = pDriverContexts;
56   
57   while (ctx)
58   {
59       if (ctx == arg_ctx)
60       {
61           return True;
62       }
63       ctx = ctx->pNext;
64   }
65   return False;
66 }
67
68 VADisplay vaGetDisplay (
69     NativeDisplay native_dpy    /* implementation specific */
70 )
71 {
72   VADisplay dpy = NULL;
73   VADriverContextP ctx = pDriverContexts;
74
75   if (!native_dpy)
76   {
77       return NULL;
78   }
79
80   while (ctx)
81   {
82       if (ctx->x11_dpy == (Display *)native_dpy)
83       {
84           dpy = (VADisplay) ctx;
85           break;
86       }
87       ctx = ctx->pNext;
88   }
89   
90   if (!dpy)
91   {
92       /* create new entry */
93       ctx = (VADriverContextP) calloc(1, sizeof(struct VADriverContext));
94       ctx->pNext = pDriverContexts;
95       ctx->x11_dpy = (Display *) native_dpy;
96       pDriverContexts = ctx;
97       dpy = (VADisplay) ctx;
98   }
99   
100   return dpy;
101 }
102
103 static void va_errorMessage(const char *msg, ...)
104 {
105     va_list args;
106
107     fprintf(stderr, "libva error: ");
108     va_start(args, msg);
109     vfprintf(stderr, msg, args);
110     va_end(args);
111 }
112
113 static void va_infoMessage(const char *msg, ...)
114 {
115     va_list args;
116
117     fprintf(stderr, "libva: ");
118     va_start(args, msg);
119     vfprintf(stderr, msg, args);
120     va_end(args);
121 }
122
123 static Bool va_checkVtable(void *ptr, char *function)
124 {
125     if (!ptr)
126     {
127         va_errorMessage("No valid vtable entry for va%s\n", function);
128         return False;
129     }
130     return True;
131 }
132
133 static Bool va_checkMaximum(int value, char *variable)
134 {
135     if (!value)
136     {
137         va_errorMessage("Failed to define max_%s in init\n", variable);
138         return False;
139     }
140     return True;
141 }
142
143 static Bool va_checkString(const char* value, char *variable)
144 {
145     if (!value)
146     {
147         va_errorMessage("Failed to define str_%s in init\n", variable);
148         return False;
149     }
150     return True;
151 }
152
153 static VAStatus va_getDriverName(VADriverContextP ctx, char **driver_name)
154 {
155     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
156     int direct_capable;
157     int driver_major;
158     int driver_minor;
159     int driver_patch;
160     Bool result = True;
161     
162     *driver_name = NULL;
163     if (geteuid() == getuid())
164     {
165         /* don't allow setuid apps to use LIBVA_DRIVER_NAME */
166         if (getenv("LIBVA_DRIVER_NAME"))
167         {
168             /* For easier debugging */
169             *driver_name = strdup(getenv("LIBVA_DRIVER_NAME"));
170             return VA_STATUS_SUCCESS;
171         }
172     }
173     if (result)
174     {
175         result = VA_DRIQueryDirectRenderingCapable(ctx->x11_dpy, ctx->x11_screen, &direct_capable);
176         if (!result)
177         {
178             va_errorMessage("VA_DRIQueryDirectRenderingCapable failed\n");
179         }
180     }
181     if (result)
182     {
183         result = direct_capable;
184         if (!result)
185         {
186             va_errorMessage("VA_DRIQueryDirectRenderingCapable returned false\n");
187         }
188     }
189     if (result)
190     {
191         result = VA_DRIGetClientDriverName(ctx->x11_dpy, ctx->x11_screen, &driver_major, &driver_minor,
192                                             &driver_patch, driver_name);
193         if (!result)
194         {
195             va_errorMessage("VA_DRIGetClientDriverName returned false\n");
196         }
197     }
198     if (result)
199     {
200         vaStatus = VA_STATUS_SUCCESS;
201         va_infoMessage("VA_DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
202              driver_major, driver_minor, driver_patch, *driver_name, ctx->x11_screen);
203     }
204
205     return vaStatus;
206 }
207
208 static VAStatus va_openDriver(VADriverContextP ctx, char *driver_name)
209 {
210     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
211     char *search_path;
212     char *saveptr;
213     char *driver_dir;
214     
215     if (geteuid() == getuid())
216     {
217         /* don't allow setuid apps to use LIBVA_DRIVERS_PATH */
218         search_path = getenv("LIBVA_DRIVERS_PATH");
219         if (!search_path)
220         {
221             search_path = getenv("LIBGL_DRIVERS_PATH");
222         }
223     }
224     if (!search_path)
225     {
226         search_path = DEFAULT_DRIVER_DIR;
227     }
228
229     search_path = strdup(search_path);
230     driver_dir = strtok_r(search_path, ":", &saveptr);
231     while(driver_dir)
232     {
233         void *handle = NULL;
234         char *driver_path = (char *) malloc( strlen(driver_dir) +
235                                              strlen(driver_name) +
236                                              strlen(DRIVER_EXTENSION) + 2 );
237         strcpy( driver_path, driver_dir );
238         strcat( driver_path, "/" );
239         strcat( driver_path, driver_name );
240         strcat( driver_path, DRIVER_EXTENSION );
241         
242         va_infoMessage("Trying to open %s\n", driver_path);
243
244         handle = dlopen( driver_path, RTLD_NOW | RTLD_GLOBAL );
245         if (!handle)
246         {
247             /* Don't give errors for non-existing files */
248             if (0 == access( driver_path, F_OK))
249             {   
250                 va_errorMessage("dlopen of %s failed: %s\n", driver_path, dlerror());
251             }
252         }
253         else
254         {
255             VADriverInit init_func;
256             init_func = (VADriverInit) dlsym(handle, DRIVER_INIT_FUNC);
257             if (!init_func)
258             {
259                 va_errorMessage("%s has no function %s\n", driver_path, DRIVER_INIT_FUNC);
260                 dlclose(handle);
261             }
262             else
263             {
264                 vaStatus = (*init_func)(ctx);
265
266                 if (VA_STATUS_SUCCESS == vaStatus)
267                 {
268                     CHECK_MAXIMUM(vaStatus, ctx, profiles);
269                     CHECK_MAXIMUM(vaStatus, ctx, entrypoints);
270                     CHECK_MAXIMUM(vaStatus, ctx, attributes);
271                     CHECK_MAXIMUM(vaStatus, ctx, image_formats);
272                     CHECK_MAXIMUM(vaStatus, ctx, subpic_formats);
273                     CHECK_MAXIMUM(vaStatus, ctx, display_attributes);
274                     CHECK_STRING(vaStatus, ctx, vendor);
275                     CHECK_VTABLE(vaStatus, ctx, Terminate);
276                     CHECK_VTABLE(vaStatus, ctx, QueryConfigProfiles);
277                     CHECK_VTABLE(vaStatus, ctx, QueryConfigEntrypoints);
278                     CHECK_VTABLE(vaStatus, ctx, QueryConfigAttributes);
279                     CHECK_VTABLE(vaStatus, ctx, CreateConfig);
280                     CHECK_VTABLE(vaStatus, ctx, DestroyConfig);
281                     CHECK_VTABLE(vaStatus, ctx, GetConfigAttributes);
282                     CHECK_VTABLE(vaStatus, ctx, CreateSurfaces);
283                     CHECK_VTABLE(vaStatus, ctx, DestroySurfaces);
284                     CHECK_VTABLE(vaStatus, ctx, CreateContext);
285                     CHECK_VTABLE(vaStatus, ctx, DestroyContext);
286                     CHECK_VTABLE(vaStatus, ctx, CreateBuffer);
287                     CHECK_VTABLE(vaStatus, ctx, BufferSetNumElements);
288                     CHECK_VTABLE(vaStatus, ctx, MapBuffer);
289                     CHECK_VTABLE(vaStatus, ctx, UnmapBuffer);
290                     CHECK_VTABLE(vaStatus, ctx, DestroyBuffer);
291                     CHECK_VTABLE(vaStatus, ctx, BeginPicture);
292                     CHECK_VTABLE(vaStatus, ctx, RenderPicture);
293                     CHECK_VTABLE(vaStatus, ctx, EndPicture);
294                     CHECK_VTABLE(vaStatus, ctx, SyncSurface);
295                     CHECK_VTABLE(vaStatus, ctx, QuerySurfaceStatus);
296                     CHECK_VTABLE(vaStatus, ctx, PutSurface);
297                     CHECK_VTABLE(vaStatus, ctx, QueryImageFormats);
298                     CHECK_VTABLE(vaStatus, ctx, CreateImage);
299                     CHECK_VTABLE(vaStatus, ctx, DestroyImage);
300                     CHECK_VTABLE(vaStatus, ctx, SetImagePalette);
301                     CHECK_VTABLE(vaStatus, ctx, GetImage);
302                     CHECK_VTABLE(vaStatus, ctx, PutImage);
303                     CHECK_VTABLE(vaStatus, ctx, QuerySubpictureFormats);
304                     CHECK_VTABLE(vaStatus, ctx, CreateSubpicture);
305                     CHECK_VTABLE(vaStatus, ctx, DestroySubpicture);
306                     CHECK_VTABLE(vaStatus, ctx, SetSubpictureImage);
307                     CHECK_VTABLE(vaStatus, ctx, SetSubpicturePalette);
308                     CHECK_VTABLE(vaStatus, ctx, SetSubpictureChromakey);
309                     CHECK_VTABLE(vaStatus, ctx, SetSubpictureGlobalAlpha);
310                     CHECK_VTABLE(vaStatus, ctx, AssociateSubpicture);
311                     CHECK_VTABLE(vaStatus, ctx, DeassociateSubpicture);
312                     CHECK_VTABLE(vaStatus, ctx, QueryDisplayAttributes);
313                     CHECK_VTABLE(vaStatus, ctx, GetDisplayAttributes);
314                     CHECK_VTABLE(vaStatus, ctx, SetDisplayAttributes);
315                     CHECK_VTABLE(vaStatus, ctx, DbgCopySurfaceToBuffer);
316                 }
317                 if (VA_STATUS_SUCCESS != vaStatus)
318                 {
319                     va_errorMessage("%s init failed\n", driver_path);
320                     dlclose(handle);
321                 }
322                 if (VA_STATUS_SUCCESS == vaStatus)
323                 {
324                     ctx->handle = handle;
325                 }
326                 free(driver_path);
327                 break;
328             }
329         }
330         free(driver_path);
331         
332         driver_dir = strtok_r(NULL, ":", &saveptr);
333     }
334     
335     free(search_path);    
336     
337     return vaStatus;
338 }
339
340
341 /*
342  * Returns a short english description of error_status
343  */
344 const char *vaErrorStr(VAStatus error_status)
345 {
346     switch(error_status)
347     {
348         case VA_STATUS_SUCCESS:
349             return "success (no error)";
350         case VA_STATUS_ERROR_ALLOCATION_FAILED:
351             return "resource allocation failed";
352         case VA_STATUS_ERROR_INVALID_CONFIG:
353             return "invalid VAConfigID";
354         case VA_STATUS_ERROR_INVALID_CONTEXT:
355             return "invalid VAContextID";
356         case VA_STATUS_ERROR_INVALID_SURFACE:
357             return "invalid VASurfaceID";
358         case VA_STATUS_ERROR_INVALID_BUFFER:
359             return "invalid VABufferID";
360         case VA_STATUS_ERROR_ATTR_NOT_SUPPORTED:
361             return "attribute not supported";
362         case VA_STATUS_ERROR_MAX_NUM_EXCEEDED:
363             return "list argument exceeds maximum number";
364         case VA_STATUS_ERROR_UNSUPPORTED_PROFILE:
365             return "the requested VAProfile is not supported";
366         case VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT:
367             return "the requested VAEntryPoint is not supported";
368         case VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT:
369             return "the requested RT Format is not supported";
370         case VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE:
371             return "the requested VABufferType is not supported";
372         case VA_STATUS_ERROR_UNKNOWN:
373             return "unknown libva error";
374     }
375     return "unknown libva error / description missing";
376 }
377       
378 VAStatus vaInitialize (
379     VADisplay dpy,
380     int *major_version,  /* out */
381     int *minor_version   /* out */
382 )
383 {
384   VADriverContextP ctx = CTX(dpy);
385   char *driver_name = NULL;
386   VAStatus vaStatus;
387   
388   CHECK_CONTEXT(ctx);
389
390   va_debug_trace = (getenv("LIBVA_DEBUG_TRACE") != NULL);
391
392   vaStatus = va_getDriverName(ctx, &driver_name);
393   va_infoMessage("va_getDriverName() returns %d\n", vaStatus);
394   
395   if (VA_STATUS_SUCCESS == vaStatus)
396   {
397       vaStatus = va_openDriver(ctx, driver_name);
398       va_infoMessage("va_openDriver() returns %d\n", vaStatus);
399       
400       *major_version = ctx->version_major;
401       *minor_version = ctx->version_minor;
402   }
403
404   if (driver_name)
405   {
406       XFree(driver_name);
407   }
408   return vaStatus;
409 }
410
411
412 /*
413  * After this call, all library internal resources will be cleaned up
414  */ 
415 VAStatus vaTerminate (
416     VADisplay dpy
417 )
418 {
419   VAStatus vaStatus = VA_STATUS_SUCCESS;
420   VADriverContextP old_ctx = CTX(dpy);
421   CHECK_CONTEXT(old_ctx);
422
423   if (old_ctx->handle)
424   {
425       vaStatus = old_ctx->vtable.vaTerminate(old_ctx);
426       dlclose(old_ctx->handle);
427       old_ctx->handle = NULL;
428   }
429
430   if (VA_STATUS_SUCCESS == vaStatus)
431   {
432       VADriverContextP *ctx = &pDriverContexts;
433
434       /* Throw away old_ctx */
435       while (*ctx)
436       {
437           if (*ctx == old_ctx)
438           {
439               *ctx = old_ctx->pNext;
440               old_ctx->pNext = NULL;
441               break;
442           }
443           ctx = &((*ctx)->pNext);
444       }
445       free(old_ctx);
446   }
447   return vaStatus;
448 }
449
450 /*
451  * vaQueryVendorString returns a pointer to a zero-terminated string
452  * describing some aspects of the VA implemenation on a specific
453  * hardware accelerator. The format of the returned string is:
454  * <vendorname>-<major_version>-<minor_version>-<addtional_info>
455  * e.g. for the Intel GMA500 implementation, an example would be:
456  * "IntelGMA500-1.0-0.2-patch3
457  */
458 const char *vaQueryVendorString (
459     VADisplay dpy
460 )
461 {
462   VADriverContextP ctx = CTX(dpy);
463   if( !vaContextIsValid(ctx) )
464   {
465       return NULL;
466   }
467   
468   return ctx->str_vendor;
469 }
470
471
472 /* Get maximum number of profiles supported by the implementation */
473 int vaMaxNumProfiles (
474     VADisplay dpy
475 )
476 {
477   VADriverContextP ctx = CTX(dpy);
478   if( !vaContextIsValid(ctx) )
479   {
480       return 0;
481   }
482   
483   return ctx->max_profiles;
484 }
485
486 /* Get maximum number of entrypoints supported by the implementation */
487 int vaMaxNumEntrypoints (
488     VADisplay dpy
489 )
490 {
491   VADriverContextP ctx = CTX(dpy);
492   if( !vaContextIsValid(ctx) )
493   {
494       return 0;
495   }
496   
497   return ctx->max_entrypoints;
498 }
499
500
501 /* Get maximum number of attributs supported by the implementation */
502 int vaMaxNumConfigAttributes (
503     VADisplay dpy
504 )
505 {
506   VADriverContextP ctx = CTX(dpy);
507   if( !vaContextIsValid(ctx) )
508   {
509       return 0;
510   }
511   
512   return ctx->max_attributes;
513 }
514
515 VAStatus vaQueryConfigEntrypoints (
516     VADisplay dpy,
517     VAProfile profile,
518     VAEntrypoint *entrypoints,  /* out */
519     int *num_entrypoints        /* out */
520 )
521 {
522   VADriverContextP ctx = CTX(dpy);
523   CHECK_CONTEXT(ctx);
524
525   TRACE(vaQueryConfigEntrypoints);
526   return ctx->vtable.vaQueryConfigEntrypoints ( ctx, profile, entrypoints, num_entrypoints);
527 }
528
529 VAStatus vaGetConfigAttributes (
530     VADisplay dpy,
531     VAProfile profile,
532     VAEntrypoint entrypoint,
533     VAConfigAttrib *attrib_list, /* in/out */
534     int num_attribs
535 )
536 {
537   VADriverContextP ctx = CTX(dpy);
538   CHECK_CONTEXT(ctx);
539
540   TRACE(vaGetConfigAttributes);
541   return ctx->vtable.vaGetConfigAttributes ( ctx, profile, entrypoint, attrib_list, num_attribs );
542 }
543
544 VAStatus vaQueryConfigProfiles (
545     VADisplay dpy,
546     VAProfile *profile_list,    /* out */
547     int *num_profiles           /* out */
548 )
549 {
550   VADriverContextP ctx = CTX(dpy);
551   CHECK_CONTEXT(ctx);
552
553   TRACE(vaQueryConfigProfiles);
554   return ctx->vtable.vaQueryConfigProfiles ( ctx, profile_list, num_profiles );
555 }
556
557 VAStatus vaCreateConfig (
558     VADisplay dpy,
559     VAProfile profile, 
560     VAEntrypoint entrypoint, 
561     VAConfigAttrib *attrib_list,
562     int num_attribs,
563     VAConfigID *config_id /* out */
564 )
565 {
566   VADriverContextP ctx = CTX(dpy);
567   CHECK_CONTEXT(ctx);
568
569   TRACE(vaCreateConfig);
570   return ctx->vtable.vaCreateConfig ( ctx, profile, entrypoint, attrib_list, num_attribs, config_id );
571 }
572
573 VAStatus vaDestroyConfig (
574     VADisplay dpy,
575     VAConfigID config_id
576 )
577 {
578   VADriverContextP ctx = CTX(dpy);
579   CHECK_CONTEXT(ctx);
580
581   TRACE(vaDestroyConfig);
582   return ctx->vtable.vaDestroyConfig ( ctx, config_id );
583 }
584
585 VAStatus vaQueryConfigAttributes (
586     VADisplay dpy,
587     VAConfigID config_id, 
588     VAProfile *profile,         /* out */
589     VAEntrypoint *entrypoint,   /* out */
590     VAConfigAttrib *attrib_list,/* out */
591     int *num_attribs            /* out */
592 )
593 {
594   VADriverContextP ctx = CTX(dpy);
595   CHECK_CONTEXT(ctx);
596
597   TRACE(vaQueryConfigAttributes);
598   return ctx->vtable.vaQueryConfigAttributes( ctx, config_id, profile, entrypoint, attrib_list, num_attribs);
599 }
600
601 VAStatus vaCreateSurfaces (
602     VADisplay dpy,
603     int width,
604     int height,
605     int format,
606     int num_surfaces,
607     VASurfaceID *surfaces       /* out */
608 )
609 {
610   VADriverContextP ctx = CTX(dpy);
611   CHECK_CONTEXT(ctx);
612
613   TRACE(vaCreateSurfaces);
614   return ctx->vtable.vaCreateSurfaces( ctx, width, height, format, num_surfaces, surfaces );
615 }
616
617 VAStatus vaDestroySurfaces (
618     VADisplay dpy,
619     VASurfaceID *surface_list,
620     int num_surfaces
621 )
622 {
623   VADriverContextP ctx = CTX(dpy);
624   CHECK_CONTEXT(ctx);
625
626   TRACE(vaDestroySurfaces);
627   return ctx->vtable.vaDestroySurfaces( ctx, surface_list, num_surfaces );
628 }
629
630 VAStatus vaCreateContext (
631     VADisplay dpy,
632     VAConfigID config_id,
633     int picture_width,
634     int picture_height,
635     int flag,
636     VASurfaceID *render_targets,
637     int num_render_targets,
638     VAContextID *context                /* out */
639 )
640 {
641   VADriverContextP ctx = CTX(dpy);
642   CHECK_CONTEXT(ctx);
643
644   TRACE(vaCreateContext);
645   return ctx->vtable.vaCreateContext( ctx, config_id, picture_width, picture_height,
646                                       flag, render_targets, num_render_targets, context );
647 }
648
649 VAStatus vaDestroyContext (
650     VADisplay dpy,
651     VAContextID context
652 )
653 {
654   VADriverContextP ctx = CTX(dpy);
655   CHECK_CONTEXT(ctx);
656
657   TRACE(vaDestroyContext);
658   return ctx->vtable.vaDestroyContext( ctx, context );
659 }
660
661 VAStatus vaCreateBuffer (
662     VADisplay dpy,
663     VAContextID context,        /* in */
664     VABufferType type,          /* in */
665     unsigned int size,          /* in */
666     unsigned int num_elements,  /* in */
667     void *data,                 /* in */
668     VABufferID *buf_id          /* out */
669 )
670 {
671   VADriverContextP ctx = CTX(dpy);
672   CHECK_CONTEXT(ctx);
673
674   TRACE(vaCreateBuffer);
675   return ctx->vtable.vaCreateBuffer( ctx, context, type, size, num_elements, data, buf_id);
676 }
677
678 VAStatus vaBufferSetNumElements (
679     VADisplay dpy,
680     VABufferID buf_id,  /* in */
681     unsigned int num_elements /* in */
682 )
683 {
684   VADriverContextP ctx = CTX(dpy);
685   CHECK_CONTEXT(ctx);
686
687   TRACE(vaBufferSetNumElements);
688   return ctx->vtable.vaBufferSetNumElements( ctx, buf_id, num_elements );
689 }
690
691
692 VAStatus vaMapBuffer (
693     VADisplay dpy,
694     VABufferID buf_id,  /* in */
695     void **pbuf         /* out */
696 )
697 {
698   VADriverContextP ctx = CTX(dpy);
699   CHECK_CONTEXT(ctx);
700
701   TRACE(vaMapBuffer);
702   return ctx->vtable.vaMapBuffer( ctx, buf_id, pbuf );
703 }
704
705 VAStatus vaUnmapBuffer (
706     VADisplay dpy,
707     VABufferID buf_id   /* in */
708 )
709 {
710   VADriverContextP ctx = CTX(dpy);
711   CHECK_CONTEXT(ctx);
712
713   TRACE(vaUnmapBuffer);
714   return ctx->vtable.vaUnmapBuffer( ctx, buf_id );
715 }
716
717 VAStatus vaDestroyBuffer (
718     VADisplay dpy,
719     VABufferID buffer_id
720 )
721 {
722   VADriverContextP ctx = CTX(dpy);
723   CHECK_CONTEXT(ctx);
724
725   TRACE(vaDestroyBuffer);
726   return ctx->vtable.vaDestroyBuffer( ctx, buffer_id );
727 }
728
729 VAStatus vaBeginPicture (
730     VADisplay dpy,
731     VAContextID context,
732     VASurfaceID render_target
733 )
734 {
735   VADriverContextP ctx = CTX(dpy);
736   CHECK_CONTEXT(ctx);
737
738   TRACE(vaBeginPicture);
739   return ctx->vtable.vaBeginPicture( ctx, context, render_target );
740 }
741
742 VAStatus vaRenderPicture (
743     VADisplay dpy,
744     VAContextID context,
745     VABufferID *buffers,
746     int num_buffers
747 )
748 {
749   VADriverContextP ctx = CTX(dpy);
750   CHECK_CONTEXT(ctx);
751
752   TRACE(vaRenderPicture);
753   return ctx->vtable.vaRenderPicture( ctx, context, buffers, num_buffers );
754 }
755
756 VAStatus vaEndPicture (
757     VADisplay dpy,
758     VAContextID context
759 )
760 {
761   VADriverContextP ctx = CTX(dpy);
762   CHECK_CONTEXT(ctx);
763
764   TRACE(vaEndPicture);
765   return ctx->vtable.vaEndPicture( ctx, context );
766 }
767
768 VAStatus vaSyncSurface (
769     VADisplay dpy,
770     VAContextID context,
771     VASurfaceID render_target
772 )
773 {
774   VADriverContextP ctx = CTX(dpy);
775   CHECK_CONTEXT(ctx);
776
777   TRACE(vaSyncSurface);
778   return ctx->vtable.vaSyncSurface( ctx, context, render_target );
779 }
780
781 VAStatus vaQuerySurfaceStatus (
782     VADisplay dpy,
783     VASurfaceID render_target,
784     VASurfaceStatus *status     /* out */
785 )
786 {
787   VADriverContextP ctx = CTX(dpy);
788   CHECK_CONTEXT(ctx);
789
790   TRACE(vaQuerySurfaceStatus);
791   return ctx->vtable.vaQuerySurfaceStatus( ctx, render_target, status );
792 }
793
794 VAStatus vaPutSurface (
795     VADisplay dpy,
796     VASurfaceID surface,
797     Drawable draw, /* X Drawable */
798     short srcx,
799     short srcy,
800     unsigned short srcw,
801     unsigned short srch,
802     short destx,
803     short desty,
804     unsigned short destw,
805     unsigned short desth,
806     VARectangle *cliprects, /* client supplied clip list */
807     unsigned int number_cliprects, /* number of clip rects in the clip list */
808     unsigned int flags /* de-interlacing flags */
809 )
810 {
811   VADriverContextP ctx = CTX(dpy);
812   CHECK_CONTEXT(ctx);
813
814   TRACE(vaPutSurface);
815   return ctx->vtable.vaPutSurface( ctx, surface, draw, srcx, srcy, srcw, srch,
816                                    destx, desty, destw, desth,
817                                    cliprects, number_cliprects, flags );
818 }
819
820 /* Get maximum number of image formats supported by the implementation */
821 int vaMaxNumImageFormats (
822     VADisplay dpy
823 )
824 {
825   VADriverContextP ctx = CTX(dpy);
826   if( !vaContextIsValid(ctx) )
827   {
828       return 0;
829   }
830   
831   return ctx->max_image_formats;
832 }
833
834 VAStatus vaQueryImageFormats (
835     VADisplay dpy,
836     VAImageFormat *format_list, /* out */
837     int *num_formats            /* out */
838 )
839 {
840   VADriverContextP ctx = CTX(dpy);
841   CHECK_CONTEXT(ctx);
842
843   TRACE(vaQueryImageFormats);
844   return ctx->vtable.vaQueryImageFormats ( ctx, format_list, num_formats);
845 }
846
847 /* 
848  * The width and height fields returned in the VAImage structure may get 
849  * enlarged for some YUV formats. The size of the data buffer that needs
850  * to be allocated will be given in the "data_size" field in VAImage.
851  * Image data is not allocated by this function.  The client should
852  * allocate the memory and fill in the VAImage structure's data field
853  * after looking at "data_size" returned from the library.
854  */
855 VAStatus vaCreateImage (
856     VADisplay dpy,
857     VAImageFormat *format,
858     int width,
859     int height,
860     VAImage *image      /* out */
861 )
862 {
863   VADriverContextP ctx = CTX(dpy);
864   CHECK_CONTEXT(ctx);
865
866   TRACE(vaCreateImage);
867   return ctx->vtable.vaCreateImage ( ctx, format, width, height, image);
868 }
869
870 /*
871  * Should call DestroyImage before destroying the surface it is bound to
872  */
873 VAStatus vaDestroyImage (
874     VADisplay dpy,
875     VAImageID image
876 )
877 {
878   VADriverContextP ctx = CTX(dpy);
879   CHECK_CONTEXT(ctx);
880
881   TRACE(vaDestroyImage);
882   return ctx->vtable.vaDestroyImage ( ctx, image);
883 }
884
885 VAStatus vaSetImagePalette (
886     VADisplay dpy,
887     VAImageID image,
888     unsigned char *palette
889 )
890 {
891   VADriverContextP ctx = CTX(dpy);
892   CHECK_CONTEXT(ctx);
893
894   TRACE(vaSetImagePalette);
895   return ctx->vtable.vaSetImagePalette ( ctx, image, palette);
896 }
897
898 /*
899  * Retrieve surface data into a VAImage
900  * Image must be in a format supported by the implementation
901  */
902 VAStatus vaGetImage (
903     VADisplay dpy,
904     VASurfaceID surface,
905     int x,      /* coordinates of the upper left source pixel */
906     int y,
907     unsigned int width, /* width and height of the region */
908     unsigned int height,
909     VAImageID image
910 )
911 {
912   VADriverContextP ctx = CTX(dpy);
913   CHECK_CONTEXT(ctx);
914
915   TRACE(vaGetImage);
916   return ctx->vtable.vaGetImage ( ctx, surface, x, y, width, height, image);
917 }
918
919 /*
920  * Copy data from a VAImage to a surface
921  * Image must be in a format supported by the implementation
922  */
923 VAStatus vaPutImage (
924     VADisplay dpy,
925     VASurfaceID surface,
926     VAImageID image,
927     int src_x,
928     int src_y,
929     unsigned int width,
930     unsigned int height,
931     int dest_x,
932     int dest_y
933 )
934 {
935   VADriverContextP ctx = CTX(dpy);
936   CHECK_CONTEXT(ctx);
937
938   TRACE(vaPutImage);
939   return ctx->vtable.vaPutImage ( ctx, surface, image, src_x, src_y, width, height, dest_x, dest_y );
940 }
941
942 /* Get maximum number of subpicture formats supported by the implementation */
943 int vaMaxNumSubpictureFormats (
944     VADisplay dpy
945 )
946 {
947   VADriverContextP ctx = CTX(dpy);
948   if( !vaContextIsValid(ctx) )
949   {
950       return 0;
951   }
952   
953   return ctx->max_subpic_formats;
954 }
955
956 /* 
957  * Query supported subpicture formats 
958  * The caller must provide a "format_list" array that can hold at
959  * least vaMaxNumSubpictureFormats() entries. The flags arrary holds the flag 
960  * for each format to indicate additional capabilities for that format. The actual 
961  * number of formats returned in "format_list" is returned in "num_formats".
962  */
963 VAStatus vaQuerySubpictureFormats (
964     VADisplay dpy,
965     VAImageFormat *format_list, /* out */
966     unsigned int *flags,        /* out */
967     unsigned int *num_formats   /* out */
968 )
969 {
970   VADriverContextP ctx = CTX(dpy);
971   CHECK_CONTEXT(ctx);
972
973   TRACE(vaQuerySubpictureFormats);
974   return ctx->vtable.vaQuerySubpictureFormats ( ctx, format_list, flags, num_formats);
975 }
976
977 /* 
978  * Subpictures are created with an image associated. 
979  */
980 VAStatus vaCreateSubpicture (
981     VADisplay dpy,
982     VAImageID image,
983     VASubpictureID *subpicture  /* out */
984 )
985 {
986   VADriverContextP ctx = CTX(dpy);
987   CHECK_CONTEXT(ctx);
988
989   TRACE(vaCreateSubpicture);
990   return ctx->vtable.vaCreateSubpicture ( ctx, image, subpicture );
991 }
992
993 /*
994  * Destroy the subpicture before destroying the image it is assocated to
995  */
996 VAStatus vaDestroySubpicture (
997     VADisplay dpy,
998     VASubpictureID subpicture
999 )
1000 {
1001   VADriverContextP ctx = CTX(dpy);
1002   CHECK_CONTEXT(ctx);
1003
1004   TRACE(vaDestroySubpicture);
1005   return ctx->vtable.vaDestroySubpicture ( ctx, subpicture);
1006 }
1007
1008 VAStatus vaSetSubpictureImage (
1009     VADisplay dpy,
1010     VASubpictureID subpicture,
1011     VAImageID image
1012 )
1013 {
1014   VADriverContextP ctx = CTX(dpy);
1015   CHECK_CONTEXT(ctx);
1016
1017   TRACE(vaSetSubpictureImage);
1018   return ctx->vtable.vaSetSubpictureImage ( ctx, subpicture, image);
1019 }
1020
1021
1022 VAStatus vaSetSubpicturePalette (
1023     VADisplay dpy,
1024     VASubpictureID subpicture,
1025     /* 
1026      * pointer to an array holding the palette data.  The size of the array is 
1027      * num_palette_entries * entry_bytes in size.  The order of the components
1028      * in the palette is described by the component_order in VASubpicture struct
1029      */
1030     unsigned char *palette 
1031 )
1032 {
1033   VADriverContextP ctx = CTX(dpy);
1034   CHECK_CONTEXT(ctx);
1035
1036   TRACE(vaSetSubpicturePalette);
1037   return ctx->vtable.vaSetSubpicturePalette ( ctx, subpicture, palette);
1038 }
1039
1040 /*
1041  * If chromakey is enabled, then the area where the source value falls within
1042  * the chromakey [min, max] range is transparent
1043  */
1044 VAStatus vaSetSubpictureChromakey (
1045     VADisplay dpy,
1046     VASubpictureID subpicture,
1047     unsigned int chromakey_min,
1048     unsigned int chromakey_max,
1049     unsigned int chromakey_mask
1050 )
1051 {
1052   VADriverContextP ctx = CTX(dpy);
1053   CHECK_CONTEXT(ctx);
1054
1055   TRACE(vaSetSubpictureChromakey);
1056   return ctx->vtable.vaSetSubpictureChromakey ( ctx, subpicture, chromakey_min, chromakey_max, chromakey_mask );
1057 }
1058
1059
1060 /*
1061  * Global alpha value is between 0 and 1. A value of 1 means fully opaque and 
1062  * a value of 0 means fully transparent. If per-pixel alpha is also specified then
1063  * the overall alpha is per-pixel alpha multiplied by the global alpha
1064  */
1065 VAStatus vaSetSubpictureGlobalAlpha (
1066     VADisplay dpy,
1067     VASubpictureID subpicture,
1068     float global_alpha 
1069 )
1070 {
1071   VADriverContextP ctx = CTX(dpy);
1072   CHECK_CONTEXT(ctx);
1073
1074   TRACE(vaSetSubpictureGlobalAlpha);
1075   return ctx->vtable.vaSetSubpictureGlobalAlpha ( ctx, subpicture, global_alpha );
1076 }
1077
1078 /*
1079   vaAssociateSubpicture associates the subpicture with the target_surface.
1080   It defines the region mapping between the subpicture and the target 
1081   surface through source and destination rectangles (with the same width and height).
1082   Both will be displayed at the next call to vaPutSurface.  Additional
1083   associations before the call to vaPutSurface simply overrides the association.
1084 */
1085 VAStatus vaAssociateSubpicture (
1086     VADisplay dpy,
1087     VASubpictureID subpicture,
1088     VASurfaceID *target_surfaces,
1089     int num_surfaces,
1090     short src_x, /* upper left offset in subpicture */
1091     short src_y,
1092     short dest_x, /* upper left offset in surface */
1093     short dest_y,
1094     unsigned short width,
1095     unsigned short height,
1096     /*
1097      * whether to enable chroma-keying or global-alpha
1098      * see VA_SUBPICTURE_XXX values
1099      */
1100     unsigned int flags
1101 )
1102 {
1103   VADriverContextP ctx = CTX(dpy);
1104   CHECK_CONTEXT(ctx);
1105
1106   TRACE(vaAssociateSubpicture);
1107   return ctx->vtable.vaAssociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces, src_x, src_y, dest_x, dest_y, width, height, flags );
1108 }
1109
1110 /*
1111  * vaDeassociateSubpicture removes the association of the subpicture with target_surfaces.
1112  */
1113 VAStatus vaDeassociateSubpicture (
1114     VADisplay dpy,
1115     VASubpictureID subpicture,
1116     VASurfaceID *target_surfaces,
1117     int num_surfaces
1118 )
1119 {
1120   VADriverContextP ctx = CTX(dpy);
1121   CHECK_CONTEXT(ctx);
1122
1123   TRACE(vaDeassociateSubpicture);
1124   return ctx->vtable.vaDeassociateSubpicture ( ctx, subpicture, target_surfaces, num_surfaces );
1125 }
1126
1127
1128 /* Get maximum number of display attributes supported by the implementation */
1129 int vaMaxNumDisplayAttributes (
1130     VADisplay dpy
1131 )
1132 {
1133   VADriverContextP ctx = CTX(dpy);
1134   if( !vaContextIsValid(ctx) )
1135   {
1136       return 0;
1137   }
1138   
1139   return ctx->max_display_attributes;
1140 }
1141
1142 /* 
1143  * Query display attributes 
1144  * The caller must provide a "attr_list" array that can hold at
1145  * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1146  * returned in "attr_list" is returned in "num_attributes".
1147  */
1148 VAStatus vaQueryDisplayAttributes (
1149     VADisplay dpy,
1150     VADisplayAttribute *attr_list,      /* out */
1151     int *num_attributes                 /* out */
1152 )
1153 {
1154   VADriverContextP ctx = CTX(dpy);
1155   CHECK_CONTEXT(ctx);
1156
1157   TRACE(vaQueryDisplayAttributes);
1158   return ctx->vtable.vaQueryDisplayAttributes ( ctx, attr_list, num_attributes );
1159 }
1160
1161 /* 
1162  * Get display attributes 
1163  * This function returns the current attribute values in "attr_list".
1164  * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1165  * from vaQueryDisplayAttributes() can have their values retrieved.  
1166  */
1167 VAStatus vaGetDisplayAttributes (
1168     VADisplay dpy,
1169     VADisplayAttribute *attr_list,      /* in/out */
1170     int num_attributes
1171 )
1172 {
1173   VADriverContextP ctx = CTX(dpy);
1174   CHECK_CONTEXT(ctx);
1175
1176   TRACE(vaGetDisplayAttributes);
1177   return ctx->vtable.vaGetDisplayAttributes ( ctx, attr_list, num_attributes );
1178 }
1179
1180 /* 
1181  * Set display attributes 
1182  * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1183  * from vaQueryDisplayAttributes() can be set.  If the attribute is not settable or 
1184  * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1185  */
1186 VAStatus vaSetDisplayAttributes (
1187     VADisplay dpy,
1188     VADisplayAttribute *attr_list,
1189     int num_attributes
1190 )
1191 {
1192   VADriverContextP ctx = CTX(dpy);
1193   CHECK_CONTEXT(ctx);
1194
1195   TRACE(vaSetDisplayAttributes);
1196   return ctx->vtable.vaSetDisplayAttributes ( ctx, attr_list, num_attributes );
1197 }
1198
1199
1200
1201 VAStatus vaDbgCopySurfaceToBuffer(VADisplay dpy,
1202     VASurfaceID surface,
1203     void **buffer, /* out */
1204     unsigned int *stride /* out */
1205 )
1206 {
1207   VADriverContextP ctx = CTX(dpy);
1208   CHECK_CONTEXT(ctx);
1209
1210   TRACE(vaDbgCopySurfaceToBuffer);
1211   return ctx->vtable.vaDbgCopySurfaceToBuffer( ctx, surface, buffer, stride );
1212 }
1213