New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JDK-8303950: [macos]Translucent Windows Flicker on Repaint #14363
Conversation
Merge openjdk/jdk into mickleness/jdk
Merge openjdk/jdk
Merge from openjdk/jdk
Updating mickleness/jdk from openjdk/jdk
Apparently calling System.exit(0) was coming across as a failing condition. So instead I'll just let the app exit on its own. Also small formatting/typo tweaks.
This test passes in the current JDK. The test criteria don't really reflect a rational expected behavior; they just reflect the current status quo.
… behavior One way of framing bug8303950 is: that problem had to do with mixing non-Swing and Swing components. This adds special behavior for RootPaneContainers to address this issue. With this approach the results of bug8303950_legacyWindowPaintBehavior are unchanged.
Since the bottom two windows are translucent: it will help safeguard test results if they're positioned above an opaque white background. Also adding a couple of text lines to the windows to help explain why they rendered the way they did.
mrserb recommended against this in a separate PR openjdk#13408 (comment)
The resolution is working, but the unit test itself isn't always synchronizing well. I'm trying to avoid baking in a permanent timer (for ex: waiting 2 seconds to let the UI load), but if I see more intermittent failures I may resort to that yet.
toBack() moves the Window behind *everything*. If it moved windows only behind other windows in the Swing app that would be great, but that's not what it does.
👋 Welcome back mickleness! A progress list of the required criteria for merging this PR into |
@mickleness The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
Webrevs
|
I haven't yet looked at this properly but I'm mightily relieved to see that previous patch gone since We'll need to test this and since it sounds like you don't have much in the way of testing resources we'll have to see |
Based on prrace's feedback openjdk#14363 (comment)
Mailing list message from Alan Snyder on client-libs-dev: Are you able to test on platforms other than macOS? (I?m not, so I can?t help with that.) Alan |
Mailing list message from Jeremy Wood on client-libs-dev: 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 I do have a Windows machine, but IIRC setting up OpenJDK to build on my - Jeremy ------ Original Message ------
|
Mailing list message from Philip Race on client-libs-dev: if you are thinking of github actions exactly ZERO client tests are run. -phil. On 6/7/23 11:58 AM, Jeremy Wood wrote:
|
Window w1 = createWindow( WINDOW_BACKGROUND, null, x, y, 400, 400, false, "window 1"); | ||
Window w2 = createWindow( WINDOW_BACKGROUND, ROOTPANE_BACKGROUND, x + 400, y, 400, 400, false, "window 2"); | ||
Window w3 = createWindow( WINDOW_BACKGROUND, null, x, y + 400, 400, 400, true, "window 3"); | ||
Window w4 = createWindow( WINDOW_BACKGROUND, ROOTPANE_BACKGROUND, x + 400, y + 400, 400, 400, true, "window 4"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Window w4 = createWindow( WINDOW_BACKGROUND, ROOTPANE_BACKGROUND, x + 400, y + 400, 400, 400, true, "window 4"); | |
Window w4 = createWindow( WINDOW_BACKGROUND, ROOTPANE_BACKGROUND, x + 400, y + 400, 400, 400, true, "window 4"); |
@mickleness This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
@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. |
@mickleness It's not assigned to me now. I can't even find that it was assigned to me. |
OK, maybe I'm mistaken. Thanks for checking. |
@mickleness This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
@mickleness This pull request has been inactive for more than 8 weeks and will now be automatically closed. If you would like to continue working on this pull request in the future, feel free to reopen it! This can be done using the |
I encountered an issue very similar to this problem, is there any chance to see progress on the fix ? |
@bric3 This is not how it works… Yet feel free to propose a patch that addresses the problem. It could be based on this PR. I looks @mickleness couldn't run the tests. I haven't looked into the code changes or tests… |
Yes, I was more thinking about discussing the patch and PR than expecting the PR to be merged right away, since the last comments don't really address the technical issue. |
I'm happy to help with/discuss anything if anyone has any questions. This PR currently resolves the original issue I was seeing and it preserves the legacy painting behavior. Tested on Mac. |
Problem Summary
For non-opaque windows, Window#paint calls
gg.fillRect(0, 0, getWidth(), getHeight())
beforesuper.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; 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). If the monitor refreshes/flushes after we've called
fillRect
but before we finishsuper.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: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:
JComponent.isOpaque
) then the JComponent's background is used. (In this case: that's the opaque green top two windows.) This is probably coming fromComponentUI.update
AlphaComposite.Src
in a couple of places to replace its destination Graphics.Progress
Integration blocker
Issue
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/14363/head:pull/14363
$ git checkout pull/14363
Update a local copy of the PR:
$ git checkout pull/14363
$ git pull https://git.openjdk.org/jdk.git pull/14363/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 14363
View PR using the GUI difftool:
$ git pr show -t 14363
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/14363.diff
Webrev
Link to Webrev Comment