RFR: JDK-8303950: [macos]Translucent Windows Flicker on Repaint
Jeremy Wood
mickleness at gmail.com
Wed Jun 7 18:58:26 UTC 2023
Alan,
No, I’m not currently set up to test OpenJDK PR’s on other platforms.
I’m fuzzy on exactly what happens automatically in an OpenJDK PR. Are my
new unit tests automatically run on a variety of platforms? (That is:
are my new unit tests part of what executes here
<https://github.com/mickleness/jdk/actions/runs/5197802507/jobs/9386648003>?
Or does that skip several UI-based unit tests?)
I do have a Windows machine, but IIRC setting up OpenJDK to build on my
Mac was difficult, and I don’t want to go through that again on Windows
unless I really have to.
- Jeremy
------ Original Message ------
>From "Alan Snyder" <javalists at cbfiddle.com>
To "Jeremy" <duke at openjdk.org>
Cc client-libs-dev at openjdk.org
Date 6/7/23, 2:06:23 PM
Subject Re: RFR: JDK-8303950: [macos]Translucent Windows Flicker on
Repaint
>Are you able to test on platforms other than macOS? (I’m not, so I can’t help with that.)
>
> Alan
>
>
>
>> On Jun 7, 2023, at 10:53 AM, Jeremy <duke at openjdk.org> wrote:
>>
>> # Problem Summary
>>
>> For non-opaque windows, Window#paint calls `gg.fillRect(0, 0, getWidth(), getHeight())` before `super.paint(g)`.
>>
>> This can cause flickering on Mac, and the flickering seems to have gotten much worse in recent JVMs. (See movie attachments to original ticket.)
>>
>> # Discussion
>>
>> This is my 2nd PR for this ticket. The original is [here](https://github.com/openjdk/jdk/pull/12993); that proposed change was IMO more invasive/scarier. It was auto-closed after 8 weeks of inactivity, and I'd rather offer this PR instead.
>>
>> In that previous discussion Alan Snyder framed the core problem as a "lack of synchronization" (see [comment here](https://github.com/openjdk/jdk/pull/12993#issuecomment-1467528061)). If the monitor refreshes/flushes after we've called `fillRect` *but before we finish `super.paint`*: it makes sense that we'd see a flicker.
>>
>> I agree with Alan, but I think the problem can also be framed as a mixing-Swing-with-AWT issue. (Which IMO will involve an easier fix.)
>>
>> This PR is a low-risk change (relative to the previous PR) that intercepts calls to repaint a Window that is also RootPaneContainer. Now we'll redirect those calls to paint the JRootPane instead. This means we'll exclusively paint within Swing's/RepaintManager's double-buffered architecture, so we bypass the risky call to `fillRect` on the screen's Graphics2D. (And this change occurs within RepaintManager, so we're clearly already in Swing's architecture.)
>>
>> So with this change: we paint everything to the double-buffer, and the *only time* we paint to the Window's Graphics2D is when have set up a AlphaComposite.Src and replace its contents with our buffer's contents.
>>
>> # Tests
>>
>> This PR includes a new test for 8303950 itself. This is pretty self-explanatory: we repaint a trivial animation for a few seconds and use the Robot to see if a pixel is the expected color.
>>
>> This PR also includes a test called `bug8303950_legacyWindowPaintBehavior` that creates a grid of 4 windows with varying opacity/backgrounds:
>>
>> <img width="805" alt="image" src="https://github.com/openjdk/jdk/assets/7669569/497c21a0-ed18-413f-a5c7-3ea146644fd6">
>>
>> I was surprised by how these windows rendered, but I don't think that's worth debating here. This test simply makes sure that we preserve this preexisting behavior. The broad "rules" appear to be:
>> 1. If a JComponent identifies as opaque (see `JComponent.isOpaque`) then the JComponent's background is used. (In this case: that's the opaque green top two windows.) This is probably coming from `ComponentUI.update`
>> 2. If a JRootPane has a translucent background, that color "wins". It doesn't composite on top of a window's translucent background: it simply *replaces* it. (See the blue-ish bottom-right window. Note it's blue -- not purple.) This is probably because the RepaintManager uses `AlphaComposite.Src` in a couple of places to replace its destination Graphics.
>> 3. If a JRootPane has a null background color, then the Window's background color paints as expected. (See the red-ish bottom-left window.)
>>
>> -------------
>>
>> Commit messages:
>> - 8303950: working on occasional unit failures
>> - 8303950: avoid System.exit(1)
>> - 8303950: adding opaque white window under test windows
>> - 8303950: this resolves bug8303950 by adding special RootPaneContainer behavior
>> - 8303950: adding unit test for legacy window behavior
>> - 8303950: fixing false negative
>> - 8303950: adding failing test to identify problem
>> - Merge pull request #4 from openjdk/master
>> - Merge pull request #3 from openjdk/master
>> - Merge pull request #2 from openjdk/master
>> - ... and 1 more: https://git.openjdk.org/jdk/compare/98a7a60f...37834391
>>
>> Changes: https://git.openjdk.org/jdk/pull/14363/files
>> Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=14363&range=00
>> Issue: https://bugs.openjdk.org/browse/JDK-8303950
>> Stats: 409 lines in 3 files changed: 407 ins; 1 del; 1 mod
>> Patch: https://git.openjdk.org/jdk/pull/14363.diff
>> Fetch: git fetch https://git.openjdk.org/jdk.git pull/14363/head:pull/14363
>>
>> PR: https://git.openjdk.org/jdk/pull/14363
>>
>
More information about the client-libs-dev
mailing list