 |
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
Kenneth_Smith
Joined: 18 May 2012 Posts: 853 Location: Lanarkshire, Scotland.
|
Posted: Thu Oct 02, 2025 2:29 pm Post subject: Fastest way to colour pixels in a %pl? |
|
|
In the program below, a heat map is plotted by colouring pixels within the �PLOT_ADJUST� section of a %pl call back.
This task is performed using to nested loops to work across/down the pixel space.
When the program is run a %ls box appears on the RHS of the graphic. This allows you to change whether the individual pixels are coloured using a call to DRAW_POINT@(ix,iy,iz) or DRAW_FILLED_RECTANGLE@(ix,iy,ix,iy,iz)
Intuitively I would expect a call to DRAW_POINT@ to be faster than DRAW_FILLED_RECTANGLE@(ix,iy,ix,iy,iz) to set the colour of an individual pixel at ix, iy, to colour iz (as there are fewer arguments to process).
However, as this example demonstrates (on my machines), the nested do loops that call DRAW_FILLED_RECTANGLE@ execute 3 to 4 times faster than those with calls to DRAW_POINT@. Apart from these alternative draw calls, the nested do loops are identical.
I am unable to explain this significant difference. Can anybody can shed some light on this? I�m at a loss with this one.
https://www.dropbox.com/scl/fi/elkhsu5jxjmxeqsyu0fru/ex35_drawpoint_or_filledrect.f95?rlkey=ninbyykqqvar6dtc6zlqu0fiq&st=k9xdyi55&dl=0 |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8277 Location: Salford, UK
|
Posted: Thu Oct 02, 2025 3:12 pm Post subject: |
|
|
I have a vague recollection that draw_point@ can be extremely slow. I don't remember if it related specifically to the use of smoothing.
The primitive function called without smoothing is SetPixel.
The primitive functions called for smoothing are GdipBitmapSetPixel and GdipDrawImageRectI.
So a rectangle is used anyway for GDI+ and this could mean that a "set pixel" function was not available or did not work.
See https://learn.microsoft.com/en-us/windows/win32/gdiplus/-gdiplus-graphics-flat. |
|
Back to top |
|
 |
Kenneth_Smith
Joined: 18 May 2012 Posts: 853 Location: Lanarkshire, Scotland.
|
Posted: Thu Oct 02, 2025 7:35 pm Post subject: |
|
|
Paul,
Thanks, that is very useful.
Your recollection is entirely consistent with what I have observed both without and with smoothing.
I will use draw_filled_rectangle@ instead of draw_pixel@ from now on.
According to AI:
When you call draw_point@ in ClearWin+ (which wraps Windows SetPixel), each pixel goes through a full GDI pipeline individually:
1. GDI checks the device context (DC) for clipping, mapping modes, and transformations.
2. GDI validates the coordinates to make sure they are inside the drawable region.
3. GDI computes the actual memory location of the pixel in the framebuffer or bitmap.
4. The pixel value is written, sometimes with extra synchronization to ensure the graphics engine sees it immediately.
5. Windows may flush the pipeline to the display (or schedule a refresh).
All of these steps are repeated for every single pixel, which is why SetPixel is notoriously slow � even for just one pixel, a lot of overhead happens.
On the other hand, when you call draw_filled_rectangle@ (even for a rectangle of size 1�1):
1. ClearWin+ translates it into a GDI fill command (like FillRect or Rectangle).
2. The GDI fill routines are highly optimised: they can batch memory writes, skip redundant calculations, and often operate directly on internal framebuffer buffers.
3. The Windows graphics engine has special �fast paths� for rectangle fills, even for tiny rectangles. This means the memory and clipping calculations are done efficiently in one go rather than per pixel.
4. Finally, the GDI engine can push the block to the screen efficiently, rather than flushing per pixel.
So the irony is that drawing a �tiny box� with draw_filled_rectangle@ triggers the optimized batch path, while draw_point@ forces a slow, per-pixel pipeline traversal.
draw_point@ = slow path, per-pixel, unbatched, lots of overhead.
draw_filled_rectangle@ = fast path, batch-optimized, even if the rectangle is just one pixel.
This explains why, counterintuitively, plotting a single �pixel rectangle� can be faster than plotting a single point.
|
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8277 Location: Salford, UK
|
Posted: Fri Oct 03, 2025 8:20 am Post subject: |
|
|
Ken
There may be some mileage in using %gr[user_surface].
I don't understand how the AI engine has managed to compose it's response to your question. I suppose it's a bit like what you read in newspapers. It relates something approximating to the truth - sometimes quite accurately, sometimes not. In this case I am both impressed and perplexed. |
|
Back to top |
|
 |
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2423 Location: Yateley, Hants, UK
|
Posted: Fri Oct 03, 2025 3:26 pm Post subject: |
|
|
Fascinating. Does draw_filled_polygon@ work faster than pixel by pixel? |
|
Back to top |
|
 |
DanRRight
Joined: 10 Mar 2008 Posts: 2943 Location: South Pole, Antarctica
|
Posted: Fri Oct 03, 2025 10:17 pm Post subject: |
|
|
and how about DRAW_LINE_between@(ix1,iy1,ix2,iy2,icolor) formerly DRAW_LINE@ ? |
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|