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

📄 blt.cpp

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 CPP
📖 第 1 页 / 共 5 页
字号:

	//I think this way I could Speed up than having a if condition in a loop - SAS
	if(Display_BPP == 8){
		for (i = 0; i < height; i++)
		{
			// COPY CURRENT POINTER TO A DWORD POINTER

			dataptr = lineptr;
			spadAddr = BB0_Base_Address;

			// COPY ALL THE DATA FOR THE CURRENT LINE INTO THE SCRATCHPAD
			// Must wait for the pipeline to be idle before loading the 
			// new data into the BLT buffer.
			
			WAIT_PIPELINE(GXregisters);

			//Convert the data from 1,2,4,8, 24 to 8
			// CHECK SOURCE COLOR DEPTH
			switch(srcDepth)
			{
				case 1:
					DataConversion1_2_8(dataptr, sXOffset, width, lookup, spadAddr);
					break;
				case 2:
					DataConversion2_2_8(dataptr, sXOffset, width, lookup, spadAddr);
					break;
				case 4:
					DataConversion4_2_8(dataptr, sXOffset, width, lookup, spadAddr);
					break;
				case 24:
					DataConversion24_2_8(dataptr, width, pBltParms->pConvert, clrConverter, spadAddr);
					break;
				case 8:
				default: //* 8 bit depth
					DataConversion8_2_8(dataptr, width, lookup, spadAddr);
					break;
			}

			WRITE_REG16(GXregisters, GP_BLIT_MODE, blit_mode);

			// ADJUST SOURCE OFFSET FOR NEXT SCANLINE
			lineptr += stride;
		}
	} else { //Depth == 16
		for (i = 0; i < height; i++)
		{
			// COPY CURRENT POINTER TO A DWORD POINTER

			dataptr = lineptr;
			spadAddr = BB0_Base_Address;

			// COPY ALL THE DATA FOR THE CURRENT LINE INTO THE SCRATCHPAD
			// Must wait for the pipeline to be idle before loading the 
			// new data into the BLT buffer.
			
			WAIT_PIPELINE(GXregisters);

			//Convert the data from 1,2,4,8, 24 to 16

			switch(srcDepth)
			{
				case 1:
					DataConversion1_2_16(dataptr, sXOffset, width, lookup, spadAddr);
					break;
				case 2:
					DataConversion2_2_16(dataptr, sXOffset, width, lookup, spadAddr);
					break;
				case 4:
					DataConversion4_2_16(dataptr, sXOffset, width, lookup, spadAddr);
					break;
				case 24:
					DataConversion24_2_16(dataptr, width, pBltParms->pConvert, clrConverter, spadAddr);
					break;
				case 8:
				default: //* 8 bit depth
					DataConversion8_2_16(dataptr, width, lookup, spadAddr);
					break;
			}

			WRITE_REG16(GXregisters, GP_BLIT_MODE, blit_mode);

			// ADJUST SOURCE OFFSET FOR NEXT SCANLINE
			lineptr += stride;
		}
	}
	
	return S_OK;
}


//----------------------------------------------------------------------------
// AcceleratedMaskCopyBlt
//
// This routine is called to perform a screen to screen BLT when a mask is 
// involved.
//
// This routine is does not really implement the 0xCCAA raster operation 
// corrrectly.  It emulates a mask BLT by performing and AND/OR combination.
// It first uses the mask to AND the destination location, then uses a 
// source to destination BLT with OR.   
//
//----------------------------------------------------------------------------

