libva backend
[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 "x11/va_dricommon.h"
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 static int open_device (char *dev_name)
47 {
48   struct stat st;
49   int fd;
50
51   if (-1 == stat (dev_name, &st))
52     {
53       printf ("Cannot identify '%s': %d, %s\n",
54                dev_name, errno, strerror (errno));
55       return -1;
56     }
57
58   if (!S_ISCHR (st.st_mode))
59     {
60       printf ("%s is no device\n", dev_name);
61       return -1;
62     }
63
64   fd = open (dev_name, O_RDWR /* required */  | O_NONBLOCK, 0);
65
66   if (-1 == fd)
67     {
68       fprintf (stderr, "Cannot open '%s': %d, %s\n",
69                dev_name, errno, strerror (errno));
70       return -1;
71     }
72
73   return fd;
74 }
75
76 static int va_DisplayContextIsValid (
77     VADisplayContextP pDisplayContext
78 )
79 {
80     return 1;
81 }
82
83 static void va_DisplayContextDestroy (
84     VADisplayContextP pDisplayContext
85 )
86 {
87     VADisplayContextP *ctx = &pDisplayContexts;
88
89     /* Throw away pDisplayContext */
90     while (*ctx)
91     {
92         if (*ctx == pDisplayContext)
93         {
94             *ctx = pDisplayContext->pNext;
95             pDisplayContext->pNext = NULL;
96             break;
97         }
98         ctx = &((*ctx)->pNext);
99     }
100     free(pDisplayContext->pDriverContext);
101     free(pDisplayContext);
102 }
103
104
105 static VAStatus va_DisplayContextGetDriverName (
106     VADisplayContextP pDisplayContext,
107     char **driver_name
108 )
109 {  
110     char *driver_name_env;
111     struct {
112         unsigned int verndor_id;
113         unsigned int device_id;
114         char driver_name[64];
115     } devices[] = {
116         { 0x8086, 0x4100, "psb" },
117     };
118
119     if (driver_name)
120         *driver_name = NULL;
121
122     *driver_name = strdup(devices[0].driver_name);
123     
124     return VA_STATUS_SUCCESS;
125 }
126
127
128 VADisplay vaGetDisplay (
129     Display *native_dpy /* implementation specific */
130 )
131 {
132   VADisplay dpy = NULL;
133   VADisplayContextP pDisplayContext = pDisplayContexts;
134
135   if (!native_dpy)
136       return NULL;
137
138   while (pDisplayContext)
139   {
140       if (pDisplayContext->pDriverContext &&
141           pDisplayContext->pDriverContext->native_dpy == (void *)native_dpy)
142       {
143           dpy = (VADisplay)pDisplayContext;
144           break;
145       }
146       pDisplayContext = pDisplayContext->pNext;
147   }
148
149
150   if (!dpy)
151   {
152       /* create new entry */
153       VADriverContextP pDriverContext;
154       struct dri_state *dri_state;
155
156       pDisplayContext = (VADisplayContextP)calloc(1, sizeof(*pDisplayContext));
157       pDriverContext  = (VADriverContextP)calloc(1, sizeof(*pDriverContext));
158       dri_state       = (struct dri_state*)calloc(1, sizeof(*dri_state));
159
160       /* assgin necessary dri_state struct variable */
161       dri_state->driConnectedFlag = VA_DRI2;
162       dri_state->fd = open_device(DEVICE_NAME);
163       dri_state->createDrawable = NULL;
164       dri_state->destroyDrawable = NULL;
165       dri_state->swapBuffer = NULL;
166       dri_state->getRenderingBuffer = NULL;
167       dri_state->close = NULL;
168
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 VAStatus vaPutSurface (
207     VADisplay dpy,
208     VASurfaceID surface,
209     //Surface *draw, /* Android Surface/Window */
210     void *draw,
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, draw, srcx, srcy, srcw, srch, 
230                                    destx, desty, destw, desth,
231                                    cliprects, number_cliprects, flags );
232 }
233