//#ifdef MSTAR_DEBUG_LAYER
#define DIRECT_ENABLE_DEBUG
//#endif


#include <config.h>

#include <stdio.h>

#include <sys/mman.h>

#include <asm/types.h>

#include <directfb.h>

#include <fusion/fusion.h>
#include <fusion/shmalloc.h>

#include <core/core.h>
#include <core/coredefs.h>
#include <core/coretypes.h>
#include <core/layers.h>
#include <core/palette.h>
#include <core/surface.h>
#include <core/surface_buffer.h>
#include <core/system.h>
#include <core/layers_internal.h>

#include <gfx/convert.h>

#include <misc/conf.h>

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

#include <MsCommon.h>
#include  <apiGFX.h>
#include  <apiGOP.h>
//#include <apiGOP_v2.h>

#include <assert.h>

#include <drvXC_IOPort.h>
#include <drvTVEncoder.h>
#include <apiXC.h>
#include <apiPNL.h>
#include "mstar.h"
#include "mstar_types.h"
#include "mstar_layer.h"
#include <drvMVOP.h>

//#define MS_LAYER_DEFAULT_WIDTH 1360     //replace with dfb_config->mst_layer_default_width
//#define MS_LAYER_DEFAULT_HEIGHT 768      //replace with dfb_config->mst_layer_default_height

D_DEBUG_DOMAIN( MSTAR_Layer, "MSTAR/Layer", "MSTAR Layers" );


#define GOP_MIU_MASK 0x80000000

#define FRAME_PACKAGE_WIDTH_1920  1920
#define FRAME_PACKAGE_WIDTH_1280  1280
#define FRAME_PACKAGE_HEIGHT_1080 1080
#define FRAME_PACKAGE_HEIGHT_720  720
/**********************************************************************************************************************/

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_ColorFormat _mstarDFBFmt2MSFmt(DFBSurfacePixelFormat format)
{

     switch ( format )
     {
        case DSPF_ARGB1555:
               return E_MS_FMT_ARGB1555;
        case DSPF_ARGB :
               return E_MS_FMT_ARGB8888;
        case DSPF_LUT8 :
                 return E_MS_FMT_I8;
       case DSPF_ARGB4444 :
                 return E_MS_FMT_ARGB4444;
        case DSPF_RGB16:
               return E_MS_FMT_RGB565;

        case DSPF_AYUV:
               return E_MS_FMT_AYUV8888;
        case DSPF_YVYU:
               return E_MS_FMT_YUV422;
        case DSPF_UYVY:
               return E_MS_FMT_YUV422;
        case DSPF_YUY2:
               return E_MS_FMT_YUV422;
        
        default:
                 return E_MS_FMT_GENERIC;
       }
 }

static void  _mstarSetSurfInfoSlotFree(MSTARDriverData *sdrv, int slotID)
{
     D_ASSERT(sdrv && slotID>=0 && slotID<MSTARGFX_MAX_LAYER_BUFFER);
     sdrv->mstarLayerBuffer[slotID].u16SlotUsed  = 0;
     sdrv->mstarLayerBuffer[slotID].u8GWinID = 0xee;
     //printf("clear surf slot %d \n", slotID);
}
static void  _mstarFreeRelatedSurfInfo(MSTARDriverData *sdrv, CoreSurface *surf)
{
    int i;
    for( i=0; i<MSTARGFX_MAX_LAYER_BUFFER; i++)
        if(sdrv->mstarLayerBuffer[i].u16SlotUsed && sdrv->mstarLayerBuffer[i].pCoDFBCoreSurface==surf&&sdrv->mstarLayerBuffer[i].u8GWinID==0xee)
        {
            MApi_GOP_GWIN_DestroyFB( (u8)sdrv->mstarLayerBuffer[i].u16GOPFBID);

            _mstarSetSurfInfoSlotFree(sdrv, i);
        }
}

void  mstarAllSurfInfo(MSTARDriverData *sdrv)
{
    int i;
    for( i=0; i<MSTARGFX_MAX_LAYER_BUFFER; i++)
        if(sdrv->mstarLayerBuffer[i].u16SlotUsed)
        {
             MApi_GOP_GWIN_DestroyFB( (u8)sdrv->mstarLayerBuffer[i].u16GOPFBID);
            _mstarSetSurfInfoSlotFree(sdrv, i);
        }
}

static int _mstarGetFreeSurfInfoSlot(MSTARDriverData *sdrv)
{
    int i;
    for( i=0; i<MSTARGFX_MAX_LAYER_BUFFER; i++)
        if(sdrv->mstarLayerBuffer[i].u16SlotUsed == 0)
            return i;

    return -1;   

    
}


/*
#define _MApi_GOP_GWIN_CreateFBFrom3rdSurf(width, height,   fbFmt, u32FbAddr, pitch, ret_FBId)  \
({   \
    printf("################# _MApi_GOP_GWIN_CreateFBFrom3rdSurf, %s, %d ,pid=%d \n",__FUNCTION__,__LINE__,getpid());   \
    MApi_GOP_GWIN_CreateFBFrom3rdSurf(width, height,   fbFmt, u32FbAddr, pitch, ret_FBId);\
})


#define _MApi_GOP_GWIN_DestroyFB(fbId)  \
({   \
    printf("################# _MApi_GOP_GWIN_DestroyFB, %s, %d ,fbid = %d \n",__FUNCTION__,__LINE__,fbId);   \
    MApi_GOP_GWIN_DestroyFB(fbId);\
})
*/
static int _mstardumpsurinfoslot(MSTARDriverData *sdrv)
{
    int i;
    for( i=0; i<MSTARGFX_MAX_LAYER_BUFFER; i++)
        printf("~!~[i=%d], used=%d, fbid = %d,surface=%x,coDFBBuf=%x,phyaddr=%x,format=%x,gwinid=%x ,pid=%d \n"
        ,i,sdrv->mstarLayerBuffer[i].u16SlotUsed,sdrv->mstarLayerBuffer[i].u16GOPFBID,sdrv->mstarLayerBuffer[i].pCoDFBCoreSurface,
        sdrv->mstarLayerBuffer[i].pCoDFBBuffer,sdrv->mstarLayerBuffer[i].physAddr,sdrv->mstarLayerBuffer[i].format,sdrv->mstarLayerBuffer[i].u8GWinID,getpid());
    return 0;
}

static u8 _mstarFindFBIdbyGWinID(MSTARDriverData *sdrv,u8 u8GWindID,u16  *u16SlotID, CoreSurface **pSurface)
{
    int i;
    for( i=0; i<MSTARGFX_MAX_LAYER_BUFFER; i++)
    {
        if(sdrv->mstarLayerBuffer[i].u16SlotUsed && (sdrv->mstarLayerBuffer[i].u8GWinID == u8GWindID))
        {
            //printf("~!~ find FBID %d by GWinID%d ,index [%d]\n",sdrv->mstarLayerBuffer[i].u16GOPFBID,u8GWindID,i);
            *u16SlotID = i;
            *pSurface = sdrv->mstarLayerBuffer[i].pCoDFBCoreSurface;
            return sdrv->mstarLayerBuffer[i].u16GOPFBID;
        }
    }

    //_mstardumpsurinfoslot(sdrv);
    return 0xff;
}


static u8 _mstarFindFBIdbySurfacewithExcept(MSTARDriverData *sdrv,u8 u8GWindID,u16  *u16SlotID, CoreSurface *pSurface ,u16 *pExcept)
{
    int i;
    //printf("u8GWindID = %d \n",u8GWindID);
    for( i=0; i<MSTARGFX_MAX_LAYER_BUFFER; i++)
    {
        if(sdrv->mstarLayerBuffer[i].u16SlotUsed && (sdrv->mstarLayerBuffer[i].pCoDFBCoreSurface == pSurface))
        {
            //printf("~!~ find FBID %d by surface %x ,index [%d],u8GWindID=%d,sdrv->mstarLayerBuffer[i].u8GWinID= %d\n",
            //sdrv->mstarLayerBuffer[i].u16GOPFBID,sdrv->mstarLayerBuffer[i].pCoDFBCoreSurface,i,u8GWindID,sdrv->mstarLayerBuffer[i].u8GWinID);

            if(u8GWindID != sdrv->mstarLayerBuffer[i].u8GWinID)
            {
                if(sdrv->mstarLayerBuffer[i].u8GWinID != 0xee)
                    continue;
            }
            //D_ASSERT(u8GWindID == sdrv->mstarLayerBuffer[i].u8GWinID);
            *u16SlotID = i;
            if(pExcept)
            {
                if(*pExcept == sdrv->mstarLayerBuffer[i].u16GOPFBID)
                    continue;
            }
            return sdrv->mstarLayerBuffer[i].u16GOPFBID;
        }
    }

    return 0xff;
}


static u8 _mstarFindFBIdbySurface(MSTARDriverData *sdrv,u8 u8GWindID,u16  *u16SlotID, CoreSurface *pSurface)
{
    int i;
   // printf("u8GWindID = %d \n",u8GWindID);
    for( i=0; i<MSTARGFX_MAX_LAYER_BUFFER; i++)
    {
        if(sdrv->mstarLayerBuffer[i].u16SlotUsed && (sdrv->mstarLayerBuffer[i].pCoDFBCoreSurface == pSurface))
        {
            //printf("~!~ find FBID %d by surface %x ,index [%d],u8GWindID=%d,sdrv->mstarLayerBuffer[i].u8GWinID= %d\n",
            //sdrv->mstarLayerBuffer[i].u16GOPFBID,sdrv->mstarLayerBuffer[i].pCoDFBCoreSurface,i,u8GWindID,sdrv->mstarLayerBuffer[i].u8GWinID);

            if(u8GWindID != sdrv->mstarLayerBuffer[i].u8GWinID)
            {
                if(sdrv->mstarLayerBuffer[i].u8GWinID != 0xee)
                    continue;
            }
            //D_ASSERT(u8GWindID == sdrv->mstarLayerBuffer[i].u8GWinID);
            *u16SlotID = i;
            return sdrv->mstarLayerBuffer[i].u16GOPFBID;
        }
    }

    return 0xff;
}

static void _mstarSetSlotGWinID(MSTARDriverData *sdrv, int slotID,  u8 u8GWinID)
{
    sdrv->mstarLayerBuffer[slotID].u16SlotUsed = 1;
    sdrv->mstarLayerBuffer[slotID].u8GWinID = u8GWinID;
}


static void _mstarSetSurfInfoSlot(MSTARDriverData *sdrv, int slotID,  u16 u16FBID,
                                                                               CoreSurface *surf, CoreSurfaceBuffer *buffer, unsigned long physAddr,unsigned long pitch)
{
    D_ASSERT(sdrv && slotID>=0 && slotID<MSTARGFX_MAX_LAYER_BUFFER);
    sdrv->mstarLayerBuffer[slotID].u16GOPFBID  = u16FBID;
    sdrv->mstarLayerBuffer[slotID].pCoDFBCoreSurface  = surf;
    sdrv->mstarLayerBuffer[slotID].pCoDFBBuffer  = buffer;
    sdrv->mstarLayerBuffer[slotID].physAddr = physAddr;
    sdrv->mstarLayerBuffer[slotID].format = surf->config.format;
    sdrv->mstarLayerBuffer[slotID].u16SlotUsed  = 1;
    sdrv->mstarLayerBuffer[slotID].pitch = pitch;
    //printf("neohe debug set surf slot %d physical to %08x, surface %08x, buffer%08x\n", slotID, physAddr, surf, buffer);
}

static int _mstarGetSurfInfoSlot(MSTARDriverData *sdrv, MSTARLayerData   *slay,CoreSurface *surf, CoreSurfaceBuffer *buffer,
                                                            unsigned long  phys, unsigned long pitch, u16 *pFBId, bool *bNew)                                                            


{
    u8 u8GOP_Ret, u8FBId;
    int i=0;

    //check whether the buffer has been assigned the bufferslot and fbid
    for(i=0; i<MSTARGFX_MAX_LAYER_BUFFER; i++)
    {
        if(sdrv->mstarLayerBuffer[i].u16SlotUsed 
            && sdrv->mstarLayerBuffer[i].pCoDFBBuffer==buffer
            && sdrv->mstarLayerBuffer[i].pCoDFBCoreSurface == surf
            && sdrv->mstarLayerBuffer[i].format == surf->config.format
            && sdrv->mstarLayerBuffer[i].pitch == pitch
            && sdrv->mstarLayerBuffer[i].physAddr==phys)
        {
            if(pFBId)
            {
                *pFBId = sdrv->mstarLayerBuffer[i].u16GOPFBID;
            }
            *bNew = false;            
            return i;
           
        }
        
    }

     //create the new fbid and assign the new bufferslot

     i=_mstarGetFreeSurfInfoSlot(sdrv);

     D_ASSERT((i>=0)&&(i<MSTARGFX_MAX_LAYER_BUFFER));

     u8GOP_Ret = MApi_GOP_GWIN_CreateFBFrom3rdSurf(surf->config.size.w, surf->config.size.h,
                               _mstarDFBFmt2MSFmt(surf->config.format),    phys, pitch, &u8FBId);
     if(GWIN_OK != u8GOP_Ret)
     {
           printf("    Serious warning, create FB for allocation Failed(%d), free slot %d!!!\n", u8GOP_Ret, i);
           _mstarSetSurfInfoSlotFree(sdrv, i);
           return -1;
     }
    DBG_LAYER_MSG("MApi_GOP_GWIN_CreateFBFrom3rdSurf: width=%d, height=%d, pitch=%d, fbid =%d\n ", 
                    surf->config.size.w, surf->config.size.h,pitch ,u8FBId );

     
     _mstarSetSurfInfoSlot(sdrv, i,  u8FBId, surf, buffer, phys,pitch);
   
     
     if(pFBId)
    {
        *pFBId = sdrv->mstarLayerBuffer[i].u16GOPFBID;
    }
     *bNew = true;
     return i;
 
}



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);
    }
}

static int gfx_GOPStretch(MS_U8 gop, MS_U8 gop_dest,MS_U16 srcWidth, MS_U16 srcHeight, MS_U16 dstWidth, MS_U16 dstHeight, MS_U16 start_x, MS_U16 start_y )
{


    MApi_GOP_GWIN_SwitchGOP(gop);
    /* GOP stretch setting */
    MApi_GOP_GWIN_Set_HSCALE(TRUE, srcWidth, dstWidth);
    MApi_GOP_GWIN_Set_VSCALE(TRUE, srcHeight, dstHeight);
    MApi_GOP_GWIN_Set_STRETCHWIN(gop, gop_dest, start_x, start_y, srcWidth, srcHeight);
    if (gop_dest == E_GOP_DST_OP0)
        MApi_GOP_SetGOPHStart(gop, mstar_sc_get_h_cap_start());
    

    return 0;
}

static int
mstarLayerDataSize()
{
     D_DEBUG_AT(MSTAR_Layer, "%s\n", __FUNCTION__);
     return sizeof(MSTARLayerData);
}

static int
mstarRegionDataSize()
{
     D_DEBUG_AT(MSTAR_Layer, "%s\n", __FUNCTION__);
     return sizeof(MSTARRegionData);
}

static DFBResult
mstarInitLayer( CoreLayer                  *layer,
                 void                       *driver_data,
                 void                       *layer_data,
                 DFBDisplayLayerDescription *description,
                 DFBDisplayLayerConfig      *config,
                 DFBColorAdjustment         *adjustment )
{
     MSTARDriverData *sdrv = driver_data;
     MSTARDeviceData *sdev = sdrv->dev;
     MSTARLayerData  *data = layer_data;
     u8 i;
     u8  curGopIndex;
     CoreDFB *core = layer->core;

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

     /* initialize layer data */

     for( i=0; i<MSTAR_MAX_OUTPUT_LAYER_COUNT; i++)
     {
          char  buf[24];
          if(layer == sdrv->layers[i])
          {
                 data->layer_index = i;
#if MSTAR_MULTI_GOP_SUPPORT
                 //the gopindex should be required form the dfbconfig
                 data->gop_index   = dfb_config->mst_gop_available[i];
                 data->gop_index_r = dfb_config->mst_gop_available_r[i];
                 data->gop_dst     = dfb_config->mst_gop_dstPlane[i];
                 data->layer_displayMode = DLDM_NORMAL;
                 data->GopDstMode = dfb_config->mst_gop_dstPlane[i];
#else
                 data->gop_index   = 0;
                 data->gop_dst     = E_GOP_DST_OP0;
#endif
                 sdev->layer_zorder[i]  = 1;
                 sdev->layer_active[i] = false;
                 sdev->layer_gwin_id[i] = INVALID_WIN_ID;
                 sdev->layer_gwin_id_r[i] = INVALID_WIN_ID;
                //init fusion & reactor
                snprintf( buf, sizeof(buf), "Core Layer %d", i );
                /* create reactor */
                data->reactor = fusion_reactor_new( sizeof(CoreLayerEvent), buf, dfb_core_world(core) );

                /* init call */
                fusion_call_init( &data->call, mstar_layer_funcs_call_handler, layer, dfb_core_world(core) );
                 break;
          }

     }

     D_ASSERT(i<MSTAR_MAX_OUTPUT_LAYER_COUNT);

     D_DEBUG_AT(MSTAR_Layer, "%s: data->layer: %d\n", __FUNCTION__, data->layer_index);

     for( i=0; i<MSTARGFX_MAX_LAYER_BUFFER; i++)
     {
        memset(&sdrv->mstarLayerBuffer[i],0,sizeof(sdrv->mstarLayerBuffer[i]));
        sdrv->mstarLayerBuffer[i].u8GWinID = 0xee;
     }


     /* set capabilities and type */
     description->caps = DLCAPS_SURFACE | DLCAPS_ALPHACHANNEL | DLCAPS_OPACITY  | DLCAPS_SRC_COLORKEY|
                                                                DLCAPS_LEVELS|DLCAPS_SCREEN_LOCATION;

     description->type = DLTF_STILL_PICTURE | DLTF_GRAPHICS | DLTF_VIDEO;

     /* set name */
     snprintf( description->name, DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, "Input %d", sdrv->num_inputs );

     /* fill out the default configuration */
     config->flags       = DLCONF_WIDTH       | DLCONF_HEIGHT |
                           DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | DLCONF_OPTIONS;
    // config->width       = MS_LAYER_DEFAULT_WIDTH;//MSTAR MAX GFX WIDTH;
   //  config->height      = MS_LAYER_DEFAULT_HEIGHT;//MSTAR MAX GFX HEIGHT;
     config->pixelformat = DSPF_ARGB;
     config->buffermode  = DLBM_BACKVIDEO;
     config->options     = DLOP_ALPHACHANNEL;
	 config->btile_mode  = false;
     
     curGopIndex = MApi_GOP_GWIN_GetCurrentGOP();
     if(curGopIndex != data->gop_index)
        MApi_GOP_GWIN_SwitchGOP(data->gop_index);

     if((data->gop_dst == E_GOP_DST_OP0)||(data->gop_dst == E_GOP_DST_MIXER2OP)||(data->gop_dst == E_GOP_DST_BYPASS))
     {
           MS_PNL_DST_DispInfo dstDispInfo;
           MApi_PNL_GetDstInfo(&dstDispInfo, sizeof(MS_PNL_DST_DispInfo));
           if(dstDispInfo.bYUVOutput)
           {
                MApi_GOP_GWIN_OutputColor(GOPOUT_YUV);
           }
           else
           {
                if(dfb_config->mst_GOP_Set_YUV)
                    MApi_GOP_GWIN_OutputColor(GOPOUT_YUV);
                else
                    MApi_GOP_GWIN_OutputColor(GOPOUT_RGB);
           }
           
           if(data->gop_index_r!=0xf) //switch gop_r
            {
                MApi_GOP_GWIN_SwitchGOP(data->gop_index_r);
                if(dstDispInfo.bYUVOutput)
                {
                    MApi_GOP_GWIN_OutputColor(GOPOUT_YUV);
                }
                else
                {
                    if(dfb_config->mst_GOP_Set_YUV)
                        MApi_GOP_GWIN_OutputColor(GOPOUT_YUV);
                    else
                        MApi_GOP_GWIN_OutputColor(GOPOUT_RGB);
                }
                MApi_GOP_GWIN_SwitchGOP(data->gop_index);
            }

           config->width  = dstDispInfo.DEHEND - dstDispInfo.DEHST + 1;
           config->height = dstDispInfo.DEVEND - dstDispInfo.DEVST + 1;
           data->screen_size.width  = sdev->layer_screen_size[data->layer_index].width = config->width;
           data->screen_size.height = sdev->layer_screen_size[data->layer_index].height= config->height;
           data->screen_size.Hstart = sdev->layer_screen_size[data->layer_index].Hstart= 0;
           data->screen_size.Vstart = sdev->layer_screen_size[data->layer_index].Vstart= 0;

           if(sdev->gfx_max_width <= config->width)
           {
                config->width = sdev->gfx_max_width;
           }

           if(sdev->gfx_max_height <= config->height)
           {
                config->height = sdev->gfx_max_height;
           }
      /*
           printf("\nthe dst is OP\n");
           printf("\nthe dstDispInfo.HDTOT: %d\n",dstDispInfo.HDTOT);
           printf("\nthe dstDispInfo.VDTOT:%d\n",dstDispInfo.VDTOT);
           printf("\nthe dstDispInfo.DEHST:%d\n",dstDispInfo.DEHST);
           printf("\nthe dstDispInfo.DEHEND:%d\n",dstDispInfo.DEHEND);
           printf("\nthe dstDispInfo.DEVST:%d\n",dstDispInfo.DEVST);
           printf("\nthe dstDispInfo.DEVEND:%d\n",dstDispInfo.DEVEND);
           printf("\nthe dstDispInfo.bYUVOutput:%d\n",dstDispInfo.bYUVOutput);
      */

     }
     else if((data->gop_dst == E_GOP_DST_MIXER2VE) || (data->gop_dst == E_GOP_DST_VE))
     {

       //printf("\nbefore the MApi_VE_GetDstInfo\n");
       MS_VE_DST_DispInfo dstDispInfo;
       MApi_VE_GetDstInfo(&dstDispInfo,sizeof(MS_VE_DST_DispInfo));


       config->width  = dstDispInfo.DEHEND - dstDispInfo.DEHST + 1;
       config->height = dstDispInfo.DEVEND - dstDispInfo.DEVST + 1;
       data->screen_size.width  = sdev->layer_screen_size[data->layer_index].width  = config->width;
       data->screen_size.height = sdev->layer_screen_size[data->layer_index].height = config->height;
       data->screen_size.Hstart = sdev->layer_screen_size[data->layer_index].Hstart = dstDispInfo.DEHST;
       data->screen_size.Vstart = sdev->layer_screen_size[data->layer_index].Vstart = dstDispInfo.DEVST;

/*
       printf("\nthe layer data is%x\n",data);
       printf("\nafter MApi_VE_GetDstInfo\n");
       printf("\nthe dstDispInfo.bInterfaceMode is %d \n",dstDispInfo.bInterlaceMode);
       printf("\nthe dstDispInfo.HDTOT: %d\n",dstDispInfo.HDTOT);
       printf("\nthe dstDispInfo.VDTOT:%d\n",dstDispInfo.VDTOT);
       printf("\nthe dstDispInfo.DEHST:%d\n",dstDispInfo.DEHST);
       printf("\nthe dstDispInfo.DEHEND:%d\n",dstDispInfo.DEHEND);
       printf("\nthe dstDispInfo.DEVST:%d\n",dstDispInfo.DEVST);
       printf("\nthe dstDispInfo.DEVEND:%d\n",dstDispInfo.DEVEND);
*/

     }
     else if(data->gop_dst == E_GOP_DST_IP0)
     {
        //Default use the the 64*64 resolution
       config->options     =  DLOP_ALPHACHANNEL;
       config->width       = 64;
       config->height      = 64;
       data->screen_size.width  = sdev->layer_screen_size[data->layer_index].width  = config->width;
       data->screen_size.height = sdev->layer_screen_size[data->layer_index].height = config->height;
       data->screen_size.Hstart = sdev->layer_screen_size[data->layer_index].Hstart = 0;
       data->screen_size.Vstart = sdev->layer_screen_size[data->layer_index].Vstart = 0;

     }
     else if(data->gop_dst == E_GOP_DST_FRC)
     {
	   MS_OSDC_DST_DispInfo dstDispInfo;
	   memset(&dstDispInfo,0,sizeof(MS_OSDC_DST_DispInfo));
       dstDispInfo.ODSC_DISPInfo_Version = ODSC_DISPINFO_VERSIN;
	   MApi_XC_OSDC_GetDstInfo(&dstDispInfo,sizeof(MS_OSDC_DST_DispInfo));
       config->width       = dstDispInfo.DEHEND - dstDispInfo.DEHST + 1;
       config->height      = dstDispInfo.DEVEND - dstDispInfo.DEVST + 1;
       data->screen_size.width  = sdev->layer_screen_size[data->layer_index].width  = config->width;
       data->screen_size.height = sdev->layer_screen_size[data->layer_index].height = config->height;
       data->screen_size.Hstart = sdev->layer_screen_size[data->layer_index].Hstart = 0;
       data->screen_size.Vstart = sdev->layer_screen_size[data->layer_index].Vstart = 0;
     }
     else if(data->gop_dst == E_GOP_DST_IP1)
     {
        //Default use the the 64*64 resolution
       config->options     =  DLOP_ALPHACHANNEL;
       config->width       = 64;
       config->height      = 64;
       data->screen_size.width  = sdev->layer_screen_size[data->layer_index].width  = config->width;
       data->screen_size.height = sdev->layer_screen_size[data->layer_index].height = config->height;
       data->screen_size.Hstart = sdev->layer_screen_size[data->layer_index].Hstart = 0;
       data->screen_size.Vstart = sdev->layer_screen_size[data->layer_index].Vstart = 0;

     }

     if(config->width > dfb_config->mst_layer_default_width && dfb_config->mst_layer_default_width > 0)
          config->width = dfb_config->mst_layer_default_width;
     if(config->height > dfb_config->mst_layer_default_height && dfb_config->mst_layer_default_height > 0)
          config->height = dfb_config->mst_layer_default_height;

     
     adjustment->flags = DCAF_BRIGHTNESS;
     return DFB_OK;
}

#if MSTAR_MULTI_GOP_SUPPORT
static DFBResult mstarReorderGWIN(MSTARDriverData           *sdrv)
{
     return DFB_OK;
}
#else
static DFBResult mstarReorderGWIN(MSTARDriverData           *sdrv)
{
     MSTARDeviceData           *sdev = sdrv->dev;
     u8  gwinId[MSTAR_MAX_OUTPUT_LAYER_COUNT];
     int  gwinzlevel[MSTAR_MAX_OUTPUT_LAYER_COUNT];
     u8  gwinCnt = 0;
     u8 i, j, k;
      for( i=0; i<MSTAR_MAX_OUTPUT_LAYER_COUNT; i++)
     {
          if(false == sdev->layer_active[i])
                continue;
          for(j=0; j<gwinCnt; j++)
          {
              if(gwinzlevel[j]<sdev->layer_zorder[i])
                break;
          }
          k=gwinCnt;
          while(k>j)
          {
               gwinId[k] = gwinId[k-1];
               gwinzlevel[k] = gwinzlevel[k-1];
               k--;
          }
          gwinzlevel[j] = sdev->layer_zorder[i];
          gwinId[j] = sdev->layer_gwin_id[i];
          gwinCnt++;
     }
     if(gwinCnt > 1)
     {
         GOP_GwinPri gwinPri;
         gwinPri.u8GwinNum = gwinCnt;
         for( i=0; i<gwinCnt; i++)
            gwinPri.u8GwinPri[i] = gwinId[i];
         MApi_GOP_GWIN_SetRelativeWinPrio(sdev->gfx_gop_index, &gwinPri);

     }
     return DFB_OK;
}
#endif
static DFBResult
_mstarTestRegion( CoreLayer                  *layer,
                  void                       *driver_data,
                  void                       *layer_data,
                  CoreLayerRegionConfig      *config,
                  CoreLayerRegionConfigFlags *failed )
{
     MSTARDriverData           *sdrv = driver_data;
     MSTARDeviceData           *sdev = sdrv->dev;
     MSTARLayerData            *slay = layer_data;
     CoreLayerRegionConfigFlags  fail = 0;
     u8  curGopIndex;

     DBG_LAYER_MSG("%s --> %d, GOPDST:%d\n", __FUNCTION__, __LINE__ , slay->gop_dst);


// Ip path special ,because OP ve path should can get the valid value in mstarInitlayer

     curGopIndex = MApi_GOP_GWIN_GetCurrentGOP();
     if(curGopIndex != slay->gop_index)
        MApi_GOP_GWIN_SwitchGOP(slay->gop_index);

     if(slay->gop_dst == E_GOP_DST_IP0 || slay->gop_dst == E_GOP_DST_IP1)
     {
         MS_XC_DST_DispInfo dstDispInfo;
         u32 width=0;
         u32 height=0;
        if(MApi_XC_GetDstInfo(&dstDispInfo,sizeof(MS_XC_DST_DispInfo),E_GOP_XCDST_IP1_MAIN))
        {
            width  = dstDispInfo.DEHEND - dstDispInfo.DEHST + 1;
            height = dstDispInfo.DEVEND - dstDispInfo.DEVST + 1;

            slay->screen_size.width  = sdev->layer_screen_size[slay->layer_index].width  = width;
            slay->screen_size.height = sdev->layer_screen_size[slay->layer_index].height = height;
            slay->screen_size.Hstart = sdev->layer_screen_size[slay->layer_index].Hstart = dstDispInfo.DEHST;
            slay->screen_size.Vstart = sdev->layer_screen_size[slay->layer_index].Vstart = dstDispInfo.DEVST;
            if(dstDispInfo.bYUVInput)
            {
                MApi_GOP_GWIN_OutputColor(GOPOUT_YUV);
            }
            else
            {
                MApi_GOP_GWIN_OutputColor(GOPOUT_RGB);
            }
        }

     }
     else if(slay->gop_dst == E_GOP_DST_MIXER2VE || slay->gop_dst == E_GOP_DST_VE)
     {

       //printf("\nbefore the MApi_VE_GetDstInfo\n");
       MS_VE_DST_DispInfo dstDispInfo;
       u32 width=0;
       u32 height=0;
       MApi_VE_GetDstInfo(&dstDispInfo,sizeof(MS_VE_DST_DispInfo));
       width  = dstDispInfo.DEHEND - dstDispInfo.DEHST + 1;
       height = dstDispInfo.DEVEND - dstDispInfo.DEVST + 1;

       slay->screen_size.width  = sdev->layer_screen_size[slay->layer_index].width  = width;
       slay->screen_size.height = sdev->layer_screen_size[slay->layer_index].height = height;
       slay->screen_size.Hstart = sdev->layer_screen_size[slay->layer_index].Hstart = dstDispInfo.DEHST;
       slay->screen_size.Vstart = sdev->layer_screen_size[slay->layer_index].Vstart = dstDispInfo.DEVST;
       if( config->width > slay->screen_size.width )
           config->width = slay->screen_size.width;
       if( config->height > slay->screen_size.height )
           config->height = slay->screen_size.height;

/*
       printf("\nthe layer data is%x\n",data);
       printf("\nafter MApi_VE_GetDstInfo\n");
       printf("\nthe dstDispInfo.bInterfaceMode is %d \n",dstDispInfo.bInterlaceMode);
       printf("\nthe dstDispInfo.HDTOT: %d\n",dstDispInfo.HDTOT);
       printf("\nthe dstDispInfo.VDTOT:%d\n",dstDispInfo.VDTOT);
       printf("\nthe dstDispInfo.DEHST:%d\n",dstDispInfo.DEHST);
       printf("\nthe dstDispInfo.DEHEND:%d\n",dstDispInfo.DEHEND);
       printf("\nthe dstDispInfo.DEVST:%d\n",dstDispInfo.DEVST);
       printf("\nthe dstDispInfo.DEVEND:%d\n",dstDispInfo.DEVEND);
*/

     }
     else if((slay->gop_dst == E_GOP_DST_OP0)||(slay->gop_dst == E_GOP_DST_BYPASS))
     {
         MS_PNL_DST_DispInfo dstDispInfo;
         MApi_PNL_GetDstInfo(&dstDispInfo, sizeof(MS_PNL_DST_DispInfo));

         int width = 0;
         int height = 0;

         width  = dstDispInfo.DEHEND - dstDispInfo.DEHST + 1;
         height = dstDispInfo.DEVEND - dstDispInfo.DEVST + 1;

         slay->screen_size.width  = sdev->layer_screen_size[slay->layer_index].width = width;
         slay->screen_size.height = sdev->layer_screen_size[slay->layer_index].height=height;
         slay->screen_size.Hstart = sdev->layer_screen_size[slay->layer_index].Hstart= dstDispInfo.DEHST;
         slay->screen_size.Vstart = sdev->layer_screen_size[slay->layer_index].Vstart= dstDispInfo.DEVST;

         if( config->width > slay->screen_size.width )
             config->width = slay->screen_size.width;

         if( config->height > slay->screen_size.height )
             config->height = slay->screen_size.height;

         if(dstDispInfo.bYUVOutput)
         {
             MApi_GOP_GWIN_OutputColor(GOPOUT_YUV);
         }
         else
         {
             if(dfb_config->mst_GOP_Set_YUV)
             {
                 MApi_GOP_GWIN_OutputColor(GOPOUT_YUV);
             }
             else
             {
                 MApi_GOP_GWIN_OutputColor(GOPOUT_RGB);
             }
         }
         
         if(slay->gop_index_r!= 0xf)
        {
             MApi_GOP_GWIN_SwitchGOP(slay->gop_index_r);
             if(dstDispInfo.bYUVOutput)
             {
                 MApi_GOP_GWIN_OutputColor(GOPOUT_YUV);
             }
             else
             {
                 if(dfb_config->mst_GOP_Set_YUV)
                 {
                     MApi_GOP_GWIN_OutputColor(GOPOUT_YUV);
                 }
                 else
                 {
                     MApi_GOP_GWIN_OutputColor(GOPOUT_RGB);
                 }
             }
             MApi_GOP_GWIN_SwitchGOP(slay->gop_index);
        }
    }
     else if( slay->gop_dst == E_GOP_DST_FRC)
    {
       int width = 0;
       int height= 0;
       MS_OSDC_DST_DispInfo dstDispInfo;
       memset(&dstDispInfo,0,sizeof(MS_OSDC_DST_DispInfo));
       dstDispInfo.ODSC_DISPInfo_Version = ODSC_DISPINFO_VERSIN;
       MApi_XC_OSDC_GetDstInfo(&dstDispInfo,sizeof(MS_OSDC_DST_DispInfo));
       width       = dstDispInfo.DEHEND - dstDispInfo.DEHST + 1;
       height      = dstDispInfo.DEVEND - dstDispInfo.DEVST + 1;   
       slay->screen_size.width  = sdev->layer_screen_size[slay->layer_index].width = width;
       slay->screen_size.height = sdev->layer_screen_size[slay->layer_index].height=height;

       if( config->width > slay->screen_size.width )
             config->width = slay->screen_size.width;

       if( config->height > slay->screen_size.height )
             config->height = slay->screen_size.height;

     }
        

    if(curGopIndex != slay->gop_index)
    MApi_GOP_GWIN_SwitchGOP(curGopIndex);

#if MSTAR_MULTI_GOP_SUPPORT
     //sdev->gfx_max_height= slay->screen_size.height;
     //sdev->gfx_max_width = slay->screen_size.width ;
#endif



     if (config->options & ~MSTAR_LAYER_SUPPORTED_OPTIONS){
          fail |= CLRCF_OPTIONS;
          printf("\nDean %s --> %d\n", __FUNCTION__, __LINE__);
     }

     // TODO: Currently, we only implement I8, ARGB8888 and ARGB1555
     switch (config->format) {
          case DSPF_LUT8:
          case DSPF_ARGB:
          case DSPF_ARGB1555:
          case DSPF_ARGB4444:
          case DSPF_RGB16:

          case DSPF_YVYU:
          case DSPF_AYUV:
          case DSPF_UYVY:
          case DSPF_YUY2:
               break;
          default:
               fail |= CLRCF_FORMAT;
     }

    DBG_LAYER_MSG("slayer->gop_dst:%x\n",slay->gop_dst);
    DBG_LAYER_MSG("%s (%d) config->width=%d config->height=%d\n", __FUNCTION__, __LINE__, config->width, config->height);

    DBG_LAYER_MSG("%s (%d) config->dest.x: %d config->dest.y=%d\n", __FUNCTION__, __LINE__, config->dest.x, config->dest.y);
    DBG_LAYER_MSG("%s (%d) config->dest.w: %d config->dest.h=%d\n", __FUNCTION__, __LINE__, config->dest.w, config->dest.h);

    if (config->width  < 32 || config->width  > slay->screen_size.width)
          fail |= CLRCF_WIDTH;

     if (config->height < 32 || config->height > slay->screen_size.height)
          fail |= CLRCF_HEIGHT;

     if(slay->gop_dst == E_GOP_DST_OP0)
     {
       if (config->dest.x >= sdev->lcd_width || config->dest.y >= sdev->lcd_height)
            fail |= CLRCF_DEST;
       if(config->dest.x+config->dest.w >sdev->lcd_width||  config->dest.y+config->dest.h > sdev->lcd_height)
            fail |= CLRCF_DEST;
  
        DBG_LAYER_MSG("%s (%d) sdev->lcd_width: %d, sdev->lcd_height: %d\n", __FUNCTION__, __LINE__, sdev->lcd_width, sdev->lcd_height);
     }
     else
     {
       if (config->dest.x >= slay->screen_size.width || config->dest.y >= slay->screen_size.height)
            fail |= CLRCF_DEST;
       if(config->dest.x+config->dest.w >slay->screen_size.width||  config->dest.y+config->dest.h > slay->screen_size.height)
            fail |= CLRCF_DEST;
        DBG_LAYER_MSG("%s (%d) sdev->screen_size.w: %d, sdev->screen_size.h: %d\n", __FUNCTION__, __LINE__,slay->screen_size.width, slay->screen_size.height);
     }




     if(config->options & (DLOP_DST_COLORKEY|DLOP_FLICKER_FILTERING))
        fail |= CLRCF_OPTIONS;

     if((config->options&(DLOP_ALPHACHANNEL|DLOP_OPACITY)) == (DLOP_ALPHACHANNEL|DLOP_OPACITY))
     {
        //we can't support both of them.
        fail |= CLRCF_OPTIONS;
     }
     if(config->options&(DLOP_DEINTERLACING|DLOP_FIELD_PARITY))
        fail |= CLRCF_OPTIONS;

     if(config->num_clips > 0)
        fail |= CLRCF_CLIPS;

     if (failed)
          *failed = fail;

     if (fail)
    {
        DBG_LAYER_MSG("%s (%d) fail: 0x%x\n", __FUNCTION__, __LINE__, fail);
        return DFB_UNSUPPORTED;
    }
     DBG_LAYER_MSG( "%s  (%d)\n", __FUNCTION__, __LINE__);
     return DFB_OK;
}

