⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blt.cpp

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// This routine is called to perform a solid rectangle fill when destination
// data is involved (DSTINVERT, PATINVERT, etc).  Since no source data is 
// involved, use BB0 to store the DST data and let it spill into BB1.  This
// means we never have to check the width of the rectangle to avoid 
// overflowing the BLT buffers. 
//----------------------------------------------------------------------------

SCODE GxVideo::AcceleratedFillRectDst( GPEBltParms *pBltParms )
{
	DEBUGMSG(0,(TEXT("AcceleratedFillRectDst\n")));

	GxVideoSurf *dst = (GxVideoSurf *)(pBltParms->pDst);
	int left = dst->Left();
	int top = dst->Top();
	int x1 = pBltParms->prclDst->left   + left;
	int y1 = pBltParms->prclDst->top    + top;
	int x2 = pBltParms->prclDst->right  + left;
	int y2 = pBltParms->prclDst->bottom + top;

	unsigned long width = x2 - x1;
	unsigned long height = y2 - y1;

#ifdef DURANGO
	unsigned short color;
	color = (unsigned short)GetBltSolidColor(pBltParms);
	gfx_set_solid_pattern(color);
	gfx_set_raster_operation((unsigned char) pBltParms->rop4);
	gfx_pattern_fill(x1,y1,x2 - x1,y2 - y1);
#else
	// Caller assures a well-ordered, non-empty rect
	//ASSERT(width > 0 && height > 0);

	// SETUP RECTANGLE PARAMETERS
	// Must wait until there is not a primitive pending before writing to
	// the registers.

	WAIT_PENDING(GXregisters);
	WRITE_REG32(GXregisters, GP_DST_XCOOR, (y1 << 16) | x1);
	WRITE_REG16(GXregisters, GP_RASTER_MODE, (unsigned short) pBltParms->rop4 & 0x00FF);
	WRITE_REG32(GXregisters, GP_WIDTH, (height << 16) | width);
	WRITE_REG16(GXregisters, GP_BLIT_MODE, BM_READ_DST_FB0);
#endif 
	return S_OK;
}

//----------------------------------------------------------------------------
// AcceleratedSrcCopyBlt
//
// This routine is called to perform a screen to screen BLT.  It should only
// be called when the raster operaion is SRCCOPY, meaning that destination 
// data is not required.  It should not be called for a transparent BLT.
//----------------------------------------------------------------------------

SCODE GxVideo::AcceleratedSrcCopyBlt( GPEBltParms *pBltParms )
{
	DEBUGMSG(0,(TEXT("AcceleratedSrcCopyBlt\n")));

	GxVideoSurf *dst = (GxVideoSurf *)(pBltParms->pDst);
	GxVideoSurf *src = (GxVideoSurf *)(pBltParms->pSrc);
	int srcX = pBltParms->prclSrc->left   + src->Left(); // left of source rect
	int srcY = pBltParms->prclSrc->top    + src->Top();  // top of source rect
	int dstX = pBltParms->prclDst->left   + dst->Left(); // left of dest rect
	int dstY = pBltParms->prclDst->top    + dst->Top();  // top of dest rect
	unsigned long width =	pBltParms->prclDst->right  - pBltParms->prclDst->left;
	unsigned long height = pBltParms->prclDst->bottom - pBltParms->prclDst->top;
	unsigned short blit_mode = BM_READ_SRC_FB;

#ifdef DURANGO
		gfx_set_solid_pattern(0);
		gfx_set_raster_operation((unsigned char) pBltParms->rop4);
	if (pBltParms->bltFlags & BLT_TRANSPARENT) {
		unsigned short xcolor = (unsigned short) pBltParms->solidColor;

		if (Display_BPP == 8) 
		{
			xcolor &= 0x00FF;
			xcolor |= (xcolor << 8);
		} else 
			xcolor = (unsigned short)GetBltSolidColor(pBltParms);

		gfx_screen_to_screen_xblt((unsigned short) srcX, (unsigned short)srcY, 
			(unsigned short)dstX, (unsigned short)dstY, 
			(unsigned short)width, (unsigned short)height, xcolor);
	} else {
		gfx_screen_to_screen_blt((unsigned short) srcX, (unsigned short)srcY, 
			(unsigned short)dstX, (unsigned short)dstY, 
			(unsigned short)width, (unsigned short)height);
	}

#else  //hrhr
	DEBUGMSG(0,(TEXT("%d %d, %d %d, %d %d, %d %d , %d %d\n"),
		srcX,srcY,dstX,dstY,width,height, src->Left(), src->Top(), 
		pBltParms->prclSrc->left, pBltParms->prclSrc->top));

	// Caller assures a well-ordered, non-empty rect
	//ASSERT(width > 0 && height > 0);

	// CHECK IF NEGATIVE Y DIRECTION
	// For GX, an entire scanline is read into the BLT buffer, so the X 
	// direction is not a consideration.

	if(!pBltParms->yPositive )
	{
		srcY += ( height - 1 );
		dstY += ( height - 1 );
		blit_mode |= BM_REVERSE_Y;
	}

	// PERFORM SCREEN TO SCREEN BLT

	WAIT_PENDING(GXregisters);
	WRITE_REG32(GXregisters, GP_SRC_XCOOR, (srcY << 16) | srcX);
	WRITE_REG32(GXregisters, GP_DST_XCOOR, (dstY << 16) | dstX);
	WRITE_REG32(GXregisters, GP_WIDTH, (height << 16) | width);
	WRITE_REG16(GXregisters, GP_RASTER_MODE, (unsigned short) pBltParms->rop4 & 0x00FF);
	WRITE_REG16(GXregisters, GP_BLIT_MODE, blit_mode);
#endif
	return S_OK;
}

