/*
// Copyright (c) 2014 Intel Corporation 
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/
#include <common/utils/HwcTrace.h>
#include <Hwcomposer.h>
#include <BufferManager.h>
#include <ips/anniedale/AnnRGBPlane.h>
#include <ips/tangier/TngGrallocBuffer.h>
#include <ips/common/PixelFormat.h>

namespace android {
namespace intel {

AnnRGBPlane::AnnRGBPlane(int index, int type, int disp)
    : DisplayPlane(index, type, disp)
{
    CTRACE();
    memset(&mContext, 0, sizeof(mContext));
}

AnnRGBPlane::~AnnRGBPlane()
{
    CTRACE();
}

bool AnnRGBPlane::enable()
{
    return enablePlane(true);
}

bool AnnRGBPlane::disable()
{
    return enablePlane(false);
}

bool AnnRGBPlane::reset()
{
    while (!mScalingBufferMap.isEmpty()) {
        uint32_t handle = mScalingBufferMap.valueAt(0);
        Hwcomposer::getInstance().getBufferManager()->freeGrallocBuffer(handle);
        mScalingBufferMap.removeItemsAt(0);
    }

    return DisplayPlane::reset();
}

bool AnnRGBPlane::flip(void*)
{
    if (mForceScaling) {
        BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
        if (!bm->blitGrallocBuffer(mScalingSource, mScalingTarget, mDisplayCrop, 0)) {
            ELOGTRACE("Failed to blit RGB buffer.");
            return false;
        }
    }

    return true;
}

void* AnnRGBPlane::getContext() const
{
    CTRACE();
    return (void *)&mContext;
}

void AnnRGBPlane::setZOrderConfig(ZOrderConfig& /* config */, void * /* nativeConfig */)
{
    CTRACE();
}

bool AnnRGBPlane::setDataBuffer(uint32_t handle)
{
    if (!handle) {
        if (!mForceScaling) {
            setFramebufferTarget(handle);
            return true;
        } else {
            ELOGTRACE("Invalid handle while scaling is required.");
            return false;
        }
    }

    if (mForceScaling) {
        BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
        ssize_t index = mScalingBufferMap.indexOfKey(handle);
        if (index < 0) {
            mScalingTarget = bm->allocGrallocBuffer(
                    mDisplayWidth,
                    mDisplayHeight,
                    HAL_PIXEL_FORMAT_RGBA_8888,
                    GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE);
            if (!mScalingTarget) {
                ELOGTRACE("Failed to allocate gralloc buffer.");
                return false;
            }
            mScalingBufferMap.add(handle, mScalingTarget);
        } else {
            mScalingTarget = mScalingBufferMap.valueAt(index);
        }
        mScalingSource = handle;
        handle = mScalingTarget;
    }

    TngGrallocBuffer tmpBuf(handle);
    uint32_t usage;
    bool ret;

    ALOGTRACE("handle = %#x", handle);

    usage = tmpBuf.getUsage();
    if (GRALLOC_USAGE_HW_FB & usage) {
        setFramebufferTarget(handle);
        return true;
    }

    // use primary as a sprite
    ret = DisplayPlane::setDataBuffer(handle);
    if (ret == false) {
        ELOGTRACE("failed to set data buffer");
        return ret;
    }

    return true;
}

