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.
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)
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
- wglCreateContext failed
- No function was found with the name {proc}.
- PInvoke.RegisterClassEx failed: {Win32Helper.GetErrorMessage
- PInvoke.CreateWindowEx failed: {Win32Helper.GetErrorMessage(
AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13).
Data as JSON: /api/errors/24c5de7629907ba5.
Report an issue: GitHub.