RFR: 8303904: [macos]Transparent Windows Paint Wrong (Opaque, Pixelated) w/o Volatile Buffering [v6]
Jeremy Wood
jwood at openjdk.org
Thu Jan 22 21:15:58 UTC 2026
> When "swing.volatileImageBufferEnabled" is false: we were mistakenly using an opaque image at 100% resolution.
>
> In hindsight the original ticket probably should be split up into two distinct issues:
> 1. The window is opaque, so pixels that should be transparent are black.
> 2. The window is the wrong resolution. On a 200% resolution monitor it renders as if it were 100% (so it looks pixelated).
>
> This PR started 2 years ago. I got stuck and abandoned it, and @anass-baya picked it back up again this year: https://github.com/openjdk/jdk/pull/23430/
>
> In that PR @mrserb suggested we try to fix this problem in RepaintManager (see https://github.com/openjdk/jdk/pull/23430#discussion_r2089555453 ), so that's what this PR does.
>
> Also this refactors some existing code (the BackingStoreMultiResolutionImage) from JViewport to wrap a BufferedImage in a smaller (transformed) MultiResolutionImage.
Jeremy Wood has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains 34 additional commits since the last revision:
- Merge branch 'master' into JDK-8303904
# Conflicts:
# src/java.desktop/macosx/classes/sun/java2d/metal/MTLGraphicsConfig.java
# src/java.desktop/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java
# src/java.desktop/share/classes/javax/swing/JViewport.java
- 8303904: Updating copyright year
- Merge branch 'master' into JDK-8303904
- Merge branch 'master' into JDK-8303904
- 8303904: comment cleanup
- 8303904: designing around imagined edge cases
I don't know if these will ever come up in the real world, but since this is critical infrastructure I want to be careful. (A Swing app may become unusable if this code fails.)
Concern A:
In the event our AffineTransform is a rotation or a flip:
Now we'll use the c.createImage(virtualWidth, virtualHeight), which means we fall back to the code we've been using for over a decade.
Concern B:
In the event our AffineTransform scales to zero, we'll at least make the image 1x1.
- 8303904: minor cleanup
- 8303904: minor cleanup
- 8303904: minor cleanup
This makes this method ALWAYS return a BackingStoreMultiResolutionImage, even if the scaled size is the same as the virtual size. (Just because making this method return a BufferedImage OR a BackingStoreMultiResolutionImage seems like an unnecessary level of abstraction; and that could turn into a potential point of confusion for future devs.)
- 8303904: use BackingStoreMultiResolutionImage
It's functionally the same thing; this is just reusing code (and it avoids the hacky fake image involving getScaledInstance).
- ... and 24 more: https://git.openjdk.org/jdk/compare/6f19417b...7dace983
-------------
Changes:
- all: https://git.openjdk.org/jdk/pull/13196/files
- new: https://git.openjdk.org/jdk/pull/13196/files/547b121e..7dace983
Webrevs:
- full: https://webrevs.openjdk.org/?repo=jdk&pr=13196&range=05
- incr: https://webrevs.openjdk.org/?repo=jdk&pr=13196&range=04-05
Stats: 149700 lines in 4537 files changed: 85362 ins; 33342 del; 30996 mod
Patch: https://git.openjdk.org/jdk/pull/13196.diff
Fetch: git fetch https://git.openjdk.org/jdk.git pull/13196/head:pull/13196
PR: https://git.openjdk.org/jdk/pull/13196
More information about the client-libs-dev
mailing list