i965_drv_vidoe: thread safety for rendering
[platform/upstream/libva.git] / dummy_drv_video / dummy_drv_video.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 "config.h"
26 #include <va/va_backend.h>
27
28 #include "dummy_drv_video.h"
29
30 #include "assert.h"
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <stdarg.h>
35
36 #define ASSERT  assert
37
38 #define INIT_DRIVER_DATA        struct dummy_driver_data *driver_data = (struct dummy_driver_data *) ctx->pDriverData;
39
40 #define CONFIG(id)  ((object_config_p) object_heap_lookup( &driver_data->config_heap, id ))
41 #define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
42 #define SURFACE(id)     ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id ))
43 #define BUFFER(id)  ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id ))
44
45 #define CONFIG_ID_OFFSET                0x01000000
46 #define CONTEXT_ID_OFFSET               0x02000000
47 #define SURFACE_ID_OFFSET               0x04000000
48 #define BUFFER_ID_OFFSET                0x08000000
49
50 static void dummy__error_message(const char *msg, ...)
51 {
52     va_list args;
53
54     fprintf(stderr, "dummy_drv_video error: ");
55     va_start(args, msg);
56     vfprintf(stderr, msg, args);
57     va_end(args);
58 }
59
60 static void dummy__information_message(const char *msg, ...)
61 {
62     va_list args;
63
64     fprintf(stderr, "dummy_drv_video: ");
65     va_start(args, msg);
66     vfprintf(stderr, msg, args);
67     va_end(args);
68 }
69
70 VAStatus dummy_QueryConfigProfiles(
71                 VADriverContextP ctx,
72                 VAProfile *profile_list,        /* out */
73                 int *num_profiles                       /* out */
74         )
75 {
76     INIT_DRIVER_DATA
77     int i = 0;
78
79     profile_list[i++] = VAProfileMPEG2Simple;
80     profile_list[i++] = VAProfileMPEG2Main;
81     profile_list[i++] = VAProfileMPEG4Simple;
82     profile_list[i++] = VAProfileMPEG4AdvancedSimple;
83     profile_list[i++] = VAProfileMPEG4Main;
84     profile_list[i++] = VAProfileH264Baseline;
85     profile_list[i++] = VAProfileH264Main;
86     profile_list[i++] = VAProfileH264High;
87     profile_list[i++] = VAProfileVC1Simple;
88     profile_list[i++] = VAProfileVC1Main;
89     profile_list[i++] = VAProfileVC1Advanced;
90
91     /* If the assert fails then DUMMY_MAX_PROFILES needs to be bigger */
92     ASSERT(i <= DUMMY_MAX_PROFILES);
93     *num_profiles = i;
94
95     return VA_STATUS_SUCCESS;
96 }
97
98 VAStatus dummy_QueryConfigEntrypoints(
99                 VADriverContextP ctx,
100                 VAProfile profile,
101                 VAEntrypoint  *entrypoint_list, /* out */
102                 int *num_entrypoints            /* out */
103         )
104 {
105     INIT_DRIVER_DATA
106
107     switch (profile) {
108         case VAProfileMPEG2Simple:
109         case VAProfileMPEG2Main:
110                 *num_entrypoints = 2;
111                 entrypoint_list[0] = VAEntrypointVLD;
112                 entrypoint_list[1] = VAEntrypointMoComp;
113                 break;
114
115         case VAProfileMPEG4Simple:
116         case VAProfileMPEG4AdvancedSimple:
117         case VAProfileMPEG4Main:
118                 *num_entrypoints = 1;
119                 entrypoint_list[0] = VAEntrypointVLD;
120                 break;
121
122         case VAProfileH264Baseline:
123         case VAProfileH264Main:
124         case VAProfileH264High:
125                 *num_entrypoints = 1;
126                 entrypoint_list[0] = VAEntrypointVLD;
127                 break;
128
129         case VAProfileVC1Simple:
130         case VAProfileVC1Main:
131         case VAProfileVC1Advanced:
132                 *num_entrypoints = 1;
133                 entrypoint_list[0] = VAEntrypointVLD;
134                 break;
135
136         default:
137                 *num_entrypoints = 0;
138                 break;
139     }
140
141     /* If the assert fails then DUMMY_MAX_ENTRYPOINTS needs to be bigger */
142     ASSERT(*num_entrypoints <= DUMMY_MAX_ENTRYPOINTS);
143     return VA_STATUS_SUCCESS;
144 }
145
146 VAStatus dummy_GetConfigAttributes(
147                 VADriverContextP ctx,
148                 VAProfile profile,
149                 VAEntrypoint entrypoint,
150                 VAConfigAttrib *attrib_list,    /* in/out */
151                 int num_attribs
152         )
153 {
154     INIT_DRIVER_DATA
155
156     int i;
157
158     /* Other attributes don't seem to be defined */
159     /* What to do if we don't know the attribute? */
160     for (i = 0; i < num_attribs; i++)
161     {
162         switch (attrib_list[i].type)
163         {
164           case VAConfigAttribRTFormat:
165               attrib_list[i].value = VA_RT_FORMAT_YUV420;
166               break;
167
168           default:
169               /* Do nothing */
170               attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
171               break;
172         }
173     }
174
175     return VA_STATUS_SUCCESS;
176 }
177
178 static VAStatus dummy__update_attribute(object_config_p obj_config, VAConfigAttrib *attrib)
179 {
180     int i;
181     /* Check existing attrbiutes */
182     for(i = 0; obj_config->attrib_count < i; i++)
183     {
184         if (obj_config->attrib_list[i].type == attrib->type)
185         {
186             /* Update existing attribute */
187             obj_config->attrib_list[i].value = attrib->value;
188             return VA_STATUS_SUCCESS;
189         }
190     }
191     if (obj_config->attrib_count < DUMMY_MAX_CONFIG_ATTRIBUTES)
192     {
193         i = obj_config->attrib_count;
194         obj_config->attrib_list[i].type = attrib->type;
195         obj_config->attrib_list[i].value = attrib->value;
196         obj_config->attrib_count++;
197         return VA_STATUS_SUCCESS;
198     }
199     return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
200 }
201
202 VAStatus dummy_CreateConfig(
203                 VADriverContextP ctx,
204                 VAProfile profile,
205                 VAEntrypoint entrypoint,
206                 VAConfigAttrib *attrib_list,
207                 int num_attribs,
208                 VAConfigID *config_id           /* out */
209         )
210 {
211     INIT_DRIVER_DATA
212     VAStatus vaStatus;
213     int configID;
214     object_config_p obj_config;
215     int i;
216
217     /* Validate profile & entrypoint */
218     switch (profile) {
219         case VAProfileMPEG2Simple:
220         case VAProfileMPEG2Main:
221                 if ((VAEntrypointVLD == entrypoint) ||
222                     (VAEntrypointMoComp == entrypoint))
223                 {
224                     vaStatus = VA_STATUS_SUCCESS;
225                 }
226                 else
227                 {
228                     vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
229                 }
230                 break;
231
232         case VAProfileMPEG4Simple:
233         case VAProfileMPEG4AdvancedSimple:
234         case VAProfileMPEG4Main:
235                 if (VAEntrypointVLD == entrypoint)
236                 {
237                     vaStatus = VA_STATUS_SUCCESS;
238                 }
239                 else
240                 {
241                     vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
242                 }
243                 break;
244
245         case VAProfileH264Baseline:
246         case VAProfileH264Main:
247         case VAProfileH264High:
248                 if (VAEntrypointVLD == entrypoint)
249                 {
250                     vaStatus = VA_STATUS_SUCCESS;
251                 }
252                 else
253                 {
254                     vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
255                 }
256                 break;
257
258         case VAProfileVC1Simple:
259         case VAProfileVC1Main:
260         case VAProfileVC1Advanced:
261                 if (VAEntrypointVLD == entrypoint)
262                 {
263                     vaStatus = VA_STATUS_SUCCESS;
264                 }
265                 else
266                 {
267                     vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
268                 }
269                 break;
270
271         default:
272                 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
273                 break;
274     }
275
276     if (VA_STATUS_SUCCESS != vaStatus)
277     {
278         return vaStatus;
279     }
280
281     configID = object_heap_allocate( &driver_data->config_heap );
282     obj_config = CONFIG(configID);
283     if (NULL == obj_config)
284     {
285         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
286         return vaStatus;
287     }
288
289     obj_config->profile = profile;
290     obj_config->entrypoint = entrypoint;
291     obj_config->attrib_list[0].type = VAConfigAttribRTFormat;
292     obj_config->attrib_list[0].value = VA_RT_FORMAT_YUV420;
293     obj_config->attrib_count = 1;
294
295     for(i = 0; i < num_attribs; i++)
296     {
297         vaStatus = dummy__update_attribute(obj_config, &(attrib_list[i]));
298         if (VA_STATUS_SUCCESS != vaStatus)
299         {
300             break;
301         }
302     }
303
304     /* Error recovery */
305     if (VA_STATUS_SUCCESS != vaStatus)
306     {
307         object_heap_free( &driver_data->config_heap, (object_base_p) obj_config);
308     }
309     else
310     {
311         *config_id = configID;
312     }
313
314     return vaStatus;
315 }
316
317 VAStatus dummy_DestroyConfig(
318                 VADriverContextP ctx,
319                 VAConfigID config_id
320         )
321 {
322     INIT_DRIVER_DATA
323     VAStatus vaStatus;
324     object_config_p obj_config;
325
326     obj_config = CONFIG(config_id);
327     if (NULL == obj_config)
328     {
329         vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
330         return vaStatus;
331     }
332
333     object_heap_free( &driver_data->config_heap, (object_base_p) obj_config);
334     return VA_STATUS_SUCCESS;
335 }
336
337 VAStatus dummy_QueryConfigAttributes(
338                 VADriverContextP ctx,
339                 VAConfigID config_id,
340                 VAProfile *profile,             /* out */
341                 VAEntrypoint *entrypoint,       /* out */
342                 VAConfigAttrib *attrib_list,    /* out */
343                 int *num_attribs                /* out */
344         )
345 {
346     INIT_DRIVER_DATA
347     VAStatus vaStatus = VA_STATUS_SUCCESS;
348     object_config_p obj_config;
349     int i;
350
351     obj_config = CONFIG(config_id);
352     ASSERT(obj_config);
353
354     *profile = obj_config->profile;
355     *entrypoint = obj_config->entrypoint;
356     *num_attribs =  obj_config->attrib_count;
357     for(i = 0; i < obj_config->attrib_count; i++)
358     {
359         attrib_list[i] = obj_config->attrib_list[i];
360     }
361
362     return vaStatus;
363 }
364
365 VAStatus dummy_CreateSurfaces(
366                 VADriverContextP ctx,
367                 int width,
368                 int height,
369                 int format,
370                 int num_surfaces,
371                 VASurfaceID *surfaces           /* out */
372         )
373 {
374     INIT_DRIVER_DATA
375     VAStatus vaStatus = VA_STATUS_SUCCESS;
376     int i;
377
378     /* We only support one format */
379     if (VA_RT_FORMAT_YUV420 != format)
380     {
381         return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
382     }
383
384     for (i = 0; i < num_surfaces; i++)
385     {
386         int surfaceID = object_heap_allocate( &driver_data->surface_heap );
387         object_surface_p obj_surface = SURFACE(surfaceID);
388         if (NULL == obj_surface)
389         {
390             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
391             break;
392         }
393         obj_surface->surface_id = surfaceID;
394         surfaces[i] = surfaceID;
395     }
396
397     /* Error recovery */
398     if (VA_STATUS_SUCCESS != vaStatus)
399     {
400         /* surfaces[i-1] was the last successful allocation */
401         for(; i--; )
402         {
403             object_surface_p obj_surface = SURFACE(surfaces[i]);
404             surfaces[i] = VA_INVALID_SURFACE;
405             ASSERT(obj_surface);
406             object_heap_free( &driver_data->surface_heap, (object_base_p) obj_surface);
407         }
408     }
409
410     return vaStatus;
411 }
412
413 VAStatus dummy_DestroySurfaces(
414                 VADriverContextP ctx,
415                 VASurfaceID *surface_list,
416                 int num_surfaces
417         )
418 {
419     INIT_DRIVER_DATA
420     int i;
421     for(i = num_surfaces; i--; )
422     {
423         object_surface_p obj_surface = SURFACE(surface_list[i]);
424         ASSERT(obj_surface);
425         object_heap_free( &driver_data->surface_heap, (object_base_p) obj_surface);
426     }
427     return VA_STATUS_SUCCESS;
428 }
429
430 VAStatus dummy_QueryImageFormats(
431         VADriverContextP ctx,
432         VAImageFormat *format_list,        /* out */
433         int *num_formats           /* out */
434 )
435 {
436     INIT_DRIVER_DATA
437     
438     /* TODO */
439     return VA_STATUS_SUCCESS;
440 }
441
442 VAStatus dummy_CreateImage(
443         VADriverContextP ctx,
444         VAImageFormat *format,
445         int width,
446         int height,
447         VAImage *image     /* out */
448 )
449 {
450     INIT_DRIVER_DATA
451     
452     /* TODO */
453     return VA_STATUS_SUCCESS;
454 }
455
456 VAStatus dummy_DeriveImage(
457         VADriverContextP ctx,
458         VASurfaceID surface,
459         VAImage *image     /* out */
460 )
461 {
462     INIT_DRIVER_DATA
463     
464     /* TODO */
465     return VA_STATUS_SUCCESS;
466 }
467
468 VAStatus dummy_DestroyImage(
469         VADriverContextP ctx,
470         VAImageID image
471 )
472 {
473     INIT_DRIVER_DATA
474     
475     /* TODO */
476     return VA_STATUS_SUCCESS;
477 }
478
479 VAStatus dummy_SetImagePalette(
480         VADriverContextP ctx,
481         VAImageID image,
482         unsigned char *palette
483 )
484 {
485     INIT_DRIVER_DATA
486     
487     /* TODO */
488     return VA_STATUS_SUCCESS;
489 }
490
491 VAStatus dummy_GetImage(
492         VADriverContextP ctx,
493         VASurfaceID surface,
494         int x,     /* coordinates of the upper left source pixel */
495         int y,
496         unsigned int width, /* width and height of the region */
497         unsigned int height,
498         VAImageID image
499 )
500 {
501     INIT_DRIVER_DATA
502     
503     /* TODO */
504     return VA_STATUS_SUCCESS;
505 }
506
507
508 VAStatus dummy_PutImage(
509         VADriverContextP ctx,
510         VASurfaceID surface,
511         VAImageID image,
512         int src_x,
513         int src_y,
514         unsigned int src_width,
515         unsigned int src_height,
516         int dest_x,
517         int dest_y,
518         unsigned int dest_width,
519         unsigned int dest_height
520 )
521 {
522     INIT_DRIVER_DATA
523     
524     /* TODO */
525     return VA_STATUS_SUCCESS;
526 }
527
528 VAStatus dummy_QuerySubpictureFormats(
529         VADriverContextP ctx,
530         VAImageFormat *format_list,        /* out */
531         unsigned int *flags,       /* out */
532         unsigned int *num_formats  /* out */
533 )
534 {
535     INIT_DRIVER_DATA
536     
537     /* TODO */
538     return VA_STATUS_SUCCESS;
539 }
540
541 VAStatus dummy_CreateSubpicture(
542         VADriverContextP ctx,
543         VAImageID image,
544         VASubpictureID *subpicture   /* out */
545 )
546 {
547     INIT_DRIVER_DATA
548     
549     /* TODO */
550     return VA_STATUS_SUCCESS;
551 }
552
553 VAStatus dummy_DestroySubpicture(
554         VADriverContextP ctx,
555         VASubpictureID subpicture
556 )
557 {
558     INIT_DRIVER_DATA
559     
560     /* TODO */
561     return VA_STATUS_SUCCESS;
562 }
563
564 VAStatus dummy_SetSubpictureImage(
565         VADriverContextP ctx,
566         VASubpictureID subpicture,
567         VAImageID image
568 )
569 {
570     INIT_DRIVER_DATA
571     
572     /* TODO */
573     return VA_STATUS_SUCCESS;
574 }
575
576 VAStatus dummy_SetSubpicturePalette(
577         VADriverContextP ctx,
578         VASubpictureID subpicture,
579         /*
580          * pointer to an array holding the palette data.  The size of the array is
581          * num_palette_entries * entry_bytes in size.  The order of the components
582          * in the palette is described by the component_order in VASubpicture struct
583          */
584         unsigned char *palette
585 )
586 {
587     INIT_DRIVER_DATA
588     
589     /* TODO */
590     return VA_STATUS_SUCCESS;
591 }
592
593 VAStatus dummy_SetSubpictureChromakey(
594         VADriverContextP ctx,
595         VASubpictureID subpicture,
596         unsigned int chromakey_min,
597         unsigned int chromakey_max,
598         unsigned int chromakey_mask
599 )
600 {
601     INIT_DRIVER_DATA
602     
603     /* TODO */
604     return VA_STATUS_SUCCESS;
605 }
606
607 VAStatus dummy_SetSubpictureGlobalAlpha(
608         VADriverContextP ctx,
609         VASubpictureID subpicture,
610         float global_alpha 
611 )
612 {
613     INIT_DRIVER_DATA
614     
615     /* TODO */
616     return VA_STATUS_SUCCESS;
617 }
618
619
620 VAStatus dummy_AssociateSubpicture(
621         VADriverContextP ctx,
622         VASubpictureID subpicture,
623         VASurfaceID *target_surfaces,
624         int num_surfaces,
625         short src_x, /* upper left offset in subpicture */
626         short src_y,
627         unsigned short src_width,
628         unsigned short src_height,
629         short dest_x, /* upper left offset in surface */
630         short dest_y,
631         unsigned short dest_width,
632         unsigned short dest_height,
633         /*
634          * whether to enable chroma-keying or global-alpha
635          * see VA_SUBPICTURE_XXX values
636          */
637         unsigned int flags
638 )
639 {
640     INIT_DRIVER_DATA
641     
642     /* TODO */
643     return VA_STATUS_SUCCESS;
644 }
645
646 VAStatus dummy_DeassociateSubpicture(
647         VADriverContextP ctx,
648         VASubpictureID subpicture,
649         VASurfaceID *target_surfaces,
650         int num_surfaces
651 )
652 {
653     INIT_DRIVER_DATA
654     
655     /* TODO */
656     return VA_STATUS_SUCCESS;
657 }
658
659 VAStatus dummy_CreateContext(
660                 VADriverContextP ctx,
661                 VAConfigID config_id,
662                 int picture_width,
663                 int picture_height,
664                 int flag,
665                 VASurfaceID *render_targets,
666                 int num_render_targets,
667                 VAContextID *context            /* out */
668         )
669 {
670     INIT_DRIVER_DATA
671     VAStatus vaStatus = VA_STATUS_SUCCESS;
672     object_config_p obj_config;
673     int i;
674
675     obj_config = CONFIG(config_id);
676     if (NULL == obj_config)
677     {
678         vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
679         return vaStatus;
680     }
681
682     /* Validate flag */
683     /* Validate picture dimensions */
684
685     int contextID = object_heap_allocate( &driver_data->context_heap );
686     object_context_p obj_context = CONTEXT(contextID);
687     if (NULL == obj_context)
688     {
689         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
690         return vaStatus;
691     }
692
693     obj_context->context_id  = contextID;
694     *context = contextID;
695     obj_context->current_render_target = -1;
696     obj_context->config_id = config_id;
697     obj_context->picture_width = picture_width;
698     obj_context->picture_height = picture_height;
699     obj_context->num_render_targets = num_render_targets;
700     obj_context->render_targets = (VASurfaceID *) malloc(num_render_targets * sizeof(VASurfaceID));
701     if (obj_context->render_targets == NULL)
702     {
703         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
704         return vaStatus;
705     }
706     
707     for(i = 0; i < num_render_targets; i++)
708     {
709         if (NULL == SURFACE(render_targets[i]))
710         {
711             vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
712             break;
713         }
714         obj_context->render_targets[i] = render_targets[i];
715     }
716     obj_context->flags = flag;
717
718     /* Error recovery */
719     if (VA_STATUS_SUCCESS != vaStatus)
720     {
721         obj_context->context_id = -1;
722         obj_context->config_id = -1;
723         free(obj_context->render_targets);
724         obj_context->render_targets = NULL;
725         obj_context->num_render_targets = 0;
726         obj_context->flags = 0;
727         object_heap_free( &driver_data->context_heap, (object_base_p) obj_context);
728     }
729
730     return vaStatus;
731 }
732
733
734 VAStatus dummy_DestroyContext(
735                 VADriverContextP ctx,
736                 VAContextID context
737         )
738 {
739     INIT_DRIVER_DATA
740     object_context_p obj_context = CONTEXT(context);
741     ASSERT(obj_context);
742
743     obj_context->context_id = -1;
744     obj_context->config_id = -1;
745     obj_context->picture_width = 0;
746     obj_context->picture_height = 0;
747     if (obj_context->render_targets)
748     {
749         free(obj_context->render_targets);
750     }
751     obj_context->render_targets = NULL;
752     obj_context->num_render_targets = 0;
753     obj_context->flags = 0;
754
755     obj_context->current_render_target = -1;
756
757     object_heap_free( &driver_data->context_heap, (object_base_p) obj_context);
758
759     return VA_STATUS_SUCCESS;
760 }
761
762
763
764 static VAStatus dummy__allocate_buffer(object_buffer_p obj_buffer, int size)
765 {
766     VAStatus vaStatus = VA_STATUS_SUCCESS;
767
768     obj_buffer->buffer_data = realloc(obj_buffer->buffer_data, size);
769     if (NULL == obj_buffer->buffer_data)
770     {
771         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
772     }
773     return vaStatus;
774 }
775
776 VAStatus dummy_CreateBuffer(
777                 VADriverContextP ctx,
778                 VAContextID context,    /* in */
779                 VABufferType type,      /* in */
780                 unsigned int size,              /* in */
781                 unsigned int num_elements,      /* in */
782                 void *data,                     /* in */
783                 VABufferID *buf_id              /* out */
784 )
785 {
786     INIT_DRIVER_DATA
787     VAStatus vaStatus = VA_STATUS_SUCCESS;
788     int bufferID;
789     object_buffer_p obj_buffer;
790
791     /* Validate type */
792     switch (type)
793     {
794         case VAPictureParameterBufferType:
795         case VAIQMatrixBufferType:
796         case VABitPlaneBufferType:
797         case VASliceGroupMapBufferType:
798         case VASliceParameterBufferType:
799         case VASliceDataBufferType:
800         case VAMacroblockParameterBufferType:
801         case VAResidualDataBufferType:
802         case VADeblockingParameterBufferType:
803         case VAImageBufferType:
804             /* Ok */
805             break;
806         default:
807             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
808             return vaStatus;
809     }
810
811     bufferID = object_heap_allocate( &driver_data->buffer_heap );
812     obj_buffer = BUFFER(bufferID);
813     if (NULL == obj_buffer)
814     {
815         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
816         return vaStatus;
817     }
818
819     obj_buffer->buffer_data = NULL;
820
821     vaStatus = dummy__allocate_buffer(obj_buffer, size * num_elements);
822     if (VA_STATUS_SUCCESS == vaStatus)
823     {
824         obj_buffer->max_num_elements = num_elements;
825         obj_buffer->num_elements = num_elements;
826         if (data)
827         {
828             memcpy(obj_buffer->buffer_data, data, size * num_elements);
829         }
830     }
831
832     if (VA_STATUS_SUCCESS == vaStatus)
833     {
834         *buf_id = bufferID;
835     }
836
837     return vaStatus;
838 }
839
840
841 VAStatus dummy_BufferSetNumElements(
842                 VADriverContextP ctx,
843                 VABufferID buf_id,      /* in */
844         unsigned int num_elements       /* in */
845         )
846 {
847     INIT_DRIVER_DATA
848     VAStatus vaStatus = VA_STATUS_SUCCESS;
849     object_buffer_p obj_buffer = BUFFER(buf_id);
850     ASSERT(obj_buffer);
851
852     if ((num_elements < 0) || (num_elements > obj_buffer->max_num_elements))
853     {
854         vaStatus = VA_STATUS_ERROR_UNKNOWN;
855     }
856     if (VA_STATUS_SUCCESS == vaStatus)
857     {
858         obj_buffer->num_elements = num_elements;
859     }
860
861     return vaStatus;
862 }
863
864 VAStatus dummy_MapBuffer(
865                 VADriverContextP ctx,
866                 VABufferID buf_id,      /* in */
867                 void **pbuf         /* out */
868         )
869 {
870     INIT_DRIVER_DATA
871     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
872     object_buffer_p obj_buffer = BUFFER(buf_id);
873     ASSERT(obj_buffer);
874     if (NULL == obj_buffer)
875     {
876         vaStatus = VA_STATUS_ERROR_INVALID_BUFFER;
877         return vaStatus;
878     }
879
880     if (NULL != obj_buffer->buffer_data)
881     {
882         *pbuf = obj_buffer->buffer_data;
883         vaStatus = VA_STATUS_SUCCESS;
884     }
885     return vaStatus;
886 }
887
888 VAStatus dummy_UnmapBuffer(
889                 VADriverContextP ctx,
890                 VABufferID buf_id       /* in */
891         )
892 {
893     /* Do nothing */
894     return VA_STATUS_SUCCESS;
895 }
896
897 static void dummy__destroy_buffer(struct dummy_driver_data *driver_data, object_buffer_p obj_buffer)
898 {
899     if (NULL != obj_buffer->buffer_data)
900     {
901         free(obj_buffer->buffer_data);
902         obj_buffer->buffer_data = NULL;
903     }
904
905     object_heap_free( &driver_data->buffer_heap, (object_base_p) obj_buffer);
906 }
907
908 VAStatus dummy_DestroyBuffer(
909                 VADriverContextP ctx,
910                 VABufferID buffer_id
911         )
912 {
913     INIT_DRIVER_DATA
914     object_buffer_p obj_buffer = BUFFER(buffer_id);
915     ASSERT(obj_buffer);
916
917     dummy__destroy_buffer(driver_data, obj_buffer);
918     return VA_STATUS_SUCCESS;
919 }
920
921 VAStatus dummy_BeginPicture(
922                 VADriverContextP ctx,
923                 VAContextID context,
924                 VASurfaceID render_target
925         )
926 {
927     INIT_DRIVER_DATA
928     VAStatus vaStatus = VA_STATUS_SUCCESS;
929     object_context_p obj_context;
930     object_surface_p obj_surface;
931
932     obj_context = CONTEXT(context);
933     ASSERT(obj_context);
934
935     obj_surface = SURFACE(render_target);
936     ASSERT(obj_surface);
937
938     obj_context->current_render_target = obj_surface->base.id;
939
940     return vaStatus;
941 }
942
943 VAStatus dummy_RenderPicture(
944                 VADriverContextP ctx,
945                 VAContextID context,
946                 VABufferID *buffers,
947                 int num_buffers
948         )
949 {
950     INIT_DRIVER_DATA
951     VAStatus vaStatus = VA_STATUS_SUCCESS;
952     object_context_p obj_context;
953     object_surface_p obj_surface;
954     int i;
955
956     obj_context = CONTEXT(context);
957     ASSERT(obj_context);
958
959     obj_surface = SURFACE(obj_context->current_render_target);
960     ASSERT(obj_surface);
961
962     /* verify that we got valid buffer references */
963     for(i = 0; i < num_buffers; i++)
964     {
965         object_buffer_p obj_buffer = BUFFER(buffers[i]);
966         ASSERT(obj_buffer);
967         if (NULL == obj_buffer)
968         {
969             vaStatus = VA_STATUS_ERROR_INVALID_BUFFER;
970             break;
971         }
972     }
973     
974     /* Release buffers */
975     for(i = 0; i < num_buffers; i++)
976     {
977         object_buffer_p obj_buffer = BUFFER(buffers[i]);
978         ASSERT(obj_buffer);
979         dummy__destroy_buffer(driver_data, obj_buffer);
980     }
981
982     return vaStatus;
983 }
984
985 VAStatus dummy_EndPicture(
986                 VADriverContextP ctx,
987                 VAContextID context
988         )
989 {
990     INIT_DRIVER_DATA
991     VAStatus vaStatus = VA_STATUS_SUCCESS;
992     object_context_p obj_context;
993     object_surface_p obj_surface;
994
995     obj_context = CONTEXT(context);
996     ASSERT(obj_context);
997
998     obj_surface = SURFACE(obj_context->current_render_target);
999     ASSERT(obj_surface);
1000
1001     // For now, assume that we are done with rendering right away
1002     obj_context->current_render_target = -1;
1003
1004     return vaStatus;
1005 }
1006
1007
1008 VAStatus dummy_SyncSurface(
1009                 VADriverContextP ctx,
1010                 VASurfaceID render_target
1011         )
1012 {
1013     INIT_DRIVER_DATA
1014     VAStatus vaStatus = VA_STATUS_SUCCESS;
1015     object_surface_p obj_surface;
1016
1017     obj_surface = SURFACE(render_target);
1018     ASSERT(obj_surface);
1019
1020     return vaStatus;
1021 }
1022
1023 VAStatus dummy_QuerySurfaceStatus(
1024                 VADriverContextP ctx,
1025                 VASurfaceID render_target,
1026                 VASurfaceStatus *status /* out */
1027         )
1028 {
1029     INIT_DRIVER_DATA
1030     VAStatus vaStatus = VA_STATUS_SUCCESS;
1031     object_surface_p obj_surface;
1032
1033     obj_surface = SURFACE(render_target);
1034     ASSERT(obj_surface);
1035
1036     *status = VASurfaceReady;
1037
1038     return vaStatus;
1039 }
1040
1041 VAStatus dummy_PutSurface(
1042                 VADriverContextP ctx,
1043                 VASurfaceID surface,
1044                 void *draw, /* X Drawable */
1045                 short srcx,
1046                 short srcy,
1047                 unsigned short srcw,
1048                 unsigned short srch,
1049                 short destx,
1050                 short desty,
1051                 unsigned short destw,
1052                 unsigned short desth,
1053                 VARectangle *cliprects, /* client supplied clip list */
1054                 unsigned int number_cliprects, /* number of clip rects in the clip list */
1055                 unsigned int flags /* de-interlacing flags */
1056         )
1057 {
1058     /* TODO */
1059     Drawable drawable = (Drawable)draw;
1060
1061     (void)drawable;
1062
1063     return VA_STATUS_ERROR_UNKNOWN;
1064 }
1065
1066 /* 
1067  * Query display attributes 
1068  * The caller must provide a "attr_list" array that can hold at
1069  * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1070  * returned in "attr_list" is returned in "num_attributes".
1071  */
1072 VAStatus dummy_QueryDisplayAttributes (
1073                 VADriverContextP ctx,
1074                 VADisplayAttribute *attr_list,  /* out */
1075                 int *num_attributes             /* out */
1076         )
1077 {
1078     /* TODO */
1079     return VA_STATUS_ERROR_UNKNOWN;
1080 }
1081
1082 /* 
1083  * Get display attributes 
1084  * This function returns the current attribute values in "attr_list".
1085  * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1086  * from vaQueryDisplayAttributes() can have their values retrieved.  
1087  */
1088 VAStatus dummy_GetDisplayAttributes (
1089                 VADriverContextP ctx,
1090                 VADisplayAttribute *attr_list,  /* in/out */
1091                 int num_attributes
1092         )
1093 {
1094     /* TODO */
1095     return VA_STATUS_ERROR_UNKNOWN;
1096 }
1097
1098 /* 
1099  * Set display attributes 
1100  * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1101  * from vaQueryDisplayAttributes() can be set.  If the attribute is not settable or 
1102  * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1103  */
1104 VAStatus dummy_SetDisplayAttributes (
1105                 VADriverContextP ctx,
1106                 VADisplayAttribute *attr_list,
1107                 int num_attributes
1108         )
1109 {
1110     /* TODO */
1111     return VA_STATUS_ERROR_UNKNOWN;
1112 }
1113
1114
1115 VAStatus dummy_BufferInfo(
1116         VADriverContextP ctx,
1117         VAContextID context,    /* in */
1118         VABufferID buf_id,      /* in */
1119         VABufferType *type,     /* out */
1120         unsigned int *size,     /* out */
1121         unsigned int *num_elements /* out */
1122     )
1123 {
1124     /* TODO */
1125     return VA_STATUS_ERROR_UNIMPLEMENTED;
1126 }
1127
1128     
1129
1130 VAStatus dummy_LockSurface(
1131                 VADriverContextP ctx,
1132                 VASurfaceID surface,
1133                 unsigned int *fourcc, /* following are output argument */
1134                 unsigned int *luma_stride,
1135                 unsigned int *chroma_u_stride,
1136                 unsigned int *chroma_v_stride,
1137                 unsigned int *luma_offset,
1138                 unsigned int *chroma_u_offset,
1139                 unsigned int *chroma_v_offset,
1140                 unsigned int *buffer_name,
1141                 void **buffer
1142         )
1143 {
1144     /* TODO */
1145     return VA_STATUS_ERROR_UNIMPLEMENTED;
1146 }
1147
1148 VAStatus dummy_UnlockSurface(
1149                 VADriverContextP ctx,
1150                 VASurfaceID surface
1151         )
1152 {
1153     /* TODO */
1154     return VA_STATUS_ERROR_UNIMPLEMENTED;
1155 }
1156
1157 VAStatus dummy_Terminate( VADriverContextP ctx )
1158 {
1159     INIT_DRIVER_DATA
1160     object_buffer_p obj_buffer;
1161     object_surface_p obj_surface;
1162     object_context_p obj_context;
1163     object_config_p obj_config;
1164     object_heap_iterator iter;
1165
1166     /* Clean up left over buffers */
1167     obj_buffer = (object_buffer_p) object_heap_first( &driver_data->buffer_heap, &iter);
1168     while (obj_buffer)
1169     {
1170         dummy__information_message("vaTerminate: bufferID %08x still allocated, destroying\n", obj_buffer->base.id);
1171         dummy__destroy_buffer(driver_data, obj_buffer);
1172         obj_buffer = (object_buffer_p) object_heap_next( &driver_data->buffer_heap, &iter);
1173     }
1174     object_heap_destroy( &driver_data->buffer_heap );
1175
1176     /* TODO cleanup */
1177     object_heap_destroy( &driver_data->surface_heap );
1178
1179     /* TODO cleanup */
1180     object_heap_destroy( &driver_data->context_heap );
1181
1182     /* Clean up configIDs */
1183     obj_config = (object_config_p) object_heap_first( &driver_data->config_heap, &iter);
1184     while (obj_config)
1185     {
1186         object_heap_free( &driver_data->config_heap, (object_base_p) obj_config);
1187         obj_config = (object_config_p) object_heap_next( &driver_data->config_heap, &iter);
1188     }
1189     object_heap_destroy( &driver_data->config_heap );
1190
1191     free(ctx->pDriverData);
1192     ctx->pDriverData = NULL;
1193
1194     return VA_STATUS_SUCCESS;
1195 }
1196
1197 VAStatus VA_DRIVER_INIT_FUNC(  VADriverContextP ctx )
1198 {
1199     struct VADriverVTable * const vtable = ctx->vtable;
1200     object_base_p obj;
1201     int result;
1202     struct dummy_driver_data *driver_data;
1203     int i;
1204
1205     ctx->version_major = VA_MAJOR_VERSION;
1206     ctx->version_minor = VA_MINOR_VERSION;
1207     ctx->max_profiles = DUMMY_MAX_PROFILES;
1208     ctx->max_entrypoints = DUMMY_MAX_ENTRYPOINTS;
1209     ctx->max_attributes = DUMMY_MAX_CONFIG_ATTRIBUTES;
1210     ctx->max_image_formats = DUMMY_MAX_IMAGE_FORMATS;
1211     ctx->max_subpic_formats = DUMMY_MAX_SUBPIC_FORMATS;
1212     ctx->max_display_attributes = DUMMY_MAX_DISPLAY_ATTRIBUTES;
1213     ctx->str_vendor = DUMMY_STR_VENDOR;
1214
1215     vtable->vaTerminate = dummy_Terminate;
1216     vtable->vaQueryConfigEntrypoints = dummy_QueryConfigEntrypoints;
1217     vtable->vaQueryConfigProfiles = dummy_QueryConfigProfiles;
1218     vtable->vaQueryConfigEntrypoints = dummy_QueryConfigEntrypoints;
1219     vtable->vaQueryConfigAttributes = dummy_QueryConfigAttributes;
1220     vtable->vaCreateConfig = dummy_CreateConfig;
1221     vtable->vaDestroyConfig = dummy_DestroyConfig;
1222     vtable->vaGetConfigAttributes = dummy_GetConfigAttributes;
1223     vtable->vaCreateSurfaces = dummy_CreateSurfaces;
1224     vtable->vaDestroySurfaces = dummy_DestroySurfaces;
1225     vtable->vaCreateContext = dummy_CreateContext;
1226     vtable->vaDestroyContext = dummy_DestroyContext;
1227     vtable->vaCreateBuffer = dummy_CreateBuffer;
1228     vtable->vaBufferSetNumElements = dummy_BufferSetNumElements;
1229     vtable->vaMapBuffer = dummy_MapBuffer;
1230     vtable->vaUnmapBuffer = dummy_UnmapBuffer;
1231     vtable->vaDestroyBuffer = dummy_DestroyBuffer;
1232     vtable->vaBeginPicture = dummy_BeginPicture;
1233     vtable->vaRenderPicture = dummy_RenderPicture;
1234     vtable->vaEndPicture = dummy_EndPicture;
1235     vtable->vaSyncSurface = dummy_SyncSurface;
1236     vtable->vaQuerySurfaceStatus = dummy_QuerySurfaceStatus;
1237     vtable->vaPutSurface = dummy_PutSurface;
1238     vtable->vaQueryImageFormats = dummy_QueryImageFormats;
1239     vtable->vaCreateImage = dummy_CreateImage;
1240     vtable->vaDeriveImage = dummy_DeriveImage;
1241     vtable->vaDestroyImage = dummy_DestroyImage;
1242     vtable->vaSetImagePalette = dummy_SetImagePalette;
1243     vtable->vaGetImage = dummy_GetImage;
1244     vtable->vaPutImage = dummy_PutImage;
1245     vtable->vaQuerySubpictureFormats = dummy_QuerySubpictureFormats;
1246     vtable->vaCreateSubpicture = dummy_CreateSubpicture;
1247     vtable->vaDestroySubpicture = dummy_DestroySubpicture;
1248     vtable->vaSetSubpictureImage = dummy_SetSubpictureImage;
1249     vtable->vaSetSubpictureChromakey = dummy_SetSubpictureChromakey;
1250     vtable->vaSetSubpictureGlobalAlpha = dummy_SetSubpictureGlobalAlpha;
1251     vtable->vaAssociateSubpicture = dummy_AssociateSubpicture;
1252     vtable->vaDeassociateSubpicture = dummy_DeassociateSubpicture;
1253     vtable->vaQueryDisplayAttributes = dummy_QueryDisplayAttributes;
1254     vtable->vaGetDisplayAttributes = dummy_GetDisplayAttributes;
1255     vtable->vaSetDisplayAttributes = dummy_SetDisplayAttributes;
1256     vtable->vaLockSurface = dummy_LockSurface;
1257     vtable->vaUnlockSurface = dummy_UnlockSurface;
1258     vtable->vaBufferInfo = dummy_BufferInfo;
1259
1260     driver_data = (struct dummy_driver_data *) malloc( sizeof(*driver_data) );
1261     ctx->pDriverData = (void *) driver_data;
1262
1263     result = object_heap_init( &driver_data->config_heap, sizeof(struct object_config), CONFIG_ID_OFFSET );
1264     ASSERT( result == 0 );
1265
1266     result = object_heap_init( &driver_data->context_heap, sizeof(struct object_context), CONTEXT_ID_OFFSET );
1267     ASSERT( result == 0 );
1268
1269     result = object_heap_init( &driver_data->surface_heap, sizeof(struct object_surface), SURFACE_ID_OFFSET );
1270     ASSERT( result == 0 );
1271
1272     result = object_heap_init( &driver_data->buffer_heap, sizeof(struct object_buffer), BUFFER_ID_OFFSET );
1273     ASSERT( result == 0 );
1274
1275
1276     return VA_STATUS_SUCCESS;
1277 }
1278