Back to News

Fog Panther v0.3.4 — Memory and Rendering Performance

March 12, 2026

Fog Panther v0.3.4 ships a set of internal optimizations that
dramatically reduce memory consumption and improve rendering
performance, particularly for large documents and long editing sessions.


Compressed Undo History

-----------------------

The undo system now stores tile snapshots as zstd-compressed data
instead of full uncompressed copies. Every brush stroke, fill, or
filter application that previously stored raw 16 KB tile buffers now
compresses them at capture time using zstd level 1, which runs at
roughly 500 MB/s.

The result: 3x to 10x less memory per undo step, depending on tile
content. The fixed 256 MB undo budget that previously held around 80
significant brush strokes now effectively holds 250 to 800. Undo and
redo remain instantaneous — decompressing a tile takes approximately
11 microseconds.

The on-disk FOG format already used zstd compression, so saved files
are unchanged. Only the in-memory representation is affected.


Display Surface Caching

-----------------------

Non-RGBA8 pixel formats — RGBA16, CMYKA, Grayscale — require a format
conversion to produce the Cairo ARGB32 surface used for screen display.
Previously, this conversion ran on every visible tile on every frame.

Tiles now cache their display surface after the first conversion. The
cache is invalidated automatically whenever the tile data changes. For
a 16-bit document with 200 visible tiles, this eliminates 200 format
conversions per frame during panning and zooming.


Proactive Tile Cache Trimming

-----------------------------

The tile cache previously waited until it exceeded its memory limit
before evicting entries, causing brief memory overshoot. It now begins
trimming at 90% capacity and trims down to 85%, creating a hysteresis
band that prevents repeated eviction on the next insert.


Checkerboard Pattern Caching

-----------------------------

The transparency checkerboard pattern — drawn behind every document on
every frame — was previously created and destroyed each render pass.
It is now created once and reused for the lifetime of the process.


Bug Fixes

---------

This release also includes several correctness fixes discovered during
review of the optimization work:

- Display cache is now properly invalidated by all pixel-writing
  functions, not only the raw data accessor
- History serialization no longer writes a malformed flag byte sequence
  when a compressed tile decompresses to void
- Redo of erasure operations now correctly restores void tiles
- Tile cache memory accounting is now correct when replacing a cached
  tile with one of a different pixel format
- Checkerboard pattern initialization is now thread-safe