//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
// Copyright (c) Samsung Electronics. Co. LTD. All rights reserved.

/*++

THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:

    ddoverlay.cpp

Abstract:

    This module implements the main class that derived from DDGPE of display driver to support DirectDraw
    In this part, there are codes that implement base logical HW control functions to use DirectDraw Overlay

Functions:

    Overlay Resource Control, Overlay Enable/Disable

Notes:

--*/

#include "precomp.h"

#ifdef OVERLAY_USE_MEM2MEM
void Disp_post_thread(LPVOID lpParam)
{
    SMDKDisp* tempSmdk = (SMDKDisp*)lpParam;
    tempSmdk->Post_thread();
}
#endif

BOOL
SMDKDisp::OverlayAllocResource(BOOL bPostAttached)
{
    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] ++%s(%d)\n\r"), _T(__FUNCTION__), bPostAttached));

    DWORD dwBytes;

    // Request FIMD Win1 H/W Resource to Video Engine Driver for Overlay Window
    if ( !DeviceIoControl(m_hVideoDrv, IOCTL_OVERLAY_WINDOW_REQUEST, NULL, 0, NULL, 0, &dwBytes, NULL) )
    {
        RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_OVERLAY_WINDOW_REQUEST Failed\n\r"), _T(__FUNCTION__)));
        goto AllocFail;
    }

    if(bPostAttached)
    {
        // Request Post Processor H/W Resource to Video Engine Driver for Overlay Window
        if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_RSC_REQUEST_POST, NULL, 0, NULL, 0, &dwBytes, NULL) )
        {
            RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_SVE_RSC_REQUEST_POST Failed\n\r"), _T(__FUNCTION__)));
            goto AllocFail;
        }
#ifdef OVERLAY_USE_MEM2MEM
        for(int i=0;i<OVERLAY_FB_NUM;i++)
        {
            if(m_pOverlayDMAOutputBuf[i] != NULL)
            {
                delete m_pOverlayDMAOutputBuf[i];
                m_pOverlayDMAOutputBuf[i] = NULL;
            }
            AllocSurface((DDGPESurf**)&(m_pOverlayDMAOutputBuf[i]), \
                            m_OverlayCtxt.uiDstWidth, \
                            m_OverlayCtxt.uiDstHeight, gpe32Bpp, \
                            EGPEFormatToEDDGPEPixelFormat[gpe32Bpp], \
                            GPE_REQUIRE_VIDEO_MEMORY);
            if(m_pOverlayDMAOutputBuf[i] == NULL)
            {
                RETAIL_DISP_MSG(DISP_ZONE_ERROR,(TEXT("m_pOverlayDMAOutputBuf[%d] Surface Allocation is failed. %d\n"),i,__LINE__));
                RETAIL_DISP_MSG(DISP_ZONE_ERROR,(TEXT("Maybe There's no sufficient video memory. please increase video memory\r\n")));
                goto AllocFail;
            }
        }

        m_hPostReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
        if(NULL == m_hPostReadyEvent)
        {
            RETAIL_DISP_MSG(DISP_ZONE_ERROR,(_T("[DISPDRV:ERR] %s() : CreateEvent() m_hPostReadyEvent Failed \n\r"),_T(__FUNCTION__)));
            goto AllocFail;
        }
        SetEvent(m_hPostReadyEvent);
        //RETAIL_DISP_MSG(DISP_ZONE_TEMP,(_T("[DISPDRV] %s() : SetEvent(m_hPostReadyEvent)\r\n"),_T(__FUNCTION__)));

        m_hPostBusyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
        if(NULL == m_hPostBusyEvent)
        {
            RETAIL_DISP_MSG(DISP_ZONE_ERROR,(_T("[DISPDRV:ERR] %s() : CreateEvent() m_hPostBusyEvent Failed \n\r"),_T(__FUNCTION__)));
            goto AllocFail;
        }

        m_hPostTreadEnd = CreateEvent(NULL, FALSE, FALSE, NULL);
        if(NULL == m_hPostTreadEnd)
        {
            RETAIL_DISP_MSG(DISP_ZONE_ERROR,(_T("[DISPDRV:ERR] %s() : CreateEvent() m_hPostTreadEnd Failed \n\r"),_T(__FUNCTION__)));
            goto AllocFail;
        }

        m_bPostThreadExit = FALSE;
        m_hPostIST = CreateThread(NULL, 0, \
                (LPTHREAD_START_ROUTINE)Disp_post_thread, this, 0, NULL);
        if (m_hPostIST == NULL)
        {
            RETAIL_DISP_MSG(DISP_ZONE_ERROR,(_T("[DISPDRV:ERR] %s() : m_hPostIST CreateThread() Fail\n\r"),_T(__FUNCTION__)));
            goto AllocFail;
        }
#endif // OVERLAY_USE_MEM2MEM
    }

    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] --%s()\n\r"), _T(__FUNCTION__)));

    return TRUE;

AllocFail:

    // Release Partially Allocated Resource
    OverlayReleaseResource(bPostAttached);

    RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] --%s() : Failed\n\r"), _T(__FUNCTION__)));

    return FALSE;
}

BOOL
SMDKDisp::OverlayReleaseResource(BOOL bPostAttached)
{
    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] ++%s(%d)\n\r"), _T(__FUNCTION__), bPostAttached));

    BOOL bRet = TRUE;
    DWORD dwBytes;

    // Release FIMD Win1 H/W Resource to Video Engine Driver for Overlay Window
    if ( !DeviceIoControl(m_hVideoDrv, IOCTL_OVERLAY_WINDOW_RELEASE, NULL, 0, NULL, 0, &dwBytes, NULL) )
    {
        RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_OVERLAY_WINDOW_RELEASE Failed\n\r"), _T(__FUNCTION__)));
        bRet = FALSE;
    }

    if(bPostAttached)
    {
        // Release Post Processor H/W Resource to Video Engine Driver for Overlay Window
        if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_RSC_RELEASE_POST, NULL, 0, NULL, 0, &dwBytes, NULL) )
        {
            RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_SVE_RSC_RELEASE_POST Failed\n\r"), _T(__FUNCTION__)));
            bRet = FALSE;
        }
#ifdef OVERLAY_USE_MEM2MEM
        for(int i=0;i<OVERLAY_FB_NUM;i++)
        {
            if(m_pOverlayDMAOutputBuf[i] != NULL)
            {
                delete m_pOverlayDMAOutputBuf[i];
            }
            m_pOverlayDMAOutputBuf[i] = NULL;
        }

        if (m_hPostIST != NULL)
        {
            m_bPostThreadExit = TRUE;
            SetEvent(m_hPostBusyEvent);
            //RETAIL_DISP_MSG(DISP_ZONE_TEMP,(_T("[DISPDRV] %s() : SetEvent(m_hPostBusyEvent)\r\n"),_T(__FUNCTION__)));
            //RETAIL_DISP_MSG(DISP_ZONE_TEMP,(_T("[DISPDRV] %s() : WaitForSingleObject(m_hPostTreadEnd)\r\n"),_T(__FUNCTION__)));
            WaitForSingleObject(m_hPostTreadEnd, INFINITE);
        }

        if (m_hPostBusyEvent != NULL)
        {
            CloseHandle(m_hPostBusyEvent);
            m_hPostBusyEvent = NULL;
        }

        if (m_hPostReadyEvent != NULL)
        {
            CloseHandle(m_hPostReadyEvent);
            m_hPostReadyEvent = NULL;
        }

        if (m_hPostTreadEnd != NULL)
        {
            CloseHandle(m_hPostTreadEnd);
            m_hPostTreadEnd = NULL;
        }

        m_uiCurPostFB = 0;
        m_hPostIST = NULL;
#endif // OVERLAY_USE_MEM2MEM
    }

    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] --%s()\n\r"), _T(__FUNCTION__)));

    return bRet;
}


