I think it would be feasible to develop some form of automatic virtualisation API, but I don't think it needs to be an API that ships with JavaFX. A generic implementation would probably need to abstract out three details:

1) The 'cell factory' (in the lingo of existing controls) to generate nodes on demand (in other words, a node factory) 2) A means of specifying when a node should be 'removed' from the scenegraph (and added back to the pile of available nodes that can be reused) 3) The actual layout of all nodes that are currently part of the visualisation

I don't think there is any escaping detail #2 above, unless you want to do a very simplistic 'if (nodeX < 0 || nodeY < 0 || nodeX > w || nodeY > h)'. Perhaps that would be fine in some simplistic cases, but if you're working in a zooming case I imagine you might want to prune the scenegraph in situations where nodes are technically within bounds but are no longer entirely relevant to the view.

This is essentially all that happens in the VirtualFlow code used in a number of UI controls. Could this VirtualFlow code be rewritten to be based on top of a more abstract virtualisation engine? Sure....but it probably won't be :-)

Hope that helps.

-- Jonathan

On 9/08/2013 9:38 a.m., Felix Bembrick wrote:
With all this talk of node virtualisation, I am wondering how feasible it would to build some kind of "automatic virtualiser" such that you pass it your real-world model and then it automagically works out the actual nodes and pools required and manages them seamlessly to maximise rendering performance and responsiveness? That is, it determines how many nodes will be visible at any one time and just manages all that stuff for you completely under the hood.

Maybe Jonanthan you have come some way to building such a beast with your work on bidirectional virtualisation in FX 8 TableView or other controls?

Felix


