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     unsigned int initalized_info_flag = 1;
705     VASurfaceAttribExternalBuffers  *pExternalBufDesc = NULL;
706     PsbSurfaceAttributeTPI attribute_tpi;
707 
708     CHECK_INVALID_PARAM(num_surfaces <= 0);
709     CHECK_SURFACE(surface_list);
710 
711     if ((attrib_list != NULL) && (num_attribs > 0)) {
712         for (i = 0; i < num_attribs; i++, attrib_list++) {
713             if (!attrib_list)
714                 return VA_STATUS_ERROR_INVALID_PARAMETER;
715             switch (attrib_list->type) {
716             case VASurfaceAttribExternalBufferDescriptor:
717                 {
718                     pExternalBufDesc = (VASurfaceAttribExternalBuffers *)attrib_list->value.value.p;
719                     if (pExternalBufDesc == NULL) {
720                         drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid VASurfaceAttribExternalBuffers.\n");
721                         return VA_STATUS_ERROR_INVALID_PARAMETER;
722                     }
723                     attribute_tpi.type = memory_type;
724                     attribute_tpi.buffers = malloc(sizeof(long) * pExternalBufDesc->num_buffers);
725                     attribute_tpi.width = pExternalBufDesc->width;
726                     attribute_tpi.height = pExternalBufDesc->height;
727                     attribute_tpi.count = pExternalBufDesc->num_buffers;
728                     memcpy((void*)attribute_tpi.buffers, (void*)pExternalBufDesc->buffers,
729                             sizeof(pExternalBufDesc->buffers[0]) *
730                             pExternalBufDesc->num_buffers);
731                     attribute_tpi.pixel_format = pExternalBufDesc->pixel_format;
732                     attribute_tpi.size = pExternalBufDesc->data_size;
733                     attribute_tpi.luma_stride = pExternalBufDesc->pitches[0];
734                     attribute_tpi.chroma_u_stride = pExternalBufDesc->pitches[1];
735                     attribute_tpi.chroma_v_stride = pExternalBufDesc->pitches[2];
736                     attribute_tpi.luma_offset = pExternalBufDesc->offsets[0];
737                     attribute_tpi.chroma_u_offset = pExternalBufDesc->offsets[1];
738                     attribute_tpi.chroma_v_offset = pExternalBufDesc->offsets[2];
739                     attribute_tpi.reserved[0] = (unsigned long) pExternalBufDesc->private_data;
740                     if (pExternalBufDesc->flags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING)
741                         attribute_tpi.tiling = 1;
742                     else
743                         attribute_tpi.tiling = 0;
744                 }
745                 break;
746             case VASurfaceAttribMemoryType:
747                 {
748                     switch (attrib_list->value.value.i) {
749                         case VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR:
750                             memory_type = VAExternalMemoryUserPointer;
751                             break;
752                         case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM:
753                             memory_type = VAExternalMemoryKernelDRMBufffer;
754                             break;
755                         case VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC:
756                             memory_type = VAExternalMemoryAndroidGrallocBuffer;
757                             break;
758                         case VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION:
759                             memory_type = VAExternalMemoryIONSharedFD;
760                             break;
761                         case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
762                             memory_type = VAExternalMemoryNULL;
763                             break;
764                         default:
765                             drv_debug_msg(VIDEO_DEBUG_ERROR, "Unsupported memory type.\n");
766                             return VA_STATUS_ERROR_INVALID_PARAMETER;
767 
768                     }
769                 }
770                 break;
771             case VASurfaceAttribUsageHint:
772                 {
773                     /* Share info is to be initialized when created sufaces by default (for the data producer)
774                      * VPP Read indicate we do not NOT touch share info (for data consumer, which share buffer with data
775                      * producer, such as of VPP).
776                      */
777                     drv_debug_msg(VIDEO_DEBUG_GENERAL, "VASurfaceAttribUsageHint.\n");
778                     if ((attrib_list->value.value.i & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_READ)!= 0){
779                         initalized_info_flag = 0;
780                         drv_debug_msg(VIDEO_DEBUG_GENERAL, "explicat not initialized share info.\n");
781                     }
782                 }
783                 break;
784             default:
785                 drv_debug_msg(VIDEO_DEBUG_ERROR, "Unsupported attribute.\n");
786                 return VA_STATUS_ERROR_INVALID_PARAMETER;
787             }
788         }
789     }
790 
791     if ((memory_type == -1 && pExternalBufDesc != NULL) ||
792             (memory_type != -1 && pExternalBufDesc == NULL)) {
793         return VA_STATUS_ERROR_INVALID_PARAMETER;
794     }
795     else if(memory_type !=-1 && pExternalBufDesc != NULL) {
796         attribute_tpi.type = memory_type;
797         //set initialized share info in reserverd 1, by default we will initialized share_info
798         attribute_tpi.reserved[2] = (unsigned int)initalized_info_flag;
799         vaStatus = psb_CreateSurfacesWithAttribute(ctx, width, height, format, num_surfaces, surface_list, (VASurfaceAttributeTPI *)&attribute_tpi);
800         pExternalBufDesc->private_data = (void *)(attribute_tpi.reserved[1]);
801         if (attribute_tpi.buffers) free(attribute_tpi.buffers);
802         return vaStatus;
803     }
804 
805     format = format & (~VA_RT_FORMAT_PROTECTED);
806 
807     /* We only support one format */
808     if ((VA_RT_FORMAT_YUV420 != format)
809         && (VA_RT_FORMAT_YUV422 != format)
810         && (VA_RT_FORMAT_YUV444 != format)) {
811         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
812         DEBUG_FAILURE;
813         return vaStatus;
814     }
815 
816     vaStatus = psb__checkSurfaceDimensions(driver_data, width, height);
817     CHECK_VASTATUS();
818 
819     /* Adjust height to be a multiple of 32 (height of macroblock in interlaced mode) */
820     height_origin = height;
821     height = (height + 0x1f) & ~0x1f;
822 
823 
824     for (i = 0; i < num_surfaces; i++) {
825         int surfaceID;
826         object_surface_p obj_surface;
827         psb_surface_p psb_surface;
828 
829         surfaceID = object_heap_allocate(&driver_data->surface_heap);
830         obj_surface = SURFACE(surfaceID);
831         if (NULL == obj_surface) {
832             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
833             DEBUG_FAILURE;
834             break;
835         }
836         MEMSET_OBJECT(obj_surface, struct object_surface_s);
837 
838         obj_surface->surface_id = surfaceID;
839         surface_list[i] = surfaceID;
840         obj_surface->context_id = -1;
841         obj_surface->width = width;
842         obj_surface->height = height;
843         obj_surface->width_r = width;
844         obj_surface->height_r = height;
845         obj_surface->height_origin = height_origin;
846         obj_surface->share_info = NULL;
847 
848         psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s));
849         if (NULL == psb_surface) {
850             object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
851             obj_surface->surface_id = VA_INVALID_SURFACE;
852             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
853             DEBUG_FAILURE;
854             break;
855         }
856 
857         switch (format) {
858         case VA_RT_FORMAT_YUV444:
859             fourcc = VA_FOURCC_YV32; /* allocate 4 planar */
860             break;
861         case VA_RT_FORMAT_YUV422:
862             fourcc = VA_FOURCC_YV16;
863             break;
864         case VA_RT_FORMAT_YUV420:
865         default:
866             fourcc = VA_FOURCC_NV12;
867             break;
868         }
869 
870         flags |= driver_data->protected ? IS_PROTECTED : 0;
871         vaStatus = psb_surface_create(driver_data, width, height, fourcc,
872                                       flags, psb_surface);
873 
874         if (VA_STATUS_SUCCESS != vaStatus) {
875             free(psb_surface);
876             object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
877             obj_surface->surface_id = VA_INVALID_SURFACE;
878             DEBUG_FAILURE;
879             break;
880         }
881         buffer_stride = psb_surface->stride;
882         /* by default, surface fourcc is NV12 */
883         psb_surface->extra_info[4] = fourcc;
884         psb_surface->extra_info[8] = fourcc;
885         obj_surface->psb_surface = psb_surface;
886     }
887 
888     /* Error recovery */
889     if (VA_STATUS_SUCCESS != vaStatus) {
890         /* surface_list[i-1] was the last successful allocation */
891         for (; i--;) {
892             object_surface_p obj_surface = SURFACE(surface_list[i]);
893             psb__destroy_surface(driver_data, obj_surface);
894             surface_list[i] = VA_INVALID_SURFACE;
895         }
896         drv_debug_msg(VIDEO_DEBUG_ERROR, "CreateSurfaces failed\n");
897         return vaStatus;
898     }
899     DEBUG_FUNC_EXIT
900     return vaStatus;
901 }
902 
psb_DestroySurfaces(VADriverContextP ctx,VASurfaceID * surface_list,int num_surfaces)903 VAStatus psb_DestroySurfaces(
904     VADriverContextP ctx,
905     VASurfaceID *surface_list,
906     int num_surfaces
907 )
908 {
909     INIT_DRIVER_DATA
910     int i;
911     VAStatus vaStatus = VA_STATUS_SUCCESS;
912 
913     if (num_surfaces <= 0) {
914         return VA_STATUS_ERROR_INVALID_PARAMETER;
915     }
916 
917     CHECK_SURFACE(surface_list);
918 
919 #if 0
920     /* Free PVR2D buffer wrapped from the surfaces */
921     psb_free_surface_pvr2dbuf(driver_data);
922 #endif
923 
924     /* Make validation happy */
925     for (i = 0; i < num_surfaces; i++) {
926         object_surface_p obj_surface = SURFACE(surface_list[i]);
927         if (obj_surface == NULL) {
928             return VA_STATUS_ERROR_INVALID_SURFACE;
929         }
930         if (obj_surface->derived_imgcnt > 0) {
931             drv_debug_msg(VIDEO_DEBUG_ERROR, "Some surface is deriving by images\n");
932             return VA_STATUS_ERROR_OPERATION_FAILED;
933         }
934     }
935 
936     for (i = 0; i < num_surfaces; i++) {
937         object_surface_p obj_surface = SURFACE(surface_list[i]);
938         if (obj_surface == NULL)
939             return VA_STATUS_ERROR_INVALID_SURFACE;
940 
941         if (driver_data->cur_displaying_surface == surface_list[i]) {
942             /* Surface is being displaying. Need to stop overlay here */
943             psb_coverlay_stop(ctx);
944         }
945         drv_debug_msg(VIDEO_DEBUG_INIT, "%s : obj_surface->surface_id = 0x%x\n",__FUNCTION__, obj_surface->surface_id);
946         if (obj_surface->share_info) {
947             psb_DestroySurfaceGralloc(obj_surface);
948         }
949         psb__destroy_surface(driver_data, obj_surface);
950         surface_list[i] = VA_INVALID_SURFACE;
951     }
952 
953     DEBUG_FUNC_EXIT
954     return VA_STATUS_SUCCESS;
955 }
956 
psb_new_context(psb_driver_data_p driver_data,uint64_t ctx_type)957 int psb_new_context(psb_driver_data_p driver_data, uint64_t ctx_type)
958 {
959     struct drm_lnc_video_getparam_arg arg;
960     int ret = 0;
961 
962     arg.key = IMG_VIDEO_NEW_CONTEXT;
963     arg.value = (uint64_t)((unsigned long) & ctx_type);
964     ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
965                               &arg, sizeof(arg));
966     if (ret != 0)
967         drv_debug_msg(VIDEO_DEBUG_ERROR, "Set context %d failed\n", ctx_type);
968 
969     return ret;
970 }
971 
972 #ifdef PSBVIDEO_MSVDX_DEC_TILING
psb_update_context(psb_driver_data_p driver_data,unsigned long ctx_type)973 int psb_update_context(psb_driver_data_p driver_data, unsigned long ctx_type)
974 {
975     struct drm_lnc_video_getparam_arg arg;
976     int ret = 0;
977 
978     arg.key = IMG_VIDEO_UPDATE_CONTEXT;
979     arg.value = (uint64_t)((unsigned long) & ctx_type);
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, "Update context %d failed\n", ctx_type);
984 
985     return ret;
986 }
987 #endif
988 
psb_rm_context(psb_driver_data_p driver_data)989 int psb_rm_context(psb_driver_data_p driver_data)
990 {
991     struct drm_lnc_video_getparam_arg arg;
992     int tmp;
993     int ret = 0;
994 
995     arg.key = IMG_VIDEO_RM_CONTEXT;
996     arg.value = (uint64_t)((unsigned long) & tmp); /* value is ignored */
997     ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
998                               &arg, sizeof(arg));
999     if (ret != 0)
1000         drv_debug_msg(VIDEO_DEBUG_ERROR, "Remove context failed\n");
1001 
1002     return ret;
1003 }
1004 
1005 #ifdef PSBVIDEO_MSVDX_DEC_TILING
psb__tile_stride_log2_256(int w)1006 unsigned long psb__tile_stride_log2_256(int w)
1007 {
1008     int stride_mode = 0;
1009 
1010     if (512 >= w)
1011         stride_mode = 1;
1012     else if (1024 >= w)
1013         stride_mode = 2;
1014     else if (2048 >= w)
1015         stride_mode = 3;
1016     else if (4096 >= w)
1017         stride_mode = 4;
1018 
1019     return stride_mode;
1020 }
1021 
psb__tile_stride_log2_512(int w)1022 unsigned long psb__tile_stride_log2_512(int w)
1023 {
1024     int stride_mode = 0;
1025 
1026     if (512 >= w)
1027         stride_mode = 0;
1028     else if (1024 >= w)
1029         stride_mode = 1;
1030     else if (2048 >= w)
1031         stride_mode = 2;
1032     else if (4096 >= w)
1033         stride_mode = 3;
1034 
1035     return stride_mode;
1036 }
1037 #endif
1038 
psb_CreateContext(VADriverContextP ctx,VAConfigID config_id,int picture_width,int picture_height,int flag,VASurfaceID * render_targets,int num_render_targets,VAContextID * context)1039 VAStatus psb_CreateContext(
1040     VADriverContextP ctx,
1041     VAConfigID config_id,
1042     int picture_width,
1043     int picture_height,
1044     int flag,
1045     VASurfaceID *render_targets,
1046     int num_render_targets,
1047     VAContextID *context        /* out */
1048 )
1049 {
1050     DEBUG_FUNC_ENTER
1051     INIT_DRIVER_DATA
1052     VAStatus vaStatus = VA_STATUS_SUCCESS;
1053     object_config_p obj_config;
1054     int cmdbuf_num, encode = 0, proc = 0;
1055     int i;
1056     drv_debug_msg(VIDEO_DEBUG_ERROR, "CreateContext config_id:%d, pic_w:%d, pic_h:%d, flag:%d, num_render_targets:%d.\n",
1057         config_id, picture_width, picture_height, flag, num_render_targets);
1058 
1059     //CHECK_INVALID_PARAM(num_render_targets <= 0);
1060 
1061     //CHECK_SURFACE(render_targets);
1062     CHECK_CONTEXT(context);
1063 
1064     vaStatus = psb__checkSurfaceDimensions(driver_data, picture_width, picture_height);
1065     CHECK_VASTATUS();
1066 
1067     obj_config = CONFIG(config_id);
1068     CHECK_CONFIG(obj_config);
1069 
1070     int contextID = object_heap_allocate(&driver_data->context_heap);
1071     object_context_p obj_context = CONTEXT(contextID);
1072     CHECK_ALLOCATION(obj_context);
1073 
1074     *context = contextID;
1075 
1076     MEMSET_OBJECT(obj_context, struct object_context_s);
1077 
1078     obj_context->driver_data = driver_data;
1079     obj_context->current_render_target = NULL;
1080     obj_context->ec_target = NULL;
1081     obj_context->ec_candidate = NULL;
1082     obj_context->is_oold = driver_data->is_oold;
1083     obj_context->context_id = contextID;
1084     obj_context->config_id = config_id;
1085     obj_context->picture_width = picture_width;
1086     obj_context->picture_height = picture_height;
1087     obj_context->num_render_targets = num_render_targets;
1088     obj_context->msvdx_scaling = 0;
1089 #ifdef SLICE_HEADER_PARSING
1090     obj_context->msvdx_frame_end = 0;
1091     for (i = 0; i < obj_config->attrib_count; i++) {
1092         if ((obj_config->attrib_list[i].type == VAConfigAttribDecSliceMode) &&
1093             (obj_config->attrib_list[i].value == VA_DEC_SLICE_MODE_SUBSAMPLE)) {
1094             obj_context->modular_drm = 1;
1095             break;
1096         }
1097     }
1098 #endif
1099     obj_context->scaling_width = 0;
1100     obj_context->scaling_height = 0;
1101 
1102     if (num_render_targets > 0) {
1103         obj_context->render_targets = (VASurfaceID *) calloc(1, num_render_targets * sizeof(VASurfaceID));
1104         if (obj_context->render_targets == NULL) {
1105             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1106             DEBUG_FAILURE;
1107 
1108             object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1109 
1110             return vaStatus;
1111         }
1112     }
1113 
1114     /* allocate buffer points for vaRenderPicture */
1115     obj_context->num_buffers = 10;
1116     obj_context->buffer_list = (object_buffer_p *) calloc(1, sizeof(object_buffer_p) * obj_context->num_buffers);
1117     if (obj_context->buffer_list == NULL) {
1118         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1119         DEBUG_FAILURE;
1120 
1121         if (NULL != obj_context->render_targets)
1122             free(obj_context->render_targets);
1123         object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1124 
1125         return vaStatus;
1126     }
1127 
1128     memset(obj_context->buffers_unused, 0, sizeof(obj_context->buffers_unused));
1129     memset(obj_context->buffers_unused_count, 0, sizeof(obj_context->buffers_unused_count));
1130     memset(obj_context->buffers_unused_tail, 0, sizeof(obj_context->buffers_unused_tail));
1131     memset(obj_context->buffers_active, 0, sizeof(obj_context->buffers_active));
1132 
1133     if (obj_config->entrypoint == VAEntrypointEncSlice
1134         || obj_config->entrypoint == VAEntrypointEncPicture) {
1135         encode = 1;
1136     }
1137 #ifdef PSBVIDEO_MRFL_VPP
1138     if (obj_config->entrypoint == VAEntrypointVideoProc)
1139         proc = 1;
1140 
1141     //todo: fixme
1142     if (obj_config->entrypoint == VAEntrypointEncSlice && obj_config->profile == VAProfileVP8Version0_3){
1143             proc = 1;
1144             encode = 0;
1145     }
1146 #endif
1147 
1148     if (encode)
1149         cmdbuf_num = LNC_MAX_CMDBUFS_ENCODE;
1150     else if (proc)
1151         cmdbuf_num = VSP_MAX_CMDBUFS;
1152     else
1153         cmdbuf_num = PSB_MAX_CMDBUFS;
1154 
1155     if (num_render_targets > 0) {
1156         for (i = 0; i < num_render_targets; i++) {
1157             object_surface_p obj_surface = SURFACE(render_targets[i]);
1158             psb_surface_p psb_surface;
1159 
1160             if (NULL == obj_surface) {
1161                 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
1162                 DEBUG_FAILURE;
1163                 break;
1164             }
1165 
1166             if (!driver_data->protected && obj_surface->share_info)
1167                 obj_surface->share_info->force_output_method = 0;
1168 
1169             psb_surface = obj_surface->psb_surface;
1170 
1171             /* Clear format specific surface info */
1172             obj_context->render_targets[i] = render_targets[i];
1173             obj_surface->context_id = contextID; /* Claim ownership of surface */
1174 #ifdef PSBVIDEO_MSVDX_DEC_TILING
1175             if (GET_SURFACE_INFO_tiling(psb_surface))
1176 #ifdef BAYTRAIL
1177                 obj_context->msvdx_tile = psb__tile_stride_log2_512(obj_surface->width);
1178 #else
1179             if (obj_config->entrypoint == VAEntrypointVideoProc && obj_config->profile == VAProfileNone)
1180                 // It's for two pass rotation case
1181                 // Need the source surface width for tile stride setting
1182                 obj_context->msvdx_tile = psb__tile_stride_log2_256(obj_context->picture_width);
1183             else
1184                 obj_context->msvdx_tile = psb__tile_stride_log2_256(obj_surface->width);
1185 #endif
1186         else {
1187             ;
1188         }
1189 #endif
1190 #if 0
1191             /* for decode, move the surface into |TT */
1192             if ((encode == 0) && /* decode */
1193                     ((psb_surface->buf.pl_flags & DRM_PSB_FLAG_MEM_RAR) == 0)) /* surface not in RAR */
1194                 psb_buffer_setstatus(&obj_surface->psb_surface->buf,
1195                         WSBM_PL_FLAG_TT | WSBM_PL_FLAG_SHARED, DRM_PSB_FLAG_MEM_MMU);
1196 #endif
1197         }
1198     }
1199 
1200     obj_context->va_flags = flag;
1201     obj_context->format_vtable = obj_config->format_vtable;
1202     obj_context->format_data = NULL;
1203 
1204     if (VA_STATUS_SUCCESS == vaStatus) {
1205         vaStatus = obj_context->format_vtable->createContext(obj_context, obj_config);
1206     }
1207 
1208     /* Error recovery */
1209     if (VA_STATUS_SUCCESS != vaStatus) {
1210         obj_context->context_id = -1;
1211         obj_context->config_id = -1;
1212         obj_context->picture_width = 0;
1213         obj_context->picture_height = 0;
1214         if (NULL != obj_context->render_targets)
1215             free(obj_context->render_targets);
1216         free(obj_context->buffer_list);
1217         obj_context->num_buffers = 0;
1218         obj_context->render_targets = NULL;
1219         obj_context->num_render_targets = 0;
1220         obj_context->va_flags = 0;
1221         object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1222 
1223         return vaStatus;
1224     }
1225 
1226     /* initialize cmdbuf */
1227     for (i = 0; i < PNW_MAX_CMDBUFS_ENCODE; i++) {
1228         obj_context->pnw_cmdbuf_list[i] = NULL;
1229     }
1230 
1231 #ifdef PSBVIDEO_MRFL
1232     for (i = 0; i < TNG_MAX_CMDBUFS_ENCODE; i++) {
1233         obj_context->tng_cmdbuf_list[i] = NULL;
1234     }
1235 #endif
1236 
1237 #ifdef PSBVIDEO_MRFL_VPP
1238     for (i = 0; i < VSP_MAX_CMDBUFS; i++) {
1239         obj_context->vsp_cmdbuf_list[i] = NULL;
1240     }
1241 #endif
1242 
1243     for (i = 0; i < PSB_MAX_CMDBUFS; i++) {
1244         obj_context->cmdbuf_list[i] = NULL;
1245     }
1246 
1247     for (i = 0; i < cmdbuf_num; i++) {
1248         void  *cmdbuf = NULL;
1249 #ifndef BAYTRAIL
1250         if (encode) { /* Topaz encode context */
1251 #ifdef PSBVIDEO_MRFL
1252             if (IS_MRFL(obj_context->driver_data))
1253                 cmdbuf = calloc(1, sizeof(struct tng_cmdbuf_s));
1254 #endif
1255 #ifdef PSBVIDEO_MFLD
1256             if (IS_MFLD(obj_context->driver_data))
1257                 cmdbuf = calloc(1, sizeof(struct pnw_cmdbuf_s));
1258 #endif
1259         } else if (proc) { /* VSP VPP context */
1260             /* VED two pass rotation under VPP API */
1261             if (driver_data->ved_vpp)
1262                 cmdbuf =  calloc(1, sizeof(struct psb_cmdbuf_s));
1263 #ifdef PSBVIDEO_MRFL_VPP
1264             else if (IS_MRFL(obj_context->driver_data))
1265                 cmdbuf = calloc(1, sizeof(struct vsp_cmdbuf_s));
1266 #endif
1267         } else /* MSVDX decode context */
1268 #endif
1269             cmdbuf =  calloc(1, sizeof(struct psb_cmdbuf_s));
1270 
1271         if (NULL == cmdbuf) {
1272             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1273             DEBUG_FAILURE;
1274             break;
1275         }
1276 
1277 #ifndef BAYTRAIL
1278         if (encode) { /* Topaz encode context */
1279 
1280 #ifdef PSBVIDEO_MRFL
1281             if (IS_MRFL(obj_context->driver_data))
1282                 vaStatus = tng_cmdbuf_create(obj_context, driver_data, (tng_cmdbuf_p)cmdbuf);
1283 #endif
1284 #ifdef PSBVIDEO_MFLD
1285             if (IS_MFLD(obj_context->driver_data))
1286                 vaStatus = pnw_cmdbuf_create(obj_context, driver_data, (pnw_cmdbuf_p)cmdbuf);
1287 #endif
1288         } else if (proc) { /* VSP VPP context */
1289             if (driver_data->ved_vpp)
1290                 vaStatus = psb_cmdbuf_create(obj_context, driver_data, (psb_cmdbuf_p)cmdbuf);
1291 #ifdef PSBVIDEO_MRFL_VPP
1292             else if (IS_MRFL(obj_context->driver_data))
1293                 vaStatus = vsp_cmdbuf_create(obj_context, driver_data, (vsp_cmdbuf_p)cmdbuf);
1294 #endif
1295         } else /* MSVDX decode context */
1296 #endif
1297             vaStatus = psb_cmdbuf_create(obj_context, driver_data, (psb_cmdbuf_p)cmdbuf);
1298 
1299         if (VA_STATUS_SUCCESS != vaStatus) {
1300             free(cmdbuf);
1301             DEBUG_FAILURE;
1302             break;
1303         }
1304 
1305 #ifndef BAYTRAIL
1306         if (encode) { /* Topaz encode context */
1307             if (i >= LNC_MAX_CMDBUFS_ENCODE) {
1308                 free(cmdbuf);
1309                 DEBUG_FAILURE;
1310                 break;
1311             }
1312 
1313 #ifdef PSBVIDEO_MRFL
1314             if (IS_MRFL(obj_context->driver_data))
1315                 obj_context->tng_cmdbuf_list[i] = (tng_cmdbuf_p)cmdbuf;
1316 #endif
1317 #ifdef PSBVIDEO_MFLD
1318             if (IS_MFLD(obj_context->driver_data))
1319                 obj_context->pnw_cmdbuf_list[i] = (pnw_cmdbuf_p)cmdbuf;
1320 #endif
1321         } else if (proc) { /* VSP VPP context */
1322             if (driver_data->ved_vpp)
1323                 obj_context->cmdbuf_list[i] = (psb_cmdbuf_p)cmdbuf;
1324 #ifdef PSBVIDEO_MRFL_VPP
1325             else if (IS_MRFL(obj_context->driver_data))
1326                 obj_context->vsp_cmdbuf_list[i] = (vsp_cmdbuf_p)cmdbuf;
1327 #endif
1328         } else /* MSVDX decode context */
1329 #endif
1330             obj_context->cmdbuf_list[i] = (psb_cmdbuf_p)cmdbuf;
1331     }
1332 
1333     obj_context->cmdbuf_current = -1;
1334     obj_context->cmdbuf = NULL;
1335     obj_context->pnw_cmdbuf = NULL;
1336     obj_context->tng_cmdbuf = NULL;
1337 #ifdef PSBVIDEO_MRFL_VPP
1338     obj_context->vsp_cmdbuf = NULL;
1339 #endif
1340     obj_context->frame_count = 0;
1341     obj_context->slice_count = 0;
1342     obj_context->msvdx_context = ((driver_data->msvdx_context_base & 0xff0000) >> 16) |
1343                                  ((contextID & 0xff000000) >> 16);
1344 #ifdef ANDROID
1345     obj_context->msvdx_context = ((driver_data->drm_fd & 0xf) << 4) |
1346                                  ((unsigned int)gettid() & 0xf);
1347 #endif
1348     obj_context->profile = obj_config->profile;
1349     obj_context->entry_point = obj_config->entrypoint;
1350 
1351     /* Error recovery */
1352     if (VA_STATUS_SUCCESS != vaStatus) {
1353         if (cmdbuf_num > LNC_MAX_CMDBUFS_ENCODE)
1354             cmdbuf_num = LNC_MAX_CMDBUFS_ENCODE;
1355         for (i = 0; i < cmdbuf_num; i++) {
1356 #ifndef BAYTRAIL
1357             if (obj_context->pnw_cmdbuf_list[i]) {
1358                 pnw_cmdbuf_destroy(obj_context->pnw_cmdbuf_list[i]);
1359                 free(obj_context->pnw_cmdbuf_list[i]);
1360                 obj_context->pnw_cmdbuf_list[i] = NULL;
1361             }
1362 #endif
1363 #ifdef PSBVIDEO_MRFL
1364             if (obj_context->tng_cmdbuf_list[i]) {
1365                 tng_cmdbuf_destroy(obj_context->tng_cmdbuf_list[i]);
1366                 free(obj_context->tng_cmdbuf_list[i]);
1367                 obj_context->tng_cmdbuf_list[i] = NULL;
1368             }
1369 #endif
1370             if (obj_context->cmdbuf_list[i]) {
1371                 psb_cmdbuf_destroy(obj_context->cmdbuf_list[i]);
1372                 free(obj_context->cmdbuf_list[i]);
1373                 obj_context->cmdbuf_list[i] = NULL;
1374             }
1375 #ifdef PSBVIDEO_MRFL_VPP
1376             if (obj_context->vsp_cmdbuf_list[i]) {
1377                 vsp_cmdbuf_destroy(obj_context->vsp_cmdbuf_list[i]);
1378                 free(obj_context->vsp_cmdbuf_list[i]);
1379                 obj_context->vsp_cmdbuf_list[i] = NULL;
1380             }
1381 #endif
1382         }
1383 
1384         obj_context->cmdbuf = NULL;
1385 #ifdef PSBVIDEO_MRFL_VPP
1386         obj_context->vsp_cmdbuf = NULL;
1387 #endif
1388 
1389         obj_context->context_id = -1;
1390         obj_context->config_id = -1;
1391         obj_context->picture_width = 0;
1392         obj_context->picture_height = 0;
1393         if (NULL != obj_context->render_targets)
1394             free(obj_context->render_targets);
1395         free(obj_context->buffer_list);
1396         obj_context->num_buffers = 0;
1397         obj_context->render_targets = NULL;
1398         obj_context->num_render_targets = 0;
1399         obj_context->va_flags = 0;
1400         object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1401     }
1402     obj_context->ctp_type = (((obj_config->profile << 8) |
1403                              obj_config->entrypoint | driver_data->protected) & 0xffff);
1404 
1405     /* VSP's PM rely on VPP ctx, so ved vpp use diferent profile/level for ctx */
1406     if (driver_data->ved_vpp)
1407         obj_context->ctp_type = (((obj_config->profile << 8) |
1408                              VAEntrypointVLD | driver_data->protected) & 0xffff);
1409 
1410     if (!encode) {
1411         obj_context->ctp_type |= ((obj_context->msvdx_tile & 0xff) << 16);
1412     }
1413 
1414     if (obj_config->profile == VAProfileVC1Simple ||
1415         obj_config->profile == VAProfileVC1Main ||
1416         obj_config->profile == VAProfileVC1Advanced) {
1417         uint64_t width_in_mb = ((driver_data->render_rect.x + driver_data->render_rect.width + 15) / 16);
1418         obj_context->ctp_type |= (width_in_mb << 32);
1419     }
1420 
1421     /* add ctx_num to save vp8 enc context num to support dual vp8 encoding */
1422     int ret = psb_new_context(driver_data, obj_context->ctp_type | driver_data->protected);
1423     if (ret)
1424         vaStatus = VA_STATUS_ERROR_UNKNOWN;
1425 
1426     DEBUG_FUNC_EXIT
1427     return vaStatus;
1428 }
1429 
psb__allocate_malloc_buffer(object_buffer_p obj_buffer,int size)1430 static VAStatus psb__allocate_malloc_buffer(object_buffer_p obj_buffer, int size)
1431 {
1432     VAStatus vaStatus = VA_STATUS_SUCCESS;
1433 
1434     obj_buffer->buffer_data = realloc(obj_buffer->buffer_data, size);
1435     CHECK_ALLOCATION(obj_buffer->buffer_data);
1436 
1437     return vaStatus;
1438 }
1439 
1440 static VAStatus psb__unmap_buffer(object_buffer_p obj_buffer);
1441 
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)1442 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)
1443 {
1444     VAStatus vaStatus = VA_STATUS_SUCCESS;
1445 
1446     ASSERT(NULL == obj_buffer->buffer_data);
1447 
1448     if (obj_buffer->psb_buffer && (psb_bs_queued == obj_buffer->psb_buffer->status)) {
1449         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Abandoning BO for buffer %08x type %s\n", obj_buffer->base.id,
1450                                  buffer_type_to_string(obj_buffer->type));
1451         /* need to set psb_buffer aside and get another one */
1452         obj_buffer->psb_buffer->status = psb_bs_abandoned;
1453         obj_buffer->psb_buffer = NULL;
1454         obj_buffer->size = 0;
1455         obj_buffer->alloc_size = 0;
1456     }
1457 
1458     if (type == VAProtectedSliceDataBufferType) {
1459         if (obj_buffer->psb_buffer) {
1460             drv_debug_msg(VIDEO_DEBUG_GENERAL, "RAR: old RAR slice buffer with RAR handle 0%08x, current RAR handle 0x%08x\n",
1461                                      obj_buffer->psb_buffer->rar_handle, (uint32_t)data);
1462             drv_debug_msg(VIDEO_DEBUG_GENERAL, "RAR: force old RAR buffer destroy and new buffer re-allocation by set size=0\n");
1463             obj_buffer->alloc_size = 0;
1464         }
1465     }
1466 
1467     if (obj_buffer->alloc_size < (unsigned int)size) {
1468         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Buffer size mismatch: Need %d, currently have %d\n", size, obj_buffer->alloc_size);
1469         if (obj_buffer->psb_buffer) {
1470             if (obj_buffer->buffer_data) {
1471                 psb__unmap_buffer(obj_buffer);
1472             }
1473             psb_buffer_destroy(obj_buffer->psb_buffer);
1474             obj_buffer->alloc_size = 0;
1475         } else {
1476             obj_buffer->psb_buffer = (psb_buffer_p) calloc(1, sizeof(struct psb_buffer_s));
1477             if (NULL == obj_buffer->psb_buffer) {
1478                 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1479                 DEBUG_FAILURE;
1480             }
1481         }
1482         if (VA_STATUS_SUCCESS == vaStatus) {
1483             drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocate new GPU buffers for vaCreateBuffer:type=%s,size=%d.\n",
1484                                      buffer_type_to_string(obj_buffer->type), size);
1485 
1486             size = (size + 0x7fff) & ~0x7fff; /* Round up */
1487             if (obj_buffer->type == VAImageBufferType) /* Xserver side PutSurface, Image/subpicture buffer
1488                                                         * should be shared between two process
1489                                                         */
1490                 vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu_shared, obj_buffer->psb_buffer);
1491 #ifndef BAYTRAIL
1492             else if (obj_buffer->type == VAProtectedSliceDataBufferType) {
1493                 vaStatus = psb_buffer_reference_imr(driver_data, (uint32_t)data, obj_buffer->psb_buffer);
1494             }
1495 #endif
1496             else if (obj_buffer->type == VAEncCodedBufferType)
1497                 vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu, obj_buffer->psb_buffer);
1498             else
1499                 vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu, obj_buffer->psb_buffer);
1500 
1501             if (VA_STATUS_SUCCESS != vaStatus) {
1502                 free(obj_buffer->psb_buffer);
1503                 obj_buffer->psb_buffer = NULL;
1504                 DEBUG_FAILURE;
1505             } else {
1506                 obj_buffer->alloc_size = size;
1507             }
1508         }
1509     }
1510     return vaStatus;
1511 }
1512 
psb__map_buffer(object_buffer_p obj_buffer)1513 static VAStatus psb__map_buffer(object_buffer_p obj_buffer)
1514 {
1515     if (obj_buffer->psb_buffer) {
1516         return psb_buffer_map(obj_buffer->psb_buffer, &obj_buffer->buffer_data);
1517     }
1518     return VA_STATUS_SUCCESS;
1519 }
1520 
psb__unmap_buffer(object_buffer_p obj_buffer)1521 static VAStatus psb__unmap_buffer(object_buffer_p obj_buffer)
1522 {
1523     if (obj_buffer->psb_buffer) {
1524         obj_buffer->buffer_data = NULL;
1525         return psb_buffer_unmap(obj_buffer->psb_buffer);
1526     }
1527     return VA_STATUS_SUCCESS;
1528 }
1529 
psb__destroy_buffer(psb_driver_data_p driver_data,object_buffer_p obj_buffer)1530 static void psb__destroy_buffer(psb_driver_data_p driver_data, object_buffer_p obj_buffer)
1531 {
1532     if (obj_buffer->psb_buffer) {
1533         if (obj_buffer->buffer_data) {
1534             psb__unmap_buffer(obj_buffer);
1535         }
1536         psb_buffer_destroy(obj_buffer->psb_buffer);
1537         free(obj_buffer->psb_buffer);
1538         obj_buffer->psb_buffer = NULL;
1539     }
1540 
1541     if (NULL != obj_buffer->buffer_data) {
1542         free(obj_buffer->buffer_data);
1543         obj_buffer->buffer_data = NULL;
1544         obj_buffer->size = 0;
1545     }
1546 
1547     object_heap_free(&driver_data->buffer_heap, (object_base_p) obj_buffer);
1548 }
1549 
psb__suspend_buffer(psb_driver_data_p driver_data,object_buffer_p obj_buffer)1550 void psb__suspend_buffer(psb_driver_data_p driver_data, object_buffer_p obj_buffer)
1551 {
1552     if (obj_buffer->context) {
1553         VABufferType type = obj_buffer->type;
1554         object_context_p obj_context = obj_buffer->context;
1555 
1556         if (type >= PSB_MAX_BUFFERTYPES) {
1557             drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid buffer type %d\n", type);
1558             return;
1559         }
1560 
1561         /* Remove buffer from active list */
1562         *obj_buffer->pptr_prev_next = obj_buffer->ptr_next;
1563 
1564         /* Add buffer to tail of unused list */
1565         obj_buffer->ptr_next = NULL;
1566         obj_buffer->last_used = obj_context->frame_count;
1567         if (obj_context->buffers_unused_tail[type]) {
1568             obj_buffer->pptr_prev_next = &(obj_context->buffers_unused_tail[type]->ptr_next);
1569         } else {
1570             obj_buffer->pptr_prev_next = &(obj_context->buffers_unused[type]);
1571         }
1572         *obj_buffer->pptr_prev_next = obj_buffer;
1573         obj_context->buffers_unused_tail[type] = obj_buffer;
1574         obj_context->buffers_unused_count[type]++;
1575 
1576         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Adding buffer %08x type %s to unused list. unused count = %d\n", obj_buffer->base.id,
1577                                  buffer_type_to_string(obj_buffer->type), obj_context->buffers_unused_count[type]);
1578 
1579         object_heap_suspend_object((object_base_p) obj_buffer, 1); /* suspend */
1580         return;
1581     }
1582 
1583     if (obj_buffer->psb_buffer && (psb_bs_queued == obj_buffer->psb_buffer->status)) {
1584         /* need to set psb_buffer aside */
1585         obj_buffer->psb_buffer->status = psb_bs_abandoned;
1586         obj_buffer->psb_buffer = NULL;
1587     }
1588 
1589     psb__destroy_buffer(driver_data, obj_buffer);
1590 }
1591 
psb__destroy_context(psb_driver_data_p driver_data,object_context_p obj_context)1592 static void psb__destroy_context(psb_driver_data_p driver_data, object_context_p obj_context)
1593 {
1594     int encode, i;
1595 
1596     if (obj_context->entry_point == VAEntrypointEncSlice)
1597         encode = 1;
1598     else
1599         encode = 0;
1600 
1601     obj_context->format_vtable->destroyContext(obj_context);
1602 
1603     for (i = 0; i < PSB_MAX_BUFFERTYPES; i++) {
1604         object_buffer_p obj_buffer;
1605         obj_buffer = obj_context->buffers_active[i];
1606         for (; obj_buffer; obj_buffer = obj_buffer->ptr_next) {
1607             drv_debug_msg(VIDEO_DEBUG_INIT, "%s: destroying active buffer %08x\n", __FUNCTION__, obj_buffer->base.id);
1608             psb__destroy_buffer(driver_data, obj_buffer);
1609         }
1610         obj_buffer = obj_context->buffers_unused[i];
1611         for (; obj_buffer; obj_buffer = obj_buffer->ptr_next) {
1612             drv_debug_msg(VIDEO_DEBUG_INIT, "%s: destroying unused buffer %08x\n", __FUNCTION__, obj_buffer->base.id);
1613             psb__destroy_buffer(driver_data, obj_buffer);
1614         }
1615         obj_context->buffers_unused_count[i] = 0;
1616     }
1617 #ifndef BAYTRAIL
1618     for (i = 0; i < LNC_MAX_CMDBUFS_ENCODE; i++) {
1619         if (obj_context->pnw_cmdbuf_list[i]) {
1620             pnw_cmdbuf_destroy(obj_context->pnw_cmdbuf_list[i]);
1621             free(obj_context->pnw_cmdbuf_list[i]);
1622             obj_context->pnw_cmdbuf_list[i] = NULL;
1623         }
1624     }
1625 #endif
1626 #ifdef PSBVIDEO_MRFL
1627     for (i = 0; i < TNG_MAX_CMDBUFS_ENCODE; i++) {
1628         if (obj_context->tng_cmdbuf_list[i]) {
1629             tng_cmdbuf_destroy(obj_context->tng_cmdbuf_list[i]);
1630             free(obj_context->tng_cmdbuf_list[i]);
1631             obj_context->tng_cmdbuf_list[i] = NULL;
1632         }
1633     }
1634 #endif
1635 #ifdef PSBVIDEO_MRFL_VPP
1636     for (i = 0; i < VSP_MAX_CMDBUFS; i++) {
1637         if (obj_context->vsp_cmdbuf_list[i]) {
1638             vsp_cmdbuf_destroy(obj_context->vsp_cmdbuf_list[i]);
1639             free(obj_context->vsp_cmdbuf_list[i]);
1640             obj_context->vsp_cmdbuf_list[i] = NULL;
1641         }
1642     }
1643 #endif
1644 
1645     for (i = 0; i < PSB_MAX_CMDBUFS; i++) {
1646         if (obj_context->cmdbuf_list[i]) {
1647             psb_cmdbuf_destroy(obj_context->cmdbuf_list[i]);
1648             free(obj_context->cmdbuf_list[i]);
1649             obj_context->cmdbuf_list[i] = NULL;
1650         }
1651     }
1652     obj_context->cmdbuf = NULL;
1653 #ifdef PSBVIDEO_MRFL_VPP
1654     obj_context->vsp_cmdbuf = NULL;
1655 #endif
1656 
1657     obj_context->context_id = -1;
1658     obj_context->config_id = -1;
1659     obj_context->picture_width = 0;
1660     obj_context->picture_height = 0;
1661     if (obj_context->render_targets)
1662         free(obj_context->render_targets);
1663     obj_context->render_targets = NULL;
1664     obj_context->num_render_targets = 0;
1665     obj_context->va_flags = 0;
1666 
1667     obj_context->current_render_target = NULL;
1668     obj_context->ec_target = NULL;
1669     obj_context->ec_candidate = NULL;
1670     if (obj_context->buffer_list)
1671         free(obj_context->buffer_list);
1672     obj_context->num_buffers = 0;
1673 
1674     object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1675 
1676     psb_rm_context(driver_data);
1677 }
1678 
psb_DestroyContext(VADriverContextP ctx,VAContextID context)1679 VAStatus psb_DestroyContext(
1680     VADriverContextP ctx,
1681     VAContextID context
1682 )
1683 {
1684     DEBUG_FUNC_ENTER
1685     INIT_DRIVER_DATA
1686     VAStatus vaStatus = VA_STATUS_SUCCESS;
1687     object_context_p obj_context = CONTEXT(context);
1688     CHECK_CONTEXT(obj_context);
1689 
1690     psb__destroy_context(driver_data, obj_context);
1691 
1692     DEBUG_FUNC_EXIT
1693     return vaStatus;
1694 }
1695 
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)1696 VAStatus psb__CreateBuffer(
1697     psb_driver_data_p driver_data,
1698     object_context_p obj_context,       /* in */
1699     VABufferType type,  /* in */
1700     unsigned int size,          /* in */
1701     unsigned int num_elements, /* in */
1702     unsigned char *data,         /* in */
1703     VABufferID *buf_desc    /* out */
1704 )
1705 {
1706     DEBUG_FUNC_ENTER
1707     VAStatus vaStatus = VA_STATUS_SUCCESS;
1708     int bufferID;
1709     object_buffer_p obj_buffer;
1710     int unused_count;
1711 
1712     /*PSB_MAX_BUFFERTYPES is the size of array buffers_unused*/
1713     if (type >= PSB_MAX_BUFFERTYPES) {
1714         drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid buffer type %d\n", type);
1715         return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1716     }
1717 
1718 
1719     obj_buffer = obj_context ? obj_context->buffers_unused[type] : NULL;
1720     unused_count = obj_context ? obj_context->buffers_unused_count[type] : 0;
1721 
1722     /*
1723      * Buffer Management
1724      * For each buffer type, maintain
1725      *   - a LRU sorted list of unused buffers
1726      *   - a list of active buffers
1727      * We only create a new buffer when
1728      *   - no unused buffers are available
1729      *   - the last unused buffer is still queued
1730      *   - the last unused buffer was used very recently and may still be fenced
1731      *      - used recently is defined as within the current frame_count (subject to tweaks)
1732      *
1733      * The buffer that is returned will be moved to the list of active buffers
1734      *   - vaDestroyBuffer and vaRenderPicture will move the active buffer back to the list of unused buffers
1735     */
1736     drv_debug_msg(VIDEO_DEBUG_GENERAL, "Requesting buffer creation, size=%d,elements=%d,type=%s\n", size, num_elements,
1737                              buffer_type_to_string(type));
1738 
1739     /* on MFLD, data is IMR offset, and could be 0 */
1740     /*
1741     if ((type == VAProtectedSliceDataBufferType) && (data == NULL)) {
1742         drv_debug_msg(VIDEO_DEBUG_ERROR, "RAR: Create protected slice buffer, but RAR handle is NULL\n");
1743         return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE ;
1744     }
1745     */
1746 
1747     if (obj_buffer && obj_buffer->psb_buffer) {
1748         if (psb_bs_queued == obj_buffer->psb_buffer->status) {
1749             /* Buffer is still queued, allocate new buffer instead */
1750             drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x, still queued\n", obj_buffer->base.id);
1751             obj_buffer = NULL;
1752         } else if ((obj_buffer->last_used == obj_context->frame_count) && (unused_count < MAX_UNUSED_BUFFERS)) {
1753             /* Buffer was used for this frame, allocate new buffer instead */
1754             drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x, recently used. Unused = %d\n", obj_buffer->base.id, unused_count);
1755             obj_buffer = NULL;
1756         } else if (obj_context->frame_count - obj_buffer->last_used < 5) {
1757             /* Buffer was used for previous frame, allocate new buffer instead */
1758             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);
1759             obj_buffer = NULL;
1760         }
1761     }
1762 
1763     if (obj_buffer) {
1764         bufferID = obj_buffer->base.id;
1765         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Reusing buffer %08x type %s from unused list. Unused = %d\n", bufferID,
1766                                  buffer_type_to_string(type), unused_count);
1767 
1768         /* Remove from unused list */
1769         obj_context->buffers_unused[type] = obj_buffer->ptr_next;
1770         if (obj_context->buffers_unused[type]) {
1771             obj_context->buffers_unused[type]->pptr_prev_next = &(obj_context->buffers_unused[type]);
1772             ASSERT(obj_context->buffers_unused_tail[type] != obj_buffer);
1773         } else {
1774             ASSERT(obj_context->buffers_unused_tail[type] == obj_buffer);
1775             obj_context->buffers_unused_tail[type] = 0;
1776         }
1777         obj_context->buffers_unused_count[type]--;
1778 
1779         object_heap_suspend_object((object_base_p)obj_buffer, 0); /* Make BufferID valid again */
1780         ASSERT(type == obj_buffer->type);
1781         ASSERT(obj_context == obj_buffer->context);
1782     } else {
1783         bufferID = object_heap_allocate(&driver_data->buffer_heap);
1784         obj_buffer = BUFFER(bufferID);
1785         CHECK_ALLOCATION(obj_buffer);
1786 
1787         MEMSET_OBJECT(obj_buffer, struct object_buffer_s);
1788 
1789         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocating new buffer %08x type %s.\n", bufferID, buffer_type_to_string(type));
1790         obj_buffer->type = type;
1791         obj_buffer->buffer_data = NULL;
1792         obj_buffer->psb_buffer = NULL;
1793         obj_buffer->size = 0;
1794         obj_buffer->max_num_elements = 0;
1795         obj_buffer->alloc_size = 0;
1796         obj_buffer->context = obj_context;
1797     }
1798     if (obj_context) {
1799         /* Add to front of active list */
1800         obj_buffer->ptr_next = obj_context->buffers_active[type];
1801         if (obj_buffer->ptr_next) {
1802             obj_buffer->ptr_next->pptr_prev_next = &(obj_buffer->ptr_next);
1803         }
1804         obj_buffer->pptr_prev_next = &(obj_context->buffers_active[type]);
1805         *obj_buffer->pptr_prev_next = obj_buffer;
1806     }
1807 
1808     switch (obj_buffer->type) {
1809     case VABitPlaneBufferType:
1810     case VASliceDataBufferType:
1811     case VAResidualDataBufferType:
1812     case VAImageBufferType:
1813     case VASliceGroupMapBufferType:
1814     case VAEncCodedBufferType:
1815     case VAProtectedSliceDataBufferType:
1816 #ifdef SLICE_HEADER_PARSING
1817     case VAParseSliceHeaderGroupBufferType:
1818 #endif
1819         vaStatus = psb__allocate_BO_buffer(driver_data, obj_context,obj_buffer, size * num_elements, data, obj_buffer->type);
1820         DEBUG_FAILURE;
1821         break;
1822     case VAPictureParameterBufferType:
1823     case VAIQMatrixBufferType:
1824     case VASliceParameterBufferType:
1825     case VAMacroblockParameterBufferType:
1826     case VADeblockingParameterBufferType:
1827     case VAEncPackedHeaderParameterBufferType:
1828     case VAEncPackedHeaderDataBufferType:
1829     case VAEncSequenceParameterBufferType:
1830     case VAEncPictureParameterBufferType:
1831     case VAEncSliceParameterBufferType:
1832     case VAQMatrixBufferType:
1833     case VAEncMiscParameterBufferType:
1834     case VAProbabilityBufferType:
1835     case VAHuffmanTableBufferType:
1836     case VAProcPipelineParameterBufferType:
1837     case VAProcFilterParameterBufferType:
1838 #ifdef SLICE_HEADER_PARSING
1839     case VAParsePictureParameterBufferType:
1840 #endif
1841         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocate new malloc buffers for vaCreateBuffer:type=%s,size=%d, buffer_data=%p.\n",
1842                                  buffer_type_to_string(type), size, obj_buffer->buffer_data);
1843         vaStatus = psb__allocate_malloc_buffer(obj_buffer, size * num_elements);
1844         DEBUG_FAILURE;
1845         break;
1846 
1847     default:
1848         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1849         DEBUG_FAILURE;
1850         break;;
1851     }
1852 
1853     if (VA_STATUS_SUCCESS == vaStatus) {
1854         obj_buffer->size = size;
1855         obj_buffer->max_num_elements = num_elements;
1856         obj_buffer->num_elements = num_elements;
1857         if (data && (obj_buffer->type != VAProtectedSliceDataBufferType)) {
1858             vaStatus = psb__map_buffer(obj_buffer);
1859             if (VA_STATUS_SUCCESS == vaStatus) {
1860                 memcpy(obj_buffer->buffer_data, data, size * num_elements);
1861 
1862                 psb__unmap_buffer(obj_buffer);
1863             }
1864         }
1865     }
1866     if (VA_STATUS_SUCCESS == vaStatus) {
1867         *buf_desc = bufferID;
1868     } else {
1869         psb__destroy_buffer(driver_data, obj_buffer);
1870     }
1871 
1872     DEBUG_FUNC_EXIT
1873     return vaStatus;
1874 }
1875 
psb_CreateBuffer(VADriverContextP ctx,VAContextID context,VABufferType type,unsigned int size,unsigned int num_elements,void * data,VABufferID * buf_desc)1876 VAStatus psb_CreateBuffer(
1877     VADriverContextP ctx,
1878     VAContextID context,        /* in */
1879     VABufferType type,  /* in */
1880     unsigned int size,          /* in */
1881     unsigned int num_elements, /* in */
1882     void *data,         /* in */
1883     VABufferID *buf_desc    /* out */
1884 )
1885 {
1886     DEBUG_FUNC_ENTER
1887     INIT_DRIVER_DATA
1888     VAStatus vaStatus = VA_STATUS_SUCCESS;
1889 
1890     CHECK_INVALID_PARAM(num_elements <= 0);
1891 
1892     switch (type) {
1893     case VABitPlaneBufferType:
1894     case VASliceDataBufferType:
1895     case VAProtectedSliceDataBufferType:
1896     case VAResidualDataBufferType:
1897     case VASliceGroupMapBufferType:
1898     case VAPictureParameterBufferType:
1899     case VAIQMatrixBufferType:
1900     case VASliceParameterBufferType:
1901     case VAMacroblockParameterBufferType:
1902     case VADeblockingParameterBufferType:
1903     case VAEncCodedBufferType:
1904     case VAEncSequenceParameterBufferType:
1905     case VAEncPictureParameterBufferType:
1906     case VAEncSliceParameterBufferType:
1907     case VAEncPackedHeaderParameterBufferType:
1908     case VAEncPackedHeaderDataBufferType:
1909     case VAQMatrixBufferType:
1910     case VAEncMiscParameterBufferType:
1911     case VAProbabilityBufferType:
1912     case VAHuffmanTableBufferType:
1913     case VAProcPipelineParameterBufferType:
1914     case VAProcFilterParameterBufferType:
1915 #ifdef SLICE_HEADER_PARSING
1916     case VAParsePictureParameterBufferType:
1917     case VAParseSliceHeaderGroupBufferType:
1918 #endif
1919         break;
1920 
1921     default:
1922         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1923         DEBUG_FAILURE;
1924         return vaStatus;
1925     }
1926 
1927     object_context_p obj_context = CONTEXT(context);
1928     CHECK_CONTEXT(obj_context);
1929     CHECK_INVALID_PARAM(buf_desc == NULL);
1930 
1931     vaStatus = psb__CreateBuffer(driver_data, obj_context, type, size, num_elements, data, buf_desc);
1932 
1933     DEBUG_FUNC_EXIT
1934     return vaStatus;
1935 }
1936 
1937 
psb_BufferInfo(VADriverContextP ctx,VABufferID buf_id,VABufferType * type,unsigned int * size,unsigned int * num_elements)1938 VAStatus psb_BufferInfo(
1939     VADriverContextP ctx,
1940     VABufferID buf_id,  /* in */
1941     VABufferType *type, /* out */
1942     unsigned int *size,         /* out */
1943     unsigned int *num_elements /* out */
1944 )
1945 {
1946     DEBUG_FUNC_ENTER
1947     INIT_DRIVER_DATA
1948     VAStatus vaStatus = VA_STATUS_SUCCESS;
1949 
1950     object_buffer_p obj_buffer = BUFFER(buf_id);
1951     CHECK_BUFFER(obj_buffer);
1952 
1953     *type = obj_buffer->type;
1954     *size = obj_buffer->size;
1955     *num_elements = obj_buffer->num_elements;
1956     DEBUG_FUNC_EXIT
1957     return VA_STATUS_SUCCESS;
1958 }
1959 
1960 
psb_BufferSetNumElements(VADriverContextP ctx,VABufferID buf_id,unsigned int num_elements)1961 VAStatus psb_BufferSetNumElements(
1962     VADriverContextP ctx,
1963     VABufferID buf_id,    /* in */
1964     unsigned int num_elements    /* in */
1965 )
1966 {
1967     DEBUG_FUNC_ENTER
1968     INIT_DRIVER_DATA
1969     VAStatus vaStatus = VA_STATUS_SUCCESS;
1970     object_buffer_p obj_buffer = BUFFER(buf_id);
1971     CHECK_BUFFER(obj_buffer);
1972 
1973     if ((num_elements <= 0) || (num_elements > obj_buffer->max_num_elements)) {
1974         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
1975     }
1976     if (VA_STATUS_SUCCESS == vaStatus) {
1977         obj_buffer->num_elements = num_elements;
1978     }
1979 
1980     DEBUG_FUNC_EXIT
1981     return vaStatus;
1982 }
1983 
psb_MapBuffer(VADriverContextP ctx,VABufferID buf_id,void ** pbuf)1984 VAStatus psb_MapBuffer(
1985     VADriverContextP ctx,
1986     VABufferID buf_id,    /* in */
1987     void **pbuf         /* out */
1988 )
1989 {
1990     DEBUG_FUNC_ENTER
1991     INIT_DRIVER_DATA
1992     VAStatus vaStatus = VA_STATUS_SUCCESS;
1993     object_buffer_p obj_buffer = BUFFER(buf_id);
1994     CHECK_BUFFER(obj_buffer);
1995 
1996     CHECK_INVALID_PARAM(pbuf == NULL);
1997 
1998     vaStatus = psb__map_buffer(obj_buffer);
1999     CHECK_VASTATUS();
2000 
2001     if (NULL != obj_buffer->buffer_data) {
2002         *pbuf = obj_buffer->buffer_data;
2003 
2004         /* specifically for Topaz encode
2005          * write validate coded data offset in CodedBuffer
2006          */
2007         if (obj_buffer->type == VAEncCodedBufferType)
2008             psb_codedbuf_map_mangle(ctx, obj_buffer, pbuf);
2009         /* *(IMG_UINT32 *)((unsigned char *)obj_buffer->buffer_data + 4) = 16; */
2010     } else {
2011         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
2012     }
2013     DEBUG_FUNC_EXIT
2014     return vaStatus;
2015 }
2016 
psb_UnmapBuffer(VADriverContextP ctx,VABufferID buf_id)2017 VAStatus psb_UnmapBuffer(
2018     VADriverContextP ctx,
2019     VABufferID buf_id    /* in */
2020 )
2021 {
2022     DEBUG_FUNC_ENTER
2023     INIT_DRIVER_DATA
2024     VAStatus vaStatus = VA_STATUS_SUCCESS;
2025     object_buffer_p obj_buffer = BUFFER(buf_id);
2026     CHECK_BUFFER(obj_buffer);
2027 
2028     vaStatus = psb__unmap_buffer(obj_buffer);
2029     DEBUG_FUNC_EXIT
2030     return vaStatus;
2031 }
2032 
2033 
psb_DestroyBuffer(VADriverContextP ctx,VABufferID buffer_id)2034 VAStatus psb_DestroyBuffer(
2035     VADriverContextP ctx,
2036     VABufferID buffer_id
2037 )
2038 {
2039     DEBUG_FUNC_ENTER
2040     INIT_DRIVER_DATA
2041     VAStatus vaStatus = VA_STATUS_SUCCESS;
2042     object_buffer_p obj_buffer = BUFFER(buffer_id);
2043     if (NULL == obj_buffer) {
2044         return vaStatus;
2045     }
2046     psb__suspend_buffer(driver_data, obj_buffer);
2047     DEBUG_FUNC_EXIT
2048     return vaStatus;
2049 }
2050 
2051 
psb_BeginPicture(VADriverContextP ctx,VAContextID context,VASurfaceID render_target)2052 VAStatus psb_BeginPicture(
2053     VADriverContextP ctx,
2054     VAContextID context,
2055     VASurfaceID render_target
2056 )
2057 {
2058     DEBUG_FUNC_ENTER
2059     INIT_DRIVER_DATA
2060     VAStatus vaStatus = VA_STATUS_SUCCESS;
2061     object_context_p obj_context;
2062     object_surface_p obj_surface;
2063     object_config_p obj_config;
2064 
2065     obj_context = CONTEXT(context);
2066     CHECK_CONTEXT(obj_context);
2067 
2068     /* Must not be within BeginPicture / EndPicture already */
2069     ASSERT(obj_context->current_render_target == NULL);
2070 
2071     obj_surface = SURFACE(render_target);
2072     CHECK_SURFACE(obj_surface);
2073 
2074     obj_context->current_render_surface_id = render_target;
2075     obj_context->current_render_target = obj_surface;
2076     obj_context->slice_count = 0;
2077 
2078     obj_config = CONFIG(obj_context->config_id);
2079     if (obj_config == NULL)
2080         return VA_STATUS_ERROR_INVALID_CONFIG;
2081 
2082     /* if the surface is decode render target, and in displaying */
2083     if (obj_config &&
2084         (obj_config->entrypoint != VAEntrypointEncSlice) &&
2085         (driver_data->cur_displaying_surface == render_target))
2086         drv_debug_msg(VIDEO_DEBUG_ERROR, "WARNING: rendering a displaying surface, may see tearing\n");
2087 
2088     if (VA_STATUS_SUCCESS == vaStatus) {
2089         vaStatus = obj_context->format_vtable->beginPicture(obj_context);
2090     }
2091 
2092 #ifdef ANDROID
2093     /* want msvdx to do rotate
2094      * but check per-context stream type: interlace or not
2095      */
2096     if ((obj_config->entrypoint != VAEntrypointEncSlice) &&
2097         (obj_config->entrypoint != VAEntrypointEncPicture)) {
2098         psb_RecalcAlternativeOutput(obj_context);
2099     }
2100 #endif
2101 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
2102     if (driver_data->vpp_on && GET_SURFACE_INFO_tiling(obj_surface->psb_surface))
2103         driver_data->disable_msvdx_rotate = 0;
2104 #endif
2105     if (obj_context->interlaced_stream || driver_data->disable_msvdx_rotate) {
2106         int i;
2107         obj_context->msvdx_rotate = 0;
2108         if (obj_context->num_render_targets > 0) {
2109             for (i = 0; i < obj_context->num_render_targets; i++) {
2110                 object_surface_p obj_surface = SURFACE(obj_context->render_targets[i]);
2111                 /*we invalidate all surfaces's rotate buffer share info here.*/
2112                 if (obj_surface && obj_surface->share_info) {
2113                     obj_surface->share_info->surface_rotate = 0;
2114                 }
2115             }
2116         }
2117     }
2118     else
2119         obj_context->msvdx_rotate = driver_data->msvdx_rotate_want;
2120 
2121     /* the main surface track current rotate information
2122      * try to reuse the allocated rotate surfaces and don't destroy them
2123      * thus the rotation info in obj_surface->out_loop_surface may not be updated
2124      */
2125 
2126     SET_SURFACE_INFO_rotate(obj_surface->psb_surface, obj_context->msvdx_rotate);
2127 
2128      if (CONTEXT_SCALING(obj_context) && obj_config->entrypoint != VAEntrypointEncSlice)
2129           if(VA_STATUS_SUCCESS != psb_CreateScalingSurface(obj_context, obj_surface)) {
2130              obj_context->msvdx_scaling = 0;
2131              ALOGE("%s: fail to allocate scaling surface", __func__);
2132           }
2133 
2134     if (CONTEXT_ROTATE(obj_context)) {
2135 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
2136         /* The VSP rotation is just for 1080P with tilling */
2137         if (driver_data->vpp_on && GET_SURFACE_INFO_tiling(obj_surface->psb_surface)) {
2138             if (obj_config->entrypoint == VAEntrypointVideoProc)
2139                 vaStatus = psb_CreateRotateSurface(obj_context, obj_surface, obj_context->msvdx_rotate);
2140             else {
2141                 SET_SURFACE_INFO_rotate(obj_surface->psb_surface, 0);
2142                 obj_context->msvdx_rotate = 0;
2143                 vaStatus = psb_DestroyRotateBuffer(obj_context, obj_surface);
2144             }
2145         } else
2146 #endif
2147         vaStatus = psb_CreateRotateSurface(obj_context, obj_surface, obj_context->msvdx_rotate);
2148         if (VA_STATUS_SUCCESS !=vaStatus)
2149             ALOGE("%s: fail to allocate out loop surface", __func__);
2150 
2151     } else {
2152         if (obj_surface && obj_surface->share_info) {
2153             obj_surface->share_info->metadata_rotate = VAROTATION2HAL(driver_data->va_rotate);
2154             obj_surface->share_info->surface_rotate = VAROTATION2HAL(obj_context->msvdx_rotate);
2155         }
2156     }
2157 
2158     if (obj_surface && obj_surface->share_info &&
2159         obj_config->entrypoint == VAEntrypointVLD) {
2160         obj_surface->share_info->crop_width = driver_data->render_rect.width;
2161         obj_surface->share_info->crop_height = driver_data->render_rect.height;
2162     }
2163 
2164     if (driver_data->is_oold &&  !obj_surface->psb_surface->in_loop_buf) {
2165         psb_surface_p psb_surface = obj_surface->psb_surface;
2166 
2167         psb_surface->in_loop_buf = calloc(1, sizeof(struct psb_buffer_s));
2168         CHECK_ALLOCATION(psb_surface->in_loop_buf);
2169 
2170         /* FIXME: For RAR surface, need allocate RAR buffer  */
2171         vaStatus = psb_buffer_create(obj_context->driver_data,
2172                                      psb_surface->size,
2173                                      psb_bt_surface,
2174                                      psb_surface->in_loop_buf);
2175     } else if (!driver_data->is_oold && obj_surface->psb_surface->in_loop_buf) {
2176         psb_surface_p psb_surface = obj_surface->psb_surface;
2177 
2178         psb_buffer_destroy(psb_surface->in_loop_buf);
2179         free(psb_surface->in_loop_buf);
2180         psb_surface->in_loop_buf = NULL;
2181     }
2182     obj_context->is_oold = driver_data->is_oold;
2183 
2184     drv_debug_msg(VIDEO_DEBUG_GENERAL, "---BeginPicture 0x%08x for frame %d --\n",
2185                              render_target, obj_context->frame_count);
2186     psb__trace_message("------Trace frame %d------\n", obj_context->frame_count);
2187 
2188     DEBUG_FUNC_EXIT
2189     return vaStatus;
2190 }
2191 
psb_RenderPicture(VADriverContextP ctx,VAContextID context,VABufferID * buffers,int num_buffers)2192 VAStatus psb_RenderPicture(
2193     VADriverContextP ctx,
2194     VAContextID context,
2195     VABufferID *buffers,
2196     int num_buffers
2197 )
2198 {
2199     DEBUG_FUNC_ENTER
2200     INIT_DRIVER_DATA
2201     VAStatus vaStatus = VA_STATUS_SUCCESS;
2202     object_context_p obj_context;
2203     object_buffer_p *buffer_list;
2204     int i;
2205 
2206     obj_context = CONTEXT(context);
2207     CHECK_CONTEXT(obj_context);
2208 
2209     CHECK_INVALID_PARAM(num_buffers <= 0);
2210     /* Don't crash on NULL pointers */
2211     CHECK_BUFFER(buffers);
2212     /* Must be within BeginPicture / EndPicture */
2213     ASSERT(obj_context->current_render_target != NULL);
2214 
2215     if (num_buffers > obj_context->num_buffers) {
2216         free(obj_context->buffer_list);
2217 
2218         obj_context->buffer_list = (object_buffer_p *) calloc(1, sizeof(object_buffer_p) * num_buffers);
2219         if (obj_context->buffer_list == NULL) {
2220             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
2221             obj_context->num_buffers = 0;
2222         }
2223 
2224         obj_context->num_buffers = num_buffers;
2225     }
2226     buffer_list = obj_context->buffer_list;
2227 
2228     if (VA_STATUS_SUCCESS == vaStatus) {
2229         /* Lookup buffer references */
2230         for (i = 0; i < num_buffers; i++) {
2231             object_buffer_p obj_buffer = BUFFER(buffers[i]);
2232             CHECK_BUFFER(obj_buffer);
2233 
2234             buffer_list[i] = obj_buffer;
2235             drv_debug_msg(VIDEO_DEBUG_GENERAL, "Render buffer %08x type %s\n", obj_buffer->base.id,
2236                                      buffer_type_to_string(obj_buffer->type));
2237         }
2238     }
2239 
2240     if (VA_STATUS_SUCCESS == vaStatus) {
2241         vaStatus = obj_context->format_vtable->renderPicture(obj_context, buffer_list, num_buffers);
2242     }
2243 
2244     if (buffer_list) {
2245         /* Release buffers */
2246         for (i = 0; i < num_buffers; i++) {
2247             if (buffer_list[i]) {
2248                 psb__suspend_buffer(driver_data, buffer_list[i]);
2249             }
2250         }
2251     }
2252 
2253     DEBUG_FUNC_EXIT
2254     return vaStatus;
2255 }
2256 
psb_EndPicture(VADriverContextP ctx,VAContextID context)2257 VAStatus psb_EndPicture(
2258     VADriverContextP ctx,
2259     VAContextID context
2260 )
2261 {
2262     DEBUG_FUNC_ENTER
2263     INIT_DRIVER_DATA
2264     VAStatus vaStatus;
2265     object_context_p obj_context;
2266 
2267     obj_context = CONTEXT(context);
2268     CHECK_CONTEXT(obj_context);
2269 
2270     vaStatus = obj_context->format_vtable->endPicture(obj_context);
2271 
2272     drv_debug_msg(VIDEO_DEBUG_GENERAL, "---EndPicture for frame %d --\n", obj_context->frame_count);
2273 
2274     obj_context->current_render_target = NULL;
2275     obj_context->frame_count++;
2276 
2277     psb__trace_message("FrameCount = %03d\n", obj_context->frame_count);
2278     drv_debug_msg(VIDEO_DEBUG_GENERAL, "FrameCount = %03d\n", obj_context->frame_count);
2279     psb__trace_message(NULL);
2280 
2281 
2282     //psb_SyncSurface(ctx, obj_context->current_render_surface_id);
2283     DEBUG_FUNC_EXIT
2284     return vaStatus;
2285 }
2286 
2287 
psb__surface_usage(psb_driver_data_p driver_data,object_surface_p obj_surface,int * decode,int * encode,int * rc_enable,int * proc)2288 static void psb__surface_usage(
2289     psb_driver_data_p driver_data,
2290     object_surface_p obj_surface,
2291     int *decode, int *encode, int *rc_enable, int *proc
2292 )
2293 {
2294     object_context_p obj_context;
2295     object_config_p obj_config;
2296     VAEntrypoint tmp;
2297     unsigned int eRCmode;
2298     int i;
2299 
2300 
2301     *decode = 0;
2302     *encode = 0;
2303     *rc_enable = 0;
2304     *proc = 0;
2305 
2306     obj_context = CONTEXT(obj_surface->context_id);
2307     if (NULL == obj_context) /* not associate with a context */
2308         return;
2309 
2310     obj_config = CONFIG(obj_context->config_id);
2311     if (NULL == obj_config) /* not have a validate context */
2312         return;
2313 
2314     tmp = obj_config->entrypoint;
2315 
2316     *encode = (tmp == VAEntrypointEncSlice) || (tmp == VAEntrypointEncPicture);
2317     *decode = (VAEntrypointVLD <= tmp) && (tmp <= VAEntrypointDeblocking);
2318 #ifdef PSBVIDEO_MRFL_VPP
2319     *proc = (VAEntrypointVideoProc == tmp);
2320 #endif
2321 
2322     if (*encode) {
2323         for (i = 0; i < obj_config->attrib_count; i++) {
2324             if (obj_config->attrib_list[i].type == VAConfigAttribRateControl)
2325                 break;
2326         }
2327 
2328         if (i >= obj_config->attrib_count)
2329             eRCmode = VA_RC_NONE;
2330         else
2331             eRCmode = obj_config->attrib_list[i].value;
2332 
2333         if (eRCmode == VA_RC_NONE)
2334             *rc_enable = 0;
2335         else
2336             *rc_enable = 1;
2337     }
2338 }
2339 
psb_SyncSurface(VADriverContextP ctx,VASurfaceID render_target)2340 VAStatus psb_SyncSurface(
2341     VADriverContextP ctx,
2342     VASurfaceID render_target
2343 )
2344 {
2345     DEBUG_FUNC_ENTER
2346     INIT_DRIVER_DATA
2347     VAStatus vaStatus = VA_STATUS_SUCCESS;
2348     object_surface_p obj_surface;
2349     int decode = 0, encode = 0, rc_enable = 0, proc = 0;
2350     object_context_p obj_context = NULL;
2351     object_config_p obj_config = NULL;
2352 
2353     drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_SyncSurface: 0x%08x\n", render_target);
2354 
2355     obj_surface = SURFACE(render_target);
2356     CHECK_SURFACE(obj_surface);
2357 
2358     obj_context = CONTEXT(obj_surface->context_id);
2359     if (obj_context) {
2360         obj_config = CONFIG(obj_context->config_id);
2361     }
2362 
2363     /* The cur_displaying_surface indicates the surface being displayed by overlay.
2364      * The diaplay_timestamp records the time point of put surface, which would
2365      * be set to zero while using texture blit.*/
2366 
2367     /* don't use mutex here for performance concern... */
2368     //pthread_mutex_lock(&output->output_mutex);
2369     if (render_target == driver_data->cur_displaying_surface)
2370         vaStatus = VA_STATUS_ERROR_SURFACE_IN_DISPLAYING;
2371     else if ((VA_INVALID_SURFACE != driver_data->cur_displaying_surface)    /* use overlay */
2372              && (render_target == driver_data->last_displaying_surface)) {  /* It's the last displaying surface*/
2373         object_surface_p cur_obj_surface = SURFACE(driver_data->cur_displaying_surface);
2374         /*  The flip operation on current displaying surface could be delayed to
2375          *  next VBlank and hadn't been finished yet. Then, the last displaying
2376          *  surface shouldn't be freed, because the hardware may not
2377          *  complete loading data of it. Any change of the last surface could
2378          *  have a impect on the scrren.*/
2379         if (NULL != cur_obj_surface) {
2380             while ((GetTickCount() - cur_obj_surface->display_timestamp) < PSB_MAX_FLIP_DELAY)
2381                 usleep(PSB_MAX_FLIP_DELAY * 1000);
2382         }
2383     }
2384     //pthread_mutex_unlock(&output->output_mutex);
2385 
2386     if (vaStatus != VA_STATUS_ERROR_SURFACE_IN_DISPLAYING) {
2387 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
2388         /* For VPP buffer, will sync the rotated buffer */
2389         if (obj_config && obj_config->entrypoint == VAEntrypointVideoProc) {
2390             if (GET_SURFACE_INFO_tiling(obj_surface->psb_surface) &&
2391                 (obj_context->msvdx_rotate == VA_ROTATION_90 || obj_context->msvdx_rotate == VA_ROTATION_270) &&
2392                 obj_surface->out_loop_surface)
2393                 vaStatus = psb_surface_sync(obj_surface->out_loop_surface);
2394             else
2395                 vaStatus = psb_surface_sync(obj_surface->psb_surface);
2396         } else
2397 #endif
2398         vaStatus = psb_surface_sync(obj_surface->psb_surface);
2399     }
2400 
2401     /* report any error of decode for Android */
2402     psb__surface_usage(driver_data, obj_surface, &decode, &encode, &rc_enable, &proc);
2403 #if 0
2404     if (decode && IS_MRST(driver_data)) {
2405         struct drm_lnc_video_getparam_arg arg;
2406         uint32_t ret, handle, fw_status = 0;
2407         handle = wsbmKBufHandle(wsbmKBuf(obj_surface->psb_surface->buf.drm_buf));
2408         arg.key = IMG_VIDEO_DECODE_STATUS;
2409         arg.arg = (uint64_t)((unsigned long) & handle);
2410         arg.value = (uint64_t)((unsigned long) & fw_status);
2411         ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
2412                                   &arg, sizeof(arg));
2413         if (ret == 0) {
2414             if (fw_status != 0)
2415                 vaStatus = VA_STATUS_ERROR_DECODING_ERROR;
2416         } else {
2417             drv_debug_msg(VIDEO_DEBUG_GENERAL, "IMG_VIDEO_DECODE_STATUS ioctl return failed.\n");
2418             vaStatus = VA_STATUS_ERROR_UNKNOWN;
2419         }
2420     } else if (proc && IS_MRFL(driver_data)) {
2421         /* FIXME: does it need a new surface sync mechanism for FRC? */
2422     }
2423 #endif
2424     if (proc && IS_MRFL(driver_data)) {
2425         /* FIXME: does it need a new surface sync mechanism for FRC? */
2426     }
2427 
2428     //psb__dump_NV_buffers(obj_surface->psb_surface, 0, 0, obj_surface->width, obj_surface->height);
2429     //psb__dump_NV_buffers(obj_surface->psb_surface_rotate, 0, 0, obj_surface->height, ((obj_surface->width + 0x1f) & (~0x1f)));
2430     if (obj_surface->scaling_surface)
2431         psb__dump_NV12_buffers(obj_surface->scaling_surface, 0, 0, obj_surface->width_s, obj_surface->height_s);
2432     DEBUG_FAILURE;
2433     DEBUG_FUNC_EXIT
2434     return vaStatus;
2435 }
2436 
2437 
psb_QuerySurfaceStatus(VADriverContextP ctx,VASurfaceID render_target,VASurfaceStatus * status)2438 VAStatus psb_QuerySurfaceStatus(
2439     VADriverContextP ctx,
2440     VASurfaceID render_target,
2441     VASurfaceStatus *status    /* out */
2442 )
2443 {
2444     DEBUG_FUNC_ENTER
2445     INIT_DRIVER_DATA
2446     VAStatus vaStatus = VA_STATUS_SUCCESS;
2447     object_surface_p obj_surface;
2448     VASurfaceStatus surface_status;
2449     int frame_skip = 0, encode = 0, decode = 0, rc_enable = 0, proc = 0;
2450     object_context_p obj_context = NULL;
2451 
2452     obj_surface = SURFACE(render_target);
2453     CHECK_SURFACE(obj_surface);
2454 
2455     CHECK_INVALID_PARAM(status == NULL);
2456 
2457     psb__surface_usage(driver_data, obj_surface, &decode, &encode, &rc_enable, &proc);
2458 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
2459     /* For VPP 1080P, will query the rotated buffer */
2460     if (proc) {
2461         obj_context = CONTEXT(obj_surface->context_id);
2462         CHECK_CONTEXT(obj_context);
2463         if (GET_SURFACE_INFO_tiling(obj_surface->psb_surface) &&
2464             (obj_context->msvdx_rotate == VA_ROTATION_90 || obj_context->msvdx_rotate == VA_ROTATION_270) &&
2465             obj_surface->out_loop_surface)
2466             vaStatus = psb_surface_query_status(obj_surface->out_loop_surface, &surface_status);
2467         else
2468             vaStatus = psb_surface_query_status(obj_surface->psb_surface, &surface_status);
2469     } else
2470 #endif
2471         vaStatus = psb_surface_query_status(obj_surface->psb_surface, &surface_status);
2472 
2473     /* The cur_displaying_surface indicates the surface being displayed by overlay.
2474      * The diaplay_timestamp records the time point of put surface, which would
2475      * be set to zero while using texture blit.*/
2476     pthread_mutex_lock(&driver_data->output_mutex);
2477     if (render_target == driver_data->cur_displaying_surface)
2478         surface_status = VASurfaceDisplaying;
2479     else if ((VA_INVALID_SURFACE != driver_data->cur_displaying_surface)    /* use overlay */
2480              && (render_target == driver_data->last_displaying_surface)) {  /* It's the last displaying surface*/
2481         object_surface_p cur_obj_surface = SURFACE(driver_data->cur_displaying_surface);
2482         /*The flip operation on current displaying surface could be delayed to
2483          *  next VBlank and hadn't been finished yet. Then, the last displaying
2484          *  surface shouldn't be freed, because the hardware may not
2485          *  complete loading data of it. Any change of the last surface could
2486          *  have a impect on the scrren.*/
2487         if ((NULL != cur_obj_surface)
2488             && ((GetTickCount() - cur_obj_surface->display_timestamp) < PSB_MAX_FLIP_DELAY)) {
2489             surface_status = VASurfaceDisplaying;
2490         }
2491     }
2492     pthread_mutex_unlock(&driver_data->output_mutex);
2493 
2494     /* try to get frameskip flag for encode */
2495 #ifndef BAYTRAIL
2496     if (!decode) {
2497         /* The rendering surface may not be associated with any context. So driver should
2498            check the frame skip flag even variable encode is 0 */
2499 #ifdef PSBVIDEO_MRFL
2500         if (IS_MRFL(driver_data))
2501             tng_surface_get_frameskip(driver_data, obj_surface->psb_surface, &frame_skip);
2502         else
2503 #endif
2504             pnw_surface_get_frameskip(driver_data, obj_surface->psb_surface, &frame_skip);
2505 
2506         if (frame_skip == 1) {
2507             surface_status = surface_status | VASurfaceSkipped;
2508             drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s next frame of 0x%08x is skipped",
2509                     __FUNCTION__, render_target);
2510         }
2511     } else
2512 #endif
2513     if (decode) {
2514 #ifdef ANDROID
2515         if (obj_surface->psb_surface->buf.handle) {
2516             buffer_handle_t handle = obj_surface->psb_surface->buf.handle;
2517             int display_status;
2518             int err;
2519             err = gralloc_getdisplaystatus(handle, &display_status);
2520             if (!err) {
2521                 if (display_status)
2522                     surface_status = VASurfaceDisplaying;
2523                 else
2524                     surface_status = VASurfaceReady;
2525             } else {
2526                 surface_status = VASurfaceReady;
2527             }
2528 
2529             /* if not used by display, then check whether surface used by widi */
2530             if (surface_status == VASurfaceReady && obj_surface->share_info) {
2531                 if (obj_surface->share_info->renderStatus == 1) {
2532                     surface_status = VASurfaceDisplaying;
2533                 }
2534             }
2535         }
2536 #endif
2537     } else if (proc) {
2538         /* FIXME: does it need a new surface sync mechanism for FRC? */
2539     }
2540 
2541     *status = surface_status;
2542     DEBUG_FUNC_EXIT
2543     return vaStatus;
2544 }
2545 
psb_QuerySurfaceError(VADriverContextP ctx,VASurfaceID render_target,VAStatus error_status,void ** error_info)2546 VAStatus psb_QuerySurfaceError(
2547     VADriverContextP ctx,
2548     VASurfaceID render_target,
2549     VAStatus error_status,
2550     void **error_info /*out*/
2551 )
2552 {
2553     DEBUG_FUNC_ENTER
2554     INIT_DRIVER_DATA
2555     VAStatus vaStatus = VA_STATUS_SUCCESS;
2556     object_surface_p obj_surface;
2557     uint32_t i;
2558 
2559     obj_surface = SURFACE(render_target);
2560     CHECK_SURFACE(obj_surface);
2561 
2562 #ifdef PSBVIDEO_MSVDX_EC
2563     if (driver_data->ec_enabled == 0) {
2564 #else
2565     {
2566 #endif
2567         drv_debug_msg(VIDEO_DEBUG_GENERAL, "error concealment is not supported for this profile.\n");
2568         error_info = NULL;
2569         return VA_STATUS_ERROR_UNKNOWN;
2570     }
2571 
2572     if (error_status == VA_STATUS_ERROR_DECODING_ERROR) {
2573         drm_psb_msvdx_decode_status_t *decode_status = driver_data->msvdx_decode_status;
2574         struct drm_lnc_video_getparam_arg arg;
2575         uint32_t ret, handle;
2576         handle = wsbmKBufHandle(wsbmKBuf(obj_surface->psb_surface->buf.drm_buf));
2577 
2578         arg.key = IMG_VIDEO_MB_ERROR;
2579         arg.arg = (uint64_t)((unsigned long) & handle);
2580         arg.value = (uint64_t)((unsigned long)decode_status);
2581         ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
2582                                   &arg, sizeof(arg));
2583         if (ret != 0) {
2584                 drv_debug_msg(VIDEO_DEBUG_GENERAL,"return value is %d drmCommandWriteRead\n",ret);
2585                 return VA_STATUS_ERROR_UNKNOWN;
2586         }
2587 #ifndef _FOR_FPGA_
2588         if (decode_status->num_region > MAX_MB_ERRORS) {
2589             drv_debug_msg(VIDEO_DEBUG_GENERAL, "too much mb errors are reported.\n");
2590             return VA_STATUS_ERROR_UNKNOWN;
2591         }
2592         i = 0;
2593         for (i = 0; i < decode_status->num_region; ++i) {
2594             driver_data->surface_mb_error[i].status = 1;
2595             driver_data->surface_mb_error[i].start_mb = decode_status->mb_regions[i].start;
2596             driver_data->surface_mb_error[i].end_mb = decode_status->mb_regions[i].end;
2597             //driver_data->surface_mb_error[i].start_mb = decode_status->start_error_mb_list[i];
2598             //driver_data->surface_mb_error[i].end_mb = decode_status->end_error_mb_list[i];
2599             //driver_data->surface_mb_error[i].decode_error_type = decode_status->slice_missing_or_error[i];
2600         }
2601 #endif
2602         driver_data->surface_mb_error[i].status = -1;
2603         *error_info = driver_data->surface_mb_error;
2604     } else {
2605         error_info = NULL;
2606         return VA_STATUS_ERROR_UNKNOWN;
2607     }
2608     DEBUG_FUNC_EXIT
2609     return vaStatus;
2610 }
2611 
2612 #define PSB_MAX_SURFACE_ATTRIBUTES 16
2613 
2614 VAStatus psb_QuerySurfaceAttributes(VADriverContextP ctx,
2615                             VAConfigID config,
2616                             VASurfaceAttrib *attrib_list,
2617                             unsigned int *num_attribs)
2618 {
2619     DEBUG_FUNC_ENTER
2620     INIT_DRIVER_DATA
2621 
2622     VAStatus vaStatus = VA_STATUS_SUCCESS;
2623     object_config_p obj_config;
2624     unsigned int i = 0;
2625 
2626     CHECK_INVALID_PARAM(num_attribs == NULL);
2627 
2628     if (attrib_list == NULL) {
2629         *num_attribs = PSB_MAX_SURFACE_ATTRIBUTES;
2630         return VA_STATUS_SUCCESS;
2631     }
2632 
2633     obj_config = CONFIG(config);
2634     CHECK_CONFIG(obj_config);
2635 
2636     VASurfaceAttrib *attribs = NULL;
2637     attribs = malloc(PSB_MAX_SURFACE_ATTRIBUTES *sizeof(VASurfaceAttrib));
2638     if (attribs == NULL)
2639         return VA_STATUS_ERROR_ALLOCATION_FAILED;
2640 
2641     attribs[i].type = VASurfaceAttribPixelFormat;
2642     attribs[i].value.type = VAGenericValueTypeInteger;
2643     attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
2644     attribs[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
2645     i++;
2646 
2647     attribs[i].type = VASurfaceAttribMemoryType;
2648     attribs[i].value.type = VAGenericValueTypeInteger;
2649     attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
2650     if (obj_config->entrypoint == VAEntrypointEncSlice && obj_config->profile == VAProfileVP8Version0_3) {
2651         attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
2652             VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
2653             VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC |
2654             VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION;
2655     } else {
2656         attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
2657             VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
2658             VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR |
2659             VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC |
2660             VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION;
2661     }
2662     i++;
2663 
2664     attribs[i].type = VASurfaceAttribExternalBufferDescriptor;
2665     attribs[i].value.type = VAGenericValueTypePointer;
2666     attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
2667     attribs[i].value.value.p = NULL;
2668     i++;
2669 
2670     //modules have speical formats to support
2671     if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
2672 
2673     } else if (obj_config->entrypoint == VAEntrypointEncSlice ||  /* encode */
2674                    obj_config->entrypoint == VAEntrypointEncPicture) {
2675     #ifdef PSBVIDEO_MFLD
2676         if (IS_MFLD(driver_data)) {}
2677     #endif
2678     #ifdef PSBVIDEO_MRFL
2679         if (IS_MRFL(driver_data)) {}
2680     #endif
2681     #ifdef BAYTRAIL
2682         if (IS_BAYTRAIL(driver_data)) {}
2683     #endif
2684     }
2685     else if (obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
2686 
2687     }
2688 
2689     if (i > *num_attribs) {
2690         *num_attribs = i;
2691         return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
2692     }
2693 
2694     *num_attribs = i;
2695     memcpy(attrib_list, attribs, i * sizeof(*attribs));
2696     free(attribs);
2697 
2698     DEBUG_FUNC_EXIT
2699     return vaStatus;
2700 }
2701 
2702 VAStatus psb_LockSurface(
2703     VADriverContextP ctx,
2704     VASurfaceID surface,
2705     unsigned int *fourcc, /* following are output argument */
2706     unsigned int *luma_stride,
2707     unsigned int *chroma_u_stride,
2708     unsigned int *chroma_v_stride,
2709     unsigned int *luma_offset,
2710     unsigned int *chroma_u_offset,
2711     unsigned int *chroma_v_offset,
2712     unsigned int *buffer_name,
2713     void **buffer
2714 )
2715 {
2716     DEBUG_FUNC_ENTER
2717     INIT_DRIVER_DATA
2718     VAStatus vaStatus = VA_STATUS_SUCCESS;
2719     unsigned char *surface_data;
2720     int ret;
2721 
2722     object_surface_p obj_surface = SURFACE(surface);
2723     psb_surface_p psb_surface;
2724     CHECK_SURFACE(obj_surface);
2725 
2726     psb_surface = obj_surface->psb_surface;
2727     if (buffer_name)
2728         *buffer_name = (uint32_t)(wsbmKBufHandle(wsbmKBuf(psb_surface->buf.drm_buf)));
2729 
2730     if (buffer) { /* map the surface buffer */
2731         uint32_t srf_buf_ofs = 0;
2732         ret = psb_buffer_map(&psb_surface->buf, &surface_data);
2733         if (ret) {
2734             *buffer = NULL;
2735             vaStatus = VA_STATUS_ERROR_UNKNOWN;
2736             DEBUG_FAILURE;
2737             return vaStatus;
2738         }
2739         srf_buf_ofs = psb_surface->buf.buffer_ofs;
2740         *buffer = surface_data + srf_buf_ofs;
2741     }
2742 
2743     *fourcc = VA_FOURCC_NV12;
2744     *luma_stride = psb_surface->stride;
2745     *chroma_u_stride = psb_surface->stride;
2746     *chroma_v_stride = psb_surface->stride;
2747     *luma_offset = 0;
2748     *chroma_u_offset = obj_surface->height * psb_surface->stride;
2749     *chroma_v_offset = obj_surface->height * psb_surface->stride + 1;
2750     DEBUG_FUNC_EXIT
2751     return vaStatus;
2752 }
2753 
2754 
2755 VAStatus psb_UnlockSurface(
2756     VADriverContextP ctx,
2757     VASurfaceID surface
2758 )
2759 {
2760     DEBUG_FUNC_ENTER
2761     INIT_DRIVER_DATA
2762     VAStatus vaStatus = VA_STATUS_SUCCESS;
2763 
2764     object_surface_p obj_surface = SURFACE(surface);
2765     CHECK_SURFACE(obj_surface);
2766 
2767     psb_surface_p psb_surface = obj_surface->psb_surface;
2768 
2769     psb_buffer_unmap(&psb_surface->buf);
2770 
2771     DEBUG_FUNC_EXIT
2772     return VA_STATUS_SUCCESS;
2773 }
2774 
2775 VAStatus psb_GetEGLClientBufferFromSurface(
2776     VADriverContextP ctx,
2777     VASurfaceID surface,
2778     void **buffer
2779 )
2780 {
2781     DEBUG_FUNC_ENTER
2782     INIT_DRIVER_DATA
2783     VAStatus vaStatus = VA_STATUS_SUCCESS;
2784 
2785     object_surface_p obj_surface = SURFACE(surface);
2786     CHECK_SURFACE(obj_surface);
2787 
2788     psb_surface_p psb_surface = obj_surface->psb_surface;
2789     *buffer = (unsigned char *)psb_surface->bc_buffer;
2790 
2791     DEBUG_FUNC_EXIT
2792     return vaStatus;
2793 }
2794 
2795 VAStatus psb_PutSurfaceBuf(
2796     VADriverContextP ctx,
2797     VASurfaceID surface,
2798     unsigned char __maybe_unused * data,
2799     int __maybe_unused * data_len,
2800     short __maybe_unused srcx,
2801     short __maybe_unused srcy,
2802     unsigned short __maybe_unused srcw,
2803     unsigned short __maybe_unused srch,
2804     short __maybe_unused destx,
2805     short __maybe_unused desty,
2806     unsigned short __maybe_unused destw,
2807     unsigned short __maybe_unused desth,
2808     VARectangle __maybe_unused * cliprects, /* client supplied clip list */
2809     unsigned int __maybe_unused number_cliprects, /* number of clip rects in the clip list */
2810     unsigned int __maybe_unused flags /* de-interlacing flags */
2811 )
2812 {
2813     DEBUG_FUNC_ENTER
2814     INIT_DRIVER_DATA;
2815     object_surface_p obj_surface = SURFACE(surface);
2816     psb_surface_p psb_surface;
2817 
2818     obj_surface = SURFACE(surface);
2819     if (obj_surface == NULL)
2820         return VA_STATUS_ERROR_INVALID_SURFACE;
2821 
2822     psb_surface = obj_surface->psb_surface;
2823 
2824 #if 0
2825     psb_putsurface_textureblit(ctx, data, surface, srcx, srcy, srcw, srch, destx, desty, destw, desth, 1, /* check subpicture */
2826                                obj_surface->width, obj_surface->height,
2827                                psb_surface->stride, psb_surface->buf.drm_buf,
2828                                psb_surface->buf.pl_flags, 1 /* wrap dst */);
2829 #endif
2830 
2831     DEBUG_FUNC_EXIT
2832     return VA_STATUS_SUCCESS;
2833 }
2834 
2835 VAStatus psb_SetTimestampForSurface(
2836     VADriverContextP ctx,
2837     VASurfaceID surface,
2838     long long timestamp
2839 )
2840 {
2841     INIT_DRIVER_DATA;
2842     VAStatus vaStatus = VA_STATUS_SUCCESS;
2843     object_surface_p obj_surface = SURFACE(surface);
2844 
2845     obj_surface = SURFACE(surface);
2846     CHECK_SURFACE(obj_surface);
2847 
2848     if (obj_surface->share_info) {
2849         obj_surface->share_info->timestamp = timestamp;
2850         return VA_STATUS_SUCCESS;
2851     } else {
2852         return VA_STATUS_ERROR_UNKNOWN;
2853     }
2854 }
2855 
2856 int  LOCK_HARDWARE(psb_driver_data_p driver_data)
2857 {
2858     char ret = 0;
2859 
2860     if (driver_data->dri2 || driver_data->dri_dummy)
2861         return 0;
2862 
2863     pthread_mutex_lock(&driver_data->drm_mutex);
2864     DRM_CAS(driver_data->drm_lock, driver_data->drm_context,
2865             (DRM_LOCK_HELD | driver_data->drm_context), ret);
2866     if (ret) {
2867         ret = drmGetLock(driver_data->drm_fd, driver_data->drm_context, 0);
2868         /* driver_data->contended_lock=1; */
2869     }
2870 
2871     return ret;
2872 }
2873 
2874 int UNLOCK_HARDWARE(psb_driver_data_p driver_data)
2875 {
2876     /* driver_data->contended_lock=0; */
2877     if (driver_data->dri2 || driver_data->dri_dummy)
2878         return 0;
2879 
2880     DRM_UNLOCK(driver_data->drm_fd, driver_data->drm_lock, driver_data->drm_context);
2881     pthread_mutex_unlock(&driver_data->drm_mutex);
2882 
2883     return 0;
2884 }
2885 
2886 
2887 static void psb__deinitDRM(VADriverContextP ctx)
2888 {
2889     INIT_DRIVER_DATA
2890 
2891     if (driver_data->main_pool) {
2892         driver_data->main_pool->takeDown(driver_data->main_pool);
2893         driver_data->main_pool = NULL;
2894     }
2895     if (driver_data->fence_mgr) {
2896         wsbmFenceMgrTTMTakedown(driver_data->fence_mgr);
2897         driver_data->fence_mgr = NULL;
2898     }
2899 
2900     if (wsbmIsInitialized())
2901         wsbmTakedown();
2902 
2903     driver_data->drm_fd = -1;
2904 }
2905 
2906 
2907 static VAStatus psb__initDRI(VADriverContextP ctx)
2908 {
2909     INIT_DRIVER_DATA
2910     struct drm_state *drm_state = (struct drm_state *)ctx->drm_state;
2911 
2912     assert(dri_state);
2913 #ifdef _FOR_FPGA_
2914     dri_state->driConnectedFlag = VA_DUMMY;
2915     /* ON FPGA machine, psb may co-exist with gfx's drm driver */
2916     dri_state->fd = open("/dev/dri/card1", O_RDWR);
2917     if (dri_state->fd < 0)
2918         dri_state->fd = open("/dev/dri/card0", O_RDWR);
2919     assert(dri_state->fd >= 0);
2920 #endif
2921     assert(dri_state->driConnectedFlag == VA_DRI2 ||
2922            dri_state->driConnectedFlag == VA_DUMMY);
2923 
2924     driver_data->drm_fd = drm_state->fd;
2925     driver_data->dri_dummy = 1;
2926     driver_data->dri2 = 0;
2927     driver_data->ws_priv = NULL;
2928     driver_data->bus_id = NULL;
2929 
2930     return VA_STATUS_SUCCESS;
2931 }
2932 
2933 
2934 static VAStatus psb__initTTM(VADriverContextP ctx)
2935 {
2936     INIT_DRIVER_DATA
2937 
2938     const char drm_ext[] = "psb_ttm_placement_alphadrop";
2939     union drm_psb_extension_arg arg;
2940     struct _WsbmBufferPool *pool;
2941     int ret;
2942     const char exec_ext[] = "psb_ttm_execbuf_alphadrop";
2943     union drm_psb_extension_arg exec_arg;
2944     const char lncvideo_getparam_ext[] = "lnc_video_getparam";
2945     union drm_psb_extension_arg lncvideo_getparam_arg;
2946 
2947     /* init wsbm
2948      * WSBM node is not used in driver, thus can pass NULL Node callback
2949      */
2950     ret = wsbmInit(wsbmNullThreadFuncs(), NULL/*psbVNodeFuncs()*/);
2951     if (ret) {
2952         drv_debug_msg(VIDEO_DEBUG_ERROR, "failed initializing libwsbm.\n");
2953         return VA_STATUS_ERROR_UNKNOWN;
2954     }
2955 
2956     strncpy(arg.extension, drm_ext, sizeof(arg.extension));
2957     /* FIXME: should check dri enabled?
2958      * it seems not init dri here at all
2959      */
2960     ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION,
2961                               &arg, sizeof(arg));
2962     if (ret != 0 || !arg.rep.exists) {
2963         drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to detect DRM extension \"%s\", fd=%d\n",
2964                       drm_ext, driver_data->drm_fd);
2965         drv_debug_msg(VIDEO_DEBUG_ERROR, "found error %s (ret=%d), arg.rep.exists=%d",
2966                       strerror(errno), ret, arg.rep.exists);
2967 
2968         driver_data->main_pool = NULL;
2969         return VA_STATUS_ERROR_UNKNOWN;
2970     } else {
2971         pool = wsbmTTMPoolInit(driver_data->drm_fd,
2972                                arg.rep.driver_ioctl_offset);
2973         if (pool == NULL) {
2974             drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to get ttm pool\n");
2975             return VA_STATUS_ERROR_UNKNOWN;
2976         }
2977         driver_data->main_pool = pool;
2978     }
2979 
2980     strncpy(exec_arg.extension, exec_ext, sizeof(exec_arg.extension));
2981     ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION, &exec_arg,
2982                               sizeof(exec_arg));
2983     if (ret != 0 || !exec_arg.rep.exists) {
2984         drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to detect DRM extension \"%s\".\n",
2985                            exec_ext);
2986         return FALSE;
2987     }
2988     driver_data->execIoctlOffset = exec_arg.rep.driver_ioctl_offset;
2989 
2990     strncpy(lncvideo_getparam_arg.extension, lncvideo_getparam_ext, sizeof(lncvideo_getparam_arg.extension));
2991     ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION, &lncvideo_getparam_arg,
2992                               sizeof(lncvideo_getparam_arg));
2993     if (ret != 0 || !lncvideo_getparam_arg.rep.exists) {
2994         drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to detect DRM extension \"%s\".\n",
2995                            lncvideo_getparam_ext);
2996         /* return FALSE; */ /* not reture FALSE, so it still can run */
2997     }
2998     driver_data->getParamIoctlOffset = lncvideo_getparam_arg.rep.driver_ioctl_offset;
2999     return VA_STATUS_SUCCESS;
3000 }
3001 
3002 static VAStatus psb__initDRM(VADriverContextP ctx)
3003 {
3004     VAStatus vaStatus;
3005 
3006     vaStatus = psb__initDRI(ctx);
3007 
3008     if (vaStatus == VA_STATUS_SUCCESS)
3009         return psb__initTTM(ctx);
3010     else
3011         return vaStatus;
3012 }
3013 
3014 VAStatus psb_Terminate(VADriverContextP ctx)
3015 {
3016     DEBUG_FUNC_ENTER
3017     INIT_DRIVER_DATA
3018     object_subpic_p obj_subpic;
3019     object_image_p obj_image;
3020     object_buffer_p obj_buffer;
3021     object_surface_p obj_surface;
3022     object_context_p obj_context;
3023     object_config_p obj_config;
3024     object_heap_iterator iter;
3025 
3026     drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: begin to tear down\n");
3027 
3028     /* Clean up left over contexts */
3029     obj_context = (object_context_p) object_heap_first(&driver_data->context_heap, &iter);
3030     while (obj_context) {
3031         drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: contextID %08x still allocated, destroying\n", obj_context->base.id);
3032         psb__destroy_context(driver_data, obj_context);
3033         obj_context = (object_context_p) object_heap_next(&driver_data->context_heap, &iter);
3034     }
3035     object_heap_destroy(&driver_data->context_heap);
3036 
3037     /* Clean up SubpicIDs */
3038     obj_subpic = (object_subpic_p) object_heap_first(&driver_data->subpic_heap, &iter);
3039     while (obj_subpic) {
3040         drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: subpictureID %08x still allocated, destroying\n", obj_subpic->base.id);
3041         psb__destroy_subpicture(driver_data, obj_subpic);
3042         obj_subpic = (object_subpic_p) object_heap_next(&driver_data->subpic_heap, &iter);
3043     }
3044     object_heap_destroy(&driver_data->subpic_heap);
3045 
3046     /* Clean up ImageIDs */
3047     obj_image = (object_image_p) object_heap_first(&driver_data->image_heap, &iter);
3048     while (obj_image) {
3049         drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: imageID %08x still allocated, destroying\n", obj_image->base.id);
3050         psb__destroy_image(driver_data, obj_image);
3051         obj_image = (object_image_p) object_heap_next(&driver_data->image_heap, &iter);
3052     }
3053     object_heap_destroy(&driver_data->image_heap);
3054 
3055     /* Clean up left over buffers */
3056     obj_buffer = (object_buffer_p) object_heap_first(&driver_data->buffer_heap, &iter);
3057     while (obj_buffer) {
3058         drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: bufferID %08x still allocated, destroying\n", obj_buffer->base.id);
3059         psb__destroy_buffer(driver_data, obj_buffer);
3060         obj_buffer = (object_buffer_p) object_heap_next(&driver_data->buffer_heap, &iter);
3061     }
3062     object_heap_destroy(&driver_data->buffer_heap);
3063 
3064     /* Clean up left over surfaces */
3065 
3066 #if 0
3067     /* Free PVR2D buffer wrapped from the surfaces */
3068     psb_free_surface_pvr2dbuf(driver_data);
3069 #endif
3070     obj_surface = (object_surface_p) object_heap_first(&driver_data->surface_heap, &iter);
3071     while (obj_surface) {
3072         drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: surfaceID %08x still allocated, destroying\n", obj_surface->base.id);
3073         psb__destroy_surface(driver_data, obj_surface);
3074         obj_surface = (object_surface_p) object_heap_next(&driver_data->surface_heap, &iter);
3075     }
3076     object_heap_destroy(&driver_data->surface_heap);
3077 
3078     /* Clean up configIDs */
3079     obj_config = (object_config_p) object_heap_first(&driver_data->config_heap, &iter);
3080     while (obj_config) {
3081         object_heap_free(&driver_data->config_heap, (object_base_p) obj_config);
3082         obj_config = (object_config_p) object_heap_next(&driver_data->config_heap, &iter);
3083     }
3084     object_heap_destroy(&driver_data->config_heap);
3085 
3086     if (driver_data->camera_bo) {
3087         drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: clearup camera global BO\n");
3088 
3089         psb_buffer_destroy((psb_buffer_p)driver_data->camera_bo);
3090         free(driver_data->camera_bo);
3091         driver_data->camera_bo = NULL;
3092     }
3093 
3094     if (driver_data->rar_bo) {
3095         drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: clearup RAR global BO\n");
3096 
3097         psb_buffer_destroy((psb_buffer_p)driver_data->rar_bo);
3098         free(driver_data->rar_bo);
3099         driver_data->rar_bo = NULL;
3100     }
3101 
3102     if (driver_data->ws_priv) {
3103         drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: tear down output portion\n");
3104 
3105         psb_deinitOutput(ctx);
3106         driver_data->ws_priv = NULL;
3107     }
3108 
3109     drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: de-initialized DRM\n");
3110 
3111     psb__deinitDRM(ctx);
3112 
3113     if (driver_data->msvdx_decode_status)
3114         free(driver_data->msvdx_decode_status);
3115 
3116     if (driver_data->surface_mb_error)
3117         free(driver_data->surface_mb_error);
3118 
3119     pthread_mutex_destroy(&driver_data->drm_mutex);
3120     free(ctx->pDriverData);
3121     free(ctx->vtable_egl);
3122     free(ctx->vtable_tpi);
3123 
3124     ctx->pDriverData = NULL;
3125     drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: goodbye\n\n");
3126 
3127     psb__close_log();
3128     DEBUG_FUNC_EXIT
3129     return VA_STATUS_SUCCESS;
3130 }
3131 
3132 EXPORT VAStatus __vaDriverInit_0_31(VADriverContextP ctx)
3133 {
3134     psb_driver_data_p driver_data;
3135     struct VADriverVTableTPI *tpi;
3136     struct VADriverVTableEGL *va_egl;
3137     int result;
3138     if (psb_video_trace_fp) {
3139         /* make gdb always stop here */
3140         signal(SIGUSR1, SIG_IGN);
3141         kill(getpid(), SIGUSR1);
3142     }
3143 
3144     psb__open_log();
3145 
3146     drv_debug_msg(VIDEO_DEBUG_INIT, "vaInitilize: start the journey\n");
3147 
3148     ctx->version_major = 0;
3149     ctx->version_minor = 31;
3150 
3151     ctx->max_profiles = PSB_MAX_PROFILES;
3152     ctx->max_entrypoints = PSB_MAX_ENTRYPOINTS;
3153     ctx->max_attributes = PSB_MAX_CONFIG_ATTRIBUTES;
3154     ctx->max_image_formats = PSB_MAX_IMAGE_FORMATS;
3155     ctx->max_subpic_formats = PSB_MAX_SUBPIC_FORMATS;
3156     ctx->max_display_attributes = PSB_MAX_DISPLAY_ATTRIBUTES;
3157 
3158     ctx->vtable->vaTerminate = psb_Terminate;
3159     ctx->vtable->vaQueryConfigEntrypoints = psb_QueryConfigEntrypoints;
3160     ctx->vtable->vaTerminate = psb_Terminate;
3161     ctx->vtable->vaQueryConfigProfiles = psb_QueryConfigProfiles;
3162     ctx->vtable->vaQueryConfigEntrypoints = psb_QueryConfigEntrypoints;
3163     ctx->vtable->vaQueryConfigAttributes = psb_QueryConfigAttributes;
3164     ctx->vtable->vaCreateConfig = psb_CreateConfig;
3165     ctx->vtable->vaDestroyConfig = psb_DestroyConfig;
3166     ctx->vtable->vaGetConfigAttributes = psb_GetConfigAttributes;
3167     ctx->vtable->vaCreateSurfaces2 = psb_CreateSurfaces2;
3168     ctx->vtable->vaCreateSurfaces = psb_CreateSurfaces;
3169     ctx->vtable->vaGetSurfaceAttributes = psb_GetSurfaceAttributes;
3170     ctx->vtable->vaDestroySurfaces = psb_DestroySurfaces;
3171     ctx->vtable->vaCreateContext = psb_CreateContext;
3172     ctx->vtable->vaDestroyContext = psb_DestroyContext;
3173     ctx->vtable->vaCreateBuffer = psb_CreateBuffer;
3174     ctx->vtable->vaBufferSetNumElements = psb_BufferSetNumElements;
3175     ctx->vtable->vaMapBuffer = psb_MapBuffer;
3176     ctx->vtable->vaUnmapBuffer = psb_UnmapBuffer;
3177     ctx->vtable->vaDestroyBuffer = psb_DestroyBuffer;
3178     ctx->vtable->vaBeginPicture = psb_BeginPicture;
3179     ctx->vtable->vaRenderPicture = psb_RenderPicture;
3180     ctx->vtable->vaEndPicture = psb_EndPicture;
3181     ctx->vtable->vaSyncSurface = psb_SyncSurface;
3182     ctx->vtable->vaQuerySurfaceStatus = psb_QuerySurfaceStatus;
3183     ctx->vtable->vaQuerySurfaceError = psb_QuerySurfaceError;
3184     ctx->vtable->vaPutSurface = psb_PutSurface;
3185     ctx->vtable->vaQueryImageFormats = psb_QueryImageFormats;
3186     ctx->vtable->vaCreateImage = psb_CreateImage;
3187     ctx->vtable->vaDeriveImage = psb_DeriveImage;
3188     ctx->vtable->vaDestroyImage = psb_DestroyImage;
3189     ctx->vtable->vaSetImagePalette = psb_SetImagePalette;
3190     ctx->vtable->vaGetImage = psb_GetImage;
3191     ctx->vtable->vaPutImage = psb_PutImage;
3192     ctx->vtable->vaQuerySubpictureFormats = psb_QuerySubpictureFormats;
3193     ctx->vtable->vaCreateSubpicture = psb_CreateSubpicture;
3194     ctx->vtable->vaDestroySubpicture = psb_DestroySubpicture;
3195     ctx->vtable->vaSetSubpictureImage = psb_SetSubpictureImage;
3196     ctx->vtable->vaSetSubpictureChromakey = psb_SetSubpictureChromakey;
3197     ctx->vtable->vaSetSubpictureGlobalAlpha = psb_SetSubpictureGlobalAlpha;
3198     ctx->vtable->vaAssociateSubpicture = psb_AssociateSubpicture;
3199     ctx->vtable->vaDeassociateSubpicture = psb_DeassociateSubpicture;
3200     ctx->vtable->vaQueryDisplayAttributes = psb_QueryDisplayAttributes;
3201     ctx->vtable->vaGetDisplayAttributes = psb_GetDisplayAttributes;
3202     ctx->vtable->vaSetDisplayAttributes = psb_SetDisplayAttributes;
3203     ctx->vtable->vaQuerySurfaceAttributes = psb_QuerySurfaceAttributes;
3204     ctx->vtable->vaBufferInfo = psb_BufferInfo;
3205     ctx->vtable->vaLockSurface = psb_LockSurface;
3206     ctx->vtable->vaUnlockSurface = psb_UnlockSurface;
3207 #ifdef PSBVIDEO_MRFL_VPP
3208     ctx->vtable_vpp->vaQueryVideoProcFilters = vsp_QueryVideoProcFilters;
3209     ctx->vtable_vpp->vaQueryVideoProcFilterCaps = vsp_QueryVideoProcFilterCaps;
3210     ctx->vtable_vpp->vaQueryVideoProcPipelineCaps = vsp_QueryVideoProcPipelineCaps;
3211 #endif
3212 
3213 #ifdef PSBVIDEO_MFLD
3214     ctx->vtable_vpp->vaQueryVideoProcFilters = ved_QueryVideoProcFilters;
3215     ctx->vtable_vpp->vaQueryVideoProcFilterCaps = ved_QueryVideoProcFilterCaps;
3216     ctx->vtable_vpp->vaQueryVideoProcPipelineCaps = ved_QueryVideoProcPipelineCaps;
3217 #endif
3218 
3219     ctx->vtable_tpi = calloc(1, sizeof(struct VADriverVTableTPI));
3220     if (NULL == ctx->vtable_tpi)
3221         return VA_STATUS_ERROR_ALLOCATION_FAILED;
3222 
3223     tpi = (struct VADriverVTableTPI *)ctx->vtable_tpi;
3224     tpi->vaCreateSurfacesWithAttribute = psb_CreateSurfacesWithAttribute;
3225     tpi->vaPutSurfaceBuf = psb_PutSurfaceBuf;
3226         tpi->vaSetTimestampForSurface = psb_SetTimestampForSurface;
3227 
3228     ctx->vtable_egl = calloc(1, sizeof(struct VADriverVTableEGL));
3229     if (NULL == ctx->vtable_egl)
3230         return VA_STATUS_ERROR_ALLOCATION_FAILED;
3231 
3232     va_egl = (struct VADriverVTableEGL *)ctx->vtable_egl;
3233     va_egl->vaGetEGLClientBufferFromSurface = psb_GetEGLClientBufferFromSurface;
3234 
3235     driver_data = (psb_driver_data_p) calloc(1, sizeof(*driver_data));
3236     ctx->pDriverData = (unsigned char *) driver_data;
3237     if (NULL == driver_data) {
3238         if (ctx->vtable_tpi)
3239             free(ctx->vtable_tpi);
3240         if (ctx->vtable_egl)
3241             free(ctx->vtable_egl);
3242         return VA_STATUS_ERROR_ALLOCATION_FAILED;
3243     }
3244 
3245     if (VA_STATUS_SUCCESS != psb__initDRM(ctx)) {
3246         free(ctx->pDriverData);
3247         ctx->pDriverData = NULL;
3248         return VA_STATUS_ERROR_UNKNOWN;
3249     }
3250 
3251     pthread_mutex_init(&driver_data->drm_mutex, NULL);
3252 
3253     /*
3254      * To read PBO.MSR.CCF Mode and Status Register C-Spec -p112
3255      */
3256 #define PCI_PORT5_REG80_VIDEO_SD_DISABLE        0x0008
3257 #define PCI_PORT5_REG80_VIDEO_HD_DISABLE        0x0010
3258 
3259 #if 0
3260     struct drm_psb_hw_info hw_info;
3261     do {
3262         result = drmCommandRead(driver_data->drm_fd, DRM_PSB_HW_INFO, &hw_info, sizeof(hw_info));
3263     } while (result == EAGAIN);
3264 
3265     if (result != 0) {
3266         psb__deinitDRM(ctx);
3267         free(ctx->pDriverData);
3268         ctx->pDriverData = NULL;
3269         return VA_STATUS_ERROR_UNKNOWN;
3270     }
3271 
3272     driver_data->video_sd_disabled = !!(hw_info.caps & PCI_PORT5_REG80_VIDEO_SD_DISABLE);
3273     driver_data->video_hd_disabled = !!(hw_info.caps & PCI_PORT5_REG80_VIDEO_HD_DISABLE);
3274     drv_debug_msg(VIDEO_DEBUG_GENERAL, "hw_info: rev_id = %08x capabilities = %08x\n", hw_info.rev_id, hw_info.caps);
3275     drv_debug_msg(VIDEO_DEBUG_GENERAL, "hw_info: video_sd_disable=%d,video_hd_disable=%d\n",
3276                              driver_data->video_sd_disabled, driver_data->video_hd_disabled);
3277     if (driver_data->video_sd_disabled != 0) {
3278         drv_debug_msg(VIDEO_DEBUG_ERROR, "MRST: hw_info shows video_sd_disable is true,fix it manually\n");
3279         driver_data->video_sd_disabled = 0;
3280     }
3281     if (driver_data->video_hd_disabled != 0) {
3282         drv_debug_msg(VIDEO_DEBUG_ERROR, "MRST: hw_info shows video_hd_disable is true,fix it manually\n");
3283         driver_data->video_hd_disabled = 0;
3284     }
3285 #endif
3286 
3287     if (0 != psb_get_device_info(ctx)) {
3288         drv_debug_msg(VIDEO_DEBUG_ERROR, "ERROR: failed to get video device info\n");
3289         driver_data->encode_supported = 1;
3290         driver_data->decode_supported = 1;
3291         driver_data->hd_encode_supported = 1;
3292         driver_data->hd_decode_supported = 1;
3293     }
3294 
3295 #if 0
3296     psb_init_surface_pvr2dbuf(driver_data);
3297 #endif
3298 
3299     if (VA_STATUS_SUCCESS != psb_initOutput(ctx)) {
3300         pthread_mutex_destroy(&driver_data->drm_mutex);
3301         psb__deinitDRM(ctx);
3302         free(ctx->pDriverData);
3303         ctx->pDriverData = NULL;
3304         return VA_STATUS_ERROR_UNKNOWN;
3305     }
3306 
3307     driver_data->msvdx_context_base = (((unsigned int) getpid()) & 0xffff) << 16;
3308 #ifdef PSBVIDEO_MRFL
3309     if (IS_MRFL(driver_data)) {
3310         drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield topazhp encoder\n");
3311         driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3312         driver_data->profile2Format[VAProfileH264Main][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3313         driver_data->profile2Format[VAProfileH264High][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3314         driver_data->profile2Format[VAProfileH264StereoHigh][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3315         driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointEncSlice] = &tng_H263ES_vtable;
3316         driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointEncPicture] = &tng_JPEGES_vtable;
3317         driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointEncSlice] = &tng_MPEG4ES_vtable;
3318         driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointEncSlice] = &tng_MPEG4ES_vtable;
3319         driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3320     }
3321 #endif
3322 #ifdef PSBVIDEO_MRFL_VPP
3323     if (IS_MRFL(driver_data)) {
3324         drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield vsp vpp\n");
3325         driver_data->vpp_profile = &vsp_VPP_vtable;
3326         driver_data->profile2Format[VAProfileVP8Version0_3][VAEntrypointEncSlice] = &vsp_VP8_vtable;
3327     }
3328 #endif
3329 
3330 #ifdef PSBVIDEO_VXD392
3331     if (IS_MRFL(driver_data) || IS_BAYTRAIL(driver_data)) {
3332         drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield VXD392 decoder\n");
3333         driver_data->profile2Format[VAProfileVP8Version0_3][VAEntrypointVLD] = &tng_VP8_vtable;
3334         driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointVLD] = &tng_JPEG_vtable;
3335 
3336         driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3337         driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3338 
3339         driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3340 
3341         driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointVLD] = &pnw_H264_vtable;
3342         driver_data->profile2Format[VAProfileH264Main][VAEntrypointVLD] = &pnw_H264_vtable;
3343         driver_data->profile2Format[VAProfileH264High][VAEntrypointVLD] = &pnw_H264_vtable;
3344 
3345         driver_data->profile2Format[VAProfileVC1Simple][VAEntrypointVLD] = &pnw_VC1_vtable;
3346         driver_data->profile2Format[VAProfileVC1Main][VAEntrypointVLD] = &pnw_VC1_vtable;
3347         driver_data->profile2Format[VAProfileVC1Advanced][VAEntrypointVLD] = &pnw_VC1_vtable;
3348         driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointVLD] = &pnw_H264_vtable;
3349     }
3350 #endif
3351 
3352 #ifdef PSBVIDEO_MRFL_VPP
3353     if (IS_MRFL(driver_data)) {
3354         if (*((unsigned int *)ctx->native_dpy) == 0x56454450 /* VEDP */) {
3355 
3356             drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield ved vpp\n");
3357             driver_data->vpp_profile = &tng_yuv_processor_vtable;
3358             ctx->vtable_vpp->vaQueryVideoProcFilters = ved_QueryVideoProcFilters;
3359             ctx->vtable_vpp->vaQueryVideoProcFilterCaps = ved_QueryVideoProcFilterCaps;
3360             ctx->vtable_vpp->vaQueryVideoProcPipelineCaps = ved_QueryVideoProcPipelineCaps;
3361             driver_data->ved_vpp = 1;
3362         }
3363     }
3364 #endif
3365 
3366 #ifdef PSBVIDEO_MFLD
3367     if (IS_MFLD(driver_data)) {
3368         driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointEncSlice] = &pnw_H263ES_vtable;
3369         driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointEncSlice] = &pnw_H264ES_vtable;
3370         driver_data->profile2Format[VAProfileH264Main][VAEntrypointEncSlice] = &pnw_H264ES_vtable;
3371         driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointEncSlice] = &pnw_MPEG4ES_vtable;
3372         driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointEncSlice] = &pnw_MPEG4ES_vtable;
3373         driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointEncPicture] = &pnw_JPEG_vtable;
3374 
3375         driver_data->profile2Format[VAProfileMPEG2Main][VAEntrypointVLD] = &pnw_MPEG2_vtable;
3376 
3377         driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3378         driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3379 
3380         driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3381 
3382         driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointVLD] = &pnw_H264_vtable;
3383         driver_data->profile2Format[VAProfileH264Main][VAEntrypointVLD] = &pnw_H264_vtable;
3384         driver_data->profile2Format[VAProfileH264High][VAEntrypointVLD] = &pnw_H264_vtable;
3385 
3386         driver_data->profile2Format[VAProfileVC1Simple][VAEntrypointVLD] = &pnw_VC1_vtable;
3387         driver_data->profile2Format[VAProfileVC1Main][VAEntrypointVLD] = &pnw_VC1_vtable;
3388         driver_data->profile2Format[VAProfileVC1Advanced][VAEntrypointVLD] = &pnw_VC1_vtable;
3389         driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointVLD] = &pnw_H264_vtable;
3390 
3391         driver_data->vpp_profile = &tng_yuv_processor_vtable;
3392         driver_data->ved_vpp = 1;
3393     }
3394 #endif
3395 
3396     result = object_heap_init(&driver_data->config_heap, sizeof(struct object_config_s), CONFIG_ID_OFFSET);
3397     ASSERT(result == 0);
3398 
3399     result = object_heap_init(&driver_data->context_heap, sizeof(struct object_context_s), CONTEXT_ID_OFFSET);
3400     ASSERT(result == 0);
3401 
3402     result = object_heap_init(&driver_data->surface_heap, sizeof(struct object_surface_s), SURFACE_ID_OFFSET);
3403     ASSERT(result == 0);
3404 
3405     result = object_heap_init(&driver_data->buffer_heap, sizeof(struct object_buffer_s), BUFFER_ID_OFFSET);
3406     ASSERT(result == 0);
3407 
3408     result = object_heap_init(&driver_data->image_heap, sizeof(struct object_image_s), IMAGE_ID_OFFSET);
3409     ASSERT(result == 0);
3410 
3411     result = object_heap_init(&driver_data->subpic_heap, sizeof(struct object_subpic_s), SUBPIC_ID_OFFSET);
3412     ASSERT(result == 0);
3413 
3414     driver_data->cur_displaying_surface = VA_INVALID_SURFACE;
3415     driver_data->last_displaying_surface = VA_INVALID_SURFACE;
3416 
3417     driver_data->clear_color = 0;
3418     driver_data->blend_color = 0;
3419     driver_data->blend_mode = 0;
3420     driver_data->overlay_auto_paint_color_key = 0;
3421 
3422     if (IS_BAYTRAIL(driver_data))
3423         ctx->str_vendor = PSB_STR_VENDOR_BAYTRAIL;
3424     if (IS_MRFL(driver_data))
3425         ctx->str_vendor = PSB_STR_VENDOR_MRFL;
3426     else if (IS_MFLD(driver_data))
3427     {
3428         if (IS_LEXINGTON(driver_data))
3429             ctx->str_vendor = PSB_STR_VENDOR_LEXINGTON;
3430         else
3431             ctx->str_vendor = PSB_STR_VENDOR_MFLD;
3432     }
3433     else
3434         ctx->str_vendor = PSB_STR_VENDOR_MRST;
3435 
3436     driver_data->msvdx_decode_status = calloc(1, sizeof(drm_psb_msvdx_decode_status_t));
3437     if (NULL == driver_data->msvdx_decode_status) {
3438         pthread_mutex_destroy(&driver_data->drm_mutex);
3439         return VA_STATUS_ERROR_ALLOCATION_FAILED;
3440     }
3441     driver_data->surface_mb_error = calloc(MAX_MB_ERRORS, sizeof(VASurfaceDecodeMBErrors));
3442     if (NULL == driver_data->surface_mb_error) {
3443         pthread_mutex_destroy(&driver_data->drm_mutex);
3444         return VA_STATUS_ERROR_ALLOCATION_FAILED;
3445     }
3446 
3447     drv_debug_msg(VIDEO_DEBUG_INIT, "vaInitilize: succeeded!\n\n");
3448 
3449 #ifdef ANDROID
3450 #ifndef PSBVIDEO_VXD392
3451     gralloc_init();
3452 #endif
3453 #endif
3454 
3455     return VA_STATUS_SUCCESS;
3456 }
3457 
3458 
3459 EXPORT VAStatus __vaDriverInit_0_32(VADriverContextP ctx)
3460 {
3461     return __vaDriverInit_0_31(ctx);
3462 }
3463 
3464 
3465 
3466 static int psb_get_device_info(VADriverContextP ctx)
3467 {
3468     INIT_DRIVER_DATA;
3469     struct drm_lnc_video_getparam_arg arg;
3470     unsigned long device_info;
3471     int ret = 0;
3472     unsigned long video_capability;
3473     unsigned long pci_device;
3474 
3475     driver_data->dev_id = 0x4100; /* by default MRST */
3476 
3477     arg.key = LNC_VIDEO_DEVICE_INFO;
3478     arg.value = (uint64_t)((unsigned long) & device_info);
3479     ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
3480                               &arg, sizeof(arg));
3481     if (ret != 0) {
3482         drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to get video device info\n");
3483         return ret;
3484     }
3485 
3486     pci_device = (device_info >> 16) & 0xffff;
3487     video_capability = device_info & 0xffff;
3488 
3489     driver_data->dev_id = pci_device;
3490     drv_debug_msg(VIDEO_DEBUG_INIT, "Retrieve Device ID 0x%08x\n", driver_data->dev_id);
3491 
3492     if (IS_MFLD(driver_data) || IS_MRFL(driver_data))
3493         driver_data->encode_supported = 1;
3494     else /* 0x4101 or other device hasn't encode support */
3495         driver_data->encode_supported = 0;
3496 
3497     driver_data->decode_supported = 1;
3498     driver_data->hd_decode_supported = 1;
3499     driver_data->hd_encode_supported = 1;
3500 
3501     return ret;
3502 }
3503