//#ifdef MSTAR_DEBUG_DRIVER
#define DIRECT_ENABLE_DEBUG
//#endif

#include <stdio.h>

#undef HAVE_STDLIB_H

#include <config.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <assert.h>

#include <sys/mman.h>
#include <fcntl.h>

#include <asm/types.h>

#include <directfb.h>
#include <directfb_util.h>

#include <direct/debug.h>
#include <direct/messages.h>
#include <direct/system.h>

#include <misc/conf.h>

#include <core/core.h>
#include <core/gfxcard.h>
#include <core/layers.h>
#include <core/screens.h>
#include <core/system.h>

#include <core/graphics_driver.h>

#include <direct/mem.h>
#include <direct/memcpy.h>

#include <core/coredefs.h>
#include <core/coretypes.h>

#include <core/state.h>
#include <core/gfxcard.h>
#include <core/surface.h>
#include <core/surface_buffer.h>

#include  <core/palette.h>
#include <gfx/convert.h>

#include <MsCommon.h>
#include <drvSEM.h>
#include  <apiGFX.h>
#include  <apiGOP.h>
#include  <drvMMIO.h>

#include <drvXC_IOPort.h>
#include <drvTVEncoder.h>
#include <drvMVOP.h>
#include <drvTVEncoder.h>
#include <apiXC.h>
#include <apiPNL.h>
#if DFB_BUILD_FOR_PRJ_OBAMA
#include "madp.h"
#include "dfb_mmap_ref.h"
#endif
#include "mstar_layer.h"
#include "mstar_screen.h"
#include <core/layers_internal.h>
#include <dlfcn.h>
#include <assert.h>

#define MSTAR_DFB_BLT_MIRROR_PATCH 1
#define MSTAR_HARDWARE_LIMITATION_WIDTH 4096
#define MSTAR_HARDWARE_LIMITATION_HEIGHT 4096
#define LINE_WIDTH 1

#if MSTAR_DFB_BLT_MIRROR_PATCH
#define SET_BLT_MIRROR_SRCX(sdrv, rectinfo)    \
    if (sdrv->ge_blit_xmirror) \
    { \
        rectinfo.srcblk.x += rectinfo.srcblk.width - 1; \
    }

#define SET_BLT_MIRROR_SRCY(sdrv,rectinfo)   \       
    if (dfb_config->do_GE_Vmirror == true) \     
    { \       
        if (!sdrv->ge_blit_ymirror) \        
        { \                   
            rectinfo.srcblk.y += rectinfo.srcblk.height - 1; \        
        } \    
    } \    
    else \    
    { \        
        if (sdrv->ge_blit_ymirror) \        
        { \            
            rectinfo.srcblk.y += rectinfo.srcblk.height - 1; \        
        }  \    
    }  
#else
#define SET_BLT_MIRROR_X(sdrv, rectinfo) do{}while(0)
#define SET_BLT_MIRROR_Y(sdrv, rectinfo) do{}while(0)
#endif

DFB_GRAPHICS_DRIVER( mstar_g2 )

void Global_Init ()
{
    typedef void  (*MDRV_SYS_GLOBALINIT) (void);
    MDRV_SYS_GLOBALINIT MDrv_SYS_GlobalInit;

    void *handle = NULL;
    const char* err;
    handle = dlopen ("liblinux.so", RTLD_LAZY);
    if (!handle)
    {
        return;
    }
    MDrv_SYS_GlobalInit = (MDRV_SYS_GLOBALINIT) dlsym (handle, "MDrv_SYS_GlobalInit");
    if (err = dlerror())
    {
        return;
    }
    MDrv_SYS_GlobalInit();
    
    dlclose(handle);
}

D_DEBUG_DOMAIN( MSTAR_G2_Driver, "MSTAR_G2/Driver", "MSTAR G2 Driver" );
void AddGraphicsDriverModule()
{
}
typedef enum
{
   MSTAR_FILL_RECT = 0x00000001,
   MSTAR_DRAW_RECT = 0x00000002,
   MSTAR_DRAW_LINE = 0x00000004,
   MSTAR_TRAPEZOID_FILL = 0x00000008,
   MSTAR_DRAW_OVAL = 0x00000010,
   MSTAR_BIT_BLIT = 0x00010000,
   MSTAR_STRETCH = 0x00020000,
   MSTAR_TRAPEZOID_BLIT = 0x00040000,
   MSTAR_OPT_MAX = 0xffffffff
}MSTAR_OP_TYPE;

#define DEFAULT_MAX_GFX_WIDTH   1366
#define DEFAULT_MAX_GFX_HEIGHT  768

#define IS_MSTAR_BLIT_OP(op)  ((op) & 0xffff0000)

#define MSTAR_GFX_RENDER_OP_NONE          0x0
#define MSTAR_GFX_RENDER_OP_DRAW          0x1
#define MSTAR_GFX_RENDER_OP_BLIT          0x2

#define OSD2VE_SUPPORT		//RC@20100212, Support the OP direct output to VE display

static inline GFX_Buffer_Format adjustcolorformat(MSTARDriverData * sdrv)
{
   if(!sdrv)
       return -1;

   if((sdrv->src_ge_format ==GFX_FMT_I8 || sdrv->src_ge_format == GFX_FMT_I4 || sdrv->src_ge_format == GFX_FMT_I2 || sdrv->src_ge_format == GFX_FMT_I1 ) && sdrv->dst_ge_format != GFX_FMT_I8)
       return GFX_FMT_ARGB8888;
   else
       return (GFX_Buffer_Format)sdrv->src_ge_format;

}


unsigned long
    mstar_pixel_to_color( DFBSurfacePixelFormat  format,
                      unsigned long pixel, CorePalette *palette);
unsigned long
    mstar_pixel_to_colorkey( DFBSurfacePixelFormat  format,
                      unsigned long pixel, CorePalette *palette);

static void dumpFormat( unsigned int format ){
    switch(format){
    case DSPF_UNKNOWN:
        printf( "DSPF_UNKNOWN\n" ) ;
        break ;
    case DSPF_ARGB1555:
        printf( "DSPF_ARGB1555\n" ) ;
        break;
    case DSPF_RGB16:
        printf( "DSPF_RGB16\n" ) ;
        break ;
    case DSPF_RGB24:
        printf( "DSPF_RGB24\n" ) ;
        break ;
    case DSPF_RGB32:
        printf( "DSPF_RGB32\n" ) ;
        break ;
    case DSPF_ARGB:
        printf( "DSPF_ARGB\n" ) ;
        break ;
    case DSPF_ABGR:
        printf( "DSPF_ABGR\n" ) ;
        break ;
    case DSPF_A8:
        printf( "DSPF_A8\n" ) ;
        break ;
    case DSPF_YUY2:
        printf( "DSPF_YUY2\n" ) ;
        break ;
    case DSPF_YVYU:
        printf( "DSPF_YVYU\n" ) ;
        break ;
    case DSPF_RGB332:
        printf( "DSPF_RGB332\n" ) ;
        break ;
    case DSPF_UYVY:
        printf( "DSPF_UYVY\n" ) ;
        break ;
    case DSPF_I420:
        printf( "DSPF_I420\n" ) ;
        break ;
    case DSPF_YV12:
        printf( "DSPF_YV12\n" ) ;
        break ;
    case DSPF_LUT8:
        printf( "DSPF_LUT8\n" ) ;
        break ;
    case DSPF_ALUT44:
        printf( "DSPF_ALUT44\n" ) ;
        break ;
     /* 32 bit  ARGB (4 byte, inv. alpha 8@24, red 8@16, green 8@8, blue 8@0) */
    case DSPF_AiRGB:
        printf( "DSPF_AiRGB\n" ) ;
        break ;
     /*  1 bit alpha (1 byte/ 8 pixel, most significant bit used first) */
    case DSPF_A1:
        printf( "DSPF_A1\n" ) ;
        break ;
     /* 12 bit   YUV (8 bit Y plane followed by one 16 bit quarter size Cb|Cr [7:0|7:0] plane) */
    case DSPF_NV12:
        printf( "DSPF_NV12\n" ) ;
        break ;
     /* 16 bit   YUV (8 bit Y plane followed by one 16 bit half width Cb|Cr [7:0|7:0] plane) */
    case DSPF_NV16:
        printf( "DSPF_NV16\n" ) ;
        break ;
     /* 16 bit  ARGB (2 byte, alpha 2@14, red 5@9, green 5@4, blue 4@0) */
    case DSPF_ARGB2554:
        printf( "DSPF_ARGB2554\n" ) ;
        break ;
     /* 16 bit  ARGB (2 byte, alpha 4@12, red 4@8, green 4@4, blue 4@0) */
    case DSPF_ARGB4444:
        printf( "DSPF_ARGB4444\n" ) ;
        break ;
     /* 12 bit   YUV (8 bit Y plane followed by one 16 bit quarter size Cr|Cb [7:0|7:0] plane) */
    case DSPF_NV21:
        printf( "DSPF_NV21\n" ) ;
        break ;
     /* 32 bit  AYUV (4 byte, alpha 8@24, Y 8@16, Cb 8@8, Cr 8@0) */
    case DSPF_AYUV:
        printf( "DSPF_AYUV\n" ) ;
        break ;
     /*  4 bit alpha (1 byte/ 2 pixel, more significant nibble used first) */
    case DSPF_A4:
        printf( "DSPF_A4\n" ) ;
        break ;
     /*  1 bit alpha (3 byte/  alpha 1@18, red 6@16, green 6@6, blue 6@0) */
    case DSPF_ARGB1666:
        printf( "DSPF_ARGB1666\n" ) ;
        break ;
     /*  6 bit alpha (3 byte/  alpha 6@18, red 6@16, green 6@6, blue 6@0) */
    case DSPF_ARGB6666:
        printf( "DSPF_ARGB6666\n" ) ;
        break ;
     /*  6 bit   RGB (3 byte/   red 6@16, green 6@6, blue 6@0) */
    case DSPF_RGB18:
        printf( "DSPF_RGB18\n" ) ;
        break ;
     /*  2 bit   LUT (1 byte/ 4 pixel, 2 bit color and alpha lookup from palette) */
    case DSPF_LUT2:
        printf( "DSPF_LUT2\n" ) ;
        break ;
     /*  1 bit   LUT (1 byte/ 8 pixel, 1 bit color and alpha lookup from palette) */
    case DSPF_LUT1:
        printf( "DSPF_LUT1\n" ) ;
        break ;
     /*  4 bit   LUT (1 byte/ 2 pixel, 4 bit color and alpha lookup from palette) */
    case DSPF_LUT4:
        printf( "DSPF_LUT4\n" ) ;
        break ;
     /* 16 bit   RGB (2 byte, nothing @12, red 4@8, green 4@4, blue 4@0) */
    case DSPF_RGB444:
        printf( "DSPF_RGB444\n" ) ;
        break ;
     /* 16 bit   RGB (2 byte, nothing @15, red 5@10, green 5@5, blue 5@0) */
    case DSPF_RGB555:
        printf( "DSPF_RGB555\n" ) ;
        break ;
     /* 16 bit   BGR (2 byte, nothing @15, blue 5@10, green 5@5, red 5@0) */
    case DSPF_BGR555:
        printf( "DSPF_BGR555\n" ) ;
        break ;
    }
}


 u32 mstarGFXAddr(u32 cpuPhysicalAddr, u32 mst_miu1_cpu_offset, u32 mst_miu1_hal_offset)
{
   if(cpuPhysicalAddr >= mst_miu1_cpu_offset)
      return (cpuPhysicalAddr-mst_miu1_cpu_offset+mst_miu1_hal_offset);
    else
        return (cpuPhysicalAddr-dfb_config->mst_miu0_cpu_offset+dfb_config->mst_miu0_hal_offset);

   return cpuPhysicalAddr;
}

/*
    return true if blending enabled; return false if blending disabled;
*/
static inline bool mstarMapGFXBlitOption(DFBSurfaceBlittingFlags  blittingflags,
                                        DFBSurfaceBlendFunction  src_blend,
                                        DFBSurfaceBlendFunction  dst_blend,
                                        GFX_DFBBldOP *pgfx_src_bld_op,
                                        GFX_DFBBldOP *pgfx_dst_bld_op,
                                        u16 *pu16_bld_flags)
{
    if(DSBLIT_NOFX == blittingflags)
        return false;

    //Set Blend Flag:
    *pu16_bld_flags = 0x0;
    if(blittingflags & DSBLIT_BLEND_ALPHACHANNEL)
        *pu16_bld_flags |= GFX_DFB_BLD_FLAG_ALPHACHANNEL;
    if(blittingflags & DSBLIT_BLEND_COLORALPHA)
        *pu16_bld_flags |= GFX_DFB_BLD_FLAG_COLORALPHA;
    if(blittingflags & DSBLIT_COLORIZE)
        *pu16_bld_flags |= GFX_DFB_BLD_FLAG_COLORIZE;
    if(blittingflags & DSBLIT_SRC_PREMULTIPLY)
        *pu16_bld_flags |= GFX_DFB_BLD_FLAG_SRCPREMUL;
    if(blittingflags & DSBLIT_DST_PREMULTIPLY)
        *pu16_bld_flags |= GFX_DFB_BLD_FLAG_DSTPREMUL;
    if(blittingflags & DSBLIT_DEMULTIPLY)
        *pu16_bld_flags |= GFX_DFB_BLD_FLAG_DEMULTIPLY;
    if(blittingflags & DSBLIT_SRC_PREMULTCOLOR)
        *pu16_bld_flags |= GFX_DFB_BLD_FLAG_SRCPREMULCOL;
    if(blittingflags & DSBLIT_XOR)
        *pu16_bld_flags |= GFX_DFB_BLD_FLAG_XOR;
    if(blittingflags & DSBLIT_SRC_MASK_ALPHA)
        *pu16_bld_flags |= GFX_DFB_BLD_FLAG_SRCALPHAMASK;
    if(blittingflags & DSBLIT_SRC_MASK_COLOR)
        *pu16_bld_flags |= GFX_DFB_BLD_FLAG_SRCCOLORMASK;

    //No blending!
    if(0x0 == *pu16_bld_flags)
        return false;

    if(DSBF_UNKNOWN == src_blend)
        *pgfx_src_bld_op = GFX_DFB_BLD_OP_ONE;
    else
        *pgfx_src_bld_op = (GFX_DFBBldOP)(src_blend-1);

    if(DSBF_UNKNOWN == dst_blend)
        *pgfx_dst_bld_op = GFX_DFB_BLD_OP_ONE;
    else
        *pgfx_dst_bld_op = (GFX_DFBBldOP)(dst_blend-1);

    if(!(blittingflags &(DSBLIT_BLEND_ALPHACHANNEL|DSBLIT_BLEND_COLORALPHA)))
    {
        //patch HW, current GE only do blend operations with alpha blend on
        *pgfx_src_bld_op = GFX_DFB_BLD_OP_ONE;
        *pgfx_dst_bld_op = GFX_DFB_BLD_OP_ZERO;
    }

    return true;
}

/*
   return true for hw support this blit options
*/
static inline bool mstarCheckBlitOption(DFBSurfaceBlittingFlags  blittingflags, DFBSurfaceBlittingFlags  supported_blittingflags)
{
    if(blittingflags & ~(supported_blittingflags))
        return false;

    return true;
}

static void _mstarCheckStateInternal(CardState *state, DFBAccelerationMask accel,  DFBAccelerationMask *pAccelRdy, DFBSurfaceBlittingFlags supported_blittingflags)
{
    bool bcheck_destination_rgb_format = false;
    
    if(state->render_options & DSRO_MATRIX)
    {
        if(state->matrix[0] !=(1<<16) || state->matrix[1] !=0 || state->matrix[2] !=0 ||
            state->matrix[3] !=0 ||state->matrix[4] !=(1<<16)  || state->matrix[5] !=0 || state->matrix[6] !=0||
            state->matrix[7] !=0|| state->matrix[8] !=(1<<16) )
            {
              printf(" matrix not supported yet!!\n");
            }
    }

   if(state->destination->config.size.w >= MSTAR_HARDWARE_LIMITATION_WIDTH ||state->destination->config.size.h >= MSTAR_HARDWARE_LIMITATION_HEIGHT)
   {
           printf("Against the GE hardware limitation! HW (GE) not support return to SW render ! width: %d(limit:%d), height:%d(limit:%d)\n", state->destination->config.size.w, MSTAR_HARDWARE_LIMITATION_WIDTH -1, state->destination->config.size.h, MSTAR_HARDWARE_LIMITATION_HEIGHT -1);
           return;
    }


	//here check whether the dstbuffer foramt is supported by the  GE

    switch( state->destination->config.format ){
    case DSPF_ARGB4444:
    case DSPF_ARGB1555:
    case DSPF_ARGB:
    case DSPF_ABGR:
    case DSPF_RGB16:    
            if(dfb_config->do_yuvtorgb_sw_patch)
            {
                 bcheck_destination_rgb_format = true;
            }
    case DSPF_YVYU:
    case DSPF_YUY2:
    case DSPF_UYVY:
    case DSPF_LUT8:
		break;
 	case DSPF_A8:
 		if(DFB_BLITTING_FUNCTION(accel)&&(state->source->config.format == DSPF_A8))
 			break;
        else
            return;
    default:
        //printf( "error format %s:%d, 0x%08X\n",__FILE__,__LINE__,state->dst.buffer->format ) ;
        //dumpFormat(state->dst.buffer->format) ;
        return;
    }

    if(DFB_BLITTING_FUNCTION(accel))
    {
         if(state->source->config.size.w  >=  MSTAR_HARDWARE_LIMITATION_WIDTH  ||state->source->config.size.h  >=  MSTAR_HARDWARE_LIMITATION_HEIGHT)
        {
              printf("Against the hardware limitation! HW (GE) not support return to SW render ! width: %d(limit:%d), height:%d(limit:%d)\n", state->source->config.size.w, MSTAR_HARDWARE_LIMITATION_WIDTH -1, state->source->config.size.h, MSTAR_HARDWARE_LIMITATION_HEIGHT -1);
              return;
        }
         
        if(mstarCheckBlitOption(state->blittingflags, supported_blittingflags))
        {
            switch(state->source->config.format){
            case DSPF_LUT8:
            case DSPF_LUT4:
            case DSPF_LUT2:
            case DSPF_LUT1:
                if (dfb_config->do_i8toargb4444_sw_patch)
                {
                    D_INFO("HW BUG to patch it with SW (i8 to other pixelfomat)\n");
                    return;
                }
            case DSPF_YUY2:
            case DSPF_YVYU:
            case DSPF_UYVY:
                if (bcheck_destination_rgb_format && dfb_config->do_yuvtorgb_sw_patch)
                {
                    D_INFO("HW BUG to patch it with SW\n");
                    return;
                }
            case DSPF_ARGB1555:
            case DSPF_ARGB:
            case DSPF_ABGR:
            case DSPF_ARGB4444:
            case DSPF_RGB16:
 //        	case DSPF_A8:
                *pAccelRdy |= accel&(DFXL_BLIT|DFXL_STRETCHBLIT|DFXL_TRAPEZOID_BLIT);
                break ;
            default:
                break;
                }

            //do not support stretchblit with rotation NOW
            if((accel & DFXL_STRETCHBLIT) && (state->blittingflags & (DSBLIT_ROTATE90|DSBLIT_ROTATE180|DSBLIT_ROTATE270)))
            {
                //printf("do not support stretchblit with rotation NOW \n");
                *pAccelRdy ^= DFXL_STRETCHBLIT;
            }

        }
        else
        {
            //printf("reject alpha blend %08x, %08x, %08x\n", state->blittingflags, state->src_blend, state->dst_blend);
        }
    }

    if(DFB_DRAWING_FUNCTION(accel))
    {
        *pAccelRdy |= accel&(DFXL_FILLRECTANGLE|DFXL_DRAWLINE|DFXL_DRAWRECTANGLE|DFXL_FILLTRAPEZOID|DFXL_DRAWOVAL) ;
    }
}

void mstarCheckState( void                *drv,
                  void                *dev,
                  CardState           *state,
                  DFBAccelerationMask  accel )
{
     MSTARDriverData *sdrv = drv;

     return _mstarCheckStateInternal(state, accel, &state->accel, sdrv->gfx_supported_bld_flags);
}

void mstarCheckState_null( void                *drv,
                  void                *dev,
                  CardState           *state,
                  DFBAccelerationMask  accel )
{}

static void mstarSetEngineBlitState(StateModificationFlags   modified, MSTARDriverData *sdrv, MSTARDeviceData *sdev)
{
    //Set ColorKey:
    if(modified & (SMF_BLITTING_FLAGS | SMF_SRC_COLORKEY ))
        MApi_GFX_SetSrcColorKey(sdrv->ge_src_colorkey_enabled, CK_OP_EQUAL, adjustcolorformat(sdrv), &sdrv->src_ge_clr_key, &sdrv->src_ge_clr_key);

    if(modified & (SMF_BLITTING_FLAGS | SMF_DST_COLORKEY ))
        MApi_GFX_SetDstColorKey(sdrv->ge_blit_dst_colorkey_enabled,
             CK_OP_NOT_EQUAL, (GFX_Buffer_Format)sdrv->dst_ge_format, &sdrv->dst_ge_clr_key, &sdrv->dst_ge_clr_key);

    //Set Alpha Blend:
    if(modified & (SMF_BLITTING_FLAGS | SMF_SRC_BLEND | SMF_DST_BLEND | SMF_COLOR))
    {
        if(sdrv->ge_blit_alpha_blend_enabled)
        {
            GFX_RgbColor rgbColor;

            MApi_GFX_SetDFBBldFlags((MS_U16)sdrv->ge_blit_bld_flags);
            MApi_GFX_SetDFBBldOP(sdrv->ge_src_blend, sdrv->ge_dst_blend);
            rgbColor.a = sdrv->color.a;
            rgbColor.r = sdrv->color.r;
            rgbColor.g = sdrv->color.g;
            rgbColor.b = sdrv->color.b;
            MApi_GFX_SetDFBBldConstColor(rgbColor);
            MApi_GFX_EnableDFBBlending(TRUE);
            MApi_GFX_EnableAlphaBlending(TRUE);
        }
        else
        {
            MApi_GFX_EnableDFBBlending(FALSE);
            MApi_GFX_EnableAlphaBlending(FALSE);
            MApi_GFX_SetAlphaSrcFrom(ABL_FROM_ASRC);
        }
    }
    ////////////////////////////////////////////////////////////
    //Set Src Buffer, Blt ops Needed:
   if(modified & SMF_SOURCE)
   {
            GFX_BufferInfo buf;
            buf.u32Addr = (MS_U32)sdrv->src_phys;
            buf.u32ColorFmt = sdrv->src_ge_format;
            buf.u32Width = sdrv->src_w;
            buf.u32Height = sdrv->src_h;
            buf.u32Pitch = sdrv->src_pitch;

            MApi_GFX_SetSrcBufferInfo(&buf, 0);
     }

    //Set BLIT rotation
    if(modified & SMF_BLITTING_FLAGS)
    {
            if(sdrv->bflags & DSBLIT_ROTATE90)
                //MApi_GFX_SetRotate(GEROTATE_90);      //make DFB's rotation convent with GE's
                MApi_GFX_SetRotate(GEROTATE_270);
            else if(sdrv->bflags & DSBLIT_ROTATE180)
                MApi_GFX_SetRotate(GEROTATE_180);
            else if(sdrv->bflags & DSBLIT_ROTATE270)
                //MApi_GFX_SetRotate(GEROTATE_270);     //make DFB's rotation convent with GE's
                MApi_GFX_SetRotate(GEROTATE_90);
            else
                MApi_GFX_SetRotate(GEROTATE_0);
     }

        //Set Blit Nearest Mode:
     if(modified & SMF_BLIT_NEARESTMODE)
            MApi_GFX_SetNearestMode((MS_BOOL)sdrv->ge_blit_nearestmode_enabled);
     
     if (dfb_config->do_GE_Vmirror == true) //GOP mirror do GE mirror for mantis id:0523773     
     {         
            if(modified & (SMF_BLIT_XMIRROR | SMF_BLIT_YMIRROR))         
            {            
                MApi_GFX_SetMirror((MS_BOOL) sdrv->ge_blit_xmirror, (MS_BOOL) !sdrv->ge_blit_ymirror);         
            }
            MApi_GFX_SetDstMirror((MS_BOOL)false, (MS_BOOL)TRUE);     
     }     
     else     
     {         
            if(modified & (SMF_BLIT_XMIRROR | SMF_BLIT_YMIRROR))             
                MApi_GFX_SetMirror((MS_BOOL)sdrv->ge_blit_xmirror, (MS_BOOL)sdrv->ge_blit_ymirror);     

            MApi_GFX_SetDstMirror((MS_BOOL)false, (MS_BOOL)false);     
     }
        //Set Blit Mirror:
}

static void mstarSetEngineDrawState(StateModificationFlags   modified, MSTARDriverData *sdrv, MSTARDeviceData *sdev)
{
    if(modified & (SMF_DRAWING_FLAGS | SMF_SRC_COLORKEY ))
        MApi_GFX_SetSrcColorKey(FALSE, CK_OP_EQUAL, adjustcolorformat(sdrv), &sdrv->src_ge_clr_key, &sdrv->src_ge_clr_key);

    if(modified & (SMF_DRAWING_FLAGS | SMF_DST_COLORKEY ))
        MApi_GFX_SetDstColorKey(sdrv->ge_draw_dst_colorkey_enabled,
             CK_OP_NOT_EQUAL, (GFX_Buffer_Format)sdrv->dst_ge_format, &sdrv->dst_ge_clr_key, &sdrv->dst_ge_clr_key);

    if(modified & (SMF_DRAWING_FLAGS | SMF_SRC_BLEND | SMF_DST_BLEND | SMF_COLOR))
    {
        if(sdrv->ge_draw_alpha_blend_enabled)
        {
            GFX_RgbColor rgbColor;

            MApi_GFX_SetDFBBldFlags((MS_U16)sdrv->ge_draw_bld_flags);
            MApi_GFX_SetDFBBldOP(sdrv->ge_src_blend, sdrv->ge_dst_blend);
            rgbColor.a = sdrv->color.a;
            rgbColor.r = sdrv->color.r;
            rgbColor.g = sdrv->color.g;
            rgbColor.b = sdrv->color.b;
            MApi_GFX_SetDFBBldConstColor(rgbColor);
            MApi_GFX_EnableDFBBlending(TRUE);
            MApi_GFX_EnableAlphaBlending(TRUE);
	     //if alpha_compare_mode can work when DFB HW blend ,this patch should be removed
           if(sdrv->ge_render_alpha_cmp_enabled)
	    {

			  MApi_GFX_EnableDFBBlending(FALSE);
			  //(GFX_BlendCoef)0x2: Csrc * Asrc + Cdst * (1 - Asrc)
			  MApi_GFX_SetAlphaBlending((GFX_BlendCoef)0x2, sdrv->color.a);
			  MApi_GFX_SetAlphaSrcFrom(ABL_FROM_ASRC);
	    }

        }
        else
        {
            MApi_GFX_EnableDFBBlending(FALSE);
            MApi_GFX_EnableAlphaBlending(FALSE);
            MApi_GFX_SetAlphaSrcFrom(ABL_FROM_ASRC);
        }
    }
}

static void mstarSetEngineShareState(StateModificationFlags   modified, DFBAccelerationMask support_accel, MSTARDriverData *sdrv, MSTARDeviceData *sdev)
{
    GFX_Point v0, v1;
    GFX_BufferInfo buf;

    ////////////////////////////////////////////////////////////
    //Set Dst Buffer State, All ops Needed:
    if(modified & SMF_DESTINATION)
    {
        buf.u32Addr = (MS_U32)sdrv->dst_phys;
        buf.u32ColorFmt = sdrv->dst_ge_format;
        buf.u32Width = sdrv->dst_w;
        buf.u32Height = sdrv->dst_h;
        buf.u32Pitch = sdrv->dst_pitch;
        MApi_GFX_SetDstBufferInfo(&buf, 0);

       if(!sdev->b_hwclip)
        {
            v0.x = 0;
            v0.y = 0;
            v1.x = buf.u32Width-1;
            v1.y = buf.u32Height-1;
            MApi_GFX_SetClip(&v0, &v1);
        }
    }
    if((modified & SMF_CLIP) && sdev->b_hwclip)
    {
            v0.x = sdrv->clip.x1;
            v0.y = sdrv->clip.y1;
            v1.x = sdrv->clip.x2;
            v1.y = sdrv->clip.y2;
            MApi_GFX_SetClip(&v0, &v1);
    }

    //Set Alpha Compare:
    if(modified & SMF_ALPHA_CMP)
        MApi_GFX_SetAlphaCmp((MS_BOOL)sdrv->ge_render_alpha_cmp_enabled, sdrv->ge_render_alpha_cmp );

    //SetYUV Format:
    if(modified & (SMF_DESTINATION | SMF_SOURCE)) //SetYUV Format:
        MApi_GFX_SetDC_CSC_FMT(GFX_YUV_RGB2YUV_255, GFX_YUV_OUT_255, GFX_YUV_IN_255, sdrv->src_ge_yuv_fmt,  sdrv->dst_ge_yuv_fmt);





    //Set Blit Palette:
    if(sdrv->ge_palette_enabled && sdev->num_entries)
        MApi_GFX_SetPaletteOpt(sdev->palette_tbl, 0, (sdev->num_entries-1));

    //Set Intensity Palette:
    if(sdrv->ge_palette_intensity_enabled)
    {
        int i;
        for(i=0; i<sdev->num_intensity; i++)
        {
            MApi_GFX_SetIntensity(i, GFX_FMT_ARGB8888, (MS_U32 *)&sdev->palette_intensity[i]);
        }
    }
}

