RFR: JDK-8303950: [macos]Translucent Windows Flicker on Repaint [v3]
Jeremy
duke at openjdk.org
Mon Jul 17 03:43:17 UTC 2023
On Fri, 16 Jun 2023 23:16:53 GMT, 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. (I...
>
> Jeremy has updated the pull request incrementally with one additional commit since the last revision:
>
> 8303950: removing unnecessary whitespace in unit test
>
> See https://github.com/openjdk/jdk/pull/14363#pullrequestreview-1484315506
@aivanov-jdk IIRC this ticket (a P3) was initially assigned to you, and I asked to look at it instead. It looks like for now this PR is stalled, so please feel free to reassign the openJDK ticket (or make any other appropriate changes) if needed.
-------------
PR Comment: https://git.openjdk.org/jdk/pull/14363#issuecomment-1637330958
More information about the client-libs-dev
mailing list