• 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     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
psb_CreateSurfacesFromGralloc(VADriverContextP ctx,int width,int height,int format,int num_surfaces,VASurfaceID * surface_list,PsbSurfaceAttributeTPI * attribute_tpi)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
psb_CreateSurfacesFromGralloc(VADriverContextP ctx,int width,int height,int format,int num_surfaces,VASurfaceID * surface_list,PsbSurfaceAttributeTPI * attribute_tpi)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