After updating a MacBook Pro (M1 Pro) from macOS 15.8 to the 15.8.2 release candidate (24H219), every OpenGL context that is attached to a window has no default framebuffer. NSOpenGLView and -[NSOpenGLContext setView:] are both affected, so anything drawn that way shows a blank window. I filed FB25133383 with a minimal sample, kernel log and call trace.
Symptoms
- kCGLCPHasDrawable is 0, glCheckFramebufferStatus(GL_FRAMEBUFFER) returns GL_FRAMEBUFFER_UNDEFINED (0x8219), and glClear raises GL_INVALID_FRAMEBUFFER_OPERATION (0x506).
- For every attach attempt the kernel logs:
(IOGPUFamily) IOGPUGLDrawableUserClient::set_surface(sIOGPUGLDrawableClientSetSurfaceData *): Invalid surface ID = N - CGLSetSurface returns kCGLBadDrawable (10005). Stepping through it, CGSBindSurface succeeds and the IOGPU user-client call then fails with kIOReturnBadArgument.
What still works
- Offscreen FBOs in the same context.
- CAOpenGLLayer and NSOpenGLLayer render correctly in the same process. Only the window-surface path is broken.
Minimal sample (public API only)
// clang -fobjc-arc -Wno-deprecated-declarations -framework Cocoa -framework OpenGL repro.m -o repro && ./repro
#define GL_SILENCE_DEPRECATION 1
#import <Cocoa/Cocoa.h>
#import <OpenGL/OpenGL.h>
#import <OpenGL/gl.h>
#import <OpenGL/glext.h>
@interface ReproView : NSOpenGLView
@end
@implementation ReproView
- (void)drawRect:(NSRect)dirtyRect {
NSOpenGLContext *ctx = [self openGLContext];
[ctx makeCurrentContext];
GLint hasDrawable = -1;
CGLGetParameter(ctx.CGLContextObj, kCGLCPHasDrawable, &hasDrawable);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
glClearColor(0, 1, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
GLenum err = glGetError();
printf("hasDrawable=%d status=0x%x glError=0x%x\n", hasDrawable, status, err);
fflush(stdout);
[ctx flushBuffer];
}
@end
int main(void) {
@autoreleasepool {
NSApplication *app = [NSApplication sharedApplication];
[app setActivationPolicy:NSApplicationActivationPolicyRegular];
NSWindow *win = [[NSWindow alloc] initWithContentRect:NSMakeRect(200, 300, 240, 240)
styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable
backing:NSBackingStoreBuffered defer:NO];
NSOpenGLPixelFormatAttribute attrs[] = { NSOpenGLPFADoubleBuffer, NSOpenGLPFAAccelerated, 0 };
NSOpenGLPixelFormat *pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
[win.contentView addSubview:[[ReproView alloc] initWithFrame:NSMakeRect(20, 20, 200, 200) pixelFormat:pf]];
[win makeKeyAndOrderFront:nil];
[app activateIgnoringOtherApps:YES];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ [app terminate:nil]; });
[app run];
}
return 0;
}
Expected: a green square and hasDrawable=1 status=0x8cd5 glError=0x0. On 24H219: nothing is drawn and it prints hasDrawable=0 status=0x8219 glError=0x506.
Scope
- Same result for arm64 and x86_64 under Rosetta, layer-backed or not, main thread or background thread.
- Affected on my Mac: Sony Imaging Edge Desktop Viewer (NSOpenGLView), DJI Studio (Qt 6, NSOpenGLContext) and its Quick Look extension.
- Public reports with the same symptom on 24H219: kitty #10645, Alacritty #9067, Godot #124311, Bambu Studio #12530 (all on GitHub). They cover M1, M4, M4 Pro and M4 Max, and the Alacritty report says 15.8.1 was fine.
Questions
- Is this a known issue in the 15.8.2 RC, and will it be fixed before 15.8.2 ships?
- Is anyone seeing it on the macOS 26.7.2 RC or the 27.2 beta?
Workaround for developers in the meantime: render into an IOSurface-backed FBO and present that surface in a CALayer, or use CAOpenGLLayer.