BOOL
SMDKDisp::OverlayInitialize(SMDKSurf* pOverlaySurface, RECT *pSrc, RECT *pDest)
{
    BOOL bRet = TRUE;

    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DDHAL:INF] OverlayInitialize() (%d,%d) (%d,%d,%d,%d) (%d,%d,%d,%d)\n\r"),
                    pOverlaySurface->Width(), pOverlaySurface->Height(),
                    pSrc->left, pSrc->top, pSrc->right, pSrc->bottom,
                    pDest->left, pDest->top, pDest->right, pDest->bottom));

    EnterCriticalSection(&m_csDevice);

    m_OverlayCtxt.pSurface = pOverlaySurface;

    switch(m_iRotate)
    {
    case DMDO_0:
    default:
        // Driver support Overlay Source Clipping
        m_OverlayCtxt.uiSrcWidth = pSrc->right - pSrc->left;
        m_OverlayCtxt.uiSrcHeight = pSrc->bottom - pSrc->top;
        m_OverlayCtxt.uiSrcOffsetX = pSrc->left;
        m_OverlayCtxt.uiSrcOffsetY = pSrc->top;

        //  Driver support Overlay Destination Stretch
        m_OverlayCtxt.uiDstWidth = pDest->right - pDest->left;
        m_OverlayCtxt.uiDstHeight = pDest->bottom - pDest->top;
        m_OverlayCtxt.uiDstOffsetX = pDest->left;
        m_OverlayCtxt.uiDstOffsetY = pDest->top;
        break;
    case DMDO_90:
        // Driver support Overlay Source Clipping
        m_OverlayCtxt.uiSrcWidth = pSrc->bottom - pSrc->top;
        m_OverlayCtxt.uiSrcHeight = pSrc->right - pSrc->left;
        m_OverlayCtxt.uiSrcOffsetX = pSrc->top;
        m_OverlayCtxt.uiSrcOffsetY = pOverlaySurface->Height()
                                        - m_OverlayCtxt.uiSrcHeight - pSrc->left;

        //  Driver support Overlay Destination Stretch
        m_OverlayCtxt.uiDstWidth = pDest->bottom - pDest->top;
        m_OverlayCtxt.uiDstHeight = pDest->right - pDest->left;
        m_OverlayCtxt.uiDstOffsetX = pDest->top;
        m_OverlayCtxt.uiDstOffsetY = m_pPrimarySurface->ScreenHeight()
                                        - m_OverlayCtxt.uiDstHeight - pDest->left;
        break;
    case DMDO_180:
        // Driver support Overlay Source Clipping
        m_OverlayCtxt.uiSrcWidth = pSrc->right - pSrc->left;
        m_OverlayCtxt.uiSrcHeight = pSrc->bottom - pSrc->top;
        m_OverlayCtxt.uiSrcOffsetX = pOverlaySurface->Width()
                                        - m_OverlayCtxt.uiSrcWidth - pSrc->left;
        m_OverlayCtxt.uiSrcOffsetY = pOverlaySurface->Height()
                                        - m_OverlayCtxt.uiSrcHeight - pSrc->top;

        //  Driver support Overlay Destination Stretch
        m_OverlayCtxt.uiDstWidth = pDest->right - pDest->left;
        m_OverlayCtxt.uiDstHeight = pDest->bottom - pDest->top;
        m_OverlayCtxt.uiDstOffsetX = m_pPrimarySurface->ScreenWidth()
                                        - m_OverlayCtxt.uiDstWidth - pDest->left;
        m_OverlayCtxt.uiDstOffsetY = m_pPrimarySurface->ScreenHeight()
                                        - m_OverlayCtxt.uiDstHeight - pDest->top;
        break;
    case DMDO_270:
        // Driver support Overlay Source Clipping
        m_OverlayCtxt.uiSrcHeight = pSrc->right - pSrc->left;
        m_OverlayCtxt.uiSrcWidth = pSrc->bottom - pSrc->top;
        m_OverlayCtxt.uiSrcOffsetX = pOverlaySurface->Width()
                                        - m_OverlayCtxt.uiSrcWidth - pSrc->top;;
        m_OverlayCtxt.uiSrcOffsetY = pSrc->left;

        //  Driver support Overlay Destination Stretch
        m_OverlayCtxt.uiDstHeight = pDest->right - pDest->left;
        m_OverlayCtxt.uiDstWidth = pDest->bottom - pDest->top;
        m_OverlayCtxt.uiDstOffsetX = m_pPrimarySurface->ScreenWidth()
                                        - m_OverlayCtxt.uiDstWidth - pDest->top;
        m_OverlayCtxt.uiDstOffsetY = pDest->left;
        break;
    }

    switch(m_OverlayCtxt.pSurface->PixelFormat())
    {
    case ddgpePixelFormat_I420:    // YUV420
    case ddgpePixelFormat_YV12:    // YVU420
        m_OverlayCtxt.bPostAttached = TRUE;
        m_OverlayCtxt.bLocalPath = OVERLAY_USE_LOCALPATH;
        m_OverlayCtxt.dwWinMode = OVERLAY_WINDOW_FIFO;
        m_OverlayCtxt.dwBPPMode = DISP_24BPP_888;
        m_OverlayCtxt.dwPostSrcType = POST_SRC_YUV420;
        break;
    case ddgpePixelFormat_NV12:     // YUV420 (2Plane)
        m_OverlayCtxt.bPostAttached = TRUE;
        m_OverlayCtxt.bLocalPath = OVERLAY_USE_LOCALPATH;
        m_OverlayCtxt.dwWinMode = OVERLAY_WINDOW_FIFO;
        m_OverlayCtxt.dwBPPMode = DISP_24BPP_888;
        m_OverlayCtxt.dwPostSrcType = POST_SRC_NV12;
        break;
    case ddgpePixelFormat_YUYV:    // YUV422 (YCbYCr)
    case ddgpePixelFormat_YUY2:    // YUV422 (YCbYCr)
        m_OverlayCtxt.bPostAttached = TRUE;
        m_OverlayCtxt.bLocalPath = OVERLAY_USE_LOCALPATH;
        m_OverlayCtxt.dwWinMode = OVERLAY_WINDOW_FIFO;
        m_OverlayCtxt.dwBPPMode = DISP_24BPP_888;
        m_OverlayCtxt.dwPostSrcType = POST_SRC_YUV422_CRYCBY;
        break;
    case ddgpePixelFormat_UYVY:    // YUV422(CbYCrY)
        m_OverlayCtxt.bPostAttached = TRUE;
        m_OverlayCtxt.bLocalPath = OVERLAY_USE_LOCALPATH;
        m_OverlayCtxt.dwWinMode = OVERLAY_WINDOW_FIFO;
        m_OverlayCtxt.dwBPPMode = DISP_24BPP_888;
        m_OverlayCtxt.dwPostSrcType = POST_SRC_YUV422_YCRYCB;
        break;
    case ddgpePixelFormat_YVYU:    // YUV422 (YCrYCb)
        m_OverlayCtxt.bPostAttached = TRUE;
        m_OverlayCtxt.bLocalPath = OVERLAY_USE_LOCALPATH;
        m_OverlayCtxt.dwWinMode = OVERLAY_WINDOW_FIFO;
        m_OverlayCtxt.dwBPPMode = DISP_24BPP_888;
        m_OverlayCtxt.dwPostSrcType = POST_SRC_YUV422_CBYCRY;
        break;
    case ddgpePixelFormat_VYUY:    // YUV422 (CrYCbY)
        m_OverlayCtxt.bPostAttached = TRUE;
        m_OverlayCtxt.bLocalPath = OVERLAY_USE_LOCALPATH;
        m_OverlayCtxt.dwWinMode = OVERLAY_WINDOW_FIFO;
        m_OverlayCtxt.dwBPPMode = DISP_24BPP_888;
        m_OverlayCtxt.dwPostSrcType = POST_SRC_YUV422_YCBYCR;
        break;
    case ddgpePixelFormat_565:
        if (    (m_OverlayCtxt.uiSrcWidth == pOverlaySurface->Width())
            && (m_OverlayCtxt.uiSrcHeight == pOverlaySurface->Height())
            && (m_OverlayCtxt.uiDstWidth == pOverlaySurface->Width())
            && (m_OverlayCtxt.uiDstHeight == pOverlaySurface->Height()))
        {
            // No Clipping and No Stretch, Don't Use Local Path for RGB
            m_OverlayCtxt.bPostAttached = FALSE;
            m_OverlayCtxt.bLocalPath = FALSE;
            m_OverlayCtxt.dwWinMode = OVERLAY_WINDOW_DMA;
            m_OverlayCtxt.dwBPPMode = DISP_16BPP_565;
        }
        else
        {
            // Use Local Path for RGB
            m_OverlayCtxt.bPostAttached = TRUE;
            m_OverlayCtxt.bLocalPath = OVERLAY_USE_LOCALPATH;
            m_OverlayCtxt.dwWinMode = OVERLAY_WINDOW_FIFO;
            m_OverlayCtxt.dwBPPMode = DISP_24BPP_888;
            m_OverlayCtxt.dwPostSrcType = POST_SRC_RGB16;
        }
        break;
    case ddgpePixelFormat_5551:
    case ddgpePixelFormat_5550:
        if (    (m_OverlayCtxt.uiSrcWidth == pOverlaySurface->Width())
            && (m_OverlayCtxt.uiSrcHeight == pOverlaySurface->Height())
            && (m_OverlayCtxt.uiDstWidth == pOverlaySurface->Width())
            && (m_OverlayCtxt.uiDstHeight == pOverlaySurface->Height()))
        {
            // No Clipping and No Stretch, Don't Use Local Path for RGB
            m_OverlayCtxt.bPostAttached = FALSE;
            m_OverlayCtxt.bLocalPath = FALSE;
            m_OverlayCtxt.dwWinMode = OVERLAY_WINDOW_DMA;
            m_OverlayCtxt.dwBPPMode = DISP_16BPP_I555;
        }
        else
        {
            // Use Local Path for RGB
            m_OverlayCtxt.bPostAttached = TRUE;
            m_OverlayCtxt.bLocalPath = OVERLAY_USE_LOCALPATH;
            m_OverlayCtxt.dwWinMode = OVERLAY_WINDOW_FIFO;
            m_OverlayCtxt.dwBPPMode = DISP_24BPP_888;
            m_OverlayCtxt.dwPostSrcType = POST_SRC_RGB16;
        }
        break;
    //case ddgpePixelFormat_8880:    // FIMD can not support Packed RGB888
    case ddgpePixelFormat_8888:
        if (    (m_OverlayCtxt.uiSrcWidth == pOverlaySurface->Width())
            && (m_OverlayCtxt.uiSrcHeight == pOverlaySurface->Height())
            && (m_OverlayCtxt.uiDstWidth == pOverlaySurface->Width())
            && (m_OverlayCtxt.uiDstHeight == pOverlaySurface->Height()))
        {
            // No Clipping and No Stretch, Don't Use Local Path for RGB
            m_OverlayCtxt.bPostAttached = FALSE;
            m_OverlayCtxt.bLocalPath = FALSE;
            m_OverlayCtxt.dwWinMode = OVERLAY_WINDOW_DMA;
            m_OverlayCtxt.dwBPPMode = DISP_24BPP_888;
        }
        else
        {
            // Use Local Path for RGB
            m_OverlayCtxt.bPostAttached = TRUE;
            m_OverlayCtxt.bLocalPath = OVERLAY_USE_LOCALPATH;
            m_OverlayCtxt.dwWinMode = OVERLAY_WINDOW_FIFO;
            m_OverlayCtxt.dwBPPMode = DISP_24BPP_888;
            m_OverlayCtxt.dwPostSrcType = POST_SRC_RGB24;
        }
        break;
    }

#ifndef OVERLAY_USE_MEM2MEM
    // Request H/W Resource for Overlay to Video Engine Driver
    if (OverlayAllocResource(m_OverlayCtxt.bPostAttached) == FALSE)
    {
        RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] OverlayInitialize() : OverlayAllocResource() Failed\n\r")));
        bRet = FALSE;
        goto CleanUp;
    }
