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

📄 cim_gp.c

📁 LX 800 WindowsCE 6.0 BSP
💻 C
📖 第 1 页 / 共 5 页
字号:

	    if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
		{
			gp3_cmd_next  = gp3_cmd_top;
            	
			GP3_WAIT_WRAP(temp);
			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
				GP3_DATA_LOAD_HDR_ENABLE);
		}
		else
		{
			GP3_WAIT_PRIMITIVE(temp);
			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
		}

        /* WRITE DWORD COUNT */

		WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | (total_dwords * height));

        while (height--)
	    {
		    /* WRITE DATA */

		    WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
		    WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
			    srcoffset + (dword_count << 2), byte_count);

		    srcoffset += pitch;
            cim_cmd_ptr += total_dwords << 2;
	    }

        WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
		gp3_cmd_current = gp3_cmd_next;
    }
    else
    {
	    /* WRITE DATA LINE BY LINE */
	    /* Each line will be created as a separate command buffer entry to allow */
	    /* line-by-line wrapping and to allow simultaneous rendering by the HW.  */
    	
	    while (height--)
	    {
		    /* UPDATE THE COMMAND POINTER */
		    /* The WRITE_COMMANDXX macros use a pointer to the current buffer space. */
		    /* This is created by adding gp3_cmd_current to the base pointer.        */

		    cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;

		    /* CHECK IF A WRAP WILL BE NEEDED */

		    gp3_cmd_next = gp3_cmd_current + size_dwords;
		    if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
		    {
			    gp3_cmd_next  = gp3_cmd_top;
    			
			    /* WAIT FOR HARDWARE */
    			
			    GP3_WAIT_WRAP(temp);
			    WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
				    GP3_DATA_LOAD_HDR_ENABLE);
		    }
		    else
		    {
			    /* WAIT FOR AVAILABLE SPACE */

			    GP3_WAIT_PRIMITIVE(temp);
			    WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
		    }

		    /* WRITE DWORD COUNT */
    		
		    WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | total_dwords);

		    /* WRITE DATA */

		    WRITE_COMMAND_STRING32 (8, data, srcoffset, dword_count);
		    WRITE_COMMAND_STRING8 (8 + (dword_count << 2), data,
			    srcoffset + (dword_count << 2), byte_count);

		    /* UPDATE POINTERS */

		    srcoffset += pitch;
		    WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
		    gp3_cmd_current = gp3_cmd_next;
	    }
    }
}

/*---------------------------------------------------------------------------
 * gp_custom_convert_blt
 *
 * This routine is identical to gp_color_convert_blt, except that the macro
 * to write data to the frame buffer has been replaced with a new macro.  This
 * allows a user to implement custom behavior when sending data, such as manually
 * converting 24BPP to 32BPP, converting 2BPP to 4BPP or premultiplying alpha data.
 *-------------------------------------------------------------------------*/

void gp_custom_convert_blt (unsigned long dstoffset, unsigned long srcx,
    unsigned long width, unsigned long height, unsigned char *data, long pitch)
{
	unsigned long indent, temp;
	unsigned long total_dwords, size_dwords;
	unsigned long dword_count, byte_count;
	unsigned long size = ((width << 16) | height);
	unsigned long ch3_offset, srcoffset;
    unsigned long ch3_size, base;
		
	/* ASSUME BITMAPS ARE DWORD ALIGNED */
	/* We will offset into the source data in DWORD increments.  We  */
	/* set the source index to the remaining byte offset and         */
	/* increment the size of each line to account for the dont-care  */
	/* pixel(s).   For 4BPP source data, we also set the appropriate */
	/* nibble index.                                                 */
	
    /* CALCULATE THE SIZE OF ONE LINE */

    if ((gp3_src_format & GP3_CH3_SRC_MASK) == GP3_CH3_SRC_24BPP_PACKED)
    {
        /* HANDLE 24BPP */
        /* Note that we do not do anything to guarantee that the source data      */
        /* is DWORD aligned.  The logic here is that the source data will be      */
        /* cacheable, in which case Geode LX will not lose any clocks for unaligned */
        /* moves.  Also note that the channel 3 width is programmed as the        */
        /* number of dwords, while the normal width is programmed as the number   */
        /* of pixels.                                                             */

        srcoffset  = srcx * 3;
        ch3_offset = 0;
        temp       = width * 3;
        ch3_size   = (((temp + 3) >> 2) << 16) | height;
    }
    else
    {
        ch3_size = size;

	    if (gp3_src_pix_shift == 3)
	    {
		    /* CALCULATE INDENT AND SOURCE OFFSET */

		    indent     = (srcx >> 1);
		    srcoffset  = (indent & ~3L);
		    indent    &= 3;
		    ch3_offset = indent | ((srcx & 1) << 25);

		    temp = ((width + (srcx & 1) + 1) >> 1) + indent;
	    }
	    else
	    {
		    indent     = (srcx << gp3_src_pix_shift);
		    srcoffset  = (indent & ~3L);
		    indent    &= 3;
		    ch3_offset = indent;

		    temp = (width << gp3_src_pix_shift) + indent;
	    }
    }

	total_dwords = (temp + 3) >> 2;
	size_dwords  = (total_dwords << 2) + 8;
	dword_count  = (temp >> 2);
	byte_count   = (temp & 3);

    base = ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000)) |
           (gp3_base_register & ~GP3_BASE_OFFSET_DSTMASK);

	/* SET APPROPRIATE ENABLES */

	gp3_cmd_header |= GP3_BLT_HDR_DST_OFF_ENABLE     |
					  GP3_BLT_HDR_WIDHI_ENABLE       |
					  GP3_BLT_HDR_CH3_STR_ENABLE     |
					  GP3_BLT_HDR_CH3_OFF_ENABLE     |
					  GP3_BLT_HDR_CH3_WIDHI_ENABLE   |
					  GP3_BLT_HDR_BASE_OFFSET_ENABLE |
					  GP3_BLT_HDR_BLT_MODE_ENABLE;

	WRITE_COMMAND32 (GP3_BLT_DST_OFFSET, (dstoffset & 0x3FFFFF) | gp3_pat_origin);
	WRITE_COMMAND32 (GP3_BLT_CH3_OFFSET, ch3_offset);
	WRITE_COMMAND32 (GP3_BLT_WID_HEIGHT, size);
	WRITE_COMMAND32 (GP3_BLT_CH3_WIDHI, ch3_size);
	WRITE_COMMAND32 (GP3_BLT_BASE_OFFSET, base);
	WRITE_COMMAND32 (GP3_BLT_CH3_MODE_STR,
		GP3_CH3_C3EN           |
		GP3_CH3_REPLACE_SOURCE |
		GP3_CH3_HST_SRC_ENABLE |
		gp3_src_format         |
	  ((gp3_blt_flags & CIMGP_BLTFLAGS_PRES_LUT) << 20));
	WRITE_COMMAND32 (GP3_BLT_MODE, gp3_blt_mode);

	/* START THE BLT */

	WRITE_COMMAND32 (GP3_BLT_CMD_HEADER, gp3_cmd_header);
	WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
	gp3_cmd_current = gp3_cmd_next;

    if (((total_dwords << 2) * height) <= GP3_BLT_1PASS_SIZE &&
        (gp3_cmd_bottom - gp3_cmd_current) > (GP3_BLT_1PASS_SIZE + 72))
    {
        /* UPDATE THE COMMAND POINTER */

		cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;

        /* CHECK IF A WRAP WILL BE NEEDED */

		gp3_cmd_next = gp3_cmd_current + ((total_dwords << 2) * height) + 8;

	    if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
		{
			gp3_cmd_next  = gp3_cmd_top;
            	
			GP3_WAIT_WRAP(temp);
			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
				GP3_DATA_LOAD_HDR_ENABLE);
		}
		else
		{
			GP3_WAIT_PRIMITIVE(temp);
			WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
		}

        /* WRITE DWORD COUNT */

		WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | (total_dwords * height));

        while (height--)
	    {
		    /* WRITE DATA */

		    WRITE_CUSTOM_COMMAND_STRING32 (8, data, srcoffset, dword_count);
		    WRITE_CUSTOM_COMMAND_STRING8 (8 + (dword_count << 2), data,
			    srcoffset + (dword_count << 2), byte_count);

		    srcoffset += pitch;
            cim_cmd_ptr += total_dwords << 2;
	    }

        WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
		gp3_cmd_current = gp3_cmd_next;
    }
    else
    {
	    /* WRITE DATA LINE BY LINE */
	    /* Each line will be created as a separate command buffer entry to allow */
	    /* line-by-line wrapping and to allow simultaneous rendering by the HW.  */
    	
	    while (height--)
	    {
		    /* UPDATE THE COMMAND POINTER */
		    /* The WRITE_COMMANDXX macros use a pointer to the current buffer space. */
		    /* This is created by adding gp3_cmd_current to the base pointer.        */

		    cim_cmd_ptr = cim_cmd_base_ptr + gp3_cmd_current;

		    /* CHECK IF A WRAP WILL BE NEEDED */

		    gp3_cmd_next = gp3_cmd_current + size_dwords;
		    if ((gp3_cmd_bottom - gp3_cmd_next) <= GP3_MAX_COMMAND_SIZE)
		    {
			    gp3_cmd_next  = gp3_cmd_top;
    			
			    /* WAIT FOR HARDWARE */
    			
			    GP3_WAIT_WRAP(temp);
			    WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_WRAP |
				    GP3_DATA_LOAD_HDR_ENABLE);
		    }
		    else
		    {
			    /* WAIT FOR AVAILABLE SPACE */

			    GP3_WAIT_PRIMITIVE(temp);
			    WRITE_COMMAND32 (0, GP3_DATA_LOAD_HDR_TYPE | GP3_DATA_LOAD_HDR_ENABLE);
		    }

		    /* WRITE DWORD COUNT */
    		
		    WRITE_COMMAND32 (4, GP3_CH3_HOST_SOURCE_TYPE | total_dwords);

		    /* WRITE DATA */

		    WRITE_CUSTOM_COMMAND_STRING32 (8, data, srcoffset, dword_count);
		    WRITE_CUSTOM_COMMAND_STRING8 (8 + (dword_count << 2), data,
			    srcoffset + (dword_count << 2), byte_count);

		    /* UPDATE POINTERS */

		    srcoffset += pitch;
		    WRITE_GP32 (GP3_CMD_WRITE, gp3_cmd_next);
		    gp3_cmd_current = gp3_cmd_next;
	    }
    }
}

