libva-1.0.6
[platform/upstream/libva.git] / va / android / va_android.cpp
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 "drmtest.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/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);
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     /* TBD: other vendor driver names */
147     vendor_id = devices[0].vendor_id;
148     device_id = devices[0].device_id;
149     *driver_name = strdup(devices[0].driver_name);
150         
151     dri_state->driConnectedFlag = VA_DUMMY;
152     
153     return VA_STATUS_SUCCESS;
154 }
155 #else
156 static VAStatus va_DisplayContextGetDriverName (
157     VADisplayContextP pDisplayContext,
158     char **driver_name
159 )
160 {
161     VADriverContextP ctx = pDisplayContext->pDriverContext;
162     struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
163     char *driver_name_env;
164     int vendor_id, device_id;
165     int i = 0;
166     
167     struct {
168         int vendor_id;
169         int device_id;
170         char driver_name[64];
171     } devices[] = {
172         { 0x8086, 0x4100, "pvr" },
173         { 0x8086, 0x0130, "pvr" },
174         { 0x0,    0x0,    "\0" },
175     };
176
177     memset(dri_state, 0, sizeof(*dri_state));
178     dri_state->fd = drm_open_any(&vendor_id, &device_id);
179     
180     if (dri_state->fd < 0) {
181         fprintf(stderr,"can't open DRM devices\n");
182         return VA_STATUS_ERROR_UNKNOWN;
183     }
184     
185     /* TBD: other vendor driver names */
186
187     while (devices[i].device_id != 0) {
188         if ((devices[i].vendor_id == vendor_id) &&
189             (devices[i].device_id == device_id))
190             break;
191         i++;
192     }
193
194     if (devices[i].device_id != 0)
195         *driver_name = strdup(devices[i].driver_name);
196     else {
197         fprintf(stderr,"device (0x%04x:0x%04x) is not supported\n",
198                 vendor_id, device_id);
199         
200         return VA_STATUS_ERROR_UNKNOWN;
201     }            
202
203     printf("DRM device is opened, loading driver %s for device 0x%04x:0x%04x\n",
204            driver_name, vendor_id, device_id);
205     
206     dri_state->driConnectedFlag = VA_DUMMY;
207     
208     return VA_STATUS_SUCCESS;
209 }
210 #endif
211
212 VADisplay vaGetDisplay (
213     void *native_dpy /* implementation specific */
214 )
215 {
216     VADisplay dpy = NULL;
217     VADisplayContextP pDisplayContext = pDisplayContexts;
218
219     if (!native_dpy)
220         return NULL;
221
222     while (pDisplayContext)
223     {
224         if (pDisplayContext->pDriverContext &&
225             pDisplayContext->pDriverContext->native_dpy == (void *)native_dpy)
226         {
227             dpy = (VADisplay)pDisplayContext;
228             break;
229         }
230         pDisplayContext = pDisplayContext->pNext;
231     }
232
233
234     if (!dpy)
235     {
236         /* create new entry */
237         VADriverContextP pDriverContext;
238         struct dri_state *dri_state;
239         pDisplayContext = (VADisplayContextP)calloc(1, sizeof(*pDisplayContext));
240         pDriverContext  = (VADriverContextP)calloc(1, sizeof(*pDriverContext));
241         dri_state       = (struct dri_state*)calloc(1, sizeof(*dri_state));
242         if (pDisplayContext && pDriverContext && dri_state)
243         {
244             pDisplayContext->vadpy_magic = VA_DISPLAY_MAGIC;          
245
246             pDriverContext->native_dpy       = (void *)native_dpy;
247             pDisplayContext->pNext           = pDisplayContexts;
248             pDisplayContext->pDriverContext  = pDriverContext;
249             pDisplayContext->vaIsValid       = va_DisplayContextIsValid;
250             pDisplayContext->vaDestroy       = va_DisplayContextDestroy;
251             pDisplayContext->vaGetDriverName = va_DisplayContextGetDriverName;
252             pDisplayContexts                 = pDisplayContext;
253             pDriverContext->dri_state        = dri_state;
254             dpy                              = (VADisplay)pDisplayContext;
255         }
256         else
257         {
258             if (pDisplayContext)
259                 free(pDisplayContext);
260             if (pDriverContext)
261                 free(pDriverContext);
262             if (dri_state)
263                 free(dri_state);
264         }
265     }
266   
267     return dpy;
268 }
269
270 #define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext)
271 #define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; }
272
273
274 #ifdef ANDROID
275 extern "C"  {
276     extern int fool_postp; /* do nothing for vaPutSurface if set */
277     extern int trace_flag; /* trace vaPutSurface parameters */
278
279     void va_TracePutSurface (
280         VADisplay dpy,
281         VASurfaceID surface,
282         void *draw, /* the target Drawable */
283         short srcx,
284         short srcy,
285         unsigned short srcw,
286         unsigned short srch,
287         short destx,
288         short desty,
289         unsigned short destw,
290         unsigned short desth,
291         VARectangle *cliprects, /* client supplied clip list */
292         unsigned int number_cliprects, /* number of clip rects in the clip list */
293         unsigned int flags /* de-interlacing flags */
294         );
295 }
296
297 #define VA_TRACE(trace_func,...)                \
298     if (trace_flag) {                           \
299         trace_func(__VA_ARGS__);                \
300     }
301
302 VAStatus vaPutSurface (
303     VADisplay dpy,
304     VASurfaceID surface,
305     sp<ISurface> draw, /* Android Surface/Window */
306     short srcx,
307     short srcy,
308     unsigned short srcw,
309     unsigned short srch,
310     short destx,
311     short desty,
312     unsigned short destw,
313     unsigned short desth,
314     VARectangle *cliprects, /* client supplied clip list */
315     unsigned int number_cliprects, /* number of clip rects in the clip list */
316     unsigned int flags /* de-interlacing flags */
317 )
318 {
319     VADriverContextP ctx;
320
321     if (fool_postp)
322         return VA_STATUS_SUCCESS;
323
324     CHECK_DISPLAY(dpy);
325     ctx = CTX(dpy);
326
327     VA_TRACE(va_TracePutSurface, dpy, surface, static_cast<void*>(&draw), srcx, srcy, srcw, srch,
328              destx, desty, destw, desth,
329              cliprects, number_cliprects, flags );
330     
331     return ctx->vtable.vaPutSurface( ctx, surface, static_cast<void*>(&draw), srcx, srcy, srcw, srch, 
332                                      destx, desty, destw, desth,
333                                      cliprects, number_cliprects, flags );
334 }
335 #endif