#endif

    // Adjust for Post Processor and FIMD restriction
    // S5PV210 has 64bit AXI bus, So Read&write width must be aligned by 64bit
    switch(m_OverlayCtxt.pSurface->PixelFormat())
    {
    // Planar Format
    case ddgpePixelFormat_I420:     // YUV420 3Plane
    case ddgpePixelFormat_YV12:     // YVU420 3Plane
        m_OverlayCtxt.uiSrcWidth = m_OverlayCtxt.uiSrcWidth-m_OverlayCtxt.uiSrcWidth%16;    // Crop
        m_OverlayCtxt.uiSrcHeight = m_OverlayCtxt.uiSrcHeight-m_OverlayCtxt.uiSrcHeight%2;
        m_OverlayCtxt.uiSrcOffsetX = m_OverlayCtxt.uiSrcOffsetX-m_OverlayCtxt.uiSrcOffsetX%16;  // Crop

        if (m_OverlayCtxt.uiSrcWidth < 16) m_OverlayCtxt.uiSrcWidth = 16;   // for each Cb/Cr plane aligning(Y=16, Cb/Cr=8)
        if (m_OverlayCtxt.uiSrcHeight < 2) m_OverlayCtxt.uiSrcHeight = 2;   // Padded?
//        if (m_OverlayCtxt.uiDstHeight < 3) m_OverlayCtxt.uiDstHeight = 3;   // Padded?
        break;
    case ddgpePixelFormat_NV12:     // YUV420 2Plane(U/V Interleaved)
//    case ddgpePixelFormat_NV21:     // YVU420 2Plane(V/U Interleaved)
        m_OverlayCtxt.uiSrcWidth = m_OverlayCtxt.uiSrcWidth-m_OverlayCtxt.uiSrcWidth%8;    // Crop
        m_OverlayCtxt.uiSrcHeight = m_OverlayCtxt.uiSrcHeight-m_OverlayCtxt.uiSrcHeight%2;
        m_OverlayCtxt.uiSrcOffsetX = m_OverlayCtxt.uiSrcOffsetX-m_OverlayCtxt.uiSrcOffsetX%8;  // Crop

        if (m_OverlayCtxt.uiSrcWidth < 8) m_OverlayCtxt.uiSrcWidth = 8;     // Cb&Cr plane has 2byte size per pixel
        if (m_OverlayCtxt.uiSrcHeight < 2) m_OverlayCtxt.uiSrcHeight = 2;
//        if (m_OverlayCtxt.uiDstHeight < 3) m_OverlayCtxt.uiDstHeight = 3;
        break;
    // Packed Format
    case ddgpePixelFormat_YUYV:
    case ddgpePixelFormat_YUY2:
    case ddgpePixelFormat_UYVY:
    case ddgpePixelFormat_YVYU:
    case ddgpePixelFormat_VYUY:
        m_OverlayCtxt.uiSrcWidth = m_OverlayCtxt.uiSrcWidth-m_OverlayCtxt.uiSrcWidth%4;    // 4Bytes per 2Pixel
        m_OverlayCtxt.uiSrcHeight = m_OverlayCtxt.uiSrcHeight-m_OverlayCtxt.uiSrcHeight%2;
        m_OverlayCtxt.uiSrcOffsetX = m_OverlayCtxt.uiSrcOffsetX-m_OverlayCtxt.uiSrcOffsetX%4;

        if (m_OverlayCtxt.uiSrcWidth < 4) m_OverlayCtxt.uiSrcWidth = 4;
        if (m_OverlayCtxt.uiSrcHeight < 2) m_OverlayCtxt.uiSrcHeight = 2;
        break;
    case ddgpePixelFormat_565:
    case ddgpePixelFormat_5551:
    case ddgpePixelFormat_5550:
        m_OverlayCtxt.uiSrcWidth = m_OverlayCtxt.uiSrcWidth-m_OverlayCtxt.uiSrcWidth%4;
        m_OverlayCtxt.uiSrcHeight = m_OverlayCtxt.uiSrcHeight-m_OverlayCtxt.uiSrcHeight%2;
        m_OverlayCtxt.uiSrcOffsetX = m_OverlayCtxt.uiSrcOffsetX-m_OverlayCtxt.uiSrcOffsetX%4;

        m_OverlayCtxt.uiDstWidth = m_OverlayCtxt.uiDstWidth-m_OverlayCtxt.uiDstWidth%4;
        m_OverlayCtxt.uiDstOffsetX = m_OverlayCtxt.uiDstOffsetX-m_OverlayCtxt.uiDstOffsetX%4;

        if (m_OverlayCtxt.uiSrcWidth < 4) m_OverlayCtxt.uiSrcWidth = 4;
        if (m_OverlayCtxt.uiSrcHeight < 2) m_OverlayCtxt.uiSrcHeight = 2;
        if (m_OverlayCtxt.uiDstWidth < 4) m_OverlayCtxt.uiDstWidth = 4;
        break;
    }

    // Adjust for Overlay Window Position
    if (m_OverlayCtxt.uiDstWidth+m_OverlayCtxt.uiDstOffsetX > (unsigned int)m_dwDeviceScreenWidth)
    {
        //m_OverlayCtxt.uiDstWidth = m_dwDeviceScreenWidth - m_OverlayCtxt.uiDstOffsetX;    // Adjust Width
        m_OverlayCtxt.uiDstOffsetX = m_dwDeviceScreenWidth - m_OverlayCtxt.uiDstWidth;        // Adjust Offset
    }

    if (m_OverlayCtxt.uiDstHeight+m_OverlayCtxt.uiDstOffsetY  > (unsigned int)m_dwDeviceScreenHeight)
    {
        //m_OverlayCtxt.uiDstHeight = m_dwDeviceScreenHeight - m_OverlayCtxt.uiDstOffsetY;    // Adjust Height
        m_OverlayCtxt.uiDstOffsetY  = m_dwDeviceScreenHeight - m_OverlayCtxt.uiDstHeight;    // Adjust Offset
    }

#ifdef OVERLAY_USE_MEM2MEM
    // Request H/W Resource for Overlay to Video Engine Driver
    if (OverlayAllocResource(m_OverlayCtxt.bPostAttached) == FALSE)
    {
        RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] OverlayInitialize() : OverlayAllocResource() Failed\n\r")));
        bRet = FALSE;
        goto CleanUp;
    }
#endif // OVERLAY_USE_MEM2MEM

    DevOverlayInitialize();

CleanUp:

    LeaveCriticalSection(&m_csDevice);

    return bRet;
}


void
SMDKDisp::OverlaySetPosition(UINT32 uiOffsetX, UINT32 uiOffsetY)
{
    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("OverlaySetPosition(%d,%d)\n\r"), uiOffsetX, uiOffsetY));

    EnterCriticalSection(&m_csDevice);

    switch(m_iRotate)
    {
    case DMDO_0:
    default:
        m_OverlayCtxt.uiDstOffsetX = uiOffsetX;
        m_OverlayCtxt.uiDstOffsetY = uiOffsetY;
        break;
    case DMDO_90:
        m_OverlayCtxt.uiDstOffsetX = uiOffsetY;
        m_OverlayCtxt.uiDstOffsetY = m_pPrimarySurface->ScreenHeight()
                                        - m_OverlayCtxt.uiDstHeight - uiOffsetX;
        break;
    case DMDO_180:
        m_OverlayCtxt.uiDstOffsetX = m_pPrimarySurface->ScreenWidth()
                                        - m_OverlayCtxt.uiDstWidth - uiOffsetX;
        m_OverlayCtxt.uiDstOffsetY = m_pPrimarySurface->ScreenHeight()
                                        - m_OverlayCtxt.uiDstHeight - uiOffsetY;
        break;
    case DMDO_270:
        m_OverlayCtxt.uiDstOffsetX = m_pPrimarySurface->ScreenWidth()
                                        - m_OverlayCtxt.uiDstWidth - uiOffsetY;
        m_OverlayCtxt.uiDstOffsetY = uiOffsetX;
        break;
    }

    // Adjust for Post Processor and FIMD restriction
    if (m_OverlayCtxt.pSurface->PixelFormat() == ddgpePixelFormat_565 ||
        m_OverlayCtxt.pSurface->PixelFormat() == ddgpePixelFormat_5551 ||
        m_OverlayCtxt.pSurface->PixelFormat() == ddgpePixelFormat_5550
    )
    {
        m_OverlayCtxt.uiDstOffsetX = m_OverlayCtxt.uiDstOffsetX-m_OverlayCtxt.uiDstOffsetX%2;
    }

    // Adjust for Overlay Window Position
    if (m_OverlayCtxt.uiDstWidth+m_OverlayCtxt.uiDstOffsetX > (unsigned int)m_dwDeviceScreenWidth)
    {
        //m_OverlayCtxt.uiDstWidth = m_dwDeviceScreenWidth - m_OverlayCtxt.uiDstOffsetX;    // Adjust Width
        m_OverlayCtxt.uiDstOffsetX = m_dwDeviceScreenWidth - m_OverlayCtxt.uiDstWidth;        // Adjust Offset
    }

    if (m_OverlayCtxt.uiDstHeight+m_OverlayCtxt.uiDstOffsetY  > (unsigned int)m_dwDeviceScreenHeight)
    {
        //m_OverlayCtxt.uiDstHeight = m_dwDeviceScreenHeight - m_OverlayCtxt.uiDstOffsetY;    // Adjust Height
        m_OverlayCtxt.uiDstOffsetY  = m_dwDeviceScreenHeight - m_OverlayCtxt.uiDstHeight;    // Adjust Offset
    }

    DevOverlaySetPosition();

    LeaveCriticalSection(&m_csDevice);
}


void
SMDKDisp::OverlayEnable(void)
{
    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] %s()\n\r"), _T(__FUNCTION__)));

    EnterCriticalSection(&m_csDevice);

    m_OverlayCtxt.bShow = TRUE;

    DevOverlayEnable();

    LeaveCriticalSection(&m_csDevice);
}


