Skip to main content

Module budget

Module budget 

Source
Expand description

How many pixels it is safe to keep, and how that number is reached.

The one place a cap lives, and pure arithmetic — every test here takes numbers and touches no file.

§Why a viewer’s rule is the opposite of a thumbnail’s

hyprforge-clipmenu refuses any image over 16 megapixels and shows a text row instead, which is right for a clipboard popup: the picture is a convenience and the popup has other rows to draw. A viewer may not refuse. Showing the photograph is the app, and “that image is too big” is not an answer anyone accepts from the program they opened it with.

So the rule inverts: decode to fit the window, not the file. A 36-megapixel photograph on a 2560x1600 display has no business becoming a 144MB buffer, because the screen cannot show more than four million of those pixels at once. What is retained is bounded by the viewport and stays bounded no matter what the camera produced.

§What this does and does not buy

Honest about its own limits, because a budget that is believed to do more than it does is worse than none:

  • Retained memory is capped. That is the allocation that lives for as long as the picture is on screen, and the one a cache multiplies.
  • Transient memory is not, and cannot be here: image 0.25 exposes no DCT-scaled decode, so a JPEG is decoded whole and then scaled down. The peak is a property of the source, not of this budget.

§The measured numbers

A 36-megapixel JPEG (8001x4501, 2.8MB on disk — a file no larger than an email attachment) shown in a 2560x1600 viewport, measured through /proc/self/status’s VmHWM in a process that had allocated nothing else:

peakretained
decoded and scaled with resize_exact509MB56MB
decoded with no scaling at all252MB137MB
decoded and scaled with thumbnail_exact214MB56MB

Two things in that table were worth the measuring. The scaling step cost more than the decode it followed — resize_exact works through floating-point intermediates, and on a 36-megapixel source those are larger than the picture. And the cheap integer path is not merely cheaper than the expensive one, it is cheaper than not scaling, because it never materialises the full-size RGBA buffer on the way.

decode uses the third row. See its note on why that is not a quality compromise at this ratio.

What is left is a 214MB peak on a machine with any amount of memory, and the lock screen’s lesson is that a peak is not free just because it is brief. Bringing it lower needs a decoder that can scale while decoding, which is a change of dependency rather than of arithmetic.

Structs§

Budget
How much of a picture may be kept in memory at once.
DecodePixels
The size something will be decoded to — always at or under the source, never larger. A viewer showing a 64x64 icon full-screen scales it up when drawing; decoding it big would allocate a buffer full of invented pixels.
ViewportPixels
The size of the area a picture is being shown in, in physical pixels — the buffer’s unit, not the widget tree’s.