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
47static int va_DisplayContextIsValid (
48    VADisplayContextP pDisplayContext
49)
50{
51    return (pDisplayContext != NULL &&
52            pDisplayContext->pDriverContext != NULL);
53}
54
55static 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
77static 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
90static 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
103static 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
126static 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
144static 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
167VADisplay 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
216void 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
234VAStatus 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