⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddlcdcoverlay.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//------------------------------------------------------------------------------
//
//  Copyright (c) Microsoft Corporation.  All rights reserved.
//
//------------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//  Copyright (C) 2004-2005, MOTOROLA, INC. All Rights Reserved
//  THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
//  BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
//  MOTOROLA, INC.
//------------------------------------------------------------------------------
//---------------------------------------------------------------------------
//  Copyright (C) 2005-2006, 2007, Freescale Semiconductor, Inc. All Rights Reserved.
//  THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
//  AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//---------------------------------------------------------------------------

//------------------------------------------------------------------------------
//
// File:        DDLcdcOverlay.cpp
//
//  Implementation of Overlay-related functions for DDLCDC class, the
//  DirectDraw display driver.
//
//-----------------------------------------------------------------------------

#include "precomp.h"


//-----------------------------------------------------------------------------
// External Functions


//-----------------------------------------------------------------------------
// External Variables

//-----------------------------------------------------------------------------
// Local Functions
BOOL IsOverlaySurfEqual(pOverlaySurf_t pSurf1, pOverlaySurf_t pSurf2);

//-----------------------------------------------------------------------------
// Defines
//------------------------------------------------------------------------------
// Convert Microsoft color key mask into the one of the LCDC of i.MX27 for graphic window
// Microsoft : r bit 0~7; g bit 8~15; b bit 16~23
// i.MX27:     r bit 12~17; g bit 6~11, b bit 0~5
#define CONFIGURE_COLORKEY(colorKey32)   colorKey32 = ( \
        ((colorKey32 << 12) & bmLCDC_GWCR_GWCKR) |      \
        ((colorKey32 >>  2) & bmLCDC_GWCR_GWCKG) |      \
        ((colorKey32 >> 16) & bmLCDC_GWCR_GWCKB)        \
        )

#if (UNDER_CE >= 600)
#define IsOverlayMirrorUpDown(pd) (pd->dwFlags & DDOVER_MIRRORUPDOWN)
#else
#define IsOverlayMirrorUpDown(pd) ((pd->dwFlags & DDOVER_DDFX) && (pd->overlayFX.dwDDFX & DDOVERFX_MIRRORUPDOWN))
#endif


#define DUMP_OVERLAY_OP()   {\
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->isGraphicWindowRunning %s\r\n"), m_pOverlaySurfaceOp->isGraphicWindowRunning ? L"TRUE" : L"FALSE"));    \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->nBufPhysicalAddr 0x%08x\r\n"), m_pOverlaySurfaceOp->nBufPhysicalAddr));                                 \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->Width            %d\r\n"), m_pOverlaySurfaceOp->Width));                                                \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->Height           %d\r\n"), m_pOverlaySurfaceOp->Height));                                               \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->WidthHw          %d\r\n"), m_pOverlaySurfaceOp->WidthHw));                                              \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->HeightHw         %d\r\n"), m_pOverlaySurfaceOp->HeightHw));                                             \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->LineStride       %d\r\n"), m_pOverlaySurfaceOp->LineStride));                                           \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->XOffset          %d\r\n"), m_pOverlaySurfaceOp->XOffset));                                              \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->YOffset          %d\r\n"), m_pOverlaySurfaceOp->YOffset));                                              \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->Transparency     %d\r\n"), m_pOverlaySurfaceOp->Transparency));                                         \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->isUpsideDown     %s\r\n"), m_pOverlaySurfaceOp->isUpsideDown ? L"TRUE" : L"FALSE"));                    \
    DEBUGMSG(1, (TEXT("Overlay OP: Overlay->ColorKeyMask     0x%08x\r\n"), m_pOverlaySurfaceOp->ColorKeyMask));                                     \
}

