Losing and Regaining Focus breaks rendering?

Hi there,

When using my app if a user moves on to another app and then come back in there is just a black screen. The interaction and audio is still there, also the draw function is still being called, but all there is to be seen is a black screen.

Any hints as to how to fix this?
Thanks!
Miles

Hello @Miles I’ve never experienced something similar on iOS.
I would try to make a simpler app and add functionalities to pinpoint what is actually triggering this.

ok, thanks yeah I’ll do that now and report back (hopefully with a solve and more information!)

It seems to be something to do with updating (redrawing to) FBOs after regaining focus. Even trying to just draw ontop of them all with some circles they’re not seen

Its been a while since I released an iOS app but I believe the OS can delete / clear GPU memory and textures if needed when losing focus.

I think you might need to cache the fbo contents during lost focus and re-allocate the fbo and restore the contents in got focus. You could do this with readToPixels and then save the contents to disk.

The functions in ofApp should provide those callbacks.

//--------------------------------------------------------------
void ofApp::lostFocus(){

}

//--------------------------------------------------------------
void ofApp::gotFocus(){

}

Hope that is helpful!
Theo

ah ok, that makes sense with what I’m seeing. I have setup a much simpler project and the FBOs etc have been working as expected, but its a much lighter program, so it might as you say be being released by the OS, and then not being reallocated (because I’m not currently reallocating on getting focus)

I’ve had a go at deallocating and then reallocating from the gotFocus function, but that hasn’t worked. The thing that is strange to me is that after regaining focus I can’t even see a circle that I’m drawing on the top of the draw stack outside of any FBO

@miles - oh that’s interesting. I wonder if the view is not getting restored correctly?
Do you see anything drawn after you regain focus?

It might be helpful to print out some debug messages like ofGetWidth() ofGetHeight() ofGetOrientation() etc and maybe some native iOS calls to get the view dimensions?

yeah it’s odd, there’s nothing being drawn, the update and draw calls are being called, and the touch events still work.

I printed ofGetWidth, Height, and Orientation and had the same values losing focus and regaining focus (2048 x 1536, orientation 4)

Hmm.
Can you do:

ofSetLogLevel(OF_LOG_VERBOSE);

in ofApp::setup

I wonder if the whole GL context is getting destroyed?

hmmmm no hints here either:

[verbose] ofFbo: GL frame buffer object supported
[verbose] ofFbo: GL frame buffer object supported
[verbose] ofFbo: GL frame buffer object supported
[verbose] ofFbo: FRAMEBUFFER_COMPLETE - OK

I need to start using log level stuff properly, I just end up using cout<< all the time and just uncommenting when I don’t need it anymore lol.

Hmm - @danoli3 any chance you have an idea what is going on?

@miles are you using 0.11.2?
Does this happen with any of the examples?

Yeah definitely need to re-generate the textures.

I set a flag on gotFocus() to regenerate on next update which seems to fix any context issues.

So basically:
void gotFocus() {
regenerateTexturesNextDraw = true;
}
bool ofApp::getRegenerateTexturesNextDraw() const {

return regenerateTexturesNextDraw;

}

void draw() {
if(getRegenerateTexturesNextDraw()) {
regenerateTexturesNow();
}
// Render!
render();
}

1 Like

I tried the solve from @danoli3 but that hasn’t changed anything. @theo have also had a go with a couple of examples and I’m not getting the issue. Very strange. I have implemented a swift share sheet in the app, I uncommented it’s usage to test if that was the problem, but I know that Xcode does some strange things with hidden bridge files or something. I don’t know if that’s potentially causing issues?

I’ve had another few goes at it, and still couldn’t get the solution @danoli3 set out to work.
I tried using .allocate before drawing to the FBOs again in the fashion set out above, however it still doesn’t work when it hits .begin().

@danoli3 When you say “regenerateTexturesNow()” is that effectively:

fbo.begin(); 
do stuff
fbo.end();

or is it

fbo.allocate(settings);

After some more digging, there’s a bit more info and context:
I have a small vector of FBOs that get redrawn every frame, these are then drawn to another FBO which is drawn alongside 2 others. So 3 “top level” FBOs. If I just update and draw the vector of FBOs without the “top level” FBOs it works fine, but when it hits the first .begin() of any of the “top level” FBOs ALL drawing stops.

If I use fbo.getTexture().bind() and fbo.getTexture().unbind() then drawing works again, but it has some really strange issues ie. the only FBO drawn is the previous one updated, regardless of whether or not that fbo’s draw function is called.

ok, so in an early attempt to sort out the hardware orientation issue I was having I uncommented this line in main:

settings.windowControllerType = ofxiOSWindowControllerType::GL_KIT; // Window Controller Type

Putting that back in solves the losing and regaining focus fbo issue, but then breaks my landscape orientation workaround. Slight bit of whack-a-mole over here!

The app is landscape only, so suffers from the issue of iOS orientation on startup:

I have been able to deal with the orientation issue - Landscape only on iPad issue - #8 by Miles

So, although the underlying issues still exist to a degree, using the above post, and the link above I now have an app which is landscape only and doesn’t have it’s FBOs messed up by losing and gaining focus.
This does however make the swift share sheet that I implemented rotated 90degrees, which takes me back to this issue: