OSDN Git Service

More update for DRI2 support
[android-x86/hardware-intel-common-libva.git] / src / X11 / va_x11.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.h"
27 #include "va_backend.h"
28 #include "va_x11.h"
29 #include "va_dri.h"
30 #include "va_dri2.h"
31 #include <stdio.h>
32 #include <stdarg.h>
33 #include <string.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37 #include <errno.h>
38
39 static VADisplayContextP pDisplayContexts = NULL;
40
41 static void va_errorMessage(const char *msg, ...)
42 {
43     va_list args;
44
45     fprintf(stderr, "libva error: ");
46     va_start(args, msg);
47     vfprintf(stderr, msg, args);
48     va_end(args);
49 }
50
51 static void va_infoMessage(const char *msg, ...)
52 {
53     va_list args;
54
55     fprintf(stderr, "libva: ");
56     va_start(args, msg);
57     vfprintf(stderr, msg, args);
58     va_end(args);
59 }
60
61 static int va_DisplayContextIsValid (
62     VADisplayContextP pDisplayContext
63 )
64 {
65     VADisplayContextP ctx = pDisplayContexts;
66
67     while (ctx)
68     {
69         if (ctx == pDisplayContext && pDisplayContext->pDriverContext)
70             return 1;
71         ctx = ctx->pNext;
72     }
73     return 0;
74 }
75
76 static void va_DisplayContextDestroy (
77     VADisplayContextP pDisplayContext
78 )
79 {
80     VADisplayContextP *ctx = &pDisplayContexts;
81
82     /* Throw away pDisplayContext */
83     while (*ctx)
84     {
85         if (*ctx == pDisplayContext)
86         {
87             *ctx = pDisplayContext->pNext;
88             pDisplayContext->pNext = NULL;
89             break;
90         }
91         ctx = &((*ctx)->pNext);
92     }
93     free(pDisplayContext->pDriverContext);
94     free(pDisplayContext);
95 }
96
97
98 static VAStatus va_DRI2GetDriverName (
99     VADisplayContextP pDisplayContext,
100     char **driver_name
101 )
102 {
103     VADriverContextP ctx = pDisplayContext->pDriverContext;
104     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
105     int eventBase, errorBase;
106     char *device_name;
107     int driver_major;
108     int driver_minor;
109     int driver_patch;
110     Bool result = True;
111
112     if (!VA_DRI2QueryExtension(ctx->x11_dpy, &eventBase, &errorBase)) {
113         va_infoMessage("DRI2 extension isn't present\n");
114         return VA_STATUS_ERROR_UNKNOWN;
115     }
116
117     if (!VA_DRI2QueryVersion(ctx->x11_dpy, &driver_major, &driver_minor)) {
118         va_errorMessage("VA_DRI2QueryVersion failed\n");
119         return VA_STATUS_ERROR_UNKNOWN;
120     }
121     
122     if (!VA_DRI2Connect(ctx->x11_dpy, RootWindow(ctx->x11_dpy, ctx->x11_screen),
123                      driver_name, &device_name)) {
124         va_infoMessage("DRI2 isn't enabled, fallback to DRI1\n");
125         return VA_STATUS_ERROR_UNKNOWN;
126     }
127
128     va_infoMessage("VA_DRI2Connect: %d.%d.%d %s (screen %d)\n",
129                    driver_major, driver_minor, driver_patch, *driver_name, ctx->x11_screen);
130     ctx->dri2 = 1;
131     
132     return VA_STATUS_SUCCESS;
133 }
134
135 static VAStatus va_DRIGetDriverName (
136     VADisplayContextP pDisplayContext,
137     char **driver_name
138 )
139 {
140     VADriverContextP ctx = pDisplayContext->pDriverContext;
141     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
142     int eventBase, errorBase;
143     int direct_capable;
144     int driver_major;
145     int driver_minor;
146     int driver_patch;
147     Bool result = True;
148     char *x_driver_name = NULL;
149
150     if (!VA_DRIQueryExtension(ctx->x11_dpy, &eventBase, &errorBase)) {
151         va_errorMessage("VA_DRIQueryExtension failed\n");
152         return VA_STATUS_ERROR_UNKNOWN;
153     }
154     
155     if (result)
156     {
157         result = VA_DRIQueryDirectRenderingCapable(ctx->x11_dpy, ctx->x11_screen, &direct_capable);
158         if (!result)
159         {
160             va_errorMessage("VA_DRIQueryDirectRenderingCapable failed\n");
161         }
162     }
163     if (result)
164     {
165         result = direct_capable;
166         if (!result)
167         {
168             va_errorMessage("VA_DRIQueryDirectRenderingCapable returned false\n");
169         }
170     }
171     if (result)
172     {
173         result = VA_DRIGetClientDriverName(ctx->x11_dpy, ctx->x11_screen, &driver_major, &driver_minor,
174                                             &driver_patch, &x_driver_name);
175         if (!result)
176         {
177             va_errorMessage("VA_DRIGetClientDriverName returned false\n");
178         }
179     }
180     if (result)
181     {
182         vaStatus = VA_STATUS_SUCCESS;
183         va_infoMessage("VA_DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
184              driver_major, driver_minor, driver_patch, x_driver_name, ctx->x11_screen);
185         if (driver_name)
186             *driver_name = strdup(x_driver_name);
187     }
188     if (x_driver_name)
189         XFree(x_driver_name);
190
191     return vaStatus;
192 }
193
194 static VAStatus va_DisplayContextGetDriverName (
195     VADisplayContextP pDisplayContext,
196     char **driver_name
197 )
198 {
199     VADriverContextP ctx = pDisplayContext->pDriverContext;
200     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
201     int direct_capable;
202     int driver_major;
203     int driver_minor;
204     int driver_patch;
205     Bool result = True;
206     char *x_driver_name = NULL;
207
208     if (driver_name)
209         *driver_name = NULL;
210     
211     vaStatus = va_DRI2GetDriverName(pDisplayContext, driver_name);
212     if (vaStatus != VA_STATUS_SUCCESS)
213         vaStatus = va_DRIGetDriverName(pDisplayContext, driver_name);
214
215     if ((vaStatus == VA_STATUS_SUCCESS)
216         && geteuid() == getuid())
217     {
218         /* don't allow setuid apps to use LIBVA_DRIVER_NAME */
219         if (getenv("LIBVA_DRIVER_NAME"))
220         {
221             /* For easier debugging */
222             if (*driver_name)
223                 XFree(*driver_name);
224             
225             *driver_name = strdup(getenv("LIBVA_DRIVER_NAME"));
226             return VA_STATUS_SUCCESS;
227         }
228     }
229     
230     return vaStatus;
231 }
232
233 int vaDisplayIsValid(VADisplay dpy)
234 {
235   VADisplayContextP tmp=NULL;
236   VADisplayContextP pDisplayContext = pDisplayContexts;
237
238   while (pDisplayContext)
239   {
240       if (pDisplayContext == (VADisplayContextP)dpy)
241       {
242           tmp = (VADisplay)pDisplayContext;
243           break;
244       }
245       pDisplayContext = pDisplayContext->pNext;
246   }
247
248   if (!tmp)
249       return 0;
250   
251   return tmp->vaIsValid(pDisplayContext);
252 }
253
254
255 VADisplay vaGetDisplay (
256     Display *native_dpy /* implementation specific */
257 )
258 {
259   VADisplay dpy = NULL;
260   VADisplayContextP pDisplayContext = pDisplayContexts;
261
262   if (!native_dpy)
263       return NULL;
264
265   while (pDisplayContext)
266   {
267       if (pDisplayContext->pDriverContext &&
268           pDisplayContext->pDriverContext->x11_dpy == native_dpy)
269       {
270           dpy = (VADisplay)pDisplayContext;
271           break;
272       }
273       pDisplayContext = pDisplayContext->pNext;
274   }
275
276   if (!dpy)
277   {
278       /* create new entry */
279       VADriverContextP pDriverContext;
280       pDisplayContext = calloc(1, sizeof(*pDisplayContext));
281       pDriverContext  = calloc(1, sizeof(*pDriverContext));
282       if (pDisplayContext && pDriverContext)
283       {
284           pDriverContext->old_pNext        = (void *)(unsigned long)0xdeadbeef;
285           pDriverContext->x11_dpy          = native_dpy;
286           pDisplayContext->pNext           = pDisplayContexts;
287           pDisplayContext->pDriverContext  = pDriverContext;
288           pDisplayContext->vaIsValid       = va_DisplayContextIsValid;
289           pDisplayContext->vaDestroy       = va_DisplayContextDestroy;
290           pDisplayContext->vaGetDriverName = va_DisplayContextGetDriverName;
291           pDisplayContexts                 = pDisplayContext;
292           dpy                              = (VADisplay)pDisplayContext;
293       }
294       else
295       {
296           if (pDisplayContext)
297               free(pDisplayContext);
298           if (pDriverContext)
299               free(pDriverContext);
300       }
301   }
302   
303   return dpy;
304 }