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 + -
显示快捷键?