I think I know quite a bit about JavaFX graphics and I do not generally agree with your statements. Especially the statement that the Canvas is so much superior is a myth from the old days of Java 8 where there were a few performance bugs in the scene graph handling. But that's a long time ago. (I even gave a workshop on this at the JavaLand conference some time ago.) Maybe you could present a few more details about your use-case and not so much about the technique that you think is the best fit for it. Maybe even some demo code somewhere. I am always interested in a discussion about graphics as long as it is supported by facts. Neither the scene graph nor the canvas is a silver bullet.
It always depends on your use-case.
Michael

Am 09.05.20 um 00:18 schrieb jfx user2:
From the JavaDoc "Canvas is an image that can be drawn on using a set of graphics commands provided by a GraphicsContext."  This a bit of a misnomer.  While canvas can be used to draw in image (actually GraphicsContext not canvas itself), the image based methods of GraphicsContext are far outweighed by the "vector" or path based methods.  The GraphicsContext gives you the ability to freely create dynamic graphics without the constraints of the Scene Graph.  It can be highly performant and scalable if done properly.  The Scene Graph will not perform like the GraphicsContext.  If you haven't worked with highly dynamic graphics, you might not have encountered any issues.  The Scene Graph works ok up to a certain number of objects and it is not good at adding and removing objects often.  GraphicsContext does not have the same restrictions.  It can involve more work but the end result will scale far beyond what you can do in a Scene Graph... I think this is already widely accepted.

The proposed method on the GraphicsContext simply returns what is already there.  It would convert the already stored Path2D to a Path.  Why reinvent what is already present and only private? This in turn CAN be used in the Scene Graph but it can also be used as a container to draw back onto the GraphicsContext.  You see,  a Path that is calculated once and then used repeatedly to draw in the GraphicsContext (possibly even transformed) is better than sub-optimally calculating that Path on every pass through the GraphicsContext or storing it as an image or Shape (those were some of my workarounds).

Anyway, I'm requesting that a private API be used to create a new public method.  This is really no different than existing public methods that use private APIs.  I'm not asking to expose private APIs (not in this request :o).  There isn't even much code.  It's reusing what's already there.

Ask Gerrit Grunwald about his experience with the Scene Graph vs Canvas/GraphicsContext.