#define SETUP_OVERLAY_POSITION(X, Y) switch(m_iRotate){ \
        case DMDO_0:                                                                                        \
            m_pOverlaySurfaceOp->XOffset = (UINT16)X;                                                       \
            m_pOverlaySurfaceOp->YOffset = (UINT16)Y;                                                       \
            break;                                                                                          \
        case DMDO_90:                                                                                       \
            m_pOverlaySurfaceOp->XOffset = (UINT16)Y;                                                       \
            m_pOverlaySurfaceOp->YOffset = (UINT16)(m_pMode->width - (X + m_pOverlaySurfaceOp->Width));     \
            break;                                                                                          \
        case DMDO_180:                                                                                      \
            m_pOverlaySurfaceOp->XOffset = (UINT16)(m_pMode->width - (X + m_pOverlaySurfaceOp->Width));     \
            m_pOverlaySurfaceOp->YOffset = (UINT16)(m_pMode->height - (Y + m_pOverlaySurfaceOp->Height));   \
            break;                                                                                          \
        case DMDO_270:                                                                                      \
            m_pOverlaySurfaceOp->XOffset = (UINT16)(m_pMode->height - (Y + m_pOverlaySurfaceOp->Height));   \
            m_pOverlaySurfaceOp->YOffset = (UINT16)X;                                                       \
            break;                                                                                          \
        default:                                                                                            \
            break;                                                                                          \
}


