• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
3  * Copyright (c) Imagination Technologies Limited, UK
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sub license, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the
14  * next paragraph) shall be included in all copies or substantial portions
15  * of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
21  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  *
25  * Authors:
26  *    Waldo Bastian <waldo.bastian@intel.com>
27  *
28  */
29 
30 #include <va/va_backend.h>
31 #include <va/va_backend_tpi.h>
32 #include <va/va_backend_egl.h>
33 #ifdef PSBVIDEO_MRFL_VPP
34 #include <va/va_backend_vpp.h>
35 #endif
36 #ifdef PSBVIDEO_MFLD
37 #include <va/va_backend_vpp.h>
38 #endif
39 #include <va/va_drmcommon.h>
40 #include <va/va_android.h>
41 #include <va/va_tpi.h>
42 
43 #include "psb_drv_video.h"
44 #include "psb_texture.h"
45 #include "psb_cmdbuf.h"
46 #ifndef BAYTRAIL
47 #include "pnw_cmdbuf.h"
48 #include "tng_cmdbuf.h"
49 #endif
50 #ifdef PSBVIDEO_MRFL_VPP
51 #include "vsp_cmdbuf.h"
52 #endif
53 #include "psb_surface.h"
54 
55 #include "pnw_MPEG2.h"
56 #include "pnw_MPEG4.h"
57 #include "pnw_H264.h"
58 #include "pnw_VC1.h"
59 #include "tng_jpegdec.h"
60 #include "tng_VP8.h"
61 #include "tng_yuv_processor.h"
62 
63 #ifdef PSBVIDEO_MFLD
64 #include "pnw_MPEG4ES.h"
65 #include "pnw_H264ES.h"
66 #include "pnw_H263ES.h"
67 #include "pnw_jpeg.h"
68 #endif
69 #ifdef PSBVIDEO_MRFL
70 #include "tng_H264ES.h"
71 #include "tng_H263ES.h"
72 #include "tng_MPEG4ES.h"
73 #include "tng_jpegES.h"
74 #endif
75 #ifdef PSBVIDEO_MRFL_VPP
76 #include "vsp_VPP.h"
77 #include "vsp_vp8.h"
78 #endif
79 #include "psb_output.h"
80 #include <stdio.h>
81 #include <string.h>
82 #include <stdarg.h>
83 #include <time.h>
84 #include <unistd.h>
85 #include <wsbm/wsbm_pool.h>
86 #include <wsbm/wsbm_manager.h>
87 #include <wsbm/wsbm_util.h>
88 #include <wsbm/wsbm_fencemgr.h>
89 #include <linux/videodev2.h>
90 #include <errno.h>
91 
92 #include "psb_def.h"
93 #include "psb_drv_debug.h"
94 #ifndef BAYTRAIL
95 #include "psb_ws_driver.h"
96 #endif
97 #include "pnw_rotate.h"
98 #include "psb_surface_attrib.h"
99 #include "android/psb_gralloc.h"
100 
101 #ifndef PSB_PACKAGE_VERSION
102 #define PSB_PACKAGE_VERSION "Undefined"
103 #endif
104 
105 #define PSB_DRV_VERSION  PSB_PACKAGE_VERSION
106 #define PSB_CHG_REVISION "(0X00000071)"
107 
108 #define PSB_STR_VENDOR_MRST     "Intel GMA500-MRST-" PSB_DRV_VERSION " " PSB_CHG_REVISION
109 #define PSB_STR_VENDOR_MFLD     "Intel GMA500-MFLD-" PSB_DRV_VERSION " " PSB_CHG_REVISION
110 #define PSB_STR_VENDOR_MRFL     "Intel GMA500-MRFL-" PSB_DRV_VERSION " " PSB_CHG_REVISION
111 #define PSB_STR_VENDOR_BAYTRAIL     "Intel GMA500-BAYTRAIL-" PSB_DRV_VERSION " " PSB_CHG_REVISION
112 #define PSB_STR_VENDOR_LEXINGTON     "Intel GMA500-LEXINGTON-" PSB_DRV_VERSION " " PSB_CHG_REVISION
113 
114 #define MAX_UNUSED_BUFFERS      16
115 
116 #define PSB_MAX_FLIP_DELAY (1000/30/10)
117 
118 #include <signal.h>
119 
120 #define EXPORT __attribute__ ((visibility("default")))
121 
122 #define INIT_DRIVER_DATA    psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData;
123 
124 #ifdef PSBVIDEO_MRFL_VPP
125 #define INIT_FORMAT_VTABLE format_vtable_p format_vtable = ((profile < PSB_MAX_PROFILES) && (entrypoint < PSB_MAX_ENTRYPOINTS)) ? (profile == VAProfileNone? driver_data->vpp_profile : driver_data->profile2Format[profile][entrypoint]) : NULL;
126 #endif
127 #ifdef PSBVIDEO_MFLD
128 #define INIT_FORMAT_VTABLE format_vtable_p format_vtable = ((profile < PSB_MAX_PROFILES) && (entrypoint < PSB_MAX_ENTRYPOINTS)) ? (profile == VAProfileNone? driver_data->vpp_profile : driver_data->profile2Format[profile][entrypoint]) : NULL;
129 #endif
130 
131 #define CONFIG(id)  ((object_config_p) object_heap_lookup( &driver_data->config_heap, id ))
132 #define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
133 #define SURFACE(id)    ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id ))
134 #define BUFFER(id)  ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id ))
135 
136 #define CONFIG_ID_OFFSET        0x01000000
137 #define CONTEXT_ID_OFFSET       0x02000000
138 #define SURFACE_ID_OFFSET       0x03000000
139 #define BUFFER_ID_OFFSET        0x04000000
140 #define IMAGE_ID_OFFSET         0x05000000
141 #define SUBPIC_ID_OFFSET        0x06000000
142 
143 static int psb_get_device_info(VADriverContextP ctx);
144 
145 
146 void psb_init_surface_pvr2dbuf(psb_driver_data_p driver_data);
147 void psb_free_surface_pvr2dbuf(psb_driver_data_p driver_data);
148 
psb_QueryConfigProfiles(VADriverContextP ctx,VAProfile * profile_list,int * num_profiles)149 VAStatus psb_QueryConfigProfiles(
150     VADriverContextP ctx,
151     VAProfile *profile_list,    /* out */
152     int *num_profiles            /* out */
153 )
154 {
155     DEBUG_FUNC_ENTER
156     (void) ctx; /* unused */
157     int i = 0;
158     VAStatus vaStatus = VA_STATUS_SUCCESS;
159     INIT_DRIVER_DATA
160 
161     CHECK_INVALID_PARAM(profile_list == NULL);
162     CHECK_INVALID_PARAM(num_profiles == NULL);
163 
164 #ifdef PSBVIDEO_MRFL_VPP
165     profile_list[i++] = VAProfileNone;
166 #endif
167 //    profile_list[i++] = VAProfileMPEG2Simple;
168     profile_list[i++] = VAProfileMPEG2Main;
169     profile_list[i++] = VAProfileMPEG4Simple;
170     profile_list[i++] = VAProfileMPEG4AdvancedSimple;
171 //    profile_list[i++] = VAProfileMPEG4Main;
172     profile_list[i++] = VAProfileH264Baseline;
173     profile_list[i++] = VAProfileH264Main;
174     profile_list[i++] = VAProfileH264High;
175     profile_list[i++] = VAProfileH264StereoHigh;
176     profile_list[i++] = VAProfileVC1Simple;
177     profile_list[i++] = VAProfileVC1Main;
178     profile_list[i++] = VAProfileVC1Advanced;
179 
180     if (IS_MRFL(driver_data) || IS_BAYTRAIL(driver_data)) {
181         profile_list[i++] = VAProfileH263Baseline;
182         profile_list[i++] = VAProfileJPEGBaseline;
183         profile_list[i++] = VAProfileVP8Version0_3;
184     } else if (IS_MFLD(driver_data)) {
185         profile_list[i++] = VAProfileH263Baseline;
186         profile_list[i++] = VAProfileJPEGBaseline;
187     }
188     profile_list[i++] = VAProfileH264ConstrainedBaseline;
189 
190     /* If the assert fails then PSB_MAX_PROFILES needs to be bigger */
191     ASSERT(i <= PSB_MAX_PROFILES);
192     *num_profiles = i;
193     DEBUG_FUNC_EXIT
194     return VA_STATUS_SUCCESS;
195 }
196 
psb_QueryConfigEntrypoints(VADriverContextP ctx,VAProfile profile,VAEntrypoint * entrypoint_list,int * num_entrypoints)197 VAStatus psb_QueryConfigEntrypoints(
198     VADriverContextP ctx,
199     VAProfile profile,
200     VAEntrypoint  *entrypoint_list,    /* out */
201     int *num_entrypoints        /* out */
202 )
203 {
204     DEBUG_FUNC_ENTER
205     INIT_DRIVER_DATA
206     VAStatus vaStatus = VA_STATUS_SUCCESS;
207     int entrypoints = 0;
208     int i;
209 
210     CHECK_INVALID_PARAM(entrypoint_list == NULL);
211     CHECK_INVALID_PARAM((num_entrypoints == NULL) || (profile >= PSB_MAX_PROFILES));
212 
213     for (i = 0; i < PSB_MAX_ENTRYPOINTS; i++) {
214 #ifndef BAYTRAIL
215 #ifdef PSBVIDEO_MRFL_VPP
216         if (profile == VAProfileNone && driver_data->vpp_profile &&
217             i == VAEntrypointVideoProc) {
218                 entrypoints++;
219                 *entrypoint_list++ = i;
220 	} else
221 #endif
222 #endif
223 	if (profile != VAProfileNone && driver_data->profile2Format[profile][i]) {
224                 entrypoints++;
225                 *entrypoint_list++ = i;
226         }
227     }
228 
229     /* If the assert fails then PSB_MAX_ENTRYPOINTS needs to be bigger */
230     ASSERT(entrypoints <= PSB_MAX_ENTRYPOINTS);
231 
232     if (0 == entrypoints) {
233         return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
234     }
235 
236     *num_entrypoints = entrypoints;
237     DEBUG_FUNC_EXIT
238     return VA_STATUS_SUCCESS;
239 }
240 
241 /*
242  * Figure out if we should return VA_STATUS_ERROR_UNSUPPORTED_PROFILE
243  * or VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT
244  */
psb__error_unsupported_profile_entrypoint(psb_driver_data_p driver_data,VAProfile profile,VAEntrypoint __maybe_unused entrypoint)245 static VAStatus psb__error_unsupported_profile_entrypoint(psb_driver_data_p driver_data, VAProfile profile, VAEntrypoint __maybe_unused entrypoint)
246 {
247     /* Does the driver support _any_ entrypoint for this profile? */
248     if (profile < PSB_MAX_PROFILES) {
249         int i;
250 
251         /* Do the parameter check for MFLD and MRFLD */
252         if (profile == VAProfileNone)
253             return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
254 
255         for (i = 0; i < PSB_MAX_ENTRYPOINTS; i++) {
256             if (driver_data->profile2Format[profile][i]) {
257                 /* There is an entrypoint, so the profile is supported */
258                 return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
259             }
260         }
261     }
262     return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
263 }
264 
psb_GetConfigAttributes(VADriverContextP ctx,VAProfile profile,VAEntrypoint entrypoint,VAConfigAttrib * attrib_list,int num_attribs)265 VAStatus psb_GetConfigAttributes(
266     VADriverContextP ctx,
267     VAProfile profile,
268     VAEntrypoint entrypoint,
269     VAConfigAttrib *attrib_list,    /* in/out */
270     int num_attribs
271 )
272 {
273     DEBUG_FUNC_ENTER
274     INIT_DRIVER_DATA
275 
276 #if defined(BAYTRAIL)
277     format_vtable_p format_vtable = driver_data->profile2Format[profile][entrypoint];
278 #elif defined(PSBVIDEO_MRFL_VPP)
279     INIT_FORMAT_VTABLE
280 #else
281     format_vtable_p format_vtable = driver_data->profile2Format[profile][entrypoint];
282 #endif
283     int i;
284     VAStatus vaStatus = VA_STATUS_SUCCESS;
285     if (NULL == format_vtable) {
286         return psb__error_unsupported_profile_entrypoint(driver_data, profile, entrypoint);
287     }
288 
289     CHECK_INVALID_PARAM(attrib_list == NULL);
290     CHECK_INVALID_PARAM(num_attribs <= 0);
291 
292     /* Generic attributes */
293     for (i = 0; i < num_attribs; i++) {
294         switch (attrib_list[i].type) {
295         case VAConfigAttribRTFormat:
296             attrib_list[i].value = VA_RT_FORMAT_YUV420;
297             if (entrypoint == VAEntrypointEncPicture)
298                 attrib_list[i].value |= VA_RT_FORMAT_YUV422;
299             if ((profile == VAProfileJPEGBaseline) && (entrypoint == VAEntrypointVLD))
300                 attrib_list[i].value |= VA_RT_FORMAT_YUV444;
301             break;
302 
303         default:
304             attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
305             break;
306         }
307     }
308     /* format specific attributes */
309     format_vtable->queryConfigAttributes(profile, entrypoint, attrib_list, num_attribs);
310     DEBUG_FUNC_EXIT
311     return VA_STATUS_SUCCESS;
312 }
313 
psb__update_attribute(object_config_p obj_config,VAConfigAttrib * attrib)314 static VAStatus psb__update_attribute(object_config_p obj_config, VAConfigAttrib *attrib)
315 {
316     int i;
317     /* Check existing attributes */
318     for (i = 0; i < obj_config->attrib_count; i++) {
319         if (obj_config->attrib_list[i].type == attrib->type) {
320             /* Update existing attribute */
321             obj_config->attrib_list[i].value = attrib->value;
322             return VA_STATUS_SUCCESS;
323         }
324     }
325     if (obj_config->attrib_count < PSB_MAX_CONFIG_ATTRIBUTES) {
326         i = obj_config->attrib_count;
327         obj_config->attrib_list[i].type = attrib->type;
328         obj_config->attrib_list[i].value = attrib->value;
329         obj_config->attrib_count++;
330         return VA_STATUS_SUCCESS;
331     }
332     return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
333 }
334 
psb__validate_config(object_config_p obj_config)335 static VAStatus psb__validate_config(object_config_p obj_config)
336 {
337     int i;
338     /* Check all attributes */
339     for (i = 0; i < obj_config->attrib_count; i++) {
340         switch (obj_config->attrib_list[i].type) {
341         case VAConfigAttribRTFormat:
342             if (!(obj_config->attrib_list[i].value == VA_RT_FORMAT_YUV420
343                   || (obj_config->attrib_list[i].value == VA_RT_FORMAT_YUV422 &&
344                       obj_config->entrypoint == VAEntrypointEncPicture)
345                   || (obj_config->attrib_list[i].value == (VA_RT_FORMAT_YUV444 | VA_RT_FORMAT_YUV420 )))) {
346                 return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
347             }
348             break;
349 
350         default:
351             /*
352              * Ignore unknown attributes here, it
353              * may be format specific.
354              */
355             break;
356         }
357     }
358     return VA_STATUS_SUCCESS;
359 }
360 
psb_get_active_entrypoint_number(VADriverContextP ctx,unsigned int entrypoint)361 static int psb_get_active_entrypoint_number(
362     VADriverContextP ctx,
363     unsigned int entrypoint)
364 {
365     INIT_DRIVER_DATA;
366     struct drm_lnc_video_getparam_arg arg;
367     int count = 0;
368     int ret;
369 
370     if (VAEntrypointVLD > entrypoint ||
371         entrypoint > VAEntrypointEncPicture) {
372         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s :Invalid entrypoint %d.\n",
373                            __FUNCTION__, entrypoint);
374         return -1;
375     }
376 
377     arg.key = PNW_VIDEO_QUERY_ENTRY;
378     arg.value = (uint64_t)((unsigned long) &count);
379     arg.arg = (uint64_t)((unsigned int)&entrypoint);
380     ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
381                               &arg, sizeof(arg));
382     if (ret) {
383         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s drmCommandWriteRead fails %d.\n",
384                            __FUNCTION__, ret);
385         return -1;
386     }
387 
388     return count;
389 }
390 
psb_CreateConfig(VADriverContextP ctx,VAProfile profile,VAEntrypoint entrypoint,VAConfigAttrib * attrib_list,int num_attribs,VAConfigID * config_id)391 VAStatus psb_CreateConfig(
392     VADriverContextP ctx,
393     VAProfile profile,
394     VAEntrypoint entrypoint,
395     VAConfigAttrib *attrib_list,
396     int num_attribs,
397     VAConfigID *config_id        /* out */
398 )
399 {
400     DEBUG_FUNC_ENTER
401     INIT_DRIVER_DATA
402 #if defined(BAYTRAIL)
403     format_vtable_p format_vtable = driver_data->profile2Format[profile][entrypoint];
404 #elif defined(PSBVIDEO_MRFL_VPP)
405     INIT_FORMAT_VTABLE
406 #else
407     format_vtable_p format_vtable = driver_data->profile2Format[profile][entrypoint];
408 #endif
409     VAStatus vaStatus = VA_STATUS_SUCCESS;
410     int configID;
411     object_config_p obj_config;
412     int i;
413 
414     drv_debug_msg(VIDEO_DEBUG_INIT, "CreateConfig profile:%d, entrypoint:%d, num_attribs:%d.\n",
415         profile, entrypoint, num_attribs);
416     /*echo 8 > /sys/module/pvrsrvkm/parameters/no_ec will disable error concealment*/
417     if ((profile == VAProfileH264ConstrainedBaseline) && (VAEntrypointVLD == entrypoint)) {
418         char ec_disable[2];
419         FILE *ec_fp = fopen("/sys/module/pvrsrvkm/parameters/no_ec", "r");
420         if (ec_fp) {
421             if (fgets(ec_disable, 2, ec_fp) != NULL) {
422                 /* force profile to VAProfileH264High */
423                 if (strcmp(ec_disable, "8") == 0) {
424                     drv_debug_msg(VIDEO_DEBUG_INIT, "disabled error concealment by setting profile to VAProfileH264High\n");
425                     profile = VAProfileH264High;
426                 }
427             }
428             fclose(ec_fp);
429         }
430     }
431 
432     CHECK_INVALID_PARAM(config_id == NULL);
433     CHECK_INVALID_PARAM(num_attribs < 0);
434     CHECK_INVALID_PARAM(attrib_list == NULL);
435 
436     if (NULL == format_vtable) {
437         vaStatus = psb__error_unsupported_profile_entrypoint(driver_data, profile, entrypoint);
438     }
439 
440     CHECK_VASTATUS();
441 
442     if ((IS_MFLD(driver_data)) &&
443         ((VAEntrypointEncPicture == entrypoint)
444 	|| (VAEntrypointEncSlice == entrypoint))) {
445 	int active_slc, active_pic;
446         /* Only allow one encoding entrypoint at the sametime.
447 	 * But if video encoding request comes when process JPEG encoding,
448 	 * it will wait until current JPEG picture encoding finish.
449 	 * Further JPEG encoding should fall back to software path.*/
450 	active_slc = psb_get_active_entrypoint_number(ctx, VAEntrypointEncSlice);
451 	active_pic = psb_get_active_entrypoint_number(ctx, VAEntrypointEncPicture);
452 
453 	if (active_slc > 0) {
454 	    drv_debug_msg(VIDEO_DEBUG_ERROR, "There already is a active video encoding entrypoint."
455 		   "Entrypoint %d isn't available.\n", entrypoint);
456 	    return VA_STATUS_ERROR_HW_BUSY;
457 	}
458 	else if (active_pic > 0 && VAEntrypointEncPicture == entrypoint) {
459 	    drv_debug_msg(VIDEO_DEBUG_ERROR, "There already is a active picture encoding entrypoint."
460 		   "Entrypoint %d isn't available.\n", entrypoint);
461 	    return VA_STATUS_ERROR_HW_BUSY;
462 	}
463     }
464 
465     configID = object_heap_allocate(&driver_data->config_heap);
466     obj_config = CONFIG(configID);
467     CHECK_ALLOCATION(obj_config);
468 
469     MEMSET_OBJECT(obj_config, struct object_config_s);
470 
471     obj_config->profile = profile;
472     obj_config->format_vtable = format_vtable;
473     obj_config->entrypoint = entrypoint;
474     obj_config->attrib_list[0].type = VAConfigAttribRTFormat;
475     obj_config->attrib_list[0].value = VA_RT_FORMAT_YUV420;
476     obj_config->attrib_count = 1;
477 
478     for (i = 0; i < num_attribs; i++) {
479         if (attrib_list[i].type > VAConfigAttribTypeMax)
480             return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
481 
482         vaStatus = psb__update_attribute(obj_config, &(attrib_list[i]));
483         if (VA_STATUS_SUCCESS != vaStatus) {
484             break;
485         }
486     }
487 
488     if (VA_STATUS_SUCCESS == vaStatus) {
489         vaStatus = psb__validate_config(obj_config);
490     }
491 
492     if (VA_STATUS_SUCCESS == vaStatus) {
493         vaStatus = format_vtable->validateConfig(obj_config);
494     }
495 
496     /* Error recovery */
497     if (VA_STATUS_SUCCESS != vaStatus) {
498         object_heap_free(&driver_data->config_heap, (object_base_p) obj_config);
499     } else {
500         *config_id = configID;
501     }
502 
503 #ifdef PSBVIDEO_MSVDX_EC
504     if((getenv("PSB_VIDEO_NOEC") == NULL)
505         && (profile == VAProfileH264ConstrainedBaseline)) {
506         drv_debug_msg(VIDEO_DEBUG_INIT, "profile is VAProfileH264ConstrainedBaseline, error concealment is enabled. \n");
507         driver_data->ec_enabled = 1;
508     } else {
509         driver_data->ec_enabled = 0;
510     }
511 
512     if (profile == VAProfileVP8Version0_3 ||
513 	profile == VAProfileH264Baseline ||
514 	profile == VAProfileH264Main ||
515 	profile == VAProfileH264High ||
516 	profile == VAProfileH264ConstrainedBaseline)
517 		driver_data->ec_enabled = 1;
518 
519     if (!IS_MRFL(driver_data)) {
520         if (profile == VAProfileMPEG4Simple ||
521             profile == VAProfileMPEG4AdvancedSimple ||
522             profile == VAProfileMPEG4Main)
523                 driver_data->ec_enabled = 1;
524     }
525 
526 #else
527     driver_data->ec_enabled = 0;
528 #endif
529 
530     DEBUG_FUNC_EXIT
531     return vaStatus;
532 }
533 
psb_DestroyConfig(VADriverContextP ctx,VAConfigID config_id)534 VAStatus psb_DestroyConfig(
535     VADriverContextP ctx,
536     VAConfigID config_id
537 )
538 {
539     DEBUG_FUNC_ENTER
540     INIT_DRIVER_DATA
541     VAStatus vaStatus = VA_STATUS_SUCCESS;
542     object_config_p obj_config;
543 
544     obj_config = CONFIG(config_id);
545     CHECK_CONFIG(obj_config);
546 
547     object_heap_free(&driver_data->config_heap, (object_base_p) obj_config);
548     DEBUG_FUNC_EXIT
549     return vaStatus;
550 }
551 
psb_QueryConfigAttributes(VADriverContextP ctx,VAConfigID config_id,VAProfile * profile,VAEntrypoint * entrypoint,VAConfigAttrib * attrib_list,int * num_attribs)552 VAStatus psb_QueryConfigAttributes(
553     VADriverContextP ctx,
554     VAConfigID config_id,
555     VAProfile *profile,        /* out */
556     VAEntrypoint *entrypoint,     /* out */
557     VAConfigAttrib *attrib_list,    /* out */
558     int *num_attribs        /* out */
559 )
560 {
561     DEBUG_FUNC_ENTER
562     INIT_DRIVER_DATA
563     VAStatus vaStatus = VA_STATUS_SUCCESS;
564     object_config_p obj_config;
565     int i;
566 
567     CHECK_INVALID_PARAM(profile == NULL);
568     CHECK_INVALID_PARAM(entrypoint == NULL);
569     CHECK_INVALID_PARAM(attrib_list == NULL);
570     CHECK_INVALID_PARAM(num_attribs == NULL);
571 
572     obj_config = CONFIG(config_id);
573     CHECK_CONFIG(obj_config);
574 
575     *profile = obj_config->profile;
576     *entrypoint = obj_config->entrypoint;
577     *num_attribs =  obj_config->attrib_count;
578     for (i = 0; i < obj_config->attrib_count; i++) {
579         attrib_list[i] = obj_config->attrib_list[i];
580     }
581 
582     DEBUG_FUNC_EXIT
583     return vaStatus;
584 }
585 
psb__destroy_surface(psb_driver_data_p driver_data,object_surface_p obj_surface)586 void psb__destroy_surface(psb_driver_data_p driver_data, object_surface_p obj_surface)
587 {
588     if (NULL != obj_surface) {
589         /* delete subpicture association */
590         psb_SurfaceDeassociateSubpict(driver_data, obj_surface);
591 
592 	obj_surface->is_ref_surface = 0;
593 
594 	psb_surface_sync(obj_surface->psb_surface);
595         psb_surface_destroy(obj_surface->psb_surface);
596 
597         if (obj_surface->out_loop_surface) {
598             psb_surface_destroy(obj_surface->out_loop_surface);
599         }
600 
601         if (obj_surface->scaling_surface) {
602             psb_surface_destroy(obj_surface->scaling_surface);
603         }
604 
605         free(obj_surface->psb_surface);
606         object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
607     }
608 }
609 
psb__checkSurfaceDimensions(psb_driver_data_p driver_data,int width,int height)610 VAStatus psb__checkSurfaceDimensions(psb_driver_data_p driver_data, int width, int height)
611 {
612     if (driver_data->video_sd_disabled) {
613         return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
614     }
615     if ((width <= 0) || (width * height > 5120 * 5120) || (height <= 0)) {
616         return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
617     }
618     if (driver_data->video_hd_disabled) {
619         if ((width > 1024) || (height > 576)) {
620             return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
621         }
622     }
623 
624     return VA_STATUS_SUCCESS;
625 }
626 
psb_GetSurfaceAttributes(VADriverContextP __maybe_unused ctx,VAConfigID __maybe_unused config,VASurfaceAttrib * attrib_list,unsigned int num_attribs)627 VAStatus psb_GetSurfaceAttributes(
628         VADriverContextP    __maybe_unused ctx,
629         VAConfigID __maybe_unused config,
630         VASurfaceAttrib *attrib_list,
631         unsigned int num_attribs
632         )
633 {
634     DEBUG_FUNC_ENTER
635 
636     uint32_t i;
637     VAStatus vaStatus = VA_STATUS_SUCCESS;
638 
639     CHECK_INVALID_PARAM(attrib_list == NULL);
640     CHECK_INVALID_PARAM(num_attribs <= 0);
641 
642     /* Generic attributes */
643     for (i = 0; i < num_attribs; i++) {
644         switch (attrib_list[i].type) {
645         case VASurfaceAttribMemoryType:
646             attrib_list[i].flags = VA_SURFACE_ATTRIB_SETTABLE | VA_SURFACE_ATTRIB_GETTABLE;
647             attrib_list[i].value.type = VAGenericValueTypeInteger;
648             attrib_list[i].value.value.i =
649                 VA_SURFACE_ATTRIB_MEM_TYPE_VA |
650                 VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR |
651                 VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
652                 VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC |
653                 VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION;
654             break;
655 
656         case VASurfaceAttribExternalBufferDescriptor:
657             attrib_list[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
658             attrib_list[i].value.type = VAGenericValueTypePointer;
659             break;
660 
661         default:
662             attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
663             break;
664         }
665     }
666 
667     DEBUG_FUNC_EXIT
668     return VA_STATUS_SUCCESS;
669 
670 }
671 
psb_CreateSurfaces(VADriverContextP __maybe_unused ctx,int __maybe_unused width,int __maybe_unused height,int __maybe_unused format,int __maybe_unused num_surfaces,VASurfaceID __maybe_unused * surface_list)672 VAStatus psb_CreateSurfaces(
673         VADriverContextP __maybe_unused ctx,
674         int __maybe_unused width,
675         int __maybe_unused height,
676         int __maybe_unused format,
677         int __maybe_unused num_surfaces,
678         VASurfaceID __maybe_unused * surface_list        /* out */
679 )
680 {
681     return VA_STATUS_ERROR_UNIMPLEMENTED;
682 }
683 
psb_CreateSurfaces2(VADriverContextP ctx,unsigned int format,unsigned int width,unsigned int height,VASurfaceID * surface_list,unsigned int num_surfaces,VASurfaceAttrib * attrib_list,unsigned int num_attribs)684 VAStatus psb_CreateSurfaces2(
685     VADriverContextP ctx,
686     unsigned int format,
687     unsigned int width,
688     unsigned int height,
689     VASurfaceID *surface_list,        /* out */
690     unsigned int num_surfaces,
691     VASurfaceAttrib *attrib_list,
692     unsigned int num_attribs
693 )
694 {
695     DEBUG_FUNC_ENTER
696     INIT_DRIVER_DATA
697     VAStatus vaStatus = VA_STATUS_SUCCESS;
698     unsigned int i;
699     int height_origin, buffer_stride = 0;
700     driver_data->protected = (VA_RT_FORMAT_PROTECTED & format);
701     unsigned long fourcc;
702     unsigned int flags = 0;
703     int memory_type = -1;
704     VASurfaceAttribExternalBuffers  *pExternalBufDesc = NULL;
705     PsbSurfaceAttributeTPI attribute_tpi;
706 
707     CHECK_INVALID_PARAM(num_surfaces <= 0);
708     CHECK_SURFACE(surface_list);
709 
710     if ((attrib_list != NULL) && (num_attribs > 0)) {
711         for (i = 0; i < num_attribs; i++, attrib_list++) {
712             if (!attrib_list)
713                 return VA_STATUS_ERROR_INVALID_PARAMETER;
714             switch (attrib_list->type) {
715             case VASurfaceAttribExternalBufferDescriptor:
716                 {
717                     pExternalBufDesc = (VASurfaceAttribExternalBuffers *)attrib_list->value.value.p;
718                     if (pExternalBufDesc == NULL) {
719                         drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid VASurfaceAttribExternalBuffers.\n");
720                         return VA_STATUS_ERROR_INVALID_PARAMETER;
721                     }
722                     attribute_tpi.type = memory_type;
723                     attribute_tpi.buffers = malloc(sizeof(long) * pExternalBufDesc->num_buffers);
724                     attribute_tpi.width = pExternalBufDesc->width;
725                     attribute_tpi.height = pExternalBufDesc->height;
726                     attribute_tpi.count = pExternalBufDesc->num_buffers;
727                     memcpy((void*)attribute_tpi.buffers, (void*)pExternalBufDesc->buffers,
728                             sizeof(pExternalBufDesc->buffers[0]) *
729                             pExternalBufDesc->num_buffers);
730                     attribute_tpi.pixel_format = pExternalBufDesc->pixel_format;
731                     attribute_tpi.size = pExternalBufDesc->data_size;
732                     attribute_tpi.luma_stride = pExternalBufDesc->pitches[0];
733                     attribute_tpi.chroma_u_stride = pExternalBufDesc->pitches[1];
734                     attribute_tpi.chroma_v_stride = pExternalBufDesc->pitches[2];
735                     attribute_tpi.luma_offset = pExternalBufDesc->offsets[0];
736                     attribute_tpi.chroma_u_offset = pExternalBufDesc->offsets[1];
737                     attribute_tpi.chroma_v_offset = pExternalBufDesc->offsets[2];
738                     attribute_tpi.reserved[0] = (unsigned long) pExternalBufDesc->private_data;
739                     if (pExternalBufDesc->flags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING)
740                         attribute_tpi.tiling = 1;
741                     else
742                         attribute_tpi.tiling = 0;
743                 }
744                 break;
745             case VASurfaceAttribMemoryType:
746                 {
747                     switch (attrib_list->value.value.i) {
748                         case VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR:
749                             memory_type = VAExternalMemoryUserPointer;
750                             break;
751                         case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM:
752                             memory_type = VAExternalMemoryKernelDRMBufffer;
753                             break;
754                         case VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC:
755                             memory_type = VAExternalMemoryAndroidGrallocBuffer;
756                             break;
757                         case VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION:
758                             memory_type = VAExternalMemoryIONSharedFD;
759                             break;
760                         case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
761                             memory_type = VAExternalMemoryNULL;
762                             break;
763                         default:
764                             drv_debug_msg(VIDEO_DEBUG_ERROR, "Unsupported memory type.\n");
765                             return VA_STATUS_ERROR_INVALID_PARAMETER;
766 
767                     }
768                 }
769                 break;
770             default:
771                 drv_debug_msg(VIDEO_DEBUG_ERROR, "Unsupported attribute.\n");
772                 return VA_STATUS_ERROR_INVALID_PARAMETER;
773             }
774         }
775     }
776 
777     if ((memory_type == -1 && pExternalBufDesc != NULL) ||
778             (memory_type != -1 && pExternalBufDesc == NULL)) {
779         return VA_STATUS_ERROR_INVALID_PARAMETER;
780     }
781     else if(memory_type !=-1 && pExternalBufDesc != NULL) {
782         attribute_tpi.type = memory_type;
783         vaStatus = psb_CreateSurfacesWithAttribute(ctx, width, height, format, num_surfaces, surface_list, (VASurfaceAttributeTPI *)&attribute_tpi);
784         pExternalBufDesc->private_data = (void *)(attribute_tpi.reserved[1]);
785         if (attribute_tpi.buffers) free(attribute_tpi.buffers);
786         return vaStatus;
787     }
788 
789     format = format & (~VA_RT_FORMAT_PROTECTED);
790 
791     /* We only support one format */
792     if ((VA_RT_FORMAT_YUV420 != format)
793         && (VA_RT_FORMAT_YUV422 != format)
794         && (VA_RT_FORMAT_YUV444 != format)) {
795         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
796         DEBUG_FAILURE;
797         return vaStatus;
798     }
799 
800     vaStatus = psb__checkSurfaceDimensions(driver_data, width, height);
801     CHECK_VASTATUS();
802 
803     /* Adjust height to be a multiple of 32 (height of macroblock in interlaced mode) */
804     height_origin = height;
805     height = (height + 0x1f) & ~0x1f;
806 
807 
808     for (i = 0; i < num_surfaces; i++) {
809         int surfaceID;
810         object_surface_p obj_surface;
811         psb_surface_p psb_surface;
812 
813         surfaceID = object_heap_allocate(&driver_data->surface_heap);
814         obj_surface = SURFACE(surfaceID);
815         if (NULL == obj_surface) {
816             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
817             DEBUG_FAILURE;
818             break;
819         }
820         MEMSET_OBJECT(obj_surface, struct object_surface_s);
821 
822         obj_surface->surface_id = surfaceID;
823         surface_list[i] = surfaceID;
824         obj_surface->context_id = -1;
825         obj_surface->width = width;
826         obj_surface->height = height;
827         obj_surface->width_r = width;
828         obj_surface->height_r = height;
829         obj_surface->height_origin = height_origin;
830         obj_surface->share_info = NULL;
831 
832         psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s));
833         if (NULL == psb_surface) {
834             object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
835             obj_surface->surface_id = VA_INVALID_SURFACE;
836             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
837             DEBUG_FAILURE;
838             break;
839         }
840 
841         switch (format) {
842         case VA_RT_FORMAT_YUV444:
843             fourcc = VA_FOURCC_YV32; /* allocate 4 planar */
844             break;
845         case VA_RT_FORMAT_YUV422:
846             fourcc = VA_FOURCC_YV16;
847             break;
848         case VA_RT_FORMAT_YUV420:
849         default:
850             fourcc = VA_FOURCC_NV12;
851             break;
852         }
853 
854         flags |= driver_data->protected ? IS_PROTECTED : 0;
855         vaStatus = psb_surface_create(driver_data, width, height, fourcc,
856                                       flags, psb_surface);
857 
858         if (VA_STATUS_SUCCESS != vaStatus) {
859             free(psb_surface);
860             object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
861             obj_surface->surface_id = VA_INVALID_SURFACE;
862             DEBUG_FAILURE;
863             break;
864         }
865         buffer_stride = psb_surface->stride;
866         /* by default, surface fourcc is NV12 */
867         psb_surface->extra_info[4] = fourcc;
868         obj_surface->psb_surface = psb_surface;
869     }
870 
871     /* Error recovery */
872     if (VA_STATUS_SUCCESS != vaStatus) {
873         /* surface_list[i-1] was the last successful allocation */
874         for (; i--;) {
875             object_surface_p obj_surface = SURFACE(surface_list[i]);
876             psb__destroy_surface(driver_data, obj_surface);
877             surface_list[i] = VA_INVALID_SURFACE;
878         }
879         drv_debug_msg(VIDEO_DEBUG_ERROR, "CreateSurfaces failed\n");
880         return vaStatus;
881     }
882     DEBUG_FUNC_EXIT
883     return vaStatus;
884 }
885 
psb_DestroySurfaces(VADriverContextP ctx,VASurfaceID * surface_list,int num_surfaces)886 VAStatus psb_DestroySurfaces(
887     VADriverContextP ctx,
888     VASurfaceID *surface_list,
889     int num_surfaces
890 )
891 {
892     INIT_DRIVER_DATA
893     int i;
894     VAStatus vaStatus = VA_STATUS_SUCCESS;
895 
896     if (num_surfaces <= 0) {
897         return VA_STATUS_ERROR_INVALID_PARAMETER;
898     }
899 
900     CHECK_SURFACE(surface_list);
901 
902 #if 0
903     /* Free PVR2D buffer wrapped from the surfaces */
904     psb_free_surface_pvr2dbuf(driver_data);
905 #endif
906 
907     /* Make validation happy */
908     for (i = 0; i < num_surfaces; i++) {
909         object_surface_p obj_surface = SURFACE(surface_list[i]);
910         if (obj_surface == NULL) {
911             return VA_STATUS_ERROR_INVALID_SURFACE;
912         }
913         if (obj_surface->derived_imgcnt > 0) {
914             drv_debug_msg(VIDEO_DEBUG_ERROR, "Some surface is deriving by images\n");
915             return VA_STATUS_ERROR_OPERATION_FAILED;
916         }
917     }
918 
919     for (i = 0; i < num_surfaces; i++) {
920         object_surface_p obj_surface = SURFACE(surface_list[i]);
921         if (obj_surface == NULL)
922             return VA_STATUS_ERROR_INVALID_SURFACE;
923 
924         if (driver_data->cur_displaying_surface == surface_list[i]) {
925             /* Surface is being displaying. Need to stop overlay here */
926             psb_coverlay_stop(ctx);
927         }
928         drv_debug_msg(VIDEO_DEBUG_INIT, "%s : obj_surface->surface_id = 0x%x\n",__FUNCTION__, obj_surface->surface_id);
929         if (obj_surface->share_info) {
930             psb_DestroySurfaceGralloc(obj_surface);
931         }
932         psb__destroy_surface(driver_data, obj_surface);
933         surface_list[i] = VA_INVALID_SURFACE;
934     }
935 
936     DEBUG_FUNC_EXIT
937     return VA_STATUS_SUCCESS;
938 }
939 
psb_new_context(psb_driver_data_p driver_data,uint64_t ctx_type)940 int psb_new_context(psb_driver_data_p driver_data, uint64_t ctx_type)
941 {
942     struct drm_lnc_video_getparam_arg arg;
943     int ret = 0;
944 
945     arg.key = IMG_VIDEO_NEW_CONTEXT;
946     arg.value = (uint64_t)((unsigned long) & ctx_type);
947     ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
948                               &arg, sizeof(arg));
949     if (ret != 0)
950         drv_debug_msg(VIDEO_DEBUG_ERROR, "Set context %d failed\n", ctx_type);
951 
952     return ret;
953 }
954 
955 #ifdef PSBVIDEO_MSVDX_DEC_TILING
psb_update_context(psb_driver_data_p driver_data,unsigned long ctx_type)956 int psb_update_context(psb_driver_data_p driver_data, unsigned long ctx_type)
957 {
958     struct drm_lnc_video_getparam_arg arg;
959     int ret = 0;
960 
961     arg.key = IMG_VIDEO_UPDATE_CONTEXT;
962     arg.value = (uint64_t)((unsigned long) & ctx_type);
963     ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
964                               &arg, sizeof(arg));
965     if (ret != 0)
966         drv_debug_msg(VIDEO_DEBUG_ERROR, "Update context %d failed\n", ctx_type);
967 
968     return ret;
969 }
970 #endif
971 
psb_rm_context(psb_driver_data_p driver_data)972 int psb_rm_context(psb_driver_data_p driver_data)
973 {
974     struct drm_lnc_video_getparam_arg arg;
975     int tmp;
976     int ret = 0;
977 
978     arg.key = IMG_VIDEO_RM_CONTEXT;
979     arg.value = (uint64_t)((unsigned long) & tmp); /* value is ignored */
980     ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
981                               &arg, sizeof(arg));
982     if (ret != 0)
983         drv_debug_msg(VIDEO_DEBUG_ERROR, "Remove context failed\n");
984 
985     return ret;
986 }
987 
988 #ifdef PSBVIDEO_MSVDX_DEC_TILING
psb__tile_stride_log2_256(int w)989 unsigned long psb__tile_stride_log2_256(int w)
990 {
991     int stride_mode = 0;
992 
993     if (512 >= w)
994         stride_mode = 1;
995     else if (1024 >= w)
996         stride_mode = 2;
997     else if (2048 >= w)
998         stride_mode = 3;
999     else if (4096 >= w)
1000         stride_mode = 4;
1001 
1002     return stride_mode;
1003 }
1004 
psb__tile_stride_log2_512(int w)1005 unsigned long psb__tile_stride_log2_512(int w)
1006 {
1007     int stride_mode = 0;
1008 
1009     if (512 >= w)
1010         stride_mode = 0;
1011     else if (1024 >= w)
1012         stride_mode = 1;
1013     else if (2048 >= w)
1014         stride_mode = 2;
1015     else if (4096 >= w)
1016         stride_mode = 3;
1017 
1018     return stride_mode;
1019 }
1020 #endif
1021 
psb_CreateContext(VADriverContextP ctx,VAConfigID config_id,int picture_width,int picture_height,int flag,VASurfaceID * render_targets,int num_render_targets,VAContextID * context)1022 VAStatus psb_CreateContext(
1023     VADriverContextP ctx,
1024     VAConfigID config_id,
1025     int picture_width,
1026     int picture_height,
1027     int flag,
1028     VASurfaceID *render_targets,
1029     int num_render_targets,
1030     VAContextID *context        /* out */
1031 )
1032 {
1033     DEBUG_FUNC_ENTER
1034     INIT_DRIVER_DATA
1035     VAStatus vaStatus = VA_STATUS_SUCCESS;
1036     object_config_p obj_config;
1037     int cmdbuf_num, encode = 0, proc = 0;
1038     int i;
1039     drv_debug_msg(VIDEO_DEBUG_INIT, "CreateContext config_id:%d, pic_w:%d, pic_h:%d, flag:%d, num_render_targets:%d.\n",
1040         config_id, picture_width, picture_height, flag, num_render_targets);
1041 
1042     CHECK_INVALID_PARAM(num_render_targets <= 0);
1043 
1044     CHECK_SURFACE(render_targets);
1045     CHECK_CONTEXT(context);
1046 
1047     vaStatus = psb__checkSurfaceDimensions(driver_data, picture_width, picture_height);
1048     CHECK_VASTATUS();
1049 
1050     obj_config = CONFIG(config_id);
1051     CHECK_CONFIG(obj_config);
1052 
1053     int contextID = object_heap_allocate(&driver_data->context_heap);
1054     object_context_p obj_context = CONTEXT(contextID);
1055     CHECK_ALLOCATION(obj_context);
1056 
1057     *context = contextID;
1058 
1059     MEMSET_OBJECT(obj_context, struct object_context_s);
1060 
1061     obj_context->driver_data = driver_data;
1062     obj_context->current_render_target = NULL;
1063     obj_context->ec_target = NULL;
1064     obj_context->ec_candidate = NULL;
1065     obj_context->is_oold = driver_data->is_oold;
1066     obj_context->context_id = contextID;
1067     obj_context->config_id = config_id;
1068     obj_context->picture_width = picture_width;
1069     obj_context->picture_height = picture_height;
1070     obj_context->num_render_targets = num_render_targets;
1071     obj_context->msvdx_scaling = 0;
1072 #ifdef SLICE_HEADER_PARSING
1073     obj_context->msvdx_frame_end = 0;
1074     for (i = 0; i < obj_config->attrib_count; i++) {
1075         if ((obj_config->attrib_list[i].type == VAConfigAttribDecSliceMode) &&
1076             (obj_config->attrib_list[i].value == VA_DEC_SLICE_MODE_SUBSAMPLE)) {
1077             obj_context->modular_drm = 1;
1078             break;
1079         }
1080     }
1081 #endif
1082     obj_context->scaling_width = 0;
1083     obj_context->scaling_height = 0;
1084     obj_context->render_targets = (VASurfaceID *) calloc(1, num_render_targets * sizeof(VASurfaceID));
1085     if (obj_context->render_targets == NULL) {
1086         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1087         DEBUG_FAILURE;
1088 
1089         object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1090 
1091         return vaStatus;
1092     }
1093 
1094     /* allocate buffer points for vaRenderPicture */
1095     obj_context->num_buffers = 10;
1096     obj_context->buffer_list = (object_buffer_p *) calloc(1, sizeof(object_buffer_p) * obj_context->num_buffers);
1097     if (obj_context->buffer_list == NULL) {
1098         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1099         DEBUG_FAILURE;
1100 
1101         free(obj_context->render_targets);
1102         object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1103 
1104         return vaStatus;
1105     }
1106 
1107     memset(obj_context->buffers_unused, 0, sizeof(obj_context->buffers_unused));
1108     memset(obj_context->buffers_unused_count, 0, sizeof(obj_context->buffers_unused_count));
1109     memset(obj_context->buffers_unused_tail, 0, sizeof(obj_context->buffers_unused_tail));
1110     memset(obj_context->buffers_active, 0, sizeof(obj_context->buffers_active));
1111 
1112     if (obj_config->entrypoint == VAEntrypointEncSlice
1113         || obj_config->entrypoint == VAEntrypointEncPicture) {
1114         encode = 1;
1115     }
1116 #ifdef PSBVIDEO_MRFL_VPP
1117     if (obj_config->entrypoint == VAEntrypointVideoProc)
1118         proc = 1;
1119 
1120     //todo: fixme
1121     if (obj_config->entrypoint == VAEntrypointEncSlice && obj_config->profile == VAProfileVP8Version0_3){
1122             proc = 1;
1123             encode = 0;
1124     }
1125 #endif
1126 
1127     if (encode)
1128         cmdbuf_num = LNC_MAX_CMDBUFS_ENCODE;
1129     else if (proc)
1130         cmdbuf_num = VSP_MAX_CMDBUFS;
1131     else
1132         cmdbuf_num = PSB_MAX_CMDBUFS;
1133 
1134     for (i = 0; i < num_render_targets; i++) {
1135         object_surface_p obj_surface = SURFACE(render_targets[i]);
1136         psb_surface_p psb_surface;
1137 
1138         if (NULL == obj_surface) {
1139             vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
1140             DEBUG_FAILURE;
1141             break;
1142         }
1143 
1144         if (!driver_data->protected && obj_surface->share_info)
1145             obj_surface->share_info->force_output_method = 0;
1146 
1147         psb_surface = obj_surface->psb_surface;
1148 
1149         /* Clear format specific surface info */
1150         obj_context->render_targets[i] = render_targets[i];
1151         obj_surface->context_id = contextID; /* Claim ownership of surface */
1152 #ifdef PSBVIDEO_MSVDX_DEC_TILING
1153         if (GET_SURFACE_INFO_tiling(psb_surface))
1154 #ifdef BAYTRAIL
1155             obj_context->msvdx_tile = psb__tile_stride_log2_512(obj_surface->width);
1156 #else
1157             if (obj_config->entrypoint == VAEntrypointVideoProc && obj_config->profile == VAProfileNone)
1158                 // It's for two pass rotation case
1159                 // Need the source surface width for tile stride setting
1160                 obj_context->msvdx_tile = psb__tile_stride_log2_256(obj_context->picture_width);
1161             else
1162                 obj_context->msvdx_tile = psb__tile_stride_log2_256(obj_surface->width);
1163 #endif
1164         else {
1165             ;
1166         }
1167 #endif
1168 #if 0
1169         /* for decode, move the surface into |TT */
1170         if ((encode == 0) && /* decode */
1171             ((psb_surface->buf.pl_flags & DRM_PSB_FLAG_MEM_RAR) == 0)) /* surface not in RAR */
1172             psb_buffer_setstatus(&obj_surface->psb_surface->buf,
1173                                  WSBM_PL_FLAG_TT | WSBM_PL_FLAG_SHARED, DRM_PSB_FLAG_MEM_MMU);
1174 #endif
1175     }
1176 
1177     obj_context->va_flags = flag;
1178     obj_context->format_vtable = obj_config->format_vtable;
1179     obj_context->format_data = NULL;
1180 
1181     if (VA_STATUS_SUCCESS == vaStatus) {
1182         vaStatus = obj_context->format_vtable->createContext(obj_context, obj_config);
1183     }
1184 
1185     /* Error recovery */
1186     if (VA_STATUS_SUCCESS != vaStatus) {
1187         obj_context->context_id = -1;
1188         obj_context->config_id = -1;
1189         obj_context->picture_width = 0;
1190         obj_context->picture_height = 0;
1191         free(obj_context->render_targets);
1192         free(obj_context->buffer_list);
1193         obj_context->num_buffers = 0;
1194         obj_context->render_targets = NULL;
1195         obj_context->num_render_targets = 0;
1196         obj_context->va_flags = 0;
1197         object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1198 
1199         return vaStatus;
1200     }
1201 
1202     /* initialize cmdbuf */
1203     for (i = 0; i < PNW_MAX_CMDBUFS_ENCODE; i++) {
1204         obj_context->pnw_cmdbuf_list[i] = NULL;
1205     }
1206 
1207 #ifdef PSBVIDEO_MRFL
1208     for (i = 0; i < TNG_MAX_CMDBUFS_ENCODE; i++) {
1209         obj_context->tng_cmdbuf_list[i] = NULL;
1210     }
1211 #endif
1212 
1213 #ifdef PSBVIDEO_MRFL_VPP
1214     for (i = 0; i < VSP_MAX_CMDBUFS; i++) {
1215         obj_context->vsp_cmdbuf_list[i] = NULL;
1216     }
1217 #endif
1218 
1219     for (i = 0; i < PSB_MAX_CMDBUFS; i++) {
1220         obj_context->cmdbuf_list[i] = NULL;
1221     }
1222 
1223     for (i = 0; i < cmdbuf_num; i++) {
1224         void  *cmdbuf = NULL;
1225 #ifndef BAYTRAIL
1226         if (encode) { /* Topaz encode context */
1227 #ifdef PSBVIDEO_MRFL
1228             if (IS_MRFL(obj_context->driver_data))
1229                 cmdbuf = calloc(1, sizeof(struct tng_cmdbuf_s));
1230 #endif
1231 #ifdef PSBVIDEO_MFLD
1232             if (IS_MFLD(obj_context->driver_data))
1233                 cmdbuf = calloc(1, sizeof(struct pnw_cmdbuf_s));
1234 #endif
1235         } else if (proc) { /* VSP VPP context */
1236             /* VED two pass rotation under VPP API */
1237             if (driver_data->ved_vpp)
1238                 cmdbuf =  calloc(1, sizeof(struct psb_cmdbuf_s));
1239 #ifdef PSBVIDEO_MRFL_VPP
1240             else if (IS_MRFL(obj_context->driver_data))
1241                 cmdbuf = calloc(1, sizeof(struct vsp_cmdbuf_s));
1242 #endif
1243         } else /* MSVDX decode context */
1244 #endif
1245             cmdbuf =  calloc(1, sizeof(struct psb_cmdbuf_s));
1246 
1247         if (NULL == cmdbuf) {
1248             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1249             DEBUG_FAILURE;
1250             break;
1251         }
1252 
1253 #ifndef BAYTRAIL
1254         if (encode) { /* Topaz encode context */
1255 
1256 #ifdef PSBVIDEO_MRFL
1257             if (IS_MRFL(obj_context->driver_data))
1258                 vaStatus = tng_cmdbuf_create(obj_context, driver_data, (tng_cmdbuf_p)cmdbuf);
1259 #endif
1260 #ifdef PSBVIDEO_MFLD
1261             if (IS_MFLD(obj_context->driver_data))
1262                 vaStatus = pnw_cmdbuf_create(obj_context, driver_data, (pnw_cmdbuf_p)cmdbuf);
1263 #endif
1264         } else if (proc) { /* VSP VPP context */
1265             if (driver_data->ved_vpp)
1266                 vaStatus = psb_cmdbuf_create(obj_context, driver_data, (psb_cmdbuf_p)cmdbuf);
1267 #ifdef PSBVIDEO_MRFL_VPP
1268             else if (IS_MRFL(obj_context->driver_data))
1269                 vaStatus = vsp_cmdbuf_create(obj_context, driver_data, (vsp_cmdbuf_p)cmdbuf);
1270 #endif
1271         } else /* MSVDX decode context */
1272 #endif
1273             vaStatus = psb_cmdbuf_create(obj_context, driver_data, (psb_cmdbuf_p)cmdbuf);
1274 
1275         if (VA_STATUS_SUCCESS != vaStatus) {
1276             free(cmdbuf);
1277             DEBUG_FAILURE;
1278             break;
1279         }
1280 
1281 #ifndef BAYTRAIL
1282         if (encode) { /* Topaz encode context */
1283             if (i >= LNC_MAX_CMDBUFS_ENCODE) {
1284                 free(cmdbuf);
1285                 DEBUG_FAILURE;
1286                 break;
1287             }
1288 
1289 #ifdef PSBVIDEO_MRFL
1290             if (IS_MRFL(obj_context->driver_data))
1291                 obj_context->tng_cmdbuf_list[i] = (tng_cmdbuf_p)cmdbuf;
1292 #endif
1293 #ifdef PSBVIDEO_MFLD
1294             if (IS_MFLD(obj_context->driver_data))
1295                 obj_context->pnw_cmdbuf_list[i] = (pnw_cmdbuf_p)cmdbuf;
1296 #endif
1297         } else if (proc) { /* VSP VPP context */
1298             if (driver_data->ved_vpp)
1299                 obj_context->cmdbuf_list[i] = (psb_cmdbuf_p)cmdbuf;
1300 #ifdef PSBVIDEO_MRFL_VPP
1301             else if (IS_MRFL(obj_context->driver_data))
1302                 obj_context->vsp_cmdbuf_list[i] = (vsp_cmdbuf_p)cmdbuf;
1303 #endif
1304         } else /* MSVDX decode context */
1305 #endif
1306             obj_context->cmdbuf_list[i] = (psb_cmdbuf_p)cmdbuf;
1307     }
1308 
1309     obj_context->cmdbuf_current = -1;
1310     obj_context->cmdbuf = NULL;
1311     obj_context->pnw_cmdbuf = NULL;
1312     obj_context->tng_cmdbuf = NULL;
1313 #ifdef PSBVIDEO_MRFL_VPP
1314     obj_context->vsp_cmdbuf = NULL;
1315 #endif
1316     obj_context->frame_count = 0;
1317     obj_context->slice_count = 0;
1318     obj_context->msvdx_context = ((driver_data->msvdx_context_base & 0xff0000) >> 16) |
1319                                  ((contextID & 0xff000000) >> 16);
1320 #ifdef ANDROID
1321     obj_context->msvdx_context = ((driver_data->drm_fd & 0xf) << 4) |
1322                                  ((unsigned int)gettid() & 0xf);
1323 #endif
1324     obj_context->profile = obj_config->profile;
1325     obj_context->entry_point = obj_config->entrypoint;
1326 
1327     /* Error recovery */
1328     if (VA_STATUS_SUCCESS != vaStatus) {
1329         if (cmdbuf_num > LNC_MAX_CMDBUFS_ENCODE)
1330             cmdbuf_num = LNC_MAX_CMDBUFS_ENCODE;
1331         for (i = 0; i < cmdbuf_num; i++) {
1332 #ifndef BAYTRAIL
1333             if (obj_context->pnw_cmdbuf_list[i]) {
1334                 pnw_cmdbuf_destroy(obj_context->pnw_cmdbuf_list[i]);
1335                 free(obj_context->pnw_cmdbuf_list[i]);
1336                 obj_context->pnw_cmdbuf_list[i] = NULL;
1337             }
1338 #endif
1339 #ifdef PSBVIDEO_MRFL
1340             if (obj_context->tng_cmdbuf_list[i]) {
1341                 tng_cmdbuf_destroy(obj_context->tng_cmdbuf_list[i]);
1342                 free(obj_context->tng_cmdbuf_list[i]);
1343                 obj_context->tng_cmdbuf_list[i] = NULL;
1344             }
1345 #endif
1346             if (obj_context->cmdbuf_list[i]) {
1347                 psb_cmdbuf_destroy(obj_context->cmdbuf_list[i]);
1348                 free(obj_context->cmdbuf_list[i]);
1349                 obj_context->cmdbuf_list[i] = NULL;
1350             }
1351 #ifdef PSBVIDEO_MRFL_VPP
1352             if (obj_context->vsp_cmdbuf_list[i]) {
1353                 vsp_cmdbuf_destroy(obj_context->vsp_cmdbuf_list[i]);
1354                 free(obj_context->vsp_cmdbuf_list[i]);
1355                 obj_context->vsp_cmdbuf_list[i] = NULL;
1356             }
1357 #endif
1358         }
1359 
1360         obj_context->cmdbuf = NULL;
1361 #ifdef PSBVIDEO_MRFL_VPP
1362         obj_context->vsp_cmdbuf = NULL;
1363 #endif
1364 
1365         obj_context->context_id = -1;
1366         obj_context->config_id = -1;
1367         obj_context->picture_width = 0;
1368         obj_context->picture_height = 0;
1369         free(obj_context->render_targets);
1370         free(obj_context->buffer_list);
1371         obj_context->num_buffers = 0;
1372         obj_context->render_targets = NULL;
1373         obj_context->num_render_targets = 0;
1374         obj_context->va_flags = 0;
1375         object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1376     }
1377     obj_context->ctp_type = (((obj_config->profile << 8) |
1378                              obj_config->entrypoint | driver_data->protected) & 0xffff);
1379 
1380     /* VSP's PM rely on VPP ctx, so ved vpp use diferent profile/level for ctx */
1381     if (driver_data->ved_vpp)
1382         obj_context->ctp_type = (((obj_config->profile << 8) |
1383                              VAEntrypointVLD | driver_data->protected) & 0xffff);
1384 
1385     if (!encode) {
1386         obj_context->ctp_type |= ((obj_context->msvdx_tile & 0xff) << 16);
1387     }
1388 
1389     if (obj_config->profile == VAProfileVC1Simple ||
1390         obj_config->profile == VAProfileVC1Main ||
1391         obj_config->profile == VAProfileVC1Advanced) {
1392         uint64_t width_in_mb = ((driver_data->render_rect.x + driver_data->render_rect.width + 15) / 16);
1393         obj_context->ctp_type |= (width_in_mb << 32);
1394     }
1395 
1396     /* add ctx_num to save vp8 enc context num to support dual vp8 encoding */
1397     int ret = psb_new_context(driver_data, obj_context->ctp_type | driver_data->protected);
1398     if (ret)
1399         vaStatus = VA_STATUS_ERROR_UNKNOWN;
1400 
1401     DEBUG_FUNC_EXIT
1402     return vaStatus;
1403 }
1404 
psb__allocate_malloc_buffer(object_buffer_p obj_buffer,int size)1405 static VAStatus psb__allocate_malloc_buffer(object_buffer_p obj_buffer, int size)
1406 {
1407     VAStatus vaStatus = VA_STATUS_SUCCESS;
1408 
1409     obj_buffer->buffer_data = realloc(obj_buffer->buffer_data, size);
1410     CHECK_ALLOCATION(obj_buffer->buffer_data);
1411 
1412     return vaStatus;
1413 }
1414 
1415 static VAStatus psb__unmap_buffer(object_buffer_p obj_buffer);
1416 
psb__allocate_BO_buffer(psb_driver_data_p driver_data,object_context_p __maybe_unused obj_context,object_buffer_p obj_buffer,int size,unsigned char * data,VABufferType type)1417 static VAStatus psb__allocate_BO_buffer(psb_driver_data_p driver_data, object_context_p __maybe_unused obj_context, object_buffer_p obj_buffer, int size, unsigned char *data, VABufferType type)
1418 {
1419     VAStatus vaStatus = VA_STATUS_SUCCESS;
1420 
1421     ASSERT(NULL == obj_buffer->buffer_data);
1422 
1423     if (obj_buffer->psb_buffer && (psb_bs_queued == obj_buffer->psb_buffer->status)) {
1424         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Abandoning BO for buffer %08x type %s\n", obj_buffer->base.id,
1425                                  buffer_type_to_string(obj_buffer->type));
1426         /* need to set psb_buffer aside and get another one */
1427         obj_buffer->psb_buffer->status = psb_bs_abandoned;
1428         obj_buffer->psb_buffer = NULL;
1429         obj_buffer->size = 0;
1430         obj_buffer->alloc_size = 0;
1431     }
1432 
1433     if (type == VAProtectedSliceDataBufferType) {
1434         if (obj_buffer->psb_buffer) {
1435             drv_debug_msg(VIDEO_DEBUG_GENERAL, "RAR: old RAR slice buffer with RAR handle 0%08x, current RAR handle 0x%08x\n",
1436                                      obj_buffer->psb_buffer->rar_handle, (uint32_t)data);
1437             drv_debug_msg(VIDEO_DEBUG_GENERAL, "RAR: force old RAR buffer destroy and new buffer re-allocation by set size=0\n");
1438             obj_buffer->alloc_size = 0;
1439         }
1440     }
1441 
1442     if (obj_buffer->alloc_size < (unsigned int)size) {
1443         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Buffer size mismatch: Need %d, currently have %d\n", size, obj_buffer->alloc_size);
1444         if (obj_buffer->psb_buffer) {
1445             if (obj_buffer->buffer_data) {
1446                 psb__unmap_buffer(obj_buffer);
1447             }
1448             psb_buffer_destroy(obj_buffer->psb_buffer);
1449             obj_buffer->alloc_size = 0;
1450         } else {
1451             obj_buffer->psb_buffer = (psb_buffer_p) calloc(1, sizeof(struct psb_buffer_s));
1452             if (NULL == obj_buffer->psb_buffer) {
1453                 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1454                 DEBUG_FAILURE;
1455             }
1456         }
1457         if (VA_STATUS_SUCCESS == vaStatus) {
1458             drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocate new GPU buffers for vaCreateBuffer:type=%s,size=%d.\n",
1459                                      buffer_type_to_string(obj_buffer->type), size);
1460 
1461             size = (size + 0x7fff) & ~0x7fff; /* Round up */
1462             if (obj_buffer->type == VAImageBufferType) /* Xserver side PutSurface, Image/subpicture buffer
1463                                                         * should be shared between two process
1464                                                         */
1465                 vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu_shared, obj_buffer->psb_buffer);
1466 #ifndef BAYTRAIL
1467             else if (obj_buffer->type == VAProtectedSliceDataBufferType) {
1468                 vaStatus = psb_buffer_reference_imr(driver_data, (uint32_t)data, obj_buffer->psb_buffer);
1469             }
1470 #endif
1471             else if (obj_buffer->type == VAEncCodedBufferType)
1472                 vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu, obj_buffer->psb_buffer);
1473             else
1474                 vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu, obj_buffer->psb_buffer);
1475 
1476             if (VA_STATUS_SUCCESS != vaStatus) {
1477                 free(obj_buffer->psb_buffer);
1478                 obj_buffer->psb_buffer = NULL;
1479                 DEBUG_FAILURE;
1480             } else {
1481                 obj_buffer->alloc_size = size;
1482             }
1483         }
1484     }
1485     return vaStatus;
1486 }
1487 
psb__map_buffer(object_buffer_p obj_buffer)1488 static VAStatus psb__map_buffer(object_buffer_p obj_buffer)
1489 {
1490     if (obj_buffer->psb_buffer) {
1491         return psb_buffer_map(obj_buffer->psb_buffer, &obj_buffer->buffer_data);
1492     }
1493     return VA_STATUS_SUCCESS;
1494 }
1495 
psb__unmap_buffer(object_buffer_p obj_buffer)1496 static VAStatus psb__unmap_buffer(object_buffer_p obj_buffer)
1497 {
1498     if (obj_buffer->psb_buffer) {
1499         obj_buffer->buffer_data = NULL;
1500         return psb_buffer_unmap(obj_buffer->psb_buffer);
1501     }
1502     return VA_STATUS_SUCCESS;
1503 }
1504 
psb__destroy_buffer(psb_driver_data_p driver_data,object_buffer_p obj_buffer)1505 static void psb__destroy_buffer(psb_driver_data_p driver_data, object_buffer_p obj_buffer)
1506 {
1507     if (obj_buffer->psb_buffer) {
1508         if (obj_buffer->buffer_data) {
1509             psb__unmap_buffer(obj_buffer);
1510         }
1511         psb_buffer_destroy(obj_buffer->psb_buffer);
1512         free(obj_buffer->psb_buffer);
1513         obj_buffer->psb_buffer = NULL;
1514     }
1515 
1516     if (NULL != obj_buffer->buffer_data) {
1517         free(obj_buffer->buffer_data);
1518         obj_buffer->buffer_data = NULL;
1519         obj_buffer->size = 0;
1520     }
1521 
1522     object_heap_free(&driver_data->buffer_heap, (object_base_p) obj_buffer);
1523 }
1524 
psb__suspend_buffer(psb_driver_data_p driver_data,object_buffer_p obj_buffer)1525 void psb__suspend_buffer(psb_driver_data_p driver_data, object_buffer_p obj_buffer)
1526 {
1527     if (obj_buffer->context) {
1528         VABufferType type = obj_buffer->type;
1529         object_context_p obj_context = obj_buffer->context;
1530 
1531         if (type >= PSB_MAX_BUFFERTYPES) {
1532             drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid buffer type %d\n", type);
1533             return;
1534         }
1535 
1536         /* Remove buffer from active list */
1537         *obj_buffer->pptr_prev_next = obj_buffer->ptr_next;
1538 
1539         /* Add buffer to tail of unused list */
1540         obj_buffer->ptr_next = NULL;
1541         obj_buffer->last_used = obj_context->frame_count;
1542         if (obj_context->buffers_unused_tail[type]) {
1543             obj_buffer->pptr_prev_next = &(obj_context->buffers_unused_tail[type]->ptr_next);
1544         } else {
1545             obj_buffer->pptr_prev_next = &(obj_context->buffers_unused[type]);
1546         }
1547         *obj_buffer->pptr_prev_next = obj_buffer;
1548         obj_context->buffers_unused_tail[type] = obj_buffer;
1549         obj_context->buffers_unused_count[type]++;
1550 
1551         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Adding buffer %08x type %s to unused list. unused count = %d\n", obj_buffer->base.id,
1552                                  buffer_type_to_string(obj_buffer->type), obj_context->buffers_unused_count[type]);
1553 
1554         object_heap_suspend_object((object_base_p) obj_buffer, 1); /* suspend */
1555         return;
1556     }
1557 
1558     if (obj_buffer->psb_buffer && (psb_bs_queued == obj_buffer->psb_buffer->status)) {
1559         /* need to set psb_buffer aside */
1560         obj_buffer->psb_buffer->status = psb_bs_abandoned;
1561         obj_buffer->psb_buffer = NULL;
1562     }
1563 
1564     psb__destroy_buffer(driver_data, obj_buffer);
1565 }
1566 
psb__destroy_context(psb_driver_data_p driver_data,object_context_p obj_context)1567 static void psb__destroy_context(psb_driver_data_p driver_data, object_context_p obj_context)
1568 {
1569     int encode, i;
1570 
1571     if (obj_context->entry_point == VAEntrypointEncSlice)
1572         encode = 1;
1573     else
1574         encode = 0;
1575 
1576     obj_context->format_vtable->destroyContext(obj_context);
1577 
1578     for (i = 0; i < PSB_MAX_BUFFERTYPES; i++) {
1579         object_buffer_p obj_buffer;
1580         obj_buffer = obj_context->buffers_active[i];
1581         for (; obj_buffer; obj_buffer = obj_buffer->ptr_next) {
1582             drv_debug_msg(VIDEO_DEBUG_INIT, "%s: destroying active buffer %08x\n", __FUNCTION__, obj_buffer->base.id);
1583             psb__destroy_buffer(driver_data, obj_buffer);
1584         }
1585         obj_buffer = obj_context->buffers_unused[i];
1586         for (; obj_buffer; obj_buffer = obj_buffer->ptr_next) {
1587             drv_debug_msg(VIDEO_DEBUG_INIT, "%s: destroying unused buffer %08x\n", __FUNCTION__, obj_buffer->base.id);
1588             psb__destroy_buffer(driver_data, obj_buffer);
1589         }
1590         obj_context->buffers_unused_count[i] = 0;
1591     }
1592 #ifndef BAYTRAIL
1593     for (i = 0; i < LNC_MAX_CMDBUFS_ENCODE; i++) {
1594         if (obj_context->pnw_cmdbuf_list[i]) {
1595             pnw_cmdbuf_destroy(obj_context->pnw_cmdbuf_list[i]);
1596             free(obj_context->pnw_cmdbuf_list[i]);
1597             obj_context->pnw_cmdbuf_list[i] = NULL;
1598         }
1599     }
1600 #endif
1601 #ifdef PSBVIDEO_MRFL
1602     for (i = 0; i < TNG_MAX_CMDBUFS_ENCODE; i++) {
1603         if (obj_context->tng_cmdbuf_list[i]) {
1604             tng_cmdbuf_destroy(obj_context->tng_cmdbuf_list[i]);
1605             free(obj_context->tng_cmdbuf_list[i]);
1606             obj_context->tng_cmdbuf_list[i] = NULL;
1607         }
1608     }
1609 #endif
1610 #ifdef PSBVIDEO_MRFL_VPP
1611     for (i = 0; i < VSP_MAX_CMDBUFS; i++) {
1612         if (obj_context->vsp_cmdbuf_list[i]) {
1613             vsp_cmdbuf_destroy(obj_context->vsp_cmdbuf_list[i]);
1614             free(obj_context->vsp_cmdbuf_list[i]);
1615             obj_context->vsp_cmdbuf_list[i] = NULL;
1616         }
1617     }
1618 #endif
1619 
1620     for (i = 0; i < PSB_MAX_CMDBUFS; i++) {
1621         if (obj_context->cmdbuf_list[i]) {
1622             psb_cmdbuf_destroy(obj_context->cmdbuf_list[i]);
1623             free(obj_context->cmdbuf_list[i]);
1624             obj_context->cmdbuf_list[i] = NULL;
1625         }
1626     }
1627     obj_context->cmdbuf = NULL;
1628 #ifdef PSBVIDEO_MRFL_VPP
1629     obj_context->vsp_cmdbuf = NULL;
1630 #endif
1631 
1632     obj_context->context_id = -1;
1633     obj_context->config_id = -1;
1634     obj_context->picture_width = 0;
1635     obj_context->picture_height = 0;
1636     if (obj_context->render_targets)
1637         free(obj_context->render_targets);
1638     obj_context->render_targets = NULL;
1639     obj_context->num_render_targets = 0;
1640     obj_context->va_flags = 0;
1641 
1642     obj_context->current_render_target = NULL;
1643     obj_context->ec_target = NULL;
1644     obj_context->ec_candidate = NULL;
1645     if (obj_context->buffer_list)
1646         free(obj_context->buffer_list);
1647     obj_context->num_buffers = 0;
1648 
1649     object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1650 
1651     psb_rm_context(driver_data);
1652 }
1653 
psb_DestroyContext(VADriverContextP ctx,VAContextID context)1654 VAStatus psb_DestroyContext(
1655     VADriverContextP ctx,
1656     VAContextID context
1657 )
1658 {
1659     DEBUG_FUNC_ENTER
1660     INIT_DRIVER_DATA
1661     VAStatus vaStatus = VA_STATUS_SUCCESS;
1662     object_context_p obj_context = CONTEXT(context);
1663     CHECK_CONTEXT(obj_context);
1664 
1665     psb__destroy_context(driver_data, obj_context);
1666 
1667     DEBUG_FUNC_EXIT
1668     return vaStatus;
1669 }
1670 
psb__CreateBuffer(psb_driver_data_p driver_data,object_context_p obj_context,VABufferType type,unsigned int size,unsigned int num_elements,unsigned char * data,VABufferID * buf_desc)1671 VAStatus psb__CreateBuffer(
1672     psb_driver_data_p driver_data,
1673     object_context_p obj_context,       /* in */
1674     VABufferType type,  /* in */
1675     unsigned int size,          /* in */
1676     unsigned int num_elements, /* in */
1677     unsigned char *data,         /* in */
1678     VABufferID *buf_desc    /* out */
1679 )
1680 {
1681     DEBUG_FUNC_ENTER
1682     VAStatus vaStatus = VA_STATUS_SUCCESS;
1683     int bufferID;
1684     object_buffer_p obj_buffer;
1685     int unused_count;
1686 
1687     /*PSB_MAX_BUFFERTYPES is the size of array buffers_unused*/
1688     if (type >= PSB_MAX_BUFFERTYPES) {
1689         drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid buffer type %d\n", type);
1690         return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1691     }
1692 
1693 
1694     obj_buffer = obj_context ? obj_context->buffers_unused[type] : NULL;
1695     unused_count = obj_context ? obj_context->buffers_unused_count[type] : 0;
1696 
1697     /*
1698      * Buffer Management
1699      * For each buffer type, maintain
1700      *   - a LRU sorted list of unused buffers
1701      *   - a list of active buffers
1702      * We only create a new buffer when
1703      *   - no unused buffers are available
1704      *   - the last unused buffer is still queued
1705      *   - the last unused buffer was used very recently and may still be fenced
1706      *      - used recently is defined as within the current frame_count (subject to tweaks)
1707      *
1708      * The buffer that is returned will be moved to the list of active buffers
1709      *   - vaDestroyBuffer and vaRenderPicture will move the active buffer back to the list of unused buffers
1710     */
1711     drv_debug_msg(VIDEO_DEBUG_GENERAL, "Requesting buffer creation, size=%d,elements=%d,type=%s\n", size, num_elements,
1712                              buffer_type_to_string(type));
1713 
1714     /* on MFLD, data is IMR offset, and could be 0 */
1715     /*
1716     if ((type == VAProtectedSliceDataBufferType) && (data == NULL)) {
1717         drv_debug_msg(VIDEO_DEBUG_ERROR, "RAR: Create protected slice buffer, but RAR handle is NULL\n");
1718         return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE ;
1719     }
1720     */
1721 
1722     if (obj_buffer && obj_buffer->psb_buffer) {
1723         if (psb_bs_queued == obj_buffer->psb_buffer->status) {
1724             /* Buffer is still queued, allocate new buffer instead */
1725             drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x, still queued\n", obj_buffer->base.id);
1726             obj_buffer = NULL;
1727         } else if ((obj_buffer->last_used == obj_context->frame_count) && (unused_count < MAX_UNUSED_BUFFERS)) {
1728             /* Buffer was used for this frame, allocate new buffer instead */
1729             drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x, recently used. Unused = %d\n", obj_buffer->base.id, unused_count);
1730             obj_buffer = NULL;
1731         } else if (obj_context->frame_count - obj_buffer->last_used < 5) {
1732             /* Buffer was used for previous frame, allocate new buffer instead */
1733             drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x used by frame %d. Unused = %d\n", obj_buffer->base.id, obj_buffer->last_used, unused_count);
1734             obj_buffer = NULL;
1735         }
1736     }
1737 
1738     if (obj_buffer) {
1739         bufferID = obj_buffer->base.id;
1740         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Reusing buffer %08x type %s from unused list. Unused = %d\n", bufferID,
1741                                  buffer_type_to_string(type), unused_count);
1742 
1743         /* Remove from unused list */
1744         obj_context->buffers_unused[type] = obj_buffer->ptr_next;
1745         if (obj_context->buffers_unused[type]) {
1746             obj_context->buffers_unused[type]->pptr_prev_next = &(obj_context->buffers_unused[type]);
1747             ASSERT(obj_context->buffers_unused_tail[type] != obj_buffer);
1748         } else {
1749             ASSERT(obj_context->buffers_unused_tail[type] == obj_buffer);
1750             obj_context->buffers_unused_tail[type] = 0;
1751         }
1752         obj_context->buffers_unused_count[type]--;
1753 
1754         object_heap_suspend_object((object_base_p)obj_buffer, 0); /* Make BufferID valid again */
1755         ASSERT(type == obj_buffer->type);
1756         ASSERT(obj_context == obj_buffer->context);
1757     } else {
1758         bufferID = object_heap_allocate(&driver_data->buffer_heap);
1759         obj_buffer = BUFFER(bufferID);
1760         CHECK_ALLOCATION(obj_buffer);
1761 
1762         MEMSET_OBJECT(obj_buffer, struct object_buffer_s);
1763 
1764         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocating new buffer %08x type %s.\n", bufferID, buffer_type_to_string(type));
1765         obj_buffer->type = type;
1766         obj_buffer->buffer_data = NULL;
1767         obj_buffer->psb_buffer = NULL;
1768         obj_buffer->size = 0;
1769         obj_buffer->max_num_elements = 0;
1770         obj_buffer->alloc_size = 0;
1771         obj_buffer->context = obj_context;
1772     }
1773     if (obj_context) {
1774         /* Add to front of active list */
1775         obj_buffer->ptr_next = obj_context->buffers_active[type];
1776         if (obj_buffer->ptr_next) {
1777             obj_buffer->ptr_next->pptr_prev_next = &(obj_buffer->ptr_next);
1778         }
1779         obj_buffer->pptr_prev_next = &(obj_context->buffers_active[type]);
1780         *obj_buffer->pptr_prev_next = obj_buffer;
1781     }
1782 
1783     switch (obj_buffer->type) {
1784     case VABitPlaneBufferType:
1785     case VASliceDataBufferType:
1786     case VAResidualDataBufferType:
1787     case VAImageBufferType:
1788     case VASliceGroupMapBufferType:
1789     case VAEncCodedBufferType:
1790     case VAProtectedSliceDataBufferType:
1791 #ifdef SLICE_HEADER_PARSING
1792     case VAParseSliceHeaderGroupBufferType:
1793 #endif
1794         vaStatus = psb__allocate_BO_buffer(driver_data, obj_context,obj_buffer, size * num_elements, data, obj_buffer->type);
1795         DEBUG_FAILURE;
1796         break;
1797     case VAPictureParameterBufferType:
1798     case VAIQMatrixBufferType:
1799     case VASliceParameterBufferType:
1800     case VAMacroblockParameterBufferType:
1801     case VADeblockingParameterBufferType:
1802     case VAEncPackedHeaderParameterBufferType:
1803     case VAEncPackedHeaderDataBufferType:
1804     case VAEncSequenceParameterBufferType:
1805     case VAEncPictureParameterBufferType:
1806     case VAEncSliceParameterBufferType:
1807     case VAQMatrixBufferType:
1808     case VAEncMiscParameterBufferType:
1809     case VAProbabilityBufferType:
1810     case VAHuffmanTableBufferType:
1811     case VAProcPipelineParameterBufferType:
1812     case VAProcFilterParameterBufferType:
1813 #ifdef SLICE_HEADER_PARSING
1814     case VAParsePictureParameterBufferType:
1815 #endif
1816         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocate new malloc buffers for vaCreateBuffer:type=%s,size=%d, buffer_data=%p.\n",
1817                                  buffer_type_to_string(type), size, obj_buffer->buffer_data);
1818         vaStatus = psb__allocate_malloc_buffer(obj_buffer, size * num_elements);
1819         DEBUG_FAILURE;
1820         break;
1821 
1822     default:
1823         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1824         DEBUG_FAILURE;
1825         break;;
1826     }
1827 
1828     if (VA_STATUS_SUCCESS == vaStatus) {
1829         obj_buffer->size = size;
1830         obj_buffer->max_num_elements = num_elements;
1831         obj_buffer->num_elements = num_elements;
1832         if (data && (obj_buffer->type != VAProtectedSliceDataBufferType)) {
1833             vaStatus = psb__map_buffer(obj_buffer);
1834             if (VA_STATUS_SUCCESS == vaStatus) {
1835                 memcpy(obj_buffer->buffer_data, data, size * num_elements);
1836 
1837                 psb__unmap_buffer(obj_buffer);
1838             }
1839         }
1840     }
1841     if (VA_STATUS_SUCCESS == vaStatus) {
1842         *buf_desc = bufferID;
1843     } else {
1844         psb__destroy_buffer(driver_data, obj_buffer);
1845     }
1846 
1847     DEBUG_FUNC_EXIT
1848     return vaStatus;
1849 }
1850 
psb_CreateBuffer(VADriverContextP ctx,VAContextID context,VABufferType type,unsigned int size,unsigned int num_elements,void * data,VABufferID * buf_desc)1851 VAStatus psb_CreateBuffer(
1852     VADriverContextP ctx,
1853     VAContextID context,        /* in */
1854     VABufferType type,  /* in */
1855     unsigned int size,          /* in */
1856     unsigned int num_elements, /* in */
1857     void *data,         /* in */
1858     VABufferID *buf_desc    /* out */
1859 )
1860 {
1861     DEBUG_FUNC_ENTER
1862     INIT_DRIVER_DATA
1863     VAStatus vaStatus = VA_STATUS_SUCCESS;
1864 
1865     CHECK_INVALID_PARAM(num_elements <= 0);
1866 
1867     switch (type) {
1868     case VABitPlaneBufferType:
1869     case VASliceDataBufferType:
1870     case VAProtectedSliceDataBufferType:
1871     case VAResidualDataBufferType:
1872     case VASliceGroupMapBufferType:
1873     case VAPictureParameterBufferType:
1874     case VAIQMatrixBufferType:
1875     case VASliceParameterBufferType:
1876     case VAMacroblockParameterBufferType:
1877     case VADeblockingParameterBufferType:
1878     case VAEncCodedBufferType:
1879     case VAEncSequenceParameterBufferType:
1880     case VAEncPictureParameterBufferType:
1881     case VAEncSliceParameterBufferType:
1882     case VAEncPackedHeaderParameterBufferType:
1883     case VAEncPackedHeaderDataBufferType:
1884     case VAQMatrixBufferType:
1885     case VAEncMiscParameterBufferType:
1886     case VAProbabilityBufferType:
1887     case VAHuffmanTableBufferType:
1888     case VAProcPipelineParameterBufferType:
1889     case VAProcFilterParameterBufferType:
1890 #ifdef SLICE_HEADER_PARSING
1891     case VAParsePictureParameterBufferType:
1892     case VAParseSliceHeaderGroupBufferType:
1893 #endif
1894         break;
1895 
1896     default:
1897         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1898         DEBUG_FAILURE;
1899         return vaStatus;
1900     }
1901 
1902     object_context_p obj_context = CONTEXT(context);
1903     CHECK_CONTEXT(obj_context);
1904     CHECK_INVALID_PARAM(buf_desc == NULL);
1905 
1906     vaStatus = psb__CreateBuffer(driver_data, obj_context, type, size, num_elements, data, buf_desc);
1907 
1908     DEBUG_FUNC_EXIT
1909     return vaStatus;
1910 }
1911 
1912 
psb_BufferInfo(VADriverContextP ctx,VABufferID buf_id,VABufferType * type,unsigned int * size,unsigned int * num_elements)1913 VAStatus psb_BufferInfo(
1914     VADriverContextP ctx,
1915     VABufferID buf_id,  /* in */
1916     VABufferType *type, /* out */
1917     unsigned int *size,         /* out */
1918     unsigned int *num_elements /* out */
1919 )
1920 {
1921     DEBUG_FUNC_ENTER
1922     INIT_DRIVER_DATA
1923     VAStatus vaStatus = VA_STATUS_SUCCESS;
1924 
1925     object_buffer_p obj_buffer = BUFFER(buf_id);
1926     CHECK_BUFFER(obj_buffer);
1927 
1928     *type = obj_buffer->type;
1929     *size = obj_buffer->size;
1930     *num_elements = obj_buffer->num_elements;
1931     DEBUG_FUNC_EXIT
1932     return VA_STATUS_SUCCESS;
1933 }
1934 
1935 
psb_BufferSetNumElements(VADriverContextP ctx,VABufferID buf_id,unsigned int num_elements)1936 VAStatus psb_BufferSetNumElements(
1937     VADriverContextP ctx,
1938     VABufferID buf_id,    /* in */
1939     unsigned int num_elements    /* in */
1940 )
1941 {
1942     DEBUG_FUNC_ENTER
1943     INIT_DRIVER_DATA
1944     VAStatus vaStatus = VA_STATUS_SUCCESS;
1945     object_buffer_p obj_buffer = BUFFER(buf_id);
1946     CHECK_BUFFER(obj_buffer);
1947 
1948     if ((num_elements <= 0) || (num_elements > obj_buffer->max_num_elements)) {
1949         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
1950     }
1951     if (VA_STATUS_SUCCESS == vaStatus) {
1952         obj_buffer->num_elements = num_elements;
1953     }
1954 
1955     DEBUG_FUNC_EXIT
1956     return vaStatus;
1957 }
1958 
psb_MapBuffer(VADriverContextP ctx,VABufferID buf_id,void ** pbuf)1959 VAStatus psb_MapBuffer(
1960     VADriverContextP ctx,
1961     VABufferID buf_id,    /* in */
1962     void **pbuf         /* out */
1963 )
1964 {
1965     DEBUG_FUNC_ENTER
1966     INIT_DRIVER_DATA
1967     VAStatus vaStatus = VA_STATUS_SUCCESS;
1968     object_buffer_p obj_buffer = BUFFER(buf_id);
1969     CHECK_BUFFER(obj_buffer);
1970 
1971     CHECK_INVALID_PARAM(pbuf == NULL);
1972 
1973     vaStatus = psb__map_buffer(obj_buffer);
1974     CHECK_VASTATUS();
1975 
1976     if (NULL != obj_buffer->buffer_data) {
1977         *pbuf = obj_buffer->buffer_data;
1978 
1979         /* specifically for Topaz encode
1980          * write validate coded data offset in CodedBuffer
1981          */
1982         if (obj_buffer->type == VAEncCodedBufferType)
1983             psb_codedbuf_map_mangle(ctx, obj_buffer, pbuf);
1984         /* *(IMG_UINT32 *)((unsigned char *)obj_buffer->buffer_data + 4) = 16; */
1985     } else {
1986         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1987     }
1988     DEBUG_FUNC_EXIT
1989     return vaStatus;
1990 }
1991 
psb_UnmapBuffer(VADriverContextP ctx,VABufferID buf_id)1992 VAStatus psb_UnmapBuffer(
1993     VADriverContextP ctx,
1994     VABufferID buf_id    /* in */
1995 )
1996 {
1997     DEBUG_FUNC_ENTER
1998     INIT_DRIVER_DATA
1999     VAStatus vaStatus = VA_STATUS_SUCCESS;
2000     object_buffer_p obj_buffer = BUFFER(buf_id);
2001     CHECK_BUFFER(obj_buffer);
2002 
2003     vaStatus = psb__unmap_buffer(obj_buffer);
2004     DEBUG_FUNC_EXIT
2005     return vaStatus;
2006 }
2007 
2008 
psb_DestroyBuffer(VADriverContextP ctx,VABufferID buffer_id)2009 VAStatus psb_DestroyBuffer(
2010     VADriverContextP ctx,
2011     VABufferID buffer_id
2012 )
2013 {
2014     DEBUG_FUNC_ENTER
2015     INIT_DRIVER_DATA
2016     VAStatus vaStatus = VA_STATUS_SUCCESS;
2017     object_buffer_p obj_buffer = BUFFER(buffer_id);
2018     if (NULL == obj_buffer) {
2019         return vaStatus;
2020     }
2021     psb__suspend_buffer(driver_data, obj_buffer);
2022     DEBUG_FUNC_EXIT
2023     return vaStatus;
2024 }
2025 
2026 
psb_BeginPicture(VADriverContextP ctx,VAContextID context,VASurfaceID render_target)2027 VAStatus psb_BeginPicture(
2028     VADriverContextP ctx,
2029     VAContextID context,
2030     VASurfaceID render_target
2031 )
2032 {
2033     DEBUG_FUNC_ENTER
2034     INIT_DRIVER_DATA
2035     VAStatus vaStatus = VA_STATUS_SUCCESS;
2036     object_context_p obj_context;
2037     object_surface_p obj_surface;
2038     object_config_p obj_config;
2039 
2040     obj_context = CONTEXT(context);
2041     CHECK_CONTEXT(obj_context);
2042 
2043     /* Must not be within BeginPicture / EndPicture already */
2044     ASSERT(obj_context->current_render_target == NULL);
2045 
2046     obj_surface = SURFACE(render_target);
2047     CHECK_SURFACE(obj_surface);
2048 
2049     obj_context->current_render_surface_id = render_target;
2050     obj_context->current_render_target = obj_surface;
2051     obj_context->slice_count = 0;
2052 
2053     obj_config = CONFIG(obj_context->config_id);
2054     if (obj_config == NULL)
2055         return VA_STATUS_ERROR_INVALID_CONFIG;
2056 
2057     /* if the surface is decode render target, and in displaying */
2058     if (obj_config &&
2059         (obj_config->entrypoint != VAEntrypointEncSlice) &&
2060         (driver_data->cur_displaying_surface == render_target))
2061         drv_debug_msg(VIDEO_DEBUG_ERROR, "WARNING: rendering a displaying surface, may see tearing\n");
2062 
2063     if (VA_STATUS_SUCCESS == vaStatus) {
2064         vaStatus = obj_context->format_vtable->beginPicture(obj_context);
2065     }
2066 
2067 #ifdef ANDROID
2068     /* want msvdx to do rotate
2069      * but check per-context stream type: interlace or not
2070      */
2071     if ((obj_config->entrypoint != VAEntrypointEncSlice) &&
2072         (obj_config->entrypoint != VAEntrypointEncPicture)) {
2073         psb_RecalcAlternativeOutput(obj_context);
2074     }
2075 #endif
2076 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
2077     if (driver_data->vpp_on && GET_SURFACE_INFO_tiling(obj_surface->psb_surface))
2078         driver_data->disable_msvdx_rotate = 0;
2079 #endif
2080     if (obj_context->interlaced_stream || driver_data->disable_msvdx_rotate) {
2081         int i;
2082         obj_context->msvdx_rotate = 0;
2083         for (i = 0; i < obj_context->num_render_targets; i++) {
2084             object_surface_p obj_surface = SURFACE(obj_context->render_targets[i]);
2085             /*we invalidate all surfaces's rotate buffer share info here.*/
2086             if (obj_surface && obj_surface->share_info) {
2087                 obj_surface->share_info->surface_rotate = 0;
2088             }
2089 	}
2090     }
2091     else
2092         obj_context->msvdx_rotate = driver_data->msvdx_rotate_want;
2093 
2094     /* the main surface track current rotate information
2095      * try to reuse the allocated rotate surfaces and don't destroy them
2096      * thus the rotation info in obj_surface->out_loop_surface may not be updated
2097      */
2098 
2099     SET_SURFACE_INFO_rotate(obj_surface->psb_surface, obj_context->msvdx_rotate);
2100 
2101      if (CONTEXT_SCALING(obj_context) && obj_config->entrypoint != VAEntrypointEncSlice)
2102           if(VA_STATUS_SUCCESS != psb_CreateScalingSurface(obj_context, obj_surface)) {
2103              obj_context->msvdx_scaling = 0;
2104              ALOGE("%s: fail to allocate scaling surface", __func__);
2105           }
2106 
2107     if (CONTEXT_ROTATE(obj_context)) {
2108 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
2109         /* The VSP rotation is just for 1080P with tilling */
2110         if (driver_data->vpp_on && GET_SURFACE_INFO_tiling(obj_surface->psb_surface)) {
2111             if (obj_config->entrypoint == VAEntrypointVideoProc)
2112                 vaStatus = psb_CreateRotateSurface(obj_context, obj_surface, obj_context->msvdx_rotate);
2113             else {
2114                 SET_SURFACE_INFO_rotate(obj_surface->psb_surface, 0);
2115                 obj_context->msvdx_rotate = 0;
2116                 vaStatus = psb_DestroyRotateBuffer(obj_context, obj_surface);
2117             }
2118         } else
2119 #endif
2120 	vaStatus = psb_CreateRotateSurface(obj_context, obj_surface, obj_context->msvdx_rotate);
2121         if (VA_STATUS_SUCCESS !=vaStatus)
2122             ALOGE("%s: fail to allocate out loop surface", __func__);
2123 
2124     } else {
2125         if (obj_surface && obj_surface->share_info) {
2126             obj_surface->share_info->metadata_rotate = VAROTATION2HAL(driver_data->va_rotate);
2127             obj_surface->share_info->surface_rotate = VAROTATION2HAL(obj_context->msvdx_rotate);
2128         }
2129     }
2130 
2131     if (obj_surface && obj_surface->share_info &&
2132         obj_config->entrypoint == VAEntrypointVLD) {
2133         obj_surface->share_info->crop_width = driver_data->render_rect.width;
2134         obj_surface->share_info->crop_height = driver_data->render_rect.height;
2135     }
2136 
2137     if (driver_data->is_oold &&  !obj_surface->psb_surface->in_loop_buf) {
2138         psb_surface_p psb_surface = obj_surface->psb_surface;
2139 
2140         psb_surface->in_loop_buf = calloc(1, sizeof(struct psb_buffer_s));
2141         CHECK_ALLOCATION(psb_surface->in_loop_buf);
2142 
2143         /* FIXME: For RAR surface, need allocate RAR buffer  */
2144         vaStatus = psb_buffer_create(obj_context->driver_data,
2145                                      psb_surface->size,
2146                                      psb_bt_surface,
2147                                      psb_surface->in_loop_buf);
2148     } else if (!driver_data->is_oold && obj_surface->psb_surface->in_loop_buf) {
2149         psb_surface_p psb_surface = obj_surface->psb_surface;
2150 
2151         psb_buffer_destroy(psb_surface->in_loop_buf);
2152         free(psb_surface->in_loop_buf);
2153         psb_surface->in_loop_buf = NULL;
2154     }
2155     obj_context->is_oold = driver_data->is_oold;
2156 
2157     drv_debug_msg(VIDEO_DEBUG_GENERAL, "---BeginPicture 0x%08x for frame %d --\n",
2158                              render_target, obj_context->frame_count);
2159     psb__trace_message("------Trace frame %d------\n", obj_context->frame_count);
2160 
2161     DEBUG_FUNC_EXIT
2162     return vaStatus;
2163 }
2164 
psb_RenderPicture(VADriverContextP ctx,VAContextID context,VABufferID * buffers,int num_buffers)2165 VAStatus psb_RenderPicture(
2166     VADriverContextP ctx,
2167     VAContextID context,
2168     VABufferID *buffers,
2169     int num_buffers
2170 )
2171 {
2172     DEBUG_FUNC_ENTER
2173     INIT_DRIVER_DATA
2174     VAStatus vaStatus = VA_STATUS_SUCCESS;
2175     object_context_p obj_context;
2176     object_buffer_p *buffer_list;
2177     int i;
2178 
2179     obj_context = CONTEXT(context);
2180     CHECK_CONTEXT(obj_context);
2181 
2182     CHECK_INVALID_PARAM(num_buffers <= 0);
2183     /* Don't crash on NULL pointers */
2184     CHECK_BUFFER(buffers);
2185     /* Must be within BeginPicture / EndPicture */
2186     ASSERT(obj_context->current_render_target != NULL);
2187 
2188     if (num_buffers > obj_context->num_buffers) {
2189         free(obj_context->buffer_list);
2190 
2191         obj_context->buffer_list = (object_buffer_p *) calloc(1, sizeof(object_buffer_p) * num_buffers);
2192         if (obj_context->buffer_list == NULL) {
2193             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
2194             obj_context->num_buffers = 0;
2195         }
2196 
2197         obj_context->num_buffers = num_buffers;
2198     }
2199     buffer_list = obj_context->buffer_list;
2200 
2201     if (VA_STATUS_SUCCESS == vaStatus) {
2202         /* Lookup buffer references */
2203         for (i = 0; i < num_buffers; i++) {
2204             object_buffer_p obj_buffer = BUFFER(buffers[i]);
2205             CHECK_BUFFER(obj_buffer);
2206 
2207             buffer_list[i] = obj_buffer;
2208             drv_debug_msg(VIDEO_DEBUG_GENERAL, "Render buffer %08x type %s\n", obj_buffer->base.id,
2209                                      buffer_type_to_string(obj_buffer->type));
2210         }
2211     }
2212 
2213     if (VA_STATUS_SUCCESS == vaStatus) {
2214         vaStatus = obj_context->format_vtable->renderPicture(obj_context, buffer_list, num_buffers);
2215     }
2216 
2217     if (buffer_list) {
2218         /* Release buffers */
2219         for (i = 0; i < num_buffers; i++) {
2220             if (buffer_list[i]) {
2221                 psb__suspend_buffer(driver_data, buffer_list[i]);
2222             }
2223         }
2224     }
2225 
2226     DEBUG_FUNC_EXIT
2227     return vaStatus;
2228 }
2229 
psb_EndPicture(VADriverContextP ctx,VAContextID context)2230 VAStatus psb_EndPicture(
2231     VADriverContextP ctx,
2232     VAContextID context
2233 )
2234 {
2235     DEBUG_FUNC_ENTER
2236     INIT_DRIVER_DATA
2237     VAStatus vaStatus;
2238     object_context_p obj_context;
2239 
2240     obj_context = CONTEXT(context);
2241     CHECK_CONTEXT(obj_context);
2242 
2243     vaStatus = obj_context->format_vtable->endPicture(obj_context);
2244 
2245     drv_debug_msg(VIDEO_DEBUG_GENERAL, "---EndPicture for frame %d --\n", obj_context->frame_count);
2246 
2247     obj_context->current_render_target = NULL;
2248     obj_context->frame_count++;
2249 
2250     psb__trace_message("FrameCount = %03d\n", obj_context->frame_count);
2251     drv_debug_msg(VIDEO_DEBUG_GENERAL, "FrameCount = %03d\n", obj_context->frame_count);
2252     psb__trace_message(NULL);
2253 
2254 
2255     //psb_SyncSurface(ctx, obj_context->current_render_surface_id);
2256     DEBUG_FUNC_EXIT
2257     return vaStatus;
2258 }
2259 
2260 
psb__surface_usage(psb_driver_data_p driver_data,object_surface_p obj_surface,int * decode,int * encode,int * rc_enable,int * proc)2261 static void psb__surface_usage(
2262     psb_driver_data_p driver_data,
2263     object_surface_p obj_surface,
2264     int *decode, int *encode, int *rc_enable, int *proc
2265 )
2266 {
2267     object_context_p obj_context;
2268     object_config_p obj_config;
2269     VAEntrypoint tmp;
2270     unsigned int eRCmode;
2271     int i;
2272 
2273 
2274     *decode = 0;
2275     *encode = 0;
2276     *rc_enable = 0;
2277     *proc = 0;
2278 
2279     obj_context = CONTEXT(obj_surface->context_id);
2280     if (NULL == obj_context) /* not associate with a context */
2281         return;
2282 
2283     obj_config = CONFIG(obj_context->config_id);
2284     if (NULL == obj_config) /* not have a validate context */
2285         return;
2286 
2287     tmp = obj_config->entrypoint;
2288 
2289     *encode = (tmp == VAEntrypointEncSlice) || (tmp == VAEntrypointEncPicture);
2290     *decode = (VAEntrypointVLD <= tmp) && (tmp <= VAEntrypointDeblocking);
2291 #ifdef PSBVIDEO_MRFL_VPP
2292     *proc = (VAEntrypointVideoProc == tmp);
2293 #endif
2294 
2295     if (*encode) {
2296         for (i = 0; i < obj_config->attrib_count; i++) {
2297             if (obj_config->attrib_list[i].type == VAConfigAttribRateControl)
2298                 break;
2299         }
2300 
2301         if (i >= obj_config->attrib_count)
2302             eRCmode = VA_RC_NONE;
2303         else
2304             eRCmode = obj_config->attrib_list[i].value;
2305 
2306         if (eRCmode == VA_RC_NONE)
2307             *rc_enable = 0;
2308         else
2309             *rc_enable = 1;
2310     }
2311 }
2312 
psb_SyncSurface(VADriverContextP ctx,VASurfaceID render_target)2313 VAStatus psb_SyncSurface(
2314     VADriverContextP ctx,
2315     VASurfaceID render_target
2316 )
2317 {
2318     DEBUG_FUNC_ENTER
2319     INIT_DRIVER_DATA
2320     VAStatus vaStatus = VA_STATUS_SUCCESS;
2321     object_surface_p obj_surface;
2322     int decode = 0, encode = 0, rc_enable = 0, proc = 0;
2323     object_context_p obj_context = NULL;
2324     object_config_p obj_config = NULL;
2325 
2326     drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_SyncSurface: 0x%08x\n", render_target);
2327 
2328     obj_surface = SURFACE(render_target);
2329     CHECK_SURFACE(obj_surface);
2330 
2331     obj_context = CONTEXT(obj_surface->context_id);
2332     if (obj_context) {
2333         obj_config = CONFIG(obj_context->config_id);
2334     }
2335 
2336     /* The cur_displaying_surface indicates the surface being displayed by overlay.
2337      * The diaplay_timestamp records the time point of put surface, which would
2338      * be set to zero while using texture blit.*/
2339 
2340     /* don't use mutex here for performance concern... */
2341     //pthread_mutex_lock(&output->output_mutex);
2342     if (render_target == driver_data->cur_displaying_surface)
2343         vaStatus = VA_STATUS_ERROR_SURFACE_IN_DISPLAYING;
2344     else if ((VA_INVALID_SURFACE != driver_data->cur_displaying_surface)    /* use overlay */
2345              && (render_target == driver_data->last_displaying_surface)) {  /* It's the last displaying surface*/
2346         object_surface_p cur_obj_surface = SURFACE(driver_data->cur_displaying_surface);
2347         /*  The flip operation on current displaying surface could be delayed to
2348          *  next VBlank and hadn't been finished yet. Then, the last displaying
2349          *  surface shouldn't be freed, because the hardware may not
2350          *  complete loading data of it. Any change of the last surface could
2351          *  have a impect on the scrren.*/
2352         if (NULL != cur_obj_surface) {
2353             while ((GetTickCount() - cur_obj_surface->display_timestamp) < PSB_MAX_FLIP_DELAY)
2354                 usleep(PSB_MAX_FLIP_DELAY * 1000);
2355         }
2356     }
2357     //pthread_mutex_unlock(&output->output_mutex);
2358 
2359     if (vaStatus != VA_STATUS_ERROR_SURFACE_IN_DISPLAYING) {
2360 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
2361         /* For VPP buffer, will sync the rotated buffer */
2362         if (obj_config && obj_config->entrypoint == VAEntrypointVideoProc) {
2363             if (GET_SURFACE_INFO_tiling(obj_surface->psb_surface) &&
2364                 (obj_context->msvdx_rotate == VA_ROTATION_90 || obj_context->msvdx_rotate == VA_ROTATION_270) &&
2365                 obj_surface->out_loop_surface)
2366                 vaStatus = psb_surface_sync(obj_surface->out_loop_surface);
2367             else
2368                 vaStatus = psb_surface_sync(obj_surface->psb_surface);
2369 	} else
2370 #endif
2371         vaStatus = psb_surface_sync(obj_surface->psb_surface);
2372     }
2373 
2374     /* report any error of decode for Android */
2375     psb__surface_usage(driver_data, obj_surface, &decode, &encode, &rc_enable, &proc);
2376 #if 0
2377     if (decode && IS_MRST(driver_data)) {
2378         struct drm_lnc_video_getparam_arg arg;
2379         uint32_t ret, handle, fw_status = 0;
2380         handle = wsbmKBufHandle(wsbmKBuf(obj_surface->psb_surface->buf.drm_buf));
2381         arg.key = IMG_VIDEO_DECODE_STATUS;
2382         arg.arg = (uint64_t)((unsigned long) & handle);
2383         arg.value = (uint64_t)((unsigned long) & fw_status);
2384         ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
2385                                   &arg, sizeof(arg));
2386         if (ret == 0) {
2387             if (fw_status != 0)
2388                 vaStatus = VA_STATUS_ERROR_DECODING_ERROR;
2389         } else {
2390             drv_debug_msg(VIDEO_DEBUG_GENERAL, "IMG_VIDEO_DECODE_STATUS ioctl return failed.\n");
2391             vaStatus = VA_STATUS_ERROR_UNKNOWN;
2392         }
2393     } else if (proc && IS_MRFL(driver_data)) {
2394         /* FIXME: does it need a new surface sync mechanism for FRC? */
2395     }
2396 #endif
2397     if (proc && IS_MRFL(driver_data)) {
2398         /* FIXME: does it need a new surface sync mechanism for FRC? */
2399     }
2400 
2401     //psb__dump_NV_buffers(obj_surface->psb_surface, 0, 0, obj_surface->width, obj_surface->height);
2402     //psb__dump_NV_buffers(obj_surface->psb_surface_rotate, 0, 0, obj_surface->height, ((obj_surface->width + 0x1f) & (~0x1f)));
2403     if (obj_surface->scaling_surface)
2404         psb__dump_NV12_buffers(obj_surface->scaling_surface, 0, 0, obj_surface->width_s, obj_surface->height_s);
2405     DEBUG_FAILURE;
2406     DEBUG_FUNC_EXIT
2407     return vaStatus;
2408 }
2409 
2410 
psb_QuerySurfaceStatus(VADriverContextP ctx,VASurfaceID render_target,VASurfaceStatus * status)2411 VAStatus psb_QuerySurfaceStatus(
2412     VADriverContextP ctx,
2413     VASurfaceID render_target,
2414     VASurfaceStatus *status    /* out */
2415 )
2416 {
2417     DEBUG_FUNC_ENTER
2418     INIT_DRIVER_DATA
2419     VAStatus vaStatus = VA_STATUS_SUCCESS;
2420     object_surface_p obj_surface;
2421     VASurfaceStatus surface_status;
2422     int frame_skip = 0, encode = 0, decode = 0, rc_enable = 0, proc = 0;
2423     object_context_p obj_context = NULL;
2424 
2425     obj_surface = SURFACE(render_target);
2426     CHECK_SURFACE(obj_surface);
2427 
2428     CHECK_INVALID_PARAM(status == NULL);
2429 
2430     psb__surface_usage(driver_data, obj_surface, &decode, &encode, &rc_enable, &proc);
2431 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
2432     /* For VPP 1080P, will query the rotated buffer */
2433     if (proc) {
2434         obj_context = CONTEXT(obj_surface->context_id);
2435         CHECK_CONTEXT(obj_context);
2436         if (GET_SURFACE_INFO_tiling(obj_surface->psb_surface) &&
2437             (obj_context->msvdx_rotate == VA_ROTATION_90 || obj_context->msvdx_rotate == VA_ROTATION_270) &&
2438             obj_surface->out_loop_surface)
2439             vaStatus = psb_surface_query_status(obj_surface->out_loop_surface, &surface_status);
2440         else
2441             vaStatus = psb_surface_query_status(obj_surface->psb_surface, &surface_status);
2442     } else
2443 #endif
2444         vaStatus = psb_surface_query_status(obj_surface->psb_surface, &surface_status);
2445 
2446     /* The cur_displaying_surface indicates the surface being displayed by overlay.
2447      * The diaplay_timestamp records the time point of put surface, which would
2448      * be set to zero while using texture blit.*/
2449     pthread_mutex_lock(&driver_data->output_mutex);
2450     if (render_target == driver_data->cur_displaying_surface)
2451         surface_status = VASurfaceDisplaying;
2452     else if ((VA_INVALID_SURFACE != driver_data->cur_displaying_surface)    /* use overlay */
2453              && (render_target == driver_data->last_displaying_surface)) {  /* It's the last displaying surface*/
2454         object_surface_p cur_obj_surface = SURFACE(driver_data->cur_displaying_surface);
2455         /*The flip operation on current displaying surface could be delayed to
2456          *  next VBlank and hadn't been finished yet. Then, the last displaying
2457          *  surface shouldn't be freed, because the hardware may not
2458          *  complete loading data of it. Any change of the last surface could
2459          *  have a impect on the scrren.*/
2460         if ((NULL != cur_obj_surface)
2461             && ((GetTickCount() - cur_obj_surface->display_timestamp) < PSB_MAX_FLIP_DELAY)) {
2462             surface_status = VASurfaceDisplaying;
2463         }
2464     }
2465     pthread_mutex_unlock(&driver_data->output_mutex);
2466 
2467     /* try to get frameskip flag for encode */
2468 #ifndef BAYTRAIL
2469     if (!decode) {
2470         /* The rendering surface may not be associated with any context. So driver should
2471            check the frame skip flag even variable encode is 0 */
2472 #ifdef PSBVIDEO_MRFL
2473         if (IS_MRFL(driver_data))
2474             tng_surface_get_frameskip(driver_data, obj_surface->psb_surface, &frame_skip);
2475         else
2476 #endif
2477             pnw_surface_get_frameskip(driver_data, obj_surface->psb_surface, &frame_skip);
2478 
2479         if (frame_skip == 1) {
2480             surface_status = surface_status | VASurfaceSkipped;
2481             drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s next frame of 0x%08x is skipped",
2482                     __FUNCTION__, render_target);
2483         }
2484     } else
2485 #endif
2486     if (decode) {
2487 #ifdef ANDROID
2488         if (obj_surface->psb_surface->buf.handle) {
2489             buffer_handle_t handle = obj_surface->psb_surface->buf.handle;
2490             int display_status;
2491             int err;
2492             err = gralloc_getdisplaystatus(handle, &display_status);
2493             if (!err) {
2494                 if (display_status)
2495                     surface_status = VASurfaceDisplaying;
2496                 else
2497                     surface_status = VASurfaceReady;
2498             } else {
2499                 surface_status = VASurfaceReady;
2500             }
2501 
2502             /* if not used by display, then check whether surface used by widi */
2503             if (surface_status == VASurfaceReady && obj_surface->share_info) {
2504                 if (obj_surface->share_info->renderStatus == 1) {
2505                     surface_status = VASurfaceDisplaying;
2506                 }
2507             }
2508         }
2509 #endif
2510     } else if (proc) {
2511         /* FIXME: does it need a new surface sync mechanism for FRC? */
2512     }
2513 
2514     *status = surface_status;
2515     DEBUG_FUNC_EXIT
2516     return vaStatus;
2517 }
2518 
psb_QuerySurfaceError(VADriverContextP ctx,VASurfaceID render_target,VAStatus error_status,void ** error_info)2519 VAStatus psb_QuerySurfaceError(
2520     VADriverContextP ctx,
2521     VASurfaceID render_target,
2522     VAStatus error_status,
2523     void **error_info /*out*/
2524 )
2525 {
2526     DEBUG_FUNC_ENTER
2527     INIT_DRIVER_DATA
2528     VAStatus vaStatus = VA_STATUS_SUCCESS;
2529     object_surface_p obj_surface;
2530     uint32_t i;
2531 
2532     obj_surface = SURFACE(render_target);
2533     CHECK_SURFACE(obj_surface);
2534 
2535 #ifdef PSBVIDEO_MSVDX_EC
2536     if (driver_data->ec_enabled == 0) {
2537 #else
2538     {
2539 #endif
2540         drv_debug_msg(VIDEO_DEBUG_GENERAL, "error concealment is not supported for this profile.\n");
2541         error_info = NULL;
2542         return VA_STATUS_ERROR_UNKNOWN;
2543     }
2544 
2545     if (error_status == VA_STATUS_ERROR_DECODING_ERROR) {
2546         drm_psb_msvdx_decode_status_t *decode_status = driver_data->msvdx_decode_status;
2547         struct drm_lnc_video_getparam_arg arg;
2548         uint32_t ret, handle;
2549         handle = wsbmKBufHandle(wsbmKBuf(obj_surface->psb_surface->buf.drm_buf));
2550 
2551         arg.key = IMG_VIDEO_MB_ERROR;
2552         arg.arg = (uint64_t)((unsigned long) & handle);
2553         arg.value = (uint64_t)((unsigned long)decode_status);
2554         ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
2555                                   &arg, sizeof(arg));
2556 	if (ret != 0) {
2557 		drv_debug_msg(VIDEO_DEBUG_GENERAL,"return value is %d drmCommandWriteRead\n",ret);
2558 		return VA_STATUS_ERROR_UNKNOWN;
2559 	}
2560 #ifndef _FOR_FPGA_
2561         if (decode_status->num_region > MAX_MB_ERRORS) {
2562             drv_debug_msg(VIDEO_DEBUG_GENERAL, "too much mb errors are reported.\n");
2563             return VA_STATUS_ERROR_UNKNOWN;
2564         }
2565         i = 0;
2566         for (i = 0; i < decode_status->num_region; ++i) {
2567             driver_data->surface_mb_error[i].status = 1;
2568             driver_data->surface_mb_error[i].start_mb = decode_status->mb_regions[i].start;
2569             driver_data->surface_mb_error[i].end_mb = decode_status->mb_regions[i].end;
2570             //driver_data->surface_mb_error[i].start_mb = decode_status->start_error_mb_list[i];
2571             //driver_data->surface_mb_error[i].end_mb = decode_status->end_error_mb_list[i];
2572             //driver_data->surface_mb_error[i].decode_error_type = decode_status->slice_missing_or_error[i];
2573         }
2574 #endif
2575         driver_data->surface_mb_error[i].status = -1;
2576         *error_info = driver_data->surface_mb_error;
2577     } else {
2578         error_info = NULL;
2579         return VA_STATUS_ERROR_UNKNOWN;
2580     }
2581     DEBUG_FUNC_EXIT
2582     return vaStatus;
2583 }
2584 
2585 #define PSB_MAX_SURFACE_ATTRIBUTES 16
2586 
2587 VAStatus psb_QuerySurfaceAttributes(VADriverContextP ctx,
2588                             VAConfigID config,
2589                             VASurfaceAttrib *attrib_list,
2590                             unsigned int *num_attribs)
2591 {
2592     DEBUG_FUNC_ENTER
2593     INIT_DRIVER_DATA
2594 
2595     VAStatus vaStatus = VA_STATUS_SUCCESS;
2596     object_config_p obj_config;
2597     unsigned int i = 0;
2598 
2599     CHECK_INVALID_PARAM(num_attribs == NULL);
2600 
2601     if (attrib_list == NULL) {
2602         *num_attribs = PSB_MAX_SURFACE_ATTRIBUTES;
2603         return VA_STATUS_SUCCESS;
2604     }
2605 
2606     obj_config = CONFIG(config);
2607     CHECK_CONFIG(obj_config);
2608 
2609     VASurfaceAttrib *attribs = NULL;
2610     attribs = malloc(PSB_MAX_SURFACE_ATTRIBUTES *sizeof(VASurfaceAttrib));
2611     if (attribs == NULL)
2612         return VA_STATUS_ERROR_ALLOCATION_FAILED;
2613 
2614     attribs[i].type = VASurfaceAttribPixelFormat;
2615     attribs[i].value.type = VAGenericValueTypeInteger;
2616     attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
2617     attribs[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
2618     i++;
2619 
2620     attribs[i].type = VASurfaceAttribMemoryType;
2621     attribs[i].value.type = VAGenericValueTypeInteger;
2622     attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
2623     if (obj_config->entrypoint == VAEntrypointEncSlice && obj_config->profile == VAProfileVP8Version0_3) {
2624         attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
2625             VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
2626 	    VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC |
2627 	    VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION;
2628     } else {
2629         attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
2630             VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
2631             VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR |
2632             VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC |
2633             VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION;
2634     }
2635     i++;
2636 
2637     attribs[i].type = VASurfaceAttribExternalBufferDescriptor;
2638     attribs[i].value.type = VAGenericValueTypePointer;
2639     attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
2640     attribs[i].value.value.p = NULL;
2641     i++;
2642 
2643     //modules have speical formats to support
2644     if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
2645 
2646     } else if (obj_config->entrypoint == VAEntrypointEncSlice ||  /* encode */
2647                    obj_config->entrypoint == VAEntrypointEncPicture) {
2648     #ifdef PSBVIDEO_MFLD
2649         if (IS_MFLD(driver_data)) {}
2650     #endif
2651     #ifdef PSBVIDEO_MRFL
2652         if (IS_MRFL(driver_data)) {}
2653     #endif
2654     #ifdef BAYTRAIL
2655         if (IS_BAYTRAIL(driver_data)) {}
2656     #endif
2657     }
2658     else if (obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
2659 
2660     }
2661 
2662     if (i > *num_attribs) {
2663         *num_attribs = i;
2664         return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
2665     }
2666 
2667     *num_attribs = i;
2668     memcpy(attrib_list, attribs, i * sizeof(*attribs));
2669     free(attribs);
2670 
2671     DEBUG_FUNC_EXIT
2672     return vaStatus;
2673 }
2674 
2675 VAStatus psb_LockSurface(
2676     VADriverContextP ctx,
2677     VASurfaceID surface,
2678     unsigned int *fourcc, /* following are output argument */
2679     unsigned int *luma_stride,
2680     unsigned int *chroma_u_stride,
2681     unsigned int *chroma_v_stride,
2682     unsigned int *luma_offset,
2683     unsigned int *chroma_u_offset,
2684     unsigned int *chroma_v_offset,
2685     unsigned int *buffer_name,
2686     void **buffer
2687 )
2688 {
2689     DEBUG_FUNC_ENTER
2690     INIT_DRIVER_DATA
2691     VAStatus vaStatus = VA_STATUS_SUCCESS;
2692     unsigned char *surface_data;
2693     int ret;
2694 
2695     object_surface_p obj_surface = SURFACE(surface);
2696     psb_surface_p psb_surface;
2697     CHECK_SURFACE(obj_surface);
2698 
2699     psb_surface = obj_surface->psb_surface;
2700     if (buffer_name)
2701         *buffer_name = (uint32_t)(wsbmKBufHandle(wsbmKBuf(psb_surface->buf.drm_buf)));
2702 
2703     if (buffer) { /* map the surface buffer */
2704         uint32_t srf_buf_ofs = 0;
2705         ret = psb_buffer_map(&psb_surface->buf, &surface_data);
2706         if (ret) {
2707             *buffer = NULL;
2708             vaStatus = VA_STATUS_ERROR_UNKNOWN;
2709             DEBUG_FAILURE;
2710             return vaStatus;
2711         }
2712         srf_buf_ofs = psb_surface->buf.buffer_ofs;
2713         *buffer = surface_data + srf_buf_ofs;
2714     }
2715 
2716     *fourcc = VA_FOURCC_NV12;
2717     *luma_stride = psb_surface->stride;
2718     *chroma_u_stride = psb_surface->stride;
2719     *chroma_v_stride = psb_surface->stride;
2720     *luma_offset = 0;
2721     *chroma_u_offset = obj_surface->height * psb_surface->stride;
2722     *chroma_v_offset = obj_surface->height * psb_surface->stride + 1;
2723     DEBUG_FUNC_EXIT
2724     return vaStatus;
2725 }
2726 
2727 
2728 VAStatus psb_UnlockSurface(
2729     VADriverContextP ctx,
2730     VASurfaceID surface
2731 )
2732 {
2733     DEBUG_FUNC_ENTER
2734     INIT_DRIVER_DATA
2735     VAStatus vaStatus = VA_STATUS_SUCCESS;
2736 
2737     object_surface_p obj_surface = SURFACE(surface);
2738     CHECK_SURFACE(obj_surface);
2739 
2740     psb_surface_p psb_surface = obj_surface->psb_surface;
2741 
2742     psb_buffer_unmap(&psb_surface->buf);
2743 
2744     DEBUG_FUNC_EXIT
2745     return VA_STATUS_SUCCESS;
2746 }
2747 
2748 VAStatus psb_GetEGLClientBufferFromSurface(
2749     VADriverContextP ctx,
2750     VASurfaceID surface,
2751     void **buffer
2752 )
2753 {
2754     DEBUG_FUNC_ENTER
2755     INIT_DRIVER_DATA
2756     VAStatus vaStatus = VA_STATUS_SUCCESS;
2757 
2758     object_surface_p obj_surface = SURFACE(surface);
2759     CHECK_SURFACE(obj_surface);
2760 
2761     psb_surface_p psb_surface = obj_surface->psb_surface;
2762     *buffer = (unsigned char *)psb_surface->bc_buffer;
2763 
2764     DEBUG_FUNC_EXIT
2765     return vaStatus;
2766 }
2767 
2768 VAStatus psb_PutSurfaceBuf(
2769     VADriverContextP ctx,
2770     VASurfaceID surface,
2771     unsigned char __maybe_unused * data,
2772     int __maybe_unused * data_len,
2773     short __maybe_unused srcx,
2774     short __maybe_unused srcy,
2775     unsigned short __maybe_unused srcw,
2776     unsigned short __maybe_unused srch,
2777     short __maybe_unused destx,
2778     short __maybe_unused desty,
2779     unsigned short __maybe_unused destw,
2780     unsigned short __maybe_unused desth,
2781     VARectangle __maybe_unused * cliprects, /* client supplied clip list */
2782     unsigned int __maybe_unused number_cliprects, /* number of clip rects in the clip list */
2783     unsigned int __maybe_unused flags /* de-interlacing flags */
2784 )
2785 {
2786     DEBUG_FUNC_ENTER
2787     INIT_DRIVER_DATA;
2788     object_surface_p obj_surface = SURFACE(surface);
2789     psb_surface_p psb_surface;
2790 
2791     obj_surface = SURFACE(surface);
2792     if (obj_surface == NULL)
2793         return VA_STATUS_ERROR_INVALID_SURFACE;
2794 
2795     psb_surface = obj_surface->psb_surface;
2796 
2797 #if 0
2798     psb_putsurface_textureblit(ctx, data, surface, srcx, srcy, srcw, srch, destx, desty, destw, desth, 1, /* check subpicture */
2799                                obj_surface->width, obj_surface->height,
2800                                psb_surface->stride, psb_surface->buf.drm_buf,
2801                                psb_surface->buf.pl_flags, 1 /* wrap dst */);
2802 #endif
2803 
2804     DEBUG_FUNC_EXIT
2805     return VA_STATUS_SUCCESS;
2806 }
2807 
2808 VAStatus psb_SetTimestampForSurface(
2809     VADriverContextP ctx,
2810     VASurfaceID surface,
2811     long long timestamp
2812 )
2813 {
2814     INIT_DRIVER_DATA;
2815     VAStatus vaStatus = VA_STATUS_SUCCESS;
2816     object_surface_p obj_surface = SURFACE(surface);
2817 
2818     obj_surface = SURFACE(surface);
2819     CHECK_SURFACE(obj_surface);
2820 
2821     if (obj_surface->share_info) {
2822         obj_surface->share_info->timestamp = timestamp;
2823         return VA_STATUS_SUCCESS;
2824     } else {
2825         return VA_STATUS_ERROR_UNKNOWN;
2826     }
2827 }
2828 
2829 int  LOCK_HARDWARE(psb_driver_data_p driver_data)
2830 {
2831     char ret = 0;
2832 
2833     if (driver_data->dri2 || driver_data->dri_dummy)
2834         return 0;
2835 
2836     pthread_mutex_lock(&driver_data->drm_mutex);
2837     DRM_CAS(driver_data->drm_lock, driver_data->drm_context,
2838             (DRM_LOCK_HELD | driver_data->drm_context), ret);
2839     if (ret) {
2840         ret = drmGetLock(driver_data->drm_fd, driver_data->drm_context, 0);
2841         /* driver_data->contended_lock=1; */
2842     }
2843 
2844     return ret;
2845 }
2846 
2847 int UNLOCK_HARDWARE(psb_driver_data_p driver_data)
2848 {
2849     /* driver_data->contended_lock=0; */
2850     if (driver_data->dri2 || driver_data->dri_dummy)
2851         return 0;
2852 
2853     DRM_UNLOCK(driver_data->drm_fd, driver_data->drm_lock, driver_data->drm_context);
2854     pthread_mutex_unlock(&driver_data->drm_mutex);
2855 
2856     return 0;
2857 }
2858 
2859 
2860 static void psb__deinitDRM(VADriverContextP ctx)
2861 {
2862     INIT_DRIVER_DATA
2863 
2864     if (driver_data->main_pool) {
2865         driver_data->main_pool->takeDown(driver_data->main_pool);
2866         driver_data->main_pool = NULL;
2867     }
2868     if (driver_data->fence_mgr) {
2869         wsbmFenceMgrTTMTakedown(driver_data->fence_mgr);
2870         driver_data->fence_mgr = NULL;
2871     }
2872 
2873     if (wsbmIsInitialized())
2874         wsbmTakedown();
2875 
2876     driver_data->drm_fd = -1;
2877 }
2878 
2879 
2880 static VAStatus psb__initDRI(VADriverContextP ctx)
2881 {
2882     INIT_DRIVER_DATA
2883     struct drm_state *drm_state = (struct drm_state *)ctx->drm_state;
2884 
2885     assert(dri_state);
2886 #ifdef _FOR_FPGA_
2887     dri_state->driConnectedFlag = VA_DUMMY;
2888     /* ON FPGA machine, psb may co-exist with gfx's drm driver */
2889     dri_state->fd = open("/dev/dri/card1", O_RDWR);
2890     if (dri_state->fd < 0)
2891         dri_state->fd = open("/dev/dri/card0", O_RDWR);
2892     assert(dri_state->fd >= 0);
2893 #endif
2894     assert(dri_state->driConnectedFlag == VA_DRI2 ||
2895            dri_state->driConnectedFlag == VA_DUMMY);
2896 
2897     driver_data->drm_fd = drm_state->fd;
2898     driver_data->dri_dummy = 1;
2899     driver_data->dri2 = 0;
2900     driver_data->ws_priv = NULL;
2901     driver_data->bus_id = NULL;
2902 
2903     return VA_STATUS_SUCCESS;
2904 }
2905 
2906 
2907 static VAStatus psb__initTTM(VADriverContextP ctx)
2908 {
2909     INIT_DRIVER_DATA
2910 
2911     const char drm_ext[] = "psb_ttm_placement_alphadrop";
2912     union drm_psb_extension_arg arg;
2913     struct _WsbmBufferPool *pool;
2914     int ret;
2915     const char exec_ext[] = "psb_ttm_execbuf_alphadrop";
2916     union drm_psb_extension_arg exec_arg;
2917     const char lncvideo_getparam_ext[] = "lnc_video_getparam";
2918     union drm_psb_extension_arg lncvideo_getparam_arg;
2919 
2920     /* init wsbm
2921      * WSBM node is not used in driver, thus can pass NULL Node callback
2922      */
2923     ret = wsbmInit(wsbmNullThreadFuncs(), NULL/*psbVNodeFuncs()*/);
2924     if (ret) {
2925         drv_debug_msg(VIDEO_DEBUG_ERROR, "failed initializing libwsbm.\n");
2926         return VA_STATUS_ERROR_UNKNOWN;
2927     }
2928 
2929     strncpy(arg.extension, drm_ext, sizeof(arg.extension));
2930     /* FIXME: should check dri enabled?
2931      * it seems not init dri here at all
2932      */
2933     ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION,
2934                               &arg, sizeof(arg));
2935     if (ret != 0 || !arg.rep.exists) {
2936         drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to detect DRM extension \"%s\", fd=%d\n",
2937                       drm_ext, driver_data->drm_fd);
2938         drv_debug_msg(VIDEO_DEBUG_ERROR, "found error %s (ret=%d), arg.rep.exists=%d",
2939                       strerror(errno), ret, arg.rep.exists);
2940 
2941         driver_data->main_pool = NULL;
2942         return VA_STATUS_ERROR_UNKNOWN;
2943     } else {
2944         pool = wsbmTTMPoolInit(driver_data->drm_fd,
2945                                arg.rep.driver_ioctl_offset);
2946         if (pool == NULL) {
2947             drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to get ttm pool\n");
2948             return VA_STATUS_ERROR_UNKNOWN;
2949         }
2950         driver_data->main_pool = pool;
2951     }
2952 
2953     strncpy(exec_arg.extension, exec_ext, sizeof(exec_arg.extension));
2954     ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION, &exec_arg,
2955                               sizeof(exec_arg));
2956     if (ret != 0 || !exec_arg.rep.exists) {
2957         drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to detect DRM extension \"%s\".\n",
2958                            exec_ext);
2959         return FALSE;
2960     }
2961     driver_data->execIoctlOffset = exec_arg.rep.driver_ioctl_offset;
2962 
2963     strncpy(lncvideo_getparam_arg.extension, lncvideo_getparam_ext, sizeof(lncvideo_getparam_arg.extension));
2964     ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION, &lncvideo_getparam_arg,
2965                               sizeof(lncvideo_getparam_arg));
2966     if (ret != 0 || !lncvideo_getparam_arg.rep.exists) {
2967         drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to detect DRM extension \"%s\".\n",
2968                            lncvideo_getparam_ext);
2969         /* return FALSE; */ /* not reture FALSE, so it still can run */
2970     }
2971     driver_data->getParamIoctlOffset = lncvideo_getparam_arg.rep.driver_ioctl_offset;
2972     return VA_STATUS_SUCCESS;
2973 }
2974 
2975 static VAStatus psb__initDRM(VADriverContextP ctx)
2976 {
2977     VAStatus vaStatus;
2978 
2979     vaStatus = psb__initDRI(ctx);
2980 
2981     if (vaStatus == VA_STATUS_SUCCESS)
2982         return psb__initTTM(ctx);
2983     else
2984         return vaStatus;
2985 }
2986 
2987 VAStatus psb_Terminate(VADriverContextP ctx)
2988 {
2989     DEBUG_FUNC_ENTER
2990     INIT_DRIVER_DATA
2991     object_subpic_p obj_subpic;
2992     object_image_p obj_image;
2993     object_buffer_p obj_buffer;
2994     object_surface_p obj_surface;
2995     object_context_p obj_context;
2996     object_config_p obj_config;
2997     object_heap_iterator iter;
2998 
2999     drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: begin to tear down\n");
3000 
3001     /* Clean up left over contexts */
3002     obj_context = (object_context_p) object_heap_first(&driver_data->context_heap, &iter);
3003     while (obj_context) {
3004         drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: contextID %08x still allocated, destroying\n", obj_context->base.id);
3005         psb__destroy_context(driver_data, obj_context);
3006         obj_context = (object_context_p) object_heap_next(&driver_data->context_heap, &iter);
3007     }
3008     object_heap_destroy(&driver_data->context_heap);
3009 
3010     /* Clean up SubpicIDs */
3011     obj_subpic = (object_subpic_p) object_heap_first(&driver_data->subpic_heap, &iter);
3012     while (obj_subpic) {
3013         drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: subpictureID %08x still allocated, destroying\n", obj_subpic->base.id);
3014         psb__destroy_subpicture(driver_data, obj_subpic);
3015         obj_subpic = (object_subpic_p) object_heap_next(&driver_data->subpic_heap, &iter);
3016     }
3017     object_heap_destroy(&driver_data->subpic_heap);
3018 
3019     /* Clean up ImageIDs */
3020     obj_image = (object_image_p) object_heap_first(&driver_data->image_heap, &iter);
3021     while (obj_image) {
3022         drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: imageID %08x still allocated, destroying\n", obj_image->base.id);
3023         psb__destroy_image(driver_data, obj_image);
3024         obj_image = (object_image_p) object_heap_next(&driver_data->image_heap, &iter);
3025     }
3026     object_heap_destroy(&driver_data->image_heap);
3027 
3028     /* Clean up left over buffers */
3029     obj_buffer = (object_buffer_p) object_heap_first(&driver_data->buffer_heap, &iter);
3030     while (obj_buffer) {
3031         drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: bufferID %08x still allocated, destroying\n", obj_buffer->base.id);
3032         psb__destroy_buffer(driver_data, obj_buffer);
3033         obj_buffer = (object_buffer_p) object_heap_next(&driver_data->buffer_heap, &iter);
3034     }
3035     object_heap_destroy(&driver_data->buffer_heap);
3036 
3037     /* Clean up left over surfaces */
3038 
3039 #if 0
3040     /* Free PVR2D buffer wrapped from the surfaces */
3041     psb_free_surface_pvr2dbuf(driver_data);
3042 #endif
3043     obj_surface = (object_surface_p) object_heap_first(&driver_data->surface_heap, &iter);
3044     while (obj_surface) {
3045         drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: surfaceID %08x still allocated, destroying\n", obj_surface->base.id);
3046         psb__destroy_surface(driver_data, obj_surface);
3047         obj_surface = (object_surface_p) object_heap_next(&driver_data->surface_heap, &iter);
3048     }
3049     object_heap_destroy(&driver_data->surface_heap);
3050 
3051     /* Clean up configIDs */
3052     obj_config = (object_config_p) object_heap_first(&driver_data->config_heap, &iter);
3053     while (obj_config) {
3054         object_heap_free(&driver_data->config_heap, (object_base_p) obj_config);
3055         obj_config = (object_config_p) object_heap_next(&driver_data->config_heap, &iter);
3056     }
3057     object_heap_destroy(&driver_data->config_heap);
3058 
3059     if (driver_data->camera_bo) {
3060         drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: clearup camera global BO\n");
3061 
3062         psb_buffer_destroy((psb_buffer_p)driver_data->camera_bo);
3063         free(driver_data->camera_bo);
3064         driver_data->camera_bo = NULL;
3065     }
3066 
3067     if (driver_data->rar_bo) {
3068         drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: clearup RAR global BO\n");
3069 
3070         psb_buffer_destroy((psb_buffer_p)driver_data->rar_bo);
3071         free(driver_data->rar_bo);
3072         driver_data->rar_bo = NULL;
3073     }
3074 
3075     if (driver_data->ws_priv) {
3076         drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: tear down output portion\n");
3077 
3078         psb_deinitOutput(ctx);
3079         driver_data->ws_priv = NULL;
3080     }
3081 
3082     drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: de-initialized DRM\n");
3083 
3084     psb__deinitDRM(ctx);
3085 
3086     if (driver_data->msvdx_decode_status)
3087         free(driver_data->msvdx_decode_status);
3088 
3089     if (driver_data->surface_mb_error)
3090         free(driver_data->surface_mb_error);
3091 
3092     pthread_mutex_destroy(&driver_data->drm_mutex);
3093     free(ctx->pDriverData);
3094     free(ctx->vtable_egl);
3095     free(ctx->vtable_tpi);
3096 
3097     ctx->pDriverData = NULL;
3098     drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: goodbye\n\n");
3099 
3100     psb__close_log();
3101     DEBUG_FUNC_EXIT
3102     return VA_STATUS_SUCCESS;
3103 }
3104 
3105 EXPORT VAStatus __vaDriverInit_0_31(VADriverContextP ctx)
3106 {
3107     psb_driver_data_p driver_data;
3108     struct VADriverVTableTPI *tpi;
3109     struct VADriverVTableEGL *va_egl;
3110     int result;
3111     if (psb_video_trace_fp) {
3112         /* make gdb always stop here */
3113         signal(SIGUSR1, SIG_IGN);
3114         kill(getpid(), SIGUSR1);
3115     }
3116 
3117     psb__open_log();
3118 
3119     drv_debug_msg(VIDEO_DEBUG_INIT, "vaInitilize: start the journey\n");
3120 
3121     ctx->version_major = 0;
3122     ctx->version_minor = 31;
3123 
3124     ctx->max_profiles = PSB_MAX_PROFILES;
3125     ctx->max_entrypoints = PSB_MAX_ENTRYPOINTS;
3126     ctx->max_attributes = PSB_MAX_CONFIG_ATTRIBUTES;
3127     ctx->max_image_formats = PSB_MAX_IMAGE_FORMATS;
3128     ctx->max_subpic_formats = PSB_MAX_SUBPIC_FORMATS;
3129     ctx->max_display_attributes = PSB_MAX_DISPLAY_ATTRIBUTES;
3130 
3131     ctx->vtable->vaTerminate = psb_Terminate;
3132     ctx->vtable->vaQueryConfigEntrypoints = psb_QueryConfigEntrypoints;
3133     ctx->vtable->vaTerminate = psb_Terminate;
3134     ctx->vtable->vaQueryConfigProfiles = psb_QueryConfigProfiles;
3135     ctx->vtable->vaQueryConfigEntrypoints = psb_QueryConfigEntrypoints;
3136     ctx->vtable->vaQueryConfigAttributes = psb_QueryConfigAttributes;
3137     ctx->vtable->vaCreateConfig = psb_CreateConfig;
3138     ctx->vtable->vaDestroyConfig = psb_DestroyConfig;
3139     ctx->vtable->vaGetConfigAttributes = psb_GetConfigAttributes;
3140     ctx->vtable->vaCreateSurfaces2 = psb_CreateSurfaces2;
3141     ctx->vtable->vaCreateSurfaces = psb_CreateSurfaces;
3142     ctx->vtable->vaGetSurfaceAttributes = psb_GetSurfaceAttributes;
3143     ctx->vtable->vaDestroySurfaces = psb_DestroySurfaces;
3144     ctx->vtable->vaCreateContext = psb_CreateContext;
3145     ctx->vtable->vaDestroyContext = psb_DestroyContext;
3146     ctx->vtable->vaCreateBuffer = psb_CreateBuffer;
3147     ctx->vtable->vaBufferSetNumElements = psb_BufferSetNumElements;
3148     ctx->vtable->vaMapBuffer = psb_MapBuffer;
3149     ctx->vtable->vaUnmapBuffer = psb_UnmapBuffer;
3150     ctx->vtable->vaDestroyBuffer = psb_DestroyBuffer;
3151     ctx->vtable->vaBeginPicture = psb_BeginPicture;
3152     ctx->vtable->vaRenderPicture = psb_RenderPicture;
3153     ctx->vtable->vaEndPicture = psb_EndPicture;
3154     ctx->vtable->vaSyncSurface = psb_SyncSurface;
3155     ctx->vtable->vaQuerySurfaceStatus = psb_QuerySurfaceStatus;
3156     ctx->vtable->vaQuerySurfaceError = psb_QuerySurfaceError;
3157     ctx->vtable->vaPutSurface = psb_PutSurface;
3158     ctx->vtable->vaQueryImageFormats = psb_QueryImageFormats;
3159     ctx->vtable->vaCreateImage = psb_CreateImage;
3160     ctx->vtable->vaDeriveImage = psb_DeriveImage;
3161     ctx->vtable->vaDestroyImage = psb_DestroyImage;
3162     ctx->vtable->vaSetImagePalette = psb_SetImagePalette;
3163     ctx->vtable->vaGetImage = psb_GetImage;
3164     ctx->vtable->vaPutImage = psb_PutImage;
3165     ctx->vtable->vaQuerySubpictureFormats = psb_QuerySubpictureFormats;
3166     ctx->vtable->vaCreateSubpicture = psb_CreateSubpicture;
3167     ctx->vtable->vaDestroySubpicture = psb_DestroySubpicture;
3168     ctx->vtable->vaSetSubpictureImage = psb_SetSubpictureImage;
3169     ctx->vtable->vaSetSubpictureChromakey = psb_SetSubpictureChromakey;
3170     ctx->vtable->vaSetSubpictureGlobalAlpha = psb_SetSubpictureGlobalAlpha;
3171     ctx->vtable->vaAssociateSubpicture = psb_AssociateSubpicture;
3172     ctx->vtable->vaDeassociateSubpicture = psb_DeassociateSubpicture;
3173     ctx->vtable->vaQueryDisplayAttributes = psb_QueryDisplayAttributes;
3174     ctx->vtable->vaGetDisplayAttributes = psb_GetDisplayAttributes;
3175     ctx->vtable->vaSetDisplayAttributes = psb_SetDisplayAttributes;
3176     ctx->vtable->vaQuerySurfaceAttributes = psb_QuerySurfaceAttributes;
3177     ctx->vtable->vaBufferInfo = psb_BufferInfo;
3178     ctx->vtable->vaLockSurface = psb_LockSurface;
3179     ctx->vtable->vaUnlockSurface = psb_UnlockSurface;
3180 #ifdef PSBVIDEO_MRFL_VPP
3181     ctx->vtable_vpp->vaQueryVideoProcFilters = vsp_QueryVideoProcFilters;
3182     ctx->vtable_vpp->vaQueryVideoProcFilterCaps = vsp_QueryVideoProcFilterCaps;
3183     ctx->vtable_vpp->vaQueryVideoProcPipelineCaps = vsp_QueryVideoProcPipelineCaps;
3184 #endif
3185 
3186 #ifdef PSBVIDEO_MFLD
3187     ctx->vtable_vpp->vaQueryVideoProcFilters = ved_QueryVideoProcFilters;
3188     ctx->vtable_vpp->vaQueryVideoProcFilterCaps = ved_QueryVideoProcFilterCaps;
3189     ctx->vtable_vpp->vaQueryVideoProcPipelineCaps = ved_QueryVideoProcPipelineCaps;
3190 #endif
3191 
3192     ctx->vtable_tpi = calloc(1, sizeof(struct VADriverVTableTPI));
3193     if (NULL == ctx->vtable_tpi)
3194         return VA_STATUS_ERROR_ALLOCATION_FAILED;
3195 
3196     tpi = (struct VADriverVTableTPI *)ctx->vtable_tpi;
3197     tpi->vaCreateSurfacesWithAttribute = psb_CreateSurfacesWithAttribute;
3198     tpi->vaPutSurfaceBuf = psb_PutSurfaceBuf;
3199 	tpi->vaSetTimestampForSurface = psb_SetTimestampForSurface;
3200 
3201     ctx->vtable_egl = calloc(1, sizeof(struct VADriverVTableEGL));
3202     if (NULL == ctx->vtable_egl)
3203         return VA_STATUS_ERROR_ALLOCATION_FAILED;
3204 
3205     va_egl = (struct VADriverVTableEGL *)ctx->vtable_egl;
3206     va_egl->vaGetEGLClientBufferFromSurface = psb_GetEGLClientBufferFromSurface;
3207 
3208     driver_data = (psb_driver_data_p) calloc(1, sizeof(*driver_data));
3209     ctx->pDriverData = (unsigned char *) driver_data;
3210     if (NULL == driver_data) {
3211         if (ctx->vtable_tpi)
3212             free(ctx->vtable_tpi);
3213         if (ctx->vtable_egl)
3214             free(ctx->vtable_egl);
3215         return VA_STATUS_ERROR_ALLOCATION_FAILED;
3216     }
3217 
3218     if (VA_STATUS_SUCCESS != psb__initDRM(ctx)) {
3219         free(ctx->pDriverData);
3220         ctx->pDriverData = NULL;
3221         return VA_STATUS_ERROR_UNKNOWN;
3222     }
3223 
3224     pthread_mutex_init(&driver_data->drm_mutex, NULL);
3225 
3226     /*
3227      * To read PBO.MSR.CCF Mode and Status Register C-Spec -p112
3228      */
3229 #define PCI_PORT5_REG80_VIDEO_SD_DISABLE        0x0008
3230 #define PCI_PORT5_REG80_VIDEO_HD_DISABLE        0x0010
3231 
3232 #if 0
3233     struct drm_psb_hw_info hw_info;
3234     do {
3235         result = drmCommandRead(driver_data->drm_fd, DRM_PSB_HW_INFO, &hw_info, sizeof(hw_info));
3236     } while (result == EAGAIN);
3237 
3238     if (result != 0) {
3239         psb__deinitDRM(ctx);
3240         free(ctx->pDriverData);
3241         ctx->pDriverData = NULL;
3242         return VA_STATUS_ERROR_UNKNOWN;
3243     }
3244 
3245     driver_data->video_sd_disabled = !!(hw_info.caps & PCI_PORT5_REG80_VIDEO_SD_DISABLE);
3246     driver_data->video_hd_disabled = !!(hw_info.caps & PCI_PORT5_REG80_VIDEO_HD_DISABLE);
3247     drv_debug_msg(VIDEO_DEBUG_GENERAL, "hw_info: rev_id = %08x capabilities = %08x\n", hw_info.rev_id, hw_info.caps);
3248     drv_debug_msg(VIDEO_DEBUG_GENERAL, "hw_info: video_sd_disable=%d,video_hd_disable=%d\n",
3249                              driver_data->video_sd_disabled, driver_data->video_hd_disabled);
3250     if (driver_data->video_sd_disabled != 0) {
3251         drv_debug_msg(VIDEO_DEBUG_ERROR, "MRST: hw_info shows video_sd_disable is true,fix it manually\n");
3252         driver_data->video_sd_disabled = 0;
3253     }
3254     if (driver_data->video_hd_disabled != 0) {
3255         drv_debug_msg(VIDEO_DEBUG_ERROR, "MRST: hw_info shows video_hd_disable is true,fix it manually\n");
3256         driver_data->video_hd_disabled = 0;
3257     }
3258 #endif
3259 
3260     if (0 != psb_get_device_info(ctx)) {
3261         drv_debug_msg(VIDEO_DEBUG_ERROR, "ERROR: failed to get video device info\n");
3262         driver_data->encode_supported = 1;
3263         driver_data->decode_supported = 1;
3264         driver_data->hd_encode_supported = 1;
3265         driver_data->hd_decode_supported = 1;
3266     }
3267 
3268 #if 0
3269     psb_init_surface_pvr2dbuf(driver_data);
3270 #endif
3271 
3272     if (VA_STATUS_SUCCESS != psb_initOutput(ctx)) {
3273         pthread_mutex_destroy(&driver_data->drm_mutex);
3274         psb__deinitDRM(ctx);
3275         free(ctx->pDriverData);
3276         ctx->pDriverData = NULL;
3277         return VA_STATUS_ERROR_UNKNOWN;
3278     }
3279 
3280     driver_data->msvdx_context_base = (((unsigned int) getpid()) & 0xffff) << 16;
3281 #ifdef PSBVIDEO_MRFL
3282     if (IS_MRFL(driver_data)) {
3283         drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield topazhp encoder\n");
3284         driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3285         driver_data->profile2Format[VAProfileH264Main][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3286         driver_data->profile2Format[VAProfileH264High][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3287         driver_data->profile2Format[VAProfileH264StereoHigh][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3288         driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointEncSlice] = &tng_H263ES_vtable;
3289         driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointEncPicture] = &tng_JPEGES_vtable;
3290         driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointEncSlice] = &tng_MPEG4ES_vtable;
3291         driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointEncSlice] = &tng_MPEG4ES_vtable;
3292         driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3293     }
3294 #endif
3295 #ifdef PSBVIDEO_MRFL_VPP
3296     if (IS_MRFL(driver_data)) {
3297         drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield vsp vpp\n");
3298         driver_data->vpp_profile = &vsp_VPP_vtable;
3299         driver_data->profile2Format[VAProfileVP8Version0_3][VAEntrypointEncSlice] = &vsp_VP8_vtable;
3300     }
3301 #endif
3302 
3303 #ifdef PSBVIDEO_VXD392
3304     if (IS_MRFL(driver_data) || IS_BAYTRAIL(driver_data)) {
3305         drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield VXD392 decoder\n");
3306 	driver_data->profile2Format[VAProfileVP8Version0_3][VAEntrypointVLD] = &tng_VP8_vtable;
3307         driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointVLD] = &tng_JPEG_vtable;
3308 
3309         driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3310         driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3311 
3312         driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3313 
3314         driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointVLD] = &pnw_H264_vtable;
3315         driver_data->profile2Format[VAProfileH264Main][VAEntrypointVLD] = &pnw_H264_vtable;
3316         driver_data->profile2Format[VAProfileH264High][VAEntrypointVLD] = &pnw_H264_vtable;
3317 
3318         driver_data->profile2Format[VAProfileVC1Simple][VAEntrypointVLD] = &pnw_VC1_vtable;
3319         driver_data->profile2Format[VAProfileVC1Main][VAEntrypointVLD] = &pnw_VC1_vtable;
3320         driver_data->profile2Format[VAProfileVC1Advanced][VAEntrypointVLD] = &pnw_VC1_vtable;
3321         driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointVLD] = &pnw_H264_vtable;
3322     }
3323 #endif
3324 
3325 #ifdef PSBVIDEO_MRFL_VPP
3326     if (IS_MRFL(driver_data)) {
3327         if (*((unsigned int *)ctx->native_dpy) == 0x56454450 /* VEDP */) {
3328 
3329             drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield ved vpp\n");
3330             driver_data->vpp_profile = &tng_yuv_processor_vtable;
3331             ctx->vtable_vpp->vaQueryVideoProcFilters = ved_QueryVideoProcFilters;
3332             ctx->vtable_vpp->vaQueryVideoProcFilterCaps = ved_QueryVideoProcFilterCaps;
3333             ctx->vtable_vpp->vaQueryVideoProcPipelineCaps = ved_QueryVideoProcPipelineCaps;
3334             driver_data->ved_vpp = 1;
3335         }
3336     }
3337 #endif
3338 
3339 #ifdef PSBVIDEO_MFLD
3340     if (IS_MFLD(driver_data)) {
3341         driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointEncSlice] = &pnw_H263ES_vtable;
3342         driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointEncSlice] = &pnw_H264ES_vtable;
3343         driver_data->profile2Format[VAProfileH264Main][VAEntrypointEncSlice] = &pnw_H264ES_vtable;
3344         driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointEncSlice] = &pnw_MPEG4ES_vtable;
3345         driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointEncSlice] = &pnw_MPEG4ES_vtable;
3346         driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointEncPicture] = &pnw_JPEG_vtable;
3347 
3348         driver_data->profile2Format[VAProfileMPEG2Main][VAEntrypointVLD] = &pnw_MPEG2_vtable;
3349 
3350         driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3351         driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3352 
3353         driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3354 
3355         driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointVLD] = &pnw_H264_vtable;
3356         driver_data->profile2Format[VAProfileH264Main][VAEntrypointVLD] = &pnw_H264_vtable;
3357         driver_data->profile2Format[VAProfileH264High][VAEntrypointVLD] = &pnw_H264_vtable;
3358 
3359         driver_data->profile2Format[VAProfileVC1Simple][VAEntrypointVLD] = &pnw_VC1_vtable;
3360         driver_data->profile2Format[VAProfileVC1Main][VAEntrypointVLD] = &pnw_VC1_vtable;
3361         driver_data->profile2Format[VAProfileVC1Advanced][VAEntrypointVLD] = &pnw_VC1_vtable;
3362         driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointVLD] = &pnw_H264_vtable;
3363 
3364         driver_data->vpp_profile = &tng_yuv_processor_vtable;
3365         driver_data->ved_vpp = 1;
3366     }
3367 #endif
3368 
3369     result = object_heap_init(&driver_data->config_heap, sizeof(struct object_config_s), CONFIG_ID_OFFSET);
3370     ASSERT(result == 0);
3371 
3372     result = object_heap_init(&driver_data->context_heap, sizeof(struct object_context_s), CONTEXT_ID_OFFSET);
3373     ASSERT(result == 0);
3374 
3375     result = object_heap_init(&driver_data->surface_heap, sizeof(struct object_surface_s), SURFACE_ID_OFFSET);
3376     ASSERT(result == 0);
3377 
3378     result = object_heap_init(&driver_data->buffer_heap, sizeof(struct object_buffer_s), BUFFER_ID_OFFSET);
3379     ASSERT(result == 0);
3380 
3381     result = object_heap_init(&driver_data->image_heap, sizeof(struct object_image_s), IMAGE_ID_OFFSET);
3382     ASSERT(result == 0);
3383 
3384     result = object_heap_init(&driver_data->subpic_heap, sizeof(struct object_subpic_s), SUBPIC_ID_OFFSET);
3385     ASSERT(result == 0);
3386 
3387     driver_data->cur_displaying_surface = VA_INVALID_SURFACE;
3388     driver_data->last_displaying_surface = VA_INVALID_SURFACE;
3389 
3390     driver_data->clear_color = 0;
3391     driver_data->blend_color = 0;
3392     driver_data->blend_mode = 0;
3393     driver_data->overlay_auto_paint_color_key = 0;
3394 
3395     if (IS_BAYTRAIL(driver_data))
3396         ctx->str_vendor = PSB_STR_VENDOR_BAYTRAIL;
3397     if (IS_MRFL(driver_data))
3398         ctx->str_vendor = PSB_STR_VENDOR_MRFL;
3399     else if (IS_MFLD(driver_data))
3400     {
3401         if (IS_LEXINGTON(driver_data))
3402             ctx->str_vendor = PSB_STR_VENDOR_LEXINGTON;
3403         else
3404             ctx->str_vendor = PSB_STR_VENDOR_MFLD;
3405     }
3406     else
3407         ctx->str_vendor = PSB_STR_VENDOR_MRST;
3408 
3409     driver_data->msvdx_decode_status = calloc(1, sizeof(drm_psb_msvdx_decode_status_t));
3410     if (NULL == driver_data->msvdx_decode_status) {
3411         pthread_mutex_destroy(&driver_data->drm_mutex);
3412         return VA_STATUS_ERROR_ALLOCATION_FAILED;
3413     }
3414     driver_data->surface_mb_error = calloc(MAX_MB_ERRORS, sizeof(VASurfaceDecodeMBErrors));
3415     if (NULL == driver_data->surface_mb_error) {
3416         pthread_mutex_destroy(&driver_data->drm_mutex);
3417         return VA_STATUS_ERROR_ALLOCATION_FAILED;
3418     }
3419 
3420     drv_debug_msg(VIDEO_DEBUG_INIT, "vaInitilize: succeeded!\n\n");
3421 
3422 #ifdef ANDROID
3423 #ifndef PSBVIDEO_VXD392
3424     gralloc_init();
3425 #endif
3426 #endif
3427 
3428     return VA_STATUS_SUCCESS;
3429 }
3430 
3431 
3432 EXPORT VAStatus __vaDriverInit_0_32(VADriverContextP ctx)
3433 {
3434     return __vaDriverInit_0_31(ctx);
3435 }
3436 
3437 
3438 
3439 static int psb_get_device_info(VADriverContextP ctx)
3440 {
3441     INIT_DRIVER_DATA;
3442     struct drm_lnc_video_getparam_arg arg;
3443     unsigned long device_info;
3444     int ret = 0;
3445     unsigned long video_capability;
3446     unsigned long pci_device;
3447 
3448     driver_data->dev_id = 0x4100; /* by default MRST */
3449 
3450     arg.key = LNC_VIDEO_DEVICE_INFO;
3451     arg.value = (uint64_t)((unsigned long) & device_info);
3452     ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
3453                               &arg, sizeof(arg));
3454     if (ret != 0) {
3455         drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to get video device info\n");
3456         return ret;
3457     }
3458 
3459     pci_device = (device_info >> 16) & 0xffff;
3460     video_capability = device_info & 0xffff;
3461 
3462     driver_data->dev_id = pci_device;
3463     drv_debug_msg(VIDEO_DEBUG_INIT, "Retrieve Device ID 0x%08x\n", driver_data->dev_id);
3464 
3465     if (IS_MFLD(driver_data) || IS_MRFL(driver_data))
3466         driver_data->encode_supported = 1;
3467     else /* 0x4101 or other device hasn't encode support */
3468         driver_data->encode_supported = 0;
3469 
3470     driver_data->decode_supported = 1;
3471     driver_data->hd_decode_supported = 1;
3472     driver_data->hd_encode_supported = 1;
3473 
3474     return ret;
3475 }
3476