On Fri, May 8, 2020 at 4:27 PM Michael Paus <m...@jugs.org <mailto:m...@jugs.org>> wrote:

    Hi,
    I have to say that your requirements sound a little bit strange to
    me,
    but maybe you can make it clearer what your real use-case behind
    them is.
    What I do not understand is why you are using the canvas at all.
    Conceptually the canvas is for direct mode rendering into an
    image. The
    fact that
    this is handled a little bit different internally is an
    implementation
    detail, you should not rely on. Why don't you use the scene graph
    which
    seems
    to provide many of the aspects that you need? I admit that there
    are a
    few hidden gems internally that I would also like to be made public
    (e.g. the flattening path iterator) but I definitely see these things
    more in the scene graph context but not for Canvas.
    Just my two €ent.
    Michael

    Am 08.05.20 um 22:08 schrieb jfx user2:
    > No... given a Shape, create a Path that represents the outline
    of that shape.  If I had a Path I wouldn’t be requesting the new
    methods.
    >
    > One of the workarounds for getting a Path from a GraphicsContext
    is to keep track of it as I’m drawing... however, this is overhead
    in the gc call that can become very expensive when you have a lot
    of gcs or if your gc is doing a lot of work.  The path is already
    there in Path2D along with a method to convert it to a public
    Path.  There’s no need for an expensive custom workaround.  All
    that’s required is a method on the GraphicsContext that returns a
    Path.  The same is true for getting a Path from a Shape.
    >
    > Please note that this behavior is desirable for highly optimized
    use of GraphicsContext and Shapes where you need “outlines” of
    things in vector format.  The private api is unnecessarily hiding
    this information.
    >
    >> On May 8, 2020, at 3:38 PM, Philip Race <philip.r...@oracle.com
    <mailto:philip.r...@oracle.com>> wrote:
    >>
    >> The current path is defined by the application - you - and yet
    you don't know what it is  ?
    >> You do say
    >>> I have other workarounds where I have to maintain a path as
    I’m drawing in the canvas
    >> Why can't you do that ? No internal API digging.
    >>
    >> -phil
    >>
    >>> On 5/8/20, 12:02 PM, jfx user2 wrote:
    >>> Ok, then please consider the GraphicsContext request that I’ve
    made.  It simply enables you to get the Path from the context
    without exposing com classes at all.  I have other workarounds
    where I have to maintain a path as I’m drawing in the canvas or I
    have to do hit testing on a non vector image to determine the path
    but these are way more expensive than simply creating a Path
    object from the Path2D that is already in the GraphicContext. 
    That path can be used in drag and drop scenarios, fast secondary
    rendering under heavy gc use, edge tracing, and the list goes on.
    >>>
    >>> The same is true for the Shape class.  I’d like to request
    that the following be added to Shape:
    >>> public Path getPath() {
    >>>      return Shape.createFromGeomShape(getTransformedArea());
    >>> }
    >>>
    >>> That’s it.  The underlying methods are there but the public
    api doesn’t expose them.  This gives you a vector outline of the
    Shape as Path.l on demand, not stored.
    >>>
    >>> There are expensive workarounds for performing these tasks and
    I spent a long time trying... until I discovers the private apis
    already had the capability but simply did. It expose it.
    >>>
    >>> I’d these are not supported, I’ll have to stick with
    reflection,  bytebuddy, or forking - non of which will be easily
    maintained or portable.
    >>>
    >>> Ps I will post additional concerns over time. The next one
    likely has to do with the mismatch between javafx canvas (gc) and
    other canvases such as svg, html2.  I think there is private api
    that would help in this case.
    >>>
    >>>>> On May 8, 2020, at 2:41 PM, Kevin
    Rushforth<kevin.rushfo...@oracle.com
    <mailto:kevin.rushfo...@oracle.com>> wrote:
    >>>> Since Canvas is an immediate mode graphics API, I presume
    you are interested in the most recent drawing primitive? (we don't
    keep the composite shape for all drawing primitives -- that would
    be both too expensive and not really appropriate). How would you
    expect current rendering attributes (e.g., transforms) to affect
    the results? These are all questions that need to be addressed.
    >>>>
    >>>> As for the bigger picture, we intentionally have a separate
    render graph with "peers" for each node, although some of the
    duplication of classes is historical (we used to have a looser
    decoupling before Prism became the only backend). Unless there is
    a compelling need, we are unlikely to consider changing this in
    the general case, but perhaps could look at specific cases if it
    made sense. This is a separate issue, though, from public API and
    the two shouldn't be conflated.
    >>>>
    >>>> Btw, JavaFX has been fully open-sourced since 2013, although
    the design of Prism predates that.
    >>>>
    >>>> -- Kevin
    >>>>
    >>>>
    >>>>> On 5/8/2020 10:43 AM, jfx user2 wrote:
    >>>>> Kevin, go easy please :0).  There is a need.
    >>>>>
    >>>>> Access to the outline of the path in the canvas is great for
    edge following, node attachment points, animating around the
    non-rectangular border of what’s actually displayed, etc.
    >>>>>
    >>>>> The other request that I haven’t posted yet is to do the
    same for Shape.   I’ve tested both of these enhancements and it
    works as desired.  I’ll post the second request soon.
    >>>>>
    >>>>> But back to the bigger picture.  The requests that I’m
    making are only additions to return a path from javafx not com. 
    But there are other cases where geometry and convenience methods
    in com would be beneficial to the public api.  It also seems odd
    that there are two layers to begin with...  parallel apis often
    result in too much object creation or cpu overhead translating
    between them.  I’ll be more specific about these cases over time. 
     Part of my intention is to spark a discussion about the design
    since previously this was relatively closed source.
    >>>>>
    >>>>>>> On May 8, 2020, at 1:12 PM, Kevin
    Rushforth<kevin.rushfo...@oracle.com
    <mailto:kevin.rushfo...@oracle.com>> wrote:
    >>>>>> While there is no plan to "open up" more of com.sun.javafx
    (and that isn't really the right way to look at it), if you have a
    proposed enhancement to the existing public javafx.* classes we
    could discuss it.
    >>>>>>
    >>>>>> As for your specific example, can you say more about what
    your use case is? The GraphicsContext object is a drawing context
    for a Canvas node, so it is not a natural place to put an API that
    computes or returns a path. I get the sense that you are looking
    at the existing internal implementation classes and saying "how
    can I get access to some information that might be useful to my
    application" rather than describing what your application is
    trying to do. Once we understand what you are trying to do, we can
    discuss whether the need is general enough to propose adding to
    the public API of JavaFX and what form such a new API might take.
    >>>>>>
    >>>>>> -- Kevin
    >>>>>>
    >>>>>>
    >>>>>>> On 5/8/2020 9:35 AM, jfx user2 wrote:
    >>>>>>> I am aware of this and that’s why I am asking.  There are
    useful private features in com.sun.javafx and I explained one of
    them in my message.  I have an additional related example but the
    larger question is if there is a plan to open more of
    com.sun.javafx to the public api, documentation surrounding this,
    or possibly a complete replacement?
    >>>>>>>
    >>>>>>> Please consider the example I provided as a feature request.
    >>>>>>>
    >>>>>>>>> On May 8, 2020, at 9:39 AM, Kevin
    Rushforth<kevin.rushfo...@oracle.com
    <mailto:kevin.rushfo...@oracle.com>> wrote:
    >>>>>>>> Only javafx.* packages are part of the public API.
    Anything else, including com.sun.javafx.*, is internal
    implementation details that an application should never call.
    >>>>>>>>
    >>>>>>>> -- Kevin
    >>>>>>>>
    >>>>>>>>
    >>>>>>>>> On 5/8/2020 12:38 AM, jfx user2 wrote:
    >>>>>>>>> Is there documentation around the packages
    (com.sun.javafx vs javafx) used
    >>>>>>>>> in JavaFX?
    >>>>>>>>>
    >>>>>>>>> For example, why is there a com.sun.javafx.geom that
    isn't fully mirrored
    >>>>>>>>> in the javafx.scene.shape package?  Why are there
    missing features from
    >>>>>>>>> Graphics2D?
    >>>>>>>>>
    >>>>>>>>> I have a specific example that prompted the question:
    >>>>>>>>>
    >>>>>>>>> Consider the following classes:
    >>>>>>>>>
    >>>>>>>>> javafx.scene.shape.Shape
    >>>>>>>>>      private static Path
    >>>>>>>>> createFromGeomShape(com.sunjavafx.geom.Shape geomShape)
    >>>>>>>>>
    >>>>>>>>> javafx.scene.canvas.GraphicsContext
    >>>>>>>>>      Path2D path;
    >>>>>>>>>
    >>>>>>>>> I want to write a line as follows:
    >>>>>>>>> Path path = Path.createFromGeomShape(gc.path);
    >>>>>>>>> b/c I want to inexpensively get the outline of the
    GraphicsContext.
    >>>>>>>>>
    >>>>>>>>> However:
    >>>>>>>>> We can't access Path2D b/c it's in com.sun.javafx.geom
    which isn't exported
    >>>>>>>>> by the module.
    >>>>>>>>> We can't access Path.createFromGeomShape b/c it's private.
    >>>>>>>>> We can't access path in GraphicsContext b/c it's default
    and doesn't have
    >>>>>>>>> an accessor.
    >>>>>>>>>
    >>>>>>>>> A possible solution is to add a new method:
    >>>>>>>>> javafx.scene.canvas.GraphicsContext
    >>>>>>>>> public Path getPath() {
    >>>>>>>>>      //implementation copied from
    >>>>>>>>> javafx.scene.shape.Shape.createFromGeomShape but use
    gc.path as the path
    >>>>>>>>> }
    >>>>>>>>>
    >>>>>>>>> That would solve my immediate problem but raises the
    question... why is
    >>>>>>>>> com.sun.javafx hidden? What's the architectural reason? 
    Is there any work
    >>>>>>>>> in progress that will impact this design?
    >>>>>>>>>
    >>>>>>>>> PS my example is actually very important.  I currently
    use reflection and
    >>>>>>>>> module opens in the build to get the path but if the
    getPath method could
    >>>>>>>>> be added to GraphicsContext, that would be great.  For
    performance, it
    >>>>>>>>> would be even better to get the PathIterator directly
    instead of
    >>>>>>>>> translating into a javafx..Path but that is related to
    the bigger question.



Reply via email to