Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Fastest forms of putpixel()/getpixel()

Credits go to kazzmir for helping out!
This thread is locked; no one can reply to it. rss feed Print
Fastest forms of putpixel()/getpixel()
Kikaru
Member #7,616
August 2006
avatar

Ok, just a quick question: What are the fastest possible funcitons that work like putpixel() and getpixel()?

kazzmir
Member #1,786
December 2001
avatar

Kikaru
Member #7,616
August 2006
avatar

I thought there was like a memory_getpixel() function that was faster... Anyone know about that?

Nevermind, nevermind, found it... Well, thanks! :D

HoHo
Member #4,534
April 2004
avatar

direct memory access through the lines[] pointer would is the fastest but you'll have to make sure you won't go out of bitmap bounds.

__________
In theory, there is no difference between theory and practice. But, in practice, there is - Jan L.A. van de Snepscheut
MMORPG's...Many Men Online Role Playing Girls - Radagar
"Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!" - Jakub Wasilewski

Kitty Cat
Member #2,815
October 2002
avatar

lines[] also only works on memory bitmaps. Depending on what you're doing, theo fastest may be:

// Once per line
bmp_write_line bmp_read_line
// Once per pixel
bmp_write8/16/24/32 bmp_read8/16/24/32
// Once when done
bmp_unwrite_line

That will work on any and all valid bitmaps, and for memory bitmaps resolves to little more than direct line[] access. You may have to manually acquire/release the bitmap though.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

HoHo
Member #4,534
April 2004
avatar

If he wants to play directly with pixels then won't there be a severe performance loss unless the bitmap is memory bitmap?

__________
In theory, there is no difference between theory and practice. But, in practice, there is - Jan L.A. van de Snepscheut
MMORPG's...Many Men Online Role Playing Girls - Radagar
"Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!" - Jakub Wasilewski

Milan Mimica
Member #3,877
September 2003
avatar

Quote:

direct memory access through the lines[] pointer would is the fastest but you'll have to make sure you won't go out of bitmap bounds.f

You have to care about that when using _putpixel too. _putpixel is not any faster then using line[] pointer, just cleaner.

HoHo
Member #4,534
April 2004
avatar

I think direct memory access could still have some benefits. E.g you could take the line pointer, saving a bit on pointer calculations (line [X] instead of bmp->line[X]). Also I think using full pixels (int32_t for 32bit) instead of separate RGB channels could give a bit of speed. When getting maximum possible speed very important you could always use MMX/SSE intrinsics for some SIMD action :)

__________
In theory, there is no difference between theory and practice. But, in practice, there is - Jan L.A. van de Snepscheut
MMORPG's...Many Men Online Role Playing Girls - Radagar
"Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!" - Jakub Wasilewski

Dustin Dettmer
Member #3,935
October 2003
avatar

I seem to remember _putpixel* being slower then line[] for some reason. Even if thats not so and forgetting about ASM tricks, you could process multiple pixels at a time via line[].

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

I seem to remember _putpixel* being slower then line[] for some reason.

It is, because it has to lock the bitmap, select the line you're writing to, then write the pixel, then deselect the line, and finally unlock the bitmap. Doing all that yourself to ensure they aren't called more than necessary will be quicker.

Using line is a bit faster, but will only work on memory bitmaps.

Quote:

If he wants to play directly with pixels then won't there be a severe performance loss unless the bitmap is memory bitmap?

Depends. The driver can have it set so you write to system RAM, then will push it all out to the card in one shot when you read/unwrite. In such cases, it won't be much slower as long as you keep read/write switches to a minimal (there'll also be additional gains from having no intermediary bitmap (page flipping or dirty rectangles on the screen), or by having accelerated vram->vram blits).

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Kikaru
Member #7,616
August 2006
avatar

I am not drawing to the screen, and I am already checking to see if it's inside. Should I use direct access? ???

[EDIT]
Is it possible to just access the pixels like this:

bmp->line[y][x] = color;

?

orz
Member #565
August 2000

Kikaru:
If the BITMAP is a memory bitmap, and it's an 8 bit per pixel BITMAP, that's all you need. If it's not an 8 bit per pixel bitmap, it's almost that simple, but you need to add a cast (like: ((short*)(bmp->line[y]))[x] = color; for 15 or 16 bit per pixel modes). Any bitmap created with create_bitmap is a memory bitmap. The screen usually is not a memory bitmap though. However, the screen usually is a linear bitmap, which can be used almost as fast via a slightly different technique.

This is all in the docs, under "Direct access to video memory".

Damian Grove
Member #6,758
January 2006

I can definitely recommend the line[] method. When I began writing my ProSonic game engine, I was still learning about Allegro. I tried many methods of drawing to the screen, but that is by far the fastest way! It did wonders for the performance in my game engine. It is indeed faster than _putpixel.

Get into awesome with Saxman! -- http://www.youtube.com/saxman727

Dustin Dettmer
Member #3,935
October 2003
avatar

((uintN_t*)(bmp->line[y]))[x] = color;where N is the color depth.

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

((uintN_t*)(bmp->line[y]))[x] = color;
where N is the color depth.

That won't work for 24-bit..

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Mr. Big
Member #6,196
September 2005

If I recall correctly, there was an Allegro example, 'exflame.c', which compared three methods of writing pixels.
First using 'getpixel()' and 'putpixel()', which was slow, then using direct memory access, which was faster, then using block memory copy operations, which was by far faster than both.
Perhaps you should check that out?

If you're going to use direct memory access, there's a chapter devoted to it in the manual, called 'Direct access to video memory'. You could also try the following optimizations:

Instead of 'for(x = 0; x < SCREEN_W; x++)' do 'for(x = SCREEN_W; x--; )'.
This will save the processor the need of subtracting 'x' from 'SCREEN_W' every time.

Try unrolling the loops in blocks of 8. (I think every resolution can be divided by 8.)
For a resolution of 800x600, it could save you 472,500 operations of incrementing the counters and testing for loop conditions per frame.

Kikaru
Member #7,616
August 2006
avatar

I read part of the manual, but it tries to give me some functions that are not defined in my version of allegro (4.2) :-/

Do I need to call lock_bitmap() or something before I do that?

Go to: