Skip to content

[rtextures] Optimize ImageClearBackground and ImageDrawRectangleRec with doubling strategy - #5363

Merged
raysan5 merged 1 commit into
raysan5:masterfrom
ChocolateChipKookie:optimize-image-clear-background
Nov 19, 2025
Merged

raysan5 merged 1 commit into
raysan5:masterfrom
ChocolateChipKookie:optimize-image-clear-background

Conversation

@ChocolateChipKookie

Copy link
Copy Markdown
Contributor

Background

I use the ImageDraw* functions in a slightly unconventional way, and while doing so I noticed that ImageClearBackground is over an order of magnitude slower than simply calling ImageDrawRectangle over the entire image.

Issue

ImageClearBackground calls memcpy once per pixel and doesn’t take advantage of the fact that memcpy is very fast when copying large contiguous blocks of memory. As a result, it incurs the overhead of a function call for every pixel.

Fix

Instead of copying one pixel at a time, we can iteratively copy the data that has already been written to the image buffer, effectively doubling the amount of initialized data with each iteration. This reduces the number of memcpy calls from O(N) to O(log N).

I applied the same optimization to ImageDrawRectangleRec. The improvement there is smaller because only the first row is written pixel-by-pixel.

Result

15-20 times faster execution times on my PC.

Before change:
Image Size: 1024x1024 (1048576 pixels)
--------------------------------------------------------------------------------
  GRAYSCALE                     :  3.615 ms/call,      276.65 MB/s
  GRAY_ALPHA                    :  3.323 ms/call,      601.83 MB/s
  R5G6B5                        :  3.323 ms/call,      601.79 MB/s
  R8G8B8                        :  3.335 ms/call,      899.66 MB/s
  R5G5B5A1                      :  3.324 ms/call,      601.67 MB/s
  R4G4B4A4                      :  3.324 ms/call,      601.67 MB/s
  R8G8B8A8                      :  3.646 ms/call,     1097.08 MB/s
  R32                           :  3.646 ms/call,     1097.15 MB/s
  R32G32B32                     :  3.395 ms/call,     3535.04 MB/s
  R32G32B32A32                  :  3.403 ms/call,     4701.50 MB/s
  R16                           :  3.318 ms/call,      602.84 MB/s
  R16G16B16                     :  3.661 ms/call,     1638.94 MB/s
  R16G16B16A16                  :  3.355 ms/call,     2384.82 MB/s

After change:
Image Size: 1024x1024 (1048576 pixels)
--------------------------------------------------------------------------------
  GRAYSCALE                     :  0.038 ms/call,    26481.94 MB/s
  GRAY_ALPHA                    :  0.074 ms/call,    26984.73 MB/s
  R5G6B5                        :  0.075 ms/call,    26812.89 MB/s
  R8G8B8                        :  0.126 ms/call,    23838.65 MB/s
  R5G5B5A1                      :  0.074 ms/call,    26926.22 MB/s
  R4G4B4A4                      :  0.074 ms/call,    26945.42 MB/s
  R8G8B8A8                      :  0.172 ms/call,    23277.30 MB/s
  R32                           :  0.172 ms/call,    23304.70 MB/s
  R32G32B32                     :  0.492 ms/call,    24401.23 MB/s
  R32G32B32A32                  :  0.715 ms/call,    22390.98 MB/s
  R16                           :  0.074 ms/call,    27102.76 MB/s
  R16G16B16                     :  0.255 ms/call,    23522.38 MB/s
  R16G16B16A16                  :  0.338 ms/call,    23692.66 MB/s

@ChocolateChipKookie ChocolateChipKookie changed the title feat: Optimize ImageClearBackground and ImageDrawRectangleRec with doubling strategy [rtextures] Optimize ImageClearBackground and ImageDrawRectangleRec with doubling strategy Nov 18, 2025
@raysan5
raysan5 merged commit e2233ac into raysan5:master Nov 19, 2025
@raysan5

raysan5 commented Nov 19, 2025

Copy link
Copy Markdown
Owner

@ChocolateChipKookie Nice improvement! Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants