macOS 15.8.2의 예기치 못한 OpenGL 중단: 드라이버 변경 없이 창 렌더링이 백화된 이유

macOS 15.8.2의 예기치 못한 OpenGL 중단: 드라이버 변경 없이 창 렌더링이 백화된 이유

macOSOpenGLMetal그래픽 렌더링개발 도구

데이터 소스:HN + web research

2026년 10월 9일, 애플은 macOS 15.8.2의 테스트 빌드인 24H219를 배포했다. 이 정기 시스템 패치가 적용된 직후, 수많은 데스크톱 생산성 및 개발 도구들이 실행과 동시에 새하얀 빈 화면으로 변했다. 일반적인 충돌 대화상자조차 뜨지 않았다. 고도(Godot) 게임 엔진과 여러 터미널 에뮬레이터가 실행 순간 그래픽 출력을 완전히 상실했다.

최소 재현 코드를 실행해 보면 hasDrawable=0과 GL_FRAMEBUFFER_UNDEFINED가 출력되며, 저수준 파이프라인의 물리적 연결이 끊어졌음을 보여주었다. 이 사고는 기존의 단계적 지원 중단 일정을 흔들어 놓았다. 8년에 걸쳐 유지되던 완충 기간이 정기 유지보수 업데이트 한 번으로 사실상의 인터페이스 차단으로 이어진 것이다.

창이 일제히 백화되며 멈춰 선 생산성 도구들

2026년 10월 9일, 개발자 tobycroft는 깃허브의 Godot 엔진 저장소에 124311번 이슈를 등록했다. 시스템을 15.8.2의 24H219로 업데이트한 뒤, 안정화 버전과 개발 버전을 불문하고 Godot 프로젝트 관리자가 실행 즉시 순백색 창만 띄운다는 내용이었다. Application Support 캐시 디렉터리를 비우고 실행 파일을 새로 내려받아도 창은 여전히 하얗게 굳어 있었다.

엔진 백엔드의 동작은 겉모습과 확연히 대조되었다. 터미널에서 Godot을 실행하면 초기화 로그는 막힘없이 출력되었다. 에디터 설정과 테마가 정상적으로 로드되었고, Metal 역시 M1 Pro 칩을 올바르게 인식했다. 프런트엔드의 창 렌더링은 완전히 멈췄지만, 백엔드의 실행 로직과 하드웨어 연결은 아무런 손상 없이 작동하고 있었던 것이다.

Godot 프로젝트 관리자 백화 현상 재현 화면 그림: 15.8.2 환경에서 Godot 프로젝트 관리자가 하얗게 변하는 현상. 출처: godotengine/godot 이슈 124311

이 문제는 특정 엔진 하나에 국한된 단발성 오류가 아니었다. 이후 며칠 동안 여러 핵심 도구 저장소에서 동일한 문제가 잇따라 터져 나왔다. GPU 가속 터미널인 kitty는 창 내부가 회백색으로 변했고, Alacritty 0.17 버전의 창 역시 텅 빈 채 출력되었다. 3D 프린팅 슬라이서 도구인 Bambu Studio 2.8.2.61의 제어판과 도구 모음은 M4 맥 미니에서 전혀 표시되지 않았다. 상용 프로그램도 예외가 아니었다. 소니의 Imaging Edge Desktop Viewer와 DJI의 DJI Studio에서도 메인 창이나 미리보기 플러그인이 검게 변하는 현상이 나타났다. 영향을 받은 기기는 M1부터 최신 M4, M4 Pro, M4 Max까지 전 라인업에 걸쳐 있었다.

드라이버 버전은 그대로인데, 커널 호출 체인이 끊어졌다

일반적으로 대규모 창 렌더링 실패는 그래픽 스택의 대대적인 개편을 의미한다. 하지만 15.8.2 업데이트 패키지에서 핵심 그래픽 구성 요소 버전은 그대로 유지되었다. IOGPUFamily는 104.6.6을 유지했고, AGXG13X 드라이버 버전은 여전히 329.2였으며, IOSurface도 372.5.4를 가리키고 있었다. 2026년 10월 14일에 배포된 24H225(RC 2) 빌드에서도 이 버전들은 전혀 바뀌지 않았다. 시스템 내부에서 달라진 것은 오직 커널 빌드 번호뿐이었다.

구성 요소 버전은 동일했지만, 시스템이 애플리케이션에 전달하는 하드웨어 인터페이스 상태는 완전히 딴판이었다. 정상적인 macOS 15.8.1 환경에서 최소 재현 코드를 실행하면 컨텍스트 질의는 hasDrawable=1 status=0x8cd5 glError=0x0을 반환했다. 반면 24H219 및 24H225 환경에서는 동일한 바이너리가 hasDrawable=0 status=0x8219 glError=0x506이라는 비정상적인 값을 뱉어냈다.

상태 코드는 파이프라인이 끊어진 구체적인 위치를 가리키고 있었다. status=0x8219는 OpenGL 규격의 GL_FRAMEBUFFER_UNDEFINED에 해당하며 기본 프레임버퍼가 존재하지 않음을 뜻한다. glError=0x506은 GL_INVALID_FRAMEBUFFER_OPERATION으로, 해당 버퍼에 픽셀을 기록하려는 작업이 그래픽 드라이버에 의해 즉시 거부된다는 의미다.

시스템 저수준 로그를 살펴보면 세부적인 연결 단절 과정이 확연히 드러난다. 상위의 CGSBindSurface는 정상적으로 호출되었지만, 이어지는 IOGPU 클라이언트 인터페이스에서 kIOReturnBadArgument를 반환했다. 커널 로그의 IOGPUGLDrawableUserClient::set_surface에 Invalid surface ID가 기록되면서 CGLSetSurface 호출이 실패하고 kCGLBadDrawable(오류 코드 10005)이 발생했다. 드라이버 자체의 그래픽 렌더링 능력에는 문제가 없었다. 결함은 WindowServer가 커널로 서피스 핸들을 전달하고 검증하는 과정에서 발생했다.

오프스크린 렌더링은 정상, 창 표면만 프레임버퍼 상실

이번 조사의 가장 두드러진 특징은 장애가 매우 선택적으로 나타났다는 점이다. 애플리케이션이 렌더링 대상을 오프스크린 FBO로 돌리거나 CAOpenGLLayer 계층을 사용하면 GPU는 정상적으로 텍스처를 출력했다. 파이프라인 손상은 네이티브 데스크톱 창에 직접 연결되는 단일 경로에 철저히 국한되어 있었다.

NSOpenGLView를 사용하든 명시적으로 -[NSOpenGLContext setView:]를 호출하든, 시스템이 창에 하드웨어 서피스를 할당하는 단계에서 실패했다. 테스트 결과 이 문제는 아키텍처를 가리지 않고 발생했다. 애플 실리콘 네이티브 arm64 바이너리와 로제타(Rosetta)로 구동되는 x86_64 바이너리가 완전히 동일한 증상을 보였다. 레이어 지원 옵션이나 메인 스레드, 보조 스레드 여부와 관계없이 테스트 결과는 한결같이 kCGLCPHasDrawable 0으로 고정되었다.

kitty 터미널 빈 화면 재현 화면 그림: 15.8.2 환경에서 kitty 터미널 창 내용이 비어 있는 현상. 출처: kovidgoyal/kitty 이슈 10645

기본 프레임버퍼가 누락되었기 때문에 터미널이 보내는 화면 지우기(glClear) 명령은 드라이버 진입 단계에서 차단되었다. 터미널 내부 이벤트 루프는 키 입력을 정상적으로 수신하고 문자 버퍼를 제때 갱신했다. 하지만 최종적으로 화면에 프레임을 전달할 때 가용한 서피스를 찾지 못해 모든 픽셀이 드라이버 입구에서 버려졌다. 화면이 하얗게 멈춘 것은 애플리케이션 프리징이 아니었다. 그리기 명령이 화면에 도달하는 마지막 관문에서 차단된 것이다.

검사 항목 및 호출 경로정상 환경 (15.8.1 / 27.0.1)오류 발생 환경 (15.8.2 24H219/225)기술적 진단 및 영향
창 컨텍스트 버퍼 플래그kCGLCPHasDrawable 값 1 반환kCGLCPHasDrawable 값 0 반환창이 유효한 기본 프레임버퍼를 얻지 못함
프레임버퍼 상태 질의0x8CD5 정상 완료0x8219 상태 미정의창에 연결된 기본 FBO가 정의되지 않음
화면 지우기 glClear 작업오류 코드 없이 0x0 반환0x506 유효하지 않은 작업 발생그리기 호출이 모두 실패해 창이 백화 상태 유지
오프스크린 렌더링 및 FBO정상 래스터화 및 텍스처 출력정상 래스터화 및 텍스처 출력하드웨어 렌더링은 정상이므로 드라이버 자체 결함 아님
CAOpenGLLayer 계층 경로정상 렌더링 및 합성정상 렌더링 및 합성CoreAnimation 계층 합성 파이프라인은 영향 없음
창 바인딩 호출 체인CGSBindSurface 정상 연결set_surface에서 유효하지 않은 핸들 보고커널이 창 서피스 핸들 검증 시 매개변수 거부

