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 "sysdeps.h"
27 #include "va.h"
28 #include "va_backend.h"
29 #include "va_trace.h"
30 #include "va_fool.h"
31 #include "va_x11.h"
32 #include "va_dri.h"
33 #include "va_dri2.h"
34 #include "va_dricommon.h"
35 #include "va_nvctrl.h"
36 #include "va_fglrx.h"
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <stdarg.h>
40 #include <string.h>
41 #include <unistd.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #include <fcntl.h>
45 #include <errno.h>
46 
va_DisplayContextIsValid(VADisplayContextP pDisplayContext)47 static int va_DisplayContextIsValid (
48     VADisplayContextP pDisplayContext
49 )
50 {
51     return (pDisplayContext != NULL &&
52             pDisplayContext->pDriverContext != NULL);
53 }
54 
va_DisplayContextDestroy(VADisplayContextP pDisplayContext)55 static void va_DisplayContextDestroy (
56     VADisplayContextP pDisplayContext
57 )
58 {
59     VADriverContextP ctx;
60     struct dri_state *dri_state;
61 
62     if (pDisplayContext == NULL)
63         return;
64 
65     ctx = pDisplayContext->pDriverContext;
66     dri_state = ctx->drm_state;
67 
68     if (dri_state && dri_state->close)
69         dri_state->close(ctx);
70 
71     free(pDisplayContext->pDriverContext->drm_state);
72     free(pDisplayContext->pDriverContext);
73     free(pDisplayContext);
74 }
75 
76 
va_DRI2GetDriverName(VADisplayContextP pDisplayContext,char ** driver_name)77 static VAStatus va_DRI2GetDriverName (
78     VADisplayContextP pDisplayContext,
79     char **driver_name
80 )
81 {
82     VADriverContextP ctx = pDisplayContext->pDriverContext;
83 
84     if (!isDRI2Connected(ctx, driver_name))
85         return VA_STATUS_ERROR_UNKNOWN;
86 
87     return VA_STATUS_SUCCESS;
88 }
89 
va_DRIGetDriverName(VADisplayContextP pDisplayContext,char ** driver_name)90 static VAStatus va_DRIGetDriverName (
91     VADisplayContextP pDisplayContext,
92     char **driver_name
93 )
94 {
95     VADriverContextP ctx = pDisplayContext->pDriverContext;
96 
97     if (!isDRI1Connected(ctx, driver_name))
98         return VA_STATUS_ERROR_UNKNOWN;
99 
100     return VA_STATUS_SUCCESS;
101 }
102 
va_NVCTRL_GetDriverName(VADisplayContextP pDisplayContext,char ** driver_name)103 static VAStatus va_NVCTRL_GetDriverName (
104     VADisplayContextP pDisplayContext,
105     char **driver_name
106 )
107 {
108     VADriverContextP ctx = pDisplayContext->pDriverContext;
109     int direct_capable, driver_major, driver_minor, driver_patch;
110     Bool result;
111 
112     result = VA_NVCTRLQueryDirectRenderingCapable(ctx->native_dpy, ctx->x11_screen,
113                                                   &direct_capable);
114     if (!result || !direct_capable)
115         return VA_STATUS_ERROR_UNKNOWN;
116 
117     result = VA_NVCTRLGetClientDriverName(ctx->native_dpy, ctx->x11_screen,
118                                           &driver_major, &driver_minor,
119                                           &driver_patch, driver_name);
120     if (!result)
121         return VA_STATUS_ERROR_UNKNOWN;
122 
123     return VA_STATUS_SUCCESS;
124 }
125 
va_FGLRX_GetDriverName(VADisplayContextP pDisplayContext,char ** driver_name)126 static VAStatus va_FGLRX_GetDriverName (
127     VADisplayContextP pDisplayContext,
128     char **driver_name
129 )
130 {
131     VADriverContextP ctx = pDisplayContext->pDriverContext;
132     int driver_major, driver_minor, driver_patch;
133     Bool result;
134 
135     result = VA_FGLRXGetClientDriverName(ctx->native_dpy, ctx->x11_screen,
136                                          &driver_major, &driver_minor,
137                                          &driver_patch, driver_name);
138     if (!result)
139         return VA_STATUS_ERROR_UNKNOWN;
140 
141     return VA_STATUS_SUCCESS;
142 }
143 
va_DisplayContextGetDriverName(VADisplayContextP pDisplayContext,char ** driver_name)144 static VAStatus va_DisplayContextGetDriverName (
145     VADisplayContextP pDisplayContext,
146     char **driver_name
147 )
148 {
149     VAStatus vaStatus;
150 
151     if (driver_name)
152 	*driver_name = NULL;
153     else
154         return VA_STATUS_ERROR_UNKNOWN;
155 
156     vaStatus = va_DRI2GetDriverName(pDisplayContext, driver_name);
157     if (vaStatus != VA_STATUS_SUCCESS)
158         vaStatus = va_DRIGetDriverName(pDisplayContext, driver_name);
159     if (vaStatus != VA_STATUS_SUCCESS)
160         vaStatus = va_NVCTRL_GetDriverName(pDisplayContext, driver_name);
161     if (vaStatus != VA_STATUS_SUCCESS)
162         vaStatus = va_FGLRX_GetDriverName(pDisplayContext, driver_name);
163     return vaStatus;
164 }
165 
166 
vaGetDisplay(Display * native_dpy)167 VADisplay vaGetDisplay (
168     Display *native_dpy /* implementation specific */
169 )
170 {
171   VADisplay dpy = NULL;
172   VADisplayContextP pDisplayContext;
173 
174   if (!native_dpy)
175       return NULL;
176 
177   if (!dpy)
178   {
179       /* create new entry */
180       VADriverContextP pDriverContext;
181       struct dri_state *dri_state;
182       pDisplayContext = calloc(1, sizeof(*pDisplayContext));
183       pDriverContext  = calloc(1, sizeof(*pDriverContext));
184       dri_state       = calloc(1, sizeof(*dri_state));
185       if (pDisplayContext && pDriverContext && dri_state)
186       {
187 	  pDisplayContext->vadpy_magic = VA_DISPLAY_MAGIC;
188 
189 	  pDriverContext->native_dpy       = (void *)native_dpy;
190           pDriverContext->display_type     = VA_DISPLAY_X11;
191 	  pDisplayContext->pDriverContext  = pDriverContext;
192 	  pDisplayContext->vaIsValid       = va_DisplayContextIsValid;
193 	  pDisplayContext->vaDestroy       = va_DisplayContextDestroy;
194 	  pDisplayContext->vaGetDriverName = va_DisplayContextGetDriverName;
195           pDisplayContext->opaque          = NULL;
196 	  pDriverContext->drm_state 	   = dri_state;
197 	  dpy                              = (VADisplay)pDisplayContext;
198       }
199       else
200       {
201 	  if (pDisplayContext)
202 	      free(pDisplayContext);
203 	  if (pDriverContext)
204 	      free(pDriverContext);
205           if (dri_state)
206               free(dri_state);
207       }
208   }
209 
210   return dpy;
211 }
212 
213 #define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext)
214 #define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; }
215 
216 void va_TracePutSurface (
217     VADisplay dpy,
218     VASurfaceID surface,
219     void *draw, /* the target Drawable */
220     short srcx,
221     short srcy,
222     unsigned short srcw,
223     unsigned short srch,
224     short destx,
225     short desty,
226     unsigned short destw,
227     unsigned short desth,
228     VARectangle *cliprects, /* client supplied clip list */
229     unsigned int number_cliprects, /* number of clip rects in the clip list */
230     unsigned int flags /* de-interlacing flags */
231 );
232 
233 
vaPutSurface(VADisplay dpy,VASurfaceID surface,Drawable draw,short srcx,short srcy,unsigned short srcw,unsigned short srch,short destx,short desty,unsigned short destw,unsigned short desth,VARectangle * cliprects,unsigned int number_cliprects,unsigned int flags)234 VAStatus vaPutSurface (
235     VADisplay dpy,
236     VASurfaceID surface,
237     Drawable draw, /* X Drawable */
238     short srcx,
239     short srcy,
240     unsigned short srcw,
241     unsigned short srch,
242     short destx,
243     short desty,
244     unsigned short destw,
245     unsigned short desth,
246     VARectangle *cliprects, /* client supplied clip list */
247     unsigned int number_cliprects, /* number of clip rects in the clip list */
248     unsigned int flags /* de-interlacing flags */
249 )
250 {
251   VADriverContextP ctx;
252 
253   if (fool_postp)
254       return VA_STATUS_SUCCESS;
255 
256   CHECK_DISPLAY(dpy);
257   ctx = CTX(dpy);
258 
259   VA_TRACE_LOG(va_TracePutSurface, dpy, surface, (void *)draw, srcx, srcy, srcw, srch,
260                destx, desty, destw, desth,
261                cliprects, number_cliprects, flags );
262 
263   return ctx->vtable->vaPutSurface( ctx, surface, (void *)draw, srcx, srcy, srcw, srch,
264                                    destx, desty, destw, desth,
265                                    cliprects, number_cliprects, flags );
266 }
267