void
SMDKDisp::OverlayDisable(void)
{
    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] %s()\n\r"), _T(__FUNCTION__)));

    m_OverlayCtxt.pSurface = NULL;
    m_OverlayCtxt.pPrevSurface = NULL;

    m_OverlayCtxt.bShow = FALSE;

    EnterCriticalSection(&m_csDevice);

    DevOverlayDisable();

    LeaveCriticalSection(&m_csDevice);

    // Release H/W Resource for Overlay to Video Engine Driver
    OverlayReleaseResource(m_OverlayCtxt.bPostAttached);
}


void
SMDKDisp::OverlayBlendDisable()
{
    m_OverlayCtxt.bBlendOn = FALSE;
    DevOverlayBlendDisable();
}


void
SMDKDisp::OverlaySetColorKey(BOOL bSrcCKey, EDDGPEPixelFormat Format, DWORD ColorKey)
{
    m_OverlayCtxt.bBlendOn = TRUE;
    m_OverlayCtxt.bColorKey = TRUE;
    m_OverlayCtxt.bColorKeyWithAlpha = FALSE;
    m_OverlayCtxt.bSrcCKey = bSrcCKey;

    if (Format == ddgpePixelFormat_565)    // RGB565
    {
        m_OverlayCtxt.ColorKey =
                    (((ColorKey&0xF800)>>11)<<19) |    // R bit
                    (((ColorKey&0x07E0)>>5)<<10) |    // G bit
                    ((ColorKey&0x001F)<<3);            // B bit
        m_OverlayCtxt.CompareKey = 0x00070307;
    }
    else if(Format == ddgpePixelFormat_5551 ||
            Format == ddgpePixelFormat_5550 )
    {
        RETAIL_DISP_MSG(DISP_ZONE_TEMP,(TEXT("ColorKey:0x%x\r\n"), ColorKey));
        m_OverlayCtxt.ColorKey =
                    (((ColorKey&0x7C00)>>10)<<20) |    // R bit
                    (((ColorKey&0x03E0)>>5)<<11) |    // G bit
                    ((ColorKey&0x001F)<<3);            // B bit
        m_OverlayCtxt.CompareKey = 0x00070707;
    }
    else    // if (Format == ddgpePixelFormat_8888)    // RGB888
    {
        RETAIL_DISP_MSG(DISP_ZONE_TEMP,(TEXT("ColorKey:0x%x\r\n"), ColorKey));
        m_OverlayCtxt.ColorKey = ColorKey;
        m_OverlayCtxt.CompareKey = 0x00000000;
    }

    // Reset alpha blending and color keying settings
    DevOverlayBlendDisable();

    DevOverlaySetColorKey();
}

void
SMDKDisp::OverlaySetAlphaPlane(DWORD Alpha)
{
    m_OverlayCtxt.bBlendOn = TRUE;
    m_OverlayCtxt.bColorKey = FALSE;
    m_OverlayCtxt.bColorKeyWithAlpha = FALSE;
    m_OverlayCtxt.bUsePixelBlend = FALSE;
    m_OverlayCtxt.Alpha = Alpha;

    // Reset alpha blending and color keying settings
    DevOverlayBlendDisable();

    DevOverlaySetAlpha();
}

void
SMDKDisp::OverlaySetAlphaPixel(BOOL bSrcAlpha)
{
    m_OverlayCtxt.bBlendOn = TRUE;
    m_OverlayCtxt.bColorKey = FALSE;
    m_OverlayCtxt.bColorKeyWithAlpha = FALSE;
    m_OverlayCtxt.bUsePixelBlend = TRUE;
    m_OverlayCtxt.bSrcAlpha = bSrcAlpha;

    // Reset alpha blending and color keying settings
    DevOverlayBlendDisable();

    DevOverlaySetAlpha();
}

void
SMDKDisp::OverlaySetColorKeyWithAlpha(BOOL bSrcCKey, EDDGPEPixelFormat Format, DWORD ColorKey, DWORD Alpha)
{
    m_OverlayCtxt.bBlendOn = TRUE;
    m_OverlayCtxt.bColorKey = FALSE;
    m_OverlayCtxt.bColorKeyWithAlpha = TRUE;
    m_OverlayCtxt.bSrcCKey = bSrcCKey;
    m_OverlayCtxt.bUsePixelBlend = FALSE;
    m_OverlayCtxt.Alpha = Alpha;

    if (Format == ddgpePixelFormat_565)    // RGB565
    {
        m_OverlayCtxt.ColorKey =
                    (((ColorKey&0xF800)>>11)<<19) |    // R bit
                    (((ColorKey&0x07E0)>>5)<<10) |    // G bit
                    ((ColorKey&0x001F)<<3);            // B bit
        m_OverlayCtxt.CompareKey = 0x00070307;
    }
    else if(Format == ddgpePixelFormat_5551 ||
            Format == ddgpePixelFormat_5550 )
    {
        RETAIL_DISP_MSG(DISP_ZONE_TEMP,(TEXT("ColorKeyA:0x%x\r\n"), ColorKey));
        m_OverlayCtxt.ColorKey =
                    (((ColorKey&0x7C00)>>10)<<20) |    // R bit
                    (((ColorKey&0x03E0)>>5)<<11) |    // G bit
                    ((ColorKey&0x001F)<<3);            // B bit
        m_OverlayCtxt.CompareKey = 0x00070707;
    }
    else    // if (Format == ddgpePixelFormat_8888)    // RGB888
    {
        RETAIL_DISP_MSG(DISP_ZONE_TEMP,(TEXT("ColorKeyA:0x%x\r\n"), ColorKey));
        m_OverlayCtxt.ColorKey = ColorKey;
        m_OverlayCtxt.CompareKey = 0x00000000;
    }

    // Reset alpha blending and color keying settings
    DevOverlayBlendDisable();

    DevOverlaySetColorKeyWithAlpha();
}

void SMDKDisp::SetVisibleSurface(GPESurf *pSurf, BOOL bWaitForVBlank)
{
    SMDKSurf *pDDSurf = (SMDKSurf *)pSurf;

    if(pDDSurf->IsOverlay() == TRUE)
    {
        m_OverlayCtxt.pPrevSurface = m_OverlayCtxt.pSurface;        // Being Flipped Surface
        m_OverlayCtxt.pSurface = pDDSurf;
    }
    else
    {
        m_pVisibleSurface = pDDSurf;
    }

    EnterCriticalSection(&m_csDevice);

    DevSetVisibleSurface(pDDSurf, bWaitForVBlank);

    LeaveCriticalSection(&m_csDevice);
}

void
SMDKDisp::InitalizeOverlayContext(void)
{
    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] ++InitalizeOverlayContext()\n\r")));

    m_OverlayCtxt.pSurface = NULL;            // Current Overlay Surface
    m_OverlayCtxt.pPrevSurface = NULL;

    m_OverlayCtxt.bLocalPath = FALSE;
    m_OverlayCtxt.uiSrcWidth = 0;
    m_OverlayCtxt.uiSrcHeight = 0;
    m_OverlayCtxt.uiSrcOffsetX = 0;
    m_OverlayCtxt.uiSrcOffsetY = 0;
    m_OverlayCtxt.uiDstWidth = 0;
    m_OverlayCtxt.uiDstHeight = 0;
    m_OverlayCtxt.uiDstOffsetX = 0;
    m_OverlayCtxt.uiDstOffsetY = 0;
    m_OverlayCtxt.bEnabled = FALSE;
    m_OverlayCtxt.bShow = FALSE;

    m_OverlayCtxt.bBlendOn = FALSE;
    m_OverlayCtxt.bColorKey = FALSE;
    m_OverlayCtxt.bColorKeyWithAlpha = FALSE;
    m_OverlayCtxt.bSrcCKey = FALSE;
    m_OverlayCtxt.CompareKey = 0x0;
    m_OverlayCtxt.ColorKey = 0x0;
    m_OverlayCtxt.bUsePixelBlend = FALSE;
    m_OverlayCtxt.Alpha = 0x0;

    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] --InitalizeOverlayContext()\n\r")));
}


SMDKSurf*
SMDKDisp::GetCurrentOverlaySurf(void)
{
    return m_OverlayCtxt.pSurface;
}


SMDKSurf*
SMDKDisp::GetPreviousOverlaySurf(void)
{
    return m_OverlayCtxt.pPrevSurface;
}