static DFBResult
mstarTestRegion( CoreLayer                  *layer,
                  void                       *driver_data,
                  void                       *layer_data,
                  CoreLayerRegionConfig      *config,
                  CoreLayerRegionConfigFlags *failed )
{
    MSTARLayerData  *slay = layer_data;
    CoreLayerCallParameter *parameter;
    FusionSHMPoolShared *shm_pool;
    int ret;

    shm_pool = dfb_core_shmpool_data(layer->core);
    D_ASSERT(shm_pool);

    parameter = SHMALLOC(shm_pool, sizeof(*parameter));
    if(!parameter)
       return DFB_NOSHAREDMEMORY;

    memcpy(&parameter->config,config,sizeof(*config));
    if(failed)
        memcpy(&parameter->flags,failed,sizeof(*failed));
    if (fusion_call_execute( &slay->call, FCEF_NONE, CLC_TEST_REGION, parameter, &ret ))
    {
        SHFREE(shm_pool, parameter);
        return DFB_FUSION;
    }
    memcpy(config,&parameter->config,sizeof(*config));
    if(failed)
        memcpy(failed,&parameter->flags,sizeof(*failed));

    SHFREE(shm_pool, parameter);

    return ret;
}

static DFBResult
_mstarAddRegion( CoreLayer             *layer,
                 void                  *driver_data,
                 void                  *layer_data,
                 void                  *region_data,
                 CoreLayerRegionConfig *config )
{
     MSTARRegionData *sreg = region_data;
     MSTARDriverData *sdrv = driver_data;
     MSTARDeviceData *sdev = sdrv->dev;
     MSTARLayerData  *slay = layer_data;
     D_DEBUG_AT( MSTAR_Layer, "%s()\n", __FUNCTION__ );

     D_MAGIC_SET( sreg, MSTARRegionData );
     sreg->config = *config;
     sreg->config_dirtyFlag = CLRCF_ALL;
     sdev->layer_refcnt[slay->layer_index]++;
     return DFB_OK;
}

static DFBResult
mstarAddRegion( CoreLayer             *layer,
                 void                  *driver_data,
                 void                  *layer_data,
                 void                  *region_data,
                 CoreLayerRegionConfig *config )
{
        MSTARLayerData  *slay = layer_data;
        CoreLayerCallParameter *parameter;
        FusionSHMPoolShared *shm_pool;
        int ret;

        shm_pool = dfb_core_shmpool_data(layer->core);
        D_ASSERT(shm_pool);
        parameter = SHMALLOC(shm_pool, sizeof(*parameter));

        if(!parameter)
           return DFB_NOSHAREDMEMORY;

        parameter->reg_data = region_data;
        memcpy(&parameter->config,config,sizeof(*config));
        if (fusion_call_execute( &slay->call, FCEF_NONE, CLC_ADD_REGION, parameter, &ret ))
        {
            SHFREE(shm_pool, parameter);
            return DFB_FUSION;
        }
        memcpy(config,&parameter->config,sizeof(*config));
        SHFREE(shm_pool, parameter);
        return ret;
}

static inline CoreLayerRegionConfigFlags mstarBuildUpdate( MSTARRegionData *sreg,    CoreLayerRegionConfig      *config,
                                                                                        CoreLayerRegionConfigFlags  updated)
{
     CoreLayerRegionConfigFlags retUpdated = CLRCF_NONE;


    if((updated&CLRCF_WIDTH) && sreg->config.width != config->width)
    {
        retUpdated |= CLRCF_WIDTH;
       sreg->config.width = config->width;
    }
    if((updated&CLRCF_HEIGHT) && sreg->config.height != config->height)
    {
        retUpdated |= CLRCF_HEIGHT;
       sreg->config.height = config->height;
    }
    if((updated&CLRCF_FORMAT) && sreg->config.format != config->format)
    {
        retUpdated |= CLRCF_FORMAT;
       sreg->config.format = config->format;
    }
    if((updated&CLRCF_SURFACE_CAPS) && sreg->config.surface_caps != config->surface_caps)
    {
        retUpdated |= CLRCF_SURFACE_CAPS;
       sreg->config.surface_caps = config->surface_caps;
    }
    if((updated&CLRCF_BUFFERMODE) && sreg->config.buffermode != config->buffermode)
    {
        retUpdated |= CLRCF_BUFFERMODE;
       sreg->config.buffermode = config->buffermode;
    }
    if((updated&CLRCF_OPTIONS) && sreg->config.options != config->options)
    {
        retUpdated |= CLRCF_OPTIONS;
       sreg->config.options = config->options;
    }
    if((updated&CLRCF_SOURCE_ID) && sreg->config.source_id != config->source_id)
    {
        retUpdated |= CLRCF_SOURCE_ID;
       sreg->config.source_id = config->source_id;
    }
    if((updated&CLRCF_SOURCE) && memcmp(&sreg->config.source ,  &config->source, sizeof(sreg->config.source)))
    {
        retUpdated |= CLRCF_SOURCE;
       memcpy(&sreg->config.source, &config->source, sizeof(sreg->config.source));
    }

    if((updated&CLRCF_DEST)&& memcmp(&sreg->config.dest, &config->dest, sizeof(sreg->config.dest)))
    {
        retUpdated |= CLRCF_DEST;
       memcpy(&sreg->config.dest, &config->dest, sizeof(sreg->config.dest));
    }

    //U4 special ,because the U4 layer0 layer1 used the same GOP
    if(dfb_config->mst_gop_available[0] ==dfb_config->mst_gop_available[1])
    {
        if((updated&CLRCF_DEST))
        {
            retUpdated |= CLRCF_DEST;
            memcpy(&sreg->config.dest, &config->dest, sizeof(sreg->config.dest));
        }
    }

    if(updated&CLRCF_CLIPS && config->num_clips>0)
    {
        retUpdated |= CLRCF_CLIPS;
        printf("warning: mstar t2 gfx driver doesn't support HW clip chains yet!\n");
    }
    if((updated&CLRCF_OPACITY) && sreg->config.opacity != config->opacity)
    {
        retUpdated |= CLRCF_OPACITY;
       sreg->config.opacity = config->opacity;
    }
    if((updated&CLRCF_ALPHA_RAMP) && memcmp(sreg->config.alpha_ramp, config->alpha_ramp, sizeof(sreg->config.alpha_ramp)))
    {
        retUpdated |= CLRCF_ALPHA_RAMP;
       memcpy(sreg->config.alpha_ramp , config->alpha_ramp, sizeof(sreg->config.alpha_ramp));
    }
    if((updated&CLRCF_SRCKEY) && memcmp(&sreg->config.src_key , &config->src_key, sizeof(sreg->config.src_key)))
    {
        retUpdated |= CLRCF_SRCKEY;
        memcpy(&sreg->config.src_key , &config->src_key, sizeof(sreg->config.src_key));
    }
    if((updated&CLRCF_DSTKEY) && memcmp(&sreg->config.dst_key , &config->dst_key, sizeof(sreg->config.dst_key)))
    {
        retUpdated |= CLRCF_DSTKEY;
        memcpy(&sreg->config.dst_key , &config->dst_key, sizeof(sreg->config.dst_key));
        printf("warning: mstar t2 gfx driver doesn't support destionation color yet!\n");
    }
     if((updated&CLRCF_PARITY) && sreg->config.positive != config->positive)
    {
        retUpdated |= CLRCF_PARITY;
       sreg->config.positive = config->positive;
    }

    if((updated&CLRCF_TILEMODE) && sreg->config.btile_mode != config->btile_mode)
    {
        retUpdated |= CLRCF_TILEMODE;
        sreg->config.btile_mode = config->btile_mode;
    }

    if((updated&CLRCF_HSTRETCH) && sreg->config.hstretchmode != config->hstretchmode)
    {
        retUpdated |= CLRCF_HSTRETCH;
        sreg->config.hstretchmode = config->hstretchmode;
    }

    if((updated&CLRCF_VSTRETCH) && sreg->config.vstretchmode != config->vstretchmode)
    {
        retUpdated |= CLRCF_VSTRETCH;
        sreg->config.vstretchmode = config->vstretchmode;
    }

    if((updated&CLRCF_TSTRETCH) && sreg->config.tstretchmode != config->tstretchmode)
    {
        retUpdated |= CLRCF_TSTRETCH;
        sreg->config.tstretchmode = config->tstretchmode;
    }

    if(updated&CLRCF_PALETTE)
    {
         if(config->format==DSPF_LUT8)
         {
             retUpdated |= CLRCF_PALETTE;
         }
    }

    if(updated&CLRCF_FREEZE)
    {
        retUpdated |= CLRCF_FREEZE;
    }


    return retUpdated;
}

