Exception when switching window from fullscreen to windowed mode
Release Type: Official Release
Version: 4.1.0.1734
Platform: Windows
Describe the bug Exception during switching to windowed mode.
To Reproduce Steps to reproduce the behavior:
- Create a new game project using default settings
- Add a SyncScript asset with the following code:
using Stride.Engine;
using Stride.Input;
public class FullScreenToggler : SyncScript
{
public override void Update()
{
if (Input.Keyboard.IsKeyDown(Keys.F))
{
Game.Window.IsFullscreen = !Game.Window.IsFullscreen;
}
}
}
- Add a ScriptComponent with the script from step 2 to the Camera (or any other) entity.
- Run the game using F5 hotkey (or in any other way).
- Toggle fullscreen mode using the "F" or "Alt+Enter" hotkey.
- Toggle windowed mode using exactly "F" hotkey (handled by the script from step 2).
Expected behavior Game window is switched to windowed mode like it was before step 5 execution.
Screenshots

Log and callstacks
- ReproducingExceptionInfo.txt ReproducingAfterExceptionConsole.log - console log after you click on continue button (see screenshot above).
- RealProjectExceptionInfo.txt
Additional context
- Using the "Alt+Enter" hotkey in step 6 (for switching back from fullscreen mode to windowed) works as expected.
- Even an empty scene with the only empty entity on it which has the ScriptComponent with the script from step 2 works as described.
- There are also similar issues, but they all belongs to a different kind of exception.
Since "Alt+Enter" is working as expected this may not be a big issue, but there is a common practice to add a fullscreen toggler in game video options and it won't work there.
I'll try to repro this later, but the exceptions you're showing are related to serialization which should have nothing to do with changing window mode, which either should be very worrying or there's something else going on here.
I'm not so sure if related, but I get a very similar exception when I try to change window size while in fullscreen mode (different asset but same serializer can't be found).
Ok, so I was able to repro this easily. Basically whenever things change for the GraphicsDevice such that it has to recreate everything it calls ResumeManager.OnReload which invokes reloading of all visual assets.
The exception message is thrown in the Reload callback of TextureContentSerializer L45, which performs a Load<Image> on the asset associated to the graphicsResource, but that graphics resource is of type Texture, which causes ContentManager to fail to retrieve it from cache of loaded objects and then try to deserialize it from the raw data, which fails again because there's no serializer compatible for a Texture that would return an Image.
While the underlying serialized data of a texture can be deserialized as an Image it seems that the way Reload callbacks are set up isn't taking all the details into account and would require deeper investigation to understand why this is happening.
The other issue is why this full reload happens in the first place. Looks like there may be an exception thrown during resizing from FullScreen in GraphicsDeviceManager.ChangeOrCreateDevice L1053.
(Error 0x80004005 is a type of unspecified Windows error code)
External component has thrown an exception.
at System.Runtime.InteropServices.Marshal.Release(IntPtr pUnk)
at SharpDX.ComObject.SharpDX.IUnknown.Release()
at SharpDX.ComObject.Dispose(Boolean disposing)
at SharpDX.DisposeBase.CheckAndDispose(Boolean disposing)
at Stride.Graphics.SwapChainGraphicsPresenter.OnDestroyed() in C:\stride\sources\engine\Stride.Graphics\Direct3D\SwapChainGraphicsPresenter.Direct3D.cs:line 184
at Stride.Graphics.SwapChainGraphicsPresenter.set_IsFullScreen(Boolean value) in C:\stride\sources\engine\Stride.Graphics\Direct3D\SwapChainGraphicsPresenter.Direct3D.cs:line 116
at Stride.Games.GraphicsDeviceManager.ChangeOrCreateDevice(Boolean forceCreate) in C:\stride\sources\engine\Stride.Games\GraphicsDeviceManager.cs:line 1053
@manio143 , thanks for a quick feedback. I wonder if the Alt+Enter hotkey uses a different code, because it causes no exceptions. If so, is this the expected behavior?
I was able to trace the Alt+Enter behavior to GameForm.cs and seems to be doing the exactly same thing, except in a different moment in the game loop (before calling any of the game's systems, it happens in WindowsMessageLoop that process OS messages before calling Game.Tick() to process another frame) - this may be a better moment to modify the graphics device, but I'm not fully sure why.
It'll work if you try it like this.
if (Input.Keyboard.IsKeyDown(Keys.E))
{
if (Game.Window.IsFullscreen)
{
Game.Window.Visible = false;
Game.Window.IsFullscreen = false;
Game.Window.Visible = true;
}
else
{
Game.Window.SetSize(new Int2(1920, 1080));
Game.Window.PreferredFullscreenSize = new Int2(1920, 1080);
Game.Window.IsFullscreen = true;
}
}
It'll work if you try it like this.
if (Input.Keyboard.IsKeyDown(Keys.E)) { if (Game.Window.IsFullscreen) { Game.Window.Visible = false; Game.Window.IsFullscreen = false; Game.Window.Visible = true; } else { Game.Window.SetSize(new Int2(1920, 1080)); Game.Window.PreferredFullscreenSize = new Int2(1920, 1080); Game.Window.IsFullscreen = true; } }
That's a nice workaround, tested it myself and it works like a charm. I'll leave one more note here: when changing resolution in fullscreen, these two ways worked for me:
// First way. I prefer this one because it causes less flickering
Game.Window.Visible = false;
Game.Window.SetSize(resolution);
Game.Window.PreferredFullscreenSize = resolution;
Game.Window.IsFullscreen = true;
Game.Window.Visible = true;
// Second way (switching to windowed and back to fullscreen)
gameSettings.Window.Visible = false;
gameSettings.Window.IsFullscreen = false;
gameSettings.Window.Visible = true;
gameSettings.Window.SetSize(resolution);
gameSettings.Window.PreferredFullscreenSize = resolution;
gameSettings.Window.IsFullscreen = true;