← All issues

Lazy Video Viewport Observer: GPU Layer Teardown for Off-Screen Videos

93297c8

Source/WebCore/html/HTMLVideoElement.cpp

+void HTMLVideoElement::viewportIntersectionChanged(bool isIntersecting)
+{
+ if (m_isIntersectingViewport == isIntersecting)
+ return;
+ m_isIntersectingViewport = isIntersecting;
+ isVisibleInViewportChanged();
+ computeAcceleratedRenderingStateAndUpdateMediaPlayer();
+}

This commit introduces LazyLoadVideoObserver and a ViewportVisibility enum to track whether video elements intersect the viewport. When visibility drops to NotVisible, compositor layers are torn down for AVFoundation-backed players; when the element scrolls back into view, layers are recreated. This mirrors the existing LazyLoadImageObserver/LazyLoadFrameObserver pattern.

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

The fix addresses window server jetsams (OOM kills of the compositor) on infinite-scroll video pages by releasing GPU-side layer resources for off-screen elements. A new three-state visibility model (NotVisible / IntersectingViewport / VisibleInViewport) replaces the previous boolean, where IntersectingViewport is triggered by an IntersectionObserver with a 100% rootMargin.

The layer teardown/recreation cycle adds a new state transition to media player lifecycle that must correctly handle all combinations of page visibility, viewport visibility, fullscreen, and PiP states.

The shouldAttachLayerToPlayer() decision function now integrates four flags — any disagreement between WebProcess-side state and GPUProcess-side state during rapid scroll transitions could leave a video in an inconsistent layer state.

🔒

New state machine interactions across multiple visibility flags and the layer attach/detach lifecycle — audit directions included.

Subscribe to read more