OSDN Git Service

add new va_DisplayContextGetDriverName, remove 'x11/XX' include folder name
[android-x86/hardware-intel-common-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 #ifndef ANDROID
41 #include <libudev.h>
42 #include "drm_test.h"
43 #endif
44
45 #define CHECK_SYMBOL(func) { if (!func) printf("func %s not found\n", #func); return VA_STATUS_ERROR_UNKNOWN; }
46 #define DEVICE_NAME "/dev/dri/card0"
47
48 static VADisplayContextP pDisplayContexts = NULL;
49
50 static int open_device (char *dev_name)
51 {
52   struct stat st;
53   int fd;
54
55   if (-1 == stat (dev_name, &st))
56     {
57       printf ("Cannot identify '%s': %d, %s\n",
58                dev_name, errno, strerror (errno));
59       return -1;
60     }
61
62   if (!S_ISCHR (st.st_mode))
63     {
64       printf ("%s is no device\n", dev_name);
65       return -1;
66     }
67
68   fd = open (dev_name, O_RDWR /* required */  | O_NONBLOCK, 0);
69
70   if (-1 == fd)
71     {
72       fprintf (stderr, "Cannot open '%s': %d, %s\n",
73                dev_name, errno, strerror (errno));
74       return -1;
75     }
76
77   return fd;
78 }
79
80 static int va_DisplayContextIsValid (
81     VADisplayContextP pDisplayContext
82 )
83 {
84     VADisplayContextP ctx = pDisplayContexts;
85
86     while (ctx)
87     {
88         if (ctx == pDisplayContext && pDisplayContext->pDriverContext)
89             return 1;
90         ctx = ctx->pNext;
91     }
92     return 0;
93 }
94
95 static void va_DisplayContextDestroy (
96     VADisplayContextP pDisplayContext
97 )
98 {
99     VADisplayContextP *ctx = &pDisplayContexts;
100
101     /* Throw away pDisplayContext */
102     while (*ctx)
103     {
104         if (*ctx == pDisplayContext)
105         {
106             *ctx = pDisplayContext->pNext;
107             pDisplayContext->pNext = NULL;
108             break;
109         }
110         ctx = &((*ctx)->pNext);
111     }
112     free(pDisplayContext->pDriverContext->dri_state);
113     free(pDisplayContext->pDriverContext);
114     free(pDisplayContext);
115 }
116
117 #ifdef ANDROID
118 static VAStatus va_DisplayContextGetDriverName (
119     VADisplayContextP pDisplayContext,
120     char **driver_name
121 )
122 {
123     VADriverContextP ctx = pDisplayContext->pDriverContext;
124     struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
125     char *driver_name_env;
126     int vendor_id, device_id;
127     
128     struct {
129         int vendor_id;
130         int device_id;
131         char driver_name[64];
132     } devices[] = {
133         { 0x8086, 0x4100, "pvr" },
134         { 0x8086, 0x0130, "pvr" },
135         { 0x0,    0x0,    "\0" },
136     };
137
138     memset(dri_state, 0, sizeof(*dri_state));
139     dri_state->fd = open_device(DEVICE_NAME);
140     
141     if (dri_state->fd < 0) {
142         fprintf(stderr,"can't open DRM devices\n");
143         return VA_STATUS_ERROR_UNKNOWN;
144     }
145
146     if ((driver_name_env = getenv("LIBVA_DRIVER_NAME")) != NULL
147         && geteuid() == getuid()) {
148         /* don't allow setuid apps to use LIBVA_DRIVER_NAME */
149         *driver_name = strdup(driver_name_env);
150         return VA_STATUS_SUCCESS;
151     } else { /* TBD: other vendor driver names */
152         vendor_id = devices[0].vendor_id;
153         device_id = devices[0].device_id;
154         *driver_name = strdup(devices[0].driver_name);
155     }
156
157     dri_state->driConnectedFlag = VA_DUMMY;
158     
159     return VA_STATUS_SUCCESS;
160 }
161 #else
162 static VAStatus va_DisplayContextGetDriverName (
163     VADisplayContextP pDisplayContext,
164     char **driver_name
165 )
166 {
167     VADriverContextP ctx = pDisplayContext->pDriverContext;
168     struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
169     char *driver_name_env;
170
171     struct {
172         unsigned int vendor_id;
173         unsigned int device_id;
174         char driver_name[64];
175     } devices[] = {
176         { 0x8086, 0x4100, "pvr" },
177     };
178
179     memset(dri_state, 0, sizeof(*dri_state));
180     dri_state->fd = drm_open_any_master();
181     if (dri_state->fd < 0) {
182         fprintf(stderr, "open DRM device by udev failed, try /dev/dri/card0\n");
183         dri_state->fd = open("/dev/dri/card0", O_RDWR);
184     }
185
186     if (dri_state->fd < 0) {
187         fprintf(stderr,"can't open DRM devices\n");
188         return VA_STATUS_ERROR_UNKNOWN;
189     }
190
191     if ((driver_name_env = getenv("LIBVA_DRIVER_NAME")) != NULL
192         && geteuid() == getuid())
193     {
194         /* don't allow setuid apps to use LIBVA_DRIVER_NAME */
195         *driver_name = strdup(driver_name_env);
196         return VA_STATUS_SUCCESS;
197     } else /* TBD: other vendor driver names */
198         *driver_name = strdup(devices[0].driver_name);
199
200
201     dri_state->driConnectedFlag = VA_DUMMY;
202
203     return VA_STATUS_SUCCESS;
204 }
205 #endif
206
207 VADisplay vaGetDisplay (
208     void *native_dpy /* implementation specific */
209 )
210 {
211   VADisplay dpy = NULL;
212   VADisplayContextP pDisplayContext = pDisplayContexts;
213
214   if (!native_dpy)
215       return NULL;
216
217   while (pDisplayContext)
218   {
219       if (pDisplayContext->pDriverContext &&
220           pDisplayContext->pDriverContext->native_dpy == (void *)native_dpy)
221       {
222           dpy = (VADisplay)pDisplayContext;
223           break;
224       }
225       pDisplayContext = pDisplayContext->pNext;
226   }
227
228
229   if (!dpy)
230   {
231       /* create new entry */
232       VADriverContextP pDriverContext;
233       struct dri_state *dri_state;
234       pDisplayContext = (VADisplayContextP)calloc(1, sizeof(*pDisplayContext));
235       pDriverContext  = (VADriverContextP)calloc(1, sizeof(*pDriverContext));
236       dri_state       = calloc(1, sizeof(*dri_state));
237       if (pDisplayContext && pDriverContext && dri_state)
238       {
239           pDisplayContext->vadpy_magic = VA_DISPLAY_MAGIC;          
240
241           pDriverContext->native_dpy       = (void *)native_dpy;
242           pDisplayContext->pNext           = pDisplayContexts;
243           pDisplayContext->pDriverContext  = pDriverContext;
244           pDisplayContext->vaIsValid       = va_DisplayContextIsValid;
245           pDisplayContext->vaDestroy       = va_DisplayContextDestroy;
246           pDisplayContext->vaGetDriverName = va_DisplayContextGetDriverName;
247           pDisplayContexts                 = pDisplayContext;
248           pDriverContext->dri_state        = dri_state;
249           dpy                              = (VADisplay)pDisplayContext;
250       }
251       else
252       {
253           if (pDisplayContext)
254               free(pDisplayContext);
255           if (pDriverContext)
256               free(pDriverContext);
257           if (dri_state)
258               free(dri_state);
259       }
260   }
261   
262   return dpy;
263 }
264
265 #define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext)
266 #define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; }
267
268 static int vaDisplayIsValid(VADisplay dpy)
269 {
270     VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
271     return pDisplayContext && (pDisplayContext->vadpy_magic == VA_DISPLAY_MAGIC) && pDisplayContext->vaIsValid(pDisplayContext);
272 }
273
274 #ifdef ANDROID
275 VAStatus vaPutSurface (
276     VADisplay dpy,
277     VASurfaceID surface,
278     Surface *draw, /* Android Surface/Window */
279     short srcx,
280     short srcy,
281     unsigned short srcw,
282     unsigned short srch,
283     short destx,
284     short desty,
285     unsigned short destw,
286     unsigned short desth,
287     VARectangle *cliprects, /* client supplied clip list */
288     unsigned int number_cliprects, /* number of clip rects in the clip list */
289     unsigned int flags /* de-interlacing flags */
290 )
291 {
292   VADriverContextP ctx;
293
294   CHECK_DISPLAY(dpy);
295   ctx = CTX(dpy);
296   return ctx->vtable.vaPutSurface( ctx, surface, (void *)draw, srcx, srcy, srcw, srch, 
297                                    destx, desty, destw, desth,
298                                    cliprects, number_cliprects, flags );
299 }
300
301 #endif