• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
psb_DestroySurfaceGralloc(object_surface_p obj_surface)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
psb_CreateSurfacesFromGralloc(VADriverContextP ctx,int width,int height,int format,int num_surfaces,VASurfaceID * surface_list,PsbSurfaceAttributeTPI * attribute_tpi)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
psb_CreateSurfacesFromGralloc(VADriverContextP ctx,int width,int height,int format,int num_surfaces,VASurfaceID * surface_list,PsbSurfaceAttributeTPI * attribute_tpi)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