Pausing Quantum Renderer

Jim Graham james.graham at oracle.com
Thu Nov 19 01:21:16 UTC 2015


And, even if it isn't, shouldn't we have a concept of "you can't draw 
right now, just go away and we'll tell you when it's available again" 
built into the Presentable API?  You shouldn't have to set the 
dimensions to 0,0 to mean "I'm not here right now"...

			...jim

On 11/18/15 5:02 PM, Alexander Kouznetsov wrote:
> 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