dispdrvr.c
来自「PXA255 WINCE 4.2 BSP ,该BSP是商用的。」· C语言 代码 · 共 1,785 行 · 第 1/4 页
C
1,785 行
dstStartRow = xLeft * DispDrvr_cyScreen;
dstMarginWidth = (DispDrvr_cyScreen-(yBottom-yTop))*bytesPerPixel;
pDstBuf = gFrameBuffer + dstStartRow + (DispDrvr_cyScreen -yBottom)*bytesPerPixel;
dstStep = DispDrvr_cyScreen*bytesPerPixel; //portrait frame buffer step
srcMarginWidth2 = DispDrvr_cxScreen* bytesPerPixel + ((xRight-xLeft)) ;
dstMarginWidth2 = (xRight-xLeft)*dstStep/bytesPerPixel;
}
pSrcBuf = gDibBuffer +srcStartRow +xLeft;
EnterCriticalSection(&displayMutex);
if (bLandscapeDisplay) {
for (row = yTop;row < yBottom;row++) {
i=srcWidthB;
while(i > 0)
{
if (i<4 || ((unsigned)pDstBuf & 0x3) || ((unsigned)pSrcBuf & 0x3))
{
*pDstBuf++ = *pSrcBuf;
pSrcBuf++;
i-=1;
} else
{
*(unsigned *)pDstBuf = *(unsigned *)pSrcBuf;
pDstBuf+=4;
pSrcBuf+=4;
i-=4;
}
}
pSrcBuf += srcMarginWidth;
pDstBuf += dstMarginWidth;
}
} else {
DirtyRectDumpPortraitLoop_C_rectfill(pDstBuf,
srcColor,
yTop,
yBottom,
srcWidthB,
bytesPerRow,
bytesPerPixel,
srcMarginWidth,
dstMarginWidth);
}
// Cursor update request?.
if (gDrawCursorFlag &&
gCursorRect.left*bytesPerPixel < xRight && gCursorRect.right*bytesPerPixel > xLeft &&
(DWORD)gCursorRect.top < yBottom && (DWORD)gCursorRect.bottom > yTop) {
DWORD srcRowMarginB;
DWORD cursorSizeXB;
yTop=gCursorRect.top;
// Clip off cursor if past bottom of screen
yBottom = gCursorRect.bottom > gDibBufferHeight ? gDibBufferHeight : gCursorRect.bottom;
// Now clip off cursor if past right side of screen
clipWidthB=gCursorRect.right > gDibBufferWidth ? gCursorRect.right -gDibBufferWidth : 0;
clipWidthB*=bytesPerPixel;
xLeft=gCursorRect.left*bytesPerPixel;
cursorWidthB=CURSOR_XSIZE*bytesPerPixel;
cursorSizeXB=(gCursorRect.right - gCursorRect.left)*bytesPerPixel;
srcWidthB=cursorSizeXB - clipWidthB;
srcRowMarginB = cursorWidthB - cursorSizeXB;
if (bLandscapeDisplay) {
srcStartRow = 0;
srcMarginWidth = 0;
dstStartRow = yTop * bytesPerRow;
dstMarginWidth = bytesPerRow-srcWidthB;
pDstBuf = gFrameBuffer + dstStartRow + xLeft;
} else {
srcStartRow = (yBottom-yTop-1) * cursorWidthB;
srcMarginWidth = (yBottom-yTop) * cursorWidthB;
dstStartRow = xLeft * DispDrvr_cyScreen;
dstMarginWidth = (DispDrvr_cyScreen-(yBottom-yTop))*bytesPerPixel;
pDstBuf = gFrameBuffer + dstStartRow + (DispDrvr_cyScreen -yBottom)*bytesPerPixel;
}
pSrcBuf =(BYTE *)gCursorData + srcStartRow;
pSrcMask =(BYTE *)gCursorMask + srcStartRow;
if (bLandscapeDisplay) {
for (row=yTop;row<yBottom;row++)
{
i=srcWidthB;
pSrcBuf += srcRowMarginB;
pSrcMask += srcRowMarginB;
while (i > 0)
{
if (i<4 || ((unsigned)pDstBuf & 0x3) || ((unsigned)pSrcBuf & 0x3))
{
*pDstBuf &= *pSrcMask;
*pDstBuf++ ^= *pSrcBuf;
pSrcMask++;
pSrcBuf++;
i-=1;
} else
{
*(unsigned *)pDstBuf &= *(unsigned *)pSrcMask;
*(unsigned *)pDstBuf ^= *(unsigned *)pSrcBuf;
pDstBuf+=4;
pSrcMask+=4;
pSrcBuf+=4;
i-=4;
}
}
pSrcMask += clipWidthB;
pSrcBuf += clipWidthB;
pDstBuf += dstMarginWidth;
}
} else {
pSrcBuf += srcRowMarginB;
pSrcMask += srcRowMarginB;
for (i=0;i<srcWidthB/bytesPerPixel;i++) {
for (row=yTop;row<yBottom;row++) {
for (j=0;j<bytesPerPixel;j++) {
*pDstBuf &= *(pSrcMask+j);
*pDstBuf++ ^= *(pSrcBuf+j);
}
pSrcBuf-=cursorWidthB;
pSrcMask-=cursorWidthB;
}
pSrcBuf +=srcMarginWidth+2;
pSrcMask +=srcMarginWidth+2;
pDstBuf +=dstMarginWidth;
}
}
}
LeaveCriticalSection(&displayMutex);
}
}
void DispDrvrDirtyRectDump2(LPCRECT prc,DWORD color)
{
WORD *pDstBuf;
WORD srcColor = (WORD)color;
DWORD xLeft,yTop,xRight,yBottom;
DWORD srcWidthB,dstMarginWidth;
DWORD dstStartRow;
if (bAllowOSFrameBufferUpdates)
{
xLeft = prc->left < 0 ? 0 : prc->left;
yTop = prc->top < 0 ? 0 : prc->top;
xRight = prc->right > gDibBufferWidth ? gDibBufferWidth : prc->right;
yBottom = prc->bottom > gDibBufferHeight ? gDibBufferHeight : prc->bottom;
if ((LONG)xLeft >= (LONG)xRight || (LONG)yTop >= (LONG)yBottom) return;
srcWidthB = xRight -xLeft;
dstStartRow = xLeft * DispDrvr_cyScreen;
dstMarginWidth = (DispDrvr_cyScreen-(yBottom-yTop));
pDstBuf = (WORD*)gFrameBuffer + dstStartRow + (DispDrvr_cyScreen -yBottom);
EnterCriticalSection(&displayMutex);
ellipse_core_ASM(srcColor, (dstMarginWidth+1)*2,srcWidthB,pDstBuf);
LeaveCriticalSection(&displayMutex);
}
}
void DispDrvrMoveCursor(INT32 xLocation,INT32 yLocation)
{
// First clear the cursor's old location
gDrawCursorFlag = FALSE;
DispDrvrDirtyRectDump(&gCursorRect);
// Now set the new location of the cursor and redraw
gCursorRect.left = xLocation - gxHot;
if (gCursorRect.left < 0) {
gCursorRect.left = 0;
}
gCursorRect.top = yLocation - gyHot;
if (gCursorRect.top < 0) {
gCursorRect.top = 0;
}
gCursorRect.right = xLocation - gxHot + CURSOR_XSIZE;
gCursorRect.bottom = yLocation - gyHot + CURSOR_YSIZE;
gDrawCursorFlag = TRUE;
DispDrvrDirtyRectDump(&gCursorRect);
}
#define VIDEO_REG_PATH TEXT("Drivers\\Display\\Intel")
#define VIDEO_ROW_RES TEXT("CxScreen")
#define VIDEO_COL_RES TEXT("CyScreen")
#define PIXEL_DEPTH TEXT("Bpp")
#define VIDEO_DISPLAY_TYPE TEXT("DisplayType")
#define VIDEO_BUFFER TEXT("UseFrameBuffer")
BOOL ReadRegistryData()
{
LONG regError;
HKEY hKey;
DWORD dwDataSize;
DWORD dwUsePhysicalFrameBuffer;
TCHAR DisplayType[64];
bpp=0;
DispDrvr_cyScreen = 0;
DispDrvr_cxScreen = 0;
dwUsePhysicalFrameBuffer = 0;
// Open the registry key
regError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,VIDEO_REG_PATH,0,KEY_ALL_ACCESS,&hKey);
if (regError != ERROR_SUCCESS) {
DEBUGMSG(DEBUGZONE(0),(VIDEO_REG_PATH));
DEBUGMSG(DEBUGZONE(0),(TEXT("Failed opening \\Drivers\\Display\\Intel\r\n")));
return (FALSE);
}
// Display width
dwDataSize = sizeof(DispDrvr_cxScreen);
regError = RegQueryValueEx(hKey,VIDEO_ROW_RES, NULL, NULL,(LPBYTE)&DispDrvr_cxScreen,&dwDataSize);
if (regError != ERROR_SUCCESS) {
DEBUGMSG(DEBUGZONE(0),(TEXT("Failed to get display x value, Error 0x%X\r\n"),regError));
return (FALSE);
}
// Display height
dwDataSize = sizeof(DispDrvr_cyScreen);
regError = RegQueryValueEx(hKey,VIDEO_COL_RES,NULL,NULL,(LPBYTE)&DispDrvr_cyScreen,&dwDataSize);
if (regError != ERROR_SUCCESS) {
DEBUGMSG(DEBUGZONE(0),(TEXT("Failed to get display y value, Error 0x%X\r\n"),regError));
return (FALSE);
}
// Color depth
dwDataSize = sizeof(bpp);
regError=RegQueryValueEx(hKey,PIXEL_DEPTH,NULL,NULL,(LPBYTE)&bpp,&dwDataSize);
if (regError != ERROR_SUCCESS) {
bpp=0;
}
// Display Type
dwDataSize = sizeof(DisplayType);
regError = RegQueryValueEx(hKey,VIDEO_DISPLAY_TYPE,NULL,NULL,(LPBYTE)DisplayType,&dwDataSize);
if (regError != ERROR_SUCCESS) {
DEBUGMSG(DEBUGZONE(0),(TEXT("Failed to get display type, Error 0x%X\r\n"),regError));
return (FALSE);
}
// Decide whether to use expose the physical frame buffer to GDI, or an off
// screen buffer.
dwDataSize = sizeof(dwUsePhysicalFrameBuffer);
regError = RegQueryValueEx(hKey,VIDEO_BUFFER,NULL,NULL,(LPBYTE)&dwUsePhysicalFrameBuffer,&dwDataSize);
if (regError != ERROR_SUCCESS) {
DEBUGMSG(DEBUGZONE(0),(TEXT("Failed to get display frame buffer value, Error 0x%X\r\n"),regError));
}
RegCloseKey (hKey);
RETAILMSG(1, (TEXT("Done getting Registry values:\r\nbpp: 0x%x\r\n CxScreen: 0x%x\r\n CyScreen: 0x%x\r\nDisplay Type: %s\r\n"), bpp, DispDrvr_cxScreen, DispDrvr_cyScreen,DisplayType));
if (_wcsicmp(DisplayType, TEXT("LTM04C380K")) == 0)
nDisplayType = LTM04C380K;
else if (_wcsicmp(DisplayType, TEXT("LTM04C387S")) == 0)
nDisplayType = LTM04C387S;
else if (_wcsicmp(DisplayType, TEXT("LQ039Q2DS54")) == 0)
nDisplayType = LQ039Q2DS54;
else if (_wcsicmp(DisplayType, TEXT("LM8V31")) == 0)
nDisplayType = LM8V31;
else if (_wcsicmp(DisplayType, TEXT("LM057QCTT03")) == 0)
nDisplayType = LM057QCTT03;
else if (_wcsicmp(DisplayType, TEXT("TFTQVGA")) == 0)
nDisplayType = TFTQVGA;
else if (_wcsicmp(DisplayType, TEXT("LQ64D341")) == 0)
nDisplayType = LQ64D341;
else if (_wcsicmp(DisplayType, TEXT("LQ64D343")) == 0)
nDisplayType = LQ64D343;
else if (_wcsicmp(DisplayType, TEXT("SX14Q001")) == 0)
nDisplayType = SX14Q001;
else
nDisplayType = NONE;
// bLandscapeDisplay is used to indicate whether or not a rotation of the offscreen frame buffer
// is required in order to orient it correctly for the target display.
// TRUE indicates that no rotation is required. FALSE indicates that a rotation is required.
// For native landscape mode displays, the width > height. Rotation is required if the system
// configuration does not match.
// For native portrait mode displays, the width < height. Rotation is required if the system
// configuration does not match.
bLandscapeDisplay = FALSE;
switch (nDisplayType)
{
case LTM04C380K: // fall through
case LTM04C387S: // fall through
case LQ039Q2DS54: // fall through
case LM8V31: // fall through
case LM057QCTT03: // fall through
case TFTQVGA:
case LQ64D343:
case SX14Q001:
if (DispDrvr_cxScreen > DispDrvr_cyScreen)
bLandscapeDisplay = TRUE;
break;
case LQ64D341:
if (DispDrvr_cxScreen < DispDrvr_cyScreen)
bLandscapeDisplay = TRUE;
break;
default:
bLandscapeDisplay = TRUE;
break;
}
// Do not use an off-screen surface if it's possible, and the regkey requests it.
if (bLandscapeDisplay && dwUsePhysicalFrameBuffer == 1)
{
gUseDispDrvrPhysicalFrameBuffer = TRUE;
}
// Calculate the stride of the frame buffer (in DWORDs)
DispDrvr_cdwStride = DispDrvr_cxScreen/4*bpp/8;
return (TRUE);
}
void LCDClearStatusReg()
{
// Clear the status register by writing 1's to each bit.
v_pLcdRegs->LCSR = ( LCD_LDD | LCD_SOF | LCD_BER | LCD_ABC | LCD_IUL |
LCD_IUU | LCD_OU | LCD_QD | LCD_EOF | LCD_BS |
LCD_SINT );
}
void LcdSetupGPIOs()
{
// init display on gpio
v_pGPIORegs->GPCR_z |= GPIO_77;
// Program the GPDR to configure GPIO 58 through 77 as outputs
v_pGPIORegs->GPDR_y |= ( GPIO_58 | GPIO_59 | GPIO_60 | GPIO_61 | GPIO_62 | GPIO_63);
v_pGPIORegs->GPDR_z |= ( GPIO_64 | GPIO_65 | GPIO_66 | GPIO_67 | GPIO_68 |
GPIO_69 | GPIO_70 | GPIO_71 | GPIO_72 | GPIO_73 |
GPIO_74 | GPIO_75 | GPIO_76 | GPIO_77);
// Program the GAFR1_y to select alternate function 2 for GPIO 58 through 63.
v_pGPIORegs->GAFR1_y = (v_pGPIORegs->GAFR1_y & 0x000FFFFF) |
( GPIO_58_AF2_LDD0 | GPIO_59_AF2_LDD1 | GPIO_60_AF2_LDD2 |
GPIO_61_AF2_LDD3 | GPIO_62_AF2_LDD4 | GPIO_63_AF2_LDD5 );
// Program the GAFR1_z to select alternate function 2 for GPIO 64 through 77.
v_pGPIORegs->GAFR0_z = (v_pGPIORegs->GAFR0_z & 0xF0000000) |
( GPIO_64_AF2_LDD6 | GPIO_65_AF2_LDD7 | GPIO_66_AF2_LDD8 |
GPIO_67_AF2_LDD9 | GPIO_68_AF2_LDD10 | GPIO_69_AF2_LDD11 |
GPIO_70_AF2_LDD12 | GPIO_71_AF2_LDD13 | GPIO_72_AF2_LDD14 |
/*GPIO_73_AF2_LDD15 |*/ GPIO_74_AF2_LCD_FCLK | GPIO_75_AF2_LCD_LCLK |
GPIO_76_AF2_LCD_PCLK /*| GPIO_77_AF2_LCD_ACBIAS*/ );
#ifdef PLAT_SANDGATE
// Program the GAFR1_x to configure GPIO 16 as PWM[0] for use with the Sandgate backlight.
v_pGPIORegs->GPCR_x |= GPIO_16;
v_pGPIORegs->GPDR_x |= GPIO_16;
v_pGPIORegs->GAFR1_x |= ( GPIO_16_AF2_PWM0 );
#endif
}
// Display the contents of a given page of video ram.
// This function assumes that the frame buffer has been arranged into one contiguous region.
// If your implementation uses frame buffers that are not contiguous, then you'll have to
// change the implementation of this function to explicitly set/determine
// each frame buffer start address.
void DisplayPageBuffer(int page)
{
if (page < NUM_FRAME_BUFFERS)
{
EnterCriticalSection(&frameDescriptorMutex);
activeFrameBuffer = page;
// Set the physical address of the frame buffer for all three frame descriptors
frameDescriptorCh0fd1->FSADR = LCD_FSADR(FRAME_BUFFER_BASE_PHYSICAL+activeFrameBuffer*frameBufferSize);
frameDescriptorCh0fd2->FSADR = LCD_FSADR(FRAME_BUFFER_BASE_PHYSICAL+activeFrameBuffer*frameBufferSize);
frameDescriptorCh1->FSADR = LCD_FSADR(FRAME_BUFFER_BASE_PHYSICAL+activeFrameBuffer*frameBufferSize+(frameBufferSize/2));
LeaveCriticalSection(&frameDescriptorMutex);
}
}
void ScrollBuffer(int direction)
{
EnterCriticalSection(&frameDescriptorMutex);
// Set the physical address of the frame buffer for all three frame descriptors
if (direction == 1) // scroll up
{
frameDescriptorCh0fd1->FSADR += DispDrvr_cdwStride << 2;
frameDescriptorCh0fd2->FSADR += DispDrvr_cdwStride << 2;
frameDescriptorCh1->FSADR += DispDrvr_cdwStride << 2;
} else // scroll down
{
frameDescriptorCh0fd1->FSADR -= DispDrvr_cdwStride << 2;
frameDescriptorCh0fd2->FSADR -= DispDrvr_cdwStride << 2;
frameDescriptorCh1->FSADR -= DispDrvr_cdwStride << 2;
}
LeaveCriticalSection(&frameDescriptorMutex);
}
// This code must be run in Kernel mode in order to access the page tables.
// Reads the page tables looking for the virtual address of the descriptor that
// maps a given physical address. This virtual address is the virtual address
// of the 1MB section descriptor that maps the supplied physical address.
// NOTE:
// There are two section descriptors that map the frame buffer. The first section descriptor
// maps the cached virtual address of the frame buffer. The second section descriptor
// maps the uncached virtual address of the frame buffer. We want to use the second
// section descriptor, since that maps the uncached virtual address that is typically
// used throughout this code base.
/*
unsigned int GetDescriptorAddress(unsigned int physical_address)
{
unsigned int descriptor, *pPageTableData, x;
int num_matching_descriptors = 0;
descriptor = 0;
pPageTableData = (unsigned int *)0xFFFd0000; // uncached virtual address of TTB
for(x=0;x<0x1000;x++)
{ //
// use loop counter of x1000 (16KB/ 4B/W = 0x1000)
//
descriptor = *pPageTableData;
if( (descriptor & 0xFFF00000) == (physical_address & 0xFFF00000) )
{
NKDbgPrintfW(TEXT("\r\nFound Descriptor: Address= %x\r\n"), pPageTableData);
num_matching_descriptors ++;
if (num_matching_descriptors == 2) // We want the second matching descriptor
break;
}
pPageTableData++;
}
return (unsigned int)pPageTableData;
}
*/
// This code must be run in Kernel mode in order to access the page tables.
// Clear the cache attribute and set the bufferable attribute for the given section descriptor
void ConfigureFrameBufferSectionDescriptor(unsigned int descriptor)
{
unsigned int *pDescriptor;
pDescriptor = (unsigned int *)descriptor;
*pDescriptor &= ~0x8;
*pDescriptor |= 0x4;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?