void
mstarSetState( void                *drv,
                void                *dev,
                GraphicsDeviceFuncs *funcs,
                CardState           *state,
                DFBAccelerationMask  accel )
{
    int i ;
    MSTARDeviceData *sdev = dev ;
    MSTARDriverData *sdrv = drv;
    CoreSurface       *dsurface = state->destination ;
    DFBAccelerationMask      support_accel = state->accel & accel ;
    CorePalette *palette = NULL;
    CorePalette *palette_intensity = NULL;
    DFBSurfacePixelFormat  palette_intensity_format = DSPF_LUT4;
    u32 max_palette_intensity_cnt = MAX_PALETTE_INTENSITY_I4_CNT;
    StateModificationFlags   modified = state->mod_hw;

    state->set = DFXL_NONE;

    if(support_accel == DFXL_NONE)
    {
        printf("Serious warning, rejet mstarSetState\n");
        return;
    }

    if(DFB_BLITTING_FUNCTION(support_accel) && (sdrv->ge_last_render_op != MSTAR_GFX_RENDER_OP_BLIT))
    {
        modified |= (SMF_SOURCE | SMF_BLITTING_FLAGS | SMF_SRC_COLORKEY | SMF_DST_COLORKEY | SMF_SRC_BLEND | SMF_DST_BLEND|SMF_BLIT_XMIRROR|SMF_BLIT_YMIRROR|SMF_BLIT_NEARESTMODE);
    }else
    if(DFB_DRAWING_FUNCTION(support_accel) && (sdrv->ge_last_render_op != MSTAR_GFX_RENDER_OP_DRAW))
    {
        modified |= (SMF_DRAWING_FLAGS | SMF_SRC_COLORKEY | SMF_DST_COLORKEY | SMF_SRC_BLEND | SMF_DST_BLEND);
    }

    if( (modified & SMF_CLIP) && sdev->b_hwclip)
    {
       sdrv->clip = state->clip;
    }

    if(modified & SMF_DESTINATION)
    {
        switch( state->dst.buffer->format ){
        case DSPF_ARGB1555:
            sdrv->dst_ge_format = GFX_FMT_ARGB1555 ;
            break ;
        case DSPF_ARGB:
            sdrv->dst_ge_format = GFX_FMT_ARGB8888 ;
            break ;
        case DSPF_ABGR:
            sdrv->dst_ge_format = GFX_FMT_ABGR8888 ;
            break ;
        case DSPF_YVYU:
            sdrv->dst_ge_yuv_fmt = GFX_YUV_YVYU;
            sdrv->dst_ge_format = GFX_FMT_YUV422;
            break;
        case DSPF_YUY2:
            sdrv->dst_ge_yuv_fmt = GFX_YUV_YUYV;
            sdrv->dst_ge_format = GFX_FMT_YUV422;
            break ;

        case DSPF_UYVY:
            sdrv->dst_ge_yuv_fmt = GFX_YUV_UYVY;
            sdrv->dst_ge_format = GFX_FMT_YUV422;
            break ;

        case DSPF_LUT8:
            sdrv->dst_ge_format = GFX_FMT_I8 ;
            palette = dsurface->palette;
            //printf( "I8 not support yet %s:%d\n",__FILE__,__LINE__ ) ;
            break ;

        case DSPF_ARGB4444:
            sdrv->dst_ge_format = GFX_FMT_ARGB4444;
            break;
        case DSPF_RGB16:
            sdrv->dst_ge_format = GFX_FMT_RGB565;
            break;
        case DSPF_A8:
            sdrv->dst_ge_format = GFX_FMT_I8 ;
            break;
        default:
            //printf( "error format %s:%d, 0x%08X\n",__FILE__,__LINE__,state->dst.buffer->format ) ;
            dumpFormat(state->dst.buffer->format) ;
            return;
        }

        if(dfb_config->bUsingHWTLB)
        {
            sdrv->dst_phys = state->dst.phys;
        }
        else
        {
        	sdrv->dst_phys = mstarGFXAddr(state->dst.phys, sdev->mst_miu1_cpu_offset, sdev->mst_miu1_hal_offset);
        }
#ifdef DFB_ION
        if(state->dst.phys_type == CSBPT_TLB)
        {
            //call set GE src/dst TLB base addr APIĄŁ for monaco, GE can support src only, dst only  or both tlb
        }
#endif
        sdrv->dst_w = dsurface->config.size.w;
        sdrv->dst_h = dsurface->config.size.h;
        sdrv->dst_bpp    = DFB_BYTES_PER_PIXEL( state->dst.buffer->format );
        sdrv->dst_pitch  = state->dst.pitch;
    }

    if(modified & SMF_COLOR)
    {
        sdrv->color = state->color ;
        sdrv->color2 = state->color2;
        if(GFX_FMT_I8 == sdrv->dst_ge_format)
            sdrv->color.b = state->color_index ;
    }

    if(modified & SMF_BLIT_NEARESTMODE)
        sdrv->ge_blit_nearestmode_enabled = state->blit_nearestmode_enabled;
    if(modified & SMF_BLIT_XMIRROR)
        sdrv->ge_blit_xmirror = state->blit_xmirror_enabled;
    if(modified & SMF_BLIT_YMIRROR)
        sdrv->ge_blit_ymirror = state->blit_ymirror_enabled;

    if(modified & SMF_ALPHA_CMP)
    {
        switch(state->cmp_mode)
        {
         case DSBF_ACMP_OP_MAX:
         case DSBF_ACMP_OP_MIN:
              sdrv->ge_render_alpha_cmp = (u32)(state->cmp_mode-1);
              sdrv->ge_render_alpha_cmp_enabled = 1;
              break;
         default:
               sdrv->ge_render_alpha_cmp_enabled = 0;
              break;
        }
    }

    sdrv->ge_palette_enabled = 0;

    if( DFB_DRAWING_FUNCTION(support_accel) )
    {
        DFBSurfaceBlittingFlags  blittingflags = DSBLIT_NOFX;

        if(modified & SMF_DRAWING_FLAGS)
            sdrv->dflags = state->drawingflags;

        if(modified & (SMF_DRAWING_FLAGS | SMF_DST_COLORKEY))
        {
            sdrv->ge_draw_dst_colorkey_enabled = ((state->drawingflags& DSDRAW_DST_COLORKEY)?1:0);
            sdrv->dst_ge_clr_key = mstar_pixel_to_colorkey(state->dst.buffer->format, state->dst_colorkey, palette) ;
        }

        if(modified & (SMF_DRAWING_FLAGS | SMF_SRC_BLEND | SMF_DST_BLEND))
        {
            if(state->drawingflags & DSDRAW_BLEND)
                blittingflags |= DSBLIT_BLEND_ALPHACHANNEL;
            if(state->drawingflags & DSDRAW_SRC_PREMULTIPLY)
                blittingflags |= DSBLIT_SRC_PREMULTIPLY;
            if(state->drawingflags & DSDRAW_DST_PREMULTIPLY)
                blittingflags |= DSBLIT_DST_PREMULTIPLY;
            if(state->drawingflags & DSDRAW_DEMULTIPLY)
                blittingflags |= DSBLIT_DEMULTIPLY;
            if(state->drawingflags & DSDRAW_XOR)
                blittingflags |= DSBLIT_XOR;

            sdrv->ge_draw_alpha_blend_enabled = mstarMapGFXBlitOption(blittingflags, state->src_blend, state->dst_blend, &sdrv->ge_src_blend, &sdrv->ge_dst_blend, &sdrv->ge_draw_bld_flags);
        }
    }

    if( DFB_BLITTING_FUNCTION(support_accel) )
    {
        CoreSurface *ssurface = state->source;

        if(modified & SMF_BLITTING_FLAGS)
            sdrv->bflags = state->blittingflags;

        if(modified & (SMF_BLITTING_FLAGS | SMF_DST_COLORKEY))
        {
            sdrv->ge_blit_dst_colorkey_enabled = ((state->blittingflags& DSBLIT_DST_COLORKEY)?1:0);
            sdrv->dst_ge_clr_key = mstar_pixel_to_colorkey(state->dst.buffer->format, state->dst_colorkey, palette) ;
        }

        if(modified & (SMF_BLITTING_FLAGS | SMF_SRC_BLEND | SMF_DST_BLEND))
        {
            sdrv->ge_blit_alpha_blend_enabled = mstarMapGFXBlitOption(state->blittingflags, state->src_blend, state->dst_blend, &sdrv->ge_src_blend, &sdrv->ge_dst_blend, &sdrv->ge_blit_bld_flags);
        }

        if(modified & SMF_SOURCE)
        {
            sdrv->src_w = ssurface->config.size.w ;
            sdrv->src_h = ssurface->config.size.h ;

            if(dfb_config->bUsingHWTLB)
            {
                sdrv->src_phys = state->src.phys;	
            }
            else
            {
                sdrv->src_phys = mstarGFXAddr(state->src.phys, sdev->mst_miu1_cpu_offset, sdev->mst_miu1_hal_offset);
            }
#ifdef DFB_ION
            if(state->src.phys_type == CSBPT_TLB)
            {
                //call set GE src/dst TLB base addr APIĄŁ for monaco, GE can support src only, dst only  or both tlb
            }
#endif
            switch( state->src.buffer->format ){
            case DSPF_ARGB1555:
                sdrv->src_ge_format = GFX_FMT_ARGB1555 ;
                break ;
            case DSPF_ARGB:
                sdrv->src_ge_format = GFX_FMT_ARGB8888 ;
                break ;
            case DSPF_ABGR:
                sdrv->src_ge_format = GFX_FMT_ABGR8888 ;
                break ;
            case DSPF_YVYU:
                sdrv->src_ge_yuv_fmt = GFX_YUV_YVYU;
                sdrv->src_ge_format =  GFX_FMT_YUV422 ;
                break ;
            case DSPF_YUY2:
                sdrv->src_ge_yuv_fmt = GFX_YUV_YUYV;
                sdrv->src_ge_format =  GFX_FMT_YUV422 ;
                break ;
            case DSPF_UYVY:
                sdrv->src_ge_yuv_fmt = GFX_YUV_UYVY;
                sdrv->src_ge_format =  GFX_FMT_YUV422 ;
                break ;
            case DSPF_LUT8:
                sdrv->src_ge_format = GFX_FMT_I8 ;
                if( NULL == palette )
                {
                    palette = ssurface->palette;
                }
                break ;
            case DSPF_LUT4:
                palette_intensity_format = DSPF_LUT4;
                max_palette_intensity_cnt = MAX_PALETTE_INTENSITY_I4_CNT;
                sdrv->src_ge_format = GFX_FMT_I4 ;
                palette_intensity = ssurface->palette;
                break ;
            case DSPF_LUT2:
                palette_intensity_format = DSPF_LUT2;
                max_palette_intensity_cnt = MAX_PALETTE_INTENSITY_I2_CNT;
                sdrv->src_ge_format = GFX_FMT_I2 ;
                palette_intensity = ssurface->palette;
                break ;
            case DSPF_LUT1:
                palette_intensity_format = DSPF_LUT1;
                max_palette_intensity_cnt = MAX_PALETTE_INTENSITY_I1_CNT;
                sdrv->src_ge_format = GFX_FMT_I1 ;
                palette_intensity = ssurface->palette;
                break ;
            case DSPF_ARGB4444:
                sdrv->src_ge_format = GFX_FMT_ARGB4444 ;
                break ;
             case DSPF_RGB16:
                sdrv->src_ge_format = GFX_FMT_RGB565 ;
                break ;
    		case DSPF_A8:
                sdrv->src_ge_format = GFX_FMT_I8 ;
                break ;
            default:
                printf( "error format %s:%d, 0x%08X\n",__FILE__,__LINE__,state->src.buffer->format ) ;
                dumpFormat(state->src.buffer->format) ;
                return ;
            }

            sdrv->src_bpp    = DFB_BYTES_PER_PIXEL( state->src.buffer->format );
            sdrv->src_pitch  = state->src.pitch;
        }

        // For set the ge_palette_enabled when src_format=DSPF_A8, Roy modified
        //if(DSPF_A8 == state->src.buffer->format && (!sdev->a8_palette))
        if(DSPF_A8 == state->src.buffer->format)
        {
            if( NULL != dsurface->palette )
            {
                printf( "error format %s:%d, 0x%08X\n",__FILE__,__LINE__,state->src.buffer->format ) ;
                return ;
            }

            memset( sdev->palette_tbl, 0xFF, (sizeof(GFX_PaletteEntry)*MAX_PALETTE_ENTRY_CNT) );

            for(i=0; i < MAX_PALETTE_ENTRY_CNT; ++i)
            {
                sdev->palette_tbl[i].RGB.u8A = i;
            }

            sdev->num_entries = MAX_PALETTE_ENTRY_CNT;
            sdrv->ge_palette_enabled = 1;
            sdev->a8_palette = true ;
        }

        if(modified & (SMF_BLITTING_FLAGS | SMF_SRC_COLORKEY))
        {
            sdrv->ge_src_colorkey_enabled = ((state->blittingflags& DSBLIT_SRC_COLORKEY)?1:0);
            sdrv->src_ge_clr_key = mstar_pixel_to_colorkey(state->src.buffer->format, state->src_colorkey, ssurface->palette);
        }
    }

    if( palette )
    {
        int i ;
        int num_entries ;
        num_entries =( palette->num_entries > MAX_PALETTE_ENTRY_CNT ? MAX_PALETTE_ENTRY_CNT : palette->num_entries) ;

        for( i=0; i < num_entries; ++i )
        {
            sdev->palette_tbl[i].RGB.u8A = palette->entries[i].a ;
            sdev->palette_tbl[i].RGB.u8R = palette->entries[i].r ;
            sdev->palette_tbl[i].RGB.u8G = palette->entries[i].g ;
            sdev->palette_tbl[i].RGB.u8B = palette->entries[i].b ;
        }

        sdev->num_entries =  num_entries ;
        sdrv->ge_palette_enabled = 1 ;
        sdev->a8_palette = false ;
    }

    if( palette_intensity )
    {
        int i ;
        int num_entries ;
        num_entries =( palette_intensity->num_entries > max_palette_intensity_cnt ? max_palette_intensity_cnt : palette_intensity->num_entries) ;

        for( i=0; i < num_entries; ++i )
        {
            sdev->palette_intensity[i] = mstar_pixel_to_color(palette_intensity_format, i, palette_intensity) ;
        }

        sdev->num_intensity =  num_entries ;
        sdrv->ge_palette_intensity_enabled = 1 ;
    }

    state->mod_hw = 0;
    state->set = support_accel & ((DFXL_FILLRECTANGLE|DFXL_DRAWLINE|DFXL_DRAWRECTANGLE|DFXL_FILLTRAPEZOID|DFXL_DRAWOVAL)
                                  |(DFXL_BLIT|DFXL_STRETCHBLIT|DFXL_TRAPEZOID_BLIT));

    MApi_GFX_BeginDraw();
    mstarSetEngineShareState(modified, support_accel, sdrv, sdev);

    if(DFB_BLITTING_FUNCTION(support_accel))
    {
        mstarSetEngineBlitState(modified, sdrv, sdev);
        sdrv->ge_last_render_op = MSTAR_GFX_RENDER_OP_BLIT;
    }else
    if(DFB_DRAWING_FUNCTION(support_accel))
    {
        mstarSetEngineDrawState(modified, sdrv, sdev);
        sdrv->ge_last_render_op = MSTAR_GFX_RENDER_OP_DRAW;

    }

    MApi_GFX_EndDraw();

    sdrv->state = state;
}

void
mstarSetState_null( void                *drv,
                void                *dev,
                GraphicsDeviceFuncs *funcs,
                CardState           *state,
                DFBAccelerationMask  accel )
{}

bool mstarFillRectangle_null( void *drv, void *dev, DFBRectangle *rect )
{
    return true;
}

bool mstarFillRectangle_sw( void *drv, void *dev, DFBRectangle *rect )
{
    return false;
}

bool mstarFillRectangle( void *drv, void *dev, DFBRectangle *rect ){
    MSTARDeviceData *sdev = dev ;
    MSTARDriverData *sdrv = drv ;
    GFX_RectFillInfo rectInfo ;
    u32 y, cb, cr ;

    rectInfo.dstBlock.x = rect->x ;
    rectInfo.dstBlock.y = rect->y ;
    rectInfo.dstBlock.width = rect->w ;
    rectInfo.dstBlock.height = rect->h ;
    rectInfo.fmt = sdrv->dst_ge_format ;

    switch(rectInfo.fmt)
    {
        case GFX_FMT_YUV422:
            RGB_TO_YCBCR( sdrv->color.r, sdrv->color.g, sdrv->color.b, y, cb, cr ) ;
            rectInfo.colorRange.color_s.a = 0xFF ;
            rectInfo.colorRange.color_s.r = cr ;
            rectInfo.colorRange.color_s.g = y ;
            rectInfo.colorRange.color_s.b = cb ;
            break;
        default:
            rectInfo.colorRange.color_s.a = sdrv->color.a;
            rectInfo.colorRange.color_s.r = sdrv->color.r;
            rectInfo.colorRange.color_s.g = sdrv->color.g;
            rectInfo.colorRange.color_s.b = sdrv->color.b;
            break;
    }
   if(sdrv->dflags &(DSDRAW_COLOR_GRADIENT_X|DSDRAW_COLOR_GRADIENT_Y))
   {
      switch(rectInfo.fmt)
      {
            case GFX_FMT_YUV422:
                   RGB_TO_YCBCR( sdrv->color2.r, sdrv->color2.g, sdrv->color2.b, y, cb, cr ) ;
                   rectInfo.colorRange.color_e.a = 0xFF ;
                   rectInfo.colorRange.color_e.r = cr ;
                   rectInfo.colorRange.color_e.g = y ;
                   rectInfo.colorRange.color_e.b = cb ;
                   break;
            default:
                   rectInfo.colorRange.color_e.a = sdrv->color2.a;
                   rectInfo.colorRange.color_e.r = sdrv->color2.r;
                   rectInfo.colorRange.color_e.g = sdrv->color2.g;
                   rectInfo.colorRange.color_e.b = sdrv->color2.b;
                   break;
      }
      if(sdrv->dflags &DSDRAW_COLOR_GRADIENT_X)
            rectInfo.flag = GFXRECT_FLAG_COLOR_GRADIENT_X;
      else
            rectInfo.flag = 0;
     if(sdrv->dflags &DSDRAW_COLOR_GRADIENT_Y)
            rectInfo.flag |= GFXRECT_FLAG_COLOR_GRADIENT_Y;
   }
   else
           rectInfo.flag = 0;

    MApi_GFX_BeginDraw();
    MApi_GFX_RectFill( &rectInfo ) ;
    MApi_GFX_SetTAGID(MApi_GFX_GetNextTAGID(TRUE));
    MApi_GFX_EndDraw();

    return true ;
}

bool mstarDrawRectangle_null(
        void *driver_data,
        void *device_data,
        DFBRectangle *rect )
{
    return true;       
}

bool mstarDrawRectangle_sw(
        void *driver_data,
        void *device_data,
        DFBRectangle *rect )
{
    return false;
}

bool mstarDrawRectangle(
        void *driver_data,
        void *device_data,
        DFBRectangle *rect ){
    MSTARDeviceData *sdev = device_data ;
    MSTARDriverData *sdrv = driver_data ;

    GFX_DrawLineInfo l ;

    l.fmt = sdrv->dst_ge_format ;
    l.colorRange.color_s.a = sdrv->color.a ;
    l.colorRange.color_s.r = sdrv->color.r ;
    l.colorRange.color_s.g = sdrv->color.g ;
    l.colorRange.color_s.b = sdrv->color.b ;
    l.colorRange.color_e = l.colorRange.color_s ;
    l.width = LINE_WIDTH ;
    l.flag = GFXLINE_FLAG_COLOR_CONSTANT ;

    l.x1 = rect->x ;
    l.y1 = rect->y ;
    l.x2 = rect->x+rect->w-1 ;
    l.y2 = rect->y ;

    MApi_GFX_BeginDraw();
    MApi_GFX_DrawLine( &l ) ;

    l.x2 = rect->x ;
    l.y2 = rect->y+rect->h-1 ;
    MApi_GFX_DrawLine( &l ) ;

    l.y1 = rect->y+rect->h-1 ;
    l.x2 = rect->x+rect->w-1 ;
    MApi_GFX_DrawLine( &l ) ;

    l.x1 = rect->x+rect->w-1 ;
    l.y1 = rect->y ;
    
    l.x2 = rect->x+rect->w-1 ;
    l.y2 = rect->y+rect->h-1 + l.width +1;
    MApi_GFX_DrawLine( &l ) ;
    MApi_GFX_SetTAGID(MApi_GFX_GetNextTAGID(TRUE));

    MApi_GFX_EndDraw();

    return true ;
}

bool mstarDrawOval_null(
        void *driver_data,
        void *device_data,
        DFBOval *oval )
{
    return true;
}

bool mstarDrawOval_sw(
        void *driver_data,
        void *device_data,
        DFBOval *oval )
{
    return false;
}

bool mstarDrawOval(
        void *driver_data,
        void *device_data,
        DFBOval *oval ){
    MSTARDeviceData *sdev = device_data ;
    MSTARDriverData *sdrv = driver_data ;
    GFX_OvalFillInfo ovalInfo ;

    ovalInfo.dstBlock.x = oval->oval_rect.x ;
    ovalInfo.dstBlock.y = oval->oval_rect.y ;
    ovalInfo.dstBlock.width = oval->oval_rect.w ;
    ovalInfo.dstBlock.height = oval->oval_rect.h ;

    ovalInfo.fmt = sdrv->dst_ge_format ;
    ovalInfo.u32LineWidth = (u32)oval->line_width ;

    MApi_GFX_BeginDraw() ;

    if(oval->line_width > 0)
    {
        if(!DFB_COLOR_EQUAL(sdrv->color, oval->line_color))
        {
            ovalInfo.u32LineWidth = 0 ;
            ovalInfo.color.a = oval->line_color.a ;
            ovalInfo.color.r = oval->line_color.r ;
            ovalInfo.color.g = oval->line_color.g ;
            ovalInfo.color.b = oval->line_color.b ;
            MApi_GFX_DrawOval( &ovalInfo ) ;
            ovalInfo.u32LineWidth = (u32)oval->line_width ;
        }
        else
        {
            ovalInfo.u32LineWidth = 0 ;
        }
    }

    ovalInfo.color.a = sdrv->color.a ;
    ovalInfo.color.r = sdrv->color.r ;
    ovalInfo.color.g = sdrv->color.g ;
    ovalInfo.color.b = sdrv->color.b ;
    MApi_GFX_DrawOval( &ovalInfo ) ;

    MApi_GFX_SetTAGID(MApi_GFX_GetNextTAGID(TRUE)) ;
    MApi_GFX_EndDraw() ;

    return true ;
}

bool mstarDrawLine_null(
        void *driver_data,
        void *device_data,
        DFBRegion *line )
{
    return true;
}

bool mstarDrawLine_sw(
        void *driver_data,
        void *device_data,
        DFBRegion *line )
{
    return false;
}

bool mstarDrawLine(
        void *driver_data,
        void *device_data,
        DFBRegion *line ){
    MSTARDeviceData *sdev = device_data ;
    MSTARDriverData *sdrv = driver_data ;

    GFX_DrawLineInfo l ;
    u32 y, cb, cr ;

    l.x1 = line->x1 ;
    l.y1 = line->y1 ;
    l.x2 = line->x2 ;
    l.y2 = line->y2 ;
    l.fmt = sdrv->dst_ge_format ;
    l.colorRange.color_s.a = sdrv->color.a ;
    l.colorRange.color_s.r = sdrv->color.r ;
    l.colorRange.color_s.g = sdrv->color.g ;
    l.colorRange.color_s.b = sdrv->color.b ;
    l.colorRange.color_e = l.colorRange.color_s ;
    l.width = LINE_WIDTH ;
    l.flag = GFXLINE_FLAG_COLOR_CONSTANT ;


    switch(l.fmt)
    {
        case GFX_FMT_YUV422:
            RGB_TO_YCBCR( sdrv->color.r, sdrv->color.g, sdrv->color.b, y, cb, cr ) ;
            l.colorRange.color_s.a = 0xFF ;
            l.colorRange.color_s.r = cr ;
            l.colorRange.color_s.g = y ;
            l.colorRange.color_s.b = cb ;
            break;
        default:
            l.colorRange.color_s.a = sdrv->color.a ;
            l.colorRange.color_s.r = sdrv->color.r ;
            l.colorRange.color_s.g = sdrv->color.g ;
            l.colorRange.color_s.b = sdrv->color.b ;
            break;
    }
   if(sdrv->dflags &(DSDRAW_COLOR_GRADIENT_X|DSDRAW_COLOR_GRADIENT_Y))
   {
        switch(l.fmt)
        {
            case GFX_FMT_YUV422:
                   RGB_TO_YCBCR( sdrv->color2.r, sdrv->color2.g, sdrv->color2.b, y, cb, cr ) ;
                   l.colorRange.color_e.a = 0xFF ;
                   l.colorRange.color_e.r = cr ;
                   l.colorRange.color_e.g = y ;
                   l.colorRange.color_e.b = cb ;
                   break;
            default:
                   l.colorRange.color_e.a = sdrv->color2.a ;
                   l.colorRange.color_e.r = sdrv->color2.r ;
                   l.colorRange.color_e.g = sdrv->color2.g ;
                   l.colorRange.color_e.b = sdrv->color2.b ;
                   break;
       }
       l.flag = GFXLINE_FLAG_COLOR_GRADIENT ;
   }
   else
           l.flag = GFXLINE_FLAG_COLOR_CONSTANT ;


    MApi_GFX_BeginDraw();
    MApi_GFX_DrawLine( &l ) ;
    MApi_GFX_SetTAGID(MApi_GFX_GetNextTAGID(TRUE));
    MApi_GFX_EndDraw();

    return true ;
}

bool mstarBlit_null(
        void *driver_data,
        void *device_data,
        DFBRectangle *rect,
        int dx, int dy )
{
    return true;
}

bool mstarBlit_sw(
        void *driver_data,
        void *device_data,
        DFBRectangle *rect,
        int dx, int dy )
{
    return false;
}

bool mstarBlit(
        void *driver_data,
        void *device_data,
        DFBRectangle *rect,
        int dx, int dy )
{
    MSTARDeviceData *sdev = device_data ;
    MSTARDriverData *sdrv = driver_data ;

    GFX_DrawRect rectInfo;


    rectInfo.srcblk.x = rect->x;
    rectInfo.srcblk.y = rect->y;
    rectInfo.dstblk.x = dx;
    rectInfo.dstblk.y = dy;
    rectInfo.srcblk.width = rectInfo.dstblk.width = rect->w;
    rectInfo.srcblk.height = rectInfo.dstblk.height = rect->h;

    MApi_GFX_BeginDraw();
      
    SET_BLT_MIRROR_SRCX(sdrv, rectInfo);
    SET_BLT_MIRROR_SRCY(sdrv, rectInfo);
    if ( (dfb_config->mst_dither_enable) && (sdrv->src_ge_format==GFX_FMT_ARGB8888) && (sdrv->dst_ge_format==GFX_FMT_ARGB4444) )
    {
        MApi_GFX_SetDither(true);
    }
    MApi_GFX_BitBlt(&rectInfo, GFXDRAW_FLAG_DEFAULT);
    if ( (dfb_config->mst_dither_enable) && (sdrv->src_ge_format==GFX_FMT_ARGB8888) && (sdrv->dst_ge_format==GFX_FMT_ARGB4444) )
    {
        MApi_GFX_SetDither(false);
    }

    MApi_GFX_SetTAGID(MApi_GFX_GetNextTAGID(TRUE));
    MApi_GFX_EndDraw();

    return true ;
}

bool mstarStretchBlit_null(
        void *driver_data,
        void *device_data,
        DFBRectangle *srect,
        DFBRectangle *drect )
{
    return true;
}

bool mstarStretchBlit_sw(
        void *driver_data,
        void *device_data,
        DFBRectangle *srect,
        DFBRectangle *drect )
{
    return false;
}

bool mstarStretchBlit(
        void *driver_data,
        void *device_data,
        DFBRectangle *srect,
        DFBRectangle *drect ){
    MSTARDeviceData *sdev = device_data;
    MSTARDriverData *sdrv = driver_data;
    GFX_DrawRect rectInfo;
    GFX_Result ret;

    rectInfo.srcblk.x = srect->x, rectInfo.srcblk.y = srect->y;
    rectInfo.srcblk.width = srect->w, rectInfo.srcblk.height = srect->h;
    rectInfo.dstblk.x = drect->x, rectInfo.dstblk.y = drect->y ;
    rectInfo.dstblk.width = drect->w, rectInfo.dstblk.height = drect->h;


    if(sdrv->src_ge_format==GFX_FMT_YUV422)
    {
        rectInfo.srcblk.width =  rectInfo.srcblk.width&~1;
    }

    if(sdrv->dst_ge_format==GFX_FMT_YUV422)
    {
        rectInfo.dstblk.width =  (rectInfo.dstblk.width+1)&~1;
    }

    MApi_GFX_BeginDraw();
    SET_BLT_MIRROR_SRCX(sdrv, rectInfo);
    SET_BLT_MIRROR_SRCY(sdrv, rectInfo);
    if ( (dfb_config->mst_dither_enable) && (sdrv->src_ge_format==GFX_FMT_ARGB8888) && (sdrv->dst_ge_format==GFX_FMT_ARGB4444) )
    {
        MApi_GFX_SetDither(true);
    }
    ret = MApi_GFX_BitBlt(&rectInfo, GFXDRAW_FLAG_SCALE);
    if ( (dfb_config->mst_dither_enable) && (sdrv->src_ge_format==GFX_FMT_ARGB8888) && (sdrv->dst_ge_format==GFX_FMT_ARGB4444) )
    {
        MApi_GFX_SetDither(false);
    }

    //printf("\n%s:%d\n",__FUNCTION__,__LINE__);
    //printf(" src width %d, src height :%d,dst width %d,dst height %d   \n",
    //rectInfo.srcblk.width, rectInfo.srcblk.height,rectInfo.dstblk.width,rectInfo.dstblk.height);
    //printf("\nthe srectx:%d srecty:%d  drectx:%d drecty:%d\n",srect->x,srect->y,drect->x,drect->y);

    if(GFX_SUCCESS != ret)
    {
        //printf("\n%s:%d\n",__FUNCTION__,__LINE__);
        //printf("\nthe ret is %x \n",ret);
        //printf("\nthe dest x:%d dest y:%d  clip :x1:%d  clip:x2:%d  clip y1:%d   clip y2 :%d  \n",
        //    drect->x,drect->y,sdrv->clip.x1,sdrv->clip.x2,sdrv->clip.y1,sdrv->clip.y2);
        D_INFO("GE downscaling blit ratio can not be supported by HW(32:1)!, src height %d, dst height%d , src width :%d dst width %d\n",
        rectInfo.srcblk.height, rectInfo.dstblk.height,rectInfo.srcblk.width,rectInfo.dstblk.width);
    }else
        MApi_GFX_SetTAGID(MApi_GFX_GetNextTAGID(TRUE));
    MApi_GFX_EndDraw();

    return (GFX_SUCCESS==ret) ;
}

bool mstarStretchBlitEx_null(
        void *driver_data,
        void *device_data,
        DFBRectangle *srect,
        DFBRectangle *drect,
        const DFBGFX_ScaleInfo *scale_info)
{
    return true;
}

bool mstarStretchBlitEx_sw(
        void *driver_data,
        void *device_data,
        DFBRectangle *srect,
        DFBRectangle *drect,
        const DFBGFX_ScaleInfo *scale_info)
{
    return false;
}

bool mstarStretchBlitEx(
        void *driver_data,
        void *device_data,
        DFBRectangle *srect,
        DFBRectangle *drect,
        const DFBGFX_ScaleInfo *scale_info)
{
    MSTARDriverData *sdrv = driver_data;
    GFX_DrawRect rectInfo;
    GFX_Result ret;
    GFX_ScaleInfo ScaleInfo;


    rectInfo.srcblk.x = srect->x, rectInfo.srcblk.y = srect->y;
    rectInfo.srcblk.width = srect->w, rectInfo.srcblk.height = srect->h;
    rectInfo.dstblk.x = drect->x, rectInfo.dstblk.y = drect->y ;
    rectInfo.dstblk.width = drect->w, rectInfo.dstblk.height = drect->h;
    ScaleInfo.u32DeltaX     = scale_info->u32DeltaX;
    ScaleInfo.u32DeltaY     = scale_info->u32DeltaY;
    ScaleInfo.u32InitDelatX = scale_info->u32InitDelatX;
    ScaleInfo.u32InitDelatY = scale_info->u32InitDelatY;

    if(sdrv->src_ge_format==GFX_FMT_YUV422)
    {
        rectInfo.srcblk.width =  rectInfo.srcblk.width&~1;
    }

    if(sdrv->dst_ge_format==GFX_FMT_YUV422)
    {
        rectInfo.dstblk.width =  (rectInfo.dstblk.width+1)&~1;
    }

    MApi_GFX_BeginDraw();
    SET_BLT_MIRROR_SRCX(sdrv, rectInfo);
    SET_BLT_MIRROR_SRCY(sdrv, rectInfo);
    ret = MApi_GFX_BitBltEx(&rectInfo, scale_info->u32GFXDrawFlag, &ScaleInfo);
    if(GFX_SUCCESS != ret)
    {
           // printf("\n%s:%d\n",__FUNCTION__,__LINE__);
           // printf("\nthe ret is %x \n",ret);
           // printf("\nthe dest x:%d dest y:%d  clip :x1:%d  clip:x2:%d  clip y1:%d   clip y2 :%d  \n",
           // drect->x,drect->y,sdrv->clip.x1,sdrv->clip.x2,sdrv->clip.y1,sdrv->clip.y2);
            D_INFO("GE downscaling blit ratio can not be supported by HW(32:1)!, src height %d, dst height%d , src width :%d dst width %d\n",
            rectInfo.srcblk.height, rectInfo.dstblk.height,rectInfo.srcblk.width,rectInfo.dstblk.width);


    }else
        MApi_GFX_SetTAGID(MApi_GFX_GetNextTAGID(TRUE));
    MApi_GFX_EndDraw();

        return (GFX_SUCCESS==ret) ;
}

bool mstarBlitTrapezoid_null(
        void *driver_data,
        void *device_data,
        DFBRectangle *srect,
        DFBTrapezoid *dtrapezoid )
{
    return true;
}

bool mstarBlitTrapezoid_sw(
        void *driver_data,
        void *device_data,
        DFBRectangle *srect,
        DFBTrapezoid *dtrapezoid )
{
    return false;
}

bool mstarBlitTrapezoid(
        void *driver_data,
        void *device_data,
        DFBRectangle *srect,
        DFBTrapezoid *dtrapezoid ){
    MSTARDeviceData *sdev = device_data;
    MSTARDriverData *sdrv = driver_data;

    GFX_DrawRect rectInfo;
    GFX_Result ret;

    rectInfo.srcblk.x = srect->x, rectInfo.srcblk.y = srect->y;
    rectInfo.srcblk.width = srect->w, rectInfo.srcblk.height = srect->h;
    rectInfo.dsttrapeblk.u16X0= dtrapezoid->x0;
    rectInfo.dsttrapeblk.u16Y0= dtrapezoid->y0;
    rectInfo.dsttrapeblk.u16X1= dtrapezoid->x1;
    rectInfo.dsttrapeblk.u16Y1= dtrapezoid->y1;
    rectInfo.dsttrapeblk.u16DeltaTop = dtrapezoid->top_edge_width;
    rectInfo.dsttrapeblk.u16DeltaBottom= dtrapezoid->bottom_edge_width;

    MApi_GFX_BeginDraw();
    SET_BLT_MIRROR_SRCX(sdrv, rectInfo);
    SET_BLT_MIRROR_SRCY(sdrv, rectInfo);
    if(false == dtrapezoid->horiz_direct)
        ret = MApi_GFX_BitBlt(&rectInfo, GFXRECT_FLAG_TRAPE_DIRECTION_Y|GFXDRAW_FLAG_SCALE );
    else
        ret = MApi_GFX_BitBlt(&rectInfo, GFXRECT_FLAG_TRAPE_DIRECTION_X|GFXDRAW_FLAG_SCALE );

    MApi_GFX_SetTAGID(MApi_GFX_GetNextTAGID(TRUE));
    MApi_GFX_EndDraw();
    return true ;
}

bool mstarFillTrapezoid_null(
        void *driver_data,
        void *device_data,
        DFBTrapezoid *dtrapezoid )
{
    return true;
}

bool mstarFillTrapezoid_sw(
        void *driver_data,
        void *device_data,
        DFBTrapezoid *dtrapezoid )
{
    return false;
}

bool mstarFillTrapezoid(
        void *driver_data,
        void *device_data,
        DFBTrapezoid *dtrapezoid ){
    MSTARDeviceData *sdev = device_data ;
    MSTARDriverData *sdrv = driver_data ;
    GFX_RectFillInfo rectInfo ;

    rectInfo.dstTrapezoidBlk.u16X0= dtrapezoid->x0;
    rectInfo.dstTrapezoidBlk.u16Y0= dtrapezoid->y0;
    rectInfo.dstTrapezoidBlk.u16X1= dtrapezoid->x1;
    rectInfo.dstTrapezoidBlk.u16Y1= dtrapezoid->y1;
    rectInfo.dstTrapezoidBlk.u16DeltaTop = dtrapezoid->top_edge_width;
    rectInfo.dstTrapezoidBlk.u16DeltaBottom = dtrapezoid->bottom_edge_width;

    rectInfo.fmt = sdrv->dst_ge_format ;
    rectInfo.colorRange.color_s.a = sdrv->color.a;
    rectInfo.colorRange.color_s.r = sdrv->color.r;
    rectInfo.colorRange.color_s.g = sdrv->color.g;
    rectInfo.colorRange.color_s.b = sdrv->color.b;

    if(false == dtrapezoid->horiz_direct)
        rectInfo.flag = GFXDRAW_FLAG_TRAPEZOID_Y ;
    else
        rectInfo.flag = GFXDRAW_FLAG_TRAPEZOID_X ;

    MApi_GFX_BeginDraw();
    MApi_GFX_TrapezoidFill( &rectInfo) ;
    MApi_GFX_SetTAGID(MApi_GFX_GetNextTAGID(TRUE));
    MApi_GFX_EndDraw();
    
    return true ;
}


/**********************************************************************************************************************/

static int
driver_probe( CoreGraphicsDevice *device )
{
     D_DEBUG_AT( MSTAR_G2_Driver, "%s()\n", __FUNCTION__ );
     //printf("\nDean %s\n", __FUNCTION__);

     //return dfb_gfxcard_get_accelerator( device ) == 0x2D47;
     return 1;
}

static void
driver_get_info( CoreGraphicsDevice *device,
                 GraphicsDriverInfo *info )
{
     D_DEBUG_AT( MSTAR_G2_Driver, "%s()\n", __FUNCTION__ );
     //printf("\nDean %s\n", __FUNCTION__);

     /* fill driver info structure */
     snprintf( info->name,
               DFB_GRAPHICS_DRIVER_INFO_NAME_LENGTH,
               "Mstar G2 Driver" );

     snprintf( info->vendor,
               DFB_GRAPHICS_DRIVER_INFO_VENDOR_LENGTH,
               "Mstar corp." );

     info->version.major = 0;
     info->version.minor = 1;

     info->driver_data_size = sizeof(MSTARDriverData);
     info->device_data_size = sizeof(MSTARDeviceData);
}

void mstarGetSerial( void *driver_data, void *device_data, CoreGraphicsSerial *serial )
{
     MSTARDeviceData *sdev = device_data;
     serial->generation = 0;
     serial->serial = (unsigned int)MApi_GFX_GetNextTAGID(FALSE);
}

void mstarGetSerial_null( void *driver_data, void *device_data, CoreGraphicsSerial *serial )
{}

DFBResult mstarWaitSerial( void *driver_data, void *device_data, const CoreGraphicsSerial *serial )
{
     u16 tagID;

     tagID = (u16)serial->serial;
     MApi_GFX_WaitForTAGID(tagID);

     return DFB_OK;
}

DFBResult mstarWaitSerial_null( void *driver_data, void *device_data, const CoreGraphicsSerial *serial )
{
     return DFB_OK;
}

static MS_U32 mstar_dfb_OSD_RESOURCE_SetFBFmt(MS_U16 pitch,MS_U32 addr , MS_U16 fmt )
{
   printf("set osd resource %08x, %d, %04x\n", addr, pitch, fmt);
   return 0x1;
}

static MS_BOOL mstar_sc_is_interlace(void)
{
    //use MApi_XC_GetStatus for IPC issue.
    XC_ApiStatus xcStatus;
    if (MApi_XC_GetStatus(&xcStatus, MAIN_WINDOW))
    {
        //printf("XC interlace=%d \n",xcStatus.bInterlace);
        return xcStatus.bInterlace;
    }
    else
    {
        printf("Error! Cannot get XC Status! \n");
        assert(0);
    }

  //MS_XC_DST_DispInfo dstDispInfo;
  //MApi_XC_GetDstInfo(&dstDispInfo,sizeof(MS_XC_DST_DispInfo),E_GOP_XCDST_IP1_MAIN);
  //return dstDispInfo.bInterlaceMode;

  //return MDrv_MVOP_GetIsInterlace();
}

static MS_U16 mstar_sc_get_h_cap_start(void)
{
#if DFB_BUILD_FOR_PRJ_OBAMA
    return (MS_U16)MAdp_SYS_GetPanelHStart();
#else
    MS_PNL_DST_DispInfo dstDispInfo;
    MApi_PNL_GetDstInfo(&dstDispInfo, sizeof(MS_PNL_DST_DispInfo));
    return dstDispInfo.DEHST;
#endif
}

static MS_U16 mstar_sc_get_ip0_h_cap_start(void)
{
  MS_XC_DST_DispInfo dstDispInfo;
  MApi_XC_GetDstInfo(&dstDispInfo,sizeof(MS_XC_DST_DispInfo),E_GOP_XCDST_IP1_MAIN);
  return dstDispInfo.DEHST;

}

static void mstar_XC_Sys_PQ_ReduceBW_ForOSD(MS_U8 PqWin, MS_BOOL bOSD_On)
{
   // printf("mstar_XC_Sys_PQ_ReduceBW_ForOSD %d, %s\n", PqWin, bOSD_On?"on":"off");
#ifdef FIX_ME_OBAMA2
    //do Nothing currently. Remove drvPQ dependency first.
#endif
}

#if DFB_BUILD_FOR_PRJ_OBAMA
typedef MS_S8                       FONTHANDLE;      ///< Font handle
typedef MS_S16                  BMPHANDLE;       ///< Bitmap handle
typedef MS_S8                       DBHANDLE;
static MS_U32 mstar_OSD_RESOURCE_GetFontInfoGFX(FONTHANDLE handle, GFX_FontInfo* pinfo)
{
   printf("Should not arrive here!!!\n");
   assert(0);
}
static MS_U32 msAPI_OSD_RESOURCE_GetBitmapInfoGFX(BMPHANDLE handle, GFX_BitmapInfo* pinfo)
{
   printf("Should not arrive here!!!\n");
   assert(0);
}
#endif

