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_android.h" 32 #include "va_drmcommon.h" 33 #include "va_drm_utils.h" 34 #include <stdarg.h> 35 #include <unistd.h> 36 #include <sys/types.h> 37 #include <sys/stat.h> 38 #include <fcntl.h> 39 #include <dlfcn.h> 40 #include <errno.h> 41 42 43 #define CHECK_SYMBOL(func) { if (!func) printf("func %s not found\n", #func); return VA_STATUS_ERROR_UNKNOWN; } 44 #define DEVICE_NAME "/dev/dri/card0" 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); 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 (pDisplayContext != NULL && 81 pDisplayContext->pDriverContext != NULL); 82 } 83 84 static void va_DisplayContextDestroy ( 85 VADisplayContextP pDisplayContext 86 ) 87 { 88 struct drm_state *drm_state; 89 90 if (pDisplayContext == NULL) 91 return; 92 93 /* close the open-ed DRM fd */ 94 drm_state = (struct drm_state *)pDisplayContext->pDriverContext->drm_state; 95 close(drm_state->fd); 96 97 free(pDisplayContext->pDriverContext->drm_state); 98 free(pDisplayContext->pDriverContext); 99 free(pDisplayContext); 100 } 101 102 static VAStatus va_DisplayContextGetDriverName ( 103 VADisplayContextP pDisplayContext, 104 char **driver_name 105 ) 106 { 107 VADriverContextP const ctx = pDisplayContext->pDriverContext; 108 struct drm_state * drm_state = (struct drm_state *)ctx->drm_state; 109 110 memset(drm_state, 0, sizeof(*drm_state)); 111 drm_state->fd = open_device((char *)DEVICE_NAME); 112 113 if (drm_state->fd < 0) { 114 fprintf(stderr,"can't open DRM devices\n"); 115 return VA_STATUS_ERROR_UNKNOWN; 116 } 117 drm_state->auth_type = VA_DRM_AUTH_CUSTOM; 118 119 if (driver_name == NULL) 120 return VA_STATUS_ERROR_UNKNOWN; 121 122 if (strncmp((char *)ctx->native_dpy, "libva_driver_name=", 18) == 0) { 123 *driver_name = strdup((char *)ctx->native_dpy + 18); 124 if (*driver_name == NULL) 125 return VA_STATUS_ERROR_ALLOCATION_FAILED; 126 else 127 return VA_STATUS_SUCCESS; 128 } else { 129 return VA_DRM_GetDriverName(ctx, driver_name); 130 } 131 } 132 133 134 VADisplay vaGetDisplay ( 135 void *native_dpy /* implementation specific */ 136 ) 137 { 138 VADisplay dpy = NULL; 139 VADisplayContextP pDisplayContext; 140 141 if (!native_dpy) 142 return NULL; 143 144 if (!dpy) 145 { 146 /* create new entry */ 147 VADriverContextP pDriverContext = 0; 148 struct drm_state *drm_state = 0; 149 pDisplayContext = (VADisplayContextP)calloc(1, sizeof(*pDisplayContext)); 150 pDriverContext = (VADriverContextP)calloc(1, sizeof(*pDriverContext)); 151 drm_state = (struct drm_state*)calloc(1, sizeof(*drm_state)); 152 if (pDisplayContext && pDriverContext && drm_state) 153 { 154 pDisplayContext->vadpy_magic = VA_DISPLAY_MAGIC; 155 156 pDriverContext->native_dpy = (void *)native_dpy; 157 pDriverContext->display_type = VA_DISPLAY_ANDROID; 158 pDisplayContext->pDriverContext = pDriverContext; 159 pDisplayContext->vaIsValid = va_DisplayContextIsValid; 160 pDisplayContext->vaDestroy = va_DisplayContextDestroy; 161 pDisplayContext->vaGetDriverName = va_DisplayContextGetDriverName; 162 pDriverContext->drm_state = drm_state; 163 dpy = (VADisplay)pDisplayContext; 164 } 165 else 166 { 167 if (pDisplayContext) 168 free(pDisplayContext); 169 if (pDriverContext) 170 free(pDriverContext); 171 if (drm_state) 172 free(drm_state); 173 } 174 } 175 176 return dpy; 177 } 178 179 #define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext) 180 #define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; } 181 182 183 extern "C" { 184 extern int fool_postp; /* do nothing for vaPutSurface if set */ 185 extern int trace_flag; /* trace vaPutSurface parameters */ 186 187 void va_TracePutSurface ( 188 VADisplay dpy, 189 VASurfaceID surface, 190 void *draw, /* the target Drawable */ 191 short srcx, 192 short srcy, 193 unsigned short srcw, 194 unsigned short srch, 195 short destx, 196 short desty, 197 unsigned short destw, 198 unsigned short desth, 199 VARectangle *cliprects, /* client supplied clip list */ 200 unsigned int number_cliprects, /* number of clip rects in the clip list */ 201 unsigned int flags /* de-interlacing flags */ 202 ); 203 } 204 205 VAStatus vaPutSurface ( 206 VADisplay dpy, 207 VASurfaceID surface, 208 sp<ANativeWindow> draw, /* Android Native Window */ 209 short srcx, 210 short srcy, 211 unsigned short srcw, 212 unsigned short srch, 213 short destx, 214 short desty, 215 unsigned short destw, 216 unsigned short desth, 217 VARectangle *cliprects, /* client supplied clip list */ 218 unsigned int number_cliprects, /* number of clip rects in the clip list */ 219 unsigned int flags /* de-interlacing flags */ 220 ) 221 { 222 VADriverContextP ctx; 223 224 if (fool_postp) 225 return VA_STATUS_SUCCESS; 226 227 if (draw == NULL) 228 return VA_STATUS_ERROR_UNKNOWN; 229 230 CHECK_DISPLAY(dpy); 231 ctx = CTX(dpy); 232 233 VA_TRACE_LOG(va_TracePutSurface, dpy, surface, static_cast<void*>(&draw), srcx, srcy, srcw, srch, 234 destx, desty, destw, desth, 235 cliprects, number_cliprects, flags ); 236 237 return ctx->vtable->vaPutSurface( ctx, surface, static_cast<void*>(&draw), srcx, srcy, srcw, srch, 238 destx, desty, destw, desth, 239 cliprects, number_cliprects, flags ); 240 } 241 242