Pausing Quantum Renderer

Alexander Kouznetsov alexander.kouznetsov at oracle.com
Thu Nov 19 01:02:12 UTC 2015


Shouldn't this be an equivalent of minimizing the window?

Best regards,
Alexander Kouznetsov
(408) 276-0387

On 18 ноя 2015 12:45, Johan Vos wrote:
> Hi,
>
> 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



More information about the openjfx-dev mailing list