On 7/26/13 Jul 26, 1:22 AM, Richard Bair wrote:

As for multiple scenes, I'm actually curious how this happens today. If I have 
2 scenes, and we have just a single render thread servicing both, then when I 
go to present, it blocks? Or is there a non-blocking present method that we use 
instead? Because if we block, then having 2 scenes would cut you down to 30fps 
maximum, wouldn't it? If we are non-blocking today (is that possible?) then the 
only way this proposed solution would work is if there was a different render 
thread per stage (which actually is something I think we ought to be doing 
anyway?).

Currently we block/lock rendering using
    AbstractPainter.renderLock
so you can take a 'uses' to see where it is used.

In general though, we use PaintCollector to stage render jobs in a pulse - one 
per dirty Scene. This operation is on the user event thread, and is blocked by 
any pending render tasks (in effect it waits for a current pulse to complete).
The PaintCollector uses window state", similar to a shadow scene graph, so that 
the render operation is using state that is consistent (this is done using 
SceneState)

Each render task (scene) is executed separately on the render thread, and takes 
the renderLock while it is doing its thing. This means that there is an 
unlocked state between queued rendered scene tasks.

Rendering tends to be done via either PresentingPainter (accelerated) or 
UploadingPainter (sw).

The above is the simplified view - and shows that user event thread can be 
happily running along doing stuff while the render thread is doing its thing - 
at least until it is blocked by needed to push another render pulse.

But... it is a touch more complicated than that, as we found that there are a number of user event 
thread operations that really can't be happening when we have a render operation going. These are 
mostly related to "window operations", like resizing or closing a window. Changing a 
windows state while rendering to it causes "unpredictable" results on many platforms. 
Because of this, there are a number of operations where we take the renderLock before calling from 
Quantum into glass. A sampling of these cases are WindowStage setScene, setVisible, close. The idea 
is that Glass should be treated as single threaded.

Note that embedded arm behaves a touch different - because we have a single  GL graphics context 
and no "real" windows - we always paint every stage/scene from back to front. In effect, 
we are the compositor of the screen as we are the "window manage". This is pretty obvious 
in the PaintCollector class. Given that we have a single graphics context - there is no way we 
would want one render thread per scene there.


Another note - the addition of SceneState solved a problem, one that was easily 
seen with HelloWindowAbuse, which created/resized/closed windows at a frantic 
pace. There was some discussion at the time that we might have been able to 
save less state in SceneState because we already have that data in other 
places, like the SceneGraph. SceneState was a compromise solution that provided 
the quickest fix for the least amount of code reconstruction, which of course 
means that there is likely room for improvement.

So, that is my view of the elephant 
<https://en.wikipedia.org/wiki/Blind_men_and_an_elephant>, and I am sure that 
others will have a different take :-)






--
David Hill <david.h...@oracle.com>
Java Embedded Development

Education: that which reveals to the wise, and conceals from the stupid, the 
vast limits of their knowledge.
-- Mark Twain

Reply via email to