Lazy Video Viewport Observer: GPU Layer Teardown for Off-Screen Videos
Source/WebCore/html/HTMLVideoElement.cpp
이 commit에서는 LazyLoadVideoObserver와 ViewportVisibility enum이 새로 도입되었습니다. 두 요소는 video 요소가 viewport와 교차하는지를 추적하는 데 쓰입니다. visibility가 NotVisible로 전환되면 AVFoundation 기반 player의 compositor layer가 해제되고, 요소가 다시 화면 안으로 들어오면 layer가 재생성됩니다. 전반적으로 기존의 LazyLoadImageObserver/LazyLoadFrameObserver 패턴을 답습한 설계입니다.
HTMLVideoElement (WebProcess)
│ viewportIntersectionChanged()
│ │
│ isVisibleInViewportChanged()
│ │
▼ MediaPlayer::setViewportVisibility()
│
▼ [IPC]
RemoteMediaPlayerProxy::setViewportVisibility() (GPUProcess)
│
▼ MediaPlayerPrivateAVFoundationObjC
platformViewportVisibilityChanged()
│
visibility == NotVisible?
├─ YES ──► updateLayerAttachment() → detach/destroy CALayer
└─ NO ──► updateLayerAttachment() → recreate CALayer if needed
이 수정은 무한 스크롤 video 페이지에서 발생하는 window server jetsam(compositor의 OOM kill)을 해결하기 위한 것입니다. 화면 밖 요소에 대한 GPU 측 layer 리소스를 해제하는 방식으로 문제에 대응합니다. 기존의 boolean 방식은 새로운 3단계 visibility 모델(NotVisible / IntersectingViewport / VisibleInViewport)로 대체되었습니다. 이 중 IntersectingViewport는 rootMargin 100%로 설정된 IntersectionObserver에 의해 발생합니다.
Significance
Layer teardown/recreation cycle이 media player lifecycle에 새로운 state transition을 추가합니다. 이 transition은 page visibility, viewport visibility, fullscreen, PiP 상태의 모든 조합을 올바르게 처리해야 합니다.
shouldAttachLayerToPlayer() 함수는 이제 4가지 flag를 함께 고려합니다. 빠른 스크롤 전환 중 WebProcess 측 상태와 GPUProcess 측 상태 사이에 불일치가 생기면, video가 일관성 없는 layer 상태에 놓일 가능성이 있습니다.