Dumping the rendering process in JavaFX
herve.girod at gmail.com
Sun Nov 16 17:59:05 UTC 2014
I did as it was proposed, and it work. I still have some cases where
textures are a little off compared to the position where they should be,
but it might be due to the post-processing I perform after creating the awt
Compared to what I thought, there were not a lot of classes I had to "hack"
(by accessing protected or package protected methods or constructors).
Mainly: I had to create a custom Screen (just to avoid NGRegion to fetch
textures from their cache), a custom ResourceProvider (to return my
Textures rather than the Platform ones), and I had to peform some code like
in NGCanvas to get an awt image for textures.
I will post an openSource project with more generic code than mine after I
have performed some tests.
2014-11-14 2:29 GMT+01:00 Jim Graham <james.graham at oracle.com>:
> Some pie in the sky observations about the background here...
> Note that there was a fine line there that had to be evaluated. Many of
> the printing detection changes were basically just "Oh, look, I have a new
> ResourceFactory now, that probably means new Textures", but it was tempered
> with "One might think to permanently shift over to the resources from this
> new factory, but if we're just printing, we are probably going to switch
> right back to a screen factory so any permanent changes of internal state
> are likely unwarranted". On the other hand, sometimes when you print a
> scene, it was specially created just for the printing process so the
> initial ResourceFactory it sees is likely the only one it will ever see
> (and then the tree will be tossed).
> It would be nice if we could generalize this or switch the way we manage
> resource states in the NGNode tree so that this was both flexible for
> switching seamlessly to a new resource factory/pool and flexibly dealt with
> the temporary/permanent nature of why those differences might come up (in
> other words, dynamically use and cache new resources without alienating or
> losing track of old ones unless that old pipeline/RF is going away).
> Right now there aren't any on-screen related changes that might require us
> to permanently switch pipelines/resource factories (not entirely sure about
> management of D3D resources when we lose access to the screen, though) and
> printing is really the only use case where we ever even see a new
> ResourceFactory. But, who knows what the future may bring and making
> assumptions about the RF being a constant throughout the app life cycle are
> not necessarily the best implementation practice in the long run...
> Have fun! ;)
> On 11/13/14 3:15 PM, Phil Race wrote:
>> Basically for printing we had to detect that we were printing and use a
>> non-cached texture.
>> If you look for references to "PrinterGraphics" you might find some of
>> Canvas is one place we had to deal with this. There are at least one or
>> two others.
>> Doing anything like only this via public API is probably an
>> insurmountable challenge.
>> On 11/13/14 2:49 PM, Kevin Rushforth wrote:
>>> You could take a look at what JavaFX internally does for printing,
>>> which is similar to what you are trying to do. It also forces the J2D
>>> pipeline and had to deal with this issue. You likely won't be able to
>>> do it without modifying FX internals, though, which is what printing
>>> does in a few places.
>>> -- Kevin
>>> Herve Girod wrote:
>>>> I think that more than one year ago, I asked if it was possible to
>>>> dump the
>>>> JavaFX rendering process. More than one year later, I (or we, for I am
>>>> speaking on behalf of my project) are almost there. We use this in a
>>>> library for a "JavaFX to any format you want" converter. For example
>>>> we are
>>>> currently able to convert a live JavaFX image to a PowerPoint slider
>>>> POI), or we also could do the same with a WMF / EMF / SVG image, keeping
>>>> the vector content of course.
>>>> What we did is hacking the J2DPrismGraphics class to render it in a
>>>> Graphics2D context which in turn can be a PPT / SVG / WMF / or EMF
>>>> Our use case is the use of JavaFX in an Editor (no it's not a JavaFX
>>>> Editor, we edit graphic specifications for an avionics standard called
>>>> ARINC 661), and the ability to produce another Vector format with
>>>> the same UI.
>>>> It works very well, except that of course we had to hack a few JavaFX
>>>> classes to do that (obviously J2DPrismGraphics was not designed to allow
>>>> this). We did not recompile the core library, it's just separate classes
>>>> which uses com.sun classes when possible, or we used
>>>> PrivilegedActions when
>>>> a method we needed was package protected.
>>>> But we have still a big problem (I think that it might be the only one,
>>>> except for the fact that our solution is an ugly hack, as you can see):
>>>> There is still one case where our solution does not work: Textures.
>>>> In fact
>>>> we would have been able to convert JavaFX textures to BufferedImages
>>>> if we
>>>> could use the Java2D-based Texture class, but of course as we did
>>>> special, we encounter a D3D Texture (for example on Windows) which we
>>>> know how to deal with.
>>>> Which leads me to my two questions:
>>>> - Is there a programmatic way (even a contorted one) to force JavaFX
>>>> to use
>>>> our own specific Pipeline (the idea is to be able to do this temporarily
>>>> when serializing the JavaFX content, so without having to use command
>>>> - I think that it could be very useful to have a neutral and JavaFX -
>>>> supported way for developers to use their own Pipeline, even if it was
>>>> limited and with a lower than average performance. Being able to convert
>>>> from / to the JavaFX format is something that can be very useful.
More information about the openjfx-dev