fimgse2d.cpp

来自「6410BSP3」· C++ 代码 · 共 1,270 行 · 第 1/4 页

CPP
1,270
字号
//
// Copyright (c) Samsung Electronics. Co. LTD.  All rights reserved.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:    fimgse2d.cpp

Abstract:       hardware control implementation for FIMGSE-2D v2.0, This class is a kind of adapter

Functions:

Notes:          This version is made for S3C6410.

--*/

#include "precomp.h"        // Share Display Driver's
#include <assert.h>
#include <dispperf.h>
#include "regctrl_g2d.h"

#undef SWAP
#define SWAP(a,b,type) { type tmp=a; a=b; b=tmp; }

FIMGSE2D::FIMGSE2D() : RegCtrlG2D()
{
//    Reset();
        m_iROPMapper[ROP_SRC_ONLY] = G2D_ROP_SRC_ONLY;
        m_iROPMapper[ROP_PAT_ONLY] = G2D_ROP_PAT_ONLY;
        m_iROPMapper[ROP_DST_ONLY] = G2D_ROP_DST_ONLY;
        m_iROPMapper[ROP_SRC_OR_DST] = G2D_ROP_SRC_OR_DST;
        m_iROPMapper[ROP_SRC_OR_PAT] = G2D_ROP_SRC_OR_PAT;
        m_iROPMapper[ROP_DST_OR_PAT] = G2D_ROP_DST_OR_PAT;
        m_iROPMapper[ROP_SRC_AND_DST] = G2D_ROP_SRC_AND_DST;
        m_iROPMapper[ROP_SRC_AND_PAT] = G2D_ROP_SRC_AND_PAT;
        m_iROPMapper[ROP_DST_AND_PAT] = G2D_ROP_DST_AND_PAT;
        m_iROPMapper[ROP_SRC_XOR_DST] = G2D_ROP_SRC_XOR_DST;
        m_iROPMapper[ROP_SRC_XOR_PAT] = G2D_ROP_SRC_XOR_PAT;
        m_iROPMapper[ROP_DST_XOR_PAT] = G2D_ROP_DST_XOR_PAT;
        m_iROPMapper[ROP_NOTSRCCOPY] = G2D_ROP_NOTSRCCOPY;
        m_iROPMapper[ROP_DSTINVERT] = G2D_ROP_DSTINVERT;
        m_iROPMapper[ROP_R2_NOTCOPYPEN] = G2D_ROP_R2_NOTCOPYPEN;
}

FIMGSE2D::~FIMGSE2D()
{
}

// Set Ternary raster operation
// Support 256 raster operation
// Refer to ternary raster operation table if you know 256 ROP

// Set Alpha Value
void FIMGSE2D::SetAlphaValue(BYTE ucAlphaVal)
{
    ucAlphaVal &= 0xff;
    m_pG2DReg->ALPHA = (m_pG2DReg->ALPHA&(~0xff)) | ucAlphaVal;
}

// Set alpha blending mode
void FIMGSE2D::SetAlphaMode(G2D_ALPHA_BLENDING_MODE eMode)
{
    RequestEmptyFifo(1);
/*    DWORD uAlphaBlend;

    uAlphaBlend =
        (eMode == G2D_NO_ALPHA_MODE) ? G2D_NO_ALPHA_BIT :
        (eMode == G2D_PP_ALPHA_SOURCE_MODE) ? G2D_PP_ALPHA_SOURCE_BIT :
        (eMode == G2D_ALPHA_MODE) ? G2D_ALPHA_BIT : 
        (eMode == G2D_FADING_MODE) ? G2D_FADING_BIT : G2D_NO_ALPHA_BIT;
*/
    m_pG2DReg->ROP = (m_pG2DReg->ROP & ~(0x7<<10)) | eMode;//AlphaBlend;
}

// Set fade value
void FIMGSE2D::SetFadingValue(BYTE ucFadeVal)
{
    ucFadeVal &= 0xff;
    m_pG2DReg->ALPHA = (m_pG2DReg->ALPHA & ~(0xff<<8)) | (ucFadeVal<<8);
}

void FIMGSE2D::DisableEffect(void)
{
    m_pG2DReg->ROP &= ~(0x7<<10);
}

void FIMGSE2D::EnablePlaneAlphaBlending(BYTE ucAlphaVal)
{
    ucAlphaVal &= 0xff;

    // Set Alpha Blending Mode
    m_pG2DReg->ROP = ((m_pG2DReg->ROP) & ~(0x7<<10)) | G2D_ALPHA_MODE;


    // Set Alpha Value
    m_pG2DReg->ALPHA = ((m_pG2DReg->ALPHA) & ~(0xff)) | ucAlphaVal;

    m_ucAlphaVal = ucAlphaVal;
    m_bIsAlphaCall = true;
}

void FIMGSE2D::DisablePlaneAlphaBlending(void)
{
    DisableEffect();
}

void FIMGSE2D::EnablePixelAlphaBlending(void) // Only Support 24bpp and Only used in BitBlt
{
    m_pG2DReg->ROP = ((m_pG2DReg->ROP) & ~(0x7<<10)) | G2D_PP_ALPHA_SOURCE_MODE;
}

void FIMGSE2D::DisablePixelAlphaBlending(void) // Only Support 24bpp and only used in BitBlt
{
    DisableEffect();
}

void FIMGSE2D::EnableFadding(BYTE ucFadingVal)
{
    BYTE ucAlphaVal;

    ucAlphaVal = (m_bIsAlphaCall == true) ? m_ucAlphaVal : 255;

    ucFadingVal &= 0xff;

    // Set Fadding Mode    
    m_pG2DReg->ROP = ((m_pG2DReg->ROP) & ~(0x7<<10)) | G2D_FADING_MODE;

    // Set Fadding Value    
    m_pG2DReg->ALPHA = ((m_pG2DReg->ALPHA) & ~(0xff<<8)) | (ucFadingVal<<8) | (ucAlphaVal<<0);
}

void FIMGSE2D::DisableFadding(void)
{
    DisableEffect();
}



/**
*    @fn    FIMGSE2D::GetRotType(int m_iRotate)
*    @brief    This function convert rotation degree value to ROT_TYPE
*
*/
ROT_TYPE FIMGSE2D::GetRotType(int m_iRotate)
{
    switch(m_iRotate)
    {
        case DMDO_0:
            return    ROT_0;
        case DMDO_90:
            return    ROT_270;
        case DMDO_180:
            return    ROT_180;
        case DMDO_270:
            return    ROT_90;
        default:
            return    ROT_0;
    }
    return ROT_0;
}

/**
*    @fn    DWORD FIMGSE2D::CalculateXYIncrFormat(DWORD uDividend, DWORD uDivisor)
*    @brief    This function returns x_incr or y_incr vaule in register format
*    @input    this function accept real pixel coordinate, ex) (0,0)~(9,9) means that 10pixel by pixel image
*    @return    Result value
*/
DWORD FIMGSE2D::CalculateXYIncrFormat(DWORD uDividend, DWORD uDivisor)
{
    int i;
    DWORD uQuotient;
    DWORD uUnderPoint=0;

    if(uDivisor == 0)
    {
        uDivisor = 1;    //< this will prevent data abort. but result is incorrect.
    }

    uQuotient = (DWORD)(uDividend/uDivisor);
    // Quotient should be less than MAX_XCOORD or MAX_YCOORD.
    if(uQuotient > MAX_2DHW_XCOORD) 
    {
        RETAILMSG(DISP_ZONE_WARNING, (TEXT("Increment value to stretch can not exceed %d, Value will be set as 1.0\n"), MAX_2DHW_XCOORD));
        return ((1<<11) | 0 );
    }

    uDividend-=(uQuotient*uDivisor);

    /// Now under point is calculated.
    for (i=0; i<12; i++)
    {
        uDividend <<= 1;
        uUnderPoint <<= 1;

        if (uDividend >= uDivisor)
        {
            uUnderPoint = uUnderPoint | 1;
            uDividend -= uDivisor;
        }
        DEBUGMSG(DISP_ZONE_2D, (TEXT("uDivend:%x(%d), uDivisor:%x(%d), uUnderPoint:%x(%d)\n"), uDividend, uDividend, uDivisor, uDivisor,uUnderPoint, uUnderPoint));
    }

    uUnderPoint = (uUnderPoint + 1) >> 1;

    return ( uUnderPoint|(uQuotient<<11) );
}

/**
*    @fn    FIMGSE2D::BitBlt(PRECTL prclSrc, PRECTL prclDst, ROT_TYPE m_iRotate)
*    @param    prclSrc    Source Rectangle
*    @param    prclDst    Destination Rectangle
*    @param    m_iRotate    Rotatation Degree. See also ROT_TYPE type
*    @note This funciton performs real Bit blit using 2D HW. this functio can handle rotation case.
*            There's predefine macro type for presenting rotation register's setting value
*            G2D_ROTATION
@    @sa    ROT_TYPE    this can be set mixed value.
*/
void FIMGSE2D::BitBlt(PRECTL prclSrc, PRECTL prclDst, ROT_TYPE m_iRotate )
{
    DWORD uCmdRegVal=0;
    RECT    rectDst;            //< If rotation case this value must be corrected.
    
    RETAILMSG(DISP_ZONE_ENTER,(TEXT("[2DHW] BitBlt Entry\r\n")));    

    /// Always LeftTop Coordinate is less than RightBottom for Source and Destination Region
    assert( (prclSrc->left < prclSrc->right) && (prclSrc->top < prclSrc->bottom) );
    assert( (prclDst->left < prclDst->right) && (prclDst->top < prclDst->bottom) );    

    /// Set Destination's Rotation mode
    SetRotationMode(m_iRotate);
    SetCoordinateSrcBlock(prclSrc->left, prclSrc->top, prclSrc->right - 1, prclSrc->bottom - 1);

    if(m_iRotate == ROT_180)        //< origin set to (x2,y2)
    {
        rectDst.left = prclDst->right - 1;                        //< x2
        rectDst.top = prclDst->bottom - 1;                        //< y2
        rectDst.right = 2 * (prclDst->right - 1) - prclDst->left ;        //< x2 + (x2 - x1)
        rectDst.bottom = 2 * (prclDst->bottom -1) - prclDst->top;    //< y2 + (y2 - y1)
    }
    else     if(m_iRotate == ROT_90)        //<In this time, Height and Width are swapped.
    {
        rectDst.left = prclDst->right - 1;                        //< x2
        rectDst.right = prclDst->right - 1 + prclDst->bottom - 1 - prclDst->top;    //< x2 + (y2 - y1)
        rectDst.top = prclDst->top;                                        //< y1
        rectDst.bottom = prclDst->top + prclDst->right - 1 - prclDst->left;        //< y1 + (x2 - x1)
    }
    else     if(m_iRotate == ROT_270)        //<In this time, Height and Width are swapped.
    {
        rectDst.left = prclDst->left;                            //< x1
        rectDst.right = prclDst->left + prclDst->bottom - 1- prclDst->top;        //< x1 + (y2 - y1)
        rectDst.top = prclDst->bottom - 1;                                    //< y2
        rectDst.bottom = prclDst->bottom - 1 + prclDst->right - 1- prclDst->left;    //< y2 + (x2 - x1)
    }
    else        //< ROT_0
    {
        rectDst.left = prclDst->left;
        rectDst.top = prclDst->top;
        rectDst.right = prclDst->right - 1;
        rectDst.bottom = prclDst->bottom - 1;
    }

    SetRotationOrg((WORD)rectDst.left, (WORD)rectDst.top);
    SetCoordinateDstBlock(rectDst.left, rectDst.top, rectDst.right, rectDst.bottom);

    RETAILMSG(DISP_ZONE_2D,(TEXT("ROT:%d, Src:(%d,%d)~(%d,%d), Dst:(%d,%d)~(%d,%d)\r\n"), 
        m_iRotate, prclSrc->left, prclSrc->top, prclSrc->right, prclSrc->bottom, 
        rectDst.left, rectDst.top, rectDst.right, rectDst.bottom));
        
    uCmdRegVal = G2D_NORMAL_BITBLT_BIT;
    
    DoCmd(&(m_pG2DReg->CMDR1), uCmdRegVal, G2D_INTERRUPT);

    RETAILMSG(DISP_ZONE_ENTER,(TEXT("[2DHW] BitBlt Exit\r\n")));            
    /// TODO: Resource Register clearing can be needed.

}

/**
*    @fn    FIMGSE2D::GetCompensatedOffset(PRECTL prclSrc, PRECTL prclDst, ROT_TYPE m_iRotate)
*    @param    prclSrc    Source Rectangle
*    @param    prclDst    Destination Rectangle
*    @param    m_iRotate    Rotatation Degree. See also ROT_TYPE type
*    @note This funciton performs getting offset for stretchblt algorithm compensation
*    @sa    ROT_TYPE
*
**/
LONG FIMGSE2D::GetCompensatedOffset(DWORD usSrcValue, DWORD usDstValue)

{
    /// Calculate X,Y Offset
    float fIncrement;
    float fStretchRatio;
    float fReferPoint = 0.5;
    LONG i =0;
    
    fIncrement = (float)usSrcValue / (float)usDstValue;
    fStretchRatio = (float)usDstValue / (float)usSrcValue;
    
    do
    {
        if(fReferPoint > 1) break;    
        fReferPoint += fIncrement;
        i++;
    } while(1);

    RETAILMSG(DISP_ZONE_2D,(TEXT("\n fIncr : %5.6f, fSR: %5.6f, i : %d, Offset : %d"), fIncrement, fStretchRatio, i, (LONG)(fStretchRatio - i)));
    
    return (fStretchRatio < 1) ? 0 : (LONG)(fStretchRatio - i);
}

/**
*    @fn    FIMGSE2D::StretchBlt_Bilinear(PRECTL prclSrc, PRECTL prclDst, ROT_TYPE m_iRotate)
*    @param    prclSrc    Source Rectangle
*    @param    prclDst    Destination Rectangle
*    @param    m_iRotate    Rotatation Degree. See also ROT_TYPE type
*    @note This funciton performs real Stretched Bit blit using 2D HW. this functio can handle rotation case.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?