void
SMDKDisp::DevSetVisibleSurface(SMDKSurf *pSurf, BOOL bWaitForVBlank)
{
    BOOL bRetry = TRUE;
    DWORD dwBytes;

    if (!pSurf)
    {
        RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : pSurf is NULL\r\n"),_T(__FUNCTION__)));
        return;
    }

    if (pSurf->IsOverlay() == TRUE)
    {
        if (m_OverlayCtxt.bPostAttached)
        {
            if(m_OverlayCtxt.bLocalPath)
            {
                SVEARG_POST_BUFFER tPostParam;

#ifdef USE_CMM_FOR_YUVSURFACE
                tPostParam.dwBufferRGBY = \
                                    m_OverlayCtxt.pSurface->OffsetInVideoMemory();
                if(m_OverlayCtxt.pSurface->m_hCmmFB == NULL)
                {
                    tPostParam.dwBufferRGBY += m_VideoMemoryPhysicalBase;
                }
#else
                tPostParam.dwBufferRGBY = m_OverlayCtxt.pSurface->OffsetInVideoMemory() + m_VideoMemoryPhysicalBase;
#endif
                tPostParam.dwBufferCb = tPostParam.dwBufferRGBY+m_OverlayCtxt.pSurface->m_uiOffsetCb;
                tPostParam.dwBufferCr = tPostParam.dwBufferRGBY+m_OverlayCtxt.pSurface->m_uiOffsetCr;
                tPostParam.bWaitForVSync = bWaitForVBlank;

                if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_POST_SET_NEXT_SOURCE_BUFFER, &tPostParam, sizeof(SVEARG_POST_BUFFER), NULL, 0, &dwBytes, NULL) )
                {
                    RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_SVE_POST_SET_NEXT_SOURCE_BUFFER Failed at %d\n\r"), _T(__FUNCTION__), __LINE__));
                }
            }
            else
            {
                SVEARG_POST_BUFFER tPostParam;

#ifdef USE_CMM_FOR_YUVSURFACE
                tPostParam.dwBufferRGBY = \
                                    m_OverlayCtxt.pSurface->OffsetInVideoMemory();
                if(m_OverlayCtxt.pSurface->m_hCmmFB == NULL)
                {
                    tPostParam.dwBufferRGBY += m_VideoMemoryPhysicalBase;
                }
#else
                tPostParam.dwBufferRGBY = m_OverlayCtxt.pSurface->OffsetInVideoMemory() + m_VideoMemoryPhysicalBase;
#endif
                tPostParam.dwBufferCb = tPostParam.dwBufferRGBY+m_OverlayCtxt.pSurface->m_uiOffsetCb;
                tPostParam.dwBufferCr = tPostParam.dwBufferRGBY+m_OverlayCtxt.pSurface->m_uiOffsetCr;
                tPostParam.bWaitForVSync = FALSE;
#ifdef OVERLAY_USE_MEM2MEM
                //RETAIL_DISP_MSG(DISP_ZONE_TEMP,(_T("[DISPDRV] %s() : WaitForSingleObject(m_hPostReadyEvent) 0x%x\r\n"),_T(__FUNCTION__),m_hPostReadyEvent));
                WaitForSingleObject(m_hPostReadyEvent, INFINITE);

                if ( !DeviceIoControl(m_hVideoDrv, \
                                        IOCTL_SVE_POST_SET_SOURCE_BUFFER, \
                                        &tPostParam, sizeof(SVEARG_POST_BUFFER), \
                                        NULL, 0, &dwBytes, NULL) )
                {
                    RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_SVE_POST_SET_NEXT_SOURCE_BUFFER Failed at %d\n\r"), _T(__FUNCTION__), __LINE__));
                }

                m_uiCurPostFB = (m_uiCurPostFB+1)%OVERLAY_FB_NUM;
                tPostParam.dwBufferRGBY = \
                        m_pOverlayDMAOutputBuf[m_uiCurPostFB]->OffsetInVideoMemory() + \
                        m_VideoMemoryPhysicalBase;
                tPostParam.dwBufferCb = tPostParam.dwBufferRGBY;
                tPostParam.dwBufferCr = tPostParam.dwBufferRGBY;
                tPostParam.bWaitForVSync = FALSE;

                if ( !DeviceIoControl(m_hVideoDrv, \
                                        IOCTL_SVE_POST_SET_DESTINATION_BUFFER, \
                                        &tPostParam, sizeof(SVEARG_POST_BUFFER), \
                                        NULL, 0, &dwBytes, NULL) )
                {
                    RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_SVE_POST_SET_SOURCE_BUFFER Failed\n\r"),_T(__FUNCTION__)));
                }
#else // OVERLAY_USE_MEM2MEM
                if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_POST_SET_NEXT_SOURCE_BUFFER, &tPostParam, sizeof(SVEARG_POST_BUFFER), NULL, 0, &dwBytes, NULL) )
                {
                    RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_SVE_POST_SET_NEXT_SOURCE_BUFFER Failed at %d\n\r"), _T(__FUNCTION__), __LINE__));
                }
#endif // OVERLAY_USE_MEM2MEM
                // This will be Per Frame Mode
                if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_POST_SET_PROCESSING_START, NULL, 0, NULL, 0, &dwBytes, NULL) )
                {
                    RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_SVE_POST_SET_PROCESSING_START Failed\n\r"), _T(__FUNCTION__)));
                }
#ifdef OVERLAY_USE_MEM2MEM
                SetEvent(m_hPostBusyEvent);
                //RETAIL_DISP_MSG(DISP_ZONE_TEMP,(_T("[DISPDRV] %s() : SetEvent(m_hPostBusyEvent)\r\n"),_T(__FUNCTION__)));
#endif
            }
        }
        else
        {
            SVEARG_FIMD_WIN_FRAMEBUFFER tParam;

            // Change Frame Buffer
            tParam.dwWinNum = OVERLAY_WINDOW;
            tParam.dwFrameBuffer = pSurf->OffsetInVideoMemory() + m_VideoMemoryPhysicalBase;
            tParam.bWaitForVSync = bWaitForVBlank;
            if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_FRAMEBUFFER, &tParam, sizeof(SVEARG_FIMD_WIN_FRAMEBUFFER), NULL, 0, &dwBytes, NULL) )
            {
                RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_SVE_FIMD_SET_WINDOW_FRAMEBUFFER Failed\n\r"), _T(__FUNCTION__)));
            }
        }
    }
    else
    {
        SVEARG_FIMD_WIN_FRAMEBUFFER tParam;

        // Change Frame Buffer
        tParam.dwWinNum = PRIMARY_WINDOW;
        tParam.dwFrameBuffer = pSurf->OffsetInVideoMemory() + m_VideoMemoryPhysicalBase;
        tParam.bWaitForVSync = bWaitForVBlank;
        if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_FRAMEBUFFER, &tParam, sizeof(SVEARG_FIMD_WIN_FRAMEBUFFER), NULL, 0, &dwBytes, NULL) )
        {
            RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_SVE_FIMD_SET_WINDOW_FRAMEBUFFER Failed\n\r"), _T(__FUNCTION__)));
        }
    }
}


void
SMDKDisp::DevOverlayInitialize(void)
{
    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] ++DevOverlayInitialize()\n\r")));

    DWORD dwBytes;

    // Display Overlay Window
    if (m_OverlayCtxt.bEnabled)
    {
        RETAIL_DISP_MSG(DISP_ZONE_TEMP, (_T("[DDHAL] DevOverlayInitialize() : Disable Overlay\n\r")));
        DevOverlayDisable();
    }

    // Initialize Overlay Widnow
    if(m_OverlayCtxt.bPostAttached)
    {
        if (m_OverlayCtxt.bLocalPath)
        {
            SVEARG_FIMD_WIN_MODE tParamMode;
            SVEARG_POST_PARAMETER tParamPost;
            SVEARG_POST_BUFFER tParamBuffer;

            tParamMode.dwWinMode = m_OverlayCtxt.dwWinMode;
            tParamMode.dwBPP = m_OverlayCtxt.dwBPPMode;
            tParamMode.dwWidth = m_OverlayCtxt.uiDstWidth;
            tParamMode.dwHeight = m_OverlayCtxt.uiDstHeight;
            tParamMode.dwOffsetX = m_OverlayCtxt.uiDstOffsetX;
            tParamMode.dwOffsetY = m_OverlayCtxt.uiDstOffsetY;

            if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_MODE, &tParamMode, sizeof(SVEARG_FIMD_WIN_MODE), NULL, 0, &dwBytes, NULL) )
            {
                RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlayInitialize() : IOCTL_SVE_FIMD_SET_WINDOW_MODE Failed\n\r")));
            }

            tParamPost.dwOpMode = POST_FREE_RUN_MODE;
            tParamPost.dwScanMode = POST_PROGRESSIVE;
            tParamPost.dwRotFlipMode = MAKELONG(POST_0_NOFLIP, POST_0_NOFLIP);
            tParamPost.dwDMATileMode = MAKELONG(POST_DMA_LINEAR, POST_DMA_LINEAR);
            tParamPost.dwSrcType = m_OverlayCtxt.dwPostSrcType;
            tParamPost.dwSrcBaseWidth = m_OverlayCtxt.pSurface->Width();
            tParamPost.dwSrcBaseHeight = m_OverlayCtxt.pSurface->Height();
            tParamPost.dwSrcWidth = m_OverlayCtxt.uiSrcWidth;
            tParamPost.dwSrcHeight = m_OverlayCtxt.uiSrcHeight;
            tParamPost.dwSrcOffsetX = m_OverlayCtxt.uiSrcOffsetX;
            tParamPost.dwSrcOffsetY = m_OverlayCtxt.uiSrcOffsetY;
            tParamPost.dwDstType = POST_DST_FIFO_RGB888;
            tParamPost.dwDstBaseWidth = m_OverlayCtxt.uiDstWidth;
            tParamPost.dwDstBaseHeight = m_OverlayCtxt.uiDstHeight;
            tParamPost.dwDstWidth = m_OverlayCtxt.uiDstWidth;
            tParamPost.dwDstHeight = m_OverlayCtxt.uiDstHeight;
            tParamPost.dwDstOffsetX = 0;
            tParamPost.dwDstOffsetY = 0;

            RETAIL_DISP_MSG(DISP_ZONE_TEMP, (_T("[DISPDRV]++%s(%d, %d, 0x%x, 0x%x, %d, [%d, %d, %d, %d, %d, %d], %d, [%d, %d, %d, %d, %d, %d])\n\r"), _T(__FUNCTION__),
                tParamPost.dwOpMode,
                tParamPost.dwScanMode,
                tParamPost.dwRotFlipMode,
                tParamPost.dwDMATileMode,
                tParamPost.dwSrcType,
                tParamPost.dwSrcBaseWidth,
                tParamPost.dwSrcBaseHeight,
                tParamPost.dwSrcWidth,
                tParamPost.dwSrcHeight,
                tParamPost.dwSrcOffsetX,
                tParamPost.dwSrcOffsetY,
                tParamPost.dwDstType,
                tParamPost.dwDstBaseWidth,
                tParamPost.dwDstBaseHeight,
                tParamPost.dwDstWidth,
                tParamPost.dwDstHeight,
                tParamPost.dwDstOffsetX,
                tParamPost.dwDstOffsetY));

            if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_POST_SET_PROCESSING_PARAM, &tParamPost, sizeof(SVEARG_POST_PARAMETER), NULL, 0, &dwBytes, NULL) )
            {
                RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlayInitialize() : IOCTL_SVE_POST_SET_PROCESSING_PARAM Failed\n\r")));
            }

#ifdef USE_CMM_FOR_YUVSURFACE
            tParamBuffer.dwBufferRGBY = \
                                m_OverlayCtxt.pSurface->OffsetInVideoMemory();
            if(m_OverlayCtxt.pSurface->m_hCmmFB == NULL)
            {
                tParamBuffer.dwBufferRGBY += m_VideoMemoryPhysicalBase;
            }
#else
            tParamBuffer.dwBufferRGBY = m_OverlayCtxt.pSurface->OffsetInVideoMemory() + m_VideoMemoryPhysicalBase;
#endif
            tParamBuffer.dwBufferCb = tParamBuffer.dwBufferRGBY+m_OverlayCtxt.pSurface->m_uiOffsetCb;
            tParamBuffer.dwBufferCr = tParamBuffer.dwBufferRGBY+m_OverlayCtxt.pSurface->m_uiOffsetCr;
            tParamBuffer.bWaitForVSync = FALSE;

            if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_POST_SET_SOURCE_BUFFER, &tParamBuffer, sizeof(SVEARG_POST_BUFFER), NULL, 0, &dwBytes, NULL) )
            {
                RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlayInitialize() : IOCTL_SVE_POST_SET_SOURCE_BUFFER Failed\n\r")));
            }

            if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_POST_SET_NEXT_SOURCE_BUFFER, &tParamBuffer, sizeof(SVEARG_POST_BUFFER), NULL, 0, &dwBytes, NULL) )
            {
                RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_SVE_POST_SET_NEXT_SOURCE_BUFFER Failed at %d\n\r"), _T(__FUNCTION__), __LINE__));
            }
        }
        else
        {
            SVEARG_FIMD_WIN_MODE tParamMode;
            SVEARG_POST_PARAMETER tParamPost;
            SVEARG_POST_BUFFER tParamBuffer;
            SVEARG_FIMD_WIN_FRAMEBUFFER tParamFB;

            tParamPost.dwOpMode = POST_PER_FRAME_MODE;
            tParamPost.dwScanMode = POST_PROGRESSIVE;
            tParamPost.dwRotFlipMode = MAKELONG(POST_0_NOFLIP, POST_0_NOFLIP);
            tParamPost.dwDMATileMode = MAKELONG(POST_DMA_LINEAR, POST_DMA_LINEAR);
            tParamPost.dwSrcType = m_OverlayCtxt.dwPostSrcType;
            tParamPost.dwSrcBaseWidth = m_OverlayCtxt.pSurface->Width();
            tParamPost.dwSrcBaseHeight = m_OverlayCtxt.pSurface->Height();
            tParamPost.dwSrcWidth = m_OverlayCtxt.uiSrcWidth;
            tParamPost.dwSrcHeight = m_OverlayCtxt.uiSrcHeight;
            tParamPost.dwSrcOffsetX = m_OverlayCtxt.uiSrcOffsetX;
            tParamPost.dwSrcOffsetY = m_OverlayCtxt.uiSrcOffsetY;
            tParamPost.dwDstType = POST_DST_RGB24;  // This must be matched to WINDOW
            tParamPost.dwDstBaseWidth = m_OverlayCtxt.uiDstWidth;
            tParamPost.dwDstBaseHeight = m_OverlayCtxt.uiDstHeight;
            tParamPost.dwDstWidth = m_OverlayCtxt.uiDstWidth;
            tParamPost.dwDstHeight = m_OverlayCtxt.uiDstHeight;
            tParamPost.dwDstOffsetX = 0;
            tParamPost.dwDstOffsetY = 0;

            if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_POST_SET_PROCESSING_PARAM, &tParamPost, sizeof(SVEARG_POST_PARAMETER), NULL, 0, &dwBytes, NULL) )
            {
                RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlayInitialize() : IOCTL_SVE_POST_SET_PROCESSING_PARAM Failed\n\r")));
            }

#ifdef USE_CMM_FOR_YUVSURFACE
            tParamBuffer.dwBufferRGBY = \
                                m_OverlayCtxt.pSurface->OffsetInVideoMemory();
            if(m_OverlayCtxt.pSurface->m_hCmmFB == NULL)
            {
                tParamBuffer.dwBufferRGBY += m_VideoMemoryPhysicalBase;
            }
#else
            tParamBuffer.dwBufferRGBY = m_OverlayCtxt.pSurface->OffsetInVideoMemory() + m_VideoMemoryPhysicalBase;
#endif
            tParamBuffer.dwBufferCb = tParamBuffer.dwBufferRGBY+m_OverlayCtxt.pSurface->m_uiOffsetCb;
            tParamBuffer.dwBufferCr = tParamBuffer.dwBufferRGBY+m_OverlayCtxt.pSurface->m_uiOffsetCr;
            tParamBuffer.bWaitForVSync = TRUE;

            if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_POST_SET_SOURCE_BUFFER, &tParamBuffer, sizeof(SVEARG_POST_BUFFER), NULL, 0, &dwBytes, NULL) )
            {
                RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlayInitialize() : IOCTL_SVE_POST_SET_SOURCE_BUFFER Failed\n\r")));
            }

#ifdef OVERLAY_USE_MEM2MEM
            tParamBuffer.dwBufferRGBY = \
                    m_pOverlayDMAOutputBuf[m_uiCurPostFB]->OffsetInVideoMemory() + \
                    m_VideoMemoryPhysicalBase;
            tParamBuffer.dwBufferCb = tParamBuffer.dwBufferRGBY;
            tParamBuffer.dwBufferCr = tParamBuffer.dwBufferRGBY;
            tParamBuffer.bWaitForVSync = FALSE;
#else // OVERLAY_USE_MEM2MEM
            if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_POST_SET_NEXT_SOURCE_BUFFER, &tParamBuffer, sizeof(SVEARG_POST_BUFFER), NULL, 0, &dwBytes, NULL) )
            {
                RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_SVE_POST_SET_NEXT_SOURCE_BUFFER Failed at %d\n\r"), _T(__FUNCTION__), __LINE__));
            }

            if(m_pOverlayDMAOutputBuf1)
            {
                delete m_pOverlayDMAOutputBuf1;
            }
            m_pOverlayDMAOutputBuf1=NULL;
            AllocSurface((DDGPESurf**)&m_pOverlayDMAOutputBuf1, m_OverlayCtxt.uiDstWidth, m_OverlayCtxt.uiDstHeight, gpe32Bpp, EGPEFormatToEDDGPEPixelFormat[gpe32Bpp], GPE_REQUIRE_VIDEO_MEMORY);
            if(m_pOverlayDMAOutputBuf1 == NULL)
            {
                RETAIL_DISP_MSG(DISP_ZONE_WARNING,(TEXT("m_pOverlayOutputBuf1 Surface Allocation is failed. %d\n"), __LINE__));
                RETAIL_DISP_MSG(DISP_ZONE_WARNING,(TEXT("Maybe There's no sufficient video memory. please increase video memory\r\n")));
                return;
            }

            tParamBuffer.dwBufferRGBY = m_pOverlayDMAOutputBuf1->OffsetInVideoMemory() + m_VideoMemoryPhysicalBase;
            tParamBuffer.dwBufferCb = tParamBuffer.dwBufferRGBY;
            tParamBuffer.dwBufferCr = tParamBuffer.dwBufferRGBY;
            tParamBuffer.bWaitForVSync = TRUE;
#endif // OVERLAY_USE_MEM2MEM

            if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_POST_SET_DESTINATION_BUFFER, &tParamBuffer, sizeof(SVEARG_POST_BUFFER), NULL, 0, &dwBytes, NULL) )
            {
                RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlayInitialize() : IOCTL_SVE_POST_SET_SOURCE_BUFFER Failed\n\r")));
            }

            tParamMode.dwWinMode = m_OverlayCtxt.dwWinMode;
            tParamMode.dwBPP = m_OverlayCtxt.dwBPPMode;
            tParamMode.dwWidth = m_OverlayCtxt.uiDstWidth;
            tParamMode.dwHeight = m_OverlayCtxt.uiDstHeight;
            tParamMode.dwOffsetX = m_OverlayCtxt.uiDstOffsetX;
            tParamMode.dwOffsetY = m_OverlayCtxt.uiDstOffsetY;

            if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_MODE, &tParamMode, sizeof(SVEARG_FIMD_WIN_MODE), NULL, 0, &dwBytes, NULL) )
            {
                RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlayInitialize() : IOCTL_SVE_FIMD_SET_WINDOW_MODE Failed\n\r")));
            }

            tParamFB.dwWinNum = OVERLAY_WINDOW;
            tParamFB.dwFrameBuffer = tParamBuffer.dwBufferRGBY;
            tParamFB.bWaitForVSync = FALSE;

            if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_FRAMEBUFFER, &tParamFB, sizeof(SVEARG_FIMD_WIN_FRAMEBUFFER), NULL, 0, &dwBytes, NULL) )
            {
                RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlayInitialize() : IOCTL_SVE_FIMD_SET_WINDOW_FRAMEBUFFER Failed\n\r")));
            }

        }
    }
    else
    {
        SVEARG_FIMD_WIN_MODE tParamMode;
        SVEARG_FIMD_WIN_FRAMEBUFFER tParamFB;

        tParamMode.dwWinMode = m_OverlayCtxt.dwWinMode;
        tParamMode.dwBPP = m_OverlayCtxt.dwBPPMode;
        tParamMode.dwWidth = m_OverlayCtxt.uiDstWidth;
        tParamMode.dwHeight = m_OverlayCtxt.uiDstHeight;
        tParamMode.dwOffsetX = m_OverlayCtxt.uiDstOffsetX;
        tParamMode.dwOffsetY = m_OverlayCtxt.uiDstOffsetY;

        if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_MODE, &tParamMode, sizeof(SVEARG_FIMD_WIN_MODE), NULL, 0, &dwBytes, NULL) )
        {
            RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlayInitialize() : IOCTL_SVE_FIMD_SET_WINDOW_MODE Failed\n\r")));
        }

        tParamFB.dwWinNum = OVERLAY_WINDOW;
        tParamFB.dwFrameBuffer = m_OverlayCtxt.pSurface->OffsetInVideoMemory() + m_VideoMemoryPhysicalBase;
        tParamFB.bWaitForVSync = FALSE;

        if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_FRAMEBUFFER, &tParamFB, sizeof(SVEARG_FIMD_WIN_FRAMEBUFFER), NULL, 0, &dwBytes, NULL) )
        {
            RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlayInitialize() : IOCTL_SVE_FIMD_SET_WINDOW_FRAMEBUFFER Failed\n\r")));
        }
    }

    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] --DevOverlayInitialize()\n\r")));
}


