/*
 * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors:
 *    Zeng Li <zeng.li@intel.com>
 *    Jason Hu <jason.hu@intel.com>
 *    Shengquan Yuan  <shengquan.yuan@intel.com>
 */

#include <va/va.h>
#include <va/va_backend.h>
#include <va/va_backend_tpi.h>
#include <va/va_backend_egl.h>
#include <va/va_drmcommon.h>
#include "psb_drv_video.h"
#include "psb_output.h"
#include "android/psb_android_glue.h"
#include "psb_drv_debug.h"
#include "vc1_defs.h"
#include "pnw_rotate.h"
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
#include <unistd.h>
#include <wsbm/wsbm_pool.h>
#include <wsbm/wsbm_manager.h>
#include <wsbm/wsbm_util.h>
#include <wsbm/wsbm_fencemgr.h>

#ifdef ANROID
#include <system/graphics.h>
#endif

#define INIT_DRIVER_DATA    psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData
#define INIT_OUTPUT_PRIV    unsigned char* output = ((psb_driver_data_p)ctx->pDriverData)->ws_priv
#define SURFACE(id)    ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id ))
#define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
#define CONFIG(id)  ((object_config_p) object_heap_lookup( &driver_data->config_heap, id ))

/*picture structure*/
#define TOP_FIELD                       1
#define BOTTOM_FIELD                    2
#define FRAME_PICTURE                   3

#define CHECK_SURFACE_REALLOC(psb_surface, msvdx_rotate, need)  \
do {                                                            \
    int old_rotate = GET_SURFACE_INFO_rotate(psb_surface);      \
    switch (msvdx_rotate) {                                     \
    case 2: /* 180 */                                           \
        if (old_rotate == 2)                                    \
            need = 0;                                           \
        else                                                    \
            need = 1;                                           \
        break;                                                  \
    case 1: /* 90 */                                            \
    case 3: /* 270 */                                           \
        if (old_rotate == 1 || old_rotate == 3)                 \
            need = 0;                                           \
        else                                                    \
            need = 1;                                           \
        break;                                                  \
    }                                                           \
} while (0)

static int get_surface_stride(int width, int tiling)
{
    int stride = 0;

    if (0) {
        ;
    } else if (512 >= width) {
        stride = 512;
    } else if (1024 >= width) {
        stride = 1024;
    } else if (1280 >= width) {
        stride = 1280;
#ifdef PSBVIDEO_MSVDX_DEC_TILING
        if (tiling) {
            stride = 2048;
        }
#endif
    } else if (2048 >= width) {
        stride = 2048;
    } else if (4096 >= width) {
        stride = 4096;
    } else {
        stride = (width + 0x3f) & ~0x3f;
    }

    return stride;
}
//#define OVERLAY_ENABLE_MIRROR

#ifdef PSBVIDEO_MRFL_VPP

static int isVppOn(void __maybe_unused *output) {
#ifdef TARGET_HAS_MULTIPLE_DISPLAY
    return psb_android_get_mds_vpp_state(output);
#else
    return psb_android_get_vpp_state();
#endif
}
#endif

