unoplatform/uno · critical · InvalidOperationException
SetPixelFormat failed
Error message
SetPixelFormat failed
What it means
Immediately after ChoosePixelFormat succeeds, the wrapper calls SetPixelFormat(hdc, pixelFormat, &pfd); it returns 0 on failure and the wrapper throws InvalidOperationException. On Windows, SetPixelFormat can only succeed once per HDC — a second attempt on a DC whose pixel format is already set will fail. It can also fail if the pixel format index is invalid for the DC or the DC is invalid.
Solutions
- Reuse the existing pixel format if the DC already has one (call DescribePixelFormat to check) instead of calling SetPixelFormat again.
- Create a fresh HDC/HWND for a new GL context rather than reusing one whose pixel format is locked.
- Ensure the same HDC is passed to ChoosePixelFormat and SetPixelFormat.
Defensive patterns
Strategy: validation
Validate before calling
// A DC's pixel format can be set only once
if (WindowsRenderingNativeMethods.DescribePixelFormat(_hdc, 1, 0, ref default) == 0) { /* ok to set */ } Prevention
- Never call SetPixelFormat twice on the same HDC.
- Allocate a fresh HDC/HWND for each new GL context.
- Pass the exact HDC used for ChoosePixelFormat.
When it happens
Trigger: SetPixelFormat called twice on the same HDC (e.g. GLCanvasElement re-initializing its context after a recreate); the HDC differs from the one passed to ChoosePixelFormat; the chosen index is out of range for the DC.
Common situations: Window/context re-creation reusing a DC whose pixel format was already set; multiple GL hosts sharing a window's DC; reinitializing the GL wrapper after a device-loss event.
Related errors
- ChoosePixelFormat failed
- No function was found with the name
- wglCreateContext failed
- ClientWaitSync failed
- Couldn't find a field named _libraries in GLibrary
AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13).
Data as JSON: /api/errors/24c5de7629907ba5.
Report an issue: GitHub.
Appendix: source
Thrown at src/AddIns/Uno.WinUI.Graphics3DGL/Windows/WinUINativeOpenGLWrapper.cs:68
pfd.cAlphaBits = 8;
pfd.cDepthBits = 16;
pfd.cStencilBits = 1; // anything > 0 is fine, we will most likely get 8
pfd.iLayerType = WindowsRenderingNativeMethods.PFD_MAIN_PLANE;
var pixelFormat = WindowsRenderingNativeMethods.ChoosePixelFormat(_hdc, ref pfd);
// To inspect the chosen pixel format:
// WindowsRenderingNativeMethods.PIXELFORMATDESCRIPTOR temp_pfd = default;
// WindowsRenderingNativeMethods.DescribePixelFormat(_hdc, _pixelFormat, (uint)Marshal.SizeOf<WindowsRenderingNativeMethods.PIXELFORMATDESCRIPTOR>(), ref temp_pfd);
if (pixelFormat == 0)
{
throw new InvalidOperationException("ChoosePixelFormat failed");
}
if (WindowsRenderingNativeMethods.SetPixelFormat(_hdc, pixelFormat, ref pfd) == 0)
{
throw new InvalidOperationException("SetPixelFormat failed");
}
_glContext = WindowsRenderingNativeMethods.wglCreateContext(_hdc);
if (_glContext == IntPtr.Zero)
{
throw new InvalidOperationException("wglCreateContext failed");
}
}
// https://sharovarskyi.com/blog/posts/csharp-win32-opengl-silknet/
public bool TryGetProcAddress(string proc, out nint addr)
{
if (_opengl32.Value != IntPtr.Zero && NativeLibrary.TryGetExport(_opengl32.Value, proc, out addr))
{
return true;
}
View on GitHub (pinned to 0418340488)