You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There has already been one attempt to improve it by making an 'unsafe' version that doesn't do clip checking.
This does not go far enough. This function is used all over draw.c inside of while loops that draw lines containing hundreds of pixels, and shapes that may contain many lines.
For each pixel of these lines we are checking what the bit depth of the surface is. That could be a thousand checks per polygon for a large polygon - but we only need one check.
I propose, unless set_at() is being called directly by a user to change literally a single pixel, we instead make all our tests for surface bit depth (and ideally shape clipping) happen outside of any per pixel while loops and inside of them we call very specific functions that just set the pixel.
e.g.
// This 'safe' version assumes we have determined the surface bit depth but does clipping per pixel,// ideally we could clip our draw shapes at a higher levelstaticintset_at_32bit_safe(Uint8*pixels, intpitch, intx, inty, Uint32color, SDL_Rectclip_rect)
{
if (x<clip_rect.x||x >= clip_rect.x+clip_rect.w||y<clip_rect.y||y >= clip_rect.y+clip_rect.h)
return0;
*((Uint32*)(pixels+y*pitch) +x) =color;
return1;
}
//This 'unsafe' version just sets a 32bit surface pixel to a colour and assumes safe postions (i.e. inside the surface)//and that we have already determined the needed pixel tpye before callingstaticvoidset_at_32bit_unsafe(Uint8*pixels, intpitch, intx, inty, Uint32color)
{
*((Uint32*)(pixels+y*pitch) +x) =color;
}
In all cases we should also prioritise the 32 bit path - the current set_at() has an 8bit surface depth as the first case, before testing for a 16 bit surface, then a 24bit one before finally testing for a 32bit. These switch cases should be in surface commonality order which is 32bit (4byte) then 24bit (3byte), then 8bit (1byte) and finally the rarely seen 16bit (2 byte) surface.
To Do list:
Identify all the places where set_at() is eventually used inside of a pixel loop. For a refactorings list.
Create simple pixel setter functions like the 32bit onese above for all the normal bit depth surfaces (32bit, 24bit, 16bit, 8bit).
copy the surface depth switch case that currently sits inside set_at() to sit outside each of the pixel loops (or higher) so we only test the surface bit depth once per user call to draw.
use the new simple pixel setter functions inside the pixel loops now separated cleanly by bit depth.
make sure the tests still pass.
check the performance versus current main branch across however many draw functions this problem affects.
can any of this be macro'd up to reduce repetition?
The text was updated successfully, but these errors were encountered:
Currently the function
set_at()
in draw.c looks like this:There has already been one attempt to improve it by making an 'unsafe' version that doesn't do clip checking.
This does not go far enough. This function is used all over draw.c inside of while loops that draw lines containing hundreds of pixels, and shapes that may contain many lines.
For each pixel of these lines we are checking what the bit depth of the surface is. That could be a thousand checks per polygon for a large polygon - but we only need one check.
I propose, unless
set_at()
is being called directly by a user to change literally a single pixel, we instead make all our tests for surface bit depth (and ideally shape clipping) happen outside of any per pixel while loops and inside of them we call very specific functions that just set the pixel.e.g.
In all cases we should also prioritise the 32 bit path - the current set_at() has an 8bit surface depth as the first case, before testing for a 16 bit surface, then a 24bit one before finally testing for a 32bit. These switch cases should be in surface commonality order which is 32bit (4byte) then 24bit (3byte), then 8bit (1byte) and finally the rarely seen 16bit (2 byte) surface.
To Do list:
The text was updated successfully, but these errors were encountered: