Skip to content
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

Switch JavaFX to Monocle Implementation #576

Closed
tresf opened this issue Feb 9, 2020 · 7 comments
Closed

Switch JavaFX to Monocle Implementation #576

tresf opened this issue Feb 9, 2020 · 7 comments
Assignees

Comments

@tresf
Copy link
Contributor

tresf commented Feb 9, 2020

Apparently JavaFX 8 introduced formal support for a "headless" back-end for Java FX that they called "Monocle". I'd like to discuss the possibility of switching QZ Tray over to the "headless" JavaFX "Monocle" Testing framework.

  • Faster render times
  • No more popups with { rasterize: true }

This technique was discovered while investigating #547, #32.

Steps:

Hidden, see PR #586 instead
  1. Download from Maven Central: https://mvnrepository.com/artifact/org.testfx/openjfx-monocle
  2. Copy the jar to jre/lib/ext (Is there a cleaner way to do this?)
  3. Configure the JVM arguments:
    # Add the following JVM arguments (through IDE or the command line)
    -Dtestfx.robot=glass -Dglass.platform=Monocle -Dmonocle.platform=Headless -Dprism.order=sw

For more information see this StackOverflow article which explains it much better: https://stackoverflow.com/a/29131967/3196753

@tresf
Copy link
Contributor Author

tresf commented Feb 14, 2020

Initial tests are fantastic... This lifts the zoom limitations that we hit with our existing implementation... I'll prepare a PR against 2.0.

image

@tresf
Copy link
Contributor Author

tresf commented Feb 21, 2020

Initial tests are fantastic...

I spoke too soon... Quoting the JavaFX developer's mailing list...

Although first test was positive, when invoking multiple times, I'm getting some internal errors similar to this: https://stackoverflow.com/questions/49388497 and the framework grows slower and slower as it nears its final capture. (I'm using WebView.capture(...))

Fortunately a developer was kind enough to share their results...

Hi Tres,

We also are suffering from this crash when running our TestFX unit tests, particularly on Java 11.
It is due to a concurrency issue between the JavaFX thread and the QuantumRenderer thread and there is an OpenJDK bug here: https://bugs.openjdk.java.net/browse/JDK-8201567

Quoting from this bug report:

“The QuantumRenderer calls the getPixels() method while trying to find a buffer that's not in use, yet in doing so it can inadvertently modify a buffer that's in use."

There is also a related TestFX Bug: TestFX/Monocle#56

There is a fix for this issue In the first comment of the JDK-8201567, in a link to GitLab: https://gitlab.com/openjfxepd/jfxpatch/commit/

We have used this patch in our local OpenJFX build.

This has never been made into a pull request however but I believe it should.

This helps and now I'm facing a new issue, when the height is provided as zero, the WebView grows out of control, quoting:

[...] a nuance of reusing the WebView and Stage using Monocle, the stage/webview height calculation starts to grow out of control (watching the DOM height -- we calculate the natural height and then use that for snapshot).  In my case it was growing 300, 900, 2900, 8600 eventually crashing somewhere in buffer allocation.  Hard-coding the sizing didn't suffer the same fate because it bypasses our attempts to calculate the height using JavaScript.  Oddly, creating a fresh WebView each time didn't correct the issue either.  I believe the underlying issue stems somewhere from the stage height never resetting back, but attempts to do so manually cause other issues, so I'll see if there's a viable workaround by doing more renders using Monocle.

We already have an open item with Gluon regarding WebView stage sizing (SUPQZ-2), so this may be a race condition rearing its ugly head through a different symptom.  We'll continue to work on it there.

@tresf
Copy link
Contributor Author

tresf commented Mar 24, 2020

This issue is being tracked upstream (private tracker) as SUPQZ-3. Quoting the developer:

I've created a javafx.graphics jar that includes the Monocle classes for both macOS and windows based on OpenJFX 11.0.2. You can download them from the following URLs:

Edit: Paths have changed with the introduction of JavaFX 15-EA

You need to replace the javafx.graphics.jar file from your downloaded JavaFX SDK with these ones.

I've provided (to the developer quoted above) a snippet which causes a hard crash on my Windows 10 VM,.
Note: The above libraries WILL crash and thus WILL need to be patched and replaced prior to inclusion in QZ Tray.

@tresf
Copy link
Contributor Author

tresf commented Mar 25, 2020

Note: The above libraries WILL crash and thus WILL need to be patched and replaced prior to inclusion in QZ Tray.

Update: The Windows Monocle implementation no longer crashes after removing -Dprism.order=sw.

@tresf
Copy link
Contributor Author

tresf commented Apr 8, 2020

@bberenz since 52881c7, my macOS system attempts to use a virtual desktop size of 40000x40000-32 and throws the following exception:

We need to set a max value to prevent this crash from occurring. I've asked Gluon support for a san max value.

Exception in thread "JavaFX Application Thread" java.nio.BufferOverflowExceptionException in thread "JavaFX Application Thread" java.nio.BufferOverflowException
 at java.base/java.nio.HeapByteBuffer.put(HeapByteBuffer.java:233)
 at com.sun.glass.ui.monocle.Framebuffer.clearBufferContents(Framebuffer.java:81)
 at com.sun.glass.ui.monocle.Framebuffer.composePixels(Framebuffer.java:118)
 at com.sun.glass.ui.monocle.HeadlessScreen.uploadPixels(HeadlessScreen.java:118)
 at com.sun.glass.ui.monocle.MonocleView._uploadPixels(MonocleView.java:95)
 at com.sun.glass.ui.View.uploadPixels(View.java:772)
 at com.sun.prism.PresentableState.uploadPixels(PresentableState.java:308)
 at com.sun.javafx.tk.quantum.SceneState.access$001(SceneState.java:40)
 at com.sun.javafx.tk.quantum.SceneState.lambda$uploadPixels$0(SceneState.java:123)
 at com.sun.glass.ui.monocle.RunnableProcessor.runLoop(RunnableProcessor.java:92)
 at com.sun.glass.ui.monocle.RunnableProcessor.run(RunnableProcessor.java:51)
 at java.base/java.lang.Thread.run(Thread.java:834)

@tresf
Copy link
Contributor Author

tresf commented Apr 14, 2020

Testing on 2.0 is promising. Here's our first ever 1200 dpi print using the 2.0 branch:
image

tresf added a commit that referenced this issue Apr 14, 2020
tresf added a commit that referenced this issue Apr 28, 2020
Add Monocle FX support for Java 11+
- Uses JavaFX15-ea with bundled Monocle support
- Closes #576

Co-authored-by: Berenz <thebrettberenz@gmail.com>
@tresf
Copy link
Contributor Author

tresf commented Apr 28, 2020

Closed via fb4b01a. Note, this feature still needs to be ported to 2.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants