📄 mode.cpp
字号:
/***************************************************************************
* Name : mode.cpp
* Title : MBX WinCE driver GPE class
* Author(s) : Imagination Technologies
* Created : 6th January 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 mode related components of GPE class.
*
* Platform : WinCE
*
* Modifications:-
* $Log: mode.cpp $
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
****************************************************************************/
#include "precomp.h"
#ifdef SUPPORT_CLEARTYPE
#include <ctblt.h>
#endif // SUPPORT_CLEARTYPE
#include <syspal.h> // for 8Bpp we use the natural palette
#include "regpaths.h"
#undef NEG
#undef POS
//#define PROFILE_ROTATION 1
#define FIX_BACKWARDS_BLT 1
// This sub table contains the various mask arrays for the pixel formats we
// support for the primary surface.
static const ULONG ulPixelTableFormats[][4] = {
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, // gpe1Bpp
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, // gpe2Bpp
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, // gpe4Bpp
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, // gpe8Bpp
{ 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, // gpe16Bpp (565)
{ 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, // gpe24Bpp (888)
{ 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, // gpe32Bpp (8888)
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, // gpe16YrCb
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, // gpeDeviceCompatible
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000 } // gpeUndefined
};
const ULONG EGPEFormatToSrcHW[] = { MBX2D_SRC_1_PAL, //gpe1Bpp
MBX2D_SRC_2_PAL, //gpe2Bpp
MBX2D_SRC_4_PAL, //gpe4Bpp
MBX2D_SRC_8_PAL, //gpe8Bpp
MBX2D_SRC_565RGB, //gpe16Bpp
MBX2D_SRC_888RGB, //gpe24Bpp
MBX2D_SRC_8888ARGB, //gpe32Bpp
0, //gpe16YrCb
0, //gpeDeviceCompatible
0 //gpeUndefined
};
const ULONG EGPEFormatToDestHW[] = {0, //gpe1Bpp
0, //gpe2Bpp
0, //gpe4Bpp
MBX2D_DST_332RGB, //gpe8Bpp
MBX2D_DST_565RGB, //gpe16Bpp
MBX2D_DST_888RGB, //gpe24Bpp
MBX2D_DST_8888ARGB, //gpe32Bpp
0, //gpe16YrCb
0, //gpeDeviceCompatible
0 //gpeUndefined
};
SCODE MBX::SetMode (INT nModeId, HPALETTE *hPalette)
{
MBXSurf* pMBXSurf;
DPFX(PVR_ZONE_INIT,(L"MBX::SetMode"));
#ifdef LOCAL_MEMORY_SELF_REFRESH
SysLocalMemoryEnable(m_sDevData.psDevInfoKM);
#endif // LOCAL_MEMORY_SELF_REFRESH
if (nModeId >= m_sEnumerateModesList.wCount)
{
DPFERROR((L"MBX::SetMode Want mode %d, only have mode 0", nModeId));
return (E_INVALIDARG);
}
PrimarySurfaceSetMode(nModeId);
pMBXSurf = (MBXSurf*)m_pPrimarySurface;
#ifdef ROTATE_ENABLE
((GPESurfRotate *)m_pPrimarySurface)->SetRotation(m_nScreenWidth, m_nScreenHeight, m_iRotate);
if (m_iRotate)
{
pMBXSurf->m_bIsRotated = TRUE;
}
// Save the surface rotation.
// This is the only surface that will have rotation applied.
switch (m_iRotate)
{
case DMDO_0:
pMBXSurf->m_lRotationAngle = 0;
break;
case DMDO_90:
pMBXSurf->m_lRotationAngle = 90;
break;
case DMDO_180:
pMBXSurf->m_lRotationAngle = 180;
break;
case DMDO_270:
pMBXSurf->m_lRotationAngle = 270;
break;
}
// Primary rotation in degrees, if it's 0 then no rotation of any surface is ever needed.
m_lPrimaryRotation = pMBXSurf->m_lRotationAngle;
#endif
// Default
m_ulBltRotationHw = MBX2D_TEXTROT_NONE;
if (hPalette)
{
switch (m_ulColorDepth)
{
case 8:
#ifdef SUPPORT_CLEARTYPE
SetClearTypeBltPalette(_rgbIdentity, 256);
#endif
*hPalette = EngCreatePalette (PAL_INDEXED,
PALETTE_SIZE,
(ULONG*)_rgbIdentity,
0,
0,
0);
m_clDisplay.PDP_Palette((PPDP_PALETTE)&_rgbIdentity, 0, 256, FALSE);
break;
case 16:
case 24:
case 32:
#ifdef SUPPORT_CLEARTYPE
SetClearTypeBltMasks(m_ulPixelTableFormats[0],
m_ulPixelTableFormats[1],
m_ulPixelTableFormats[2]);
#endif
*hPalette = EngCreatePalette (PAL_BITFIELDS,
0,
NULL,
m_ulPixelTableFormats[0],
m_ulPixelTableFormats[1],
m_ulPixelTableFormats[2]);
break;
}
}
AllocGAPISurf(m_sModeInfo.format);
#ifdef LOCAL_MEMORY_SELF_REFRESH
SysLocalMemoryDisable(m_sDevData.psDevInfoKM);
#endif // LOCAL_MEMORY_SELF_REFRESH
return (S_OK);
}
/*****************************************************************************
FUNCTION : GetDisplayModeGPEFormat
PURPOSE : Returns the gpe format in the pixel format
associated with the display mode whose number is passed.
This is inline, hence no Enter/Exit calls.
PARAMETERS :
RETURNS :
*****************************************************************************/
EGPEFormat GetDisplayModeGPEFormat (USHORT usBpp)
{
EGPEFormat eFmt = gpeUndefined;
switch(usBpp)
{
case 1:
eFmt = gpe1Bpp;
break;
case 2:
eFmt = gpe2Bpp;
break;
case 4:
eFmt = gpe4Bpp;
break;
case 8:
eFmt = gpe8Bpp;
break;
case 16:
eFmt = gpe16Bpp;
break;
case 24:
eFmt = gpe24Bpp;
break;
case 32:
eFmt = gpe32Bpp;
break;
}
return (eFmt);
}
/*****************************************************************************
FUNCTION : PrimarySurfaceSetMode
PURPOSE : This function handles allocating a primary surface for the given display
mode. It also programs the RAMDAC to use the new primary. This function
is not intended to be reused. Rather, it makes the SetMode function easir
to read.
PARAMETERS :
RETURNS : TRUE = OK, FALSE = Failure
*****************************************************************************/
BOOL MBX::PrimarySurfaceSetMode( INT nModeId )
{
BOOL bRtn = TRUE;
PPDP_EnumTableEntry psModeEntry = &m_sEnumerateModesList.psModeList[nModeId];
m_sModeInfo.format = GetDisplayModeGPEFormat(psModeEntry->byBPP);
m_nScreenWidth = psModeEntry->wXRes;
m_nScreenHeight = psModeEntry->wYRes;
m_ulColorDepth = psModeEntry->byBPP;
m_ulDstHWFormat = EGPEFormatToDestHW[m_sModeInfo.format];
#if defined PROFILE_ROTATION
/***********************************************************************************/
ProfileVidMemBlts();
/***********************************************************************************/
#endif
#ifndef SUPPORT_VIRTUAL_MODES
m_ulPhysicalScreenX = m_nScreenWidth;
m_ulPhysicalScreenY = m_nScreenHeight;
#endif
#ifdef ROTATE_ENABLE
// do rotation if needed
SetRotateParams();
#endif
m_sModeInfo.width = m_nScreenWidth;
m_sModeInfo.height = m_nScreenHeight;
m_sModeInfo.Bpp = m_ulColorDepth;
m_sModeInfo.frequency = psModeEntry->wRefresh;
m_ulScanLineLength = psModeEntry->wStride;
//////////DPFENTER((L"->PrimarySurfaceSetMode"));
DPFINFO((L"----------------------------------------"));
DPFINFO((L"--- DISPLAY MODE : %4d x %4d x %2d ----", m_nScreenWidth, m_nScreenHeight, m_ulColorDepth ));
DPFINFO((L"----------------------------------------"));
// Free up the previous primary surface.
if (m_pPrimarySurface && m_pPrimarySurface->Buffer() != NULL)
{
delete m_pPrimarySurface;
}
#ifndef ROTATE_ENABLE
if(FAILED(AllocSurface(&m_pPrimarySurface, m_nScreenWidth, m_nScreenHeight, m_sModeInfo.format, GPE_REQUIRE_VIDEO_MEMORY)))
#else
if(FAILED(AllocSurface(&m_pPrimarySurface, m_nScreenWidthSave, m_nScreenHeightSave, m_sModeInfo.format, GPE_REQUIRE_VIDEO_MEMORY)))
#endif
{
DPFERROR((L"Couldn't allocate primary surface"));
bRtn = FALSE;
}
else
{
PDP_SETMODE sSetMode;
memcpy(m_ulPixelTableFormats, ulPixelTableFormats[m_sModeInfo.format], sizeof(m_ulPixelTableFormats));
sSetMode.wDisplayX = (WORD) m_ulPhysicalScreenX;
sSetMode.wDisplayY = (WORD) m_ulPhysicalScreenY;
sSetMode.wStride = (WORD) m_ulScanLineLength;
sSetMode.wBitsPerPixel = (WORD) m_sModeInfo.Bpp;
sSetMode.psMemInfo = ((MBXSurf*)m_pPrimarySurface)->GetMemInfo(); /* base of Display surface */
/* Get the physical address of the frame buffer. Note: the frame buffer is not allocated
from the start of the marathon address space in all cases. */
m_pbyFBPhysBase = (PBYTE) sSetMode.psMemInfo->sMemBlk.sSysPhysAddr.uiAddr;
#if FIX_BACKWARDS_BLT
/*
Backwards blt fix :
The first backwards blt goes wrong in early silicon,
so we do a small backwards blt here to flush out the bug.
To test this, with a 640x480 panel and a fixed rotation of 270 degrees,
run the following test kit GDI test : tux -o -d gdiapi -x 207 -r 26314
*/
LONG lTop=2,lLeft=2,lRight=4,lBottom=4;
/* Bug fix :
* Dummy backwards blt */
SlavePortInitWrites();
/* acquire slave port */
PVRSRVAcquireSlavePort(m_sDevData.psDevInfoKM, PVRSRV_SLAVEPORT_2D, IMG_TRUE);
/* -- 2D Dest surface */
SlavePortWrite(0xA0050500);
SlavePortWrite((( sSetMode.psMemInfo->uiDevAddr.uiAddr /* Dest surface address */
>> MBX2D_DST_ADDR_ALIGNSHIFT)
<< MBX2D_DST_ADDR_SHIFT)
& MBX2D_DST_ADDR_MASK );
/* -- 2D Source Surface */
SlavePortWrite(0x94050500); /* Src format and stride */
SlavePortWrite((( sSetMode.psMemInfo->uiDevAddr.uiAddr /* Source address */
>> MBX2D_SRC_ADDR_ALIGNSHIFT)
<< MBX2D_SRC_ADDR_SHIFT)
& MBX2D_SRC_ADDR_MASK );
/* -- Source Offset : Specify the starting pixel coordinate */
SlavePortWrite( MBX2D_SRC_OFF_BH
| (( (lLeft-1) <<MBX2D_SRCOFF_XSTART_SHIFT) & MBX2D_SRCOFF_XSTART_MASK) /* left */
| ((lTop<<MBX2D_SRCOFF_YSTART_SHIFT) & MBX2D_SRCOFF_YSTART_MASK) ); /* top */
/* -- Stretch Control */
SlavePortWrite(0x60800200); /* no stretch */
/* - Clipping */
SlavePortWrite(0x00000001); /* 1 clip rect */
/* Dest clipping rectangle */
SlavePortWrite(
(((SHORT)lRight << MBX2D_CLIP_XMAX_SHIFT) & MBX2D_CLIP_XMAX_MASK) | /* right */
(((SHORT)lLeft << MBX2D_CLIP_XMIN_SHIFT) & MBX2D_CLIP_XMIN_MASK) /* left */
);
SlavePortWrite(
(((SHORT)lTop << MBX2D_CLIP_YMIN_SHIFT) & MBX2D_CLIP_YMIN_MASK) | /* top */
(((SHORT)lBottom << MBX2D_CLIP_YMAX_SHIFT) & MBX2D_CLIP_YMAX_MASK) /* bottom */
);
/* -- 2D Control */
SlavePortWrite(0x20000001); /* old bug fix */
SlavePortWrite(0x00000000);
SlavePortWrite(0x00000000);
/* -- Blit Command */
SlavePortWrite(0x8184CCCC); /* SrcCopy with backwards blt flag */
SlavePortWrite(0x0000FFFF);
/* Dest rectangle */
SlavePortWrite( ((SHORT)lTop & MBX2D_DST_YSTART_MASK) /* top */
| (((SHORT)lLeft << MBX2D_DST_XSTART_SHIFT) /* left */
& MBX2D_DST_XSTART_MASK) );
SlavePortWrite( ((SHORT)lBottom & MBX2D_DST_YEND_MASK) /* bottom */
| (((SHORT)lRight << MBX2D_DST_XEND_SHIFT) /* right */
& MBX2D_DST_XEND_MASK) );
SlavePortFlushWrites();
PVRSRVReleaseSlavePort( m_sDevData.psDevInfoKM, PVRSRV_SLAVEPORT_2D);
#endif /* FIX_BACKWARDS_BLT */
/* clear primary surface */
memset (sSetMode.psMemInfo->pvLinAddr, 0, (sSetMode.wStride * sSetMode.wDisplayY));
m_clDisplay.PDP_SetMode (&sSetMode, FALSE);
#ifdef ROTATE_ENABLE
// notify PDP of rotation
m_clDisplay.PDP_SetCursorRotation(m_iRotate);
// notify surface of rotation
((GPESurfRotate *)m_pPrimarySurface)->SetRotation(m_nScreenWidth, m_nScreenHeight, m_iRotate);
#endif
#if HW_VERIFY
m_clHwVer.EnableHwVerForMode(m_nScreenHeight * m_ulScanLineLength);
#endif /* #ifdef HW_VERIFY */
ULONG ulStripeSize = ((((m_ulPhysicalScreenY * m_ulScanLineLength) >> 3) + 0x0FFF) & 0xFFFFF000);
m_pbyStripeLinBase = (unsigned char *)VideoAlloc(ulStripeSize, sizeof(ULONG), &m_ulStripePhyBase);
m_ulStripeSize = ulStripeSize / NUM_OF_STRIPED_BUFFERS;
/* alloc space for small surfaces */
ULONG ulBufPhys;
SMALLSURFS *psBufLin;
psBufLin = (SMALLSURFS *)VideoAlloc(sizeof(SMALLSURFS), sizeof(ULONG), &ulBufPhys);
if (!psBufLin)
{
DPFERROR((L"small buffers allocation failed"));
bRtn = FALSE;
}
else
{
m_sPaletteInfo.prgbqSrcPalette = (RGBQUAD *)&psBufLin->aSrcPal;
m_sPaletteInfo.ulSrcPalettePhys = ulBufPhys + ((ULONG)m_sPaletteInfo.prgbqSrcPalette - (ULONG)psBufLin);
m_sPaletteInfo.prgbqPatPalette = (RGBQUAD *)&psBufLin->aPatPal;
m_sPaletteInfo.ulPatPalettePhys = ulBufPhys + ((ULONG)m_sPaletteInfo.prgbqPatPalette - (ULONG)psBufLin);
#if HW_VERIFY
m_clHwVer.UpdatePaletteAddr(&m_sPaletteInfo);
#endif
m_pbyPatternFBMem = (BYTE *)&psBufLin->byPatBuf;
m_ulPatternFBMemPhys = ulBufPhys + ((ULONG)m_pbyPatternFBMem - (ULONG)psBufLin);
m_ulPatternBufSize = MAX_PATTERN_BUFFER_SIZE;
m_sCallbacks.sBltComplete.pulLinAddr = &psBufLin->ulBltComplete;
m_sCallbacks.sBltComplete.ulPhysAddr = ulBufPhys + ((ULONG)m_sCallbacks.sBltComplete.pulLinAddr - (ULONG)psBufLin);
m_sCallbacks.sStripeComplete.pulLinAddr = &psBufLin->ulStripeComplete;
m_sCallbacks.sStripeComplete.ulPhysAddr = ulBufPhys + ((ULONG)m_sCallbacks.sStripeComplete.pulLinAddr - (ULONG)psBufLin);
m_sCallbacks.sGAPIComplete.pulLinAddr = &psBufLin->ulGAPIComplete;
m_sCallbacks.sGAPIComplete.ulPhysAddr = ulBufPhys + ((ULONG)m_sCallbacks.sGAPIComplete.pulLinAddr - (ULONG)psBufLin);
*m_sCallbacks.sStripeComplete.pulLinAddr = 0;
*m_sCallbacks.sBltComplete.pulLinAddr = 0;
*m_sCallbacks.sGAPIComplete.pulLinAddr = 0;
m_ulStrideBufSig = 0;
/* alloc space for a mask buffer */
ULONG ulStripeSize = (((m_nScreenWidth * m_nScreenHeight)>>4) & 0xFFFFF000);
m_pulMaskBufLin = (ULONG*)VideoAlloc(ulStripeSize, sizeof (ULONG), &m_ulMaskBufPhys);
m_ulMaskBufferSize = (m_pulMaskBufLin) ? ulStripeSize : 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -