📄 ddlcdcoverlay.cpp
字号:
//------------------------------------------------------------------------------
//
// 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 + -