8년의 지원 중단 완충기, 패치 테스트 사각지대를 드러내다

이번 장애는 기술 커뮤니티 내에서 플랫폼 유지보수 책임에 관한 논쟁을 촉발했다. 애플은 이미 2018년 macOS 10.14 모하비(Mojave)에서 OpenGL 사용 중단(Deprecation)을 공식 선언했다. 공식 문서는 Metal을 그래픽 프로그래밍의 유일한 권장 표준으로 제시해 왔다. 운영체제 벤더 입장에서는 레거시 호환 계층을 유지하는 데 지속적인 비용이 들며, 8년이라는 긴 기간은 생태계에 충분한 전환 여유를 제공했다고 볼 수 있다.

반면 하위 애플리케이션 개발자들이 마주한 현실은 다르다. 크로스 플랫폼 프로젝트의 경우, 단일 운영체제만을 위해 렌더링 백엔드를 전면 재작성하는 것은 막대한 엔지니어링 리소스가 소모된다. 다수의 개발자들은 소수점 유지보수 패치가 인터페이스 안정성을 유지해 줄 것이라 기대한다. 돌발적인 인터페이스 단절은 기존의 소프트웨어 개발 및 유지보수 계획을 흔들어 놓았다.

Godot 엔진의 내부 구조는 이러한 크로스 플랫폼 소프트웨어의 전환 딜레마를 잘 보여준다. Godot은 게임 프로젝트 런타임 렌더러를 일찌감치 Metal로 전환했다. 그러나 개발자용 에디터 및 프로젝트 관리자 화면은 가볍고 빠른 실행을 위해 가벼운 OpenGL을 기본값으로 유지해 왔다. 기여자 bruvzg는 프로젝트 관리자 역시 진작 Metal로 넘어갔어야 했다고 인정하면서도, 지금까지 OpenGL을 유지했던 것은 최초 실행 시 셰이더 컴파일 지연을 피하기 위해서였다고 설명했다.

이번 사건은 운영체제 유지보수 시스템의 테스트 커버리지 허점을 여실히 드러냈다. macOS 15.8.2는 일반적인 정기 유지보수 패치에 불과하다. 그럼에도 기반 그래픽 파이프라인의 핵심 호출에서 치명적인 회귀 버그가 발생했다. 아무리 8년 전에 지원 중단된 API라 할지라도, SDK 내에 남아 있는 한 테스트 사각지대는 전체 개발 생태계에 큰 비용을 초래한다.

임시 우회책과 마주한 그래픽 스택 세대교체의 종착점

갑작스러운 백화 현상 앞에서 오픈소스 커뮤니티는 기민하게 임시 해결책을 내놓았다. Godot 기여자들은 토론을 통해 실행 매개변수를 제시했다. 실행 시 --rendering-driver metal 또는 --rendering-driver opengl3_angle 드라이버 옵션을 전달하면 고장 난 네이티브 창 바인딩 경로를 우회할 수 있다. Alacritty 사용자들 역시 ANGLE 변환 계층 기반의 커뮤니티 포크 빌드를 적용해 정상 작동을 복구했다.

소스 코드를 직접 관리하는 팀에게는 렌더링 대상을 창 서피스에서 분리하는 것이 정석적인 대응이다. 오프스크린 버퍼에서 래스터화를 거친 뒤 텍스처를 CALayer로 넘기거나, CAOpenGLLayer를 활용해 파이프라인을 전면 수정하지 않고도 실패하는 커널 호출을 우회할 수 있다.

가상 머신 환경에서의 테스트 결과도 단서를 제공했다. 가상 환경의 macOS 15.8.1에서는 이 문제가 재현되지 않았으며, 최신 macOS 27.0.1 프리뷰 시스템에서도 창 수준의 OpenGL 코드는 정상 작동했다. 오류가 단일 패치 브랜치에만 고립되어 있다는 사실은, 이것이 계획된 인터페이스 제거가 아니라 코드 병합 과정에서 발생한 회귀 버그임을 뒷받침한다.

임시 매개변수는 당장의 급한 불을 끌 수는 있지만 기술 플랫폼의 세대교체를 막을 수는 없다. 정기 패치 한 번으로 레거시 인터페이스가 언제든 차단될 수 있는 상황에서, macOS 상의 OpenGL에 남아 있는 허용 오차는 한계에 도달했다. 생산성 도구 개발팀에게 최신 그래픽 인터페이스로의 전환 완료는 이제 선택이 아닌 생존의 필수 과제가 되었다.

참고 링크:

  • braindetox 기술 분석
  • Godot 이슈 124311
  • 애플 개발자 포럼 피드백 스레드
  • SiTech 보도