This change fixes a potential threading issue in RTImage.draw() method in 
WebView. The issue has been theorized back in 
[JDK-8333374](https://bugs.openjdk.org/browse/JDK-8333374), I have not managed 
to figure out a reliable reproducer for it, but the circumstances for it to 
happen are there.

Issue can happen in `RTimage.draw()` method. In 99% of cases `RTImage.draw()` 
will be called only by QuantumRenderer thread (that is during regular drawing 
to a Stage/Scene), however there is also a possibility we will call 
`RTImage.draw()` from a different thread, notably with a `PrinterGraphics` 
object (or in other words, when printing). Then there is a chance we will run 
some of the initial checks in parallel to QuantumRenderer thread. I found two 
places that can be affected - the initial checks at the beginning of the method 
and the `getTexture()` call inside the code block responsible for printing.

The first place was fixed by running the checks on the render thread. That way 
we can ensure the render thread will not overwrite the `tex` reference from the 
render thread while the printing thread reads it. To make this happen I added 
`PrismInvoker.callOnRenderThread()` which functions like 
`PrismInvoker.runOnRenderThread()` but with a `Callable<>` instead of a 
`Runnable` object.

Second place can happen if, for some reason, in between previous checks and the 
`getTexture()` call QuantumRenderer will modify or free RTImage's tex reference 
(ex. while pruning the Vram pool) - then the `getTexture()` call will return 
`null` (introduced as NPE prevention from 
[JDK-8333374](https://bugs.openjdk.org/browse/JDK-8333374)) which can cause an 
NPE on QuantumRenderer thread. If that happens, we skip the `readPixels()` call 
which will print an empty RTImage.

I verified these changes on Windows and Linux with our test suite and with 
manual testing via `HelloWebView` and using an old `SimplePrint.java` 
reproducer from [JDK-8118415](https://bugs.openjdk.org/browse/JDK-8118415); 
both regular drawing and printing work as they did. I found simply loading 
`google.com` via both apps works to trigger this draw call multiple times 
(`SimplePrint.java` needed to be adjusted slightly to print out the web page 
instead of predefined HTML code). Test suite completes successfully (there were 
3 web.test failures on my end but they also happened on master and refer to 
other, unrelated parts of javafx.web) and printing works the same way it used 
to.

-------------

Commit messages:
 - Make canDraw final
 - RTImage: Run pre-draw checks on render thread

Changes: https://git.openjdk.org/jfx/pull/2092/files
  Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=2092&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8341852
  Stats: 50 lines in 2 files changed: 40 ins; 0 del; 10 mod
  Patch: https://git.openjdk.org/jfx/pull/2092.diff
  Fetch: git fetch https://git.openjdk.org/jfx.git pull/2092/head:pull/2092

PR: https://git.openjdk.org/jfx/pull/2092

Reply via email to