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