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