static DFBResult
_mstarSetRegion( CoreLayer                  *layer,
                 void                       *driver_data,
                 void                       *layer_data,
                 void                       *region_data,
                 CoreLayerRegionConfig      *config,
                 CoreLayerRegionConfigFlags  updated,
                 CoreSurface                *surface,
                 CorePalette                *palette,
                 CoreSurfaceBufferLock      *lock )
{
     MSTARDriverData *sdrv = driver_data;
     MSTARDeviceData *sdev = sdrv->dev;
     MSTARRegionData *sreg = region_data;
     MSTARLayerData  *slay = layer_data;
     u8  curGopIndex;
     u16 u16FBId = 0;  //Coverity-03132013
     u8 u8FBId;
     int freeSurfInfoSlot=-1;
     bool bGWinEnable = true;
     u32 u32Phys = 0;
     EN_GOP_CONSALPHA_BITS enConstAlpha_bits = E_GOP_VALID_6BITS;
     u8 constAlpha = 0;
     EN_GOP_CONFIG_TYPE confugType = E_GOP_CONSALPHA_BITS ;
     bool bnewFB;
     bool bvideoModeChanged = false;
     bool bGOPModeChanged = false;

    fusion_skirmish_prevail( &sdev->beu_lock );

#if MSTAR_MULTI_GOP_SUPPORT
     curGopIndex = MApi_GOP_GWIN_GetCurrentGOP();
     if(curGopIndex!=slay->gop_index)
        MApi_GOP_GWIN_SwitchGOP(slay->gop_index);
#endif

    MApi_GOP_GWIN_UpdateRegOnce(TRUE);
    MApi_GOP_GWIN_Enable(sdev->layer_gwin_id[slay->layer_index], (MS_BOOL)FALSE) ;
    MApi_GOP_GWIN_SwitchGOP(slay->gop_index);
    MApi_GOP_GWIN_UpdateRegOnceEx(FALSE, FALSE);
    MApi_GOP_GWIN_UpdateRegOnce(TRUE);
    
    sreg->config_dirtyFlag |= mstarBuildUpdate(sreg, config, updated);

    if(dfb_config->bGOPUsingHWTLB)
        u32Phys = lock->phys;
    else
        u32Phys = mstarGFXAddr(lock->phys, sdev->mst_miu1_cpu_offset, sdev->mst_miu1_hal_offset);

     if(slay->gop_dst == E_GOP_DST_IP0 || slay->gop_dst == E_GOP_DST_IP1)
     {
        E_VIDEO_FIELD_MODE video_mode = E_VIDEO_FIELD_PROGRESSIVE;
        if(mstar_sc_is_interlace())
        {
            video_mode = E_VIDEO_FIELD_INTERLACE ;
        }
        if(video_mode!=slay->VideoFiledMode)
        {

            slay->VideoFiledMode = video_mode ;
            bvideoModeChanged = true ;
        }

     }
     else if (slay->gop_dst == E_GOP_DST_BYPASS || slay->gop_dst == E_GOP_DST_OP0)
     {
         if(slay->gop_dst!=slay->GopDstMode)
         {
            bGOPModeChanged = true ;
            slay->GopDstMode = slay->gop_dst ;
            sreg->config_dirtyFlag |= CLRCF_OPACITY; //set GOP Alpha
         }
         
         //fixbug in mantis: 627551: [TM14 4K NA][MM] movie: subtitle display abnormally
         if ( slay->gop_dst ==  E_GOP_DST_OP0) 
         {
             MApi_GOP_GWIN_EnableProgressive(TRUE);
         } 
     }
     else if (dfb_config->mst_enable_ve_init) 
     {
         if ( slay->gop_dst == E_GOP_DST_VE)  //For K3s Set the gopVETimingType
         { 
             GOP_VE_TIMINGTYPE gopVETimingType;
             MS_VE_VIDEOSYS enVesys = MDrv_VE_Get_Output_Video_Std();
             if(enVesys == MS_VE_NTSC)
             {
                 gopVETimingType = GOP_VE_NTSC;
             }
             else
             {
                 gopVETimingType = GOP_VE_PAL;
             }
             MApi_GOP_VE_SetOutputTiming(gopVETimingType);
         }
         else if (slay->gop_dst == E_GOP_DST_MIXER2VE)  //For K3s Set the gopMIXER2VETimingType
         {
             GOP_MixerTiming stTiming;
             MS_VE_VIDEOSYS enVesys = MDrv_VE_Get_Output_Video_Std();
             if(enVesys == MS_VE_NTSC )
             {
                 MApi_GOP_MIXER_SetOutputTiming(GOP_NTSC, &stTiming);
             }
             else
             {
                 MApi_GOP_MIXER_SetOutputTiming(GOP_PAL, &stTiming);
             }
         }
     }

     DBG_LAYER_MSG ("%s (%d)\n", __FUNCTION__, __LINE__ );
     DBG_LAYER_MSG ("surface->num_buffers = %d, updated = %08x\n", surface->num_buffers,updated );
     DBG_LAYER_MSG ("config_flage = %x, config_dirtyFlag = %x\n", updated, sreg->config_dirtyFlag);
     D_ASSERT( slay->layer_index >= 0 );
     D_ASSERT( slay->layer_index < MSTAR_MAX_OUTPUT_LAYER_COUNT );

     D_DEBUG_AT( MSTAR_Layer, "\ndfb_gfxcard_memory_physical( NULL, lock->offset )--> 0x%x\n", dfb_gfxcard_memory_physical( NULL, lock->offset ));
     D_DEBUG_AT( MSTAR_Layer, "\ndfb_gfxcard_memory_virtual( NULL, lock->offset )--> 0x%x\n", dfb_gfxcard_memory_virtual( NULL, lock->offset ));


     DBG_LAYER_MSG( "config->width: %d  config->height: %d\n", config->width, config->height);
     DBG_LAYER_MSG( "config->buffermode: 0x%x\n", config->buffermode);
     DBG_LAYER_MSG( "config->source_id: %d\n", config->source_id);
     DBG_LAYER_MSG( "config->source.x:%d config->source.y:%d config->source.w:%d config->source.h:%d\n", config->source.x, config->source.y, config->source.w, config->source.h);
     DBG_LAYER_MSG( "config->dest.x:%d config->dest.y:%d config->dest.w:%d config->dest.h:%d\n", config->dest.x, config->dest.y, config->dest.w, config->dest.h);
     DBG_LAYER_MSG( "config->opacity: %d\n", config->opacity);
     DBG_LAYER_MSG( "the gop is sdev->gfx_gop_index:%d\n",sdev->gfx_gop_index);


    if((sreg->config_dirtyFlag&(CLRCF_WIDTH|CLRCF_HEIGHT|CLRCF_FORMAT)) && (slay->ShadowFlags&(SLF_SHADOW_LAYER_BOOLEAN|SLF_SHADOW_LAYER_INDEXALL)) )
    {
       printf("\nthe layer is configure as shadow layer or this layer has other shadowlayer,refuse setRegion\n");
       fusion_skirmish_dismiss( &sdev->beu_lock );
       MApi_GOP_GWIN_SwitchGOP(slay->gop_index);
       MApi_GOP_GWIN_UpdateRegOnce(FALSE);
       
       return DFB_FAILURE;
    }


    if(sreg->config_dirtyFlag & (CLRCF_SURFACE|CLRCF_WIDTH|CLRCF_HEIGHT|CLRCF_FORMAT|CLRCF_PALETTE)||bvideoModeChanged || bGOPModeChanged ||sdev->layer_gwin_id[slay->layer_index]==INVALID_WIN_ID)
    {

       if(INVALID_WIN_ID != sdev->layer_gwin_id[slay->layer_index])
        {
            u16 FBId,slotID;
            MApi_GOP_GWIN_DestroyWin(sdev->layer_gwin_id[slay->layer_index]);     
            if(slay->gop_index_r!= 0xf)
            {
                if(INVALID_WIN_ID != sdev->layer_gwin_id_r[slay->layer_index])
                    MApi_GOP_GWIN_DestroyWin(sdev->layer_gwin_id_r[slay->layer_index]);     
            }
            
            do
            {
                FBId = _mstarFindFBIdbyGWinID(sdrv,sdev->layer_gwin_id[slay->layer_index],&slotID,&surface);
                if(FBId!=0xff)
                {
                    MApi_GOP_GWIN_DestroyFB(FBId);
                    _mstarSetSurfInfoSlotFree(sdrv,slotID);
                }
            }while(FBId!=0xff);       

            
            sdev->layer_gwin_id[slay->layer_index] = INVALID_WIN_ID;
        }
  
   
        freeSurfInfoSlot =_mstarGetSurfInfoSlot(sdrv,slay,surface, lock->buffer, u32Phys, lock->pitch, &u16FBId, &bnewFB);  
        MApi_GOP_SetUVSwap(slay->gop_index, FALSE);
        MApi_GOP_SetYCSwap(slay->gop_index, FALSE);
        switch(config->format)
        {
            case DSPF_UNKNOWN:
            case DSPF_RGB24:
            case DSPF_RGB32:
            case DSPF_A8:
            case DSPF_RGB332:
            case DSPF_I420:
            case DSPF_YV12:
            case DSPF_ALUT44:
            case DSPF_AiRGB:
            case DSPF_A1:
            case DSPF_NV12:
            case DSPF_NV16:
            case DSPF_ARGB2554:
            case DSPF_NV21:
            case DSPF_A4:
            case DSPF_ARGB1666:
            case DSPF_ARGB6666:
            case DSPF_RGB18:
            case DSPF_LUT2:
            case DSPF_LUT1:
            case DSPF_LUT4:
            case DSPF_RGB444:
            case DSPF_RGB555:
            case DSPF_BGR555:
            case DSPF_RGBA4444:
            case DSPF_RGBA5551:
                DBG_LAYER_MSG("format:%s\n", dfb_pixelformat_name(config->format));
            break;

            case DSPF_LUT8:
                DBG_LAYER_MSG( "format: DSPF_LUT8\n");

            // set palette table
            if(sreg->config_dirtyFlag & CLRCF_PALETTE){
                if(palette){
                    DBG_LAYER_MSG( "\n================================================\n");
                    DBG_LAYER_MSG(  "palette->num_entries: %d\n", palette->num_entries);
                    DBG_LAYER_MSG( "palette->hash_attached: %d\n", palette->hash_attached);
                    DBG_LAYER_MSG( "\n================================================\n");

                    GOP_PaletteEntry GOPPaletteEntry8888[256];
                    if(palette->entries){
                        int i;
                        for(i=0; i < palette->num_entries; ++i){
                            GOPPaletteEntry8888[i].RGB.u8A = palette->entries[i].a;
                            GOPPaletteEntry8888[i].RGB.u8R = palette->entries[i].r;
                            GOPPaletteEntry8888[i].RGB.u8G = palette->entries[i].g;
                            GOPPaletteEntry8888[i].RGB.u8B = palette->entries[i].b;
                        }
                        //need add gop subbank control
                        MApi_GOP_GWIN_SetPaletteOpt(GOPPaletteEntry8888, 0, (palette->num_entries-1), E_GOP_PAL_ARGB8888);
                    }
                }
            }
            /*fall through*/

            case DSPF_YVYU:
            case DSPF_UYVY:
            case DSPF_YUY2:
            case DSPF_AYUV:
            case DSPF_ARGB1555:
            case DSPF_RGB16:
            case DSPF_ARGB:
            case DSPF_ARGB4444:

                if(config->format == DSPF_YVYU)
                {
                    MApi_GOP_SetUVSwap(slay->gop_index, TRUE);
                }
                else if (config->format == DSPF_UYVY)
                {
                    MApi_GOP_SetYCSwap(slay->gop_index, TRUE);
                }
                sdev->layer_gwin_id[slay->layer_index] = MApi_GOP_GWIN_CreateWin_Assign_FB(slay->gop_index, (u8)u16FBId, 0, 0);
  
                _mstarSetSlotGWinID(sdrv,freeSurfInfoSlot,sdev->layer_gwin_id[slay->layer_index]);

                if(slay->gop_index_r != 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
                {
                    GOP_GwinInfo info;

                   //gfx_GOPStretch(slay->gop_index,slay->gop_dst, sreg->config.width/2,sreg->config.height, sreg->config.dest.w/2,sreg->config.dest.h,sreg->config.dest.x, sreg->config.dest.y);
                   gfx_GOPStretch(slay->gop_index,slay->gop_dst, sreg->config.width/2,sreg->config.height, sreg->config.dest.w/2,sreg->config.dest.h,0, 0);

                   memset(&info, 0, sizeof(GOP_GwinInfo));
                   MApi_GOP_GWIN_GetWinInfo(sdev->layer_gwin_id[slay->layer_index],&info);
                   info.u16DispHPixelEnd = (sreg->config.width/2);
                   info.u16RBlkHPixSize = (info.u16DispHPixelEnd - info.u16DispHPixelStart);
                   MApi_GOP_GWIN_SetWinInfo(sdev->layer_gwin_id[slay->layer_index],&info);
                   
                }
                else
                {
                    gfx_GOPStretch(slay->gop_index,slay->gop_dst, sreg->config.width,sreg->config.height, sreg->config.dest.w,sreg->config.dest.h,sreg->config.dest.x, sreg->config.dest.y);
                }

                MApi_GOP_GWIN_SetWinPosition(sdev->layer_gwin_id[slay->layer_index], 0, 0);
                MApi_GOP_SetPINPON(sdev->layer_gwin_id[slay->layer_index], FALSE, GOP_PINPON_G3D);

                if(slay->gop_index_r!= 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
                {
                    GOP_GwinInfo info;
                    
                    sdev->layer_gwin_id_r[slay->layer_index] = MApi_GOP_GWIN_CreateWin_Assign_FB(slay->gop_index_r, (u8)u16FBId, 0, 0);

                     MApi_GOP_GWIN_SwitchGOP(slay->gop_index_r);
                     
                     //gfx_GOPStretch(slay->gop_index_r,slay->gop_dst, sreg->config.width/2,sreg->config.height, sreg->config.dest.w/2,sreg->config.dest.h,sreg->config.dest.x, sreg->config.dest.y);
                     gfx_GOPStretch(slay->gop_index_r,slay->gop_dst, sreg->config.width/2,sreg->config.height, sreg->config.dest.w/2,sreg->config.dest.h,0, 0);

                     memset(&info, 0, sizeof(GOP_GwinInfo));
                     MApi_GOP_GWIN_GetWinInfo(sdev->layer_gwin_id_r[slay->layer_index],&info);
                     info.u16DispHPixelEnd = (sreg->config.width/2);
                     info.u16RBlkHPixSize = (info.u16DispHPixelEnd - info.u16DispHPixelStart);
                     MApi_GOP_GWIN_SetWinInfo(sdev->layer_gwin_id_r[slay->layer_index],&info);

                     MApi_GOP_GWIN_SetWinPosition(sdev->layer_gwin_id_r[slay->layer_index], 0, 0);
                     MApi_GOP_SetPINPON(sdev->layer_gwin_id_r[slay->layer_index], FALSE, GOP_PINPON_G3D);
                     MApi_GOP_GWIN_SwitchGOP(slay->gop_index);
                }
                
                sreg->config_dirtyFlag &= ~CLRCF_DEST;

             break;

        }
   }

    if(INVALID_WIN_ID==sdev->layer_gwin_id[slay->layer_index] ||  GWIN_FAIL == sdev->layer_gwin_id[slay->layer_index])
    {
          sdev->layer_gwin_id[slay->layer_index] = INVALID_WIN_ID;
          fusion_skirmish_dismiss( &sdev->beu_lock );
          MApi_GOP_GWIN_SwitchGOP(slay->gop_index);
          MApi_GOP_GWIN_UpdateRegOnce(FALSE);
          
          return DFB_FAILURE;
    }
    if(sreg->config_dirtyFlag & (CLRCF_SRCKEY|CLRCF_OPTIONS))
    {
        MS_U32 tcol;
        if(sreg->config.options & DLOP_SRC_COLORKEY)
        {

        //to make the layer colorkey interface is the same as surface colorkey,if the format is not ARGB32.
        //the AP need to do bit shift to complete the format convert.
        //for example:ARGB1555:ARRRRRGGGGGBBBBB---->Rchannel :RRRRR000   Gchannel:GGGGG000    Bchannel:BBBBB000
        //In this function of the DFB ,we will do the second format convert as following. the blank LSB BIT will be filled with
        //the MSB
            switch(config->format)
            {
                case DSPF_ARGB1555:
                {
                    sreg->config.src_key.r = (sreg->config.src_key.r)|(sreg->config.src_key.r>>5);
                    sreg->config.src_key.g = (sreg->config.src_key.g)|(sreg->config.src_key.g>>5);
                    sreg->config.src_key.b = (sreg->config.src_key.b)|(sreg->config.src_key.b>>5);
                }
                break;

                case DSPF_RGB16:
                {
                    sreg->config.src_key.r = (sreg->config.src_key.r)|(sreg->config.src_key.r>>5);
                    sreg->config.src_key.g = (sreg->config.src_key.g)|(sreg->config.src_key.g>>6);
                    sreg->config.src_key.b = (sreg->config.src_key.b)|(sreg->config.src_key.b>>5);
                }
                break;

                case DSPF_ARGB:
                break;

                case DSPF_ARGB4444:
                {
                    sreg->config.src_key.r = (sreg->config.src_key.r)|(sreg->config.src_key.r>>4);
                    sreg->config.src_key.g = (sreg->config.src_key.g)|(sreg->config.src_key.g>>4);
                    sreg->config.src_key.b = (sreg->config.src_key.b)|(sreg->config.src_key.b>>4);
                }
                break;

                default:
                break;
            }
            tcol = sreg->config.src_key.r<<16|sreg->config.src_key.g<<8|sreg->config.src_key.b;

            
            MApi_GOP_GWIN_SetTransClr_8888(tcol, 0);
            MApi_GOP_GWIN_EnableTransClr(GOPTRANSCLR_FMT0, TRUE);
            
            if(slay->gop_index_r!= 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
            {
                MApi_GOP_GWIN_SwitchGOP(slay->gop_index_r);
                MApi_GOP_GWIN_SetTransClr_8888(tcol, 0);
                MApi_GOP_GWIN_EnableTransClr(GOPTRANSCLR_FMT0, TRUE);
                MApi_GOP_GWIN_SwitchGOP(slay->gop_index);
            }
        }
        else
        {
            MApi_GOP_GWIN_EnableTransClr(GOPTRANSCLR_FMT0, FALSE);
            if(slay->gop_index_r!= 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
            {
                MApi_GOP_GWIN_SwitchGOP(slay->gop_index_r);
                MApi_GOP_GWIN_EnableTransClr(GOPTRANSCLR_FMT0, FALSE);
                MApi_GOP_GWIN_SwitchGOP(slay->gop_index);
            }
            
        }
   }
   //is this need set for individual gop ?
   if(GOP_API_SUCCESS==MApi_GOP_GetChipCaps(E_GOP_CAP_CONSALPHA_VALIDBITS,&enConstAlpha_bits,sizeof(EN_GOP_CONSALPHA_BITS)))
   {
        MApi_GOP_SetConfig(confugType,(MS_U32*)(&enConstAlpha_bits));
   }
   constAlpha = sreg->config.opacity;
   if(enConstAlpha_bits == E_GOP_VALID_6BITS)
   {
        constAlpha = constAlpha >>2;

   }
   else if(enConstAlpha_bits == E_GOP_VALID_8BITS)
   {
        constAlpha = constAlpha ;

   }

   if(sreg->config_dirtyFlag & (CLRCF_OPACITY|CLRCF_OPTIONS))
   {
       if(sreg->config.options & DLOP_OPACITY)
       {
            MApi_GOP_GWIN_SetBlending(sdev->layer_gwin_id[slay->layer_index], FALSE, constAlpha);
            if(slay->gop_index_r!= 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
            {
                MApi_GOP_GWIN_SwitchGOP(slay->gop_index_r);
                MApi_GOP_GWIN_SetBlending(sdev->layer_gwin_id_r[slay->layer_index], FALSE, constAlpha);
                MApi_GOP_GWIN_SwitchGOP(slay->gop_index);
            }
            if(0x0 == sreg->config.opacity)
            {
                bGWinEnable = false;
            }

       }
       else if (sreg->config.options & DLOP_ALPHACHANNEL)
       {
             MApi_GOP_GWIN_SetBlending(sdev->layer_gwin_id[slay->layer_index], TRUE, constAlpha);
             if(slay->gop_index_r!= 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
             {
                 MApi_GOP_GWIN_SwitchGOP(slay->gop_index_r);
                 MApi_GOP_GWIN_SetBlending(sdev->layer_gwin_id_r[slay->layer_index], TRUE, constAlpha);
                 MApi_GOP_GWIN_SwitchGOP(slay->gop_index);
             }
       }
       else
       {
            u8 cstAlpha = 0xFF;
            if(enConstAlpha_bits==E_GOP_VALID_6BITS)
            {
                cstAlpha = cstAlpha >>2;
            }
            else if(enConstAlpha_bits==E_GOP_VALID_8BITS)
            {
                cstAlpha = cstAlpha;
            }
            MApi_GOP_GWIN_SetBlending(sdev->layer_gwin_id[slay->layer_index], FALSE, cstAlpha);
            if(slay->gop_index_r!= 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
            {
                MApi_GOP_GWIN_SwitchGOP(slay->gop_index_r);
                MApi_GOP_GWIN_SetBlending(sdev->layer_gwin_id_r[slay->layer_index], FALSE, constAlpha);
                MApi_GOP_GWIN_SwitchGOP(slay->gop_index);
            }
       }
   }
   if(sreg->config_dirtyFlag & CLRCF_HSTRETCH)
   {
        MApi_GOP_GWIN_Set_HStretchMode(sreg->config.hstretchmode);
        if(slay->gop_index_r!= 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
        {
            MApi_GOP_GWIN_SwitchGOP(slay->gop_index_r);
            MApi_GOP_GWIN_Set_HStretchMode(sreg->config.hstretchmode);
            MApi_GOP_GWIN_SwitchGOP(slay->gop_index);
        }

   }

   if(sreg->config_dirtyFlag & CLRCF_VSTRETCH)
   {
        MApi_GOP_GWIN_Set_VStretchMode(sreg->config.vstretchmode);
        if(slay->gop_index_r!= 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
        {
            MApi_GOP_GWIN_SwitchGOP(slay->gop_index_r);
            MApi_GOP_GWIN_Set_VStretchMode(sreg->config.vstretchmode);
            MApi_GOP_GWIN_SwitchGOP(slay->gop_index);
        }
   }

   if(sreg->config_dirtyFlag & CLRCF_TSTRETCH)
   {
        MApi_GOP_GWIN_Set_TranspColorStretchMode(sreg->config.tstretchmode);
        if(slay->gop_index_r!= 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
        {
            MApi_GOP_GWIN_SwitchGOP(slay->gop_index_r);
            MApi_GOP_GWIN_Set_TranspColorStretchMode(sreg->config.tstretchmode);
            MApi_GOP_GWIN_SwitchGOP(slay->gop_index);
        }
   }

   if(sreg->config_dirtyFlag & (CLRCF_DEST|CLRCF_WIDTH|CLRCF_HEIGHT))
   {

        //MApi_GOP_GWIN_SetWinPosition(sdev->layer_gwin_id[slay->layer_index], sreg->config.dest.x, sreg->config.dest.y);

        if(sreg->config.dest.w && sreg->config.dest.h)
        {
            if(slay->gop_index_r != 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
            {
                gfx_GOPStretch(slay->gop_index,slay->gop_dst, sreg->config.width/2,sreg->config.height, sreg->config.dest.w/2,sreg->config.dest.h,sreg->config.dest.x, sreg->config.dest.y);             
            }
            else
            {
                gfx_GOPStretch(slay->gop_index,slay->gop_dst, sreg->config.width,sreg->config.height, sreg->config.dest.w,sreg->config.dest.h,sreg->config.dest.x, sreg->config.dest.y);
            }
            
            MApi_GOP_GWIN_SetStretchWinPosition(slay->gop_index, sreg->config.dest.x, sreg->config.dest.y);
            if(slay->gop_index_r != 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
            {
                MApi_GOP_GWIN_SwitchGOP(slay->gop_index_r);
                gfx_GOPStretch(slay->gop_index_r,slay->gop_dst, sreg->config.width/2,sreg->config.height, sreg->config.dest.w/2,sreg->config.dest.h,sreg->config.dest.x, sreg->config.dest.y);
                MApi_GOP_GWIN_SetStretchWinPosition(slay->gop_index_r, sreg->config.dest.x, sreg->config.dest.y);
                MApi_GOP_GWIN_SwitchGOP(slay->gop_index);
            }

        }


   }
   //close pinon to make setting works
   if(sreg->config_dirtyFlag & CLRCF_TILEMODE)
   {

        EN_GOP_TILE_DATA_TYPE tiletype = 0xff;
        switch(DFB_BITS_PER_PIXEL(config->format))
        {
            case 16:
              tiletype = E_GOP_TILE_DATA_16BPP;
              break;
            case 32:
              tiletype = E_GOP_TILE_DATA_32BPP;
              break;
            default:
              break;

        }
        MApi_GOP_SetPINPON(sdev->layer_gwin_id[slay->layer_index], FALSE, GOP_PINPON_G3D);
        MApi_GOP_GWIN_EnableTileMode(sdev->layer_gwin_id[slay->layer_index], sreg->config.btile_mode, tiletype );
        if(slay->gop_index_r!= 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
        {
            MApi_GOP_SetPINPON(sdev->layer_gwin_id_r[slay->layer_index], FALSE, GOP_PINPON_G3D);
            MApi_GOP_GWIN_EnableTileMode(sdev->layer_gwin_id_r[slay->layer_index], sreg->config.btile_mode, tiletype );
        }

        /*
        printf("\n sreg->config.btile_mode :%d\n",sreg->config.btile_mode);
        printf("\n the tiletype is %d\n",tiletype);
        */

   }

    if(sdev->layer_zorder[slay->layer_index] < 1)
        bGWinEnable = FALSE;
    MApi_GOP_GWIN_Enable(sdev->layer_gwin_id[slay->layer_index], (MS_BOOL)bGWinEnable) ;
    if(slay->gop_index_r!= 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
    {
        MApi_GOP_GWIN_Enable(sdev->layer_gwin_id_r[slay->layer_index], (MS_BOOL)bGWinEnable) ;
    }

    if(sreg->config.btile_mode)
    {
            //this code should be only used when HW FLIP is enable
            MApi_GOP_SetPINPON(sdev->layer_gwin_id[slay->layer_index], TRUE, GOP_PINPON_G3D);
            if(slay->gop_index_r!= 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
            {
                MApi_GOP_SetPINPON(sdev->layer_gwin_id_r[slay->layer_index], TRUE, GOP_PINPON_G3D);
            }
            sdev->layer_pinpon_mode[slay->layer_index] = true;
    }
    else
    {
            sdev->layer_pinpon_mode[slay->layer_index] = false;
    }
    sdev->layer_active[slay->layer_index] = true;
    mstarReorderGWIN(sdrv);
    sreg->config_dirtyFlag = CLRCF_NONE;

    MApi_GOP_GWIN_SwitchGOP(slay->gop_index);
    MApi_GOP_GWIN_UpdateRegOnceEx(FALSE,TRUE);

#if MSTAR_MULTI_GOP_SUPPORT
    if(curGopIndex!=slay->gop_index)
        MApi_GOP_GWIN_SwitchGOP(curGopIndex);
#endif
     fusion_skirmish_dismiss( &sdev->beu_lock );

     return DFB_OK;
}

static inline void _mstarRecordLayerCurPhyAddr( MSTARDriverData *sdrv ,MSTARDeviceData *sdev,CoreSurfaceBufferLock      *lock , u8 layer_index)
{
    u32 u32Phys;

    if(NULL==sdrv||NULL==sdev||NULL == lock)
    {
        printf("\n recored the CurPhyAddr Failed\n");
        return ;
    }

    if(dfb_config->bGOPUsingHWTLB)
        u32Phys = lock->phys;
    else
        u32Phys = mstarGFXAddr(lock->phys, sdev->mst_miu1_cpu_offset, sdev->mst_miu1_hal_offset);
    
    u16 u16TagID = (u16) lock->allocation->gfxSerial.serial;

    //printf("\nthe layer:%d tagID is %d\n",layer_index,u16TagID);
    sdrv->layerFlipInfo[layer_index].CurPhysAddr = u32Phys;
    sdrv->layerFlipInfo[layer_index].tagID = u16TagID;

    return ;
}



static DFBResult
mstarSetRegion( CoreLayer                  *layer,
                 void                       *driver_data,
                 void                       *layer_data,
                 void                       *region_data,
                 CoreLayerRegionConfig      *config,
                 CoreLayerRegionConfigFlags  updated,
                 CoreSurface                *surface,
                 CorePalette                *palette,
                 CoreSurfaceBufferLock      *lock )
{
    MSTARLayerData  *slay = layer_data;
    CoreLayerCallParameter *parameter;
    FusionSHMPoolShared *shm_pool;
    MSTARDriverData *sdrv = driver_data;
    MSTARDeviceData *sdev = sdrv->dev;
    int ret;


    _mstarRecordLayerCurPhyAddr( sdrv ,sdev,lock , slay->layer_index);

    shm_pool = dfb_core_shmpool_data(layer->core);
    D_ASSERT(shm_pool);

    parameter = SHMALLOC(shm_pool, sizeof(*parameter));
    if(!parameter)
       return DFB_NOSHAREDMEMORY;

    parameter->reg_data= region_data;
    parameter->lock = lock;
    memcpy(&parameter->config,config,sizeof(*config));
    memcpy(&parameter->flags,&updated,sizeof(updated));
    parameter->surface = surface;


    if(dfb_config->mst_forcewrite_DFB & DFB_FORECWRITE_USING)
    {
        if(dfb_config->mst_forcewrite_DFB & DFB_FORCEWRITE_ENABLE)
        {

            if (fusion_call_execute( &slay->call, FCEF_NONE, CLC_FORCEWRITE_ENABLE, parameter, &ret ))
            {
                SHFREE(shm_pool, parameter);
                return DFB_FUSION;
            }

         }
        else if(dfb_config->mst_forcewrite_DFB & DFB_FORCEWRITE_DISABLE)
        {

            if (fusion_call_execute( &slay->call, FCEF_NONE, CLC_FORCEWRITE_DISABLE, parameter, &ret ))
            {
                SHFREE(shm_pool, parameter);
                return DFB_FUSION;
            }
        }
    }




    if (fusion_call_execute( &slay->call, FCEF_NONE, CLC_SET_REGION, parameter, &ret ))
    {

        SHFREE(shm_pool, parameter);
        return DFB_FUSION;
    }
    memcpy(config,&parameter->config,sizeof(*config));
    memcpy(&updated,&parameter->flags,sizeof(updated));
    SHFREE(shm_pool, parameter);

    return ret;

}

static DFBResult
_mstarRemoveRegion( CoreLayer *layer,
                    void      *driver_data,
                    void      *layer_data,
                    void      *region_data )
{
     MSTARDriverData *sdrv = driver_data;
     MSTARDeviceData *sdev = sdrv->dev;
     MSTARLayerData  *slay = layer_data;

     DBG_LAYER_MSG(" %s(%d)\n", __FUNCTION__, __LINE__);

     D_ASSERT( sdev != NULL );
     D_ASSERT( slay != NULL );

     D_ASSERT( slay->layer_index >= 0 );
     D_ASSERT( slay->layer_index < MSTAR_MAX_OUTPUT_LAYER_COUNT );

     fusion_skirmish_prevail( &sdev->beu_lock );

     sdev->layer_refcnt[slay->layer_index]--;
     if((sdev->layer_refcnt[slay->layer_index]<=0) && (INVALID_WIN_ID != sdev->layer_gwin_id[slay->layer_index]))
     {
       u16 FBId,slotID;
       CoreSurface *surface= NULL;
        //MAdp_GOP_GWIN_Enable( sdev->gfx_gop_index, 0, false) ;
        MApi_GOP_GWIN_Enable( sdev->layer_gwin_id[slay->layer_index], FALSE) ;
        if( sdev->layer_zorder[slay->layer_index] > 0)
            sdev->layer_zorder[slay->layer_index] = 0;
        MApi_GOP_SetPINPON(sdev->layer_gwin_id[slay->layer_index], FALSE, GOP_PINPON_G3D);
        MApi_GOP_GWIN_DestroyWin(sdev->layer_gwin_id[slay->layer_index]); 
        if(slay->gop_index_r != 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
        {
            MApi_GOP_GWIN_Enable( sdev->layer_gwin_id_r[slay->layer_index], FALSE) ;
            MApi_GOP_SetPINPON(sdev->layer_gwin_id_r[slay->layer_index], FALSE, GOP_PINPON_G3D);
            MApi_GOP_GWIN_DestroyWin(sdev->layer_gwin_id_r[slay->layer_index]);
        }
            

        do
        {
            FBId = _mstarFindFBIdbyGWinID(sdrv,sdev->layer_gwin_id[slay->layer_index],&slotID,&surface);
            if(FBId!=0xff)
            {
                MApi_GOP_GWIN_DestroyFB(FBId);
                _mstarSetSurfInfoSlotFree(sdrv,slotID);
            }
        }while(FBId!=0xff);        
   
       
        sdev->layer_gwin_id[slay->layer_index] = INVALID_WIN_ID;
        sdev->layer_active[slay->layer_index] = false;
     }
     fusion_skirmish_dismiss( &sdev->beu_lock );
     return DFB_OK;
}



static DFBResult
mstarRemoveRegion( CoreLayer *layer,
                    void      *driver_data,
                    void      *layer_data,
                    void      *region_data )

{
    MSTARLayerData  *slay = layer_data;
    CoreLayerCallParameter *parameter;
    FusionSHMPoolShared *shm_pool;
    int ret;

    shm_pool = dfb_core_shmpool_data(layer->core);
    D_ASSERT(shm_pool);

    parameter = SHMALLOC(shm_pool, sizeof(*parameter));

    if(!parameter)
        return DFB_NOSHAREDMEMORY;
    parameter->reg_data = region_data;
    if (fusion_call_execute( &slay->call, FCEF_NONE, CLC_REMOVE_REGION, parameter, &ret ))
    {
        SHFREE(shm_pool, parameter);

        return DFB_FUSION;
    }
    SHFREE(shm_pool, parameter);

    return ret;
}

// If you support double buffer or triple buffer, you
// should implement the feature in FlipRegion().

static DFBResult
mstarFlipRegion( CoreLayer             *layer,
                  void                  *driver_data,
                  void                  *layer_data,
                  void                  *region_data,
                  CoreSurface           *surface,
                  DFBSurfaceFlipFlags    flags,
                  CoreSurfaceBufferLock *lock )
{

     u16 tagID;
     CoreSurfaceBuffer *buffer;
     MSTARDriverData  *sdrv = driver_data;
     MSTARDeviceData  *sdev = sdrv->dev;
     MSTARLayerData   *slay = layer_data;
     MSTARRegionData *sreg = region_data;
     u16 u16FBId;
     u16 u16QueueCnt;
     u16 targetQueueCnt;

     u8  u8FBId;
     int freeSurfInfoSlot;
     u32 u32Phys = 0;
     bool changed;
     u8 timeouttimes = 0;

     D_ASSERT( slay->layer_index >= 0 );
     D_ASSERT( slay->layer_index < MSTAR_MAX_OUTPUT_LAYER_COUNT );

     D_DEBUG_AT( MSTAR_Layer, "%s()\n", __FUNCTION__ );
     #if 0
     printf("\nDean %s\n", __FUNCTION__);
     printf("\nlock->addr = 0x%x\n", (int)lock->addr);
     printf("\nlock->phy = 0x%x\n", lock->phys);
     printf("\nlock->offset = 0x%x\n", lock->offset);

     printf("\nsurface->num_buffers: %d\n", surface->num_buffers);
     printf("\nsurface->resource_id: %d\n", surface->resource_id);
     printf("\nsurface->notifications: 0x%x\n", surface->notifications);
     printf("\nsurface->flips: %d\n", surface->flips);
     #endif

     D_ASSERT( surface != NULL );
     D_ASSERT( sdrv != NULL );
     D_ASSERT( sdev != NULL );
     D_ASSERT( slay != NULL );
     D_ASSERT( region_data != NULL );
     D_ASSERT(lock && lock->allocation);


     if(slay->ShadowFlags & SLF_SHADOW_LAYER_BOOLEAN)
     {
        return DFB_OK;
     }

     _mstarRecordLayerCurPhyAddr(sdrv,sdev,lock,slay->layer_index);

    //G3D mode, GWIN will been flipped directly by G3D HW
     if(sreg->config.btile_mode)
     {
           fusion_skirmish_prevail( &sdev->beu_lock );
           dfb_surface_flip( surface, false );
           fusion_skirmish_dismiss( &sdev->beu_lock );
          return DFB_OK;
     }

     buffer = lock->buffer;
     D_ASSERT( buffer != NULL );

     if(dfb_config->bGOPUsingHWTLB)
         u32Phys = lock->phys;
     else
         u32Phys = mstarGFXAddr(lock->phys, sdev->mst_miu1_cpu_offset, sdev->mst_miu1_hal_offset);


    tagID = (u16) lock->allocation->gfxSerial.serial;

    if(surface->config.caps & DSCAPS_TRIPLE)
         targetQueueCnt = 2;
    else//  if(surface->config.caps & DSCAPS_DOUBLE)
         targetQueueCnt = 1;

    //printf( "Flip: 0x%08X, pitch%d, slay->gop_dst:%d\n", u32Phys, lock->pitch, slay->gop_dst) ;

    do
    {
         u16QueueCnt = targetQueueCnt;

         if(slay->gop_index_r!= 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
         {
             GOP_MultiFlipInfo stMultiFlipInfo;
             stMultiFlipInfo.u8InfoCnt = 2;
             stMultiFlipInfo.astGopInfo[0].gWinId = sdev->layer_gwin_id[slay->layer_index];
             stMultiFlipInfo.astGopInfo[0].u32FlipAddr = u32Phys;
             stMultiFlipInfo.astGopInfo[0].u32SubAddr = 0;
             stMultiFlipInfo.astGopInfo[0].u16WaitTagID = tagID;
             stMultiFlipInfo.astGopInfo[0].pU16QueueCnt = &u16QueueCnt;
             
             stMultiFlipInfo.astGopInfo[1].gWinId = sdev->layer_gwin_id_r[slay->layer_index];
             stMultiFlipInfo.astGopInfo[1].u32FlipAddr = (u32Phys + lock->pitch/2);
             stMultiFlipInfo.astGopInfo[1].u32SubAddr = 0;
             stMultiFlipInfo.astGopInfo[1].u16WaitTagID = tagID;
             stMultiFlipInfo.astGopInfo[1].pU16QueueCnt = &targetQueueCnt;

             //printf("[DFB] stMultiFlipInfo.astGopInfo[0].u32FlipAddr:%x , \n", stMultiFlipInfo.astGopInfo[0].u32FlipAddr);
             //printf("[DFB] stMultiFlipInfo.astGopInfo[1].u32FlipAddr:%x , \n", stMultiFlipInfo.astGopInfo[1].u32FlipAddr);
             //printf("[DFB] lock->pitch:%d , \n", lock->pitch);
             if(MApi_GOP_Switch_Multi_GWIN_2_FB_BY_ADDR(stMultiFlipInfo))
            {
                break;
            }
        }
        else
        {
             if(MApi_GOP_Switch_GWIN_2_FB_BY_ADDR(sdev->layer_gwin_id[slay->layer_index], u32Phys, tagID, &u16QueueCnt))
             {
                //printf("MApi_GOP_Switch_GWIN_2_FB_Fusion success , break \n");
                break;
             }
        }
         timeouttimes ++;

         //if hw flip failed,but the u16QueueCnt<targetQueueCnt ,it is strange. because  u16QueueCnt <targetQueueCnt imply flip successfully

         if(u16QueueCnt <= targetQueueCnt-1)
         {
              printf("Serious warning, unknow error!!\n");
              return DFB_FAILURE;
         }
    }while(timeouttimes < 30);



    if(slay->ShadowFlags&SLF_SHADOW_LAYER_INDEXALL)
    {
        int i=0;
        u32 layerIndexFlag = slay->ShadowFlags&SLF_SHADOW_LAYER_INDEXALL;
        for(i=0;i<MSTAR_MAX_OUTPUT_LAYER_COUNT;i++)
        {
           if((layerIndexFlag>>i)&SLF_SHADOW_LAYER_INDEX0)
           {
                do
                {
                     u16QueueCnt = 1;
                     //if(MApi_GOP_Switch_GWIN_2_FB(sdev->layer_gwin_id[slay->layer_index], u16FBId, tagID, &u16QueueCnt))
                     if(MApi_GOP_Switch_GWIN_2_FB_BY_ADDR(sdev->layer_gwin_id[i], u32Phys, 0, &u16QueueCnt))
                     {
                        //printf("MApi_GOP_Switch_GWIN_2_FB_Fusion success , break \n");
                        break;
                     }
                     timeouttimes ++;


                }while(timeouttimes < 30);

           }
        }
    }




    if(timeouttimes >= 30)
    {
        int i;
        for(i = 0 ; i < timeouttimes ; i ++)
            printf("[%d]#################### layer=%d , gwin=%d \n",i,slay->layer_index,sdev->layer_gwin_id[slay->layer_index]);
    }

     fusion_skirmish_prevail( &sdev->beu_lock );

     dfb_surface_flip( surface, false );

     fusion_skirmish_dismiss( &sdev->beu_lock );

     return DFB_OK;
}

/*
static DFBResult
mstarUpdateRegion( CoreLayer             *layer,
                    void                  *driver_data,
                    void                  *layer_data,
                    void                  *region_data,
                    CoreSurface           *surface,
                    const DFBRegion       *update,
                    CoreSurfaceBufferLock *lock )
{
     MSTARDriverData *sdrv = driver_data;
     //MSTARDeviceData *sdev = sdrv->dev;

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

     D_ASSERT( surface != NULL );
     D_ASSERT( sdrv != NULL );
     //D_ASSERT( sdev != NULL );


     //BEU_Start( sdrv, sdev );

     //if (!(surface->config.caps & DSCAPS_FLIPPING))
         // BEU_Wait( sdrv, sdev );

     return DFB_OK;
}
*/
static DFBResult
mstar_primaryAllocateSurface( CoreLayer              *layer,
                        void                   *driver_data,
                        void                   *layer_data,
                        void                   *region_data,
                        CoreLayerRegionConfig  *config,
                        CoreSurface           **ret_surface )
{
     CoreSurfaceConfig conf;
     DFBResult ret;
     MSTARDriverData *sdrv = driver_data;
     MSTARDeviceData *sdev = sdrv->dev;
     CoreSurface *surface;
     int i, number_buffers;
     CoreSurfaceBufferLock ret_lock;
     int freeSurfInfoSlot;
     u8 u8FBID, u8GOP_Ret;
     CoreSurfaceTypeFlags cstf_flag = 0;
     u32 u32Phys = 0;
     u32 u32_gop_index = 0;
     bool tryAgain = false;

     if(_mstarDFBFmt2MSFmt(config->format) == E_MS_FMT_GENERIC)
        return DFB_FAILURE;

     DBG_LAYER_MSG ("%s (%d), w =%d, h =%d\n", __FUNCTION__, __LINE__ , config->width, config->height );

	
     conf.flags  = CSCONF_SIZE | CSCONF_FORMAT | CSCONF_CAPS;
     conf.size.w = config->width;
     conf.size.h = config->height;
     conf.format = config->format;
     conf.caps   = DSCAPS_VIDEOONLY;

     if (config->buffermode != DLBM_FRONTONLY)
     {
          if(config->buffermode & DLBM_TRIPLE)
            conf.caps |= DSCAPS_TRIPLE;
          else
            conf.caps |= DSCAPS_DOUBLE;
     }

     cstf_flag = CSTF_LAYER;

#if 1
    if (dfb_config->mst_gop_miu_setting & GOP_MIU_MASK )
    {
        u32_gop_index= dfb_config->mst_gop_available[layer->shared->layer_id];
        if(dfb_config->mst_gop_miu_setting & (0x1L<<u32_gop_index))
        {
            cstf_flag |= CSTF_MIU1;
        }
        else
        {
            cstf_flag |= CSTF_MIU0;
        }
    }
#else
    u32_gop_index = dfb_config->mst_gop_available[layer->shared->layer_id];
    if(0==MApi_GOP_GetMIUSel(u32_gop_index))
    {
        cstf_flag |= CSTF_MIU0;
    }
    else
    {
        cstf_flag |= CSTF_MIU1;
    }

#endif
     ret = dfb_surface_create( layer->core, &conf, cstf_flag, (unsigned long )layer->shared->layer_id, NULL, ret_surface );
     if(ret)
     {
         D_DEBUG_AT( MSTAR_Layer, "\nstar_primaryAllocateSurface failed-->%d\n", ret);
         return ret;
     }
     surface = *ret_surface;
     if(conf.caps & DSCAPS_TRIPLE)
     {
         number_buffers = 3;
     }
     else if(conf.caps & DSCAPS_DOUBLE)
     {
         number_buffers = 2;
     }
     else
     {
         number_buffers = 1;
     }
TRY_AGAIN:
     for(i=0; i<number_buffers; i++)
     {
         CoreSurfaceBufferRole bufferRole;
         switch(i)
         {
            case 0:
                bufferRole = CSBR_IDLE; break;
            case 1:
               bufferRole = CSBR_BACK; break;
            case 2:
               bufferRole = CSBR_FRONT; break;
            default:
                D_ASSERT(0);
               goto FAILED_FREE_SURFACE;
          }

     }

     return DFB_OK;
FAILED_FREE_SURFACE:
        /* Unlink from structure. */

     dfb_surface_unlink( ret_surface );
    return DFB_FAILURE;

}

static DFBResult
mstar_primaryReallocateSurface( CoreLayer             *layer,
                          void                  *driver_data,
                          void                  *layer_data,
                          void                  *region_data,
                          CoreLayerRegionConfig *config,
                          CoreSurface           *surface )
{
     MSTARDriverData *sdrv = driver_data;
     MSTARDeviceData *sdev = sdrv->dev;
     DFBResult         ret;
     CoreSurfaceConfig conf;
     int i, number_buffers;
     int freeSurfInfoSlot;
     u8 u8FBID, u8GOP_Ret;
     CoreSurfaceBufferLock ret_lock;
	 u32 u32Phys = 0;
     bool tryAgain = false;

     DBG_LAYER_MSG ("%s (%d), w =%d, h =%d\n", __FUNCTION__, __LINE__ , config->width, config->height );

     memset(&conf,0,sizeof(CoreSurfaceConfig));
     conf.flags  = CSCONF_SIZE | CSCONF_FORMAT | CSCONF_CAPS;
     conf.size.w = config->width;
     conf.size.h = config->height;
     conf.format = config->format;
     conf.caps   = DSCAPS_VIDEOONLY;

     if (config->buffermode != DLBM_FRONTONLY)
     {
          if(config->buffermode & DLBM_TRIPLE)
            conf.caps |= DSCAPS_TRIPLE;
          else
            conf.caps |= DSCAPS_DOUBLE;
     }

     if(!memcmp(&conf,&surface->config,sizeof(CoreSurfaceConfig)))
     {
          return DFB_OK;
     }

     ret = dfb_surface_reconfig( surface, &conf );

     if (ret)
     	 return ret;


     if (DFB_PIXELFORMAT_IS_INDEXED(config->format) && !surface->palette) {

          DFBResult    ret;
          CorePalette *palette;

          ret = dfb_palette_create( NULL,    /* FIXME */
                                    1 << DFB_COLOR_BITS_PER_PIXEL( config->format ),
                                    &palette );
          if (ret)
               return ret;

          if (config->format == DSPF_LUT8)
               dfb_palette_generate_rgb332_map( palette );

          dfb_surface_set_palette( surface, palette );

          dfb_palette_unref( palette );
     }

     if(conf.caps & DSCAPS_TRIPLE)
     {
         number_buffers = 3;
     }
     else if(conf.caps & DSCAPS_DOUBLE)
     {
         number_buffers = 2;
     }
     else
     {
         number_buffers = 1;
     }
TRY_AGAIN:
     for(i=0; i<number_buffers; i++)
     {
         CoreSurfaceBufferRole bufferRole;
         switch(i)
         {
            case 0:
                bufferRole = CSBR_FRONT; break;
            case 1:
               bufferRole = CSBR_BACK; break;
            case 2:
               bufferRole = CSBR_IDLE; break;
            default:
                D_ASSERT(0);
               goto FAILED_RETURN;
          }


     }
     return DFB_OK;
FAILED_RETURN:

    return ret;
}

static DFBResult
mstar_primaryDeallocateSurface( CoreLayer              *layer,
                                     void                   *driver_data,
                                     void                   *layer_data,
                                     void                   *region_data,
                                     CoreSurface            *surface)
{
     MSTARDriverData *sdrv = driver_data;


     return DFB_OK;
}

     /*
      * Return the z position of the layer.
      */
DFBResult mstar_GetLayerlevel( CoreLayer              *layer,
                                         void                   *driver_data,
                                         void                   *layer_data,
                                         int                    *level )
{
     MSTARDriverData *sdrv = driver_data;
     MSTARDeviceData *sdev = sdrv->dev;
     MSTARLayerData  *slay = layer_data;
      if(level)
          *level =  sdev->layer_zorder[slay->layer_index];
      return DFB_OK;
}

     /*
      * Move the layer below or on top of others (z position).
      */

DFBResult _mstarSetLayerlevel( CoreLayer              *layer,
                                         void                   *driver_data,
                                         void                   *layer_data,
                                         int                     level )
{
       MSTARDriverData *sdrv = driver_data;
       MSTARLayerData  *slay = layer_data;
       MSTARDeviceData *sdev = sdrv->dev;

       DBG_LAYER_MSG("%s(%d): level = %d\n", __FUNCTION__, __LINE__, level);
       fusion_skirmish_prevail( &sdev->beu_lock );
       /**/
        if(sdev->layer_zorder[slay->layer_index] != level)
        {
            sdev->layer_zorder[slay->layer_index] = level;
            mstarReorderGWIN(sdrv);

            if((level>0) && sdev->layer_pinpon_mode[slay->layer_index])
                 MApi_GOP_SetPINPON(sdev->layer_gwin_id[slay->layer_index], TRUE, GOP_PINPON_G3D);

            MApi_GOP_GWIN_Enable( sdev->layer_gwin_id[slay->layer_index], level>0?TRUE:FALSE);

            if(level<=0)
                  MApi_GOP_SetPINPON(sdev->layer_gwin_id[slay->layer_index], FALSE, GOP_PINPON_G3D);

            if(slay->gop_index_r!= 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
            {
                 if((level>0) && sdev->layer_pinpon_mode[slay->layer_index])
                    MApi_GOP_SetPINPON(sdev->layer_gwin_id_r[slay->layer_index], TRUE, GOP_PINPON_G3D);

                 MApi_GOP_GWIN_Enable( sdev->layer_gwin_id_r[slay->layer_index], level>0?TRUE:FALSE);

                 if(level<=0)
                    MApi_GOP_SetPINPON(sdev->layer_gwin_id_r[slay->layer_index], FALSE, GOP_PINPON_G3D);
            }

        }

       fusion_skirmish_dismiss( &sdev->beu_lock );

       return DFB_OK;
}

DFBResult mstar_SetLayerlevel( CoreLayer              *layer,
                                         void                   *driver_data,
                                         void                   *layer_data,
                                         int                     level )
{
    MSTARLayerData  *slay = layer_data;
    CoreLayerCallParameter *parameter;
    FusionSHMPoolShared *shm_pool;
    int ret;

    shm_pool = dfb_core_shmpool_data(layer->core);
    D_ASSERT(shm_pool);

    parameter = SHMALLOC(shm_pool, sizeof(*parameter));
    if(!parameter)
       return DFB_NOSHAREDMEMORY;

    memcpy(&parameter->level,&level,sizeof(level));
    if (fusion_call_execute( &slay->call, FCEF_NONE, CLC_SET_LAYERLEVEL, parameter, &ret ))
    {
        SHFREE(shm_pool, parameter);
        return DFB_FUSION;
    }
    memcpy(&level,&parameter->level,sizeof(level));
    SHFREE(shm_pool, parameter);

    return ret;

}

DFBResult _mstar_SetColorAdjustment( CoreLayer              *layer,
                                         void                   *driver_data,
                                         void                   *layer_data,
                                         DFBColorAdjustment     *adjustment)
{
       MSTARDriverData *sdrv = driver_data;
       MSTARLayerData  *slay = layer_data;
       MSTARDeviceData *sdev = sdrv->dev;
       DFBResult ret = DFB_OK;

       if((adjustment->flags & DCAF_CONTRAST) || (adjustment->flags & DCAF_HUE) || (adjustment->flags & DCAF_SATURATION))
       {
            printf("SetColorAdjustment don't support these adjustment yet! \n");
            return DFB_UNSUPPORTED;
       }

       fusion_skirmish_prevail( &sdev->beu_lock );

       if(adjustment->flags & DCAF_BRIGHTNESS)
       {
            if(0 == MApi_GOP_SetGOPBrightness(slay->gop_index,adjustment->brightness,adjustment->bMSB))
                ret = DFB_FAILURE;
       }
       else
       {
            printf("flag DCAF_BRIGHTNESS not set! \n");
            ret = DFB_FAILURE;
       }

       fusion_skirmish_dismiss( &sdev->beu_lock );

       return ret;
}

DFBResult mstar_SetColorAdjustment( CoreLayer              *layer,
                                         void                   *driver_data,
                                         void                   *layer_data,
                                         DFBColorAdjustment     *adjustment)

{
    MSTARLayerData  *slay = layer_data;
    CoreLayerCallParameter *parameter;
    FusionSHMPoolShared *shm_pool;
    int ret;

    shm_pool = dfb_core_shmpool_data(layer->core);
    D_ASSERT(shm_pool);

    parameter = SHMALLOC(shm_pool, sizeof(*parameter));
    if(!parameter)
       return DFB_NOSHAREDMEMORY;

    memcpy(&parameter->coloradjustment,adjustment,sizeof(DFBColorAdjustment));
    if (fusion_call_execute( &slay->call, FCEF_NONE, CLC_SET_COLORADJUSTMENT, parameter, &ret ))
    {
        SHFREE(shm_pool, parameter);
        return DFB_FUSION;
    }
    memcpy(adjustment,&parameter->coloradjustment,sizeof(DFBColorAdjustment));
    SHFREE(shm_pool, parameter);

    return ret;


}


DFBResult _mstar_ForceWriteEnable(bool bEnable)
{
    DFBResult ret = DFB_OK;
    if(bEnable)
    {
        //printf("\n force write  enable %d\n",getpid());
        MApi_GOP_GWIN_SetForceWrite(TRUE);
    }
    else
    {
        //printf("\n force write  disable %d\n",getpid());
        MApi_GOP_GWIN_SetForceWrite(FALSE);
    }
    return ret;
}


DFBResult _mstar_ConfigDisplayMode( CoreLayer              *layer,
                                         void                   *driver_data,
                                         void                   *layer_data,
                                         CoreSurface            *surface,
                                         CoreSurfaceBufferLock  *lock,
                                         DFBDisplayLayerDeskTopDisplayMode      display_mode)
{
    MSTARLayerData  *slay = layer_data;  
    MSTARDriverData *sdrv = driver_data;
    MSTARDeviceData *sdev = sdrv->dev;
    int ret; 
    u8 u8SubFbId = MAX_GWIN_FB_SUPPORT;
    u16 slotID = 0;
    u8 fbid = MAX_GWIN_FB_SUPPORT; 
    int pitch = lock->pitch;
    MS_U32 fbaddr;

    if(dfb_config->bGOPUsingHWTLB)
        fbaddr = lock->phys;
    else
        fbaddr = mstarGFXAddr(lock->phys, sdev->mst_miu1_cpu_offset, sdev->mst_miu1_hal_offset);
    
    //printf("\nthe fbaddr is %x\n",fbaddr);
    
    DBG_LAYER_MSG("%s(%d): display_mode = %d\n", __FUNCTION__, __LINE__, display_mode);
   
    if(display_mode==slay->layer_displayMode)
        return DFB_OK;

    if(((display_mode!=DLDM_STEREO_FRAME_PACKING && display_mode!=DLDM_STEREO_FRAME_PACKING_FHD)
        &&(slay->layer_displayMode!=DLDM_STEREO_FRAME_PACKING && slay->layer_displayMode!=DLDM_STEREO_FRAME_PACKING_FHD)))
    {
       //no need to do anything
       slay->layer_displayMode = display_mode;
       return DFB_OK;
    }

     if(display_mode==DLDM_STEREO_FRAME_PACKING || display_mode==DLDM_STEREO_FRAME_PACKING_FHD)
    {
        if(!(((surface->config.size.w==FRAME_PACKAGE_WIDTH_1280)&&(surface->config.size.h==FRAME_PACKAGE_HEIGHT_720))
            ||((surface->config.size.w==FRAME_PACKAGE_WIDTH_1920)&&(surface->config.size.h==FRAME_PACKAGE_HEIGHT_1080))))
        {
            //printf("\nthe layer size is width:%d height:%d\n",surface->config.size.w,surface->config.size.h);
            //printf("\ncan not set displaymode DLDM_STEREO_FRAME_PACKING  DLDM_STEREO_FRAME_PACKING mode need 1280x720 or 1920x1080 layer\n");
            return DFB_FAILURE;
        }
    }

     
    do
    {
        fbid  = _mstarFindFBIdbyGWinID(sdrv,sdev->layer_gwin_id[slay->layer_index],&slotID,&surface);
        if(fbid!=0xff)
        {
            MApi_GOP_GWIN_DestroyFB(fbid);
            _mstarSetSurfInfoSlotFree(sdrv,slotID);

            
        }
    }while(fbid!=0xff);     
        

    MApi_GOP_GWIN_Enable( sdev->layer_gwin_id[slay->layer_index], FALSE) ;
    if( sdev->layer_zorder[slay->layer_index] > 0)
        sdev->layer_zorder[slay->layer_index] = 0;
    if(slay->gop_index_r!= 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
    {
        MApi_GOP_GWIN_Enable( sdev->layer_gwin_id_r[slay->layer_index], FALSE) ;
    }
    MApi_GOP_GWIN_UpdateRegOnce(TRUE);    


      switch(display_mode)
      {
            case DLDM_STEREO_FRAME_PACKING:
            case DLDM_STEREO_FRAME_PACKING_FHD: 
            {

               u8 fbid= MApi_GOP_GWIN_GetFreeFBID();
               MApi_GOP_GWIN_CreateFBbyStaticAddr(fbid, 0, 0, surface->config.size.w,surface->config.size.h , _mstarDFBFmt2MSFmt(surface->config.format), fbaddr);    
               MApi_GOP_GWIN_MapFB2Win(fbid,sdev->layer_gwin_id[slay->layer_index]);                    
               MApi_GOP_Set3DOSDMode(sdev->layer_gwin_id[slay->layer_index], fbid, fbid, E_GOP_3D_FRAMEPACKING); 

               if (display_mode == DLDM_STEREO_FRAME_PACKING)
               {
                   gfx_GOPStretch(slay->gop_index, slay->gop_dst,surface->config.size.w, surface->config.size.h, surface->config.size.w, surface->config.size.h, 0, 0);
               }
               else
               {
                   gfx_GOPStretch(slay->gop_index, slay->gop_dst,surface->config.size.w, surface->config.size.h, slay->screen_size.width, slay->screen_size.height, 0, 0);
               }
               
               MApi_GOP_GWIN_MapFB2Win(fbid,sdev->layer_gwin_id[slay->layer_index]);
               slotID=_mstarGetFreeSurfInfoSlot(sdrv);
               if(slotID!=-1)
               {                   
                     _mstarSetSurfInfoSlot(sdrv, slotID,  fbid, surface, lock->buffer, fbaddr,lock->pitch);
               }
                _mstarSetSlotGWinID(sdrv,slotID,sdev->layer_gwin_id[slay->layer_index]);

               //printf("\nDLDM_STERRO_FRAME_PACKING coming here======== the fbid is %d \n",fbid);
         
               break;
            }
            case DLDM_NORMAL:
            case DLDM_STEREO_LEFTRIGHT_3DUI:
            case DLDM_STEREO_TOPBOTTOM_3DUI:
            case DLDM_STEREO_LEFTRIGHT_TOPHALF_3DUI:	
            case DLDM_STEREO_TOPHALF_3DUI:
            {
              u8 fbid= MApi_GOP_GWIN_GetFreeFBID();
              MApi_GOP_GWIN_CreateFBbyStaticAddr(fbid, 0, 0, surface->config.size.w,surface->config.size.h , _mstarDFBFmt2MSFmt(surface->config.format), fbaddr);               
              MApi_GOP_GWIN_MapFB2Win(fbid,sdev->layer_gwin_id[slay->layer_index]);
              MApi_GOP_Set3DOSDMode(sdev->layer_gwin_id[slay->layer_index], fbid, MAX_GWIN_FB_SUPPORT, E_GOP_3D_DISABLE);
              if(slay->gop_index_r != 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
              {
                 GOP_GwinInfo info;
                 //gfx_GOPStretch(slay->gop_index,slay->gop_dst, sreg->config.width/2,sreg->config.height, sreg->config.dest.w/2,sreg->config.dest.h,sreg->config.dest.x, sreg->config.dest.y);
                 gfx_GOPStretch(slay->gop_index,slay->gop_dst, surface->config.size.w/2,surface->config.size.h, slay->screen_size.width/2,slay->screen_size.height,0, 0);

                 memset(&info, 0, sizeof(GOP_GwinInfo));
                 MApi_GOP_GWIN_GetWinInfo(sdev->layer_gwin_id[slay->layer_index],&info);
                 info.u16DispHPixelEnd = (surface->config.size.w/2);
                 info.u16RBlkHPixSize = (info.u16DispHPixelEnd - info.u16DispHPixelStart);
                 MApi_GOP_GWIN_SetWinInfo(sdev->layer_gwin_id[slay->layer_index],&info);
              }
              else
              {                 
                 gfx_GOPStretch(slay->gop_index,slay->gop_dst, surface->config.size.w, surface->config.size.h, slay->screen_size.width, slay->screen_size.height, 0, 0);
              }
              //MApi_GOP_GWIN_MapFB2Win(fbid, sdev->layer_gwin_id[slay->layer_index]); 

              if(slay->gop_index_r!= 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
              {
                 GOP_GwinInfo info;
                 memset(&info, 0, sizeof(GOP_GwinInfo));
                 
                 MApi_GOP_GWIN_MapFB2Win(fbid,sdev->layer_gwin_id_r[slay->layer_index]);
                 MApi_GOP_Set3DOSDMode(sdev->layer_gwin_id_r[slay->layer_index], fbid, MAX_GWIN_FB_SUPPORT, E_GOP_3D_DISABLE);
                 gfx_GOPStretch(slay->gop_index_r,slay->gop_dst, surface->config.size.w, surface->config.size.h, slay->screen_size.width, slay->screen_size.height, 0, 0);
                 //MApi_GOP_GWIN_MapFB2Win(fbid, sdev->layer_gwin_id[slay->layer_index]); 
                 //gfx_GOPStretch(slay->gop_index,slay->gop_dst, sreg->config.width/2,sreg->config.height, sreg->config.dest.w/2,sreg->config.dest.h,sreg->config.dest.x, sreg->config.dest.y);
                 gfx_GOPStretch(slay->gop_index_r,slay->gop_dst, surface->config.size.w/2,surface->config.size.h, slay->screen_size.width/2,slay->screen_size.height,0, 0);

                 MApi_GOP_GWIN_GetWinInfo(sdev->layer_gwin_id_r[slay->layer_index],&info);
                 info.u16DispHPixelEnd = (surface->config.size.w/2);
                 info.u16RBlkHPixSize = (info.u16DispHPixelEnd - info.u16DispHPixelStart);
                 MApi_GOP_GWIN_SetWinInfo(sdev->layer_gwin_id_r[slay->layer_index],&info);
  
              }
              slotID=_mstarGetFreeSurfInfoSlot(sdrv);
              if(slotID!=-1)
              {                   
                    _mstarSetSurfInfoSlot(sdrv, slotID,  fbid, surface, lock->buffer, fbaddr,lock->pitch);
              }
              else
              {
                D_DERROR(DFB_FAILURE,"T\nthere is no slot %s:%s:%d\n",__FUNCTION__,__FILE__,__LINE__);
                D_ASSERT(slotID!=-1);
              }
              _mstarSetSlotGWinID(sdrv,slotID,sdev->layer_gwin_id[slay->layer_index]);

              
              break;
            }
#if 0      
            case DLDM_STEREO_LINE_ALTERNATIVE_3DUI:
            {
              u8 u8NewFbid1= MApi_GOP_GWIN_GetFreeFBID();
              u8 u8NewFbid2= MApi_GOP_GWIN_GetFreeFBID();
              MApi_GOP_GWIN_CreateFBbyStaticAddr(u8NewFbid1, 0, 0, surface->config.size.w,surface->config.size.h/2 , _mstarDFBFmt2MSFmt(surface->config.format), fbaddr);  
              MApi_GOP_GWIN_CreateFBbyStaticAddr(u8NewFbid2, 0, 0, surface->config.size.w,surface->config.size.h/2 , _mstarDFBFmt2MSFmt(surface->config.format), fbaddr+surface->config.size.h/2*pitch);  

              MApi_GOP_GWIN_MapFB2Win(u8NewFbid1,sdev->layer_gwin_id[slay->layer_index]);
              MApi_GOP_Set3DOSDMode(sdev->layer_gwin_id[slay->layer_index], u8NewFbid1, u8NewFbid2, E_GOP_3D_LINE_ALTERNATIVE);
              gfx_GOPStretch(slay->gop_index,slay->gop_dst,surface->config.size.w, surface->config.size.h/2, slay->screen_size.width, slay->screen_size.height/2);

              MApi_GOP_GWIN_MapFB2Win(u8NewFbid1, sdev->layer_gwin_id[slay->layer_index]);  
  
              slotID=_mstarGetFreeSurfInfoSlot(sdrv);
              if(slotID!=-1)
              {                   
                    _mstarSetSurfInfoSlot(sdrv, slotID,  u8NewFbid1, surface, lock->buffer, fbaddr,lock->pitch);
              }
              _mstarSetSlotGWinID(sdrv,slotID,sdev->layer_gwin_id[slay->layer_index]);
              
              
              slotID=_mstarGetFreeSurfInfoSlot(sdrv);
              if(slotID!=-1)
              {                   
                    _mstarSetSurfInfoSlot(sdrv, slotID,  u8NewFbid2, surface, lock->buffer, fbaddr+surface->config.size.h/2*pitch,lock->pitch);
              }
              _mstarSetSlotGWinID(sdrv,slotID,sdev->layer_gwin_id[slay->layer_index]);
              
                
              printf("\nTOPBOTTOM coming here the fbid1 is %d  fbid2 is %d========\n",u8NewFbid1,u8NewFbid2);
                break;
            }
#endif
            default:
                break;

        
      }
      MApi_GOP_GWIN_Enable( sdev->layer_gwin_id[slay->layer_index], TRUE) ;
      if( sdev->layer_zorder[slay->layer_index] >= 0)
          sdev->layer_zorder[slay->layer_index] = 1;
      if(slay->gop_index_r!= 0xf && slay->gop_dst == E_GOP_DST_BYPASS)
      {
          MApi_GOP_GWIN_Enable( sdev->layer_gwin_id_r[slay->layer_index], TRUE) ;
      }
      MApi_GOP_GWIN_UpdateRegOnce(FALSE);   

       
      
      // MApi_GOP_GWIN_CreateFBbyStaticAddr(u8NewFbid, 0, 0, surface->config.size.w,surface->config.size.h , _mstarDFBFmt2MSFmt(surface->config.format), fbaddr);  

       slay->layer_displayMode = display_mode;
       return DFB_OK;


}



    static DFBResult
    mstar_ConfigDisplayMode( CoreLayer             *layer,
                     void                  *driver_data,
                     void                  *layer_data,
                     CoreSurface *surface,
                     CoreSurfaceBufferLock *lock,
                     DFBDisplayLayerDeskTopDisplayMode      display_mode)
                  
    {
            MSTARLayerData  *slay = layer_data;
            CoreLayerCallParameter *parameter;
            FusionSHMPoolShared *shm_pool;
            int ret;
    
            shm_pool = dfb_core_shmpool_data(layer->core);
            D_ASSERT(shm_pool);
            parameter = SHMALLOC(shm_pool, sizeof(*parameter));
    
            if(!parameter)
               return DFB_NOSHAREDMEMORY;
    
            parameter->display_mode = display_mode;
            parameter->surface = surface;
            parameter->lock = lock;
            if (fusion_call_execute( &slay->call, FCEF_NONE, CLC_CONFIG_DISPLAYMODE, parameter, &ret ))
            {
                SHFREE(shm_pool, parameter);
                return DFB_FUSION;
            }

            SHFREE(shm_pool, parameter);
            return ret;
    }


     /*
      * Set the Mirror Mode
      */

DFBResult _mstar_SetHVMirrorEnable( CoreLayer              *layer,
                                         void                   *driver_data,
                                         void                   *layer_data,
                                         bool                     HEnable,
                                         bool                     VEnable)
{
       MSTARDriverData *sdrv = driver_data;
       MSTARLayerData  *slay = layer_data;
       MSTARDeviceData *sdev = sdrv->dev;

       fusion_skirmish_prevail( &sdev->beu_lock );
       /**/
       if(HEnable)
       {
           //printf("[DFB]MApi_GOP_GWIN_SetHMirror(TRUE)\n");
           MApi_GOP_GWIN_SetHMirror(TRUE);
       }
       else
       {
            //printf("[DFB]MApi_GOP_GWIN_SetHMirror(FALSE)\n");
           MApi_GOP_GWIN_SetHMirror(FALSE);
       }

       if(VEnable)
       {
           //printf("[DFB]MApi_GOP_GWIN_SetVMirror(TRUE)\n");
           MApi_GOP_GWIN_SetVMirror(TRUE);
       }
       else
       {
            //printf("[DFB]MApi_GOP_GWIN_SetVMirror(FALSE)\n");
           MApi_GOP_GWIN_SetVMirror(FALSE);
       }
       fusion_skirmish_dismiss( &sdev->beu_lock );

       return DFB_OK;
}

DFBResult mstar_SetHVMirrorEnable( CoreLayer              *layer,
                                         void                   *driver_data,
                                         void                   *layer_data,
                                         bool                     HEnable,
                                         bool                     VEnable)
{
    MSTARLayerData  *slay = layer_data;
    CoreLayerCallParameter *parameter;
    FusionSHMPoolShared *shm_pool;
    int ret;

    shm_pool = dfb_core_shmpool_data(layer->core);
    D_ASSERT(shm_pool);

    parameter = SHMALLOC(shm_pool, sizeof(*parameter));
    if(!parameter)
       return DFB_NOSHAREDMEMORY;

    memcpy(&parameter->HMirrorEnable,&HEnable,sizeof(HEnable));
    memcpy(&parameter->VMirrorEnable,&VEnable,sizeof(VEnable));
    if (fusion_call_execute( &slay->call, FCEF_NONE, CLC_SET_MIRRORMODE, parameter, &ret ))
    {
        SHFREE(shm_pool, parameter);
        return DFB_FUSION;
    }
    memcpy(&HEnable,&parameter->HMirrorEnable,sizeof(HEnable));
    memcpy(&VEnable,&parameter->VMirrorEnable,sizeof(VEnable));
    SHFREE(shm_pool, parameter);

    return ret;

}

    /*
      * Set the LBCouple Mode
      */

DFBResult _mstar_SetLBCoupleEnable( CoreLayer              *layer,
                                         void                   *driver_data,
                                         void                   *layer_data,
                                          bool                     LBCoupleEnable)
{
       MSTARDriverData *sdrv = driver_data;
       MSTARLayerData  *slay = layer_data;
       MSTARDeviceData *sdev = sdrv->dev;

       fusion_skirmish_prevail( &sdev->beu_lock );
       /**/
       if(LBCoupleEnable)
       {
           MApi_GOP_EnableLBCouple(slay->gop_index, TRUE);
       }
       else
       {
           MApi_GOP_EnableLBCouple(slay->gop_index, FALSE);
       }
      
       fusion_skirmish_dismiss( &sdev->beu_lock );

       return DFB_OK;
}

  /*
      * Set the GOP DST ByPass Mode
      */

DFBResult _mstar_SetGOPDstByPassEnable( CoreLayer              *layer,
                                         void                   *driver_data,
                                         void                   *layer_data,
                                          bool                     ByPassEnable)
{
       MSTARDriverData *sdrv = driver_data;
       MSTARLayerData  *slay = layer_data;
       MSTARDeviceData *sdev = sdrv->dev;

       fusion_skirmish_prevail( &sdev->beu_lock );
       /**/
       if(ByPassEnable)// change to Bypass mode.
       {
          MApi_GOP_GWIN_SetGOPDst(slay->gop_index, E_GOP_DST_BYPASS);
          slay->gop_dst = E_GOP_DST_BYPASS;
       }
       else // change to OP mode. 
       {
           MApi_GOP_GWIN_SetGOPDst(slay->gop_index, E_GOP_DST_OP0);
           slay->gop_dst = E_GOP_DST_OP0;
       }
      
       fusion_skirmish_dismiss( &sdev->beu_lock );

       return DFB_OK;
}
    
DFBResult mstar_SetLBCoupleEnable( CoreLayer              *layer,
                                         void                   *driver_data,
                                         void                   *layer_data,
                                         bool                     LBCoupleEnable)
{
    MSTARLayerData  *slay = layer_data;
    CoreLayerCallParameter *parameter;
    FusionSHMPoolShared *shm_pool;
    int ret;

    shm_pool = dfb_core_shmpool_data(layer->core);
    D_ASSERT(shm_pool);

    parameter = SHMALLOC(shm_pool, sizeof(*parameter));
    if(!parameter)
       return DFB_NOSHAREDMEMORY;

    memcpy(&parameter->LBCoupleEnable,&LBCoupleEnable,sizeof(LBCoupleEnable));
    if (fusion_call_execute( &slay->call, FCEF_NONE, CLC_SET_LBCOUPLEMODE, parameter, &ret ))
    {
        SHFREE(shm_pool, parameter);
        return DFB_FUSION;
    }
    memcpy(&LBCoupleEnable,&parameter->LBCoupleEnable,sizeof(LBCoupleEnable));
    SHFREE(shm_pool, parameter);

    return ret;

}

DFBResult mstar_SetGOPDstByPassEnable( CoreLayer              *layer,
                                         void                   *driver_data,
                                         void                   *layer_data,
                                         bool                     ByPassEnable)
{
    MSTARLayerData  *slay = layer_data;
    CoreLayerCallParameter *parameter;
    FusionSHMPoolShared *shm_pool;
    int ret;

    shm_pool = dfb_core_shmpool_data(layer->core);
    D_ASSERT(shm_pool);

    parameter = SHMALLOC(shm_pool, sizeof(*parameter));
    if(!parameter)
       return DFB_NOSHAREDMEMORY;

    memcpy(&parameter->ByPassEnable,&ByPassEnable,sizeof(ByPassEnable));
    if (fusion_call_execute( &slay->call, FCEF_NONE, CLC_SET_GOPBYPASSMODE, parameter, &ret ))
    {
        SHFREE(shm_pool, parameter);
        return DFB_FUSION;
    }
    memcpy(&ByPassEnable,&parameter->ByPassEnable,sizeof(ByPassEnable));
    SHFREE(shm_pool, parameter);

    return ret;

}


DFBResult _mstar_SetHVScale( CoreLayer              *layer,
                                         void                   *driver_data,
                                         void                   *layer_data,
                                         void                   *region_data,
                                         int                     HScale,
                                         int                     VScale)
{
       MSTARDriverData *sdrv = driver_data;
       MSTARLayerData  *slay = layer_data;
       MSTARRegionData *sreg = region_data;
       MSTARDeviceData *sdev = sdrv->dev;      

       fusion_skirmish_prevail( &sdev->beu_lock );
       /**/
       MApi_GOP_GWIN_Set_STRETCHWIN(slay->gop_index,slay->gop_dst, sreg->config.dest.x, sreg->config.dest.y,sreg->config.width, sreg->config.height);
       MApi_GOP_GWIN_Set_HSCALE(TRUE, sreg->config.width, HScale);
       MApi_GOP_GWIN_Set_VSCALE(TRUE, sreg->config.height, VScale);
       
       if (slay->gop_dst == E_GOP_DST_OP0)
           MApi_GOP_SetGOPHStart(slay->gop_index, mstar_sc_get_h_cap_start());
       
       fusion_skirmish_dismiss( &sdev->beu_lock );

       return DFB_OK;
}

DFBResult mstar_SetHVScale( CoreLayer              *layer,
                                         void                   *driver_data,
                                         void                   *layer_data,
                                         void                   *region_data,
                                         int                     HScale,
                                         int                     VScale)
{
    MSTARLayerData  *slay = layer_data;
    CoreLayerCallParameter *parameter;
    FusionSHMPoolShared *shm_pool;
    int ret;

    shm_pool = dfb_core_shmpool_data(layer->core);
    D_ASSERT(shm_pool);

    parameter = SHMALLOC(shm_pool, sizeof(*parameter));
    if(!parameter)
       return DFB_NOSHAREDMEMORY;

    parameter->HScale = HScale;
    parameter->VScale = VScale;
    parameter->reg_data= region_data;

    if (fusion_call_execute( &slay->call, FCEF_NONE, CLC_SET_GOPSCALE, parameter, &ret ))
    {
        SHFREE(shm_pool, parameter);
        return DFB_FUSION;
    }

    SHFREE(shm_pool, parameter);

    return ret;

}

static EN_GOP_DST_TYPE transformDfbDst2Utopia(DFBDisplayLayerGOPDST         GopDst)
{
    EN_GOP_DST_TYPE gop_dst;
    switch (GopDst)
    {
        case DLGD_IP0:
            gop_dst = E_GOP_DST_IP0;
            break;
            
        case DLGD_MIXER2VE:
            gop_dst = E_GOP_DST_MIXER2VE;
            break;
            
        case DLGD_OP0:
            gop_dst = E_GOP_DST_OP0;
            break;
            
        case DLGD_VOP:
            gop_dst = E_GOP_DST_VOP;
            break;
            
        case DLGD_IP1:
            gop_dst = E_GOP_DST_IP1;
            break;
            
        case DLGD_IP_MAIN:
            gop_dst = E_GOP_DST_IP_MAIN;
            break;
            
        case DLGD_IP_SUB:
            gop_dst = E_GOP_DST_IP_SUB;
            break;
            
        case DLGD_MIXER2OP:
            gop_dst = E_GOP_DST_MIXER2OP;
            break;
            
        case DLGD_VOP_SUB:
            gop_dst = E_GOP_DST_VOP_SUB;
            break;
            
        case DLGD_FRC:
            gop_dst = E_GOP_DST_FRC;
            break;
            
        case DLGD_VE:
            gop_dst = E_GOP_DST_VE;
            break;
            
        case DLGD_OP1:
            gop_dst = E_GOP_DST_OP1;
            break;
            
        case DLGD_MIXER2OP1:
            gop_dst = E_GOP_DST_MIXER2OP1;
            break;
            
        case DLGD_DIP:
            gop_dst = E_GOP_DST_DIP;
            break;
            
        case DLGD_GOPScaling:
            gop_dst = E_GOP_DST_GOPScaling;
            break;
            
        case DLGD_BYPASS:
            gop_dst = E_GOP_DST_BYPASS;
            break;
            
        default:
            gop_dst = E_GOP_DST_OP0;
            break;
    }
    return gop_dst;
}


static DFBDisplayLayerGOPDST transformUtopia2DfbDst(EN_GOP_DST_TYPE         gop_dst)
{
    DFBDisplayLayerGOPDST GopDst;
    switch (gop_dst)
    {
        case E_GOP_DST_IP0:
            GopDst = DLGD_IP0;
            break;
            
        case E_GOP_DST_MIXER2VE:
            GopDst = DLGD_MIXER2VE;
            break;
            
        case E_GOP_DST_OP0:
            GopDst = DLGD_OP0;
            break;
            
        case E_GOP_DST_VOP:
            GopDst = DLGD_VOP;
            break;
            
        case E_GOP_DST_IP1:
            GopDst = DLGD_IP1;
            break;
            
        case E_GOP_DST_IP_MAIN:
            GopDst = DLGD_IP_MAIN;
            break;
            
        case E_GOP_DST_IP_SUB:
            GopDst = DLGD_IP_SUB;
            break;
            
        case E_GOP_DST_MIXER2OP:
            GopDst = DLGD_MIXER2OP;
            break;
            
        case E_GOP_DST_VOP_SUB:
            GopDst = DLGD_VOP_SUB;
            break;
            
        case E_GOP_DST_FRC:
            GopDst = DLGD_FRC;
            break;
            
        case E_GOP_DST_VE:
            GopDst = DLGD_VE;
            break;
            
        case E_GOP_DST_OP1:
            GopDst = DLGD_OP1;
            break;
            
        case E_GOP_DST_MIXER2OP1:
            GopDst = DLGD_MIXER2OP1;
            break;
            
        case E_GOP_DST_DIP:
            GopDst = DLGD_DIP;
            break;
            
        case E_GOP_DST_GOPScaling:
            GopDst = DLGD_GOPScaling;
            break;
            
        case E_GOP_DST_BYPASS:
            GopDst = DLGD_BYPASS;
            break;
            
        default:
            GopDst = DLGD_UNKNOWN;
            break;
    }
    return GopDst;
}

DFBResult mstar_SetGOPDst( CoreLayer              *layer,
                                         void                   *driver_data,
                                         void                   *layer_data,
                                         DFBDisplayLayerGOPDST    GopDst)
{
    MSTARLayerData  *slay = layer_data;
    MSTARDriverData *sdrv = driver_data;
    CoreLayerCallParameter *parameter;
    FusionSHMPoolShared *shm_pool;
    EN_GOP_DST_TYPE gop_dst;
    int ret;

    D_ASSERT(layer);
    D_ASSERT(driver_data);
    D_ASSERT(layer_data);
    D_ASSERT(layer->core);

    shm_pool = dfb_core_shmpool_data(layer->core);
    D_ASSERT(shm_pool);

    parameter = SHMALLOC(shm_pool, sizeof(*parameter));
    if(!parameter)
       return DFB_NOSHAREDMEMORY;
    gop_dst = transformDfbDst2Utopia(GopDst);
    
    memcpy(&parameter->GopDst,&gop_dst,sizeof(gop_dst));
    if (fusion_call_execute( &slay->call, FCEF_NONE, CLC_SET_GOPDST, parameter, &ret ))
    {
        SHFREE(shm_pool, parameter);
        return DFB_FUSION;
    }

    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;
    }

    SHFREE(shm_pool, parameter);

    return ret;    
}

DFBResult _mstar_SetGOPDst( CoreLayer              *layer,
                                         void                   *driver_data,
                                         void                   *layer_data,
                                         EN_GOP_DST_TYPE    GopDst)
{
    MSTARDriverData *sdrv = driver_data;
    MSTARLayerData  *slay = layer_data;
    MSTARDeviceData *sdev = sdrv->dev;
    EN_GOP_DST_TYPE gop_dst = GopDst;
    DFBDisplayLayerID layerid;
    int ret;

    D_ASSERT(layer);
    D_ASSERT(driver_data);
    D_ASSERT(layer_data);
    D_ASSERT(sdrv->dev);

    DBG_LAYER_MSG("%s(%d): GopDst = %d\n", __FUNCTION__, __LINE__, gop_dst);

    fusion_skirmish_prevail( &sdev->beu_lock );

    slay->gop_dst = gop_dst;
    MApi_GOP_GWIN_SetGOPDst(slay->gop_index, gop_dst);

    if(slay->gop_index_r!= 0xf)
    {
        MApi_GOP_GWIN_SetGOPDst(slay->gop_index_r, gop_dst);
    }

    switch (gop_dst)
    {
        case E_GOP_DST_IP0:
        {
            layer->screen = sdrv->ip0_screen;

            MS_XC_DST_DispInfo dstDispInfo;

            if(MApi_XC_GetDstInfo(&dstDispInfo,sizeof(MS_XC_DST_DispInfo),E_GOP_XCDST_IP1_MAIN))
            {
                 if(dstDispInfo.bYUVInput)
                 {
                      MApi_GOP_GWIN_OutputColor(GOPOUT_YUV);
                 }
                 else
                 {
                      MApi_GOP_GWIN_OutputColor(GOPOUT_RGB);
                 }
            }
        }
        break;
        
        case E_GOP_DST_OP0:
        {
           MS_PNL_DST_DispInfo dstDispInfo;
           
           layer->screen = sdrv->op_screen;
           
           MApi_PNL_GetDstInfo(&dstDispInfo, sizeof(MS_PNL_DST_DispInfo));
           if(dstDispInfo.bYUVOutput)
           {
                MApi_GOP_GWIN_OutputColor(GOPOUT_YUV);
           }
           else
           {
                if(dfb_config->mst_GOP_Set_YUV)
                {
                    MApi_GOP_GWIN_OutputColor(GOPOUT_YUV);
                }
                else
                {
                    MApi_GOP_GWIN_OutputColor(GOPOUT_RGB);
                }
            }
        }
        break;
       
        case E_GOP_DST_BYPASS:
        {
            layer->screen = sdrv->op_screen;
        }
        break;

        case E_GOP_DST_VE:
        {
            //For K3 Set the gopVETimingType
            VE_DrvStatus DrvStatus;
            
            layer->screen = sdrv->ve_screen;
            
            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);
        }
        break;

        default:

            break;
    }
    
    layerid = dfb_layer_id(layer);
    ret = fusion_reactor_dispatch(sdev->reactor[layerid], &gop_dst, false, NULL);
    //printf("%s:%d, ret = 0x%x, pid =%d\n", __FUNCTION__, __LINE__, ret, getpid());

        fusion_skirmish_dismiss( &sdev->beu_lock );

       return DFB_OK;
}

DFBResult mstar_GetGOPDst( CoreLayer              *layer,
                                         void                   *driver_data,
                                         void                   *layer_data,
                                         DFBDisplayLayerGOPDST    *GopDst)
{
    MSTARDriverData *sdrv = driver_data;
    MSTARDeviceData *sdev = sdrv->dev;
    MSTARLayerData	*slay = layer_data;
    DFBDisplayLayerID layerid;


    if(GopDst)
    {
        *GopDst = transformUtopia2DfbDst(slay->gop_dst);
    }
    return DFB_OK;
}

DFBResult mstar_SetBootLogoPatch( CoreLayer              *layer,
                                  void                   *driver_data,
                                  void                   *layer_data,
                                  int    miusel)
{
    MSTARLayerData  *slay = layer_data;
    MSTARDriverData *sdrv = driver_data;
    CoreLayerCallParameter *parameter;
    FusionSHMPoolShared *shm_pool;
    int ret;

    D_ASSERT(layer);
    D_ASSERT(driver_data);
    D_ASSERT(layer_data);
    D_ASSERT(layer->core);

    shm_pool = dfb_core_shmpool_data(layer->core);
    D_ASSERT(shm_pool);

    parameter = SHMALLOC(shm_pool, sizeof(*parameter));
    if(!parameter)
       return DFB_NOSHAREDMEMORY;

    memcpy(&parameter->miusel,&miusel,sizeof(miusel));
    if (fusion_call_execute( &slay->call, FCEF_NONE, CLC_SET_GOPBLOGO, parameter, &ret ))
    {
        SHFREE(shm_pool, parameter);
        return DFB_FUSION;
    }
      
    SHFREE(shm_pool, parameter);

    return ret;    
}

// Patch for time expand of display the boot logo.
DFBResult _mstar_SetBootLogoPatch( CoreLayer              *layer,
                                   void                   *driver_data,
                                   void                   *layer_data,
                                   int    miusel)
{
       MSTARDriverData *sdrv = driver_data;
       MSTARLayerData  *slay = layer_data;
       MSTARDeviceData *sdev = sdrv->dev;
       GOP_InitInfo gopInitInfo;

       D_ASSERT(layer);
       D_ASSERT(driver_data);
       D_ASSERT(layer_data);
       D_ASSERT(sdrv->dev);

       fusion_skirmish_prevail( &sdev->beu_lock );
       /**/       

        //Prepare GOP Init Params:
       gopInitInfo.u16PanelWidth = dfb_config->mst_lcd_width;
       gopInitInfo.u16PanelHeight= dfb_config->mst_lcd_height;
       gopInitInfo.u16PanelHStr = mstar_sc_get_h_cap_start();
       gopInitInfo.u32GOPRBAdr = 0;
       gopInitInfo.u32GOPRBLen = 0;
       gopInitInfo.bEnableVsyncIntFlip = TRUE;
       
       
       EN_GOP_IGNOREINIT eIgnor;
       eIgnor = 0;
       MApi_GOP_SetConfig(E_GOP_IGNOREINIT,&eIgnor); //close  GOP IGNORE INIT
       MApi_GOP_InitByGOP(&gopInitInfo,  slay->gop_index);//Initial boot logo GOP

       MApi_GOP_MIUSel(slay->gop_index, (EN_GOP_SEL_TYPE) miusel); //Set the GOP miu select to correct location. 
       //printf("[DFB] MApi_GOP_MIUSel  %d\n");
  
       fusion_skirmish_dismiss( &sdev->beu_lock );

       return DFB_OK;
}


FusionCallHandlerResult
mstar_layer_funcs_call_handler( int           caller,   /* fusion id of the caller */
                                                           int           call_arg, /* optional call parameter */
                                                           void         *call_ptr, /* optional call parameter */
                                                           void         *ctx,      /* optional handler context */
                                                           unsigned int  serial,
                                                           int          *ret_val )
{
     CoreLayerCommand  command = call_arg;
     CoreLayer        *layer;
     CoreLayerCallParameter* parameter = call_ptr;
    layer = (CoreLayer *)ctx;
    MSTARLayerData  *slay = layer->layer_data;
    //printf("\n the command is %d  pid is %d\n",command,getpid());
    D_ASSERT(layer);

     switch (command) {
        case CLC_ADD_REGION:
            {
                MSTARRegionData *reg_data;
                reg_data = parameter->reg_data;
                *ret_val = _mstarAddRegion( layer,
                                      layer->driver_data, layer->layer_data,
                                      reg_data, &parameter->config);
            }
            break;
        case CLC_TEST_REGION:
            {
                CoreLayerRegionConfigFlags *flags;
                CoreLayerRegionConfig *config;

                flags = &parameter->flags;
                config = &parameter->config;

                *ret_val = _mstarTestRegion( layer, layer->driver_data, layer->layer_data,
                                   config, flags);
            }
            break;
        case CLC_SET_REGION:
            {
                CoreSurface *surface;

                surface = parameter->surface;

                *ret_val = _mstarSetRegion( layer, layer->driver_data, layer->layer_data,
                                  parameter->reg_data, &parameter->config, parameter->flags,
                                  surface, surface ? surface->palette : NULL, parameter->lock );
            }
            break;
        case CLC_REMOVE_REGION:
            {
                *ret_val = _mstarRemoveRegion( layer, layer->driver_data,
                                layer->layer_data, parameter->reg_data);
            }

             break;
         case CLC_SET_LAYERLEVEL:
            {
                    int *level;
                    level = &parameter->level;

                    *ret_val =  _mstarSetLayerlevel( layer, layer->driver_data,
                                     layer->layer_data, *level );
            }

            break;
        case CLC_SET_COLORADJUSTMENT:
            {
                DFBColorAdjustment     *adjustment;
                adjustment = &parameter->coloradjustment;

                *ret_val =  _mstar_SetColorAdjustment( layer, layer->driver_data,
                                     layer->layer_data, adjustment);
            }
            break;
        case CLC_FORCEWRITE_ENABLE:
            {
                _mstar_ForceWriteEnable(true);
                //printf("\n_mstar force write enable\n");
            }
            break;
        case CLC_FORCEWRITE_DISABLE:
            {
                _mstar_ForceWriteEnable(false);
                //printf("\n_mstar force write disable\n");
            }
            break;
         case CLC_CONFIG_DISPLAYMODE:
            {
                DFBDisplayLayerDeskTopDisplayMode display_mode;
                display_mode = parameter->display_mode; 
                *ret_val = _mstar_ConfigDisplayMode(layer, layer->driver_data,
                                     layer->layer_data,parameter->surface,parameter->lock,parameter->display_mode);
            }
            break;
         case CLC_SET_MIRRORMODE:
            {
                    bool *HMirrorEnable;
                    bool *VMirrorEnable;
                    HMirrorEnable = &parameter->HMirrorEnable;
                    VMirrorEnable = &parameter->VMirrorEnable;

                    *ret_val =  _mstar_SetHVMirrorEnable( layer, layer->driver_data,
                                     layer->layer_data, *HMirrorEnable, *VMirrorEnable);
            }

            break;  
         case CLC_SET_LBCOUPLEMODE:
            {
                    bool *LBCoupleEnable;
                    LBCoupleEnable = &parameter->LBCoupleEnable;

                    *ret_val =  _mstar_SetLBCoupleEnable( layer, layer->driver_data,
                                     layer->layer_data, *LBCoupleEnable);
            }

            break;  
         case CLC_SET_GOPBYPASSMODE:
            {
                    bool *ByPassEnable;
                    ByPassEnable = &parameter->ByPassEnable;

                    *ret_val =  _mstar_SetGOPDstByPassEnable( layer, layer->driver_data,
                                     layer->layer_data, *ByPassEnable);
            }

            break;  
         case CLC_SET_GOPSCALE:
            {
                    int *HScale;
                    int *VScale;
                    HScale = &parameter->HScale;
                    VScale = &parameter->VScale;

                    *ret_val =  _mstar_SetHVScale( layer, layer->driver_data,
                                     layer->layer_data, parameter->reg_data,*HScale, *VScale);
            }

            break;  
         case CLC_SET_GOPDST:
            {
                    EN_GOP_DST_TYPE *GopDst;
                    GopDst = &parameter->GopDst;

                    *ret_val =  _mstar_SetGOPDst( layer, layer->driver_data,
                                     layer->layer_data, *GopDst);
            }

            break;  
         case CLC_SET_GOPBLOGO:
            {
                    int *miusel;
                    miusel = &parameter->miusel;

                    *ret_val =  _mstar_SetBootLogoPatch( layer, layer->driver_data,
                                     layer->layer_data, *miusel);
            }

            break;     
        default:
           D_BUG( "unknown  Command '%d'", command );
           *ret_val = DFB_BUG;
     }


     return FCHR_RETURN;
}




DFBResult mstar_ConfigShadowLayer( CoreLayer              *layer,
                                         void                   *driver_data,
                                         void                   *layer_data,
                                         ShadowLayerConfig      *shadowLayer_info)
{

    MSTARDriverData *sdrv = driver_data;
    MSTARDeviceData *sdev = sdrv->dev;
    MSTARLayerData  *slay = layer_data;
    DFBResult ret = DFB_OK;

    D_ASSERT(layer);
    D_ASSERT(driver_data);
    D_ASSERT(layer_data);
    D_ASSERT(sdrv->dev);
	
    fusion_skirmish_prevail( &sdev->beu_lock );

    //this layer is set as shadowlayer
    if(shadowLayer_info->bShadowLayer)
    {
        if(shadowLayer_info->bindShadowLayer)
        {
            if(slay->ShadowFlags&SLF_SHADOW_LAYER_BOOLEAN)
            {
                printf("\nthis layer :%d has been bind as shadowlayer by other layers\n",slay->layer_index);
                fusion_skirmish_dismiss( &sdev->beu_lock );
                return DFB_FAILURE;
            }
            else if(slay->ShadowFlags & SLF_SHADOW_LAYER_INDEXALL)
            {
                printf("\nthis layer :%d has bind other shadowlayer ,so it can not set as shadowlayer\n");
                fusion_skirmish_dismiss( &sdev->beu_lock );
                return DFB_FAILURE;
            }
            else
            {
                slay->ShadowFlags |= SLF_SHADOW_LAYER_BOOLEAN;
                printf("\nthis layer :%d is set  as shadowlayer\n",slay->layer_index);
            }
       }
       else if(shadowLayer_info->unbindShadowLayer)
       {
            slay->ShadowFlags &= (~SLF_SHADOW_LAYER_BOOLEAN);
            printf("\nshadow layer %d SLF_SHADOW_LAYER_BOOLEAN flag is cleared \n",slay->layer_index);
       }

    }
    else  //this layer  will bind /ubind other layers as shadow layer
    {
        u32 u32Phys = 0;
        if(shadowLayer_info->bindShadowLayer)
        {

            slay->ShadowFlags |= (SLF_SHADOW_LAYER_INDEX0<<shadowLayer_info->shadowLayerIndex);
            u32Phys = sdrv->layerFlipInfo[slay->layer_index].CurPhysAddr;
        }
        else if(shadowLayer_info->unbindShadowLayer)
        {
            slay->ShadowFlags &= (~(SLF_SHADOW_LAYER_INDEX0<<shadowLayer_info->shadowLayerIndex));
            u32Phys = sdrv->layerFlipInfo[shadowLayer_info->shadowLayerIndex].CurPhysAddr;
        }

        u8 timeouttimes = 0;
        if(u32Phys)
        {
            do
            {
                 u16 targetQueueCnt = 1;
                 u16 u16QueueCnt = targetQueueCnt;
                 //if(MApi_GOP_Switch_GWIN_2_FB(sdev->layer_gwin_id[slay->layer_index], u16FBId, tagID, &u16QueueCnt))
                 if(MApi_GOP_Switch_GWIN_2_FB_BY_ADDR(sdev->layer_gwin_id[shadowLayer_info->shadowLayerIndex], u32Phys, 0, &u16QueueCnt))
                 {
                    //printf("MApi_GOP_Switch_GWIN_2_FB_Fusion success , break \n");
                    break;
                 }
                 timeouttimes ++;

                 if(u16QueueCnt <= targetQueueCnt-1)
                 {
                      printf("Serious warning, unknow error!!\n");
                      fusion_skirmish_dismiss( &sdev->beu_lock );
                      return DFB_FAILURE;
                 }
            }while(timeouttimes < 30);

            if(timeouttimes >= 30)
            {
                int i;
                for(i = 0 ; i < timeouttimes ; i ++)
                    printf("[%d]#################### layer=%d , gwin=%d \n",i,slay->layer_index,sdev->layer_gwin_id[slay->layer_index]);
            }
        }

    }

    fusion_skirmish_dismiss( &sdev->beu_lock );

    return ret;
}

//- AddRegion() will be called when the window is first displayed
//- TestRegion() and SetRegion() are called when the configuration changes
//  eg. the window is moved or resized.
//- RemoveRegion() will be called when the window is destroyed.


DisplayLayerFuncs mstarLayerFuncs = {
     LayerDataSize:      mstarLayerDataSize,
     RegionDataSize:     mstarRegionDataSize,
     InitLayer:          mstarInitLayer,

     TestRegion:         mstarTestRegion,
     AddRegion:          mstarAddRegion,
     SetRegion:          mstarSetRegion,
     RemoveRegion:       mstarRemoveRegion,
     FlipRegion:         mstarFlipRegion,
     AllocateSurface:  mstar_primaryAllocateSurface,
     ReallocateSurface:   mstar_primaryReallocateSurface,
     DeallocateSurface:   mstar_primaryDeallocateSurface,
     GetLevel:               mstar_GetLayerlevel,
     SetLevel:               mstar_SetLayerlevel,
     SetColorAdjustment:    mstar_SetColorAdjustment,
     ConfigShadowLayer :   mstar_ConfigShadowLayer,
     ConfigDisplayMode :   mstar_ConfigDisplayMode,
     SetHVMirrorEnable :    mstar_SetHVMirrorEnable,
     SetLBCoupleEnable :    mstar_SetLBCoupleEnable,
     SetGOPDstByPassEnable :   mstar_SetGOPDstByPassEnable,
     SetHVScale :         mstar_SetHVScale,
     SetGOPDst :   mstar_SetGOPDst,
     GetGOPDst :	mstar_GetGOPDst,
     SetBootLogoPatch :   mstar_SetBootLogoPatch

     //UpdateRegion:       mstarUpdateRegion
};

