Quickly drawing an Array of pixels on the screen

Hi guys,
i’m writing an essay about sorting algorithms for school. Using SDL I have coded a program, that graphically shows the way an array gets sorted and to do this i programmed a function that represents each element of the array as a pixel on the screen, For example if the first element has the value 20 the program would draw a pixel at coordinates x=1 and y=20.

This is my function:
void drawArray(SDL_Surface *screen, SDL_Surface *temp, int *array, int n)
{
int i;
Uint8 *bufp = NULL;
Uint32 color = SDL_MapRGB(screen->format, 128, 128, 128);

SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));

if(SDL_MUSTLOCK(screen))
{
	if(SDL_LockSurface(screen))
	{
		return;
	}
}

for(i = 0; i < n; i++)
{
	bufp = (Uint8 *)screen->pixels + (array[i] * screen->pitch) + i;
	*bufp = color;
}

if(SDL_MUSTLOCK(screen))
{
	SDL_UnlockSurface(screen);
}

SDL_UpdateRect(screen, 0, 0, 0, 0);

}

It gets called many 1000 times, but its terribly slow…How can I make it faster? I thought about somehow creating a SDL_Surface in RAM and then copying the pixels in there without locking it and then blit that on the screen. Is that possible? Thanks for your help.
T.Keiditsch_________________________________________________________________
Neu: Internet Explorer 7 optimiert f?r MSN!
http://optimize.de.msn.com/default.aspx?mkt=de-de

Hi guys,
i’m writing an essay about sorting algorithms for school. Using SDL
I have coded a program, that graphically shows the way an array gets
sorted and to do this i programmed a function that represents each
element of the array as a pixel on the screen, For example if the
first element has the value 20 the program would draw a pixel at
coordinates x=1 and y=20.

This is my function:
void drawArray(SDL_Surface *screen, SDL_Surface *temp, int *array,
int n)
{
int i;
Uint8 *bufp = NULL;
Uint32 color = SDL_MapRGB(screen->format, 128, 128, 128);

SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));

if(SDL_MUSTLOCK(screen))
{
if(SDL_LockSurface(screen))
{
return;
}
}

for(i = 0; i < n; i++)
{
bufp = (Uint8 *)screen->pixels + (array[i] * screen->pitch) + i;
*bufp = color;
}

if(SDL_MUSTLOCK(screen))
{
SDL_UnlockSurface(screen);
}

SDL_UpdateRect(screen, 0, 0, 0, 0);
}

It gets called many 1000 times, but its terribly slow…How can I
make it faster? I thought about somehow creating a SDL_Surface in
RAM and then copying the pixels in there without locking it and then
blit that on the screen. Is that possible? Thanks for your help.
T.Keiditsch

It’s not exactly correct. You have to take care about endian-issues if
you use less than 32bit.Am 23.01.2008 um 11:20 schrieb Taras Keiditsch:


Albert

But I guess if i fixed the endian issues it wouldnt make the function much faster, would it? I think the lock/unlock functions make it that slow.

Taras----------------------------------------

Date: Wed, 23 Jan 2008 12:12:05 +0200
From: albert.zeyer at rwth-aachen.de
To: sdl at lists.libsdl.org
Subject: Re: [SDL] Quickly drawing an Array of pixels on the screen

Am 23.01.2008 um 11:20 schrieb Taras Keiditsch:

Hi guys,
i’m writing an essay about sorting algorithms for school. Using SDL
I have coded a program, that graphically shows the way an array gets
sorted and to do this i programmed a function that represents each
element of the array as a pixel on the screen, For example if the
first element has the value 20 the program would draw a pixel at
coordinates x=1 and y=20.

This is my function:
void drawArray(SDL_Surface *screen, SDL_Surface *temp, int *array,
int n)
{
int i;
Uint8 *bufp = NULL;
Uint32 color = SDL_MapRGB(screen->format, 128, 128, 128);

SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));

if(SDL_MUSTLOCK(screen))
{
if(SDL_LockSurface(screen))
{
return;
}
}

for(i = 0; i < n; i++)
{
bufp = (Uint8 *)screen->pixels + (array[i] * screen->pitch) + i;
*bufp = color;
}

if(SDL_MUSTLOCK(screen))
{
SDL_UnlockSurface(screen);
}

SDL_UpdateRect(screen, 0, 0, 0, 0);
}

It gets called many 1000 times, but its terribly slow…How can I
make it faster? I thought about somehow creating a SDL_Surface in
RAM and then copying the pixels in there without locking it and then
blit that on the screen. Is that possible? Thanks for your help.
T.Keiditsch

It’s not exactly correct. You have to take care about endian-issues if
you use less than 32bit.


Albert


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Neu: Internet Explorer 7 optimiert f?r MSN!
http://optimize.de.msn.com/default.aspx?mkt=de-de

Hi guys,
i’m writing an essay about sorting algorithms for school. Using SDL
I have coded a program, that graphically shows the way an array gets
sorted and to do this i programmed a function that represents each
element of the array as a pixel on the screen, For example if the
first element has the value 20 the program would draw a pixel at
coordinates x=1 and y=20.

This is my function:
void drawArray(SDL_Surface *screen, SDL_Surface *temp, int *array,
int n)
{
int i;
Uint8 *bufp = NULL;
Uint32 color = SDL_MapRGB(screen->format, 128, 128, 128);

SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));

if(SDL_MUSTLOCK(screen))
{
if(SDL_LockSurface(screen))
{
return;
}
}

for(i = 0; i < n; i++)
{
bufp = (Uint8 *)screen->pixels + (array[i] * screen->pitch) + i;
*bufp = color;
}

if(SDL_MUSTLOCK(screen))
{
SDL_UnlockSurface(screen);
}

SDL_UpdateRect(screen, 0, 0, 0, 0);
}

It gets called many 1000 times, but its terribly slow…How can I
make it faster? I thought about somehow creating a SDL_Surface in
RAM and then copying the pixels in there without locking it and then
blit that on the screen. Is that possible? Thanks for your help.
T.Keiditsch

It’s not exactly correct. You have to take care about endian-issues
if
you use less than 32bit.


Albert

But I guess if i fixed the endian issues it wouldnt make the
function much faster, would it? I think the lock/unlock functions
make it that slow.

Taras

It would make the function probably slower if you don’t do it very
tricky :slight_smile:

There are some things you can improve a bit (the inner loop).

for(i = n+1; --i; )
{
bufp = (Uint8 *)screen->pixels + (array[i] * screen->pitch) + i;
*bufp = color;
}

If you would have it the other way arround (array[i] is x-value, i is
y-value) it also can be done faster:

bufp = (Uint8 *)screen->pixels + n * screen->pitch;
for(i = n+1; --i; )
{
*(bufp + array[i]) = color;
bufp -= screen->pitch;
}

You can also enable some compiler optimisations which can optimise
things like this normally very good.Am 23.01.2008 um 17:12 schrieb Taras Keiditsch:

Date: Wed, 23 Jan 2008 12:12:05 +0200
From: @Albert_Zeyer
To: sdl at lists.libsdl.org
Subject: Re: [SDL] Quickly drawing an Array of pixels on the screen
Am 23.01.2008 um 11:20 schrieb Taras Keiditsch:

I can see two possible bottlenecks in your code.
First, it updates the entire screen, even though only a tiny fraction
of the pixels are changed. On the other hand, if you individually
update the changed pixels, you either get to create a massive array of
SDL_Rect or have the overhead of calling SDL_UpdateRect loads of
times. I’d leave this alone.
Second, your inner loop has a multiply which can’t be pipelined.
As a remedy for the second bottleneck, try swapping the x and the y,
and having a separate counter for the y coordinate. Something like:

for(i = 0, y = 0; i < n; i++, y += screen->pitch)
{
bufp = (Uint8 *)screen->pixels + y + array[i];
*bufp = color;
}
That way you replace the multiply with a couple of relatively cheap adds.
-:sigma.SB

SDL_UpdateRect(screen, 0, 0, 0, 0);
}

It gets called many 1000 times, but its terribly slow…How can I make it faster? I thought about somehow creating a SDL_Surface in RAM and then copying the pixels in there without locking it and then blit that on the screen. Is that possible? Thanks for your help.

Call SDL_UpdateRect only once, when all the drawing is done;
not for each and every pixel.Am Wednesday, dem 23. Jan 2008 schrieb Taras Keiditsch:


AKFoerster

The only pixel format where you have to worry about endian issues is
24-bit. He’s using 8-bit (…or I should hope he is from the code) so
it shouldn’t matter for him.
-:sigma.SBOn Jan 23, 2008 3:12 AM, Albert Zeyer <albert.zeyer at rwth-aachen.de> wrote:

It’s not exactly correct. You have to take care about endian-issues if
you use less than 32bit.