//------------------------------------------------------------------------------
// CLASS MEMBER FUNCTIONS
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
// Function: UpdateOverlay
//
// This function repositions or modifies the visual
// attributes of an overlay surface.
//
// Parameters:
//      pd
//          [in, out] Pointer to a DDHAL_UPDATEOVERLAYDATA structure that
//          contains the information required to update the overlay surface.
//
// Returns:
//      Returns one of the following values:
//       DDHAL_DRIVER_HANDLED
//       DDHAL_DRIVER_NOTHANDLED
//
//------------------------------------------------------------------------------
DWORD MX27DDLcdc::UpdateOverlay(LPDDHAL_UPDATEOVERLAYDATA pd)
{
    /*
    typedef struct _DDHAL_UPDATEOVERLAYDATA
    {
        LPDDRAWI_DIRECTDRAW_GBL     lpDD;           // driver struct
        LPDDRAWI_DDRAWSURFACE_LCL   lpDDDestSurface;// dest surface
        RECTL                       rDest;          // dest rect
        LPDDRAWI_DDRAWSURFACE_LCL   lpDDSrcSurface; // src surface
        RECTL                       rSrc;           // src rect
        DWORD                       dwFlags;        // flags
        DDOVERLAYFX                 overlayFX;      // overlay FX
        HRESULT                     ddRVal;         // return value
        LPDDHALSURFCB_UPDATEOVERLAY UpdateOverlay;  // PRIVATE: ptr to callback
    } DDHAL_UPDATEOVERLAYDATA;
    */
    overlaySurf_t overlaySurfInfo;

    DDGPESurf* pSrcSurf = DDGPESurf::GetDDGPESurf(pd->lpDDSrcSurface);

    if (pd->dwFlags & DDOVER_HIDE)
    {
        DEBUGMSG(GPE_ZONE_HW, (TEXT("MX27DDLcdc::OVERLAY HIDE REQUEST\r\n")));
        if (pSrcSurf == m_pVisibleOverlay)
        {
            // hide the overlay
            //WaitForVSync();
            DisableOverlay();
            // reset visible overlay
            m_pVisibleOverlay = NULL;
            DEBUGMSG(GPE_ZONE_HW, (TEXT("MX27DDLcdc::OVERLAY HIDE!\r\n")));
        }
        else
        {
            // the overlay is not currently visible
            // nothing we need to do here
        }

        pd->ddRVal = DD_OK;
        goto _done;
    }

    DDGPESurf* pDstSurf = DDGPESurf::GetDDGPESurf(pd->lpDDDestSurface);

    if (pSrcSurf != m_pVisibleOverlay)
    {
        if (pd->dwFlags & DDOVER_SHOW)
        {
            DEBUGMSG(GPE_ZONE_HW, (TEXT("MX27DDLcdc::OVERLAY SHOW REQUEST\r\n")));
            if (m_pVisibleOverlay != NULL)
            {
                // some other overlay is already visible
                DEBUGMSG(GPE_ZONE_ERROR,
                          (TEXT("Error: Other overlay already visible!\r\n")));
                pd->ddRVal = DDERR_OUTOFCAPS;
                goto _done;
            }
            else
            {
                // we are going to make the overlay visible
                // so mark it as such:
                m_pVisibleOverlay = pSrcSurf;
                DEBUGMSG(GPE_ZONE_HW, (TEXT("MX27DDLcdc::OVERLAY SHOW\r\n")));
            }
        }
        else // DDOVER_SHOW not requested
        {
            // the overlay isn't visible, and we haven't been
            // asked to make it visible, so nothing we need to do
            pd->ddRVal = DD_OK;
            goto _done;
        }
    }

    overlaySurfInfo.Width   = (UINT16)(pd->rDest.right - pd->rDest.left);
    overlaySurfInfo.Height  = (UINT16)(pd->rDest.bottom - pd->rDest.top);

    switch(m_iRotate)
    {
        case DMDO_0:
        case DMDO_180:
            overlaySurfInfo.WidthHw = overlaySurfInfo.Width;
            overlaySurfInfo.HeightHw = overlaySurfInfo.Height;
            break;

        case DMDO_90:
        case DMDO_270:
            overlaySurfInfo.WidthHw = overlaySurfInfo.Height;
            overlaySurfInfo.HeightHw = overlaySurfInfo.Width;
            break;
        default:
            break;
    }

    // Parameter validity check
    if(
        (pd->rDest.right  > m_pMode->width)  ||
        (pd->rDest.bottom > m_pMode->height) ||
        (overlaySurfInfo.WidthHw & 0xF)   ||
        (overlaySurfInfo.WidthHw < LCDC_MIN_GRAPHICWINDOW_WIDTH)
        )
    {
        DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc UpdateOverlay: wrong parameters!\r\n")));
        DUMP_OVERLAY_OP();
        pd->ddRVal = DDERR_INVALIDPARAMS;
        goto _done;
    }

    overlaySurfInfo.LineStride = overlaySurfInfo.WidthHw * m_pMode->Bpp / 8;

    SETUP_OVERLAY_POSITION(pd->rDest.left, pd->rDest.top);

    overlaySurfInfo.nBufPhysicalAddr = m_nLAWPhysical + pSrcSurf->OffsetInVideoMemory();

    // Setup if overlay is flipped as upside-down
    if(IsOverlayMirrorUpDown(pd))
    {
        DEBUGMSG(GPE_ZONE_HW, (TEXT("MX27DDLcdc UpdateOverlay: upside-down overlay is requested!\r\n")));
        overlaySurfInfo.isUpsideDown = TRUE;
    }
    else
    {
        overlaySurfInfo.isUpsideDown = FALSE;
    }

    // Setup color key.
    // LCDC only supports one color key value and does not
    // support a range.  So, we take the low value
    // from the color key mask to use as the color key.

    // Initialize color key mask to 0xFFFFFFFF.  If no color keying
    // is specified, this 0xFFFFFFFF will indicate no color key.
    overlaySurfInfo.ColorKeyMask = 0xFFFFFFFF;

    if(pd->dwFlags & DDOVER_KEYSRC)
    {
        overlaySurfInfo.ColorKeyMask = pd->lpDDSrcSurface->ddckCKSrcOverlay.dwColorSpaceLowValue;
    }
    else if(pd->dwFlags & DDOVER_KEYSRCOVERRIDE)
    {
        overlaySurfInfo.ColorKeyMask = pd->overlayFX.dckSrcColorkey.dwColorSpaceLowValue;
    }

    if(pd->dwFlags & DDOVER_KEYDEST)
    {
        DEBUGMSG(1,
          (TEXT("Error: can't handle dest color keying!\r\n")));
        pd->ddRVal = DDERR_INVALIDPARAMS;
        return (DDHAL_DRIVER_HANDLED);

        // overlaySurfInfo.ColorKeyMask = pd->lpDDDestSurface->ddckCKDestOverlay.dwColorSpaceLowValue;

    }
    else if(pd->dwFlags & DDOVER_KEYDESTOVERRIDE)
    {
        DEBUGMSG(1,
          (TEXT("Error: can't handle dest color keying!\r\n")));
        pd->ddRVal = DDERR_INVALIDPARAMS;
        return (DDHAL_DRIVER_HANDLED);

        // overlaySurfInfo.ColorKeyMask = pd->overlayFX.dckDestColorkey.dwColorSpaceLowValue;
        /*
        // This is a hack required because of incompatibilities between DDraw
        // and rotation.  The wrong color key is provided in rotation mode if
        // this is not included.  For Windows Media Player, this should always
        // be the color key: 0x841
        if (m_iRotate)
        {
            //DEBUGMSG(1, (TEXT("UpdateOverlay: Color Key hack - set to 0x841 for CE player overlay.\r\n")));
            overlaySurfInfo.ColorKeyMask = 0x841;
        }
        */
    }

    // Setup alpha blending
    overlaySurfInfo.Transparency = 0x00;

    if(pd->dwFlags & DDOVER_ALPHASRC)
    {
        overlaySurfInfo.Transparency = (UINT16)(pd->lpDDSrcSurface->ddOverlayFX.dwAlphaConst);
    }
    if(pd->dwFlags & DDOVER_ALPHASRCNEG)
    {
        overlaySurfInfo.Transparency = 0xff-overlaySurfInfo.Transparency;
    }
    if(pd->dwFlags & DDOVER_ALPHADEST)
    {
        DEBUGMSG(1,
          (TEXT("Error: can't handle dest alpha!\r\n")));
        pd->ddRVal = DDERR_INVALIDPARAMS;
        return (DDHAL_DRIVER_HANDLED);
    }
    if(pd->dwFlags & DDOVER_ALPHADESTNEG)
    {
        DEBUGMSG(1,
          (TEXT("Error: can't handle dest alpha!\r\n")));
        pd->ddRVal = DDERR_INVALIDPARAMS;
        return (DDHAL_DRIVER_HANDLED);
    }

    // If overlay surface data has not changed, skip
    // step to set up overlay and return.
    if (!IsOverlaySurfEqual(m_pOverlaySurfaceOp, &overlaySurfInfo))
    {
        overlaySurfInfo.XOffset = m_pOverlaySurfaceOp->XOffset;
        overlaySurfInfo.YOffset = m_pOverlaySurfaceOp->YOffset;
        overlaySurfInfo.isGraphicWindowRunning = m_pOverlaySurfaceOp->isGraphicWindowRunning;
        memcpy(m_pOverlaySurfaceOp, &overlaySurfInfo, sizeof(overlaySurf_t));

        // Update the graphic window of LCDC of i.MX27 processor
        pd->ddRVal = EnableOverlay();
    }
    else
    {
        pd->ddRVal = DD_OK;
    }

_done:
    DEBUGMSG(GPE_ZONE_HW, (TEXT("MX27DDLcdc UpdateOverlay: %s!\r\n"), (pd->ddRVal == DD_OK) ? L"successful" : L"failed"));
    return DDHAL_DRIVER_HANDLED;
}