void psb_InitOutLoop(VADriverContextP ctx)
{
    char env_value[64];
    INIT_DRIVER_DATA;

    /* VA rotate from APP */
    driver_data->va_rotate = VA_ROTATION_NONE;

    /* window manager rotation from OS */
    driver_data->mipi0_rotation = VA_ROTATION_NONE;
    driver_data->mipi1_rotation = VA_ROTATION_NONE;
    driver_data->hdmi_rotation = VA_ROTATION_NONE;

    /* final rotation of VA rotate+WM rotate */
    driver_data->local_rotation = VA_ROTATION_NONE;
    driver_data->extend_rotation = VA_ROTATION_NONE;

    /* MSVDX rotate */
    driver_data->msvdx_rotate_want = ROTATE_VA2MSVDX(VA_ROTATION_NONE);

    if (psb_parse_config("PSB_VIDEO_NOROTATE", &env_value[0]) == 0) {
        drv_debug_msg(VIDEO_DEBUG_GENERAL, "MSVDX: disable MSVDX rotation\n");
        driver_data->disable_msvdx_rotate = 1;
    }
    /* FIXME: Disable rotation when VPP enabled, just a workround here*/
#ifdef PSBVIDEO_MRFL_VPP
    if (isVppOn((void*)driver_data->ws_priv)) {
        drv_debug_msg(VIDEO_DEBUG_GENERAL, "For VPP: disable MSVDX rotation\n");
        driver_data->disable_msvdx_rotate = 1;
        driver_data->vpp_on = 1;
    }
#endif

#ifdef BAYTRAIL
    driver_data->disable_msvdx_rotate = 1;
#endif

    driver_data->disable_msvdx_rotate_backup = driver_data->disable_msvdx_rotate;
}

void psb_RecalcAlternativeOutput(object_context_p obj_context)
{
    psb_driver_data_p driver_data = obj_context->driver_data;
    object_surface_p obj_surface = obj_context->current_render_target;
    int angle, new_rotate, i;
    int old_rotate = driver_data->msvdx_rotate_want;
    int mode = INIT_VALUE;
#ifdef TARGET_HAS_MULTIPLE_DISPLAY
    mode = psb_android_get_mds_mode((void*)driver_data->ws_priv);
#endif

    if (mode != INIT_VALUE) {
        // clear device rotation info
        if (driver_data->mipi0_rotation != VA_ROTATION_NONE) {
            driver_data->mipi0_rotation = VA_ROTATION_NONE;
            driver_data->hdmi_rotation = VA_ROTATION_NONE;
        }
        // Disable msvdx rotation if
        // WIDI video is play and meta data rotation angle is 0
        if (mode == WIDI_VIDEO_ISPLAYING) {
            if (driver_data->va_rotate == VA_ROTATION_NONE)
                driver_data->disable_msvdx_rotate = 1;
            else {
                driver_data->mipi0_rotation = 0;
                driver_data->hdmi_rotation = 0;
                driver_data->disable_msvdx_rotate = 0;
            }
        } else {
            if (IS_MOFD(driver_data))
                driver_data->disable_msvdx_rotate = 1;
            else
                driver_data->disable_msvdx_rotate = driver_data->disable_msvdx_rotate_backup;
        }
    } else if (IS_MOFD(driver_data)) {
    /* Moorefield has overlay rotaion, so decoder doesn't generate rotation
     * output according to windows manager. It is controlled by payload info
     * in which HWC signal decoder to generate rotation output
     */
        long long hwc_timestamp = 0;
        int index = -1;

        for (i = 0; i < obj_context->num_render_targets; i++) {
            object_surface_p obj_surface = SURFACE(obj_context->render_targets[i]);
            /* traverse all surfaces' share info to find out the latest transform info */
            if (obj_surface && obj_surface->share_info) {
                if (obj_surface->share_info->hwc_timestamp > hwc_timestamp) {
                    hwc_timestamp = obj_surface->share_info->hwc_timestamp;
                    index = i;
                }
            }
        }
        if (index >= 0) {
            object_surface_p obj_surface = SURFACE(obj_context->render_targets[index]);
            if (obj_surface && obj_surface->share_info) {
                int transform = obj_surface->share_info->layer_transform;
                driver_data->mipi0_rotation = HAL2VAROTATION(transform);
                drv_debug_msg(VIDEO_DEBUG_GENERAL, "Signal from HWC to rotate %d\n", driver_data->mipi0_rotation);
            }
        }
    } else if (driver_data->native_window) {
        int display_rotate = 0;
        psb_android_surfaceflinger_rotate(driver_data->native_window, &display_rotate);
        drv_debug_msg(VIDEO_DEBUG_GENERAL, "NativeWindow(0x%x), get surface flinger rotate %d\n", driver_data->native_window, display_rotate);

        if (driver_data->mipi0_rotation != display_rotate) {
            driver_data->mipi0_rotation = display_rotate;
        }
    } else {
        long long hwc_timestamp = 0;
        int index = -1;

        for (i = 0; i < obj_context->num_render_targets; i++) {
            object_surface_p obj_surface = SURFACE(obj_context->render_targets[i]);
            /* traverse all surfaces' share info to find out the latest transform info */
            if (obj_surface && obj_surface->share_info) {
                if (obj_surface->share_info->hwc_timestamp > hwc_timestamp) {
                    hwc_timestamp = obj_surface->share_info->hwc_timestamp;
                    index = i;
                }
            }
        }
        if (index >= 0) {
            object_surface_p obj_surface = SURFACE(obj_context->render_targets[index]);
            if (obj_surface && obj_surface->share_info) {
                int transform = obj_surface->share_info->layer_transform;
                driver_data->mipi0_rotation = HAL2VAROTATION(transform);
            }
        }
    }

#ifdef PSBVIDEO_MRFL
    if ((mode == HDMI_VIDEO_ISPLAYING) && driver_data->native_window) {
        int display_rotate = 0;
        psb_android_surfaceflinger_rotate(driver_data->native_window, &display_rotate);
        drv_debug_msg(VIDEO_DEBUG_GENERAL, "NativeWindow(0x%x), get surface flinger rotate %d\n", driver_data->native_window, display_rotate);

        if (driver_data->mipi0_rotation != display_rotate && !IS_MOFD(driver_data)) {
            driver_data->mipi0_rotation = display_rotate;
        }
    }
#endif

    /* calc VA rotation and WM rotation, and assign to the final rotation degree */
    angle = Rotation2Angle(driver_data->va_rotate) + Rotation2Angle(driver_data->mipi0_rotation);
    driver_data->local_rotation = Angle2Rotation(angle);
    angle = Rotation2Angle(driver_data->va_rotate) + Rotation2Angle(driver_data->hdmi_rotation);
    driver_data->extend_rotation = Angle2Rotation(angle);

    /* On MOFD, no need to use meta rotation, just use rotation angle signal from HWC */
    if (IS_MOFD(driver_data)) {
        driver_data->local_rotation = driver_data->mipi0_rotation;
        driver_data->extend_rotation = Rotation2Angle(driver_data->hdmi_rotation);
    }

    /* for any case that local and extened rotation are not same, fallback to GPU */
    if ((driver_data->mipi1_rotation != VA_ROTATION_NONE) ||
        ((driver_data->local_rotation != VA_ROTATION_NONE) &&
         (driver_data->extend_rotation != VA_ROTATION_NONE) &&
         (driver_data->local_rotation != driver_data->extend_rotation))) {
        new_rotate = ROTATE_VA2MSVDX(driver_data->local_rotation);
        if (driver_data->is_android == 0) /*fallback to texblit path*/
            driver_data->output_method = PSB_PUTSURFACE_CTEXTURE;
    } else {
        if (driver_data->local_rotation == VA_ROTATION_NONE)
            new_rotate = driver_data->extend_rotation;
        else
            new_rotate = driver_data->local_rotation;

        if (driver_data->is_android == 0) {
            if (driver_data->output_method != PSB_PUTSURFACE_FORCE_CTEXTURE)
                driver_data->output_method = PSB_PUTSURFACE_COVERLAY;
        }
    }

    if (old_rotate != new_rotate) {
        drv_debug_msg(VIDEO_DEBUG_GENERAL, "MSVDX: new rotation %d desired\n", new_rotate);
        driver_data->msvdx_rotate_want = new_rotate;
    }

#ifdef TARGET_HAS_MULTIPLE_DISPLAY
    int scaling_buffer_width = 1920, scaling_buffer_height = 1080 ;
    int scaling_width = 0, scaling_height = 0;
    int scaling_offset_x = 0, scaling_offset_y = 0;
    int old_bufw = 0, old_bufh = 0, old_x = 0, old_y = 0, old_w = 0, old_h = 0;
    int bScaleChanged = 0, size = 0;
    unsigned char * surface_data;

    int ret = psb_android_get_mds_decoder_output_resolution(
                (void*)driver_data->ws_priv,
                &scaling_width, &scaling_height,
                &scaling_offset_x, &scaling_offset_y,
                &scaling_buffer_width, &scaling_buffer_height);

    if ((old_bufw != scaling_buffer_width) || (old_bufh != scaling_buffer_height) ||
        (old_x != scaling_offset_x) || (old_y != scaling_offset_y) ||
        (old_w != scaling_width) || (old_h != scaling_height)) {
        bScaleChanged = 1;
    }

    old_x = scaling_offset_x;
    old_y = scaling_offset_y;
    old_w = scaling_width;
    old_h = scaling_height;
    old_bufw = scaling_buffer_width;
    old_bufh = scaling_buffer_height;

    /* turn off ved downscaling if width and height are 0.
     * Besides, scaling_width and scaling_height must be a multiple of 2.
     */
    if (!ret || (!scaling_width || !scaling_height) ||
             (scaling_width & 1) || (scaling_height & 1)) {
        obj_context->msvdx_scaling = 0;
        obj_context->scaling_width = 0;
        obj_context->scaling_height = 0;
        obj_context->scaling_offset_x= 0;
        obj_context->scaling_offset_y = 0;
        obj_context->scaling_buffer_width = 0;
        obj_context->scaling_buffer_height = 0;
    } else {
        obj_context->msvdx_scaling = 1;
        obj_context->scaling_width = scaling_width;
        obj_context->scaling_height = scaling_height;
        obj_context->scaling_offset_x= scaling_offset_x;
        obj_context->scaling_offset_y = scaling_offset_y;
        obj_context->scaling_buffer_width = scaling_buffer_width;
        obj_context->scaling_buffer_height = scaling_buffer_height;
    }
    if (bScaleChanged) {
        if ((obj_surface != NULL) &&
            (obj_surface->out_loop_surface != NULL)) {
            if (psb_buffer_map(&obj_surface->out_loop_surface->buf, &surface_data)) {
                drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to map rotation buffer before clear it");
            }
            else {
                size = obj_surface->out_loop_surface->chroma_offset;
                memset(surface_data, 0, size);
                memset(surface_data + size, 0x80, obj_surface->out_loop_surface->size - size);
                psb_buffer_unmap(&obj_context->current_render_target->out_loop_surface->buf);
            }
        }
    }
#endif
}


