void (@NotNull Graphics2D g, float x, float y, float width, float height, @NotNull Consumer<? super Graphics2D> painter, @NotNull Object key, Object @NotNull ... parameters) { GraphicsConfiguration config = g.getDeviceConfiguration(); float scale = JBUIScale.sysScale(config); if ((int) scale != scale || config == null) { // fractional-scale setups are not supported currently paintAndDispose((Graphics2D)g.create(), _g -> { _g.setComposite(AlphaComposite.SrcOver); _g.translate(x, y); painter.accept(_g); }); return; } int xInt = (int)Math.floor(x); int yInt = (int)Math.floor(y); int widthInt = (int)Math.ceil(x + width) - xInt; int heightInt = (int)Math.ceil(y + height) - yInt; CachedPainting painting = ourCache.get(key); if (painting != null && !painting.matches(config, width, height, parameters)) { painting = null; } int validationResult = painting == null ? VolatileImage.IMAGE_INCOMPATIBLE : painting.image.validate(config); if (validationResult == VolatileImage.IMAGE_INCOMPATIBLE) { ourCache.put(key, painting = new CachedPainting(config, width, height, widthInt, heightInt, parameters)); } if (validationResult != VolatileImage.IMAGE_OK) { // We cannot perform antialiased rendering onto volatile image using Src composite, so we draw to a buffered image first. BufferedImage bi = new HiDPIImage(config, widthInt, heightInt, BufferedImage.TYPE_INT_ARGB, PaintUtil.RoundingMode.ROUND); paintAndDispose(bi.createGraphics(), _g -> { _g.setComposite(AlphaComposite.Src); _g.translate(x - xInt, y - yInt); painter.accept(_g); }); paintAndDispose(painting.image.createGraphics(), _g -> { _g.setComposite(AlphaComposite.Src); StartupUiUtil.drawImage(_g, bi, 0, 0, null); }); } Composite savedComposite = g.getComposite(); g.setComposite(AlphaComposite.SrcOver); g.drawImage(painting.image, xInt, yInt, null); g.setComposite(savedComposite); // We don't check whether volatile image's content was lost at this point, // because we cannot repeat painting over the initial graphics reliably anyway (without restoring its initial contents first). }