#define memInit()	\
	unsigned long Cnt=0, *dataLptr=0;\
	unsigned char *dataCptr=0;

// Expects memInit() called before we come here.
#define memCopy(dataPtr, destAddr, wordsLen, bytesLen)			\
{																\
	dataCptr = dataPtr; /* init */								\
																\
	WAIT_PIPELINE(GXregisters);									\
	/*Write the count words*/									\
	if((wordsLen)) {											\
		dataLptr = (unsigned long *)(dataPtr);					\
		for (Cnt = 0; Cnt < (wordsLen); Cnt++)					\
		{														\
			WRITE_REG32(GXregisters, (destAddr), dataLptr[Cnt]);\
																\
			(destAddr) += 4;									\
		}														\
		dataCptr = (unsigned char *)&dataLptr[Cnt];				\
	}															\
																\
	/* Now Write the count bytes left */						\
	if((bytesLen)) {											\
		for (Cnt = 0; Cnt < (bytesLen); Cnt++)					\
		{														\
			WRITE_REG8(GXregisters, (destAddr), dataCptr[Cnt]);	\
																\
			(destAddr)++;										\
		}														\
	}															\
}

//----------------------------------------------------------------------------
// AcceleratedTextBlt
//
// This routine is called when accelerating a text character.  A raster
// opreration of 0xAAF0 is used, meaning a pattern fill with a mask.  
//
// For MXi, the MONOCHROME_BITMAP request should be used.
//----------------------------------------------------------------------------