void psb_CheckInterlaceRotate(object_context_p obj_context, unsigned char *pic_param_tmp)
{
    object_surface_p obj_surface = obj_context->current_render_target;

    switch (obj_context->profile) {
    case VAProfileMPEG2Simple:
    case VAProfileMPEG2Main: {
        VAPictureParameterBufferMPEG2 *pic_params = (VAPictureParameterBufferMPEG2 *)pic_param_tmp;
        if ((pic_params->picture_coding_extension.bits.picture_structure == TOP_FIELD) ||
            (pic_params->picture_coding_extension.bits.picture_structure == BOTTOM_FIELD) ||
            ((pic_params->picture_coding_extension.bits.picture_structure == FRAME_PICTURE) &&
             (pic_params->picture_coding_extension.bits.progressive_frame == 0)))
            obj_context->interlaced_stream = 1;
        else
            obj_context->interlaced_stream = 0;
        break;
    }
    case VAProfileMPEG4Simple:
    case VAProfileMPEG4AdvancedSimple:
    case VAProfileMPEG4Main:
    case VAProfileH263Baseline: {
        VAPictureParameterBufferMPEG4 *pic_params = (VAPictureParameterBufferMPEG4 *)pic_param_tmp;

        if (pic_params->vol_fields.bits.interlaced)
            obj_context->interlaced_stream = 1; /* is it the right way to check? */
        break;
    }
    case VAProfileH264Baseline:
    case VAProfileH264Main:
    case VAProfileH264High:
    case VAProfileH264ConstrainedBaseline: {
        VAPictureParameterBufferH264 *pic_params = (VAPictureParameterBufferH264 *)pic_param_tmp;
        /* is it the right way to check? */
        if (pic_params->pic_fields.bits.field_pic_flag || pic_params->seq_fields.bits.mb_adaptive_frame_field_flag)
            obj_context->interlaced_stream = 1;

        break;
    }
    case VAProfileVC1Simple:
    case VAProfileVC1Main:
    case VAProfileVC1Advanced: {
        VAPictureParameterBufferVC1 *pic_params = (VAPictureParameterBufferVC1 *)pic_param_tmp;

        /* is it the right way to check? */
        if (pic_params->sequence_fields.bits.interlace)
            obj_context->interlaced_stream = 1;

        break;
    }
    default:
        break;
    }

    if (obj_surface->share_info) {
        psb_surface_share_info_p share_info = obj_surface->share_info;
        if (obj_context->interlaced_stream) {
            SET_SURFACE_INFO_rotate(obj_surface->psb_surface, 0);
            obj_context->msvdx_rotate = 0;
            share_info->bob_deinterlace = 1; //enable interlace flag
        } else {
           share_info->bob_deinterlace = 0;
       }
    }
}
#if 0
/*
 * Detach a surface from obj_surface
 */
VAStatus psb_DestroyRotateSurface(
    VADriverContextP ctx,
    object_surface_p obj_surface,
    int rotate
)
{
    INIT_DRIVER_DATA;
    psb_surface_p psb_surface = obj_surface->out_loop_surface;
    VAStatus vaStatus = VA_STATUS_SUCCESS;

    /* Allocate alternative output surface */
    if (psb_surface) {
        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Try to allocate surface for alternative rotate output\n");
        psb_surface_destroy(obj_surface->out_loop_surface);
        free(psb_surface);

        obj_surface->out_loop_surface = NULL;
        obj_surface->width_r = obj_surface->width;
        obj_surface->height_r = obj_surface->height;
    }

    return vaStatus;
}
#endif
#ifdef TARGET_HAS_MULTIPLE_DISPLAY
/*
 * Create and attach a downscaling surface to obj_surface
 */
static void clearScalingInfo(psb_surface_share_info_p share_info) {
    if (share_info == NULL)
        return;
    share_info->width_s = 0;
    share_info->height_s = 0;
    share_info->scaling_khandle = 0;

    share_info->scaling_luma_stride = 0;
    share_info->scaling_chroma_u_stride = 0;
    share_info->scaling_chroma_v_stride = 0;
    return;
}

VAStatus psb_CreateScalingSurface(
        object_context_p obj_context,
        object_surface_p obj_surface
)
{
    psb_surface_p psb_surface;
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    psb_surface_share_info_p share_info = obj_surface->share_info;
    unsigned int set_flags, clear_flags;
    int ret = 0;

    if (obj_context->driver_data->render_rect.width <= obj_context->scaling_width || obj_context->driver_data->render_rect.height <= obj_context->scaling_height) {
        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Either downscaling is not required or upscaling is needed for the target resolution\n");
        obj_context->msvdx_scaling = 0; /* Disable downscaling */
        clearScalingInfo(share_info);
        return VA_STATUS_ERROR_OPERATION_FAILED;
    }

    psb_surface = obj_surface->scaling_surface;
    /* Check if downscaling resolution has been changed */
    if (psb_surface) {
        if (obj_surface->width_s != obj_context->scaling_width || obj_surface->height_s != obj_context->scaling_height) {
            psb_surface_destroy(psb_surface);
            free(psb_surface);
            psb_surface = NULL;

            drv_debug_msg(VIDEO_DEBUG_GENERAL, "downscaling buffer realloc: %d x %d -> %d x %d\n",
                    obj_surface->width_s, obj_surface->height_s, obj_context->scaling_width, obj_context->scaling_height);
            clearScalingInfo(share_info);
        }
    }

    if (!psb_surface) {
        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Try to allocate surface for alternative scaling output: %dx%d\n",
                      obj_context->scaling_width, obj_context->scaling_height);
        psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s));
        CHECK_ALLOCATION(psb_surface);

        vaStatus = psb_surface_create(obj_context->driver_data, obj_context->scaling_width,
                                      (obj_context->scaling_height + 0x1f) & ~0x1f, VA_FOURCC_NV12,
                                      0, psb_surface);

        //set_flags = WSBM_PL_FLAG_CACHED | DRM_PSB_FLAG_MEM_MMU | WSBM_PL_FLAG_SHARED;
        //clear_flags = WSBM_PL_FLAG_UNCACHED | WSBM_PL_FLAG_WC;
        //ret = psb_buffer_setstatus(&psb_surface->buf, set_flags, clear_flags);

        if (VA_STATUS_SUCCESS != vaStatus || ret) {
            drv_debug_msg(VIDEO_DEBUG_GENERAL, "allocate scaling buffer fail\n");
            free(psb_surface);
            obj_surface->scaling_surface = NULL;
            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
            DEBUG_FAILURE;
            return vaStatus;
        }

        obj_surface->width_s = obj_context->scaling_width;
        obj_surface->height_s = obj_context->scaling_height;
        obj_surface->buffer_width_s = obj_context->scaling_width;
        obj_surface->buffer_height_s = obj_context->scaling_height;
        obj_surface->offset_x_s= obj_context->scaling_offset_x;
        obj_surface->offset_y_s= obj_context->scaling_offset_y;
        obj_context->scaling_update = 1;
    }
    obj_surface->scaling_surface = psb_surface;

    /* derive the protected flag from the primay surface */
    SET_SURFACE_INFO_protect(psb_surface,
                             GET_SURFACE_INFO_protect(obj_surface->psb_surface));

    /*notify hwc that rotated buffer is ready to use.
     * TODO: Do these in psb_SyncSurface()
     */
    if (share_info != NULL) {
        share_info->width_s = obj_surface->width_s;
        share_info->height_s = obj_surface->height_s;
        share_info->scaling_khandle =
        (uint32_t)(wsbmKBufHandle(wsbmKBuf(psb_surface->buf.drm_buf)));

        share_info->scaling_luma_stride = psb_surface->stride;
        share_info->scaling_chroma_u_stride = psb_surface->stride;
        share_info->scaling_chroma_v_stride = psb_surface->stride;
    }
    return vaStatus;
}
#else
VAStatus psb_CreateScalingSurface(
        object_context_p __maybe_unused obj_context,
        object_surface_p __maybe_unused obj_surface
)
{
    return VA_STATUS_ERROR_OPERATION_FAILED;
}
#endif

/*
 * Create and attach a rotate surface to obj_surface
 */
VAStatus psb_CreateRotateSurface(
    object_context_p obj_context,
    object_surface_p obj_surface,
    int msvdx_rotate
)
{
    int width, height;
    psb_surface_p rotate_surface;
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    int need_realloc = 0;
    unsigned int flags = 0;
    psb_surface_share_info_p share_info = obj_surface->share_info;
    psb_driver_data_p driver_data = obj_context->driver_data;
    int rotate_stride = 0, rotate_tiling = 0;
    object_config_p obj_config = CONFIG(obj_context->config_id);
    unsigned char * surface_data;

    CHECK_CONFIG(obj_config);

    rotate_surface = obj_surface->out_loop_surface;

    if (msvdx_rotate == 0
#ifdef OVERLAY_ENABLE_MIRROR
        /*Bypass 180 degree rotate when overlay enabling mirror*/
        || msvdx_rotate == VA_ROTATION_180
#endif
        )
        return vaStatus;

    if (rotate_surface) {
        CHECK_SURFACE_REALLOC(rotate_surface, msvdx_rotate, need_realloc);
        if (need_realloc == 0) {
            goto exit;
        } else { /* free the old rotate surface */
            /*FIX ME: it is not safe to do that because surfaces may be in use for rendering.*/
            psb_surface_destroy(obj_surface->out_loop_surface);
            memset(rotate_surface, 0, sizeof(*rotate_surface));
        }
    } else {
        rotate_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s));
        CHECK_ALLOCATION(rotate_surface);
    }