SCODE GxVideo::AcceleratedMaskCopyBlt( GPEBltParms *pBltParms )
{
	DEBUGMSG(0,(TEXT("AcceleratedMaskCopyBlt\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, maskX, maskY;
	int mstride,sstride;
	unsigned long spadAddr, i, j, width, height, width_bytes, bytes;
	unsigned char *dataptr, *maskptr, *srcptr;
	EGPEFormat format;

	// GET RECTANGLE PARAMETERS

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

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

	//-----------------------//
	//  FIRST DO "AND" MASK  //
	//-----------------------//

	srcptr = (unsigned char *) pBltParms->pSrc->Buffer();
	sstride = pBltParms->pSrc->Stride();
	format = pBltParms->pSrc->Format();

	mstride = pBltParms->pMask->Stride();
	maskX = pBltParms->prclMask->left;
	maskY = pBltParms->prclMask->top;
	width_bytes = (width + (maskX & 7) + 7) >> 3;
	maskptr = (unsigned char *) pBltParms->pMask->Buffer();
	maskptr += (maskY * mstride) + (maskX >> 3);

	DEBUGMSG(0,(TEXT("%d %d %d %d, %d %d, %d %d,%X %X, %d %d, %x\n"), 
		x1, y1, x2, y2, width, height, sstride, mstride,maskX, maskY, 
		Display_BPP,format, maskptr));

	//Get a valid data pointer
	//ASSERT(lineptr !=0);

	//First do an AND on Destination and black the area of the actual bitmap area.
	//This step is independent of the depth

	// SET PARAMETERS FOR ALL SCANLINES

	WAIT_PENDING(GXregisters);
	WRITE_REG16(GXregisters, GP_SRC_XCOOR, maskX & 7);
	WRITE_REG16(GXregisters, GP_DST_XCOOR, x1);
	WRITE_REG16(GXregisters, GP_DST_YCOOR, y1);
	WRITE_REG16(GXregisters, GP_WIDTH, width);
	WRITE_REG16(GXregisters, GP_HEIGHT, 1);
	WRITE_REG16(GXregisters, GP_RASTER_MODE, 0x0088);              
	WRITE_REG32(GXregisters, GP_SRC_COLOR_0, 0xFFFF0000);

	// REPEAT FOR EACH SCANLINE

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

		dataptr = maskptr;
		spadAddr = BB0_Base_Address;

		// COPY ALL THE DATA FOR THE CURRENT LINE INTO THE SCRATCHPAD
		// Must wait for the pipeline to be idle before loading the 
		// new data into the BLT buffer. 

		WAIT_BUSY(GXregisters);
		bytes = width_bytes;

		// LOAD COMPLETE DWORDS

		while (bytes > 4)
		{
			// WRITE DATA TO THE SCRATCHPAD
			// The register selector actually points to the beginning
			// of the scratchpad (the registers start at offset 0x8000).

			WRITE_REG32(GXregisters, spadAddr, *((unsigned long *) dataptr));
			dataptr += 4;
			spadAddr += 4;
			bytes -= 4;
		}

		// LOAD REMAINING BYTES
		for (i = 0; i < bytes; i++)
		{
			// WRITE DATA TO THE SCRATCHPAD
			// The register selector actually points to the beginning
			// of the scratchpad (the registers start at offset 0x8000).

			WRITE_REG8(GXregisters, spadAddr, *dataptr);
			dataptr++;
			spadAddr++;
		}
		// ADJUST SOURCE OFFSET FOR NEXT SCANLINE

		maskptr += mstride;
		WRITE_REG16(GXregisters, GP_BLIT_MODE, BM_READ_SRC_BB0 | BM_READ_DST_FB1 | BM_SOURCE_EXPAND);

	}

	//Now strip the area other than the mask in the source 
	//i.e the bitmap data and the mask combine to form a negative of the first pass
	//Now OR it with destination

	maskptr = (unsigned char *) pBltParms->pMask->Buffer();
	maskptr += (maskY * mstride) + (maskX >> 3);

	WAIT_PENDING(GXregisters);
	WRITE_REG16(GXregisters, GP_DST_XCOOR, x1);
	WRITE_REG16(GXregisters, GP_DST_YCOOR, y1);
	WRITE_REG16(GXregisters, GP_WIDTH, width);
	WRITE_REG16(GXregisters, GP_HEIGHT, 1);
	WRITE_REG16(GXregisters, GP_RASTER_MODE, 0xEE);

	if(Display_BPP == 8)
	{
		unsigned char *srctmp;

		srcX = pBltParms->prclSrc->left;// left of source rect
		srcY = pBltParms->prclSrc->top ;// top of source rect
		srcptr += (srcY * sstride) + srcX; //position to the correct buffer location

		DEBUGMSG(0,(TEXT("src 8 %d %d %x\n"), srcX, srcY, srcptr));
		
		for (j = 0; j < height; j++)
		{
			int mX = maskX & 7;

			// COPY CURRENT POINTER TO A DWORD POINTER
			dataptr = maskptr;
			srctmp = srcptr;
			spadAddr = BB0_Base_Address;

			// COPY ALL THE DATA FOR THE CURRENT LINE INTO THE SCRATCHPAD
			// Must wait for the pipeline to be idle before loading the 
			// new data into the BLT buffer. 

			WAIT_BUSY(GXregisters);
			for (i = 0; i < width; )
			{
				if(mX == 0){
					if(*dataptr == 0xFF){
						dataptr ++;
						mX = 0;
						WRITE_REG32(GXregisters, spadAddr, 0x0); //fill with black
						spadAddr += 4;
						WRITE_REG32(GXregisters, spadAddr, 0x0); //fill with black
						spadAddr += 4;
						srctmp += 8;

						i += 8; //increment counter
						continue;
					}
					if(*dataptr == 0x00){
						dataptr ++;
						mX = 0;
						WRITE_REG32(GXregisters, spadAddr, *((unsigned long *)srctmp));
						spadAddr += 4;
						srctmp += 4;//increment the source location
						WRITE_REG32(GXregisters, spadAddr, *((unsigned long *)srctmp));
						spadAddr += 4;
						srctmp += 4;//increment the source location

						i += 8; //increment counter
						continue;
					}
				}

				if(*dataptr & bit_mask[mX]){
					WRITE_REG8(GXregisters, spadAddr, 0x0); //fill with black
				} else {
					WRITE_REG8(GXregisters, spadAddr, *srctmp);
				}

				mX++; //increment the mask location

				if(mX == 8){
					dataptr ++;
					mX=0; //roll over
				}

				spadAddr++;
				srctmp++; //increment the source location
				i++; //increment counter
			}
			// ADJUST SOURCE OFFSET FOR NEXT SCANLINE

			maskptr += mstride;
			srcptr += sstride;

			WRITE_REG16(GXregisters, GP_BLIT_MODE, BM_READ_SRC_BB0 | BM_READ_DST_FB1);
		}

	} else { //Display is assumed to be in 16 bit mode, the only posibility

		unsigned short *srctmp;

		srcX = pBltParms->prclSrc->left;// left of source rect
		srcY = pBltParms->prclSrc->top ;// top of source rect
		srcptr += (srcY * sstride) + (srcX << 1); //position to the correct buffer location

		DEBUGMSG(0,(TEXT("src 16 %d %d %x\n"), srcX, srcY, srcptr));
		
		for (j = 0; j < height; j++)
		{
			int mX = maskX & 7;

			// COPY CURRENT POINTER TO A DWORD POINTER
			dataptr = maskptr;
			srctmp = (unsigned short *)srcptr;
			spadAddr = BB0_Base_Address;

			// COPY ALL THE DATA FOR THE CURRENT LINE INTO THE SCRATCHPAD
			// Must wait for the pipeline to be idle before loading the 
			// new data into the BLT buffer. 

			WAIT_BUSY(GXregisters);
			for (i = 0; i < width; i++)
			{
				if(mX == 0){
					int k;
					if(*dataptr == 0xFF){
						dataptr ++;
						mX = 0;
						for(k=0;k<4;k++){
							WRITE_REG32(GXregisters, spadAddr, 0x0); //fill with black
							spadAddr += 4;
						}
						srctmp += 8;//increment the source location

						i += 8; //increment counter
						continue;
					}
					if(*dataptr == 0x00){
						dataptr ++;
						mX = 0;
						for(k=0;k<4;k++){
							WRITE_REG32(GXregisters, spadAddr, *((unsigned long *)srctmp));
							spadAddr += 4;
							srctmp += 2;//increment the source location
						}

						i += 8; //increment counter
						continue;
					}
				}
				if(*dataptr & bit_mask[mX]){
					WRITE_REG16(GXregisters, spadAddr, 0x0); //fill with black
				} else {
					WRITE_REG16(GXregisters, spadAddr, *srctmp);
				}

				mX++; //increment the mask location

				if(mX == 8){ //Mask is 8 bit 
					dataptr ++;
					mX=0; //roll over
				}

				spadAddr += 2;
				srctmp++; //increment the source location
			}
			// ADJUST SOURCE OFFSET FOR NEXT SCANLINE

			maskptr += mstride;
			srcptr += sstride;

			WRITE_REG16(GXregisters, GP_BLIT_MODE, BM_READ_SRC_BB0 | BM_READ_DST_FB1);
		}
	}

	return S_OK;
}

//----------------------------------------------------------------------------
// AcceleratedPatternFill
//
//----------------------------------------------------------------------------

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

	GxVideoSurf *dst = (GxVideoSurf *)(pBltParms->pDst);
	int left = dst->Left();
	int top = dst->Top();
	int x1 = pBltParms->prclDst->left   + lef

⌨️ 快捷键说明

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