Crash on switching to fullscreen in GL

Problems building or running the engine, queries about how to use features etc.
Post Reply
User avatar
Mako_energy
Greenskin
Posts: 125
Joined: Mon Feb 22, 2010 7:48 pm
x 9

Crash on switching to fullscreen in GL

Post by Mako_energy »

As the title suggests I have an app that is crashing when it goes into fullscreen, but not resolution change. I have an SDL/Ogre setup so I am using an external context and calling Root::renderOneFrame() every frame. There are no error reports of any kind, in the log or otherwise. It simply crashes to desktop as if it wasn't even there in the first place. I also cannot debug this or get a callstack because if I try to fullscreen this while in debug, my monitor will go black and say it's not in a supported resolution, even when I have it set to it's optimal resolution. It gets stuck like that and I have to reboot.

I also have another app that is using mostly the same code base, one big difference being that there are no objects in the scene and it doesn't crash, although the textures for the UI go missing, which may be related to this. The textures only go missing when switching to fullscreen, not on a resolution change.

It really seems to me that I am somehow bypassing a check of something being ready by calling Root::renderOneFrame(), which is causing it to segfault. I've read mixed things regarding the need to reload resources ranging from only needing to do it in D3D(due to device being lost, which doesn't happen in GL as I understand it), to ogre managing all of that automatically. Is this something that could be going wrong in my situation?

I'm using the Ogre 1.7.2 SDK for MinGW. Any insights would be greatly appreciated.

Edit: Small update, I got my hands on another monitor and tried debugging with it. However when the crash occurs my desktop freezes(On WinXP) and I can't view the callstack. This persists until I kill gdb, which kills the info I need. I did however get to see that the program threw a SegFault, SIGSEGV to be specific. I had already assumed from how it was crashing that it was a segfault, but good to have confirmation I guess. I've pretty much hit a brick wall with this one. Once again insights would be very helpful.
Last edited by Mako_energy on Wed Feb 02, 2011 5:20 am, edited 3 times in total.
User avatar
Mako_energy
Greenskin
Posts: 125
Joined: Mon Feb 22, 2010 7:48 pm
x 9

Re: Crash on switching to fullscreen in GL

Post by Mako_energy »

Another update. I managed to get around to testing the linux side of both app's in Ubuntu 11.04. In the first app that was crashing in windows on fullscreen: it will fullscreen and back in linux without crashing. Only noticeable effect is that it seems to cause a small hit to the frame rate, but I don't necessarily think that is ogre's fault. In the second app with the empty scene we can switch back and forth between fullscreen without losing the textures for the UI.

In both app's however, in linux, if I try to resize to anything above the initial size(800x600) in windowed or fullscreen, it will cause artifacts in the extra area of the canvas. The original area will appear unaltered, but will anchor to the bottom left corner of the screen or window. (hope that made sense, if not I can try to post screenshots)

So it seems I've found two annoying platform specific issues. I still have no concept of how to resolve this. Once again, any insights are appreciated.
Last edited by Mako_energy on Wed Feb 02, 2011 5:19 am, edited 1 time in total.
User avatar
Mako_energy
Greenskin
Posts: 125
Joined: Mon Feb 22, 2010 7:48 pm
x 9

Re: Crash on switching to fullscreen in GL

Post by Mako_energy »

Ok, did some more testing. Hopefully this new info will narrow down the possibilities enough to get some insights.

I looked more at the SDL side, since it is creating and controlling the context Ogre is using. When toggling fullscreen I have to call SDL_SetVideoMode (using SDL 1.2.13), using this forces SDL to reset the current context. This doesn't happen in linux specifically, which is why linux doesn't suffer from this crashing issue. Knowing that I tried to see what resources I may need to reload, textures being the obvious one, so I called reloadAll() on the texture manager and all the textures for my UI re-appeared. The app with the empty scene runs fine now, but the crash still persists on my first app (which has a scene populated with a bunch of Ogre Example Robots). Adding one such robot to the app with the empty scene causes it to crash(they share the same engine code). I thought I would try to refresh as much as I could, so I tried calling reloadAll() on the mesh manager, material manager, and skeleton manager...but this didn't have any effect.

Also, I know this doesn't narrow it down much, but I tried calling RenderWindow->update() directly to see if I could eliminate any of the extra code that is called between Root->renderOneFrame() and that, and it still crashed.

That said, I know my current context is being reset and I can and have reloaded textures, but don't know what else to reset. What else needs to be renewed/reset/recreated when the current GL context is reset? Everything seems to point to the context reset invalidating something Ogre needs.
User avatar
Mako_energy
Greenskin
Posts: 125
Joined: Mon Feb 22, 2010 7:48 pm
x 9

Re: Crash on switching to fullscreen in GL

Post by Mako_energy »

Another update, getting pretty desperate for answers now. Since my last post, I stumbled upon Entity::_initialise(). Calling this with (true) along with destroying the render window and re-creating it fixes the crashing. However, after doing so Ogre renders artifacts and it seems some of the materials are either assigned to the wrong entities or simply don't work. In the case of the Ogre Example robots, they are just a flat grey colour. Some sphere shaped entities that are supposed to have one of two textures all share the same texture. Furthermore, if I try to exit out of fullscreen after all of this, the app still crashes. Survives going into, but not coming out of fullscreen.

In an effort to try and prevent losing all of these resources, I looked into setting up resource sharing between the SDL context, and the context that is documented as being created here, mentioned in the list of possible additional params. I looked through the source files used by the GL render system on Win32 to check if resource sharing is already implemented there, as that would be easier then attempting to include OpenGL libraries in my app and trying to manage my own 3rd context.

In lines 152 to 157 of OgreWin32Window.cpp, it obviously is grabbing the external context and assigning it to it's own private render context member:

Code: Select all

if ((opt = miscParams->find("externalGLContext")) != end)
		{
			mGlrc = (HGLRC)StringConverter::parseUnsignedLong(opt->second);
			if( mGlrc )
				mIsExternalGLContext = true;
		}
In lines 357 and 358 of OgreWin32Window.cpp, it grabs the old context to be shared later:

Code: Select all

HDC old_hdc = wglGetCurrentDC();
	HGLRC old_context = wglGetCurrentContext();
And lastly in lines 431 to 440 of OgreWin32Window.cpp it attempts to share the contexts if it found an old context:

Code: Select all

if (old_context && old_context != mGlrc)
       {
           // Restore old context
		   if (!wglMakeCurrent(old_hdc, old_context))
			   OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglMakeCurrent() failed", "Win32Window::create");

           // Share lists with old context
		   if (!wglShareLists(old_context, mGlrc))
			   OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglShareLists() failed", " Win32Window::create");
       }
I apologize if posting unaltered ogre source code is redundant, just wanted to make sure people that aren't familiar with the code as much are brought up to speed as much as possible. Moving on, the issue with this is that I've followed each line that is called in ogre from the initialization of root, to the creation of our custom game window(not the autowindow), and no where is a GL context created for the "old_context" variable to be valid. So nothing is shared. Immediately after these checks though it does create an instance of Win32Context, but in it it doesn't create an additional GL context at all. Even if it did there are no calls to allow sharing by that point.

Have I missed something? Is there a problem where I can't/shouldn't change when the ogre context is initialized? Is there an easier way to restore the data tied to the GL context then what I am attempting?
Post Reply