#ifdef PSBVIDEO_MSVDX_DEC_TILING
    SET_SURFACE_INFO_tiling(rotate_surface, GET_SURFACE_INFO_tiling(obj_surface->psb_surface));
#endif
#ifdef PSBVIDEO_MRFL_VPP_ROTATE
    SET_SURFACE_INFO_rotate(rotate_surface, msvdx_rotate);
#endif
    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Try to allocate surface for alternative rotate output\n");

    flags = IS_ROTATED;

    if (msvdx_rotate == 2 /* VA_ROTATION_180 */) {
        width = obj_surface->width;
        height = obj_surface->height;

#ifdef PSBVIDEO_MRFL_VPP_ROTATE
    if (obj_config->entrypoint == VAEntrypointVideoProc &&
            share_info && share_info->out_loop_khandle) {
            vaStatus = psb_surface_create_from_kbuf(driver_data, width, height,
                                  obj_surface->psb_surface->size, VA_FOURCC_NV12,
                                  share_info->out_loop_khandle,
                                  obj_surface->psb_surface->stride,
                                  obj_surface->psb_surface->stride,
                                  obj_surface->psb_surface->stride,
                                  0, 0, 0, rotate_surface);
    } else
#endif
            vaStatus = psb_surface_create(driver_data, width, height, VA_FOURCC_NV12,
                                      flags, rotate_surface);
    } else {
        width = obj_surface->height_origin;
        height = (obj_surface->width + 0x1f) & ~0x1f;

#ifdef PSBVIDEO_MRFL_VPP_ROTATE
        if (obj_config->entrypoint == VAEntrypointVideoProc &&
                share_info && share_info->out_loop_khandle != 0) {
                drv_debug_msg(VIDEO_DEBUG_GENERAL,"Create the surface from kbuf out_loop_khandle=%x!\n", share_info->out_loop_khandle);
                rotate_tiling = GET_SURFACE_INFO_tiling(rotate_surface);
                rotate_stride = get_surface_stride(width, rotate_tiling);
                vaStatus = psb_surface_create_from_kbuf(driver_data, width, height,
                                  (rotate_stride * height * 3) / 2, VA_FOURCC_NV12,
                                  share_info->out_loop_khandle,
                                  rotate_stride, rotate_stride, rotate_stride,
                                  0, rotate_stride * height, rotate_stride * height,
                                  rotate_surface);
        } else
#endif
        {
            drv_debug_msg(VIDEO_DEBUG_GENERAL,"Create rotated buffer. width=%d, height=%d\n", width, height);
            if (CONTEXT_SCALING(obj_context)) {
                width = obj_context->scaling_buffer_height;
                height = (obj_context->scaling_buffer_width+ 0x1f) & ~0x1f;
            }
            vaStatus = psb_surface_create(driver_data, width, height, VA_FOURCC_NV12,
                                      flags, rotate_surface);
        }
    }
    if (VA_STATUS_SUCCESS != vaStatus) {
        free(rotate_surface);
        obj_surface->out_loop_surface = NULL;
        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
        DEBUG_FAILURE;
        return vaStatus;
    }

    //clear rotation surface
     if (CONTEXT_SCALING(obj_context)) {
        if (psb_buffer_map(&rotate_surface->buf, &surface_data)) {
            drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to map rotation buffer before clear it");
        }
        else {
            memset(surface_data, 0, rotate_surface->chroma_offset);
            memset(surface_data + rotate_surface->chroma_offset, 0x80,
                       rotate_surface->size - rotate_surface->chroma_offset);
            psb_buffer_unmap(&rotate_surface->buf);
        }
    }
    obj_surface->width_r = width;
    obj_surface->height_r = height;

