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
8220484: JFXPanel renders a slanted image with a hidpi monitor scale of 125% or 175% #246
Conversation
… EmbeddedScene#getPixels does In edge cases where monitor scaling of 1.25 or 1.75 is active, Math.ceil and Math.round produce different results and EmbeddedScene#getPixels in JFXPanel#paintComponent causes an off-by-one error on the line width and therefore sheared rendering.
Hi @Schmidor, welcome to this OpenJDK project and thanks for contributing! We do not recognize you as Contributor and need to ensure you have signed the Oracle Contributor Agreement (OCA). If you have not signed the OCA, please follow the instructions. Please fill in your GitHub username in the "Username" field of the application. Once you have signed the OCA, please let us know by writing If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please use "Add GitHub user Schmidor" as summary for the issue. If you are contributing this work on behalf of your employer and your employer has signed the OCA, please let us know by writing |
/issue 8230007 |
@Schmidor |
@Schmidor in general, we don't use the |
Webrevs
|
/reviewers 2 |
@kevinrushforth |
/issue remove 8230007 |
@kevinrushforth Only the author (@Schmidor) is allowed to issue the |
Even though this is a seemingly simple fix, I'd like @prsadhuk to also review it. @Schmidor Can you do the following?
|
/issue remove 8230007 |
@Schmidor |
I'll look into a more detailed description with code references and try to create a test. The backbuffer of the Stage is created with Math.round(baseSize*uiScale) and for Swing the DataBuffer is referenced into an BufferdImage, where the bounds are calculated with Math.ceil(baseSize*uiScale). So when the base-width is 101px and uiscale is 1.25, the unrounded size is 126.25. The real buffer-width is then 126px, but rendered in swing using 127px. So there is an offset of one pixel per line and the resulting image is skewed. |
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.
In 2D, we normally use sun.java2d.pipe.Region.clipRound as it also checks for -ve/+ve max INTEGER but I guess that is internal class to FX so it's ok to use Math.round.
Approval pending test creation.
While both might work, as long as there is no mixed usage of round and ceil, Math.ceil seems to be better. I'm not sure if the timed waiting for the resizes is the best way for ensuring that the buffer is resized to the new bounds, so I'm open for suggestions. To me at least it seems to create a reproducible sheared output after the second resize in the test case and not anymore after changing the calculations to Math.ceil. |
This fix might be a candidate for JavaFX 15, so I recommend to not merge the master branch. If we don't spot anything of concern during the review, then we might ask you to retarget your PR to the |
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.
I left specific feedback, mostly on the test, but also one question on the fix.
For the test, make sure you can run it as follows:
gradle --info -PFULL_TEST=true -PUSE_ROBOT=true cleanTest :systemTests:test --tests JFXPanelScaledTest
(presuming you rename it to JFXPanelScaledTest
)
It should fail without your fix and pass with your fix.
Currently, it will fail because of the call to setAccessible
(see inline comments).
tests/system/src/test/java/test/javafx/embed/swing/JDK8220484Test.java
Outdated
Show resolved
Hide resolved
tests/system/src/test/java/test/javafx/embed/swing/JDK8220484Test.java
Outdated
Show resolved
Hide resolved
tests/system/src/test/java/test/javafx/embed/swing/JDK8220484Test.java
Outdated
Show resolved
Hide resolved
tests/system/src/test/java/test/javafx/embed/swing/JDK8220484Test.java
Outdated
Show resolved
Hide resolved
tests/system/src/test/java/test/javafx/embed/swing/JDK8220484Test.java
Outdated
Show resolved
Hide resolved
tests/system/src/test/java/test/javafx/embed/swing/JDK8220484Test.java
Outdated
Show resolved
Hide resolved
tests/system/src/test/java/test/javafx/embed/swing/JDK8220484Test.java
Outdated
Show resolved
Hide resolved
tests/system/src/test/java/test/javafx/embed/swing/JDK8220484Test.java
Outdated
Show resolved
Hide resolved
modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/EmbeddedScene.java
Show resolved
Hide resolved
tests/system/src/test/java/test/javafx/embed/swing/JDK8220484Test.java
Outdated
Show resolved
Hide resolved
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.
The test is looking better now. And the fix to FXPanel
looks correct as well, although needs to be tested.
I left a few comments relating to the tests. I haven't looked at the SWT test in detail, but will do that later. I also still need to test this on multiple platforms (I have a concern about platforms other than Windows due to assumptions the test is making).
build.gradle
Outdated
@@ -3597,9 +3607,11 @@ project(":systemTests") { | |||
testCompile project(":base").sourceSets.test.output | |||
testCompile project(":controls").sourceSets.test.output | |||
testCompile project(":swing").sourceSets.test.output | |||
testCompile project(":swt") | |||
testCompile name: SWT_FILE_NAME |
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.
We can't have a dependency on swt
from any other project. SWT tests need to be confined to modules/javafx.swt/src/test/java/
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.
I note that this does work for me. So copying the pattern used by systemTests
into the swt
project might be all that is needed to get it to work there.
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.
I assumed I should add it to the robot package, as it is also a visual test. I've moved it to the swt module
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.
I verified that the SWT test works well, when manually enabled in build.gradle and if it runs in isolation. As for putting it in a robot
sub-package, that seems helpful, but since it won't be enabled anyway, is optional.
We can file a follow-up issue to enable SWT tests again (as long as they aren't enabled by default. My thought is to change the default value of SWT_TEST
to false, and then enable the tests on platforms other than macOS when the SWT_TEST
is set to true
along with FULL_TEST
).
modules/javafx.swing/src/main/java/javafx/embed/swing/JFXPanel.java
Outdated
Show resolved
Hide resolved
tests/system/src/test/java/test/robot/javafx/embed/swt/FXCanvasScaledTest.java
Outdated
Show resolved
Hide resolved
tests/system/src/test/java/test/robot/javafx/embed/swing/JFXPanelScaledTest.java
Outdated
Show resolved
Hide resolved
tests/system/src/test/java/test/robot/javafx/embed/swing/JFXPanelScaledTest.java
Outdated
Show resolved
Hide resolved
Also, in general we recommend not to force-push to your branch after the review has started, unless there is some compelling reason to do so. It makes it harder for reviewers to look at incremental diffs. |
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.
The test looks good with one minor typo in the constant field name (see below). I verified that it fails on Linux and Mac (as I suspected), so you will need to limit the test to running on Windows.
modules/javafx.swt/src/test/java/test/javafx/embed/swt/FXCanvasScaledTest.java
Outdated
Show resolved
Hide resolved
tests/system/src/test/java/test/robot/javafx/embed/swing/JFXPanelScaledTest.java
Outdated
Show resolved
Hide resolved
tests/system/src/test/java/test/robot/javafx/embed/swing/JFXPanelScaledTest.java
Show resolved
Hide resolved
I think this is ready to target to |
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.
Looks good.
@prsadhuk can you also review this?
@Schmidor This change now passes all automated pre-integration checks. When the change also fulfills all project specific requirements, type
Since the source branch of this PR was last updated there have been 41 commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid automatic rebasing, please merge As you are not a known OpenJDK Author, an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@kevinrushforth, @prsadhuk) but any other Committer may sponsor as well. ➡️ To flag this PR as ready for integration with the above commit message, type |
/integrate |
/sponsor |
@kevinrushforth @Schmidor The following commits have been pushed to jfx15 since your change was applied:
Your commit was automatically rebased without conflicts. Pushed as commit 3cc29e3. |
In edge cases where monitor scaling of 1.25 or 1.75 is active, Math.ceil and Math.round produce different results and EmbeddedScene#getPixels in JFXPanel#paintComponent causes an off-by-one error on the line width and therefore sheared rendering.
The changes were already proposed by the submitter in JBS-8220484.
OCA is signed and send.
Progress
Issue
Reviewers
Download
$ git fetch https://git.openjdk.java.net/jfx pull/246/head:pull/246
$ git checkout pull/246