This might be a tricky semantic to achieve, and great care will be
needed to ensure no deadlocks or race conditions. Not running any more
pulses after this method returns seems fine, but it might be better to
let any existing renderJobs run (possibly discarding the results). This
way you could send the pause message to the renderer as a special
renderJob and not have to worry about jobs that are scheduled but not
yet run.
-- Kevin
Johan Vos wrote:
After some experiments, here is my current thinking:
Toolkit can have 2 new methods:
pauseRenderer()
resumeRenderer()
When pauseRenderer is called, it should be guaranteed that after this call,
no new pulses are fired until resumeRenderer is called.
That is not hard, but it is not enough. Before we pause the pulses, the
previous pulse probably submitted a renderJob to Prism, executed on the
QuantumRenderer ThreadPoolExecutor. That job should run fine, as the next
pulse (when we're back) will call GlassScene.waitForRenderingToComplete().
So we have to wait until there are no running or pending tasks in the
QuantumRenderer as well.
- Johan
On Wed, Nov 18, 2015 at 9:58 PM, David Hill <david.h...@oracle.com> wrote:
On 11/18/15, 3:45 PM, Johan Vos wrote:
Johan,
I think that it would be reasonable to put in something to Quantum
that causes the render loop to "pause", and then resume later. I envision
this toggle as causing the render loop to skip, rather than tinkering with
the pulses.
When resume is called, it might be best to treat the world as dirty.
Added to Toolkit, this would allow someone like Monocle to make the
toggles as is appropriate.
If this works for you, perhaps you could prototype it ?
regards,
Dave
On Android, a JavaFX Application might transfer control to another app
(and
become invisible) and enter the foreground later. In that case, the
GLSurface we are rendering on becomes invalid. In order to avoid problems
and save battery, we want to pause the renderer thread, but this turns out
to be more difficult than I expected.
When our app transfers control, we get a callback from Android. We
intercept this in javafxports, and we set the Screen width/height to 0/0
as
we don't want to render on the (invalid) surface while we lost control.
When we regain control, we resize the Screen and the app renders again.
The reason we set the width/height to 0/0 is because the PresentingPainter
will call SceneState.isValid() and this returns false in case getWidth()
or
getHeight() are 0.
However, SceneState extends PresentableState and it overrides the update
method. It will call PresentatbleState.update() which will set the
viewWidth to the width of the new Screen (hence, 0) , but after that it
overwrites the viewWidth with camera.getViewWidth(). The latter still
contains the old value. A quick inspection shows that
camera.setViewWidth()
is called when validate(...) is called on NGDefaultCamera, which is called
by ES2Context.updateRenderTarget() which happens during rendering, hence
*after* the PresentingPainter checks if the width is 0.
So immediately after we set the width of the Screen to 0 (on the FX App
Thread), a Pulse happens, and this one still things the screen is the
original size. While the pulse is happening, the android system destroys
our context, and the rendering fails. Moreover, the EGL system is in a
unpredictable state (recreating the surface fails).
A very dirty workaround for this is to wait for 1 pulse (with the new
pulselistener API this should be possible) before we return from the
callback method called by Android when the surface is about to be
destroyed. That way, we will have 1 bogus rendering on an existing (but
about-to-be-destroyed) surface.
But it would be better if there is some way to tell the quantum renderer
to
immediately stop rendering. Existing pulses are no problem, as the
renderLock guarantuees that we set the size to 0 only when no other thread
(quantum renderer) has a lock on the renderLock.
- Johan
--
David Hill<david.h...@oracle.com>
Java Embedded Development
"A man's feet should be planted in his country, but his eyes should survey
the world."
-- George Santayana (1863 - 1952)