#ifdef PSBVIDEO_MSVDX_DEC_TILING
    drv_debug_msg(VIDEO_DEBUG_GENERAL, "attempt to update tile context\n");
    if (GET_SURFACE_INFO_tiling(rotate_surface) && obj_config->entrypoint != VAEntrypointVideoProc) {
        drv_debug_msg(VIDEO_DEBUG_GENERAL, "update tile context\n");
        object_context_p obj_context = CONTEXT(obj_surface->context_id);
        if (NULL == obj_context) {
            vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
            DEBUG_FAILURE;
            return vaStatus;
        }
        unsigned long msvdx_tile = psb__tile_stride_log2_256(obj_surface->width_r);
        obj_context->msvdx_tile &= 0xf; /* clear rotate tile */
        obj_context->msvdx_tile |= (msvdx_tile << 4);
        obj_context->ctp_type &= (~PSB_CTX_TILING_MASK); /* clear tile context */
        obj_context->ctp_type |= ((obj_context->msvdx_tile & 0xff) << 16);
        psb_update_context(driver_data, obj_context->ctp_type);
    }
#endif

exit:
    obj_surface->out_loop_surface = rotate_surface;
    SET_SURFACE_INFO_rotate(rotate_surface, msvdx_rotate);
    /* derive the protected flag from the primay surface */
    SET_SURFACE_INFO_protect(rotate_surface,
                             GET_SURFACE_INFO_protect(obj_surface->psb_surface));

    /*notify hwc that rotated buffer is ready to use.
    * TODO: Do these in psb_SyncSurface()
    */
    if (share_info != NULL) {
	share_info->width_r = rotate_surface->stride;
        share_info->height_r = obj_surface->height_r;
        share_info->out_loop_khandle =
            (uint32_t)(wsbmKBufHandle(wsbmKBuf(rotate_surface->buf.drm_buf)));
        share_info->metadata_rotate = VAROTATION2HAL(driver_data->va_rotate);
        share_info->surface_rotate = VAROTATION2HAL(msvdx_rotate);

        share_info->out_loop_luma_stride = rotate_surface->stride;
        share_info->out_loop_chroma_u_stride = rotate_surface->stride;
        share_info->out_loop_chroma_v_stride = rotate_surface->stride;
    }

    return vaStatus;
}

VAStatus psb_DestroyRotateBuffer(
    object_context_p obj_context,
    object_surface_p obj_surface)
{
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    psb_surface_share_info_p share_info = obj_surface->share_info;
    psb_driver_data_p driver_data = obj_context->driver_data;
    psb_surface_p rotate_surface = obj_surface->out_loop_surface;
    struct psb_buffer_s psb_buf;

    if (share_info && share_info->out_loop_khandle) {
        drv_debug_msg(VIDEO_DEBUG_GENERAL,"psb_DestroyRotateBuffer out_loop_khandle=%x\n", share_info->out_loop_khandle);
        vaStatus = psb_kbuffer_reference(driver_data, &psb_buf, share_info->out_loop_khandle);
        if (vaStatus != VA_STATUS_SUCCESS)
            return vaStatus;
        psb_buffer_destroy(&psb_buf);
        share_info->out_loop_khandle = 0;
    }

    if (rotate_surface)
        free(rotate_surface);

    return vaStatus;
}

