psb_output_android.c revision 5b25aaf457f3ba02a4ff2a6243fa7c0f84f1e016
1/*
2 * INTEL CONFIDENTIAL
3 * Copyright 2007 Intel Corporation. All Rights Reserved.
4 *
5 * The source code contained or described herein and all documents related to
6 * the source code ("Material") are owned by Intel Corporation or its suppliers
7 * or licensors. Title to the Material remains with Intel Corporation or its
8 * suppliers and licensors. The Material may contain trade secrets and
9 * proprietary and confidential information of Intel Corporation and its
10 * suppliers and licensors, and is protected by worldwide copyright and trade
11 * secret laws and treaty provisions. No part of the Material may be used,
12 * copied, reproduced, modified, published, uploaded, posted, transmitted,
13 * distributed, or disclosed in any way without Intel's prior express written
14 * permission.
15 *
16 * No license under any patent, copyright, trade secret or other intellectual
17 * property right is granted to or conferred upon you by disclosure or delivery
18 * of the Materials, either expressly, by implication, inducement, estoppel or
19 * otherwise. Any license under such intellectual property rights must be
20 * express and approved by Intel in writing.
21 */
22
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 <wsbm/wsbm_manager.h>
46#include <psb_drm.h>
47
48#define INIT_DRIVER_DATA    psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData;
49#define INIT_OUTPUT_PRIV    psb_android_output_p output = (psb_android_output_p)(((psb_driver_data_p)ctx->pDriverData)->ws_priv)
50
51#define SURFACE(id) ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id ))
52#define BUFFER(id)  ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id ))
53#define IMAGE(id)  ((object_image_p) object_heap_lookup( &driver_data->image_heap, id ))
54#define SUBPIC(id)  ((object_subpic_p) object_heap_lookup( &driver_data->subpic_heap, id ))
55#define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
56
57#define GET_SURFACE_INFO_rotate(psb_surface) ((int) psb_surface->extra_info[5])
58#define GET_SURFACE_INFO_protect(psb_surface) ((int) psb_surface->extra_info[6])
59
60enum {
61    eWidiOff             = 1,
62    eWidiClone           = 2,
63    eWidiExtendedVideo   = 3,
64};
65
66void *psb_android_output_init(VADriverContextP ctx)
67{
68    INIT_DRIVER_DATA;
69    char put_surface[1024];
70    struct drm_psb_register_rw_arg regs;
71    psb_android_output_p output = calloc(1, sizeof(psb_android_output_s));
72    struct fb_var_screeninfo vinfo;
73    int fbfd = -1;
74    int ret;
75
76    if (output == NULL) {
77        psb__error_message("Can't malloc memory\n");
78        return NULL;
79    }
80    memset(output, 0, sizeof(psb_android_output_s));
81
82    /* Guess the screen size */
83    output->screen_width = 800;
84    output->screen_height = 480;
85
86    // Open the frame buffer for reading
87    memset(&vinfo, 0, sizeof(vinfo));
88    fbfd = open("/dev/graphics/fb0", O_RDONLY);
89    if (fbfd) {
90        if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo))
91            psb__information_message("Error reading screen information.\n");
92    }
93    close(fbfd);
94    output->screen_width = vinfo.xres;
95    output->screen_height = vinfo.yres;
96
97    /* TS by default */
98    driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING;
99    driver_data->color_key = 0x0; /*black*/
100
101    if (psb_parse_config("PSB_VIDEO_CTEXTURES", &put_surface[0]) == 0) {
102        psb__information_message("PSB_VIDEO_CTEXTURES is enabled for vaPutSurfaceBuf\n");
103        driver_data->ctexture = 1; /* Init CTEXTURE for vaPutSurfaceBuf */
104    }
105
106    if (psb_parse_config("PSB_VIDEO_TS", &put_surface[0]) == 0) {
107        psb__information_message("Putsurface use texstreaming\n");
108        driver_data->output_method = PSB_PUTSURFACE_FORCE_TEXSTREAMING;
109    }
110
111    if (psb_parse_config("PSB_VIDEO_COVERLAY", &put_surface[0]) == 0) {
112        psb__information_message("Putsurface use client overlay\n");
113        driver_data->output_method = PSB_PUTSURFACE_FORCE_COVERLAY;
114    }
115
116    if (psb_parse_config("PSB_VIDEO_SUPSRC", &put_surface[0]) == 0) {
117        psb__information_message("Putsurface use super src\n");
118        driver_data->output_method = PSB_PUTSURFACE_SUPSRC;
119    }
120
121    if (IS_MFLD(driver_data)) {
122        driver_data->coverlay = 1;
123        output->psb_HDMIExt_info = psb_HDMIExt_init(ctx, output);
124        if (!output->psb_HDMIExt_info) {
125            psb__error_message("Failed to init psb_HDMIExt.\n");
126            free(output);
127            return NULL;
128        }
129    }
130
131    return output;
132}
133
134VAStatus psb_android_output_deinit(VADriverContextP ctx)
135{
136    INIT_DRIVER_DATA;
137    INIT_OUTPUT_PRIV;
138    //psb_android_output_p output = GET_OUTPUT_DATA(ctx);
139    if (IS_MFLD(driver_data)) {
140        psb_HDMIExt_deinit(output);
141    }
142
143    return VA_STATUS_SUCCESS;
144}
145
146static VAStatus psb_putsurface_ctexture(
147    VADriverContextP ctx,
148    VASurfaceID surface,
149    unsigned char* data,
150    short srcx,
151    short srcy,
152    unsigned short srcw,
153    unsigned short srch,
154    short destx,
155    short desty,
156    unsigned short destw,
157    unsigned short desth,
158    unsigned int flags /* de-interlacing flags */
159)
160{
161    INIT_DRIVER_DATA;
162    INIT_OUTPUT_PRIV;
163    object_surface_p obj_surface = SURFACE(surface);
164    int offset = 0;
165    psb_surface_p psb_surface;
166
167    obj_surface = SURFACE(surface);
168    psb_surface = obj_surface->psb_surface;
169
170    //    psb_surface->buf.drm_buf;
171    //    psb_surface->buf.pl_flags;
172    psb_putsurface_textureblit(ctx, data, surface, srcx, srcy, srcw, srch,
173                               destx, desty, destw, desth, 0, /* no subtitle */
174                               obj_surface->width, obj_surface->height,
175                               psb_surface->stride, psb_surface->buf.drm_buf,
176                               psb_surface->buf.pl_flags, 1 /* need wrap dst */);
177
178    psb_android_postBuffer(offset);
179
180    return VA_STATUS_SUCCESS;
181}
182
183VAStatus psb_putsurface_coverlay(
184    VADriverContextP ctx,
185    VASurfaceID surface,
186    short srcx,
187    short srcy,
188    unsigned short srcw,
189    unsigned short srch,
190    short destx, /* screen cooridination */
191    short desty,
192    unsigned short destw,
193    unsigned short desth,
194    unsigned int flags /* de-interlacing flags */
195)
196{
197    INIT_OUTPUT_PRIV;
198    VAStatus vaStatus = VA_STATUS_SUCCESS;
199
200    /* USE_FIT_SCR_SIZE */
201    /* calculate fit screen size of frame */
202    unsigned short _scr_x = output->screen_width;
203    unsigned short _scr_y = output->screen_height;
204    float _slope_xy = (float)srch / srcw;
205    unsigned short _destw = (short)(_scr_y / _slope_xy);
206    unsigned short _desth = (short)(_scr_x * _slope_xy);
207    short _pos_x, _pos_y;
208
209    if (_destw <= _scr_x) {
210        _desth = _scr_y;
211        _pos_x = (_scr_x - _destw) >> 1;
212        _pos_y = 0;
213    } else {
214        _destw = _scr_x;
215        _pos_x = 0;
216        _pos_y = (_scr_y - _desth) >> 1;
217    }
218    destx += _pos_x;
219    desty += _pos_y;
220    destw = _destw;
221    desth = _desth;
222
223    psb__information_message("psb_putsurface_overlay: src (%d, %d, %d, %d), destx (%d, %d, %d, %d).\n",
224                             srcx, srcy, srcw, srch, destx, desty, destw, desth);
225    /* display by overlay */
226    vaStatus = psb_putsurface_overlay(
227                   ctx, surface, srcx, srcy, srcw, srch,
228                   destx, desty, destw, desth, /* screen coordinate */
229                   flags, OVERLAY_A, PIPEA);
230
231    return vaStatus;
232}
233
234
235VAStatus psb_putsurface_ts(
236    VADriverContextP ctx,
237    VASurfaceID surface,
238    void *android_isurface,
239    short srcx,
240    short srcy,
241    unsigned short srcw,
242    unsigned short srch,
243    short destx,
244    short desty,
245    unsigned short destw,
246    unsigned short desth,
247    VARectangle *cliprects, /* client supplied clip list */
248    unsigned int number_cliprects, /* number of clip rects in the clip list */
249    unsigned int flags /* de-interlacing flags */
250)
251{
252    INIT_DRIVER_DATA;
253    INIT_OUTPUT_PRIV;
254    object_surface_p obj_surface = SURFACE(surface);
255    uint32_t ttm_handle, i;
256    psb_surface_p psb_surface;
257
258    /* blend/positioning setting can be called by app directly, or enable VA_ENABLE_BLEND flag to let driver call */
259    if (flags & VA_ENABLE_BLEND)
260        psb_android_texture_streaming_set_blend(destx, desty, destw, desth,
261                                                driver_data->clear_color,
262                                                driver_data->blend_color,
263                                                driver_data->blend_mode);
264    /*cropping can be also used for dynamic resolution change feature, only high to low resolution*/
265    /*by default, srcw and srch is set to video width and height*/
266    if ((0 == srcw) || (0 == srch)) {
267        srcw = obj_surface->width;
268        srch = obj_surface->height_origin;
269    }
270    psb_android_texture_streaming_set_texture_dim(srcw, srch);
271
272#if 0
273    /* use cliprect for crop */
274    if (cliprects && (number_cliprects == 1))
275        psb_android_texture_streaming_set_crop(cliprects->x, cliprects->y, cliprects->width, cliprects->height);
276#endif
277
278    psb_surface = obj_surface->psb_surface;
279    ttm_handle = (uint32_t)(wsbmKBufHandle(wsbmKBuf(psb_surface->buf.drm_buf)));
280
281    for (i = 0; i < driver_data->bcd_buffer_num; i++) {
282        if (driver_data->bcd_ttm_handles[i] == ttm_handle)
283            break;
284    }
285    if (i == driver_data->bcd_buffer_num) {
286        psb__error_message("Failed to get buffer index.\n");
287        return VA_STATUS_ERROR_UNKNOWN;
288    }
289
290    psb_android_texture_streaming_display(i);
291
292    driver_data->overlay_idle_frame++;
293    output->colorkey_dirty = 1;
294
295    return VA_STATUS_SUCCESS;
296}
297
298static VAStatus psb_putsurface_dynamic_source(
299    VADriverContextP ctx,
300    VASurfaceID surface,
301    void *android_isurface,
302    unsigned short srcw,
303    unsigned short srch
304)
305{
306    INIT_DRIVER_DATA;
307    INIT_OUTPUT_PRIV;
308    VAStatus vaStatus = VA_STATUS_SUCCESS;
309    object_surface_p obj_surface = SURFACE(surface);
310    uint32_t ttm_handle, i;
311    psb_hdmi_mode hdmi_mode;
312    psb_surface_p psb_surface = obj_surface->psb_surface;
313
314    if (psb_android_dynamic_source_init(android_isurface, driver_data->bcd_id, srcw, srch, psb_surface->stride)) {
315        psb__error_message("In psb_PutSurface, android_isurface is not a valid isurface object.\n");
316        return VA_STATUS_ERROR_UNKNOWN;
317    }
318
319    if (psb_HDMIExt_update(ctx, output->psb_HDMIExt_info)) {
320        psb__error_message("%s: Failed to update HDMIExt info.\n", __FUNCTION__);
321        return -1;
322    }
323
324    hdmi_mode = psb_HDMIExt_get_mode(output);
325    ttm_handle = (uint32_t)(wsbmKBufHandle(wsbmKBuf(psb_surface->buf.drm_buf)));
326
327    for (i = 0; i < driver_data->bcd_buffer_num; i++) {
328        if (driver_data->bcd_ttm_handles[i] == ttm_handle)
329            break;
330    }
331
332    if (i == driver_data->bcd_buffer_num) {
333        psb__error_message("Failed to get buffer index.\n");
334        return VA_STATUS_ERROR_UNKNOWN;
335    }
336    psb_android_dynamic_source_display(i, (int)hdmi_mode);
337    return vaStatus;
338}
339
340static int psb_update_destbox(
341    VADriverContextP ctx
342)
343{
344    INIT_DRIVER_DATA;
345    INIT_OUTPUT_PRIV;
346    short destx;
347    short desty;
348    unsigned short destw;
349    unsigned short desth;
350    VAStatus vaStatus = VA_STATUS_SUCCESS;
351
352    psb_android_get_destbox(&destx, &desty, &destw, &desth);
353    psb__information_message("destbox = (%d,%d,%d,%d)\n", destx, desty, destw, desth);
354    if ((destx >= 0) && (desty >= 0) &&
355            ((destx + destw) <= output->screen_width) &&
356            ((desty + desth) <= output->screen_height) &&
357            (output->destx != destx ||
358             output->desty != desty ||
359             output->destw != destw ||
360             output->desth != desth)) {
361        output->destx = destx;
362        output->desty = desty;
363        output->destw = destw;
364        output->desth = desth;
365
366        /*destbox is ready. Set the new rotation for overlay*/
367        driver_data->local_rotation = driver_data->msvdx_rotate_want;
368        if (driver_data->local_rotation == 3)
369            driver_data->local_rotation = VA_ROTATION_270;
370
371        LOGD("==========New Destbox=============\n");
372        LOGD("output->destbox = (%d,%d,%d,%d)\n", output->destx, output->desty, output->destw, output->desth);
373    }
374
375    return vaStatus;
376}
377
378static int psb_check_outputmethod(
379    VADriverContextP ctx,
380    VASurfaceID surface,
381    unsigned short srcw,
382    unsigned short srch,
383    void *android_isurface,
384    psb_hdmi_mode *hdmi_mode
385)
386{
387    INIT_DRIVER_DATA;
388    INIT_OUTPUT_PRIV;
389    psb_HDMIExt_info_p psb_HDMIExt_info = (psb_HDMIExt_info_p)output->psb_HDMIExt_info;
390    object_surface_p obj_surface;
391    int rotation = 0, widi = 0;
392
393    if ((srcw >= 2048) || (srch >= 2048)) {
394        psb__information_message("Clip size extend overlay hw limit, use texstreaming\n");
395        driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING;
396        return 0;
397    }
398
399    /* use saved status to avoid per-frame checking */
400    if ((driver_data->frame_count % driver_data->outputmethod_checkinterval) != 0) {
401        *hdmi_mode = psb_HDMIExt_get_mode(output);
402        return 0;
403    }
404
405    /* check the status at outputmethod_checkinterval frequency */
406    /* at first check HDMI status */
407    if (psb_HDMIExt_update(ctx, psb_HDMIExt_info)) {
408        psb__error_message("%s: Failed to update HDMIExt info.\n", __FUNCTION__);
409        return -1;
410    }
411
412    *hdmi_mode = psb_HDMIExt_get_mode(output);
413    psb__information_message("hdmi_mode = %d\n", *hdmi_mode);
414    if (*hdmi_mode != OFF) {
415        psb_HDMIExt_get_prop(output, &driver_data->render_rect.width, &driver_data->render_rect.height,
416                             &driver_data->render_rect.x, &driver_data->render_rect.y);
417        psb__information_message("Render Rect: (%d,%d,%d,%d)\n",
418                                 driver_data->render_rect.x, driver_data->render_rect.y,
419                                 driver_data->render_rect.width, driver_data->render_rect.height);
420    }
421
422    if ((driver_data->output_method == PSB_PUTSURFACE_FORCE_COVERLAY)
423        || (driver_data->output_method == PSB_PUTSURFACE_FORCE_TEXSTREAMING))
424        return 0;
425
426    if ((*hdmi_mode == EXTENDED_VIDEO) || (*hdmi_mode == CLONE)) {
427        driver_data->msvdx_rotate_want = 0; /* disable msvdx rotate */
428        return 0;
429    }
430
431    /* HDMI is not enabled */
432    psb_android_surfaceflinger_status(android_isurface, &output->sf_composition, &rotation, &widi);
433    if (widi == eWidiClone) {
434        psb__information_message("WIDI service is detected, use texstreaming\n");
435        driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING;
436        driver_data->msvdx_rotate_want = 0;/* disable msvdx rotae */
437
438        return 0;
439    }
440
441    /* only care local rotation */
442    if (driver_data->msvdx_rotate_want != rotation) {
443        psb__information_message("New rotation degree %d\n", rotation);
444        driver_data->msvdx_rotate_want = rotation;
445    }
446
447    obj_surface = SURFACE(surface);
448    if (GET_SURFACE_INFO_protect(obj_surface->psb_surface)) {
449        psb__information_message("Protected surface, use overlay\n");
450        driver_data->output_method = PSB_PUTSURFACE_COVERLAY;
451
452        return 0;
453    }
454
455    if (output->sf_composition) {
456        psb__information_message("Composition is detected, use texstreaming\n");
457        driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING;
458        return 0;
459    }
460
461    if (rotation != 0) {
462        int srf_rotate = GET_SURFACE_INFO_rotate(obj_surface->psb_surface);
463        if (srf_rotate != rotation) { /* surface rotation isn't same with SF rotation*/
464            psb__information_message("SF rotation degree %d, MSVDX rotate %d\n", rotation, srf_rotate);
465            driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING;
466            return 0;
467        }
468    }
469
470    psb__information_message("Rotation degree %d, use overlay\n", rotation);
471    driver_data->output_method = PSB_PUTSURFACE_COVERLAY;
472
473    return 0;
474}
475
476VAStatus psb_PutSurface(
477    VADriverContextP ctx,
478    VASurfaceID surface,
479    void *android_isurface,
480    short srcx,
481    short srcy,
482    unsigned short srcw,
483    unsigned short srch,
484    short destx,
485    short desty,
486    unsigned short destw,
487    unsigned short desth,
488    VARectangle *cliprects, /* client supplied clip list */
489    unsigned int number_cliprects, /* number of clip rects in the clip list */
490    unsigned int flags /* de-interlacing flags */
491)
492{
493    INIT_DRIVER_DATA;
494    INIT_OUTPUT_PRIV;
495    object_surface_p obj_surface;
496    VAStatus vaStatus = VA_STATUS_SUCCESS;
497    PsbPortPrivPtr pPriv = (PsbPortPrivPtr)(&driver_data->coverlay_priv);
498    psb_hdmi_mode hdmi_mode = OFF;
499    int sf_composition = 0;
500
501    obj_surface = SURFACE(surface);
502    if (NULL == obj_surface) {
503        vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
504        DEBUG_FAILURE;
505        return vaStatus;
506    }
507
508    if ((NULL == cliprects) && (0 != number_cliprects)) {
509        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
510        DEBUG_FAILURE;
511        return vaStatus;
512    }
513
514    if ((srcx < 0) || (srcx > obj_surface->width) || (srcw > (obj_surface->width - srcx)) ||
515            (srcy < 0) || (srcy > obj_surface->height_origin) || (srch > (obj_surface->height_origin - srcy))) {
516        psb__error_message("vaPutSurface: source rectangle passed from upper layer is not correct.\n");
517        return VA_STATUS_ERROR_UNKNOWN;
518    }
519    if ((destx < 0) || (desty < 0)) {
520        psb__error_message("vaPutSurface: dest rectangle passed from upper layer is not correct.\n");
521        return VA_STATUS_ERROR_UNKNOWN;
522    }
523
524    if (driver_data->dummy_putsurface) {
525        psb__information_message("vaPutSurface: dummy mode, return directly\n");
526        return VA_STATUS_SUCCESS;
527    }
528
529    /* set the current displaying video frame into kernel */
530    psb_surface_set_displaying(driver_data, obj_surface->width, obj_surface->height, obj_surface->psb_surface);
531
532    /* exit MRST path at first */
533    if (IS_MRST(driver_data)) {
534        if (driver_data->output_method == PSB_PUTSURFACE_FORCE_COVERLAY) { /* overlay is for testing, not POR */
535            psb__information_message("Force overlay to display\n");
536            vaStatus = psb_putsurface_coverlay(ctx, surface,
537                                               srcx, srcy, srcw, srch,
538                                               destx, desty, destw, desth,
539                                               flags);
540        } else {
541            psb__information_message("Use texstreaming to display.\n");
542            vaStatus = psb_putsurface_ts(ctx, surface, android_isurface,
543                                         srcx, srcy, srcw, srch,
544                                         destx, desty, destw, desth,
545                                         cliprects, number_cliprects, /* number of clip rects in the clip list */
546                                         flags);
547        }
548
549        return vaStatus;
550    }
551
552    if (driver_data->output_method == PSB_PUTSURFACE_SUPSRC) {
553        psb__information_message("Use dynamic source to display.\n");
554        vaStatus = psb_putsurface_dynamic_source(ctx, surface, android_isurface, srcw, srch);
555        return vaStatus;
556    }
557
558    if (psb_android_register_isurface(android_isurface, driver_data->bcd_id, srcw, srch)) {
559        psb__error_message("In psb_PutSurface, android_isurface is not a valid isurface object.\n");
560        return VA_STATUS_ERROR_UNKNOWN;
561    }
562
563    /* time for MFLD platform */
564    psb_check_outputmethod(ctx, surface, srcw, srch, android_isurface, &hdmi_mode);
565
566    /* Extvideo: Use overlay to render external HDMI display */
567    if (hdmi_mode == EXTENDED_VIDEO) {
568        psb__information_message("HDMI: ExtVideo mode enabled, use overlay to render external HDMI display.\n");
569        /*we also need to clear local display if colorkey dirty.*/
570        if (output->colorkey_dirty) {
571            psb_android_texture_streaming_display(-1);
572            output->colorkey_dirty = 0;
573        }
574        vaStatus = psb_putsurface_overlay(ctx, surface,
575                                          srcx, srcy, srcw, srch,
576                                          driver_data->render_rect.x, driver_data->render_rect.y,
577                                          driver_data->render_rect.width, driver_data->render_rect.height,
578                                          flags, OVERLAY_A, PIPEB);
579
580        return vaStatus;
581    }
582
583    /* Clone mode: Use TS to render both MIPI and HDMI display */
584    if (hdmi_mode == CLONE) {
585        psb__information_message("HDMI: Clone mode enabled, use texsteaming for both devices\n");
586        vaStatus = psb_putsurface_ts(ctx, surface, android_isurface,
587                                     srcx, srcy, srcw, srch,
588                                     destx, desty, destw, desth,
589                                     cliprects, number_cliprects, /* number of clip rects in the clip list */
590                                     flags);
591        return vaStatus;
592    }
593
594    /*initialize output destbox.*/
595    if (output->destw == 0 || output->desth == 0) {
596        output->destx = (destx > 0) ? destx : 0;
597        output->desty = (desty > 0) ? desty : 0;
598        output->destw = ((output->destx + destw) > output->screen_width) ? (output->screen_width - output->destx) : destw;
599        output->desth = ((output->desty + desth) > output->screen_height) ? (output->screen_height - output->desty) : desth;
600    }
601
602    /*Update output destbox using layerbuffer's visible region*/
603    psb_update_destbox(ctx);
604
605    /* local video playback */
606    if ((driver_data->output_method == PSB_PUTSURFACE_TEXSTREAMING) ||
607            (driver_data->output_method == PSB_PUTSURFACE_FORCE_TEXSTREAMING)) {
608        psb__information_message("MIPI: Use texstreaming to display.\n");
609
610        vaStatus = psb_putsurface_ts(ctx, surface, android_isurface,
611                                     srcx, srcy, srcw, srch,
612                                     destx, desty, destw, desth,
613                                     cliprects, number_cliprects, /* number of clip rects in the clip list */
614                                     flags);
615    } else {
616        psb__information_message("MIPI: Use overlay to display.\n");
617
618        /* Hack for repaint color key to black(0,0,0). */
619        if (output->colorkey_dirty) {
620            psb_android_texture_streaming_display(-1);
621            output->colorkey_dirty = 0;
622            psb__information_message("Hack for repainting color key for overlay.Ignore the error message \"Texture Streaming Fails...\".\n");
623        }
624
625        psb__information_message("Overlay position = (%d,%d,%d,%d)\n", output->destx, output->desty, output->destw, output->desth);
626        vaStatus = psb_putsurface_overlay(ctx, surface,
627                                          srcx, srcy, srcw, srch,
628                                          output->destx, output->desty, output->destw, output->desth,
629                                          flags, OVERLAY_A, PIPEA);
630        driver_data->overlay_idle_frame = 0;
631    }
632
633    if (driver_data->overlay_idle_frame == 10)
634        psb_coverlay_stop(ctx);
635
636    driver_data->frame_count++;
637
638
639    return vaStatus;
640}
641