void
SMDKDisp::DevOverlaySetPosition(void)
{
    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] ++DevOverlaySetPosition()\n\r")));

    DWORD dwBytes;

    SVEARG_FIMD_WIN_POS tParam;

    tParam.dwWinNum = OVERLAY_WINDOW;
    tParam.dwOffsetX = m_OverlayCtxt.uiDstOffsetX;
    tParam.dwOffsetY = m_OverlayCtxt.uiDstOffsetY;
    tParam.bWaitForVSync = TRUE;

    if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_POSITION, &tParam, sizeof(SVEARG_FIMD_WIN_POS), NULL, 0, &dwBytes, NULL) )
    {
        RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlaySetPosition() : IOCTL_SVE_FIMD_SET_WINDOW_POSITION Failed\n\r")));
    }

    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] --DevOverlaySetPosition()\n\r")));
}


void
SMDKDisp::DevOverlayEnable(void)
{
    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] ++%s()\n\r"), _T(__FUNCTION__)));

    DWORD dwBytes;

    if (!m_OverlayCtxt.bEnabled)
    {
        if(m_OverlayCtxt.bPostAttached)
        {
            if (m_OverlayCtxt.bLocalPath)
            {
                if ( !DeviceIoControl(m_hVideoDrv, IOCTL_OVERLAY_WINDOW_LOCALPATH_START, NULL, 0, NULL, 0, &dwBytes, NULL) )
                {
                    RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_OVERLAY_WINDOW_LOCALPATH_START Failed\n\r"), _T(__FUNCTION__)));
                }
            }
            else
            {
                DWORD dwParam;

                if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_POST_SET_PROCESSING_START, NULL, 0, NULL, 0, &dwBytes, NULL) )
                {
                    RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_SVE_POST_SET_PROCESSING_START Failed\n\r"), _T(__FUNCTION__)));
                }

#ifdef OVERLAY_USE_MEM2MEM
                if ( !DeviceIoControl(m_hVideoDrv, \
                                        IOCTL_SVE_POST_WAIT_PROCESSING_DONE, \
                                        NULL, 0, NULL, 0, &dwBytes, NULL) )
                {
                    RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_SVE_POST_WAIT_PROCESSING_DONE Failed\n\r"), _T(__FUNCTION__)));
                }
#endif // OVERLAY_USE_MEM2MEM

                dwParam = OVERLAY_WINDOW;
                if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_ENABLE, &dwParam, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
                {
                    RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_SVE_FIMD_SET_WINDOW_ENABLE Failed\n\r"), _T(__FUNCTION__)));
                }
            }
        }
        else
        {
            DWORD dwParam;
            dwParam = OVERLAY_WINDOW;
            if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_ENABLE, &dwParam, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
            {
                RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_SVE_FIMD_SET_WINDOW_ENABLE Failed\n\r"), _T(__FUNCTION__)));
            }
        }

        m_OverlayCtxt.bEnabled = TRUE;
    }

    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] --%s()\n\r"), _T(__FUNCTION__)));
}


void
SMDKDisp::DevOverlayDisable(void)
{
    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] ++%s()\n\r"), _T(__FUNCTION__)));

    DWORD dwBytes;

    if (m_OverlayCtxt.bEnabled)
    {
        if (m_OverlayCtxt.bPostAttached)
        {
            if (m_OverlayCtxt.bLocalPath)
            {
                if ( !DeviceIoControl(m_hVideoDrv, IOCTL_OVERLAY_WINDOW_LOCALPATH_STOP, NULL, 0, NULL, 0, &dwBytes, NULL) )
                {
                    RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_OVERLAY_WINDOW_LOCALPATH_STOP Failed\n\r"), _T(__FUNCTION__)));
                }
            }
            else
            {
                DWORD dwParam;
                dwParam = OVERLAY_WINDOW;
                if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_DISABLE, &dwParam, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
                {
                    RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_SVE_FIMD_SET_WINDOW_DISABLE Failed\n\r"), _T(__FUNCTION__)));
                }

                if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_POST_SET_PROCESSING_STOP, NULL, 0, NULL, 0, &dwBytes, NULL) )
                {
                    RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_SVE_POST_SET_PROCESSING_STOP Failed\n\r"), _T(__FUNCTION__)));
                }
#ifndef OVERLAY_USE_MEM2MEM
                if(m_pOverlayDMAOutputBuf1)
                {
                    delete m_pOverlayDMAOutputBuf1;
                }
                m_pOverlayDMAOutputBuf1=NULL;
#endif
            }
        }
        else
        {
            DWORD dwParam;
            dwParam = OVERLAY_WINDOW;
            if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_DISABLE, &dwParam, sizeof(DWORD), NULL, 0, &dwBytes, NULL) )
            {
                RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlayDisable() : IOCTL_SVE_FIMD_SET_WINDOW_DISABLE Failed\n\r")));
            }
        }

        m_OverlayCtxt.bEnabled = FALSE;
    }

    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] --DevOverlayDisable()\n\r")));
}

void
SMDKDisp::DevOverlayBlendDisable(void)
{
    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] DevOverlayBlendDisable()\n\r")));

    SVEARG_FIMD_WIN_COLORKEY tParamCKey;
    SVEARG_FIMD_WIN_ALPHA_EX tParamAlpha;
    DWORD dwBytes;

    // Color Key Disable
    tParamCKey.dwWinNum = PRIMARY_WINDOW;
    tParamCKey.bOnOff = FALSE;
    tParamCKey.bBlend = FALSE;
    tParamCKey.dwDirection = DISP_FG_MATCH_BG_DISPLAY;
    tParamCKey.dwColorKey = 0;
    tParamCKey.dwCompareKey = 0;

    // Alpha Set to 0x0 (Show Window0)
    tParamAlpha.dwWinNum = PRIMARY_WINDOW;
    tParamAlpha.dwMethod = DISP_ALPHA_PER_PLANE;
    tParamAlpha.dwAlpha0 = 0x0;
    tParamAlpha.dwAlpha1 = 0x0;
    tParamAlpha.dwABlendEq = DISP_BLDEQ_ALPHA_A;
    tParamAlpha.dwBBlendEq = DISP_BLDEQ_INV_ALPHA_A;
    tParamAlpha.dwPBlendEq = 0x0;
    tParamAlpha.dwQBlendEq = 0x0;

    if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_BLEND_COLORKEY, &tParamCKey, sizeof(SVEARG_FIMD_WIN_COLORKEY), NULL, 0, &dwBytes, NULL) )
    {
        RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlayBlendDisable() : IOCTL_SVE_FIMD_SET_WINDOW_BLEND_COLORKEY Failed\n\r")));
    }

    if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_BLEND_ALPHA_EX, &tParamAlpha, sizeof(SVEARG_FIMD_WIN_ALPHA_EX), NULL, 0, &dwBytes, NULL) )
    {
        RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlayBlendDisable() : IOCTL_SVE_FIMD_SET_WINDOW_BLEND_ALPHA_EX Failed\n\r")));
    }

}

void
SMDKDisp::DevOverlaySetColorKey(void)
{
    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] DevOverlaySetColorKey()\n\r")));

    SVEARG_FIMD_WIN_COLORKEY tParamCKey;
    DWORD dwBytes;

    if (m_OverlayCtxt.bSrcCKey)
    {
        tParamCKey.dwWinNum = PRIMARY_WINDOW;
        tParamCKey.bOnOff = TRUE;
        tParamCKey.bBlend = FALSE;
        tParamCKey.dwDirection = DISP_BG_MATCH_FG_DISPLAY;
        tParamCKey.dwColorKey = m_OverlayCtxt.ColorKey;
        tParamCKey.dwCompareKey = m_OverlayCtxt.CompareKey;
    }
    else
    {
        tParamCKey.dwWinNum = PRIMARY_WINDOW;
        tParamCKey.bOnOff = TRUE;
        tParamCKey.bBlend = FALSE;
        tParamCKey.dwDirection = DISP_FG_MATCH_BG_DISPLAY;
        tParamCKey.dwColorKey = m_OverlayCtxt.ColorKey;
        tParamCKey.dwCompareKey = m_OverlayCtxt.CompareKey;
    }

    if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_BLEND_COLORKEY, &tParamCKey, sizeof(SVEARG_FIMD_WIN_COLORKEY), NULL, 0, &dwBytes, NULL) )
    {
        RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlaySetColorKey() : IOCTL_SVE_FIMD_SET_WINDOW_BLEND_COLORKEY Failed\n\r")));
    }

}