bool AnnRGBPlane::setDataBuffer(BufferMapper& mapper)
{
    int bpp;
    int srcX, srcY, srcW, srcH;
    int dstX, dstY, dstW, dstH;
    uint32_t spriteFormat;
    uint32_t stride;
    uint32_t linoff;
    uint32_t planeAlpha;
    drmModeModeInfoPtr mode = &mModeInfo;

    CTRACE();

    // setup plane position
    dstX = mPosition.x;
    dstY = mPosition.y;
    dstW = mPosition.w;
    dstH = mPosition.h;

    checkPosition(dstX, dstY, dstW, dstH);

    // setup plane format
    if (!PixelFormat::convertFormat(mapper.getFormat(), spriteFormat, bpp)) {
        ELOGTRACE("unsupported format %#x", mapper.getFormat());
        return false;
    }

    // setup stride and source buffer crop
    srcX = mapper.getCrop().x;
    srcY = mapper.getCrop().y;
    srcW = mapper.getWidth();
    srcH = mapper.getHeight();
    stride = mapper.getStride().rgb.stride;

    if (mPanelOrientation == PANEL_ORIENTATION_180)
        linoff = srcY * stride + srcX * bpp + (mapper.getCrop().h  - 1) * stride + (mapper.getCrop().w - 1) * bpp;
    else
        linoff = srcY * stride + srcX * bpp;

    // unlikely happen, but still we need make sure linoff is valid
    if (linoff > (stride * mapper.getHeight())) {
        ELOGTRACE("invalid source crop");
        return false;
    }

    // update context
    if (mType == PLANE_SPRITE)
        mContext.type = DC_SPRITE_PLANE;
    else
        mContext.type = DC_PRIMARY_PLANE;

    // setup plane alpha
    if (0 < mPlaneAlpha && mPlaneAlpha < 0xff) {
       planeAlpha = mPlaneAlpha | 0x80000000;
    } else {
       // disable plane alpha to offload HW
       planeAlpha = 0xff;
    }

    mContext.ctx.sp_ctx.index = mIndex;
    mContext.ctx.sp_ctx.pipe = mDevice;
    mContext.ctx.sp_ctx.cntr = spriteFormat | 0x80000000;
    mContext.ctx.sp_ctx.linoff = linoff;
    mContext.ctx.sp_ctx.stride = stride;

    // turn off premultipled alpha blending for HWC_BLENDING_COVERAGE
    if (mBlending == HWC_BLENDING_COVERAGE) {
        mContext.ctx.sp_ctx.cntr |= (0x1 << 23);
    }

    if (mPanelOrientation == PANEL_ORIENTATION_180)
        mContext.ctx.sp_ctx.cntr |= (0x1 << 15);

    if (mapper.isCompression()) {
        mContext.ctx.sp_ctx.stride = align_to(srcW, 32) * 4;
        mContext.ctx.sp_ctx.linoff = (align_to(srcW, 32) * srcH / 64) - 1;
        mContext.ctx.sp_ctx.tileoff = (srcY & 0xfff) << 16 | (srcX & 0xfff);
        mContext.ctx.sp_ctx.cntr |= (0x1 << 11);
    }

    mContext.ctx.sp_ctx.surf = mapper.getGttOffsetInPage(0) << 12;

    if (mPanelOrientation == PANEL_ORIENTATION_180) {
        if (mode->vdisplay && mode->hdisplay)
            mContext.ctx.sp_ctx.pos = ((mode->vdisplay - dstY - dstH) & 0xfff) << 16 | ((mode->hdisplay - dstX - dstW) & 0xfff);
        else
            mContext.ctx.sp_ctx.pos = (dstY & 0xfff) << 16 | (dstX & 0xfff);
    } else {
        mContext.ctx.sp_ctx.pos = (dstY & 0xfff) << 16 | (dstX & 0xfff);
    }

    mContext.ctx.sp_ctx.size =
        ((dstH - 1) & 0xfff) << 16 | ((dstW - 1) & 0xfff);
    mContext.ctx.sp_ctx.contalpa = planeAlpha;
    mContext.ctx.sp_ctx.update_mask = SPRITE_UPDATE_ALL;

    VLOGTRACE("type = %d, index = %d, cntr = %#x, linoff = %#x, stride = %#x,"
          "surf = %#x, pos = %#x, size = %#x, contalpa = %#x", mType, mIndex,
          mContext.ctx.sp_ctx.cntr,
          mContext.ctx.sp_ctx.linoff,
          mContext.ctx.sp_ctx.stride,
          mContext.ctx.sp_ctx.surf,
          mContext.ctx.sp_ctx.pos,
          mContext.ctx.sp_ctx.size,
          mContext.ctx.sp_ctx.contalpa);
    return true;
}

bool AnnRGBPlane::enablePlane(bool enabled)
{
    RETURN_FALSE_IF_NOT_INIT();

    struct drm_psb_register_rw_arg arg;
    memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));
    if (enabled) {
        arg.plane_enable_mask = 1;
    } else {
        arg.plane_disable_mask = 1;
    }

    if (mType == PLANE_SPRITE)
        arg.plane.type = DC_SPRITE_PLANE;
    else
        arg.plane.type = DC_PRIMARY_PLANE;

    arg.plane.index = mIndex;
    arg.plane.ctx = 0;

    // issue ioctl
    Drm *drm = Hwcomposer::getInstance().getDrm();
    bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
    if (ret == false) {
        WLOGTRACE("plane enabling (%d) failed with error code %d", enabled, ret);
        return false;
    }

    return true;
}

