📄 hwverify.cpp
字号:
/***************************************************************************
* Name : hwverify.cpp
* Title : MBX WinCE driver GPE class header
* Author(s) : Imagination Technologies
* Created : 12th February 2003
*
* Copyright : 2003 by Imagination Technologies. All rights reserved.
* : No part of this software, either material or conceptual
* : may be copied or distributed, transmitted, transcribed,
* : stored in a retrieval system or translated into any
* : human or computer language in any form by any means,
* : electronic, mechanical, manual or other-wise, or
* : disclosed to third parties without the express written
* : permission of Imagination Technologies Limited, Unit 8,
* : HomePark Industrial Estate, King's Langley, Hertfordshire,
* : WD4 8LZ, U.K.
*
* Description : MBX WinCE driver GPE class.
*
* Platform : WinCE
*
* Modifications:-
* $Log: hwverify.cpp $
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
****************************************************************************/
#include "precomp.h"
#include "tstring.h"
#if HW_VERIFY
static void MessageAnsi(PSTR pszFormat, ...);
static BOOL FindIntersection(PRECT psRect1, PRECT psRect2, PRECT psIntersect);
static PVOID FindMemCmpFail(PVOID pv1, PVOID pv2, ULONG ulSize);
static PVOID CompareSurfaces(PBYTE pbySrc, ULONG ulSrcDx, ULONG ulSrcDy, ULONG ulSrcStride,
PBYTE pbyDst, ULONG ulDstStride, ULONG ulBPP);
static PVOID Compare32BppSurfacesWithoutAlpha(PBYTE pbySrc, ULONG ulSrcDx, ULONG ulSrcDy, ULONG ulSrcStride,
PBYTE pbyDst, ULONG ulDstStride, ULONG ulBPP);
static BOOL CreateBmp(LPCTSTR pwszFileName, PVOID pvData, ULONG ulX, ULONG ulY, ULONG ulStride,
ULONG ulBPP, EGPEFormat eDstFmt, RGBQUAD *prgbqPalette);
static void CopySurface(PBYTE pbySrc, ULONG ulSrcDx, ULONG ulSrcDy, ULONG ulSrcStride, PBYTE pbyDst, ULONG ulDstStride, ULONG ulBPP);
#if PDUMP
#define MessageAndPDumpComment(x) MessageAnsi x; PDumpScript x;
#else
#define MessageAndPDumpComment(x) MessageAnsi x;
#endif
static ULONG HwDestToABGR(EGPEFormat eFormat, ULONG ulPixel);
DWORD gdwActionReplay=0;
/* blue, green, red, res */
static RGBQUAD gMaskPalette[2] = {{0x00, 0x00, 0x00, 0x00},
{0xFF, 0xFF, 0xFF, 0x00}};
static RGBQUAD gAlphaPalette[16] = {{0x00, 0x00, 0x00},
{0x11, 0x11, 0x11},
{0x22, 0x22, 0x22},
{0x33, 0x33, 0x33},
{0x44, 0x44, 0x44},
{0x55, 0x55, 0x55},
{0x66, 0x66, 0x66},
{0x77, 0x77, 0x77},
{0x88, 0x88, 0x88},
{0x99, 0x99, 0x99},
{0xAA, 0xAA, 0xAA},
{0xBB, 0xBB, 0xBB},
{0xCC, 0xCC, 0xCC},
{0xDD, 0xDD, 0xDD},
{0xEE, 0xEE, 0xEE},
{0xFF, 0xFF, 0xFF} };
#pragma pack(push, 1)
typedef struct
{
BITMAPFILEHEADER bmfHeader;
BITMAPINFOHEADER bmiHeader;
}BMP_HEADER, *PBMP_HEADER;
#pragma pack(pop)
CHWVerify::CHWVerify()
{
m_bEnabled = FALSE; //TRUE;
m_bPDumpFailures = TRUE;
m_bUnattendedMode = FALSE;
m_eVerDst = VERDST_RECT_PLUS;
m_ulVerifyedBlts = 0;
m_ulAccelerated = 0;
m_ulNoDestCopy = 0;
m_bInit = FALSE;
m_ulDstCopySize = 0;
m_ulHwVerifyFailureCo = 1;
m_pvDestSwCopy = NULL;
m_pvDestPDumpCopy = NULL;
m_sVerifyRgn.left = 0;
m_sVerifyRgn.right = 0;
m_sVerifyRgn.top = 0;
m_sVerifyRgn.bottom = 0;
m_bExtendTop = FALSE;
m_bExtendBottom = FALSE;
m_bExtendLeft = FALSE;
m_bExtendRight = FALSE;
m_bPDumpingOn = FALSE;
m_bForceFail = FALSE;
m_nClipIndex = 0;
m_nClipRectCount = 0;
m_nBufInfoIndex = 0;
wcscpy(m_tszHWVerPath, L"\\release\\");
}
/***********************************************************************************
Function Name : EnableHwVerForMode
Inputs :
Outputs :
Returns :
Globals Used :
Description :
************************************************************************************/
void CHWVerify::EnableHwVerForMode(ULONG ulPriSurfSize)
{
/* Calc size of primary surface */
m_ulDstCopySize = ulPriSurfSize;
if ((m_pvDestSwCopy = AllocSharedMem(m_ulDstCopySize)) == NULL)
{
m_bInit = FALSE;
}
else
{
m_bInit = TRUE;
/* Alloc PDump copy of dest if we want it */
if (m_bPDumpFailures == TRUE)
{
if ((m_pvDestPDumpCopy = AllocSharedMem(m_ulDstCopySize)) == NULL)
{
FreeSharedMem(m_pvDestSwCopy);
m_bInit = FALSE;
}
}
}
}
/***********************************************************************************
Function Name : DisableHwVerForMode
Inputs :
Outputs :
Returns :
Globals Used :
Description :
************************************************************************************/
void CHWVerify::DisableHwVerForMode(void)
{
if (m_bInit == TRUE)
{
FreeSharedMem(m_pvDestSwCopy);
m_bInit = FALSE;
if (m_bPDumpFailures == TRUE)
{
FreeSharedMem(m_pvDestPDumpCopy);
}
}
}
/***********************************************************************************
Function Name : IsVerifyEnabled
Inputs :
Outputs :
Returns :
Globals Used :
Description :
************************************************************************************/
BOOL CHWVerify::IsVerifyEnabled ()
{
return ((m_bInit && m_bEnabled) ? TRUE : FALSE);
}
/***********************************************************************************
Function Name : PrepareToPDumpThisBlt
Inputs :
Outputs :
Returns :
Globals Used :
Description :
************************************************************************************/
BOOL CHWVerify::PrepareToPDumpThisBlt ()
{
/* setup path for dumped files */
wsprintf(m_tszHWVerPath, L"\\release\\hwver_%d", m_ulHwVerifyFailureCo);
#if PDUMP
if (m_bInit)
{
if (m_bEnabled)
{
IMG_CHAR szHWVerPath[128];
TSTRTOASCII((char *)&szHWVerPath, (TCHAR *)&m_tszHWVerPath, 0 );
return (PDumpEnableVirtual((IMG_PCHAR)&szHWVerPath));
}
else
{
return PDumpDisableVirtual();
}
}
#endif
return (FALSE);
}
/***********************************************************************************
Function Name : PrepareForSWBlt
Inputs :
Outputs :
Returns :
Globals Used :
Description :
************************************************************************************/
BOOL CHWVerify::PrepareForSWBlt (GPEBltParms *psParms)
{
if ((psParms->pSrc != NULL) &&
(psParms->pSrc->Buffer() == psParms->pDst->Buffer()))
{
((MBXSurf *)psParms->pSrc)->SetBuffer((ADDRESS)m_pvDestSwCopy);
}
((MBXSurf *)psParms->pDst)->SetBuffer((ADDRESS)m_pvDestSwCopy);
return (TRUE);
}
/***********************************************************************************
Function Name : RestoreForHWBlt
Inputs :
Outputs :
Returns :
Globals Used :
Description :
************************************************************************************/
BOOL CHWVerify::RestoreForHWBlt (GPEBltParms *psParms)
{
if ((psParms->pSrc != NULL) &&
(psParms->pSrc->Buffer() == psParms->pDst->Buffer()))
{
((MBXSurf *)psParms->pSrc)->SetBuffer((ADDRESS)m_pbyDstPtr);
}
((MBXSurf *)psParms->pDst)->SetBuffer((ADDRESS)m_pbyDstPtr);
return (TRUE);
}
/***********************************************************************************
Function Name : RotateRegion
Inputs : psRegion (Logical), lBitmapHeight and lBitmapWidth (Physical)
Outputs : Physical region
Returns :
Globals Used :
Description : Logical to physical mapping of rotated destination rectangle.
************************************************************************************/
void CHWVerify::RotateRegion(PRECT psRegion, LONG lBitmapHeight, LONG lBitmapWidth)
{
RECT sInput;
CopyRect(psRegion, &sInput); // Take a copy of the unrotated region.
switch (m_lDestAngle)
{
// CE90 anticlockwise. (MBX 270 clockwise)
case 90:
{
psRegion->top = lBitmapHeight - sInput.right;
psRegion->bottom = lBitmapHeight - sInput.left;
psRegion->left = sInput.top;
psRegion->right = sInput.bottom;
break;
}
// CE180 anticlockwise.
case 180:
{
psRegion->top = lBitmapHeight - sInput.bottom;
psRegion->bottom = lBitmapHeight - sInput.top;
psRegion->left = lBitmapWidth - sInput.right;
psRegion->right = lBitmapWidth - sInput.left;
break;
}
// CE270 anticlockwise. (MBX 90 clockwise)
case 270:
{
psRegion->top = sInput.left;
psRegion->bottom = sInput.right;
psRegion->left = lBitmapWidth - sInput.bottom;
psRegion->right = lBitmapWidth - sInput.top;
break;
}
}
}
/***********************************************************************************
Function Name : MakeVerifyRect
Inputs :
Outputs :
Returns :
Globals Used :
Description : Logical to physical mapping of rotated destination rectangle.
************************************************************************************/
BOOL CHWVerify::MakeVerifyRect(GPEBltParms *psParms, LONG lDestRotation)
{
PBYTE pbySurfStart;
ULONG ulCopyOffset;
LONG lDstWidth = psParms->pDst->Width();
LONG lDstHeight = psParms->pDst->Height();
ULONG ulDstStride = psParms->pDst->Stride();
ULONG ulDstBpp = EGPEFormatToBpp[psParms->pDst->Format()];
m_pbyDstPtr = (PBYTE)psParms->pDst->Buffer();
m_lDestAngle = lDestRotation;
m_lDstWidth = lDstWidth;
m_lDstHeight = lDstHeight;
if (m_lDestAngle == 270 || m_lDestAngle == 90)
{
m_lDstWidthRotated = m_lDstHeight; // m_lDstWidthRotated is the phys bimtmap width
m_lDstHeightRotated = m_lDstWidth; // m_lDstHeightRotated is the phys bimtmap height
}
else
{
m_lDstWidthRotated = m_lDstWidth;
m_lDstHeightRotated = m_lDstHeight;
}
/* Inc counter */
m_ulVerifyedBlts++;
/*
Check the whole surface if we have VERDST_ALL,
or if we have a NULL psParms->prclDst
or the source and destination is on the same surface.
*/
if ( (m_eVerDst == VERDST_ALL)
|| (psParms->prclDst == NULL)
|| (psParms->pSrc && (m_pbyDstPtr == (PBYTE)psParms->pSrc->Buffer()))
)
{
/* Whole surface */
m_sVerifyRgn.top = 0;
m_sVerifyRgn.left = 0;
m_sVerifyRgn.bottom = lDstHeight; // Logical (rotated); we will unrotate later.
m_sVerifyRgn.right = lDstWidth;
}
else if (psParms->prclDst)
{
ULONG ulTmp;
/* Use the destination rectangle */
CopyRect(psParms->prclDst, &m_sVerifyRgn);
/* make sure rectangle is adjusted for -ve stretching */
if (m_sVerifyRgn.left > m_sVerifyRgn.right)
{
ulTmp = m_sVerifyRgn.left;
m_sVerifyRgn.left = m_sVerifyRgn.right;
m_sVerifyRgn.right = ulTmp;
}
if (m_sVerifyRgn.top > m_sVerifyRgn.bottom)
{
ulTmp = m_sVerifyRgn.top;
m_sVerifyRgn.top = m_sVerifyRgn.bottom;
m_sVerifyRgn.bottom = ulTmp;
}
}
/* Check the validity of the rectangle */
if ((m_sVerifyRgn.bottom < 0) ||
(m_sVerifyRgn.right < 0) ||
(m_sVerifyRgn.top > lDstHeight) ||
(m_sVerifyRgn.left > lDstWidth ) )
{
/* nothing to copy */
return (FALSE);
}
/* Check if we want to increase the border */
if (m_eVerDst == VERDST_RECT_PLUS)
{
/* We have not extended in any direction yet */
m_bExtendBottom = FALSE;
m_bExtendRight = FALSE;
m_bExtendLeft = FALSE;
m_bExtendTop = FALSE;
// Now if possible add a small border (1 pixel) to detect overdraw.
if (m_sVerifyRgn.right < lDstWidth)
{
m_sVerifyRgn.right++;
m_bExtendRight = TRUE;
}
if (m_sVerifyRgn.bottom < lDstHeight)
{
m_sVerifyRgn.bottom++;
m_bExtendBottom = TRUE;
}
if (m_sVerifyRgn.left > 0)
{
m_sVerifyRgn.left--;
m_bExtendLeft = TRUE;
}
if (m_sVerifyRgn.top > 0)
{
m_sVerifyRgn.top--;
m_bExtendTop = TRUE;
}
}
/* Check HW verify surf is being enough */
if ((ULONG)(lDstHeight * ulDstStride) > m_ulDstCopySize)
{
DebugBreak();
DPFERROR((L"CopyDstSurfToHWVerSurf : HwVer dest copy surface not big enough"));
}
/* clip rectangle if overlapping screen boundaries */
if (m_sVerifyRgn.bottom > lDstHeight)
{
m_sVerifyRgn.bottom = lDstHeight;
}
if (m_sVerifyRgn.right > lDstWidth)
{
m_sVerifyRgn.right = lDstWidth;
}
if (m_sVerifyRgn.top < 0)
{
m_sVerifyRgn.top = 0;
}
if (m_sVerifyRgn.left < 0)
{
m_sVerifyRgn.left = 0;
}
/* Now rotate logical to physical region */
if (m_lDestAngle)
{
RotateRegion (&m_sVerifyRgn, m_lDstHeightRotated, m_lDstWidthRotated);
}
/*
Check if the blit has a destination dependance
NOTE if we have more than 1 clip rgn we cannot skip the copy if not dest
dependance as there could be pixels in the dest that the blit does not write to
if the intersection of clip and dest did not produce a well behaved rect
*/
/* Make copy of all the verify regions */
ulCopyOffset = (ULONG)(m_sVerifyRgn.top * ulDstStride) + (ULONG)(m_sVerifyRgn.left * (ulDstBpp / 8));
pbySurfStart = (PBYTE)(m_pbyDstPtr + ulCopyOffset);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -