psb_output_android.c revision 0a86723905982451dd72a9cad792b8cb8e8528ae
1/* 2 * Copyright (c) 2011 Intel Corporation. All Rights Reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the 6 * "Software"), to deal in the Software without restriction, including 7 * without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sub license, and/or sell copies of the Software, and to 9 * permit persons to whom the Software is furnished to do so, subject to 10 * the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the 13 * next paragraph) shall be included in all copies or substantial portions 14 * of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 19 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 20 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Zhaohan Ren <zhaohan.ren@intel.com> 26 * Shengquan Yuan <shengquan.yuan@intel.com> 27 * Jiang Fei <jiang.fei@intel.com> 28 * Binglin Chen <binglin.chen@intel.com> 29 * 30 */ 31 32#include <va/va_backend.h> 33#include "psb_output.h" 34#include "psb_surface.h" 35#include "psb_buffer.h" 36#include "psb_overlay.h" 37#include "psb_texture.h" 38#include <stdio.h> 39#include <string.h> 40#include <stdarg.h> 41#include "psb_android_glue.h" 42#include "psb_texstreaming.h" 43#include "psb_output_android.h" 44#include "psb_HDMIExtMode.h" 45#include "pnw_rotate.h" 46#include <wsbm/wsbm_manager.h> 47#include <psb_drm.h> 48#include <hardware.h> 49 50#define INIT_DRIVER_DATA psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData; 51#define INIT_OUTPUT_PRIV psb_android_output_p output = (psb_android_output_p)(((psb_driver_data_p)ctx->pDriverData)->ws_priv) 52 53#define SURFACE(id) ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id )) 54#define BUFFER(id) ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id )) 55#define IMAGE(id) ((object_image_p) object_heap_lookup( &driver_data->image_heap, id )) 56#define SUBPIC(id) ((object_subpic_p) object_heap_lookup( &driver_data->subpic_heap, id )) 57#define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id )) 58 59#define GET_SURFACE_INFO_rotate(psb_surface) ((int) psb_surface->extra_info[5]) 60#define GET_SURFACE_INFO_protect(psb_surface) ((int) psb_surface->extra_info[6]) 61#define MAX_OVERLAY_IDLE_FRAME 4 62 63enum { 64 eWidiOff = 1, 65 eWidiClone = 2, 66 eWidiExtendedVideo = 3, 67}; 68extern unsigned int update_forced; 69 70inline int va2hw_rotation(int va_rotate) 71{ 72 switch (va_rotate) { 73 case VA_ROTATION_90: 74 return HAL_TRANSFORM_ROT_270; 75 case VA_ROTATION_180: 76 return HAL_TRANSFORM_ROT_180; 77 case VA_ROTATION_270: 78 return HAL_TRANSFORM_ROT_90; 79defaut: 80 return 0; 81 } 82 83 return 0; 84} 85 86void *psb_android_output_init(VADriverContextP ctx) 87{ 88 INIT_DRIVER_DATA; 89 char put_surface[1024]; 90 struct drm_psb_register_rw_arg regs; 91 psb_android_output_p output = calloc(1, sizeof(psb_android_output_s)); 92 struct fb_var_screeninfo vinfo; 93 int fbfd = -1; 94 int ret; 95 96 if (output == NULL) { 97 psb__error_message("Can't malloc memory\n"); 98 return NULL; 99 } 100 memset(output, 0, sizeof(psb_android_output_s)); 101 102 /* Guess the screen size */ 103 output->screen_width = 800; 104 output->screen_height = 480; 105 106 // Open the frame buffer for reading 107 memset(&vinfo, 0, sizeof(vinfo)); 108 fbfd = open("/dev/graphics/fb0", O_RDONLY); 109 if (fbfd) { 110 if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) 111 psb__information_message("Error reading screen information.\n"); 112 } 113 close(fbfd); 114 output->screen_width = vinfo.xres; 115 output->screen_height = vinfo.yres; 116 117 /* TS by default */ 118 driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING; 119 driver_data->color_key = 0x000001; /*light blue*/ 120 driver_data->overlay_idle_frame = 1; 121 122 if (psb_parse_config("PSB_VIDEO_CTEXTURES", &put_surface[0]) == 0) { 123 psb__information_message("PSB_VIDEO_CTEXTURES is enabled for vaPutSurfaceBuf\n"); 124 driver_data->ctexture = 1; /* Init CTEXTURE for vaPutSurfaceBuf */ 125 } 126 127 if (psb_parse_config("PSB_VIDEO_TS", &put_surface[0]) == 0) { 128 psb__information_message("Putsurface use texstreaming\n"); 129 driver_data->output_method = PSB_PUTSURFACE_FORCE_TEXSTREAMING; 130 } 131 132 if (psb_parse_config("PSB_VIDEO_COVERLAY", &put_surface[0]) == 0) { 133 psb__information_message("Putsurface use client overlay\n"); 134 driver_data->output_method = PSB_PUTSURFACE_FORCE_COVERLAY; 135 } 136 137 if (IS_MFLD(driver_data)) { 138 driver_data->coverlay = 1; 139 output->psb_HDMIExt_info = psb_HDMIExt_init(ctx, output); 140 if (!output->psb_HDMIExt_info) { 141 psb__error_message("Failed to init psb_HDMIExt.\n"); 142 free(output); 143 return NULL; 144 } 145 } 146 147 return output; 148} 149 150VAStatus psb_android_output_deinit(VADriverContextP ctx) 151{ 152 INIT_DRIVER_DATA; 153 INIT_OUTPUT_PRIV; 154 //psb_android_output_p output = GET_OUTPUT_DATA(ctx); 155 if (IS_MFLD(driver_data)) { 156 psb_HDMIExt_deinit(output); 157 } 158 159 return VA_STATUS_SUCCESS; 160} 161 162static VAStatus psb_putsurface_ctexture( 163 VADriverContextP ctx, 164 VASurfaceID surface, 165 unsigned char* data, 166 short srcx, 167 short srcy, 168 unsigned short srcw, 169 unsigned short srch, 170 short destx, 171 short desty, 172 unsigned short destw, 173 unsigned short desth, 174 unsigned int flags /* de-interlacing flags */ 175) 176{ 177 INIT_DRIVER_DATA; 178 INIT_OUTPUT_PRIV; 179 object_surface_p obj_surface = SURFACE(surface); 180 int offset = 0; 181 psb_surface_p psb_surface; 182 183 obj_surface = SURFACE(surface); 184 psb_surface = obj_surface->psb_surface; 185 186 // psb_surface->buf.drm_buf; 187 // psb_surface->buf.pl_flags; 188 psb_putsurface_textureblit(ctx, data, surface, srcx, srcy, srcw, srch, 189 destx, desty, destw, desth, 0, /* no subtitle */ 190 obj_surface->width, obj_surface->height, 191 psb_surface->stride, psb_surface->buf.drm_buf, 192 psb_surface->buf.pl_flags, 1 /* need wrap dst */); 193 194 psb_android_postBuffer(offset); 195 196 return VA_STATUS_SUCCESS; 197} 198 199VAStatus psb_putsurface_coverlay( 200 VADriverContextP ctx, 201 VASurfaceID surface, 202 short srcx, 203 short srcy, 204 unsigned short srcw, 205 unsigned short srch, 206 short destx, /* screen cooridination */ 207 short desty, 208 unsigned short destw, 209 unsigned short desth, 210 unsigned int flags /* de-interlacing flags */ 211) 212{ 213 INIT_OUTPUT_PRIV; 214 VAStatus vaStatus = VA_STATUS_SUCCESS; 215 216 /* USE_FIT_SCR_SIZE */ 217 /* calculate fit screen size of frame */ 218 unsigned short _scr_x = output->screen_width; 219 unsigned short _scr_y = output->screen_height; 220 float _slope_xy = (float)srch / srcw; 221 unsigned short _destw = (short)(_scr_y / _slope_xy); 222 unsigned short _desth = (short)(_scr_x * _slope_xy); 223 short _pos_x, _pos_y; 224 225 if (_destw <= _scr_x) { 226 _desth = _scr_y; 227 _pos_x = (_scr_x - _destw) >> 1; 228 _pos_y = 0; 229 } else { 230 _destw = _scr_x; 231 _pos_x = 0; 232 _pos_y = (_scr_y - _desth) >> 1; 233 } 234 destx += _pos_x; 235 desty += _pos_y; 236 destw = _destw; 237 desth = _desth; 238 239 psb__information_message("psb_putsurface_overlay: src (%d, %d, %d, %d), destx (%d, %d, %d, %d).\n", 240 srcx, srcy, srcw, srch, destx, desty, destw, desth); 241 /* display by overlay */ 242 vaStatus = psb_putsurface_overlay( 243 ctx, surface, srcx, srcy, srcw, srch, 244 destx, desty, destw, desth, /* screen coordinate */ 245 flags, OVERLAY_A, PIPEA); 246 247 return vaStatus; 248} 249 250 251VAStatus psb_putsurface_ts( 252 VADriverContextP ctx, 253 VASurfaceID surface, 254 void *android_isurface, 255 int buffer_index, 256 short srcx, 257 short srcy, 258 unsigned short srcw, 259 unsigned short srch, 260 short destx, 261 short desty, 262 unsigned short destw, 263 unsigned short desth, 264 VARectangle *cliprects, /* client supplied clip list */ 265 unsigned int number_cliprects, /* number of clip rects in the clip list */ 266 unsigned int flags /* de-interlacing flags */ 267) 268{ 269 INIT_DRIVER_DATA; 270 INIT_OUTPUT_PRIV; 271 object_surface_p obj_surface = SURFACE(surface); 272 273 if (driver_data->overlay_idle_frame == 0) { 274 psb_android_texture_streaming_resetParams(); 275 update_forced = 1; 276 } 277 278 /* blend/positioning setting can be called by app directly, or enable VA_ENABLE_BLEND flag to let driver call */ 279 if (flags & VA_ENABLE_BLEND) 280 psb_android_texture_streaming_set_blend(destx, desty, destw, desth, 281 driver_data->clear_color, 282 driver_data->blend_color, 283 driver_data->blend_mode); 284 /*cropping can be also used for dynamic resolution change feature, only high to low resolution*/ 285 /*by default, srcw and srch is set to video width and height*/ 286 if ((0 == srcw) || (0 == srch)) { 287 srcw = obj_surface->width; 288 srch = obj_surface->height_origin; 289 } 290 psb_android_texture_streaming_set_texture_dim(srcw, srch); 291 if (driver_data->va_rotate) 292 psb_android_texture_streaming_set_rotate(va2hw_rotation(driver_data->va_rotate)); 293 294#if 0 295 /* use cliprect for crop */ 296 if (cliprects && (number_cliprects == 1)) 297 psb_android_texture_streaming_set_crop(cliprects->x, cliprects->y, cliprects->width, cliprects->height); 298#endif 299 300 psb_android_texture_streaming_display(buffer_index); 301 302 driver_data->overlay_idle_frame++; 303 update_forced = 0; 304 305 return VA_STATUS_SUCCESS; 306} 307 308 309static int psb_update_destbox( 310 VADriverContextP ctx 311) 312{ 313 INIT_DRIVER_DATA; 314 INIT_OUTPUT_PRIV; 315 short destx; 316 short desty; 317 unsigned short destw; 318 unsigned short desth; 319 VAStatus vaStatus = VA_STATUS_SUCCESS; 320 321 psb_android_get_destbox(&destx, &desty, &destw, &desth); 322 /*psb__information_message("destbox = (%d,%d,%d,%d)\n", destx, desty, destw, desth);*/ 323 if ((destx >= 0) && (desty >= 0) && 324 ((destx + destw) <= output->screen_width) && 325 ((desty + desth) <= output->screen_height) && 326 (output->destx != destx || 327 output->desty != desty || 328 output->destw != destw || 329 output->desth != desth)) { 330 output->destx = destx; 331 output->desty = desty; 332 output->destw = destw; 333 output->desth = desth; 334 output->new_destbox = 1; 335 336 LOGD("==========New Destbox=============\n"); 337 LOGD("output->destbox = (%d,%d,%d,%d)\n", output->destx, output->desty, output->destw, output->desth); 338 } 339 340 return vaStatus; 341} 342 343static int psb_check_outputmethod( 344 VADriverContextP ctx, 345 VASurfaceID surface, 346 unsigned short srcw, 347 unsigned short srch, 348 void *android_isurface, 349 psb_hdmi_mode *hdmi_mode 350) 351{ 352 INIT_DRIVER_DATA; 353 INIT_OUTPUT_PRIV; 354 psb_HDMIExt_info_p psb_HDMIExt_info = (psb_HDMIExt_info_p)output->psb_HDMIExt_info; 355 object_surface_p obj_surface; 356 int rotation = 0, widi = 0; 357 int delta_rotation = 0; 358 int srf_rotate; /* primary surface rotation */ 359 psb_surface_p rotate_surface; /* rotate surface */ 360 int rotate_srf_rotate = -1; /* degree of the rotate surface */ 361 362 if ((srcw >= 2048) || (srch >= 2048)) { 363 psb__information_message("Clip size extend overlay hw limit, use texstreaming\n"); 364 driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING; 365 return 0; 366 } 367 368 /* use saved status to avoid per-frame checking */ 369 if ((driver_data->frame_count % driver_data->outputmethod_checkinterval) != 0) { 370 *hdmi_mode = psb_HDMIExt_get_mode(output); 371 return 0; 372 } 373 374 /* check the status at outputmethod_checkinterval frequency */ 375 /* at first check HDMI status */ 376 if (psb_HDMIExt_update(ctx, psb_HDMIExt_info)) { 377 psb__error_message("%s: Failed to update HDMIExt info.\n", __FUNCTION__); 378 return -1; 379 } 380 381 *hdmi_mode = psb_HDMIExt_get_mode(output); 382 if ((*hdmi_mode == EXTENDED_VIDEO) || (*hdmi_mode == CLONE)) { 383 unsigned short _destw, _desth; 384 short _pos_x, _pos_y; 385 unsigned short crtc_width = 0, crtc_height = 0; 386 float _slope_xy; 387 388 /* need to handle VA rotation, and set WM rotate to 0 389 * for Android, MIPI0/HDMI has the same WM rotation always 390 */ 391 if (driver_data->mipi0_rotation != 0) { 392 driver_data->mipi0_rotation = 0; 393 driver_data->hdmi_rotation = 0; 394 output->new_destbox = 1; 395 psb_RecalcRotate(ctx); 396 } 397 398 psb_HDMIExt_get_prop(output, &crtc_width, &crtc_height); 399 400 /*recalculate the render box to fit the ratio of height/width*/ 401 if ((driver_data->extend_rotation == VA_ROTATION_90) || 402 (driver_data->extend_rotation == VA_ROTATION_270)) 403 _slope_xy = (float)srcw / srch; 404 else 405 _slope_xy = (float)srch / srcw; 406 407 _destw = (short)(crtc_height / _slope_xy); 408 _desth = (short)(crtc_width * _slope_xy); 409 if (_destw <= crtc_width) { 410 _desth = crtc_height; 411 _pos_x = (crtc_width - _destw) >> 1; 412 _pos_y = 0; 413 } else { 414 _destw = crtc_width; 415 _pos_x = 0; 416 _pos_y = (crtc_height - _desth) >> 1; 417 } 418 driver_data->render_rect.x = _pos_x; 419 driver_data->render_rect.y = _pos_y; 420 driver_data->render_rect.width = _destw; 421 driver_data->render_rect.height = _desth; 422 psb__information_message("HDMI mode is on (%d), Render Rect: (%d,%d,%d,%d)\n", 423 *hdmi_mode, 424 driver_data->render_rect.x, driver_data->render_rect.y, 425 driver_data->render_rect.width, driver_data->render_rect.height); 426 return 0; 427 } 428 429 /*Update output destbox using layerbuffer's visible region*/ 430 psb_update_destbox(ctx); 431 432 if ((driver_data->output_method == PSB_PUTSURFACE_FORCE_COVERLAY) 433 || (driver_data->output_method == PSB_PUTSURFACE_FORCE_TEXSTREAMING)) 434 return 0; 435 436 /*If overlay can not get correct destbox, use texstreaming.*/ 437 if (output->destw == 0 || output->desth == 0 || 438 ((output->destw == srcw) && (output->desth == srch))) { 439 psb__information_message("No proper destbox, use texstreaming (%dx%d+%d+%d)\n", 440 output->destw, output->desth, output->destx, output->desty); 441 driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING; 442 return 0; 443 } 444 445 /* HDMI is not enabled */ 446 psb_android_surfaceflinger_status(android_isurface, &output->sf_composition, &rotation, &widi); 447 if (widi == eWidiClone) { 448 psb__information_message("WIDI service is detected, use texstreaming\n"); 449 driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING; 450 driver_data->msvdx_rotate_want = 0;/* disable msvdx rotae */ 451 452 return 0; 453 } 454 455 /* only care local rotation */ 456 delta_rotation = Rotation2Angle(driver_data->mipi0_rotation) - Rotation2Angle(rotation); 457 if ((((abs(delta_rotation) == 90) || (abs(delta_rotation) == 270)) && output->new_destbox) || 458 (abs(delta_rotation) == 180)) { 459 psb__information_message("New rotation degree %d of MIPI0 WM, Recalc rotation\n", rotation); 460 driver_data->mipi0_rotation = rotation; 461 driver_data->hdmi_rotation = rotation; 462 463 psb_RecalcRotate(ctx); 464 } 465 output->new_destbox = 0; 466 467 obj_surface = SURFACE(surface); 468 if (GET_SURFACE_INFO_protect(obj_surface->psb_surface)) { 469 psb__information_message("Protected surface, use overlay\n"); 470 driver_data->output_method = PSB_PUTSURFACE_COVERLAY; 471 472 return 0; 473 } 474 475 if (output->sf_composition) { 476 psb__information_message("Composition is detected, use texstreaming\n"); 477 driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING; 478 return 0; 479 } 480 481 srf_rotate = GET_SURFACE_INFO_rotate(obj_surface->psb_surface); 482 rotate_surface = obj_surface->psb_surface_rotate; 483 if (rotate_surface != NULL) 484 rotate_srf_rotate = GET_SURFACE_INFO_rotate(rotate_surface); 485 486 psb__information_message("SF rotation %d, VA rotation %d, final MSVDX rotation %d\n", 487 rotation, driver_data->va_rotate, driver_data->local_rotation); 488 psb__information_message("Primary surface rotation %d, rotated surface rotation %d\n", 489 srf_rotate, rotate_srf_rotate); 490 491 /* The surface rotation is not same with the final rotation */ 492 if ((driver_data->local_rotation != 0) && 493 ((srf_rotate != driver_data->local_rotation) || (rotate_srf_rotate != driver_data->local_rotation))) { 494 psb__information_message("Use texstreaming due to different VA surface rotation and final rotaion\n", 495 srf_rotate, rotate_srf_rotate); 496 driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING; 497 return 0; 498 } 499 500 driver_data->output_method = PSB_PUTSURFACE_COVERLAY; 501 502 return 0; 503} 504 505VAStatus psb_PutSurface( 506 VADriverContextP ctx, 507 VASurfaceID surface, 508 void *android_isurface, 509 short srcx, 510 short srcy, 511 unsigned short srcw, 512 unsigned short srch, 513 short destx, 514 short desty, 515 unsigned short destw, 516 unsigned short desth, 517 VARectangle *cliprects, /* client supplied clip list */ 518 unsigned int number_cliprects, /* number of clip rects in the clip list */ 519 unsigned int flags /* de-interlacing flags */ 520) 521{ 522 INIT_DRIVER_DATA; 523 INIT_OUTPUT_PRIV; 524 object_surface_p obj_surface; 525 VAStatus vaStatus = VA_STATUS_SUCCESS; 526 PsbPortPrivPtr pPriv = (PsbPortPrivPtr)(&driver_data->coverlay_priv); 527 psb_hdmi_mode hdmi_mode = OFF; 528 int sf_composition = 0, buffer_index = 0, i = 0; 529 uint32_t ttm_handle; 530 psb_surface_p psb_surface; 531 532 obj_surface = SURFACE(surface); 533 if (NULL == obj_surface) { 534 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 535 DEBUG_FAILURE; 536 return vaStatus; 537 } 538 539 if ((NULL == cliprects) && (0 != number_cliprects)) { 540 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 541 DEBUG_FAILURE; 542 return vaStatus; 543 } 544 545 if ((srcx < 0) || (srcx > obj_surface->width) || (srcw > (obj_surface->width - srcx)) || 546 (srcy < 0) || (srcy > obj_surface->height_origin) || (srch > (obj_surface->height_origin - srcy))) { 547 psb__error_message("vaPutSurface: source rectangle passed from upper layer is not correct.\n"); 548 return VA_STATUS_ERROR_UNKNOWN; 549 } 550 if ((destx < 0) || (desty < 0)) { 551 psb__error_message("vaPutSurface: dest rectangle passed from upper layer is not correct.\n"); 552 return VA_STATUS_ERROR_UNKNOWN; 553 } 554 555 if (driver_data->dummy_putsurface) { 556 psb__information_message("vaPutSurface: dummy mode, return directly\n"); 557 return VA_STATUS_SUCCESS; 558 } 559 560 /*get bcd buffer index of current surface*/ 561 psb_surface = obj_surface->psb_surface; 562 ttm_handle = (uint32_t)(wsbmKBufHandle(wsbmKBuf(psb_surface->buf.drm_buf))); 563 564 for (i = 0; i < driver_data->bcd_buffer_num; i++) { 565 if (driver_data->bcd_ttm_handles[i] == ttm_handle) 566 break; 567 } 568 if (i == driver_data->bcd_buffer_num) { 569 psb__error_message("Failed to get buffer index.\n"); 570 return VA_STATUS_ERROR_UNKNOWN; 571 } 572 buffer_index = i; 573 574 /* set the current displaying video frame into kernel */ 575 psb_surface_set_displaying(driver_data, obj_surface->width, obj_surface->height_origin, obj_surface->psb_surface); 576 577 /* exit MRST path at first */ 578 if (IS_MRST(driver_data)) { 579 if (driver_data->output_method == PSB_PUTSURFACE_FORCE_COVERLAY) { /* overlay is for testing, not POR */ 580 psb__information_message("Force overlay to display\n"); 581 vaStatus = psb_putsurface_coverlay(ctx, surface, 582 srcx, srcy, srcw, srch, 583 destx, desty, destw, desth, 584 flags); 585 } else { 586 psb__information_message("Use texstreaming to display.\n"); 587 vaStatus = psb_putsurface_ts(ctx, surface, android_isurface, buffer_index, 588 srcx, srcy, srcw, srch, 589 destx, desty, destw, desth, 590 cliprects, number_cliprects, /* number of clip rects in the clip list */ 591 flags); 592 } 593 594 return vaStatus; 595 } 596 597 if (psb_android_register_isurface(android_isurface, driver_data->bcd_id, srcw, srch)) { 598 psb__error_message("In psb_PutSurface, android_isurface is not a valid isurface object.\n"); 599 return VA_STATUS_ERROR_UNKNOWN; 600 } 601 602 /* time for MFLD platform */ 603 psb_check_outputmethod(ctx, surface, srcw, srch, android_isurface, &hdmi_mode); 604 605 if (hdmi_mode == UNDEFINED) { 606 psb__information_message("HDMI: Undefined mode, drop the frame.\n"); 607 return vaStatus; 608 } 609 610 /* Extvideo: Use overlay to render external HDMI display */ 611 if (hdmi_mode == EXTENDED_VIDEO) { 612 psb__information_message("HDMI: ExtVideo mode enabled, use overlay to render external HDMI display.\n"); 613 /*we also need to clear local display if colorkey dirty.*/ 614 if (driver_data->overlay_idle_frame != 0) { 615 psb_android_texture_streaming_set_background_color(driver_data->color_key | 0xff000000); 616 psb_android_texture_streaming_display(buffer_index); 617 driver_data->overlay_idle_frame = 0; 618 } 619 vaStatus = psb_putsurface_overlay(ctx, surface, 620 srcx, srcy, srcw, srch, 621 driver_data->render_rect.x, driver_data->render_rect.y, 622 driver_data->render_rect.width, driver_data->render_rect.height, 623 flags, OVERLAY_A, PIPEB); 624 625 return vaStatus; 626 } 627 628 /* Clone mode: Use TS to render both MIPI and HDMI display */ 629 if (hdmi_mode == CLONE) { 630 psb__information_message("HDMI: Clone mode enabled, use texsteaming for both devices\n"); 631 vaStatus = psb_putsurface_ts(ctx, surface, android_isurface, buffer_index, 632 srcx, srcy, srcw, srch, 633 destx, desty, destw, desth, 634 cliprects, number_cliprects, /* number of clip rects in the clip list */ 635 flags); 636 return vaStatus; 637 } 638 639 /* local video playback */ 640 if ((driver_data->output_method == PSB_PUTSURFACE_TEXSTREAMING) || 641 (driver_data->output_method == PSB_PUTSURFACE_FORCE_TEXSTREAMING)) { 642 psb__information_message("MIPI: Use texstreaming to display.\n"); 643 644 vaStatus = psb_putsurface_ts(ctx, surface, android_isurface, buffer_index, 645 srcx, srcy, srcw, srch, 646 destx, desty, destw, desth, 647 cliprects, number_cliprects, /* number of clip rects in the clip list */ 648 flags); 649 } else { 650 psb__information_message("MIPI: Use overlay to display.\n"); 651 652 /*initialize output destbox using default destbox if it has not been initialized until here.*/ 653 if (output->destw == 0 || output->desth == 0) { 654 output->destx = (destx > 0) ? destx : 0; 655 output->desty = (desty > 0) ? desty : 0; 656 output->destw = ((output->destx + destw) > output->screen_width) ? (output->screen_width - output->destx) : destw; 657 output->desth = ((output->desty + desth) > output->screen_height) ? (output->screen_height - output->desty) : desth; 658 } 659 660 /* Hack for repaint color key to black(0,0,0). */ 661 if (driver_data->overlay_idle_frame != 0) { 662 psb__information_message("Paint color key to 0x%x\n", driver_data->color_key); 663 psb_android_texture_streaming_set_background_color(driver_data->color_key | 0xff000000); 664 psb_android_texture_streaming_display(buffer_index); 665 driver_data->overlay_idle_frame = 0; 666 } 667 668 psb__information_message("Overlay position = (%d,%d,%d,%d)\n", output->destx, output->desty, output->destw, output->desth); 669 vaStatus = psb_putsurface_overlay(ctx, surface, 670 srcx, srcy, srcw, srch, 671 output->destx, output->desty, output->destw, output->desth, 672 flags, OVERLAY_A, PIPEA); 673 } 674 675 if (driver_data->overlay_idle_frame == MAX_OVERLAY_IDLE_FRAME) 676 psb_coverlay_stop(ctx); 677 678 driver_data->frame_count++; 679 680 681 return vaStatus; 682} 683