josm
josm copied to clipboard
#20366 Use `VolatileImage` for back-buffers to allow hardware-accelerated rendering
Summary
This partially fixes Ticket #20366 wherein rendering is abysmally slow, especially on HiDPI systems. Current behavior uses a double-buffer strategy with BufferedImages, forcing virtually all rendering into software loops.[^1] The bespoke HiDPI buffer scaling with AffineTransforms compounds this performance degradation.[^2] Performance seems to suffer exponentially with each additional layer regardless of its data; imagery tile layers seem to contribute the most.[^3]
I’ve switched the buffers to VolatileImages, so the renderer can now defer to hardware routines where possible. This also defers HiDPI-scaling to the hardware surface, eliminating the need for the existing software one. The performance improvement is most obvious when running JOSM with a hardware-accelerated pipeline and
- panning an non-trivial OSM data layer with labels disabled;
- panning an arbitrary number of enabled imagery layers;
- working with area fill enabled; or
- working at high zoom levels.
This cannot convert some inherently software-based render operations like
Graphics2Dcanvas/text anti-aliasing;GlyphVector-based text rendering; and- alpha compositing (and whatever else I couldn’t find).
These ought to be refactored to take advantage of the equivalent hardware routines, if possible. If not, then the user should have finer control over these (e.g., rendering hints).
Miscellanea
This also fixes a couple of performance regressions:
MapViewwas marked as a transparent component; and- hovering over an OSM primitive would immediately invalidate the layer, even if inactive
[^1]: See Oracle docs.
[^2]: Incidentally, this is probably why the recommendation to run with -Dsun.java2d.uiScale=1 was a suggested solution, since the resulting AffineTransform would’ve been the identity matrix.
[^3]: Stacking imagery layers very quickly destroys the frame rate.