1 /* 2 * Copyright (c) 2011 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 26 #include <sys/mman.h> 27 #include <va/va_tpi.h> 28 #include "psb_drv_video.h" 29 #include "psb_drv_debug.h" 30 #include "psb_surface.h" 31 #include "psb_surface_attrib.h" 32 33 #include <gralloc.h> 34 #include "android/psb_gralloc.h" 35 #include "android/psb_android_glue.h" 36 #ifndef BAYTRAIL 37 #include <hal/hal_public.h> 38 #endif 39 #include <wsbm/wsbm_manager.h> 40 41 #define INIT_DRIVER_DATA psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData; 42 #define CONFIG(id) ((object_config_p) object_heap_lookup( &driver_data->config_heap, id )) 43 #define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id )) 44 #define SURFACE(id) ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id )) 45 #define BUFFER(id) ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id )) 46 #define SHARE_INFO_INIT_VALUE 0x12345678 47 48 static pthread_mutex_t gralloc_mutex = PTHREAD_MUTEX_INITIALIZER; 49 50 /*FIXME: include hal_public.h instead of define it here*/ 51 enum { 52 GRALLOC_SUB_BUFFER0 = 0, 53 GRALLOC_SUB_BUFFER1, 54 GRALLOC_SUB_BUFFER2, 55 GRALLOC_SUB_BUFFER_MAX, 56 }; 57 58 VAStatus psb_DestroySurfaceGralloc(object_surface_p obj_surface) 59 { 60 void *vaddr[GRALLOC_SUB_BUFFER_MAX]; 61 int usage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER; 62 buffer_handle_t handle = obj_surface->psb_surface->buf.handle; 63 64 #ifdef PSBVIDEO_MRFL 65 usage |= GRALLOC_USAGE_SW_WRITE_OFTEN; 66 #endif 67 68 pthread_mutex_lock(&gralloc_mutex); 69 if (!gralloc_lock(handle, usage, 0, 0, 70 obj_surface->width, obj_surface->height, (void **)&vaddr[GRALLOC_SUB_BUFFER0])){ 71 if (obj_surface->share_info && vaddr[GRALLOC_SUB_BUFFER1] == obj_surface->share_info) { 72 int metadata_rotate = obj_surface->share_info->metadata_rotate; 73 int surface_protected = obj_surface->share_info->surface_protected; 74 int force_output_method = obj_surface->share_info->force_output_method; 75 int bob_deinterlace = obj_surface->share_info->bob_deinterlace; 76 77 memset(obj_surface->share_info, 0, sizeof(struct psb_surface_share_info_s)); 78 /* Still need to keep these info so that hwc can get them after suspend/resume cycle */ 79 obj_surface->share_info->metadata_rotate = metadata_rotate; 80 obj_surface->share_info->surface_protected = surface_protected; 81 obj_surface->share_info->force_output_method = force_output_method; 82 obj_surface->share_info->bob_deinterlace = bob_deinterlace; 83 } 84 gralloc_unlock(handle); 85 } 86 pthread_mutex_unlock(&gralloc_mutex); 87 88 return VA_STATUS_SUCCESS; 89 } 90 91 #ifdef BAYTRAIL 92 VAStatus psb_CreateSurfacesFromGralloc( 93 VADriverContextP ctx, 94 int width, 95 int height, 96 int format, 97 int num_surfaces, 98 VASurfaceID *surface_list, /* out */ 99 PsbSurfaceAttributeTPI *attribute_tpi 100 ) 101 { 102 INIT_DRIVER_DATA 103 VAStatus vaStatus = VA_STATUS_SUCCESS; 104 int i, height_origin, usage, buffer_stride = 0; 105 int protected = (VA_RT_FORMAT_PROTECTED & format); 106 unsigned long fourcc; 107 VASurfaceAttributeTPI *external_buffers = NULL; 108 unsigned long handle; 109 int size = num_surfaces * sizeof(unsigned int); 110 void *vaddr; 111 112 113 /* follow are gralloc-buffers */ 114 format = format & (~VA_RT_FORMAT_PROTECTED); 115 driver_data->protected = protected; 116 117 CHECK_INVALID_PARAM(num_surfaces <= 0); 118 CHECK_SURFACE(surface_list); 119 120 external_buffers = attribute_tpi; 121 122 ALOGD("format is 0x%x, width is %d, height is %d, num_surfaces is %d.\n", format, width, height, num_surfaces); 123 /* We only support one format */ 124 if ((VA_RT_FORMAT_YUV420 != format) 125 && (VA_RT_FORMAT_YUV422 != format)) { 126 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; 127 DEBUG_FAILURE; 128 return vaStatus; 129 } 130 131 CHECK_INVALID_PARAM(external_buffers == NULL); 132 133 /* 134 vaStatus = psb__checkSurfaceDimensions(driver_data, width, height); 135 CHECK_VASTATUS(); 136 */ 137 /* Adjust height to be a multiple of 32 (height of macroblock in interlaced mode) */ 138 height_origin = height; 139 height = (height + 0x1f) & ~0x1f; 140 ALOGD("external_buffers->pixel_format is 0x%x.\n", external_buffers->pixel_format); 141 /* get native window from the reserved field */ 142 driver_data->native_window = (void *)external_buffers->reserved[0]; 143 144 for (i = 0; i < num_surfaces; i++) { 145 int surfaceID; 146 object_surface_p obj_surface; 147 psb_surface_p psb_surface; 148 149 surfaceID = object_heap_allocate(&driver_data->surface_heap); 150 obj_surface = SURFACE(surfaceID); 151 if (NULL == obj_surface) { 152 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 153 DEBUG_FAILURE; 154 break; 155 } 156 MEMSET_OBJECT(obj_surface, struct object_surface_s); 157 158 obj_surface->surface_id = surfaceID; 159 surface_list[i] = surfaceID; 160 obj_surface->context_id = -1; 161 obj_surface->width = width; 162 obj_surface->height = height; 163 obj_surface->width_r = width; 164 obj_surface->height_r = height; 165 obj_surface->height_origin = height_origin; 166 obj_surface->is_ref_surface = 0; 167 168 psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s)); 169 if (NULL == psb_surface) { 170 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); 171 obj_surface->surface_id = VA_INVALID_SURFACE; 172 173 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 174 175 DEBUG_FAILURE; 176 break; 177 } 178 179 switch (format) { 180 case VA_RT_FORMAT_YUV422: 181 fourcc = VA_FOURCC_YV16; 182 break; 183 case VA_RT_FORMAT_YUV420: 184 default: 185 fourcc = VA_FOURCC_NV12; 186 break; 187 } 188 189 /*hard code the gralloc buffer usage*/ 190 usage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER; 191 192 /* usage hack for byt */ 193 usage |= GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN; 194 /* usage hack to force pages alloc and CPU/GPU cache flush */ 195 usage |= GRALLOC_USAGE_HW_VIDEO_ENCODER; 196 197 handle = (unsigned long)external_buffers->buffers[i]; 198 pthread_mutex_lock(&gralloc_mutex); 199 if (gralloc_lock(handle, usage, 0, 0, width, height, (void **)&vaddr)) { 200 vaStatus = VA_STATUS_ERROR_UNKNOWN; 201 } else { 202 int cache_flag = PSB_USER_BUFFER_UNCACHED; 203 int buf_fd = gralloc_getbuffd(handle); 204 205 vaStatus = psb_surface_create_from_ub(driver_data, width, height, fourcc, 206 external_buffers, psb_surface, vaddr, buf_fd, 207 cache_flag); 208 209 psb_surface->buf.handle = handle; 210 obj_surface->share_info = NULL; 211 gralloc_unlock(handle); 212 } 213 pthread_mutex_unlock(&gralloc_mutex); 214 215 if (VA_STATUS_SUCCESS != vaStatus) { 216 free(psb_surface); 217 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); 218 obj_surface->surface_id = VA_INVALID_SURFACE; 219 220 DEBUG_FAILURE; 221 break; 222 } 223 buffer_stride = psb_surface->stride; 224 #ifdef PSBVIDEO_MSVDX_DEC_TILING 225 psb_surface->extra_info[7] = external_buffers->tiling; 226 #endif 227 /* by default, surface fourcc is NV12 */ 228 psb_surface->extra_info[4] = fourcc; 229 obj_surface->psb_surface = psb_surface; 230 } 231 232 /* Error recovery */ 233 if (VA_STATUS_SUCCESS != vaStatus) { 234 /* surface_list[i-1] was the last successful allocation */ 235 for (; i--;) { 236 object_surface_p obj_surface = SURFACE(surface_list[i]); 237 psb__destroy_surface(driver_data, obj_surface); 238 surface_list[i] = VA_INVALID_SURFACE; 239 } 240 drv_debug_msg(VIDEO_DEBUG_ERROR, "CreateSurfaces failed\n"); 241 242 return vaStatus; 243 } 244 245 return vaStatus; 246 } 247 #else 248 VAStatus psb_CreateSurfacesFromGralloc( 249 VADriverContextP ctx, 250 int width, 251 int height, 252 int format, 253 int num_surfaces, 254 VASurfaceID *surface_list, /* out */ 255 PsbSurfaceAttributeTPI *attribute_tpi 256 ) 257 { 258 INIT_DRIVER_DATA 259 VAStatus vaStatus = VA_STATUS_SUCCESS; 260 int i, height_origin, usage, buffer_stride = 0; 261 int protected = (VA_RT_FORMAT_PROTECTED & format); 262 unsigned long fourcc; 263 PsbSurfaceAttributeTPI *external_buffers = NULL; 264 unsigned long handle; 265 int size = num_surfaces * sizeof(unsigned int); 266 void *vaddr[GRALLOC_SUB_BUFFER_MAX]; 267 268 /* follow are gralloc-buffers */ 269 format = format & (~VA_RT_FORMAT_PROTECTED); 270 driver_data->protected = protected; 271 272 CHECK_INVALID_PARAM(num_surfaces <= 0); 273 CHECK_SURFACE(surface_list); 274 275 external_buffers = attribute_tpi; 276 277 /* We only support one format */ 278 if ((VA_RT_FORMAT_YUV420 != format) 279 && (VA_RT_FORMAT_YUV422 != format) 280 && (VA_RT_FORMAT_RGB32 != format)) { 281 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; 282 DEBUG_FAILURE; 283 return vaStatus; 284 } 285 286 CHECK_INVALID_PARAM(external_buffers == NULL); 287 288 /* 289 vaStatus = psb__checkSurfaceDimensions(driver_data, width, height); 290 CHECK_VASTATUS(); 291 */ 292 /* Adjust height to be a multiple of 32 (height of macroblock in interlaced mode) */ 293 height_origin = height; 294 295 IMG_native_handle_t* h = (IMG_native_handle_t*)external_buffers->buffers[0]; 296 int gfx_colorformat = h->iFormat; 297 298 if (gfx_colorformat != HAL_PIXEL_FORMAT_NV12 && format != VA_RT_FORMAT_RGB32) 299 height = (height + 0x1f) & ~0x1f; 300 301 /* get native window from the reserved field */ 302 driver_data->native_window = (void *)external_buffers->reserved[0]; 303 304 for (i = 0; i < num_surfaces; i++) { 305 int surfaceID; 306 object_surface_p obj_surface; 307 psb_surface_p psb_surface; 308 309 surfaceID = object_heap_allocate(&driver_data->surface_heap); 310 obj_surface = SURFACE(surfaceID); 311 if (NULL == obj_surface) { 312 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 313 DEBUG_FAILURE; 314 break; 315 } 316 MEMSET_OBJECT(obj_surface, struct object_surface_s); 317 318 obj_surface->surface_id = surfaceID; 319 surface_list[i] = surfaceID; 320 obj_surface->context_id = -1; 321 obj_surface->width = width; 322 obj_surface->height = height; 323 obj_surface->width_r = width; 324 obj_surface->height_r = height; 325 obj_surface->height_origin = height_origin; 326 327 psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s)); 328 if (NULL == psb_surface) { 329 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); 330 obj_surface->surface_id = VA_INVALID_SURFACE; 331 332 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 333 334 DEBUG_FAILURE; 335 break; 336 } 337 338 switch (format) { 339 case VA_RT_FORMAT_YUV422: 340 fourcc = VA_FOURCC_YV16; 341 break; 342 case VA_RT_FORMAT_RGB32: 343 fourcc = VA_FOURCC_RGBA; 344 break; 345 case VA_RT_FORMAT_YUV420: 346 default: 347 fourcc = VA_FOURCC_NV12; 348 break; 349 } 350 351 #ifndef PSBVIDEO_MSVDX_DEC_TILING 352 external_buffers->tiling = 0; 353 #endif 354 /*hard code the gralloc buffer usage*/ 355 usage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER; 356 357 if (gfx_colorformat == HAL_PIXEL_FORMAT_NV12) 358 usage |= GRALLOC_USAGE_SW_READ_OFTEN; 359 else { 360 // video decoder allows app to read/write the buffer 361 usage |= GRALLOC_USAGE_SW_WRITE_RARELY | GRALLOC_USAGE_SW_READ_RARELY; 362 } 363 364 handle = (unsigned long)external_buffers->buffers[i]; 365 pthread_mutex_lock(&gralloc_mutex); 366 367 if (gralloc_lock((buffer_handle_t)handle, usage, 0, 0, width, height, (void **)&vaddr[GRALLOC_SUB_BUFFER0])) { 368 vaStatus = VA_STATUS_ERROR_UNKNOWN; 369 } else { 370 int cache_flag = PSB_USER_BUFFER_UNCACHED; 371 int buf_fd = gralloc_getbuffd((buffer_handle_t)handle); 372 #ifdef PSBVIDEO_MRFL 373 //cache_flag = 0; 374 #endif 375 vaStatus = psb_surface_create_from_ub(driver_data, width, height, fourcc, 376 (VASurfaceAttributeTPI *)external_buffers, psb_surface, 377 vaddr[GRALLOC_SUB_BUFFER0], buf_fd, cache_flag); 378 psb_surface->buf.handle = (void *)handle; 379 obj_surface->share_info = NULL; 380 381 if ((gfx_colorformat != HAL_PIXEL_FORMAT_NV12) && 382 (gfx_colorformat != HAL_PIXEL_FORMAT_YV12) && 383 (format != VA_RT_FORMAT_RGB32)) { 384 385 unsigned int decoder_share_info = (unsigned int)external_buffers->reserved[2]; 386 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s : Create graphic buffer initialized share info %d",__FUNCTION__, decoder_share_info); 387 obj_surface->share_info = (psb_surface_share_info_t *)vaddr[GRALLOC_SUB_BUFFER1]; 388 389 if (obj_surface->share_info->initialized != SHARE_INFO_INIT_VALUE) { 390 memset(obj_surface->share_info, 0, sizeof(struct psb_surface_share_info_s)); 391 // Set clear video the default output method as OUTPUT_FORCE_OVERLAY_FOR_SW_DECODE 392 // if the video can be decoded by HW, will reset the output method as 0 in psb_BeginPicture 393 #ifdef PSBVIDEO_MSVDX_DEC_TILING 394 obj_surface->share_info->tiling = external_buffers->tiling; 395 #endif 396 obj_surface->share_info->width = obj_surface->width; 397 obj_surface->share_info->height = obj_surface->height_origin; 398 399 obj_surface->share_info->luma_stride = psb_surface->stride; 400 obj_surface->share_info->chroma_u_stride = psb_surface->stride; 401 obj_surface->share_info->chroma_v_stride = psb_surface->stride; 402 obj_surface->share_info->format = VA_FOURCC_NV12; 403 404 obj_surface->share_info->khandle = (uint32_t)(wsbmKBufHandle(wsbmKBuf(psb_surface->buf.drm_buf))); 405 406 obj_surface->share_info->initialized = SHARE_INFO_INIT_VALUE; 407 } 408 409 if (decoder_share_info) { 410 obj_surface->share_info->force_output_method = protected ? OUTPUT_FORCE_OVERLAY : OUTPUT_FORCE_OVERLAY_FOR_SW_DECODE; 411 obj_surface->share_info->native_window = (void *)external_buffers->reserved[0]; 412 413 attribute_tpi->reserved[1] = (unsigned long)obj_surface->share_info; 414 415 if (vaddr[GRALLOC_SUB_BUFFER0] == NULL) { 416 drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to lock graphic buffer in psb_video"); 417 } 418 else { 419 size = psb_surface->chroma_offset; 420 // the following memset was used to work-around Bug 19197299 on L. 421 // on DDK-1.5 we didn't observe the problem so comment it out. 422 // memset((char *)vaddr[GRALLOC_SUB_BUFFER0], 0, size); 423 // memset((char *)vaddr[GRALLOC_SUB_BUFFER0] + size, 0x80, psb_surface->size - size); 424 } 425 // overlay only support BT.601 and BT.709 426 if (driver_data->load_csc_matrix == 1) { 427 obj_surface->share_info->csc_mode = (driver_data->is_BT601 == 1) ? 0 : 1; 428 } else { 429 // if csc matrix is not set, use BT601 by default 430 obj_surface->share_info->csc_mode = 0; 431 } 432 433 if (driver_data->set_video_range == 1) { 434 obj_surface->share_info->video_range = driver_data->video_range; 435 } else { 436 // if video range is not set, use limited range by default 437 obj_surface->share_info->video_range = 0; 438 } 439 440 obj_surface->share_info->surface_protected = driver_data->protected; 441 if (driver_data->render_rect.width == 0 || driver_data->render_rect.height == 0) { 442 obj_surface->share_info->crop_width = obj_surface->share_info->width; 443 obj_surface->share_info->crop_height = obj_surface->share_info->height; 444 } else { 445 obj_surface->share_info->crop_width = driver_data->render_rect.width; 446 obj_surface->share_info->crop_height = driver_data->render_rect.height; 447 } 448 449 if (obj_surface->share_info->coded_width == 0 || obj_surface->share_info->coded_height == 0) { 450 obj_surface->share_info->coded_width = (obj_surface->share_info->width + 0xf) & ~0xf; 451 obj_surface->share_info->coded_height = (obj_surface->share_info->height + 0xf) & ~0xf; 452 } 453 454 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s : Create graphic buffer success" 455 "surface_id= 0x%x, vaddr[0] (0x%x), vaddr[1] (0x%x)\n", 456 __FUNCTION__, surfaceID, vaddr[GRALLOC_SUB_BUFFER0], vaddr[GRALLOC_SUB_BUFFER1]); 457 } 458 } 459 gralloc_unlock((buffer_handle_t)handle); 460 psb_surface->buf.user_ptr = NULL; 461 } 462 pthread_mutex_unlock(&gralloc_mutex); 463 464 if (VA_STATUS_SUCCESS != vaStatus) { 465 free(psb_surface); 466 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); 467 obj_surface->surface_id = VA_INVALID_SURFACE; 468 469 DEBUG_FAILURE; 470 break; 471 } 472 buffer_stride = psb_surface->stride; 473 /* by default, surface fourcc is NV12 */ 474 psb_surface->extra_info[4] = fourcc; 475 /* save the pixel format set by application */ 476 psb_surface->extra_info[8] = external_buffers->pixel_format; 477 #ifdef PSBVIDEO_MSVDX_DEC_TILING 478 psb_surface->extra_info[7] = external_buffers->tiling; 479 #endif 480 obj_surface->psb_surface = psb_surface; 481 } 482 483 /* Error recovery */ 484 if (VA_STATUS_SUCCESS != vaStatus) { 485 /* surface_list[i-1] was the last successful allocation */ 486 for (; i--;) { 487 object_surface_p obj_surface = SURFACE(surface_list[i]); 488 psb__destroy_surface(driver_data, obj_surface); 489 surface_list[i] = VA_INVALID_SURFACE; 490 } 491 drv_debug_msg(VIDEO_DEBUG_ERROR, "CreateSurfaces failed\n"); 492 493 return vaStatus; 494 } 495 496 return vaStatus; 497 } 498 499 #endif 500