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