SCODE GxVideo::AcceleratedTextBlt( GPEBltParms *pBltParms )
{
	DEBUGMSG(0,(TEXT("AcceleratedTextBlt\n")));

	GxVideoSurf *dst = (GxVideoSurf *)(pBltParms->pDst);
	int left = dst->Left();
	int top = dst->Top();
	int x1 = pBltParms->prclDst->left   + left;
	int y1 = pBltParms->prclDst->top    + top;
	int x2 = pBltParms->prclDst->right  + left;
	int y2 = pBltParms->prclDst->bottom + top;
	int srcX, srcY;
	unsigned long i, bytes, width, height, width_bytes, widthWBytes;
	int stride;
	unsigned short color, spadAddr;
	unsigned char *glyphptr;
	unsigned char *dataptr;

	// GET CHARACTER PARAMETERS
	DEBUGMSG(0,(TEXT("%d %d %d %d, %d %d %d %d\n"),
			pBltParms->prclDst->left,
			pBltParms->prclDst->top,
			pBltParms->prclDst->right,
			pBltParms->prclDst->bottom,
			pBltParms->prclMask->left,
			pBltParms->prclMask->top,
			pBltParms->prclMask->right,
			pBltParms->prclMask->bottom));

	width = x2 - x1;
	height = y2 - y1;

	// Caller assures a well-ordered, non-empty rect
	//ASSERT(width > 0 && height > 0);

	stride = pBltParms->pMask->Stride();
	srcX = pBltParms->prclMask->left;
	srcY = pBltParms->prclMask->top;
	width_bytes = (width + (srcX & 0x7) + 7) >> 3;
	widthWBytes = width_bytes >> 2;
	bytes = width_bytes * height;
	glyphptr = (unsigned char *) pBltParms->pMask->Buffer();

	//Looking for a valid data pointer
	//ASSERT(glyphptr != 0);

	glyphptr += (srcY * stride) + (srcX >> 3);

	DEBUGMSG(0,(TEXT("%d %d %d %d\n"), srcX, srcY, width_bytes, bytes));

			// DETERMINE TEXT COLOR
	// For GX, an 8 BPP color must be duplicated into the upper byte.

	color = (unsigned short) pBltParms->solidColor;

	if (Display_BPP == 8) 
	{
		color &= 0x00FF;
		color |= (color << 8);
	} else 
		color = (unsigned short)GetBltSolidColor(pBltParms);

	DEBUGMSG(0,(TEXT("color = %X\n"), color));

	DEBUGMSG(0,(TEXT("Read BB0=0x%X BB1=0x%X, set 0x%X, 0x%X\n"),
		execute_cpu_read(GX_BB0_BASE), execute_cpu_read(GX_BB1_BASE), 
		BB0_Base_Address, BB1_Base_Address));

#ifdef DURANGO
	spadAddr = 0;		// - for compile
	dataptr = glyphptr;	// - for compile
	i=0;				// - for compile

	RETAILMSG(0,(TEXT("Read BB0=0x%X BB1=0x%X, set 0x%X, 0x%X\n"),
		execute_cpu_read(GX_BB0_BASE), execute_cpu_read(GX_BB1_BASE), 
		BB0_Base_Address, BB1_Base_Address));

	RETAILMSG( 0, ( TEXT(" Durango Text Blt \n") ) );
	color = (unsigned short) pBltParms->solidColor;

	glyphptr = (unsigned char *) pBltParms->pMask->Buffer();

	unsigned short bgcolor = 0xff;
	gfx_set_solid_pattern(0);
	gfx_set_mono_source(bgcolor,color,1);
	gfx_set_raster_operation(0xcc);

	gfx_mono_bitmap_to_screen_blt(srcX,srcY,x1,y1,x2 - x1,y2 - y1,glyphptr,stride);

#else

	WAIT_PENDING(GXregisters);
	// SET PARAMETERS THAT DO NOT CHANGE PER LINE
	WRITE_REG32(GXregisters, GP_SRC_XCOOR, srcX & 7);	
	WRITE_REG32(GXregisters, GP_DST_XCOOR, (y1 << 16) | x1);
	WRITE_REG16(GXregisters, GP_RASTER_MODE, RM_SRC_TRANSPARENT | RM_SRC_COPY);
	WRITE_REG16(GXregisters, GP_SRC_COLOR_1, color);

	//Do the Memory Init for the copy to follow
	memInit();


	// CHECK IF BLT CAN FIT WITHIN BLT BUFFERS
	// Since destination data is not being used, we can use BB1 as well
	// as BB0 (BB1 immediately follows BB0).  Therefore, the check to see 
	// if the data will fit is based on twice the size of BB0.
	
	if (bytes <= (unsigned long)(BB0_Size_Bytes << 1))
	{
		// LOAD MONOCHROME DATA INTO THE BLT BUFFER
		// We must wait for the graphics engine to be idle before loading 
		// the data since it may still be working on data from a previous
		// BLT.  If performance becomes a strong issue (using WAIT_BUSY 
		// here hits performance), it is possible to rewrite this code to
		// toggle between using BB0 and BB1 for the character data.  If
		// that were done, then WAIT_PENDING would be sufficient.

		spadAddr = BB0_Base_Address;

		width_bytes &= 0x3;

		for (i = 0; i < height; i++)
		{
			// COPY CURRENT POINTER TO A CHAR POINTER

			memCopy(glyphptr,  spadAddr, widthWBytes, width_bytes);

			// ADJUST SOURCE OFFSET FOR NEXT SCANLINE

			glyphptr += stride;
		}

		// RENDER THE ENTIRE CHARACTER AT ONCE

		WRITE_REG32(GXregisters, GP_WIDTH, (height << 16) | width);
		WRITE_REG16(GXregisters, GP_BLIT_MODE, BM_SOURCE_TEXT | BM_READ_SRC_BB0);
	}
	else
	{

		unsigned short BufAddr[2] = {BB0_Base_Address, BB1_Base_Address}; // Buffer address being used
		unsigned short BufMask[2] = {BM_READ_SRC_BB0, BM_READ_SRC_BB1}; // Buffer Mask to be used
		int BufNo = 0; // Buffer # 

		// RENDER THE CHARACTER A SCANLINE AT A TIME
		// This is done if the amount of data for the entire character is 
		// too large to fit within the BLT buffer.
		
		WRITE_REG32(GXregisters, GP_WIDTH, 0x10000 | width);

		// REPEAT FOR EACH SCANLINE

		width_bytes &= 0x3;
		for (i = 0; i < height; i++)
		{
			// COPY CURRENT POINTER TO A CHAR POINTER

			dataptr = glyphptr;
			spadAddr = BufAddr[BufNo];

			// COPY ALL THE DATA FOR THE CURRENT LINE INTO THE SCRATCHPAD

			memCopy(dataptr,  spadAddr, widthWBytes, width_bytes);
			// RENDER THE SCANLINE
			// Need to use BM_SOURCE_EXPAND instead of BM_SOURCE_TEXT so
			// that the X value remains the same and the Y value is 
			// incremented by one after each BLT.
			WRITE_REG16(GXregisters, GP_BLIT_MODE, BM_SOURCE_EXPAND | BufMask[BufNo]);

			// Toggle the buffer to be used after each buffer write
			ToggleMode(BufNo);

			// ADJUST SOURCE OFFSET FOR NEXT SCANLINE

			glyphptr += stride;
		}
	}
#endif
	return S_OK;
}

//----------------------------------------------------------------------------
// AcceleratedBitmapScreenBlt
//
// This routine is called to perform a bitmap to screen BLT. 
//
// For GX, the source data is loaded into BB0 and the graphics pipeline 
// reads the destination data, if required, into BB1. 
//
// POSSIBLE OPTIMIZATIONS:
//   - Check to see if the bitmap is small enough to fit entirely in the 
//     BLT buffer.
//   - Change the data load routine to use DWORDS.
//----------------------------------------------------------------------------

SCODE GxVideo::AcceleratedBitmapScreenBlt( GPEBltParms *pBltParms )
{
	DEBUGMSG(0,(TEXT("AcceleratedBitmapScreenBlt\n")));

	GxVideoSurf *dst = (GxVideoSurf *)(pBltParms->pDst);
	int left = dst->Left();
	int top = dst->Top();
	int x1 = pBltParms->prclDst->left   + left;
	int y1 = pBltParms->prclDst->top    + top;
	int x2 = pBltParms->prclDst->right  + left;
	int y2 = pBltParms->prclDst->bottom + top;
	int srcX, srcY;
	unsigned long spadAddr, i, width, height, width_bytes; 
	int stride;
	unsigned char *dataptr, *lineptr;
	unsigned short blit_mode=0;

	// GET BLT PARAMETERS

	width = x2 - x1;
    height = y2 - y1;

	// Caller assures a well-ordered, non-empty rect
	//ASSERT(width > 0 && height > 0);

	stride = pBltParms->pSrc->Stride();
	srcX = pBltParms->prclSrc->left;
	srcY = pBltParms->prclSrc->top;
	lineptr = (unsigned char *) pBltParms->pSrc->Buffer();

	DEBUGMSG(0,(TEXT("%d %d %d %d %d %d %d %d %d %d %d\n"), 
		x1, y1, x2, y2, width, height, stride, srcX, srcY, 
		Display_BPP,pBltParms->pSrc->Format()));

#ifdef DURANGO
	spadAddr = 0;		//- for compile
	dataptr = lineptr;	// - for compile
	i=0;				// - for compile
	width_bytes = 0;	//- for compile

	unsigned short color0, color1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -