Improved screen drawing performance

Thanks largely WouterH, I was able to draw on the screen in RLP world.

While addressing the registers, you can see the screen making the changes. For example in the code below, the screen progressively turn white, instead of all at once.

pixelMap = (unsigned short *)LCD_UPBASE;


int ClearScreen(unsigned int *generalArray, void **args, unsigned int argsCount, unsigned int *argSize)
{	
	int x = 0;
	unsigned short color = 0xFFFF;	
	
	for (x = 0; x < bufferSize; x++)
	{
		pixelMap[x] = color;
	}	
	return 0;
}

So my thought was to create an array and the do a memcpy.


int ClearScreen(unsigned int *generalArray, void **args, unsigned int argsCount, unsigned int *argSize)
{	
	int x = 0;
	unsigned short color = 0xFFFF;	
	unsigned short buffer[320 * 240];
	for (x = 0; x < bufferSize; x++)
	{
		buffer[x] = color;
	}	
        memcpy(buffer, pixelMap);
       
	return 0;
}

It didn’t work, so I tried: memcpy(&buffer, pixelMap);

That didn’t work either.

Is my approach wrong? Or is my implementation off?

Thanks for help

@ mhectorgato - Using memcpy is the right way to go, you just have the arguments wrong.

memcpy(pixelMap, buffer, 320 * 240);

The first argument is the destination, the second the source and the third is the number of bytes to copy.

1 Like

And size is 320 * 240 * sizeof(unsigned short)

Yes thanks WouterH, that will teach me for posting so early in the morning :slight_smile:

1 Like

@ mhectorgato - Don’t expect too much from drawing in RLP. You’ll not be able to update the screen faster than the Bitmap class in managed code, if I remember my tests correct. You will soon figure out once you progress. I’ve once implemented line drawing in RLP and it was slower then drawing a line with the Bitmap class.


Bitmap bmp = new Bitmap(320, 240);
bmp.Clear();
bmp.Flush();

will work faster then the memcpy in RLP, and that is because RLP instructions are loaded from the same SDRAM you’re doing your copy/drawing operations on and the overhead of invoking the RLP function. In addition the compiler GHI uses to compile the firmware generates faster code then GCC.

Depending on what you want to do, but I would keep the drawing in managed code.

Try the speed of this assembler routine against managed code (pass color as ushort to the .InvokeEx call):


 #define LCD_BASE_ADDR        0xFFE10000
 #define LCD_UPBASE           (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x0010))

 #define LCD_PIXELS_X        320
 #define LCD_PIXELS_Y        240
 #define LCD_PIXELS_TOTAL    (LCD_PIXELS_X * LCD_PIXELS_Y)

int LcdClear(unsigned short *generalArray)
{
    unsigned short * p = (unsigned short *)LCD_UPBASE;
    unsigned short color = generalArray[0];
    
    asm volatile (
        "mov    r3, %0"            "\n"    // screenbuffer
        "mov    r2, %2"            "\n"    // total pixels
        "mov    r1, %1"            "\n"    // color
        "CLR:"                    "\n"
        "strh    r1, [r3]"        "\n"    // store color to *screenbuffer
        "add    r3, r3, #2"        "\n"    // increase screenbuffer with 2 bytes (== skip word)
        "subs    r2, r2, #1"        "\n"    // decrease total pixels
        "bne    CLR"            "\n"    // loop until total pixels is zero
        :// no output registers f.e.: "=r"(x) 
        :"r"(p), "r"(color), "r"(LCD_PIXELS_TOTAL)        // input
        :"r1","r2","r3","cc"        // clobbered registers
    );

    return 0;
}

1 Like

Well I posted about the same comment on memcpy as you, but I forgot to press the submit button, go figure :wink:

Also, look at memset.

void * memset ( void * ptr, int value, size_t num );

This will set the whole array to the value to specify…

Thanks for the replies.

Here I thought I was being slick by doing this in RLP … oh well. Good news is that everyone is getting the super optimized version in managed code.

Thanks again!