static DFBResult
mstar_init_driver( CoreGraphicsDevice *device,
                    void               *driver_data,
                    void               *device_data )
{
    MSTARDriverData *sdrv = driver_data;
    MSTARDeviceData *sdev = device_data;
    u16 pnlW;
    u16 pnlH;

    GOP_InitInfo gopInitInfo;
    u32 u32GOP_Regdma_addr;
    u32 u32GOP_Regdma_size;
    u32 u32GOP_Regdma_aligned;
    u32 u32GOP_Regdma_miu;

    GFX_Config gfx_config;
    GFX_RgbColor gfxColor;
    u32 u32GE_VQ_addr;
    u32 u32GE_VQ_size;
    u32 u32GE_VQ_aligned;
    u32 u32GE_VQ_miu;
    int i=0;
    int status = 0;
    u16 gfx_supported_bld_flags;
    XC_INITDATA XC_InitData;

    GOP_MuxConfig muxConfig;

    int gopCount = 4; 

    D_DEBUG_AT( MSTAR_G2_Driver, "%s()\n", __FUNCTION__ );

    memset(&XC_InitData, 0, sizeof(XC_InitData));
    ////////////////////////////////////////////////////////////////////////////////
    //Init MsOS & SEM:
    //MsOS_Init();
    //MDrv_SEM_Init();
    Global_Init();
    MApi_PNL_IOMapBaseInit();
    MDrv_VE_SetIOMapBase();
    MApi_XC_Init(&XC_InitData, 0);
    
    ////////////////////////////////////////////////////////////////////////////////
    //Init GOP:
    //Get GOP Idx:
    sdev->gfx_gop_index=dfb_config->mst_gfx_gop_index;

    //Get pnlW, pnlH
    #if DFB_BUILD_FOR_PRJ_OBAMA
    if(0==dfb_config->mst_lcd_width || 0==dfb_config->mst_lcd_height)
        MAdp_SYS_GetPanelResolution(&pnlW,&pnlH);
    else
    #endif
    {
        pnlW = dfb_config->mst_lcd_width;
        pnlH = dfb_config->mst_lcd_height;
    }

    //Prepare GOP Init Params:
    gopInitInfo.u16PanelWidth = pnlW;
    gopInitInfo.u16PanelHeight= pnlH;
    gopInitInfo.u16PanelHStr = mstar_sc_get_h_cap_start();
    gopInitInfo.u32GOPRBAdr = 0;
    gopInitInfo.u32GOPRBLen = 0;
    gopInitInfo.bEnableVsyncIntFlip = TRUE;
    u32GOP_Regdma_addr = dfb_config->mst_gop_regdmaphys_addr;
    u32GOP_Regdma_size = dfb_config->mst_gop_regdmaphys_len;
    #if DFB_BUILD_FOR_PRJ_OBAMA
    if(0==u32GOP_Regdma_addr || 0==u32GOP_Regdma_size)
    {
        if(false==MAdp_SYS_GetMemoryInfo(MMAP_GOP_REGDMABASE, (unsigned long *)&u32GOP_Regdma_addr, (unsigned long *)&u32GOP_Regdma_size,
                    (unsigned long *)&u32GOP_Regdma_aligned, (unsigned long *)&u32GOP_Regdma_miu))
        {
            u32GOP_Regdma_addr = 0;
            u32GOP_Regdma_size = 0;
        }
    }
    #endif
    gopInitInfo.u32GOPRegdmaAdr = u32GOP_Regdma_addr;
    gopInitInfo.u32GOPRegdmaLen = u32GOP_Regdma_size;   

    //Register callback functions:
    MApi_GOP_RegisterFBFmtCB(mstar_dfb_OSD_RESOURCE_SetFBFmt);
    MApi_GOP_RegisterXCIsInterlaceCB(mstar_sc_is_interlace);
    MApi_GOP_RegisterXCGetCapHStartCB(mstar_sc_get_ip0_h_cap_start);
    MApi_GOP_RegisterXCReduceBWForOSDCB(mstar_XC_Sys_PQ_ReduceBW_ForOSD);
    #if DFB_BUILD_FOR_PRJ_OBAMA
    MApi_GFX_RegisterGetFontCB(mstar_OSD_RESOURCE_GetFontInfoGFX);
    MApi_GFX_RegisterGetBMPCB(msAPI_OSD_RESOURCE_GetBitmapInfoGFX);
    #endif


    gopCount = MApi_GOP_GWIN_GetMaxGOPNum();
    
    //Init GOP:
    #if MSTAR_MULTI_GOP_SUPPORT
    for(i=0; i<dfb_config->mst_gop_counts; i++)
    {
        EN_GOP_IGNOREINIT eIgnor;
        if(i >= gopCount)
        {
            printf("\nthe gop %d is not existed  total have %d gop\n",i,gopCount);
            assert(0);
        }
        
        if (dfb_config->mst_disable_layer_init == i)
        {
            eIgnor = E_GOP_IGNORE_ALL;
            printf("[DFB] 1 Ignore layer:%d, GOP:%d\n", dfb_config->mst_disable_layer_init, dfb_config->mst_gop_available[i]);
        }
        else
        {
            eIgnor = (E_GOP_IGNORE_MUX|E_GOP_BOOTLOGO_IGNORE_VEOSDEN);
        }
        
        MApi_GOP_SetConfig(E_GOP_IGNOREINIT,&eIgnor);
        
        MApi_GOP_InitByGOP(&gopInitInfo,  dfb_config->mst_gop_available[i]);
        if(dfb_config->mst_gop_available_r[i]!= 0xf)
        {
            MApi_GOP_InitByGOP(&gopInitInfo,  dfb_config->mst_gop_available_r[i]);
        }

        eIgnor = 0;
        MApi_GOP_SetConfig(E_GOP_IGNOREINIT,&eIgnor);    
    }
    #else
    MApi_GOP_InitByGOP(&gopInitInfo,  sdev->gfx_gop_index);
    #endif

    if(dfb_config->mst_GOP_HMirror>0)
         MApi_GOP_GWIN_SetHMirror(TRUE);
    else if(dfb_config->mst_GOP_HMirror==0)
          MApi_GOP_GWIN_SetHMirror(FALSE);

    if(dfb_config->mst_GOP_VMirror>0)
         MApi_GOP_GWIN_SetVMirror(TRUE);
    else if(dfb_config->mst_GOP_VMirror==0)
          MApi_GOP_GWIN_SetVMirror(FALSE);

    if(dfb_config->mst_goplayer_counts > 0)
    {
        GOP_LayerConfig stLayerSetting;
        MS_U32 u32size = sizeof(GOP_LayerConfig);
        E_GOP_API_Result enResult = GOP_API_FAIL;
        stLayerSetting.u32LayerCounts = dfb_config->mst_goplayer_counts;
        for(i = 0; i < dfb_config->mst_goplayer_counts; i++)
        {
            stLayerSetting.stGopLayer[i].u32GopIndex = dfb_config->mst_goplayer[i];
            stLayerSetting.stGopLayer[i].u32LayerIndex = i;
        }
        enResult = MApi_GOP_GWIN_SetLayer(&stLayerSetting, u32size);
        if (enResult == GOP_API_SUCCESS)
        {
            DBG_LAYER_MSG("MApi_GOP_GWIN_SetLayer  success %s(%d)\n",__FUNCTION__,__LINE__);
        }
        else
        {
            DBG_LAYER_MSG("MApi_GOP_GWIN_SetLayer fail, return %u!!! %s(%d)\n", enResult,__FUNCTION__,__LINE__);
        }
    } 
    else  if(dfb_config->mst_mux_counts > 0)
    {
        memset(&muxConfig,0,sizeof(muxConfig));
        for(i=0; i<dfb_config->mst_mux_counts; i++)
        {
            muxConfig.GopMux[i].u8MuxIndex = i;
            muxConfig.GopMux[i].u8GopIndex = dfb_config->mst_gop_mux[i];
            //printf("mux[%d]:gop[%d]",i,muxConfig.GopMux[i].u8GopIndex);
        }
        muxConfig.u8MuxCounts = dfb_config->mst_mux_counts;
        MApi_GOP_GWIN_SetMux(&muxConfig,sizeof(muxConfig));
    }

    ////////////////////////////////////////////////////////////////////////////////
    //Init GE:
    //Get VQ Addr & Size:
    u32GE_VQ_addr = dfb_config->mst_ge_vq_phys_addr;
    u32GE_VQ_size = dfb_config->mst_ge_vq_phys_len;
    #if DFB_BUILD_FOR_PRJ_OBAMA
    if(0==u32GE_VQ_addr || 0==u32GE_VQ_size)
    {
        if(false==MAdp_SYS_GetMemoryInfo(MMAP_GE_VQ_BUFFER, (unsigned long *)&u32GE_VQ_addr, (unsigned long *)&u32GE_VQ_size,
                (unsigned long *)&u32GE_VQ_aligned, (unsigned long *)&u32GE_VQ_miu))
        {
            u32GE_VQ_addr = 0;
            u32GE_VQ_size = 0;
        }
    }
    #endif

    //Prepare GE Init Params:
    gfx_config.u8Dither = FALSE;
    gfx_config.bIsCompt = FALSE;
    gfx_config.bIsHK = TRUE;
    gfx_config.u8Miu = ((dfb_config->video_phys_cpu>= dfb_config->mst_miu1_cpu_offset)?1:0);
    gfx_config.u32VCmdQAddr = u32GE_VQ_addr;
    gfx_config.u32VCmdQSize =  u32GE_VQ_size;
    //Init GE:

    MApi_GFX_Init(&gfx_config);


    //Get Supported Bliting Flags Here:
    MApi_GFX_QueryDFBBldCaps(&gfx_supported_bld_flags);
    sdrv->gfx_supported_bld_flags = (DSBLIT_SRC_COLORKEY | DSBLIT_DST_COLORKEY | DSBLIT_ROTATE90 | DSBLIT_ROTATE180 | DSBLIT_ROTATE270);
    sdrv->gfx_supported_draw_flags = DSDRAW_NOFX;
    if(gfx_supported_bld_flags & GFX_DFB_BLD_FLAG_COLORALPHA)
        sdrv->gfx_supported_bld_flags |= DSBLIT_BLEND_COLORALPHA;
    if(gfx_supported_bld_flags & GFX_DFB_BLD_FLAG_ALPHACHANNEL)
    {
        sdrv->gfx_supported_bld_flags |= DSBLIT_BLEND_ALPHACHANNEL;
        sdrv->gfx_supported_draw_flags|= DSDRAW_BLEND;
    }
    if(gfx_supported_bld_flags & GFX_DFB_BLD_FLAG_COLORIZE)
        sdrv->gfx_supported_bld_flags |= DSBLIT_COLORIZE;
    if(gfx_supported_bld_flags & GFX_DFB_BLD_FLAG_SRCPREMUL)
    {
        sdrv->gfx_supported_bld_flags |= DSBLIT_SRC_PREMULTIPLY;
        sdrv->gfx_supported_draw_flags|= DSDRAW_SRC_PREMULTIPLY;

    }
    if(gfx_supported_bld_flags & GFX_DFB_BLD_FLAG_SRCPREMULCOL)
        sdrv->gfx_supported_bld_flags |= DSBLIT_SRC_PREMULTCOLOR;
    if(gfx_supported_bld_flags & GFX_DFB_BLD_FLAG_DSTPREMUL)
    {
        sdrv->gfx_supported_bld_flags |= DSBLIT_DST_PREMULTIPLY;
        sdrv->gfx_supported_draw_flags|= DSDRAW_DST_PREMULTIPLY;
    }
    if(gfx_supported_bld_flags & GFX_DFB_BLD_FLAG_XOR)
    {
        sdrv->gfx_supported_bld_flags |= DSBLIT_XOR;
        sdrv->gfx_supported_draw_flags|= DSDRAW_XOR;
    }
    if(gfx_supported_bld_flags & GFX_DFB_BLD_FLAG_DEMULTIPLY)
    {
        sdrv->gfx_supported_bld_flags |= DSBLIT_DEMULTIPLY;
        sdrv->gfx_supported_draw_flags|= DSDRAW_DEMULTIPLY;
    }
    if(gfx_supported_bld_flags & GFX_DFB_BLD_FLAG_SRCALPHAMASK)
        sdrv->gfx_supported_bld_flags |= DSBLIT_SRC_MASK_ALPHA;
    if(gfx_supported_bld_flags & GFX_DFB_BLD_FLAG_SRCCOLORMASK)
        sdrv->gfx_supported_bld_flags |= DSBLIT_SRC_MASK_COLOR;

    sdrv->ge_blit_nearestmode_enabled =
    sdrv->ge_blit_xmirror =
    sdrv->ge_blit_ymirror =
    sdrv->ge_draw_dst_colorkey_enabled =
    sdrv->ge_blit_dst_colorkey_enabled =
    sdrv->ge_draw_alpha_blend_enabled =
    sdrv->ge_blit_alpha_blend_enabled =
    sdrv->ge_src_colorkey_enabled =
    sdrv->ge_palette_enabled =
    sdrv->ge_palette_intensity_enabled =
    sdrv->ge_render_alpha_cmp_enabled = 0;
    sdrv->ge_src_blend = sdrv->ge_dst_blend = GFX_DFB_BLD_OP_ONE;
    sdrv->ge_last_render_op = MSTAR_GFX_RENDER_OP_NONE;
    sdrv->src_ge_yuv_fmt = sdrv->dst_ge_yuv_fmt = GFX_YUV_YUYV;

    ////////////////////////////////////////////////////////////////////////////////
    //Init DIP:
    if((dfb_config->mst_enable_dip == true) && (dfb_config->mst_dip_mload_addr !=0) && (dfb_config->mst_dip_mload_length !=0))
    {
        void *pvirtual_address = NULL;
        unsigned long miu_offset;
        
        pvirtual_address = (void *)MsOS_MPool_PA2KSEG1( dfb_config->mst_dip_mload_addr );
        if(NULL == pvirtual_address)
        {
            if ( dfb_config->mst_dip_mload_addr >= dfb_config->mst_miu1_hal_offset )  
                miu_offset = dfb_config->mst_miu1_hal_offset;
            else
                miu_offset = dfb_config->mst_miu0_hal_offset;
            
            if( !MsOS_MPool_Mapping( (miu_offset== dfb_config->mst_miu0_hal_offset) ? 0 : 1, dfb_config->mst_dip_mload_addr, dfb_config->mst_dip_mload_length, 1 ) )
            {
                printf("Waring! DIP map buf error! \n");
            }
            else
            {
                MApi_XC_MLoad_Init(dfb_config->mst_dip_mload_addr, dfb_config->mst_dip_mload_length);
                MApi_XC_MLoad_Enable(TRUE);             
            }
        }
        else
        {
            MApi_XC_MLoad_Init(dfb_config->mst_dip_mload_addr, dfb_config->mst_dip_mload_length);
            MApi_XC_MLoad_Enable(TRUE);
        }      
    }


    return DFB_OK;
}

static /*EN_Gop_MuxSel*/ int _get_mutex_enum(int index)
{


   switch(index)
   {
     case 0:
          return 0;//EN_GOP_MUX0;
     case 1:
          return 1;//EN_GOP_MUX1;      
     case 2:
          return 2;//EN_GOP_MUX2;
     case 3:
          return 3;//EN_GOP_MUX3;
     case 4:
          return 18;//EN_GOP_MUX4;
     default:
          assert(0);
   }

   return 0 /*EN_GOP_MUX0*/;
 
}


static DFBResult
    mstar_init_device ( CoreGraphicsDevice *device,
                    void               *driver_data,
                    void               *device_data )
{


    MSTARDriverData *sdrv = driver_data;
    MSTARDeviceData *sdev = device_data;
    int i = 0;
    int status = 0;
    GOP_MuxConfig muxConfig;
    u32 u32GE_VQ_addr;
    u32 u32GE_VQ_size;
    u32 u32GE_VQ_aligned;
    u32 u32GE_VQ_miu;
    GFX_RgbColor gfxColor;
    //Init GOP:
    printf("\n DFB USE THE GFX : MSTAR_G2 \n");

	
	if(dfb_config->mst_mux_counts > 0)
    {
        memset(&muxConfig,0,sizeof(muxConfig));
        for(i=0; i<dfb_config->mst_mux_counts; i++)
        {
            muxConfig.GopMux[i].u8MuxIndex = _get_mutex_enum(i); //patch for mux4
            muxConfig.GopMux[i].u8GopIndex = dfb_config->mst_gop_mux[i];
            //printf("mux[%d]:gop[%d]",i,muxConfig.GopMux[i].u8GopIndex);
        }
        muxConfig.u8MuxCounts = dfb_config->mst_mux_counts;
        MApi_GOP_GWIN_SetMux(&muxConfig,sizeof(muxConfig));
    }

    //printf("[DFB] dfb_config->mst_gop_counts: %d\n", dfb_config->mst_gop_counts);
#if MSTAR_MULTI_GOP_SUPPORT
    for(i=0; i<dfb_config->mst_gop_counts; i++)
    {

       // MApi_GOP_GWIN_SetForceWrite(true);
        MApi_GOP_GWIN_SwitchGOP(dfb_config->mst_gop_available[i]);
        
        if (dfb_config->mst_disable_layer_init == i)
        {            
            printf("[DFB] Ignore layer:%d\n", dfb_config->mst_disable_layer_init);
        }
        else
        {
            printf("[DFB] SetGOPDst layer:%d\n", i);
            MApi_GOP_GWIN_SetFieldInver(TRUE);
            status =MApi_GOP_GWIN_SetGOPDst(dfb_config->mst_gop_available[i], (EN_GOP_DST_TYPE)dfb_config->mst_gop_dstPlane[i]);
        }
        //Set Stretch Mode to Linear as GE:
        MApi_GOP_GWIN_Set_HStretchMode(E_GOP_HSTRCH_6TAPE_LINEAR);
        //MApi_GOP_GWIN_SetForceWrite(false);
       // printf("\n[DFB] I = %d Set GOPDst status:%d; the gop number is %d;the gop dst is%d\n", i, status,dfb_config->mst_gop_available[i],dfb_config->mst_gop_dstPlane[i]);
        if(dfb_config->mst_gop_available_r[i]!= 0xf)
        {
             MApi_GOP_GWIN_SwitchGOP(dfb_config->mst_gop_available_r[i]);
             
             if (dfb_config->mst_disable_layer_init == i)
             {            
                 printf("[DFB] Ignore layer:%d\n", dfb_config->mst_disable_layer_init);
             }
             else
             {
                 printf("[DFB] SetGOPDst layer:%d\n", i);
                 MApi_GOP_GWIN_SetFieldInver(TRUE);
                 status =MApi_GOP_GWIN_SetGOPDst(dfb_config->mst_gop_available_r[i], (EN_GOP_DST_TYPE)dfb_config->mst_gop_dstPlane[i]);
             }
             //Set Stretch Mode to Linear as GE:
             MApi_GOP_GWIN_Set_HStretchMode(E_GOP_HSTRCH_6TAPE_LINEAR);
             
             MApi_GOP_GWIN_SwitchGOP(dfb_config->mst_gop_available[i]);
        }

        if ( (EN_GOP_DST_TYPE)dfb_config->mst_gop_dstPlane[i] == E_GOP_DST_VE)
        {
            //For K3 Set the gopVETimingType
            VE_DrvStatus DrvStatus;
            MDrv_VE_GetStatus(&DrvStatus);
            GOP_VE_TIMINGTYPE gopVETimingType;
            if(DrvStatus.VideoSystem <= 2)
            {
                gopVETimingType = GOP_VE_NTSC;
            }
            else
            {
                gopVETimingType = GOP_VE_PAL;
            }
            printf("[DFB] MApi_GOP_VE_SetOutputTiming : %d\n", gopVETimingType);
            MApi_GOP_VE_SetOutputTiming(gopVETimingType);
        }
    }
#else

    MApi_GOP_GWIN_SwitchGOP(sdev->gfx_gop_index);
    //Set Stretch Mode to Linear as GE:
    MApi_GOP_GWIN_Set_HStretchMode(E_GOP_HSTRCH_6TAPE_LINEAR);
#endif

    if(dfb_config->mst_GOP_HMirror>0)
         MApi_GOP_GWIN_SetHMirror(TRUE);
    else if(dfb_config->mst_GOP_HMirror==0)
          MApi_GOP_GWIN_SetHMirror(FALSE);

    if(dfb_config->mst_GOP_VMirror>0)
         MApi_GOP_GWIN_SetVMirror(TRUE);
    else if(dfb_config->mst_GOP_VMirror==0)
          MApi_GOP_GWIN_SetVMirror(FALSE);


    //Disable TransClr:
    MApi_GOP_GWIN_EnableTransClr(GOPTRANSCLR_FMT0, FALSE);

#ifdef OSD2VE_SUPPORT
    //Enable OP to VEMode for U4
    if(dfb_config->mst_osd_to_ve)
    {
        // MApi_XC_SetOSD2VEMode(E_VOP_SEL_OSD_BLEND0); // Using in GOP0/1 set to OP
        MApi_XC_SetOSD2VEMode((EN_VOP_SEL_OSD_XC2VE_MUX)(dfb_config->mst_xc_to_ve_mux));
    }
#endif

    //Get VQ Addr & Size:
    u32GE_VQ_addr = dfb_config->mst_ge_vq_phys_addr;
    u32GE_VQ_size = dfb_config->mst_ge_vq_phys_len;
    #if DFB_BUILD_FOR_PRJ_OBAMA
    if(0==u32GE_VQ_addr || 0==u32GE_VQ_size)
    {
        if(false==MAdp_SYS_GetMemoryInfo(MMAP_GE_VQ_BUFFER, (unsigned long *)&u32GE_VQ_addr, (unsigned long *)&u32GE_VQ_size,
                (unsigned long *)&u32GE_VQ_aligned, (unsigned long *)&u32GE_VQ_miu))
        {
            u32GE_VQ_addr = 0;
            u32GE_VQ_size = 0;
        }
    }
    #endif 

    if(dfb_config->bUsingGEVQ == false)
        u32GE_VQ_size = 0;		//turn off ge vq

        //Set VCMDQ & Buf:
    if(u32GE_VQ_size>=4*1024)
    {
        GFX_VcmqBufSize vqSize;

        if(u32GE_VQ_size>=512*1024)
            vqSize = GFX_VCMD_512K;
        else if(u32GE_VQ_size>=256*1024)
            vqSize = GFX_VCMD_256K;
        else if(u32GE_VQ_size>=128*1024)
            vqSize = GFX_VCMD_128K;
        else if(u32GE_VQ_size>=64*1024)
            vqSize = GFX_VCMD_64K;
        else if(u32GE_VQ_size>=32*1024)
            vqSize = GFX_VCMD_32K;
        else if(u32GE_VQ_size>=16*1024)
            vqSize = GFX_VCMD_16K;
        else if(u32GE_VQ_size>=8*1024)
            vqSize = GFX_VCMD_8K;
        else
            vqSize = GFX_VCMD_4K;

        u32GE_VQ_addr = u32GE_VQ_addr;
        if(GFX_SUCCESS == MApi_GFX_SetVCmdBuffer(u32GE_VQ_addr, vqSize))
            MApi_GFX_EnableVCmdQueue(TRUE);
        else
            MApi_GFX_EnableVCmdQueue(FALSE);
    }
    else 
    {
        MApi_GFX_EnableVCmdQueue(FALSE);
    }


    gfxColor.a =
    gfxColor.r =
    gfxColor.g =
    gfxColor.b = 0x00;
    MApi_GFX_SetStrBltSckType(GFX_NEAREST, &gfxColor);
    
    return DFB_OK;
}

void mstar_FlushTextureCache_null( void *driver_data, void *device_data )
{
}

void mstar_FlushTextureCache( void *driver_data, void *device_data )
{
    MsOS_FlushMemory();
}

void mstar_EngineSync_null(void *driver_data, void *device_data)
{
}

void mstar_EngineSync(void *driver_data, void *device_data)
{

    MApi_GFX_FlushQueue();
}

void mstar_BeginDraw_null( void *driver_data, void *device_data, CardState *state )
{
}

void mstar_BeginDraw( void *driver_data, void *device_data, CardState *state )
{
    //printf("in %s  \n",__FUNCTION__);
    MApi_GFX_BeginDraw();
}

void mstar_EndDraw_null( void *driver_data, void *device_data, CardState *state )
{
}

void mstar_EndDraw( void *driver_data, void *device_data, CardState *state )
{
    //printf("in %s  !!!\n",__FUNCTION__);

    MApi_GFX_EndDraw();
}

ReactionResult GopDst_reaction_callback( const void *msg_data,  void *ctx )
{
	const DFBDisplayLayerGOPDST *gop_dst  = msg_data;
	CoreLayer       *layer = ctx;
	MSTARDriverData *sdrv = (MSTARDriverData *)layer->driver_data;
	MSTARLayerData  *slay = layer->layer_data;

	//printf("%s: gop_dst = 0x%x, pid = %d\n", __FUNCTION__, *gop_dst, getpid() );

    slay->gop_dst = *gop_dst;
    
      switch(*gop_dst)
      {
          case E_GOP_DST_IP0:
              layer->screen = sdrv->ip0_screen;
              break;
              
          case E_GOP_DST_OP0:
              layer->screen = sdrv->op_screen;
              break;
              
          case E_GOP_DST_BYPASS:
              layer->screen = sdrv->op_screen;
              break;
    
          case E_GOP_DST_VE:
              layer->screen = sdrv->ve_screen;
              break;
          default:
              break;
      }
}


static DFBResult
driver_init_driver( CoreGraphicsDevice  *device,
                    GraphicsDeviceFuncs *funcs,
                    void                *driver_data,
                    void                *device_data,
                    CoreDFB             *core )
{
     DFBResult         ret;
     MSTARDriverData *sdrv = driver_data;
     MSTARDeviceData *sdev = device_data;
     u8  i;

     D_DEBUG_AT( MSTAR_G2_Driver, "%s()\n", __FUNCTION__ );
     //printf("\nDean %s\n", __FUNCTION__);

     /* Keep pointer to shared device data. */
     sdrv->dev = device_data;

     /* Keep core and device pointer. */
     sdrv->core   = core;
     sdrv->device = device;
     memset(sdrv->mstarLayerBuffer, 0, sizeof(sdrv->mstarLayerBuffer));

     //MDrv_MMIO_Init(); // I/O remap for current process

     if (dfb_config->null_driver == true) {
          printf("[sheng] driver_init_driver, null driver\n");
          funcs->GetSerial        = mstarGetSerial_null;
          funcs->WaitSerial        = mstarWaitSerial_null;
          funcs->CheckState        = mstarCheckState_null;
          funcs->SetState          = mstarSetState_null;
          funcs->FillRectangle     = mstarFillRectangle_null ;
          funcs->DrawRectangle     = mstarDrawRectangle_null ;
          funcs->DrawOval          = mstarDrawOval_null ;
          funcs->DrawLine     = mstarDrawLine_null ;
          funcs->Blit     = mstarBlit_null ;
          funcs->StretchBlit     = mstarStretchBlit_null ;
          funcs->BlitTrapezoid = mstarBlitTrapezoid_null ;
          funcs->StretchBlitEx = mstarStretchBlitEx_null ;
          funcs->FlushTextureCache = mstar_FlushTextureCache_null ;
          funcs->EngineSync = mstar_EngineSync_null ;
          funcs->BeginDraw = mstar_BeginDraw_null;
          funcs->EndDraw = mstar_EndDraw_null;
     }
     else if (dfb_config->sw_render & SWRF_ENABLE) {
          printf("[sheng] driver_init_driver, swl render\n");
          funcs->GetSerial        = mstarGetSerial;
          funcs->WaitSerial        = mstarWaitSerial;
          funcs->CheckState        = mstarCheckState;
          funcs->SetState          = mstarSetState;        		  
          funcs->FillRectangle     = ( dfb_config->sw_render & SWRF_FILLRECT )? mstarFillRectangle_sw : mstarFillRectangle;
          funcs->DrawRectangle     = ( dfb_config->sw_render & SWRF_DRAWRECT )? mstarDrawRectangle_sw : mstarDrawRectangle;
          funcs->DrawOval          = ( dfb_config->sw_render & SWRF_DRAWOVAL )? mstarDrawOval_sw : mstarDrawOval ;
          funcs->DrawLine     = ( dfb_config->sw_render & SWRF_DRAWLINE )? mstarDrawLine_sw : mstarDrawLine ;
          funcs->Blit     = ( dfb_config->sw_render & SWRF_BLIT )? mstarBlit_sw : mstarBlit ;
          funcs->StretchBlit     = ( dfb_config->sw_render & SWRF_STRETCHBLIT )? mstarStretchBlit_sw : mstarStretchBlit ;
          funcs->BlitTrapezoid = ( dfb_config->sw_render & SWRF_BLITTRAPEZOID )? mstarBlitTrapezoid_sw : mstarBlitTrapezoid ;
          funcs->StretchBlitEx = ( dfb_config->sw_render & SWRF_STRETCHBLITEX )? mstarStretchBlitEx_sw : mstarStretchBlitEx ;
          funcs->FlushTextureCache = mstar_FlushTextureCache ;
          funcs->EngineSync = mstar_EngineSync ;
          funcs->BeginDraw = mstar_BeginDraw ;
          funcs->EndDraw = mstar_EndDraw ;	 	
     }
     else {
          funcs->GetSerial        = mstarGetSerial;
          funcs->WaitSerial        = mstarWaitSerial;
          funcs->CheckState        = mstarCheckState;
          funcs->SetState          = mstarSetState;
          funcs->FillRectangle     = mstarFillRectangle ;
          funcs->DrawRectangle     = mstarDrawRectangle ;
          funcs->DrawOval          = mstarDrawOval ;
          funcs->DrawLine     = mstarDrawLine ;
          funcs->Blit     = mstarBlit ;
          funcs->StretchBlit     = mstarStretchBlit ;
          funcs->BlitTrapezoid = mstarBlitTrapezoid ;
          funcs->StretchBlitEx = mstarStretchBlitEx;
          funcs->FlushTextureCache = mstar_FlushTextureCache;
          funcs->EngineSync = mstar_EngineSync;
          funcs->BeginDraw = mstar_BeginDraw;
          funcs->EndDraw = mstar_EndDraw;
     }
     /* Get virtual address for the LCD buffer in slaves here,
        master does it in driver_init_device(). */
     if (!dfb_core_is_master( core ))
          sdrv->lcd_virt = dfb_gfxcard_memory_virtual( device, sdev->lcd_offset );


     /* Register primary screen. */
     sdrv->op_screen  = dfb_screens_register( device, driver_data, &mstarOPScreenFuncs );
     sdrv->ip0_screen = dfb_screens_register( device, driver_data, & mstarIP0ScreenFuncs);
     sdrv->ve_screen  = dfb_screens_register( device, driver_data, & mstarVEScreenFuncs );
     sdrv->oc_screen = dfb_screens_register( device, driver_data, & mstarOCScreenFuncs);
     /* Register input system layers. */
     for( i=0; i<MSTAR_MAX_OUTPUT_LAYER_COUNT; i++)
     {

#if MSTAR_MULTI_GOP_SUPPORT
          if(i <dfb_config->mst_gop_counts)
          {
               if(dfb_config->mst_gop_dstPlane[i]== E_GOP_DST_OP0)
               {
                   sdrv->layers[i] = dfb_layers_register( sdrv->op_screen, driver_data, &mstarLayerFuncs );
               }
               else if(dfb_config->mst_gop_dstPlane[i]== E_GOP_DST_IP0)
               {
                   sdrv->layers[i] = dfb_layers_register( sdrv->ip0_screen, driver_data, &mstarLayerFuncs );
               }
               else if(dfb_config->mst_gop_dstPlane[i]== E_GOP_DST_MIXER2VE)
               {
                   sdrv->layers[i] = dfb_layers_register( sdrv->ve_screen, driver_data, &mstarLayerFuncs );
               }
               else if(dfb_config->mst_gop_dstPlane[i]== E_GOP_DST_MIXER2OP)
               {
                	sdrv->layers[i] = dfb_layers_register( sdrv->op_screen, driver_data, &mstarLayerFuncs);
               }
               else if(dfb_config->mst_gop_dstPlane[i] == E_GOP_DST_FRC)
               {
                   sdrv->layers[i] = dfb_layers_register( sdrv->oc_screen, driver_data, &mstarLayerFuncs);
               }
               else if(dfb_config->mst_gop_dstPlane[i] == E_GOP_DST_VE)
               {
                   sdrv->layers[i] = dfb_layers_register( sdrv->ve_screen, driver_data, &mstarLayerFuncs);
               }
               else if(dfb_config->mst_gop_dstPlane[i] == E_GOP_DST_IP1)
               {
                   sdrv->layers[i] = dfb_layers_register( sdrv->ip0_screen, driver_data, &mstarLayerFuncs);
               }
               else if(dfb_config->mst_gop_dstPlane[i]== E_GOP_DST_BYPASS)
               {
                   sdrv->layers[i] = dfb_layers_register( sdrv->op_screen, driver_data, &mstarLayerFuncs );
               }
               else 
               {
                   printf("\n--------unsupport----------\n");
               }
          }
          else
               sdrv->layers[i] = NULL;
#else

          sdrv->layers[i] = dfb_layers_register( sdrv->op_screen, driver_data, &mstarLayerFuncs);

#endif
        if(i <dfb_config->mst_gop_counts)
        {
            if (dfb_core_is_master( core ))
                sdev->reactor[i] = fusion_reactor_new( sizeof(DFBDisplayLayerGOPDST), "GOP_DST", dfb_core_world(core) );

            ret = fusion_reactor_attach(sdev->reactor[i], GopDst_reaction_callback, sdrv->layers[i], &sdrv->layers[i]->reaction);
            //printf("%s:%d, ret = %d, pid =%d\n", __FUNCTION__, __LINE__, ret, getpid());
        }
      }

     /* Register multi window layer. */
     //sdrv->multi = dfb_layers_register( sdrv->screen, driver_data, &sh7722MultiLayerFuncs );
     return mstar_init_driver(device, driver_data, device_data);
}

static DFBResult
driver_init_device( CoreGraphicsDevice *device,
                    GraphicsDeviceInfo *device_info,
                    void               *driver_data,
                    void               *device_data )
{
    MSTARDriverData *sdrv = driver_data;
    MSTARDeviceData *sdev = device_data;
    u16 pnlW;
    u16 pnlH;
    int i;

    //sdev->gfx_gop_index=dfb_config->mst_gfx_gop_index;
    D_DEBUG_AT( MSTAR_G2_Driver, "%s()\n", __FUNCTION__ );
    //printf("\nDean %s\n", __FUNCTION__);
    //  printf("MAdp_SYS_GetPanelResolution-->%d, %d\n", pnlW, pnlH);

    for( i=0; i<MSTAR_MAX_OUTPUT_LAYER_COUNT; i++)
    {
        sdev->layer_active[i] = false;
        sdev->layer_pinpon_mode[i] = false;
        sdev->layer_gwin_id[i] = INVALID_WIN_ID;
        sdev->layer_gwin_id_r[i] = INVALID_WIN_ID;
        sdev->layer_refcnt[i] = 0x0;
    }


    //Get pnlW, pnlH
    #if DFB_BUILD_FOR_PRJ_OBAMA
    if(0==dfb_config->mst_lcd_width || 0==dfb_config->mst_lcd_height)
        MAdp_SYS_GetPanelResolution(&pnlW,&pnlH);
    else
    #endif
    {
        pnlW = dfb_config->mst_lcd_width;
        pnlH = dfb_config->mst_lcd_height;
    }

    if(dfb_config->mst_gfx_width==0)
    {
        sdev->gfx_max_width = pnlW;
    }
    else
    {
        sdev->gfx_max_width = dfb_config->mst_gfx_width;
        if(sdev->gfx_max_width > pnlW)
            sdev->gfx_max_width = pnlW;
    }

    if(dfb_config->mst_gfx_height==0)
    {
        sdev->gfx_max_height = pnlH;
    }
    else
    {
        sdev->gfx_max_height = dfb_config->mst_gfx_height;
        if(sdev->gfx_max_height >pnlH)
           sdev->gfx_max_height  = pnlH;
    }

    sdev->lcd_width = pnlW;
    sdev->lcd_height= pnlH;

    sdev->gfx_max_width  &= ~3;

    sdev->gfx_h_offset=dfb_config->mst_gfx_h_offset;
    sdev->gfx_v_offset=dfb_config->mst_gfx_v_offset;
    sdev->mst_miu1_hal_offset   = dfb_config->mst_miu1_hal_offset;
    sdev->mst_miu1_cpu_offset   = dfb_config->mst_miu1_cpu_offset;

    //Init A8 GE Palette default:
    memset( sdev->palette_tbl, 0xFF, (sizeof(GFX_PaletteEntry)*MAX_PALETTE_ENTRY_CNT) );
    for(i=0; i < MAX_PALETTE_ENTRY_CNT; ++i)
    {
           sdev->palette_tbl[i].RGB.u8A = i;
    }
    sdev->num_entries = MAX_PALETTE_ENTRY_CNT;
    sdev->a8_palette = true;
    MApi_GFX_SetPaletteOpt(sdev->palette_tbl, 0, (sdev->num_entries-1));

    /*
     * Initialize I1/I2/I4 related palette.
     */
    sdev->num_intensity = 0x0;

    /*
    * Initialize hardware.
    */
    device_info->caps.accel    = DFXL_FILLRECTANGLE|DFXL_DRAWRECTANGLE|DFXL_DRAWLINE|DFXL_DRAWOVAL|DFXL_FILLTRAPEZOID|DFXL_BLIT|DFXL_STRETCHBLIT|DFXL_TRAPEZOID_BLIT;
    device_info->caps.blitting = sdrv->gfx_supported_bld_flags;
    device_info->caps.drawing  = sdrv->gfx_supported_draw_flags;
    /* Set device limitations. */
    if(dfb_config->bUsingHWTLB)
    {
        device_info->limits.surface_byteoffset_alignment = dfb_config->TLBAlignmentSize;
    }
    else
    {
        device_info->limits.surface_byteoffset_alignment = 64;
    }
    device_info->limits.surface_bytepitch_alignment  = 64;
    device_info->limits.surface_hegiht_alignment     = 16;


    //default the hwclip is enable
	//device_info->caps.flags |= CCF_CLIPPING;
	//device_info->caps.clip = DFXL_ALL;

    device_info->caps.flags &= ~CCF_CLIPPING;
    device_info->caps.clip = DFXL_STRETCHBLIT;
	sdev->b_hwclip = true;

	if(dfb_config->mst_disable_hwclip)
	{
		device_info->caps.flags &= ~CCF_CLIPPING;
		device_info->caps.clip = 0;
		sdev->b_hwclip = false;
	}



    mstar_init_device(device, driver_data, device_data);
    /* Initialize BEU lock. */
    fusion_skirmish_init( &sdev->beu_lock, "BEU", dfb_core_world(sdrv->core) );

    return DFB_OK;
}

static void
driver_close_device( CoreGraphicsDevice *device,
                     void               *driver_data,
                     void               *device_data )
{
     MSTARDeviceData *sdev = device_data;

     D_DEBUG_AT( MSTAR_G2_Driver, "%s()\n", __FUNCTION__ );
     //printf("\nDean %s\n", __FUNCTION__);

     /* Destroy BEU lock. */
     fusion_skirmish_destroy( &sdev->beu_lock );
}
void  mstarAllSurfInfo(MSTARDriverData *sdrv);
static void
driver_close_driver( CoreGraphicsDevice *device,
                     void               *driver_data )
{
     MSTARDriverData    *sdrv   = driver_data;

     D_DEBUG_AT( MSTAR_G2_Driver, "%s()\n", __FUNCTION__ );

     mstarAllSurfInfo(sdrv);
}


#define PIXEL_CHN_MASK(st, bits) (((1UL<<(bits))-1)<<(st))

#define PIXEL_CHN_VAL(pixel, st, bits)  ((((u32)pixel)&PIXEL_CHN_MASK(st, bits))>>(st))
#define PIXEL_CHN_NORMAL(pixel, st, bits)  (PIXEL_CHN_VAL(pixel, st, bits)<<(8-(bits)))

unsigned long
mstar_build_color(u32 pixel,  u8 a_st, u8  a_bits, u8  r_st, u8  r_bits,
                               u8  g_st, u8  g_bits, u8  b_st, u8  b_bits)
{
     u32 a, r, g, b;

     if(a_bits)
        a = PIXEL_CHN_NORMAL(pixel, a_st, a_bits);
     else
        a = 0;
     if(r_bits)
         r = PIXEL_CHN_NORMAL(pixel, r_st, r_bits);
     else
      r = 0;
     if(g_bits)
         g = PIXEL_CHN_NORMAL(pixel, g_st, g_bits);
     else
      g = 0;
     if(b_bits)
         b = PIXEL_CHN_NORMAL(pixel, b_st, b_bits);
     else
      b = 0;

     if(a_bits)
     {
        while(a_bits<8)
        {
            a = a| a>>a_bits;
            a_bits <<= 1;
        }
     }
     if(r_bits)
     {
         while(r_bits<8)
         {
             r = r| r>>r_bits;
            r_bits <<= 1;
         }
     }
     if(g_bits)
     {
          while(g_bits<8)
         {
             g = g| g>>g_bits;
             g_bits <<= 1;
         }
     }
     if(b_bits)
     {
         while(b_bits<8)
        {
             b = b| b>>b_bits;
            b_bits <<= 1;
         }
     }
     return a<<24 | r<<16 | g<<8| b;

}

unsigned long
    mstar_pixel_to_color( DFBSurfacePixelFormat  format,
                      unsigned long pixel, CorePalette *palette)
{
     u32 y, cb, cr,r,g,b;

     switch (format)
     {
          case DSPF_ARGB1555:
            return mstar_build_color(pixel, 15, 1, 10, 5, 5, 5, 0, 5);

          case DSPF_RGB16:
            return mstar_build_color(pixel, 16, 0, 11, 5, 5, 6, 0, 5);

          case DSPF_RGB555:
            return mstar_build_color(pixel, 15, 0, 10, 5, 5, 5, 0, 5);

          case DSPF_BGR555:
                return mstar_build_color(pixel, 15, 0, 0, 5, 5, 5, 10, 5);

          case DSPF_ARGB2554:
               return mstar_build_color(pixel, 14, 2, 9, 5, 4, 5, 0, 4);

          case DSPF_ARGB4444:
               return mstar_build_color(pixel, 12, 4, 8, 4, 4, 4, 0, 4);

          case DSPF_RGB444:
               return mstar_build_color(pixel, 12, 0, 8, 4, 4, 4, 0, 4);

          case DSPF_RGB24:
               return mstar_build_color(pixel, 24, 0, 16, 8, 8, 8, 0, 8);

          case DSPF_RGB32:
               return mstar_build_color(pixel, 24, 0, 16, 8, 8, 8, 0, 8);

          case DSPF_ARGB:
               return mstar_build_color(pixel, 24, 8, 16, 8, 8, 8, 0, 8);

          case DSPF_ABGR:
               return mstar_build_color(pixel, 24, 8, 0, 8, 8, 8, 16, 8);

          case DSPF_LUT8:
          case DSPF_LUT4:
          case DSPF_LUT2:
          case DSPF_LUT1:
               if( palette )
               {
                    if(pixel>=0 && pixel<=(DFB_BITS_PER_PIXEL(format)<<1UL)-1)
                       return  ((unsigned long)palette->entries[pixel].a)<<24|
                                ((unsigned long)palette->entries[pixel].r)<<16|
                                ((unsigned long)palette->entries[pixel].g)<<8|
                                palette->entries[pixel].b ;
               }

               break;

          case DSPF_YUY2:
               cb = (pixel>>24) & 0xFF;
               y  = (pixel>>16) & 0xFF;
               cr = (pixel>>8) & 0xFF;

               YCBCR_TO_RGB( y, cb, cr, r, g, b );
               return 0xFF<<24|r<<16|g<<8|b;
          case DSPF_YVYU:
               cr = (pixel>>24) & 0xFF;
               y  = (pixel>>16) & 0xFF;
               cb = (pixel>>8) & 0xFF;

               YCBCR_TO_RGB( y, cb, cr, r, g, b );
               return 0xFF<<24|r<<16|g<<8|b;
          case DSPF_UYVY:
               y = (pixel>>24) & 0xFF;
               cb  = (pixel>>16) & 0xFF;
               cr = (pixel) & 0xFF;

               YCBCR_TO_RGB( y, cb, cr, r, g, b );
               return 0xFF<<24|r<<16|g<<8|b;
          default:
               D_WARN( "unknown format 0x%08x", format );
               break;
     }

     return 0x55555555;
}
unsigned long mstar_pixel_to_colorkey(DFBSurfacePixelFormat  format,
                      unsigned long pixel, CorePalette *palette)
{
     switch (format)
     {
          case DSPF_LUT8:
          case DSPF_LUT4:
          case DSPF_LUT2:
          case DSPF_LUT1:
            if(pixel>=0 && pixel<=(1UL<<DFB_BITS_PER_PIXEL(format))-1)
                return pixel<<24|pixel<<16|pixel<<8|pixel;
            return 0;
          default:
            return mstar_pixel_to_color(format, pixel, palette);
     }
}
