OSDN Git Service

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