bool AnnRGBPlane::isDisabled()
{
    RETURN_FALSE_IF_NOT_INIT();

    struct drm_psb_register_rw_arg arg;
    memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));

    if (mType == PLANE_SPRITE)
        arg.plane.type = DC_SPRITE_PLANE;
    else
        arg.plane.type = DC_PRIMARY_PLANE;

    arg.get_plane_state_mask = 1;
    arg.plane.index = mIndex;
    arg.plane.ctx = 0;

    // issue ioctl
    Drm *drm = Hwcomposer::getInstance().getDrm();
    bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
    if (ret == false) {
        WLOGTRACE("plane state query failed with error code %d", ret);
        return false;
    }

    return arg.plane.ctx == PSB_DC_PLANE_DISABLED;
}

void AnnRGBPlane::postFlip()
{
    // prevent mUpdateMasks from being reset
    // skipping flip may cause flicking
}

void AnnRGBPlane::setFramebufferTarget(uint32_t handle)
{
    uint32_t stride;
    uint32_t planeAlpha;

    CTRACE();

    // do not need to update the buffer handle
    if (mCurrentDataBuffer != handle)
        mUpdateMasks |= PLANE_BUFFER_CHANGED;
    else
        mUpdateMasks &= ~PLANE_BUFFER_CHANGED;

    // if no update then do Not need set data buffer
    if (!mUpdateMasks)
        return;

    // don't need to map data buffer for primary plane
    if (mType == PLANE_SPRITE)
        mContext.type = DC_SPRITE_PLANE;
    else
        mContext.type = DC_PRIMARY_PLANE;

    stride = align_to((4 * align_to(mPosition.w, 32)), 64);

    if (0 < mPlaneAlpha && mPlaneAlpha < 0xff) {
       planeAlpha = mPlaneAlpha | 0x80000000;
    } else {
       // disable plane alpha to offload HW
       planeAlpha = 0xff;
    }

    // FIXME: use sprite context for sprite plane
    mContext.ctx.prim_ctx.update_mask = SPRITE_UPDATE_ALL;
    mContext.ctx.prim_ctx.index = mIndex;
    mContext.ctx.prim_ctx.pipe = mDevice;

    if (mPanelOrientation == PANEL_ORIENTATION_180)
        mContext.ctx.prim_ctx.linoff = (mPosition.h  - 1) * stride + (mPosition.w - 1) * 4;
    else
        mContext.ctx.prim_ctx.linoff = 0;

    mContext.ctx.prim_ctx.stride = stride;
    mContext.ctx.prim_ctx.tileoff = 0;
    mContext.ctx.prim_ctx.pos = 0;
    mContext.ctx.prim_ctx.size =
        ((mPosition.h - 1) & 0xfff) << 16 | ((mPosition.w - 1) & 0xfff);
    mContext.ctx.prim_ctx.surf = 0;
    mContext.ctx.prim_ctx.contalpa = planeAlpha;
    mContext.ctx.prim_ctx.cntr = PixelFormat::PLANE_PIXEL_FORMAT_BGRA8888;
    mContext.ctx.prim_ctx.cntr |= 0x80000000;

    // turn off premultipled alpha blending for HWC_BLENDING_COVERAGE
    if (mBlending == HWC_BLENDING_COVERAGE) {
        mContext.ctx.prim_ctx.cntr |= (0x1 << 23);
    }

    if (mPanelOrientation == PANEL_ORIENTATION_180)
        mContext.ctx.prim_ctx.cntr |= (0x1 << 15);

    VLOGTRACE("type = %d, index = %d, cntr = %#x, linoff = %#x, stride = %#x,"
          "surf = %#x, pos = %#x, size = %#x, contalpa = %#x", mType, mIndex,
          mContext.ctx.prim_ctx.cntr,
          mContext.ctx.prim_ctx.linoff,
          mContext.ctx.prim_ctx.stride,
          mContext.ctx.prim_ctx.surf,
          mContext.ctx.prim_ctx.pos,
          mContext.ctx.prim_ctx.size,
          mContext.ctx.sp_ctx.contalpa);

    mCurrentDataBuffer = handle;
}

} // namespace intel
} // namespace android
