Discussion:
Internal scene graph redraw handling
Dr. Michael Paus
2015-09-08 18:14:23 UTC
Permalink
Hi,
I want to do some performance tuning of a JavaFX application of mine but
before
I can start with that I have to learn a little bit about the scene graph
redraw handling.
Maybe there is someone on this list who can help me there.

What I want to achieve is a super smooth animation (movement) of my
scene graph.
Let's assume the scene graph itself can be redrawn fast enough in less
than 1/60s.
In addition let's assume the scene graph contains a canvas which only
has to be
updated from time to time but an update of the canvas takes
substantially longer.
Let's say it takes 1s.

When an update of the canvas is in progress will this delay the next
pulse until all
internal drawing within the canvas is finished? From my observations I
think so.

If I submit my drawing calls to the canvas in smaller chunks via
Platform.runLater
calls will these also delay the next pulse or will the execution of
these calls be
delayed in favor of the scene graph update?

I hope my goal has become clear. I would like to be able to spread the
update of
the canvas over several scene graph redraw cycles so that an animation
of the
canvas stays smooth although the content builds up more slowly.

Michael
Jim Graham
2015-09-08 23:23:15 UTC
Permalink
I assume by "canvas" you mean "a Canvas Node"? I can only answer one of
your questions...
Post by Dr. Michael Paus
When an update of the canvas is in progress will this delay the next
pulse until all
internal drawing within the canvas is finished? From my observations I
think so.
All calls to the GraphicsContext of a Canvas will be executed on the
next rendering pass. The GraphicsContext methods place their information
in a command buffer and that command buffer is handed off to the
rendering thread the next time the Nodes are synchronized with the
rendering thread's view of the scene graph. At that time the rendering
thread will fully render all commands in a Canvas node's queue before it
renders that Canvas node to the scene. We don't have any support for
"render for only X ms" in the Canvas rendering so you'd have to break it
up yourself.

Also, as of one of the recent 8u releases, even nodes that are not
visible will be fully rendered on every rendering pass to avoid their
command queues growing uncontrollably if they scroll off the screen.
This is only true of Canvas nodes that are part of a scene that is being
rendered, though - an orphan canvas will just keep accumulating a
command queue and it won't be rendered until it is part of an active scene.

As such, the Canvas rendering commands don't "delay" the next pulse so
much as they make the next rendering pass take longer to do its work.

I have no further information to add about your questions about how to
use runLater to break up the rendering - someone else will have to chime
in on that, but in theory if you can break up your calls to
GraphicsContext over multiple rendering pulses then yes, you can
minimize the delay caused by having to flush all of the rendering calls...

...jim

Loading...