Home | History | Annotate | Download | only in android
      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