//------------------------------------------------------------------------------
//
// Function: SetOverlayPosition
//
// This callback function changes the display coordinates of
// an overlay surface.
//
// Parameters:
//      pd
//          [in, out] Pointer to a DDHAL_SETOVERLAYPOSITIONDATA structure
//          that contains the information required to change the display
//          coordinates of an overlay surface.
//
// Returns:
//      Returns one of the following values:
//       DDHAL_DRIVER_HANDLED
//       DDHAL_DRIVER_NOTHANDLED
//
//------------------------------------------------------------------------------
DWORD MX27DDLcdc::SetOverlayPosition(LPDDHAL_SETOVERLAYPOSITIONDATA pd)
{
    /*
    typedef struct _DDHAL_SETOVERLAYPOSITIONDATA
    {
        LPDDRAWI_DIRECTDRAW_GBL     lpDD;           // driver struct
        LPDDRAWI_DDRAWSURFACE_LCL   lpDDSrcSurface; // src surface
        LPDDRAWI_DDRAWSURFACE_LCL   lpDDDestSurface;// dest surface
        LONG                        lXPos;          // x position
        LONG                        lYPos;          // y position
        HRESULT                     ddRVal;         // return value
        LPDDHALSURFCB_SETOVERLAYPOSITION SetOverlayPosition;
                                                    // PRIVATE: ptr to callback
    } DDHAL_SETOVERLAYPOSITIONDATA;
    */

    if(!m_pOverlaySurfaceOp->isGraphicWindowRunning)
    {
        // The graphic window is not running
        pd->ddRVal = DD_OK;
        return DDHAL_DRIVER_HANDLED;

⌨️ 快捷键说明

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