Dan, Thanks for the thoughts / questions, I've added them to the tail of the 
wiki for processing.

> 1) turning cache to true and cache hint to SPEED  I haven't seen explained 
> what the drawbacks are to doing this. I assume there is some trade-off for 
> turning this on otherwise it would be on by default?

Caching is the process of rendering a node (or a node & its children) into a 
texture, and then render from texture each time the node needs to be rendered. 
In cases where you set things up once and do a lot of subsequent rendering, 
this is a win. In cases where you have to reconstruct the texture (or draw to 
the texture) every time, this is a loss. There is some point in the curve where 
the cost savings is worth it.

So once you have a cached image, the question is, when do you need to 
reconstruct it? Clearly when the node or any of its children have changed 
visual appearance (such as the fill of a rectangle or the visual state of a 
button when pressed) then you need to regenerate it (if you didn't, then 
instead of using the cache property you would use an ImageView and 
renderToImage to create a static view of some nodes). But you also have to 
regenerate it as the node is scaled or rotated -- at least, you have to if you 
care about visual quality more than animation speed.

The cache hints tell us under what circumstances we can cheat on quality for 
the sake of performance. QUALITY says "never cheat". ROTATE says "cheat on 
rotations". SCALE says "cheat on scales". SCALE_AND_ROTATE can cheat on both 
and SPEED cheats on everything and everything it can think of to get good 
performance.

The one thing that will never be cheated on is if the visual state (such as the 
fill) has changed, then an image will be redrawn.

So as long as you have a scene graph which isn't changing much, you can cache 
it and animate it for better performance than if you just animate it. For 
simple things this shouldn't make any difference, but if rendering times are 
getting long, it is something to look at. Used incorrectly, it can make things 
worse -- much worse. On the JavaOne scheduler app we did last year for JavaOne 
we made things faster by turning off caching, because in our particular case 
the memory pressure and changes in the UI were making things worse by using 
caching rather than better.

> 2) AnimationTimer - how is this related to transitions (like 
> TransitionTimer). They seem to be two very different things - not just at the 
> usage level but the actual underlying performance and implementation - but 
> it's not clear to me exactly the difference. I wanted to work with both 
> AnimationTimer stuff and Transitions in a consistent way (e.g. pause one 
> thing to pause my whole app). When trying to use the API my instinct was that 
> the transitions used an underlying AnimationTimer, so I was looking for a way 
> to setAnimationTimer on the transitions, so they all shared the same 
> instance. I'm obviously seeing it wrong, but it's not clear to me why these 
> things are so different. 

I assume TransitionTimer is just Translation :-)

They are quite different. Timeline and Transition are both Animations. They are 
defined by having some parameters that define an animation, and then the 
ability to play, cycle, reverse, etc.

The AnimationTimer on the other hand is a timer that is called whenever the 
next step in an animation should occur. Games are typically written around a 
game loop, which is what the AnimationTimer is designed for. Whenever the 
AnimationTimer or an Animation is running, it causes us to process a pulse ever 
16.66ms (or as close as we can get). The only other time  a pulse happens is 
when the scene graph is made dirty.

Both are driven off the same essential timing mechanism -- we get a pulse, and 
the first step of the pulse is to run the animations (see QuantumToolkit.java 
around line 594, in the pulse(boolean collect) method). After the various 
animations run (and this part of the code is more convoluted than is needed any 
longer, having its history way back in 1.0 with the differences between SE and 
ME), then the pulse is sent to the stages & scenes where CSS, Layout, 
synchronization to the render tree, etc is performed.

AnimationTimer is "lighter weight" only in that there is no machinery to run -- 
it is just given a timestamp and that's it. The Timeline and Transition classes 
need to do a bunch of stuff on your behalf such as discover what KeyFrames to 
run, what KeyValues, pump the time into an Interpolator to get an interpolated 
time, etc etc. But fundamentally I have not yet seen any great overhead spent 
in the animation classes and would consider them perfectly safe for any usage 
-- iOS, embedded, or Desktop. They could probably be made evil but I have not 
seen such a thing yet.

> 3) If I have an app with multiple views (say 20 or 30) and I want to animate 
> between them (slide in, out, etc). Should I have all the views already added 
> to the scene and then just move them off-center (and/or make them invisible), 
> or should I add and remove them at the start and end of each animation. I'd 
> assumed that adding and removing was the way to go for performance, is this 
> correct? The question really is: If a node is in the scene graph but not 
> visible does it add much overhead to rendering, picking, etc? Doing something 
> like Mac's Mission Control would be much easier if I didn't have to 
> add/remove and could just zoom, but is this a bad idea from performance 
> perspective?

For the most part adding / removing from the scene is more expensive than 
toggling visibility, and toggling visibility is more expensive than setting 
opacity to 0. At least, that's what I determined a couple weeks ago but I could 
be wrong. And it depends on what is happening to the memory on your system. If 
you're hauling around 400MB of nodes you don't need to see, then things might 
be worse than creating them when needed. I'm not sure but my feeling is that 
these cases are going to be a lot of "it depends".

> 4) Is there much of a hit in building a view full of nodes and then throwing 
> them away and rebuilding on each showing of that view? In my apps (browser 
> style) I would build all the views on startup and then reuse these by loading 
> different data into them (e.g. the same instance was used for showing Person1 
> details as Person2, just loading different values into it). I thought this 
> would be the best from performance, but there was a comment from Richard a 
> while back that suggested it was perfectly ok/performant to throw away and 
> build the page again on each showing? This would be much easier from an 
> animation point of view as animating the transition 'back' or 'forward' 
> between two pages of the same view is problematic when you are reusing the 
> same view for both! 

We know we have a problem with Node creation time, but we don't know what it is 
yet. So for now probably reusing the same nodes (when reasonable, see above) is 
probably going to be better for you.

> 5) Is there much overhead to a view that it is in memory but not actually 
> added to the scene. i.e. if I do end up building a new instance of the view 
> for every "page load" (as per question 4), then it would be extra handy to 
> just keep those views in memory so when the back button is hit I don't have 
> to rebuild them. I assume the memory would build up pretty quickly if there 
> were large tables, images, videos, etc? How does a web browser manage to 
> cache all these pages in history and would the same approach be performant 
> for JFX?

There is no per-pulse overhead, as only Scenes and Stages get pulse 
notification. The nodes probably don't have peers (but they might in the future 
if they don't now in all scenarios -- wouldn't bet one way or the other). So 
from a memory perspective they're still there. But there is no layout, no CSS, 
no picking, etc.

Richard

Reply via email to