/*---------------------------------------------------------------------------
 * gp_rotate_blt
 *
 * This routine is called to rotate a rectangular area of video memory.  The
 * data may be color converted during the rotation.  'Degrees' must be a
 * multiple of 90 and indicates a clockwise rotation.  Width and height
 * refer to the width and the height of the source.  The output
 * destinations will be equal to the rotated dimensions.
 *-------------------------------------------------------------------------*/

void gp_rotate_blt (unsigned long dstoffset, unsigned long srcoffset,
	unsigned long width, unsigned long height, int degrees)
{
	unsigned long sizein, sizeout;
	unsigned long ch3_flags;
    unsigned long base;

    base = ((gp3_fb_base << 24) + (dstoffset & 0xFFC00000))         |
	       ((gp3_fb_base << 4)  + ((srcoffset & 0xFFC00000) >> 20)) |
            (gp3_base_register & GP3_BASE_OFFSET_SRCMASK);

    srcoffset &= 0x3FFFFF;
    dstoffset &= 0x3FFFFF;

	/* SET ROTATION PARAMETERS */

	switch (degrees)
	{
		case 90:
			srcoffset += (height - 1) * gp3_src_stride;
			sizein     = ((width  << 16) | height);
			sizeout    = ((height << 16) | width);
			ch3_flags  = GP3_CH3_C3EN           |
				         GP3_CH3_REPLACE_SOURCE |
						 GP3_CH3_ROTATE_ENABLE  |
						 GP3_CH3_NEG_YDIR;	
			break;

		case 180:
			srcoffset += (height - 1) * gp3_src_stride;
			srcoffset += (width << gp3_src_pix_shift) - 1;
			sizein     = sizeout = ((width  << 16) | height);
			ch3_flags  = GP3_CH3_C3EN           |
				         GP3_CH3_REPLACE_SOURCE |
						 GP3_CH3_NEG_YDIR       |
						 GP3_CH3_NEG_XDIR;	
			break;

		case 270:
			srcoffset +=  (width << gp3_src_pix_shift) - 1;
			sizein     = ((width  << 16) | height);
			sizeout    = ((height << 16) | width);
			ch3_flags  = GP3_CH3_C3EN           |
				         GP3_CH3_REPLACE_SOURCE |
						 GP3_CH3_ROTATE_ENABLE  |
						 GP3_CH3_NEG_XDIR;	
			break;

		default:
			sizein     = sizeout = ((width  << 16) | height);
			ch3_flags  = GP3_CH3_C3EN |
				         GP3_CH3_REPLACE_SOURCE;
			break;		
	}

	/* SET APPROPRIATE ENABLES                           */
	/* We override the raster mode setting with a source */
	/* copy ROP.                                         */

	gp3_cmd_header |= GP3_BLT_HDR_RASTER_ENABLE      |
		              GP3_BLT_HDR_DST_OFF_ENABLE     |
		              GP3_BLT_HDR_WIDHI_ENABLE       |
					  GP3_BLT_HDR_CH3_OFF_ENABLE     |
					  GP3_BLT_HDR_CH3_STR_ENABLE     |
					  GP3_BLT_HDR_CH3_WIDHI_ENABLE   |
					  GP3_BLT_HDR_BASE_OFFSET_ENABLE |
					  GP3_BLT_HDR_BLT_MODE_ENABLE;

	/* WRITE ALL BLT

⌨️ 快捷键说明

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