RFR: JDK-8303950: [macos]Translucent Windows Flicker on Repaint

Philip Race philip.race at oracle.com
Wed Jun 7 19:02:30 UTC 2023


if you are thinking of github actions exactly ZERO client tests are run. 
The testing is all on you.

-phil.

On 6/7/23 11:58 AM, Jeremy Wood wrote:
> 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