void
SMDKDisp::DevOverlaySetAlpha(void)
{
    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] DevOverlaySetAlpha()\n\r")));

    SVEARG_FIMD_WIN_ALPHA_EX tParamAlphaEx;
    DWORD dwBytes;

    if (m_OverlayCtxt.bUsePixelBlend)
    {
        if(m_OverlayCtxt.bSrcAlpha)
        {
            tParamAlphaEx.dwWinNum = OVERLAY_WINDOW;
            tParamAlphaEx.dwMethod = DISP_ALPHA_PER_PIXEL;
            tParamAlphaEx.dwAlpha0 = 0;
            tParamAlphaEx.dwAlpha1 = 0;
            tParamAlphaEx.dwABlendEq = DISP_BLDEQ_ALPHA_B;
            tParamAlphaEx.dwBBlendEq = DISP_BLDEQ_INV_ALPHA_B;
            tParamAlphaEx.dwPBlendEq = 0;
            tParamAlphaEx.dwQBlendEq = 0;
        }
        else
        {
            tParamAlphaEx.dwWinNum = PRIMARY_WINDOW;
            tParamAlphaEx.dwMethod = DISP_ALPHA_PER_PIXEL;
            tParamAlphaEx.dwAlpha0 = 0;
            tParamAlphaEx.dwAlpha1 = 0;
            tParamAlphaEx.dwABlendEq = DISP_BLDEQ_ALPHA_A;
            tParamAlphaEx.dwBBlendEq = DISP_BLDEQ_INV_ALPHA_A;
            tParamAlphaEx.dwPBlendEq = 0;
            tParamAlphaEx.dwQBlendEq = 0;
        }
    }
    else
    {
        tParamAlphaEx.dwWinNum = PRIMARY_WINDOW;
        tParamAlphaEx.dwMethod = DISP_ALPHA_PER_PLANE;
        tParamAlphaEx.dwAlpha0 = m_OverlayCtxt.Alpha;
        tParamAlphaEx.dwAlpha1 = 0;
        tParamAlphaEx.dwABlendEq = DISP_BLDEQ_ALPHA_A;
        tParamAlphaEx.dwBBlendEq = DISP_BLDEQ_INV_ALPHA_A;
        tParamAlphaEx.dwPBlendEq = 0;
        tParamAlphaEx.dwQBlendEq = 0;
    }

    if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_BLEND_ALPHA_EX, &tParamAlphaEx, sizeof(SVEARG_FIMD_WIN_ALPHA_EX), NULL, 0, &dwBytes, NULL) )
    {
        RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlaySetAlpha() : IOCTL_SVE_FIMD_SET_WINDOW_BLEND_ALPHA_EX Failed\n\r")));
    }

}


void
SMDKDisp::DevOverlaySetColorKeyWithAlpha(void)
{
    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] DevOverlaySetColorKeyWithAlpha()\n\r")));

    SVEARG_FIMD_WIN_ALPHA_EX tParamAlphaEx;
    SVEARG_FIMD_WIN_COLORKEY tParamCKey;
    DWORD dwBytes;

    if (m_OverlayCtxt.bSrcCKey)
    {
        tParamAlphaEx.dwWinNum = PRIMARY_WINDOW;
        tParamAlphaEx.dwMethod = DISP_ALPHA_PER_PLANE;
        tParamAlphaEx.dwAlpha0 = 0;
        tParamAlphaEx.dwAlpha1 = 0;
        tParamAlphaEx.dwABlendEq = DISP_BLDEQ_ALPHA_A;
        tParamAlphaEx.dwBBlendEq = DISP_BLDEQ_INV_ALPHA_A;
        tParamAlphaEx.dwPBlendEq = 0;
        tParamAlphaEx.dwQBlendEq = 0;

        if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_BLEND_ALPHA_EX, &tParamAlphaEx, sizeof(SVEARG_FIMD_WIN_ALPHA_EX), NULL, 0, &dwBytes, NULL) )
        {
            RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlaySetColorKeyWithAlpha() : IOCTL_SVE_FIMD_SET_WINDOW_BLEND_ALPHA_EX Failed\n\r")));
        }

        tParamCKey.dwWinNum = PRIMARY_WINDOW;
        tParamCKey.bOnOff = TRUE;
        tParamCKey.bBlend = TRUE;
        tParamCKey.dwDirection = DISP_BG_MATCH_FG_DISPLAY;
        tParamCKey.dwColorKey = m_OverlayCtxt.ColorKey;
        tParamCKey.dwCompareKey = m_OverlayCtxt.CompareKey;
        tParamCKey.dwKeyAlpha = m_OverlayCtxt.Alpha;

        if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_BLEND_COLORKEY, &tParamCKey, sizeof(SVEARG_FIMD_WIN_COLORKEY), NULL, 0, &dwBytes, NULL) )
        {
            RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlaySetColorKeyWithAlpha() : IOCTL_SVE_FIMD_SET_WINDOW_BLEND_COLORKEY Failed\n\r")));
        }
    }
    else
    {
        tParamAlphaEx.dwWinNum = PRIMARY_WINDOW;
        tParamAlphaEx.dwMethod = DISP_ALPHA_PER_PLANE;
        tParamAlphaEx.dwAlpha0 = 0xFF;
        tParamAlphaEx.dwAlpha1 = 0xFF;
        tParamAlphaEx.dwABlendEq = DISP_BLDEQ_ALPHA_A;
        tParamAlphaEx.dwBBlendEq = DISP_BLDEQ_INV_ALPHA_A;
        tParamAlphaEx.dwPBlendEq = 0;
        tParamAlphaEx.dwQBlendEq = 0;

        if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_BLEND_ALPHA_EX, &tParamAlphaEx, sizeof(SVEARG_FIMD_WIN_ALPHA_EX), NULL, 0, &dwBytes, NULL) )
        {
            RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlaySetColorKeyWithAlpha() : IOCTL_SVE_FIMD_SET_WINDOW_BLEND_ALPHA_EX Failed\n\r")));
        }

        tParamCKey.dwWinNum = PRIMARY_WINDOW;
        tParamCKey.bOnOff = TRUE;
        tParamCKey.bBlend = TRUE;
        tParamCKey.dwDirection = DISP_FG_MATCH_BG_DISPLAY;
        tParamCKey.dwColorKey = m_OverlayCtxt.ColorKey;
        tParamCKey.dwCompareKey = m_OverlayCtxt.CompareKey;
        tParamCKey.dwKeyAlpha = m_OverlayCtxt.Alpha;

        if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_BLEND_COLORKEY, &tParamCKey, sizeof(SVEARG_FIMD_WIN_COLORKEY), NULL, 0, &dwBytes, NULL) )
        {
            RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlaySetColorKeyWithAlpha() : IOCTL_SVE_FIMD_SET_WINDOW_BLEND_COLORKEY Failed\n\r")));
        }
    }
}


void
SMDKDisp::DevRecoverOverlay(void)
{
    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] ++DevRecoverOverlay()\n\r")));

    if (m_OverlayCtxt.bShow)
    {
        // Initialize Overlay Window
        DevOverlayInitialize();

        // Configure Blending
        if (m_OverlayCtxt.bBlendOn)
        {
            if (m_OverlayCtxt.bColorKey)
            {
                DevOverlaySetColorKey();
            }
            else if (m_OverlayCtxt.bColorKeyWithAlpha)
            {
                DevOverlaySetColorKeyWithAlpha();
            }
            else
            {
                DevOverlaySetAlpha();
            }
        }
        else
        {
            DevOverlayBlendDisable();
        }

        DevOverlayEnable();
    }

    RETAIL_DISP_MSG(DISP_ZONE_ENTER, (_T("[DISPDRV] --DevRecoverOverlay()\n\r")));
}

#ifdef OVERLAY_USE_MEM2MEM
void
SMDKDisp::Post_thread(void)
{
    DWORD dwBytes;
    SVEARG_FIMD_WIN_FRAMEBUFFER tParamFB;

    RETAIL_DISP_MSG(DISP_ZONE_ENTER,(_T("\r\n\r\n[DISPDRV] ++%s()\r\n\r\n"),_T(__FUNCTION__)));

    CeSetThreadPriority(m_hPostIST, POST_THREAD_PRIORITY);

    while(!m_bPostThreadExit)
    {
        //RETAIL_DISP_MSG(DISP_ZONE_TEMP,(_T("[DISPDRV] %s() : m_hPostBusyEvent(m_hPostBusyEvent)\r\n"),_T(__FUNCTION__)));
        WaitForSingleObject(m_hPostBusyEvent, INFINITE);

        if(m_bPostThreadExit)
        {
            break;
        }

        if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_POST_WAIT_PROCESSING_DONE, \
                                NULL, 0, NULL, 0, &dwBytes, NULL) )
        {
            RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] %s() : IOCTL_SVE_POST_WAIT_PROCESSING_DONE Failed\n\r"), _T(__FUNCTION__)));
        }

        tParamFB.dwWinNum = OVERLAY_WINDOW;
        tParamFB.dwFrameBuffer = \
                m_pOverlayDMAOutputBuf[m_uiCurPostFB]->OffsetInVideoMemory() + \
                m_VideoMemoryPhysicalBase;
        tParamFB.bWaitForVSync = FALSE;

        //RETAIL_DISP_MSG(DISP_ZONE_TEMP,(_T("[DISPDRV] %s() : m_uiCurPostFB = %d\r\n"),_T(__FUNCTION__),m_uiCurPostFB));

        if ( !DeviceIoControl(m_hVideoDrv, IOCTL_SVE_FIMD_SET_WINDOW_FRAMEBUFFER, &tParamFB, sizeof(SVEARG_FIMD_WIN_FRAMEBUFFER), NULL, 0, &dwBytes, NULL) )
        {
            RETAIL_DISP_MSG(DISP_ZONE_ERROR, (_T("[DISPDRV:ERR] DevOverlayInitialize() : IOCTL_SVE_FIMD_SET_WINDOW_FRAMEBUFFER Failed\n\r")));
        }

        SetEvent(m_hPostReadyEvent);
        //RETAIL_DISP_MSG(DISP_ZONE_TEMP,(_T("[DISPDRV] %s() : SetEvent(m_hPostReadyEvent) 0x%x\r\n"),_T(__FUNCTION__),m_hPostReadyEvent));
    }

    RETAIL_DISP_MSG(DISP_ZONE_ENTER,(_T("\r\n\r\n[DISPDRV] --%s()\r\n\r\n"),_T(__FUNCTION__)));

    SetEvent(m_hPostTreadEnd);
}
#endif

