Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: ce011e7c0b491e9baf716893162bfd59c9425dad
      
https://github.com/WebKit/WebKit/commit/ce011e7c0b491e9baf716893162bfd59c9425dad
  Author: Youenn Fablet <[email protected]>
  Date:   2026-10-15 (Thu, 15 Oct 2026)

  Changed paths:
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard-utils.js
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard.any-expected.txt
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard.any.html
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard.any.js
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard.any.worker-expected.txt
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard.any.worker.html
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard.window-expected.txt
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard.window.html
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard.window.js
    M 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-copyTo-rgbx.any.js
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-drawImage-rgbx.any-expected.txt
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-drawImage-rgbx.any.html
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-drawImage-rgbx.any.js
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-drawImage-rgbx.any.worker-expected.txt
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-drawImage-rgbx.any.worker.html
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-imageBitmap.any-expected.txt
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-imageBitmap.any.html
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-imageBitmap.any.js
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-imageBitmap.any.worker-expected.txt
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-imageBitmap.any.worker.html
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-utils.js
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-webgl.window-expected.txt
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-webgl.window.html
    A 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-webgl.window.js
    M LayoutTests/ipc/cocoa/videoEncode.html
    M LayoutTests/platform/glib/TestExpectations
    M Source/WebCore/Modules/webcodecs/WebCodecsVideoFrame.cpp
    M Source/WebCore/Modules/webcodecs/WebCodecsVideoFrame.h
    M Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp
    M Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp
    M Source/WebCore/platform/VideoFrame.cpp
    M Source/WebCore/platform/VideoFrame.h
    M Source/WebCore/platform/VideoFrame.mm
    M Source/WebCore/platform/graphics/GraphicsContextGLImageExtractor.cpp
    M Source/WebCore/platform/graphics/GraphicsContextGLImageExtractor.h
    M Source/WebCore/platform/graphics/cg/GraphicsContextGLCG.cpp
    M Source/WebCore/platform/graphics/cv/ImageRotationSessionVT.mm
    M Source/WebCore/platform/graphics/cv/ImageTransferSessionVT.h
    M Source/WebCore/platform/graphics/cv/ImageTransferSessionVT.mm
    M Source/WebCore/platform/graphics/cv/VideoFrameCV.h
    M Source/WebCore/platform/graphics/cv/VideoFrameCV.mm
    M Source/WebCore/platform/graphics/gstreamer/VideoFrameGStreamer.cpp
    M Source/WebKit/WebProcess/GPU/media/RemoteVideoFrameProxy.cpp
    M Source/WebKit/WebProcess/GPU/media/RemoteVideoFrameProxy.h
    M Source/WebKit/WebProcess/GPU/media/RemoteVideoFrameProxyProperties.h
    M 
Source/WebKit/WebProcess/GPU/media/RemoteVideoFrameProxyProperties.serialization.in
    M Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp
    M 
Source/WebKit/WebProcess/GPU/webrtc/RemoteVideoFrameObjectHeapProxyProcessor.cpp
    M Source/WebKit/WebProcess/GPU/webrtc/SampleBufferDisplayLayer.cpp
    M Source/WebKit/WebProcess/GPU/webrtc/SharedVideoFrame.cpp
    M Source/WebKit/WebProcess/GPU/webrtc/SharedVideoFrame.h
    M Source/WebKit/WebProcess/GPU/webrtc/SharedVideoFrame.serialization.in

  Log Message:
  -----------
  Drawing a BGRX VideoFrame should disregard the alpha component
rdar://189794952
https://bugs.webkit.org/show_bug.cgi?id=327231

Reviewed by Jean-Yves Avenard.

RGBX and BGRX VideoFrames must be rendered as if they were opaque:.
The fourth byte of a pixel is padding, not alpha.
It was handled as alpha, so a padding byte of 0 made the frame transparent when 
drawn.

VideoFrame gets a virtual shouldIgnoreAlpha(), false by default.
- VideoFrameCV stores the flag and sets it in createRGBX/createBGRX and when
  alpha: 'discard' is used. VideoFrame::updateShouldIgnoreAlpha makes a cheap
  clone sharing the pixel buffer, so an RGBX frame made from an RGBA one is
  not deep copied. The pixel data is left untouched.
- VideoFrameCV::create takes a mandatory VideoFrameCV::ShouldIgnoreAlpha when
  given a color space. The overload computing the color space from the buffer
  has no flag; resize and asVideoFrameCV set it with updateShouldIgnoreAlpha.
- The flag is preserved by clone, rotation, resize, SharedVideoFrame and
  RemoteVideoFrameProxy properties.
- VideoFrameGStreamer needs no flag since it creates RGBx/BGRx frames.