On 9 August 2013 07:31, Felix Bembrick <felix.bembr...@gmail.com <mailto:felix.bembr...@gmail.com>> wrote:

    T
    hanks Jonathan.

    I'll have to check out the virtualisation that you refer to that's
    going on in JavaFX8 with TableView., it sounds very interesting.

    I am not saying that controls such as what I am proposing are
    *impossible* to implement using a scenegraph; it just seems
    natural to implement them in a more procedural/programmatic way
    but this could very possibly just be because I do not have a full
    grasp of the capabilities of the scenegraph and what can be
    achieved by manipulating it.  To me it seems that the costs of
    repeatedly creating nodes (or hopefully reusing them), potentially
    restructuring the hierarchy of nodes in the scenegraph and
    adjusting each node's properties to enable a truly dynamic control
    would logically be much greater than just cycling through a render
    loop and rendering each graphic element in its correct location
    but, again, you seem very confident that these costs are not
    significant enough to prevent such a control performing well.

    In the end if I can get away with a scenegraph representation of
    this control and that massaging said scenegraph is performant
    enough then I am in a happy place.  I have already observed that
    some nice stuff can happen just by playing around the scenegraph
    so it is quite possible that I am worrying about performance and
    memory issues that will never actually eventuate in practice.

    Felix


    On 9 August 2013 07:16, Jonathan Giles <jonathan.gi...@oracle.com
    <mailto:jonathan.gi...@oracle.com>> wrote:

        Felix,

        As you are restricted in what you can say, that also restricts
        how I can help. However, your example of a spreadsheet not
        being a control that can be implemented in a scenegraph-based
        manner suggests that you might want to re-evaluate your
        assumptions. A spreadsheet would be able to be implemented in
        a scenegraph approach quite nicely - the TableView control
        comes quite close to that already (especially in JavaFX 8.0
        where it can virtualise in both vertical and horizontal
        directions). In fact, I know of at least two spreadsheet
        implementations that already exist in JavaFX based on a
        scenegraph approach.

        As I've said elsewhere, the issues you are facing are because
        of merging two approaches (retained and immediate modes) into
        one control. What you are hoping to do is have your cake and
        eat it too, which unfortunately I don't think will end up too
        well for you :-) My advice is to recheck your assumptions -
        the scenegraph approach, in my opinion, should suit your
        requirements far more than an immediate mode approach (given
        that your requirement is to reuse existing scenegraph-based
        controls).

        I'm not sure why you think controls must be defined in a
        static, structured way. You could put all nodes of a control
        into a single Pane (or Region, etc) layout and layout all the
        nodes using absolute positioning. You can be as dynamic as you
        want to be.

        Unfortunately, without more information I am really unable to
        give any further advice, but I wish you good luck in whichever
        approach you decide to take.

        -- Jonathan

        On 9/08/2013 9:02 a.m., Felix Bembrick wrote:
        Hi Jonathan,

        Thanks for your reply.

        I am a little restricted in exactly what I can reveal about
        my plans for this control but I can say that it is one in
        which its very appearance could change quite significantly in
        a dynamic way at runtime.  The control also needs to support
        panning and zooming in a very performant way.  There will
        likely be a lot of graphics being draw in a manner which (to
        me at least) fits the immediate mode of rendering better than
        a scenegraph because their positions and attributes are most
        readily defined programmatically rather than declaratively.

        Though not directly analogous, consider your typical
        spreadsheet application like Excel where the user is able to
        pan to the right effectively without limits and that grid
        lines are constantly being rendered as the panning takes
        place.  Given that screens can be very large these days it is
        conceivable that a complex spreadsheet will be displaying
        hundreds of lines to define the cells in a grid at any one
        time and that it is way more concise to programmatically
        define how this grid is rendered rather than having a
        scenegraph containing a node for each line etc.  Also, the
        panning and zooming responses are much simpler to implement
        programmatically than continually fiddling around with the
        scenegraph.  Then there's the whole issue of virtualisation
        and keeping the actual number of "active" nodes to a minimum
        if it were to be done using a scenegraph.

        I am just not convinced that the costs of memory usage and
        processing cycles to maintain a retained mode representation
        of a visual structure like this can be justified or made
        performant when all you really need is a simple algorithm
        that draws lines on the screen according to the properties of
        your cell model.  Then consider that the *actual* control
        will be significantly more complex and graphically rich than
        this simplistic spreadsheet analogy.

        To me this is the sort of control that really lends itself to
        an immediate mode rendering component such as Canvas but
        there just seem to be so many impediments in the way of
        actually building a professional control with Canvas at its
        base.  If we continue with the spreadsheet analogy then
        obviously cells would contain other controls etc. and we have
        discussed the limitations on "embedding" other controls
        within a Canvas that seems to suggest it's not practical.

        I think in the end it gets down to the nature of the control
        itself and whether its appearance is best defined by data or
        by an algorithm just like the way certain types of knowledge
        are best defined by nouns whereas others are best defined
        procedurally.

        At this stage it is looking very much as though JavaFX really
        only supports controls most appropriately defined in a
        static, structured way like a scenegraph.  This in turns
        limits its applicability to a whole range of software
        applications.

        Felix


        On 6 August 2013 10:10, Jonathan Giles
        <jonathan.gi...@oracle.com
        <mailto:jonathan.gi...@oracle.com>> wrote:

            I think it would pay to take a step back and understand
            why you think a 'traditional' scenegraph-based (or
            retained mode) control is not sufficient for your needs?
            Unfortunately you've not detailed your use case, so it is
            hard to give any specific advice. Are you able to give
            any details about what it is you're trying to build and
            why you think the normal approach to building controls is
            not sufficient?

            We've built some fairly complex controls using this
            approach, and if implemented wisely, there is very little
            that a scenegraph-based approach can't do. Specifically,
            do you think your control will render all of the
            'thousands of nodes' at once, or will many of these nodes
            be off screen or otherwise not visible at any one time?
            For things like the TableView we only render the nodes
            that are visible. This means that regardless of whether
            there are 100 or 1,000,000 rows of data, we only have
            visual nodes for the 20 visible rows, for example.
            Keeping your scenegraph as minimal as possible is always
            a very wise idea, if performance is a concern.

            As you note, the other problem is that you will run into
            issues if you want to mix canvas rendering with the
            scenegraph-based controls like Button. The best you're
            likely to achieve (having not tried it personally) is to
            position the control on top of the canvas, rather than
            attempting to render the control inside the canvas (and
            having to then deal with event handling, etc). This will
            likely prove to be finicky, and more cumbersome than
            simply using an entirely canvas-based or entirely
            scenegraph-based approach.

            -- Jonathan


            On 5/08/2013 10:11 p.m., Felix Bembrick wrote:

                I am investigating the feasibility of developing a
                JavaFX 8 control based
                on Canvas.  I have chosen Canvas as the base class as
                this control is of a
                very dynamic nature and would not be easy to
                implement with a retained mode
                style ancestor (at least as far as I can tell).

                So is this feasible?  While I can readily see how to
                render the visual
                aspects of the control, I am not sure how to best
                "embed" other controls
                within it should that become necessary (and almost
                certainly will).

                For example, how would I go about embedding a Button
                within my control?  It
                looks to me like I would need to create an actual
                Button node somewhere
                else in the scenegraph and then perhaps render it
                within my control using
                gc.drawImage() passing in a snapshot of the Button
                node.  That's OK but
                then I have to somehow handle events and I am not
                sure how best to do that.

                Another issue I see is that there seems to be no way
                to apply effects to
                individual graphic elements within the Canvas as the
                applyEffect() method
                applies to the entire Canvas.

                Finally, a significant obstacle is this issue:

                https://javafx-jira.kenai.com/browse/RT-23822

                This issue relates to the lack of support for LCD
                font smoothing within
                Canvas.  This may not sound that serious but the
                difference between LCD
                font-smoothed text in other controls and the
                grey-scale text in Canvas is
                so distinct on my current machine that a control
                based on Canvas would
                really stick out like a sore thumb and appear
                significantly less appealing
                than a "standard" control.

                So, am I wasting my time?
                Are there any other issues I am likely to face?
                Are there other ways to develop dynamic controls
                which may involve
                thousands of nodes (such as lines, curves etc.)?

                Thanks,

                Felix







Reply via email to