libva-1.0.6
[platform/upstream/libva.git] / va / 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 #define _GNU_SOURCE 1
26 #include "config.h"
27 #include "va.h"
28 #include "va_backend.h"
29 #include "va_x11.h"
30 #include "va_dri.h"
31 #include "va_dri2.h"
32 #include "va_dricommon.h"
33 #include "va_nvctrl.h"
34 #include "va_fglrx.h"
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdarg.h>
38 #include <string.h>
39 #include <unistd.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <fcntl.h>
43 #include <errno.h>
44
45 static VADisplayContextP pDisplayContexts = NULL;
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_DRI2GetDriverName (
86     VADisplayContextP pDisplayContext,
87     char **driver_name
88 )
89 {
90     VADriverContextP ctx = pDisplayContext->pDriverContext;
91
92     if (!isDRI2Connected(ctx, driver_name))
93         return VA_STATUS_ERROR_UNKNOWN;
94
95     return VA_STATUS_SUCCESS;
96 }
97
98 static VAStatus va_DRIGetDriverName (
99     VADisplayContextP pDisplayContext,
100     char **driver_name
101 )
102 {
103     VADriverContextP ctx = pDisplayContext->pDriverContext;
104
105     if (!isDRI1Connected(ctx, driver_name))
106         return VA_STATUS_ERROR_UNKNOWN;
107
108     return VA_STATUS_SUCCESS;
109 }
110
111 static VAStatus va_NVCTRL_GetDriverName (
112     VADisplayContextP pDisplayContext,
113     char **driver_name
114 )
115 {
116     VADriverContextP ctx = pDisplayContext->pDriverContext;
117     int direct_capable, driver_major, driver_minor, driver_patch;
118     Bool result;
119
120     result = VA_NVCTRLQueryDirectRenderingCapable((Display *)ctx->native_dpy, ctx->x11_screen,
121                                                   &direct_capable);
122     if (!result || !direct_capable)
123         return VA_STATUS_ERROR_UNKNOWN;
124
125     result = VA_NVCTRLGetClientDriverName((Display *)ctx->native_dpy, ctx->x11_screen,
126                                           &driver_major, &driver_minor,
127                                           &driver_patch, driver_name);
128     if (!result)
129         return VA_STATUS_ERROR_UNKNOWN;
130
131     return VA_STATUS_SUCCESS;
132 }
133
134 static VAStatus va_FGLRX_GetDriverName (
135     VADisplayContextP pDisplayContext,
136     char **driver_name
137 )
138 {
139     VADriverContextP ctx = pDisplayContext->pDriverContext;
140     int driver_major, driver_minor, driver_patch;
141     Bool result;
142
143     result = VA_FGLRXGetClientDriverName(ctx->native_dpy, ctx->x11_screen,
144                                          &driver_major, &driver_minor,
145                                          &driver_patch, driver_name);
146     if (!result)
147         return VA_STATUS_ERROR_UNKNOWN;
148
149     return VA_STATUS_SUCCESS;
150 }
151
152 static VAStatus va_DisplayContextGetDriverName (
153     VADisplayContextP pDisplayContext,
154     char **driver_name
155 )
156 {
157     VAStatus vaStatus;
158
159     if (driver_name)
160         *driver_name = NULL;
161
162     vaStatus = va_DRI2GetDriverName(pDisplayContext, driver_name);
163     if (vaStatus != VA_STATUS_SUCCESS)
164         vaStatus = va_DRIGetDriverName(pDisplayContext, driver_name);
165     if (vaStatus != VA_STATUS_SUCCESS)
166         vaStatus = va_NVCTRL_GetDriverName(pDisplayContext, driver_name);
167     if (vaStatus != VA_STATUS_SUCCESS)
168         vaStatus = va_FGLRX_GetDriverName(pDisplayContext, driver_name);
169     return vaStatus;
170 }
171
172
173 VADisplay vaGetDisplay (
174     Display *native_dpy /* implementation specific */
175 )
176 {
177   VADisplay dpy = NULL;
178   VADisplayContextP pDisplayContext = pDisplayContexts;
179
180   if (!native_dpy)
181       return NULL;
182
183   while (pDisplayContext)
184   {
185       if (pDisplayContext->pDriverContext &&
186           pDisplayContext->pDriverContext->native_dpy == (void *)native_dpy)
187       {
188           dpy = (VADisplay)pDisplayContext;
189           break;
190       }
191       pDisplayContext = pDisplayContext->pNext;
192   }
193
194   if (!dpy)
195   {
196       /* create new entry */
197       VADriverContextP pDriverContext;
198       struct dri_state *dri_state;
199       pDisplayContext = calloc(1, sizeof(*pDisplayContext));
200       pDriverContext  = calloc(1, sizeof(*pDriverContext));
201       dri_state       = calloc(1, sizeof(*dri_state));
202       if (pDisplayContext && pDriverContext && dri_state)
203       {
204           pDisplayContext->vadpy_magic = VA_DISPLAY_MAGIC;          
205
206           pDriverContext->native_dpy       = (void *)native_dpy;
207           pDisplayContext->pNext           = pDisplayContexts;
208           pDisplayContext->pDriverContext  = pDriverContext;
209           pDisplayContext->vaIsValid       = va_DisplayContextIsValid;
210           pDisplayContext->vaDestroy       = va_DisplayContextDestroy;
211           pDisplayContext->vaGetDriverName = va_DisplayContextGetDriverName;
212           pDisplayContext->opaque          = NULL;
213           pDisplayContexts                 = pDisplayContext;
214           pDriverContext->dri_state        = dri_state;
215           dpy                              = (VADisplay)pDisplayContext;
216       }
217       else
218       {
219           if (pDisplayContext)
220               free(pDisplayContext);
221           if (pDriverContext)
222               free(pDriverContext);
223           if (dri_state)
224               free(dri_state);
225       }
226   }
227   
228   return dpy;
229 }
230
231 #define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext)
232 #define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; }
233
234 extern int fool_postp; /* do nothing for vaPutSurface if set */
235 extern int trace_flag; /* trace vaPutSurface parameters */
236 #define VA_TRACE(trace_func,...)                \
237     if (trace_flag) {                           \
238         trace_func(__VA_ARGS__);                \
239     }
240
241 void va_TracePutSurface (
242     VADisplay dpy,
243     VASurfaceID surface,
244     void *draw, /* the target Drawable */
245     short srcx,
246     short srcy,
247     unsigned short srcw,
248     unsigned short srch,
249     short destx,
250     short desty,
251     unsigned short destw,
252     unsigned short desth,
253     VARectangle *cliprects, /* client supplied clip list */
254     unsigned int number_cliprects, /* number of clip rects in the clip list */
255     unsigned int flags /* de-interlacing flags */
256 );
257
258
259 VAStatus vaPutSurface (
260     VADisplay dpy,
261     VASurfaceID surface,
262     Drawable draw, /* X Drawable */
263     short srcx,
264     short srcy,
265     unsigned short srcw,
266     unsigned short srch,
267     short destx,
268     short desty,
269     unsigned short destw,
270     unsigned short desth,
271     VARectangle *cliprects, /* client supplied clip list */
272     unsigned int number_cliprects, /* number of clip rects in the clip list */
273     unsigned int flags /* de-interlacing flags */
274 )
275 {
276   VADriverContextP ctx;
277
278   if (fool_postp)
279       return VA_STATUS_SUCCESS;
280
281   CHECK_DISPLAY(dpy);
282   ctx = CTX(dpy);
283   
284   VA_TRACE(va_TracePutSurface, dpy, surface, (void *)draw, srcx, srcy, srcw, srch,
285            destx, desty, destw, desth,
286            cliprects, number_cliprects, flags );
287   
288   return ctx->vtable.vaPutSurface( ctx, surface, (void *)draw, srcx, srcy, srcw, srch,
289                                    destx, desty, destw, desth,
290                                    cliprects, number_cliprects, flags );
291 }