When creating a VideoFrame from a HTMLVideoElement or HTMLImageElement, we are 
now using ShouldClone::Yes.
This is fixing an existing bug where if we create two WebCodecsVideoFrame from 
the same HTMLVideoElement synchronously,
we would use the same underlying VideoFrame, which is ok except if we are 
discarding alpha/changing timestamp in one but not the other.
By using ShouldClone::Yes, when updating, we will clone the VideoFrame around 
the same underlying resource.

Consumers use the flag as follows:
- VideoFrame::copyNativeImage creates images without alpha 
(kCGImageAlphaNoneSkipFirst).
- copyTo sets the X byte to 255 for RGBX/BGRX, and the RGBA/BGRA row copies
  now use vImage channel permutations instead of per byte loops.
- For WebGL texImage, the CG image extractor sets the skipped byte to 255 in
  a copy of the pixels when the upload format has an alpha component.
- Encoders convert RGB frames to YUV, which already drops alpha.

We update ImageTransferSessionVT::createPixelBuffer from a CGImageRef so that 
it preserves alpha.
We add a flag to allow this preservation.
We implement it by drawing on premultiplied alpha as CGBitmapContextCreate with 
kCGImageAlphaFirst does not work..

We add several tests to cover all consumers and alpha discard code paths.

Tests: 
imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard.any.html
       
imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard.any.worker.html
       
imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard.window.html
       
imported/w3c/web-platform-tests/webcodecs/videoFrame-drawImage-rgbx.any.html
       
imported/w3c/web-platform-tests/webcodecs/videoFrame-drawImage-rgbx.any.worker.html
       
imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-imageBitmap.any.html
       
imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-imageBitmap.any.worker.html
       
imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-webgl.window.html

* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard-utils.js:
 Added.
(makeTransparentCanvas):
(getPixel):
(verifyOpaquePicture):
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard.any-expected.txt:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard.any.html:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard.any.js:
 Added.
(const.kSources.string_appeared_here.new.VideoFrame.makeTransparentCanvas):
(makeSource.of.Object.entries.makeDiscardedFrame):
(makeSource.of.Object.entries.async promise_test):
(makeSource.of.Object.entries):
(async promise_test):
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard.any.worker-expected.txt:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard.any.worker.html:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard.window-expected.txt:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard.window.html:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-alpha-discard.window.js:
 Added.
(async makeTransparentImage):
(makeTransparentHTMLCanvas):
(makeSource.of.Object.entries.async makeDiscardedFrame):
(makeSource.of.Object.entries.async promise_test):
(makeSource.of.Object.entries):
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-copyTo-rgbx.any.js:
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-drawImage-rgbx.any-expected.txt:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-drawImage-rgbx.any.html:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-drawImage-rgbx.any.js:
 Added.
(makeData):
(drawAndVerify):
(string_appeared_here.0xff.promise_test.async t):
(promise_test.async t):
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-drawImage-rgbx.any.worker-expected.txt:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-drawImage-rgbx.any.worker.html:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-imageBitmap.any-expected.txt:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-imageBitmap.any.html:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-imageBitmap.any.js:
 Added.
(readPixels):
(async frame):
(promise_test.async t):
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-imageBitmap.any.worker-expected.txt:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-imageBitmap.any.worker.html:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-utils.js: 
Added.
(makeRgbxFrame):
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-webgl.window-expected.txt:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-webgl.window.html:
 Added.
* 
LayoutTests/imported/w3c/web-platform-tests/webcodecs/videoFrame-rgbx-webgl.window.js:
 Added.
