Merge branch 'va_backend' into PO
[profile/ivi/libva.git] / va / android / va_android.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 "va_android.h"
29 #include "va_dricommon.h" /* needs some helper functions from this file */
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <stdarg.h>
33 #include <string.h>
34 #include <unistd.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38 #include <dlfcn.h>
39 #include <errno.h>
40
41 #define CHECK_SYMBOL(func) { if (!func) printf("func %s not found\n", #func); return VA_STATUS_ERROR_UNKNOWN; }
42 #define DEVICE_NAME "/dev/dri/card0"
43
44 static VADisplayContextP pDisplayContexts = NULL;
45
46
47 static int va_DisplayContextIsValid (
48     VADisplayContextP pDisplayContext
49 )
50 {
51     VADisplayContextP ctx = pDisplayContexts;
52
53     while (ctx)
54     {
55         if (ctx == pDisplayContext && pDisplayContext->pDriverContext)
56             return 1;
57         ctx = ctx->pNext;
58     }
59     return 0;
60 }
61
62 static void va_DisplayContextDestroy (
63     VADisplayContextP pDisplayContext
64 )
65 {
66     VADisplayContextP *ctx = &pDisplayContexts;
67
68     /* Throw away pDisplayContext */
69     while (*ctx)
70     {
71         if (*ctx == pDisplayContext)
72         {
73             *ctx = pDisplayContext->pNext;
74             pDisplayContext->pNext = NULL;
75             break;
76         }
77         ctx = &((*ctx)->pNext);
78     }
79     free(pDisplayContext->pDriverContext->dri_state);
80     free(pDisplayContext->pDriverContext);
81     free(pDisplayContext);
82 }
83
84
85 static VAStatus va_DisplayContextGetDriverName (
86     VADisplayContextP pDisplayContext,
87     char **driver_name
88 )
89 {
90     VADriverContextP ctx = pDisplayContext->pDriverContext;
91     struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
92     char *driver_name_env;
93     int dev_id;
94     
95     struct {
96         int verndor_id;
97         int device_id;
98         char driver_name[64];
99     } devices[] = {
100         { 0x8086, 0x4100, "pvr" },
101         { 0x8086, 0x0310, "pvr" },
102         { 0x0,    0x0,    "\0" },
103     };
104
105     memset(dri_state, 0, sizeof(*dri_state));
106     dri_state->fd = drm_open_any_master(&dev_id);
107     
108     if (dri_state->fd < 0) {
109         fprintf(stderr,"can't open DRM devices\n");
110         return VA_STATUS_ERROR_UNKNOWN;
111     }
112     
113     if ((driver_name_env = getenv("LIBVA_DRIVER_NAME")) != NULL
114         && geteuid() == getuid()) {
115         /* don't allow setuid apps to use LIBVA_DRIVER_NAME */
116         *driver_name = strdup(driver_name_env);
117         return VA_STATUS_SUCCESS;
118     } else { /* TBD: other vendor driver names */
119         int i=0;
120
121         while ((devices[i].device_id !=0) &&
122                (devices[i].device_id != dev_id))
123             i++;
124
125         if (devices[i].device_id != 0)
126             *driver_name = strdup(devices[0].driver_name);
127         else {
128             fprintf(stderr,"device (0x%04x) is not supported\n", dev_id);
129             return VA_STATUS_ERROR_UNKNOWN;
130         }            
131     }
132     
133     dri_state->driConnectedFlag = VA_DUMMY;
134     
135     return VA_STATUS_SUCCESS;
136 }
137
138
139 VADisplay vaGetDisplay (
140     void *native_dpy /* implementation specific */
141 )
142 {
143   VADisplay dpy = NULL;
144   VADisplayContextP pDisplayContext = pDisplayContexts;
145
146   if (!native_dpy)
147       return NULL;
148
149   while (pDisplayContext)
150   {
151       if (pDisplayContext->pDriverContext &&
152           pDisplayContext->pDriverContext->native_dpy == (void *)native_dpy)
153       {
154           dpy = (VADisplay)pDisplayContext;
155           break;
156       }
157       pDisplayContext = pDisplayContext->pNext;
158   }
159
160
161   if (!dpy)
162   {
163       /* create new entry */
164       VADriverContextP pDriverContext;
165       struct dri_state *dri_state;
166       pDisplayContext = (VADisplayContextP)calloc(1, sizeof(*pDisplayContext));
167       pDriverContext  = (VADriverContextP)calloc(1, sizeof(*pDriverContext));
168       dri_state       = calloc(1, sizeof(*dri_state));
169       if (pDisplayContext && pDriverContext && dri_state)
170       {
171           pDisplayContext->vadpy_magic = VA_DISPLAY_MAGIC;          
172
173           pDriverContext->native_dpy       = (void *)native_dpy;
174           pDisplayContext->pNext           = pDisplayContexts;
175           pDisplayContext->pDriverContext  = pDriverContext;
176           pDisplayContext->vaIsValid       = va_DisplayContextIsValid;
177           pDisplayContext->vaDestroy       = va_DisplayContextDestroy;
178           pDisplayContext->vaGetDriverName = va_DisplayContextGetDriverName;
179           pDisplayContexts                 = pDisplayContext;
180           pDriverContext->dri_state        = dri_state;
181           dpy                              = (VADisplay)pDisplayContext;
182       }
183       else
184       {
185           if (pDisplayContext)
186               free(pDisplayContext);
187           if (pDriverContext)
188               free(pDriverContext);
189           if (dri_state)
190               free(dri_state);
191       }
192   }
193   
194   return dpy;
195 }
196
197 #define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext)
198 #define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; }
199
200 static int vaDisplayIsValid(VADisplay dpy)
201 {
202     VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
203     return pDisplayContext && (pDisplayContext->vadpy_magic == VA_DISPLAY_MAGIC) && pDisplayContext->vaIsValid(pDisplayContext);
204 }
205
206 #ifdef ANDROID
207 VAStatus vaPutSurface (
208     VADisplay dpy,
209     VASurfaceID surface,
210     Surface *draw, /* Android Surface/Window */
211     short srcx,
212     short srcy,
213     unsigned short srcw,
214     unsigned short srch,
215     short destx,
216     short desty,
217     unsigned short destw,
218     unsigned short desth,
219     VARectangle *cliprects, /* client supplied clip list */
220     unsigned int number_cliprects, /* number of clip rects in the clip list */
221     unsigned int flags /* de-interlacing flags */
222 )
223 {
224   VADriverContextP ctx;
225
226   CHECK_DISPLAY(dpy);
227   ctx = CTX(dpy);
228
229   return ctx->vtable.vaPutSurface( ctx, surface, (void *)draw, srcx, srcy, srcw, srch, 
230                                    destx, desty, destw, desth,
231                                    cliprects, number_cliprects, flags );
232 }
233
234 #endif