(readTexturePixels):
(promise_test.async t):
* Source/WebCore/Modules/webcodecs/WebCodecsVideoFrame.cpp:
(WebCore::WebCodecsVideoFrame::create):
(WebCore::WebCodecsVideoFrame::initializeFrameFromOtherFrame):
(WebCore::WebCodecsVideoFrame::initializeFrameWithResourceAndSize):
* Source/WebCore/Modules/webcodecs/WebCodecsVideoFrame.h:
(WebCore::WebCodecsVideoFrame::shoudlDiscardAlpha const): Deleted.
* Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp:
(WebCore::CanvasRenderingContext2DBase::drawImage):
* Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::texImageImpl):
* Source/WebCore/platform/VideoFrame.cpp:
(WebCore::VideoFrame::updateTimestamp):
(WebCore::VideoFrame::updateShouldIgnoreAlpha):
(WebCore::VideoFrame::createRGBX):
(WebCore::VideoFrame::createBGRX):
* Source/WebCore/platform/VideoFrame.h:
(WebCore::VideoFrame::shouldIgnoreAlpha const):
(WebCore::VideoFrame::setShouldIgnoreAlpha):
* Source/WebCore/platform/VideoFrame.mm:
(WebCore::VideoFrame::asVideoFrameCV):
* Source/WebCore/platform/graphics/GraphicsContextGLImageExtractor.cpp:
(WebCore::formatUsesAlpha):
(WebCore::GraphicsContextGLImageExtractor::GraphicsContextGLImageExtractor):
* Source/WebCore/platform/graphics/GraphicsContextGLImageExtractor.h:
* Source/WebCore/platform/graphics/cg/GraphicsContextGLCG.cpp:
(WebCore::GraphicsContextGLImageExtractor::extractImage):
(WebCore::GraphicsContextGLImageExtractor::makeAlphaChannelOpaque):
* Source/WebCore/platform/graphics/cv/ImageRotationSessionVT.mm:
(WebCore::ImageRotationSessionVT::applyRotation):
* Source/WebCore/platform/graphics/cv/ImageTransferSessionVT.mm:
(WebCore::ImageTransferSessionVT::convertVideoFrame):
(WebCore::ImageTransferSessionVT::createPixelBuffer):
(WebCore::imageMayHaveAlpha):
(WebCore::ImageTransferSessionVT::createCMSampleBuffer):
(WebCore::ImageTransferSessionVT::createVideoFrame):
* Source/WebCore/platform/graphics/cv/VideoFrameCV.h:
* Source/WebCore/platform/graphics/cv/VideoFrameCV.mm:
(WebCore::VideoFrame::createNV12):
(WebCore::createRGBABuffer):
(WebCore::VideoFrame::createRGBA):
(WebCore::VideoFrame::createRGBX):
(WebCore::createBGRABuffer):
(WebCore::VideoFrame::createBGRA):
(WebCore::VideoFrame::createBGRX):
(WebCore::VideoFrame::createI420):
(WebCore::VideoFrame::createI420A):
(WebCore::copyRGBRow):
(WebCore::VideoFrame::copyTo):
(WebCore::VideoFrame::copyNativeImage const):
(WebCore::VideoFrameCV::create):
(WebCore::VideoFrame::createFromPixelBuffer):
(WebCore::VideoFrameCV::VideoFrameCV):
(WebCore::VideoFrameCV::clone):
(WebCore::VideoFrame::fromNativeImage):
* Source/WebCore/platform/graphics/gstreamer/VideoFrameGStreamer.cpp:
(WebCore::VideoFrame::createRGBX):
(WebCore::VideoFrame::createBGRX):
(WebCore::VideoFrameGStreamer::setPresentationTime):
* Source/WebKit/WebProcess/GPU/media/RemoteVideoFrameProxy.cpp:
(WebKit::RemoteVideoFrameProxy::properties):
(WebKit::RemoteVideoFrameProxy::RemoteVideoFrameProxy):
(WebKit::m_shouldIgnoreAlpha):
(WebKit::operator<<):
(WebKit::m_pixelFormat): Deleted.
* Source/WebKit/WebProcess/GPU/media/RemoteVideoFrameProxy.h:
* Source/WebKit/WebProcess/GPU/media/RemoteVideoFrameProxyProperties.h:
* 
Source/WebKit/WebProcess/GPU/media/RemoteVideoFrameProxyProperties.serialization.in:
* Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp:
(WebKit::LibWebRTCCodecs::encodeFrameInternal):
(WebKit::LibWebRTCCodecs::encodeFrameInternalWithLock):
(WebKit::LibWebRTCCodecs::encodeFrame):
* 
Source/WebKit/WebProcess/GPU/webrtc/RemoteVideoFrameObjectHeapProxyProcessor.cpp:
(WebKit::RemoteVideoFrameObjectHeapProxyProcessor::getNativeImage):
* Source/WebKit/WebProcess/GPU/webrtc/SampleBufferDisplayLayer.cpp:
(WebKit::SampleBufferDisplayLayer::enqueueBlackFrameFrom):
* Source/WebKit/WebProcess/GPU/webrtc/SharedVideoFrame.cpp:
(WebKit::SharedVideoFrameWriter::write):
(WebKit::SharedVideoFrameReader::read):
* Source/WebKit/WebProcess/GPU/webrtc/SharedVideoFrame.h:
* Source/WebKit/WebProcess/GPU/webrtc/SharedVideoFrame.serialization.in:
* Source/WebCore/platform/graphics/cv/ImageTransferSessionVT.h:
* LayoutTests/platform/glib/TestExpectations:
* LayoutTests/ipc/cocoa/videoEncode.html:

Canonical link: https://commits.webkit.org/323809@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to