| Differences between
and this patch
- a/Source/WebCore/ChangeLog +43 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2021-09-21  Cameron McCormack  <heycam@apple.com>
2
3
        Ensure canvas.drawImage(video) uses the right color space
4
        https://bugs.webkit.org/show_bug.cgi?id=229025
5
        <rdar://problem/81828490>
6
7
        Reviewed by NOBODY (OOPS!).
8
9
        The ImageBitmap::createPromise() overload that takes an
10
        HTMLVideoElement needs to create an ImageBuffer in an appropriate
11
        color space.
12
13
        Tests: imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-video.html
14
               imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-video.html
15
16
        * html/HTMLVideoElement.cpp:
17
        (WebCore::HTMLVideoElement::colorSpace const): New function that
18
        exposes the color space of the current frame of the video.
19
        * html/HTMLVideoElement.h:
20
        * html/ImageBitmap.cpp:
21
        (WebCore::ImageBitmap::createPromise): Create the ImageBuffer in a
22
        color space that matches the video, not always sRGB.
23
        * platform/cocoa/CoreVideoSoftLink.cpp:
24
        * platform/cocoa/CoreVideoSoftLink.h: Add soft linked constant that
25
        can be used to get the color space from a CVPixelBuffer.
26
        * platform/graphics/MediaPlayer.cpp:
27
        (WebCore::MediaPlayer::colorSpace):
28
        * platform/graphics/MediaPlayer.h:
29
        * platform/graphics/MediaPlayerPrivate.h:
30
        (WebCore::MediaPlayerPrivateInterface::colorSpace):
31
        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
32
        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
33
        (WebCore::MediaPlayerPrivateAVFoundationObjC::colorSpace): Expose the
34
        color space of the current image. While we strictly only need the pixel
35
        buffer to be up to date, we call updateLastImage() since it has the
36
        UpdateSynchronously behavior, and the caller to colorSpace() will use
37
        the image soon anyway.
38
        * platform/graphics/cg/ColorSpaceCG.h:
39
        * platform/graphics/cv/PixelBufferConformerCV.cpp:
40
        (WebCore::PixelBufferConformerCV::createImageFromPixelBuffer): Create
41
        the RGB pixel buffer using the color space attached to the original
42
        format pixel buffer.
43
1
2021-09-19  Cameron McCormack  <heycam@apple.com>
44
2021-09-19  Cameron McCormack  <heycam@apple.com>
2
45
3
        Preserve color space when structured cloning ImageBitmaps
46
        Preserve color space when structured cloning ImageBitmaps
- a/Source/WebKit/ChangeLog +41 lines
Lines 1-3 a/Source/WebKit/ChangeLog_sec1
1
2021-09-21  Cameron McCormack  <heycam@apple.com>
2
3
        Ensure canvas.drawImage(video) uses the right color space
4
        https://bugs.webkit.org/show_bug.cgi?id=229025
5
        <rdar://problem/81828490>
6
7
        Reviewed by NOBODY (OOPS!).
8
9
        When GPU process media handling is enabled, canvas.drawImage(video)
10
        calls work by sending a NativeImageForCurrentTime message to the GPU
11
        process, which returns an IOSurface around which a CGImage is created.
12
        There's no good way to get the color space off the IOSurface, so we
13
        add a second return argument to NativeImageForCurrentTime to indicate
14
        the color space used.
15
16
        ImageBitmap creates an ImageBuffer for that image to be painted into,
17
        and for that we also need to know the color space of the video. The
18
        code that sends NativeImageForCurrentTime and then paints the
19
        resulting image into the GraphicsContext is further down. So we add
20
        a separate IPC message that gets the color space of the video's
21
        current frame. (It would be better if we could avoid a second
22
        synchronous IPC message call, but either ImageBitmap's scaling and
23
        cropping code, or the ImageBuffer creation call, would need to be moved
24
        down into MediaPlayerPrivateRemote::paintCurrentFrameInContext, which
25
        doesn't seem like the right place for it.)
26
27
        * GPUProcess/media/RemoteMediaPlayerProxy.h:
28
        * GPUProcess/media/RemoteMediaPlayerProxy.messages.in:
29
        * GPUProcess/media/cocoa/RemoteMediaPlayerProxyCocoa.mm:
30
        (WebKit::RemoteMediaPlayerProxy::nativeImageForCurrentTime):
31
        (WebKit::RemoteMediaPlayerProxy::colorSpace):
32
        * WebProcess/GPU/media/MediaPlayerPrivateRemote.cpp:
33
        (WebKit::MediaPlayerPrivateRemote::colorSpace):
34
        * WebProcess/GPU/media/MediaPlayerPrivateRemote.h:
35
        * WebProcess/GPU/media/cocoa/MediaPlayerPrivateRemoteCocoa.mm:
36
        (WebKit::MediaPlayerPrivateRemote::nativeImageForCurrentTime): Add a
37
        second return argument to NativeImageForCurrentTime to indicate the
38
        color space of the returned IOSurface.
39
        (WebKit::MediaPlayerPrivateRemote::colorSpace): Add a new IPC message to
40
        get the color space of a video's current frame.
41
1
2021-09-17  Alex Christensen  <achristensen@webkit.org>
42
2021-09-17  Alex Christensen  <achristensen@webkit.org>
2
43
3
        Use ObjectIdentifier for ResourceLoader
44
        Use ObjectIdentifier for ResourceLoader
- a/Source/WebCore/html/HTMLVideoElement.cpp +9 lines
Lines 283-288 void HTMLVideoElement::mediaPlayerFirstVideoFrameAvailable() a/Source/WebCore/html/HTMLVideoElement.cpp_sec1
283
        renderer->updateFromElement();
283
        renderer->updateFromElement();
284
}
284
}
285
285
286
std::optional<DestinationColorSpace> HTMLVideoElement::colorSpace() const
287
{
288
    RefPtr<MediaPlayer> player = HTMLMediaElement::player();
289
    if (!player)
290
        return std::nullopt;
291
292
    return player->colorSpace();
293
}
294
286
RefPtr<ImageBuffer> HTMLVideoElement::createBufferForPainting(const FloatSize& size, RenderingMode renderingMode, const DestinationColorSpace& colorSpace, PixelFormat pixelFormat) const
295
RefPtr<ImageBuffer> HTMLVideoElement::createBufferForPainting(const FloatSize& size, RenderingMode renderingMode, const DestinationColorSpace& colorSpace, PixelFormat pixelFormat) const
287
{
296
{
288
    auto* hostWindow = document().view() && document().view()->root() ? document().view()->root()->hostWindow() : nullptr;
297
    auto* hostWindow = document().view() && document().view()->root() ? document().view()->root()->hostWindow() : nullptr;
- a/Source/WebCore/html/HTMLVideoElement.h +1 lines
Lines 78-83 public: a/Source/WebCore/html/HTMLVideoElement.h_sec1
78
    void paintCurrentFrameInContext(GraphicsContext&, const FloatRect&);
78
    void paintCurrentFrameInContext(GraphicsContext&, const FloatRect&);
79
79
80
    RefPtr<NativeImage> nativeImageForCurrentTime();
80
    RefPtr<NativeImage> nativeImageForCurrentTime();
81
    std::optional<DestinationColorSpace> colorSpace() const;
81
82
82
    WEBCORE_EXPORT bool shouldDisplayPosterImage() const;
83
    WEBCORE_EXPORT bool shouldDisplayPosterImage() const;
83
84
- a/Source/WebCore/html/ImageBitmap.cpp -2 / +6 lines
Lines 512-519 void ImageBitmap::createPromise(ScriptExecutionContext& scriptExecutionContext, a/Source/WebCore/html/ImageBitmap.cpp_sec1
512
512
513
    auto outputSize = outputSizeForSourceRectangle(sourceRectangle, options);
513
    auto outputSize = outputSizeForSourceRectangle(sourceRectangle, options);
514
514
515
    // FIXME: Add support for color spaces / pixel formats to ImageBitmap.
515
    auto colorSpace = video->colorSpace();
516
    auto bitmapData = video->createBufferForPainting(outputSize, bufferRenderingMode, DestinationColorSpace::SRGB(), PixelFormat::BGRA8);
516
    if (!colorSpace)
517
        colorSpace = DestinationColorSpace::SRGB();
518
519
    // FIXME: Add support for pixel formats to ImageBitmap.
520
    auto bitmapData = video->createBufferForPainting(outputSize, bufferRenderingMode, *colorSpace, PixelFormat::BGRA8);
517
    if (!bitmapData) {
521
    if (!bitmapData) {
518
        resolveWithBlankImageBuffer(scriptExecutionContext, !taintsOrigin(scriptExecutionContext.securityOrigin(), *video), WTFMove(promise));
522
        resolveWithBlankImageBuffer(scriptExecutionContext, !taintsOrigin(scriptExecutionContext.securityOrigin(), *video), WTFMove(promise));
519
        return;
523
        return;
- a/Source/WebCore/platform/cocoa/CoreVideoSoftLink.cpp +1 lines
Lines 72-77 SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, CoreVideo, kCVImageBufferTransferFunction a/Source/WebCore/platform/cocoa/CoreVideoSoftLink.cpp_sec1
72
SOFT_LINK_CONSTANT_MAY_FAIL_FOR_SOURCE(WebCore, CoreVideo, kCVImageBufferYCbCrMatrix_DCI_P3, CFStringRef)
72
SOFT_LINK_CONSTANT_MAY_FAIL_FOR_SOURCE(WebCore, CoreVideo, kCVImageBufferYCbCrMatrix_DCI_P3, CFStringRef)
73
SOFT_LINK_CONSTANT_MAY_FAIL_FOR_SOURCE(WebCore, CoreVideo, kCVImageBufferYCbCrMatrix_P3_D65, CFStringRef)
73
SOFT_LINK_CONSTANT_MAY_FAIL_FOR_SOURCE(WebCore, CoreVideo, kCVImageBufferYCbCrMatrix_P3_D65, CFStringRef)
74
SOFT_LINK_CONSTANT_MAY_FAIL_FOR_SOURCE(WebCore, CoreVideo, kCVImageBufferYCbCrMatrix_ITU_R_2020, CFStringRef)
74
SOFT_LINK_CONSTANT_MAY_FAIL_FOR_SOURCE(WebCore, CoreVideo, kCVImageBufferYCbCrMatrix_ITU_R_2020, CFStringRef)
75
SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, CoreVideo, kCVImageBufferCGColorSpaceKey, CFStringRef)
75
76
76
#if USE(OPENGL_ES)
77
#if USE(OPENGL_ES)
77
SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreVideo, CVOpenGLESTextureCacheCreate, CVReturn, (CFAllocatorRef allocator, CFDictionaryRef cacheAttributes, CVEAGLContext eaglContext, CFDictionaryRef textureAttributes, CVOpenGLESTextureCacheRef* cacheOut), (allocator, cacheAttributes, eaglContext, textureAttributes, cacheOut))
78
SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreVideo, CVOpenGLESTextureCacheCreate, CVReturn, (CFAllocatorRef allocator, CFDictionaryRef cacheAttributes, CVEAGLContext eaglContext, CFDictionaryRef textureAttributes, CVOpenGLESTextureCacheRef* cacheOut), (allocator, cacheAttributes, eaglContext, textureAttributes, cacheOut))
- a/Source/WebCore/platform/cocoa/CoreVideoSoftLink.h +2 lines
Lines 111-116 SOFT_LINK_CONSTANT_FOR_HEADER(WebCore, CoreVideo, kCVImageBufferTransferFunction a/Source/WebCore/platform/cocoa/CoreVideoSoftLink.h_sec1
111
#define kCVImageBufferTransferFunction_ITU_R_709_2 get_CoreVideo_kCVImageBufferTransferFunction_ITU_R_709_2()
111
#define kCVImageBufferTransferFunction_ITU_R_709_2 get_CoreVideo_kCVImageBufferTransferFunction_ITU_R_709_2()
112
SOFT_LINK_CONSTANT_FOR_HEADER(WebCore, CoreVideo, kCVImageBufferTransferFunction_SMPTE_240M_1995, CFStringRef)
112
SOFT_LINK_CONSTANT_FOR_HEADER(WebCore, CoreVideo, kCVImageBufferTransferFunction_SMPTE_240M_1995, CFStringRef)
113
#define kCVImageBufferTransferFunction_SMPTE_240M_1995 get_CoreVideo_kCVImageBufferTransferFunction_SMPTE_240M_1995()
113
#define kCVImageBufferTransferFunction_SMPTE_240M_1995 get_CoreVideo_kCVImageBufferTransferFunction_SMPTE_240M_1995()
114
SOFT_LINK_CONSTANT_FOR_HEADER(WebCore, CoreVideo, kCVImageBufferCGColorSpaceKey, CFStringRef)
115
#define kCVImageBufferCGColorSpaceKey get_CoreVideo_kCVImageBufferCGColorSpaceKey()
114
116
115
#if USE(OPENGL_ES)
117
#if USE(OPENGL_ES)
116
SOFT_LINK_FUNCTION_FOR_HEADER(WebCore, CoreVideo, CVOpenGLESTextureCacheCreate, CVReturn, (CFAllocatorRef allocator, CFDictionaryRef cacheAttributes, CVEAGLContext eaglContext, CFDictionaryRef textureAttributes, CVOpenGLESTextureCacheRef* cacheOut), (allocator, cacheAttributes, eaglContext, textureAttributes, cacheOut))
118
SOFT_LINK_FUNCTION_FOR_HEADER(WebCore, CoreVideo, CVOpenGLESTextureCacheCreate, CVReturn, (CFAllocatorRef allocator, CFDictionaryRef cacheAttributes, CVEAGLContext eaglContext, CFDictionaryRef textureAttributes, CVOpenGLESTextureCacheRef* cacheOut), (allocator, cacheAttributes, eaglContext, textureAttributes, cacheOut))
- a/Source/WebCore/platform/graphics/MediaPlayer.cpp +5 lines
Lines 1061-1066 RefPtr<NativeImage> MediaPlayer::nativeImageForCurrentTime() a/Source/WebCore/platform/graphics/MediaPlayer.cpp_sec1
1061
    return m_private->nativeImageForCurrentTime();
1061
    return m_private->nativeImageForCurrentTime();
1062
}
1062
}
1063
1063
1064
std::optional<DestinationColorSpace> MediaPlayer::colorSpace()
1065
{
1066
    return m_private->colorSpace();
1067
}
1068
1064
MediaPlayer::SupportsType MediaPlayer::supportsType(const MediaEngineSupportParameters& parameters)
1069
MediaPlayer::SupportsType MediaPlayer::supportsType(const MediaEngineSupportParameters& parameters)
1065
{
1070
{
1066
    // 4.8.10.3 MIME types - The canPlayType(type) method must return the empty string if type is a type that the 
1071
    // 4.8.10.3 MIME types - The canPlayType(type) method must return the empty string if type is a type that the 
- a/Source/WebCore/platform/graphics/MediaPlayer.h +1 lines
Lines 470-475 public: a/Source/WebCore/platform/graphics/MediaPlayer.h_sec1
470
#endif
470
#endif
471
471
472
    RefPtr<NativeImage> nativeImageForCurrentTime();
472
    RefPtr<NativeImage> nativeImageForCurrentTime();
473
    std::optional<DestinationColorSpace> colorSpace();
473
474
474
    using MediaPlayerEnums::NetworkState;
475
    using MediaPlayerEnums::NetworkState;
475
    NetworkState networkState();
476
    NetworkState networkState();
- a/Source/WebCore/platform/graphics/MediaPlayerPrivate.h +1 lines
Lines 177-182 public: a/Source/WebCore/platform/graphics/MediaPlayerPrivate.h_sec1
177
    virtual RetainPtr<CVPixelBufferRef> pixelBufferForCurrentTime() { return nullptr; }
177
    virtual RetainPtr<CVPixelBufferRef> pixelBufferForCurrentTime() { return nullptr; }
178
#endif
178
#endif
179
    virtual RefPtr<NativeImage> nativeImageForCurrentTime() { return nullptr; }
179
    virtual RefPtr<NativeImage> nativeImageForCurrentTime() { return nullptr; }
180
    virtual std::optional<DestinationColorSpace> colorSpace() { return std::nullopt; }
180
181
181
    virtual void setPreload(MediaPlayer::Preload) { }
182
    virtual void setPreload(MediaPlayer::Preload) { }
182
183
- a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h +1 lines
Lines 254-259 private: a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h_sec1
254
    bool videoOutputHasAvailableFrame();
254
    bool videoOutputHasAvailableFrame();
255
    void paintWithVideoOutput(GraphicsContext&, const FloatRect&);
255
    void paintWithVideoOutput(GraphicsContext&, const FloatRect&);
256
    RefPtr<NativeImage> nativeImageForCurrentTime() final;
256
    RefPtr<NativeImage> nativeImageForCurrentTime() final;
257
    std::optional<DestinationColorSpace> colorSpace() final;
257
    void waitForVideoOutputMediaDataWillChange();
258
    void waitForVideoOutputMediaDataWillChange();
258
259
259
    RetainPtr<CVPixelBufferRef> pixelBufferForCurrentTime() final;
260
    RetainPtr<CVPixelBufferRef> pixelBufferForCurrentTime() final;
- a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm +13 lines
Lines 2559-2564 RefPtr<NativeImage> MediaPlayerPrivateAVFoundationObjC::nativeImageForCurrentTim a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm_sec1
2559
    return m_lastImage;
2559
    return m_lastImage;
2560
}
2560
}
2561
2561
2562
std::optional<DestinationColorSpace> MediaPlayerPrivateAVFoundationObjC::colorSpace()
2563
{
2564
    updateLastImage(UpdateType::UpdateSynchronously);
2565
    if (!m_lastPixelBuffer)
2566
        return std::nullopt;
2567
2568
    CGColorSpaceRef colorSpace = dynamic_cf_cast<CGColorSpaceRef>(CVBufferGetAttachment(m_lastPixelBuffer.get(), kCVImageBufferCGColorSpaceKey, nullptr));
2569
    if (!colorSpace)
2570
        return std::nullopt;
2571
2572
    return DestinationColorSpace(colorSpace);
2573
}
2574
2562
void MediaPlayerPrivateAVFoundationObjC::waitForVideoOutputMediaDataWillChange()
2575
void MediaPlayerPrivateAVFoundationObjC::waitForVideoOutputMediaDataWillChange()
2563
{
2576
{
2564
    [m_videoOutput requestNotificationOfMediaDataChangeWithAdvanceInterval:0];
2577
    [m_videoOutput requestNotificationOfMediaDataChangeWithAdvanceInterval:0];
- a/Source/WebCore/platform/graphics/cg/ColorSpaceCG.h -1 / +3 lines
Lines 26-34 a/Source/WebCore/platform/graphics/cg/ColorSpaceCG.h_sec1
26
#pragma once
26
#pragma once
27
27
28
#include "ColorSpace.h"
28
#include "ColorSpace.h"
29
#include <CoreGraphics/CoreGraphics.h>
29
#include <optional>
30
#include <optional>
31
#include <wtf/cf/TypeCastsCF.h>
30
32
31
typedef struct CGColorSpace *CGColorSpaceRef;
33
WTF_DECLARE_CF_TYPE_TRAIT(CGColorSpace);
32
34
33
namespace WebCore {
35
namespace WebCore {
34
36
- a/Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.cpp -1 / +5 lines
Lines 165-170 RetainPtr<CGImageRef> PixelBufferConformerCV::createImageFromPixelBuffer(CVPixel a/Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.cpp_sec1
165
    if (!byteLength)
165
    if (!byteLength)
166
        return nullptr;
166
        return nullptr;
167
167
168
    CGColorSpaceRef colorSpace = dynamic_cf_cast<CGColorSpaceRef>(CVBufferGetAttachment(rawBuffer, kCVImageBufferCGColorSpaceKey, nullptr));
169
    if (!colorSpace)
170
        colorSpace = sRGBColorSpaceRef();
171
168
    CVPixelBufferInfo* info = new CVPixelBufferInfo();
172
    CVPixelBufferInfo* info = new CVPixelBufferInfo();
169
    info->pixelBuffer = WTFMove(buffer);
173
    info->pixelBuffer = WTFMove(buffer);
170
    info->lockCount = 0;
174
    info->lockCount = 0;
Lines 172-178 RetainPtr<CGImageRef> PixelBufferConformerCV::createImageFromPixelBuffer(CVPixel a/Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.cpp_sec2
172
    CGDataProviderDirectCallbacks providerCallbacks = { 0, CVPixelBufferGetBytePointerCallback, CVPixelBufferReleaseBytePointerCallback, 0, CVPixelBufferReleaseInfoCallback };
176
    CGDataProviderDirectCallbacks providerCallbacks = { 0, CVPixelBufferGetBytePointerCallback, CVPixelBufferReleaseBytePointerCallback, 0, CVPixelBufferReleaseInfoCallback };
173
    RetainPtr<CGDataProviderRef> provider = adoptCF(CGDataProviderCreateDirect(info, byteLength, &providerCallbacks));
177
    RetainPtr<CGDataProviderRef> provider = adoptCF(CGDataProviderCreateDirect(info, byteLength, &providerCallbacks));
174
178
175
    return adoptCF(CGImageCreate(width, height, 8, 32, bytesPerRow, sRGBColorSpaceRef(), bitmapInfo, provider.get(), nullptr, false, kCGRenderingIntentDefault));
179
    return adoptCF(CGImageCreate(width, height, 8, 32, bytesPerRow, colorSpace, bitmapInfo, provider.get(), nullptr, false, kCGRenderingIntentDefault));
176
}
180
}
177
181
178
}
182
}
- a/Source/WebKit/GPUProcess/media/RemoteMediaPlayerProxy.h -1 / +2 lines
Lines 308-314 private: a/Source/WebKit/GPUProcess/media/RemoteMediaPlayerProxy.h_sec1
308
    void currentTimeChanged(const MediaTime&);
308
    void currentTimeChanged(const MediaTime&);
309
309
310
#if PLATFORM(COCOA)
310
#if PLATFORM(COCOA)
311
    void nativeImageForCurrentTime(CompletionHandler<void(std::optional<WTF::MachSendRight>&&)>&&);
311
    void nativeImageForCurrentTime(CompletionHandler<void(std::optional<WTF::MachSendRight>&&, std::optional<WebCore::DestinationColorSpace>&&)>&&);
312
    void colorSpace(CompletionHandler<void(std::optional<WebCore::DestinationColorSpace>&&)>&&);
312
#endif
313
#endif
313
#if USE(AVFOUNDATION)
314
#if USE(AVFOUNDATION)
314
    void pixelBufferForCurrentTime(CompletionHandler<void(RetainPtr<CVPixelBufferRef>&&)>&&);
315
    void pixelBufferForCurrentTime(CompletionHandler<void(RetainPtr<CVPixelBufferRef>&&)>&&);
- a/Source/WebKit/GPUProcess/media/RemoteMediaPlayerProxy.messages.in -1 / +2 lines
Lines 123-129 messages -> RemoteMediaPlayerProxy NotRefCounted { a/Source/WebKit/GPUProcess/media/RemoteMediaPlayerProxy.messages.in_sec1
123
#endif
123
#endif
124
124
125
#if PLATFORM(COCOA)
125
#if PLATFORM(COCOA)
126
    NativeImageForCurrentTime() -> (std::optional<MachSendRight> sendRight) Synchronous
126
    NativeImageForCurrentTime() -> (std::optional<MachSendRight> sendRight, std::optional<WebCore::DestinationColorSpace> colorSpace) Synchronous
127
    ColorSpace() -> (std::optional<WebCore::DestinationColorSpace> colorSpace) Synchronous
127
#endif
128
#endif
128
#if USE(AVFOUNDATION)
129
#if USE(AVFOUNDATION)
129
    PixelBufferForCurrentTime() -> (RetainPtr<CVPixelBufferRef> pixelBuffer) Synchronous
130
    PixelBufferForCurrentTime() -> (RetainPtr<CVPixelBufferRef> pixelBuffer) Synchronous
- a/Source/WebKit/GPUProcess/media/cocoa/RemoteMediaPlayerProxyCocoa.mm -5 / +15 lines
Lines 83-114 void RemoteMediaPlayerProxy::setVideoInlineSizeFenced(const WebCore::FloatSize& a/Source/WebKit/GPUProcess/media/cocoa/RemoteMediaPlayerProxyCocoa.mm_sec1
83
    setVideoInlineSizeIfPossible(*m_inlineLayerHostingContext, size);
83
    setVideoInlineSizeIfPossible(*m_inlineLayerHostingContext, size);
84
}
84
}
85
85
86
void RemoteMediaPlayerProxy::nativeImageForCurrentTime(CompletionHandler<void(std::optional<WTF::MachSendRight>&&)>&& completionHandler)
86
void RemoteMediaPlayerProxy::nativeImageForCurrentTime(CompletionHandler<void(std::optional<WTF::MachSendRight>&&, std::optional<WebCore::DestinationColorSpace>&&)>&& completionHandler)
87
{
87
{
88
    if (!m_player) {
88
    if (!m_player) {
89
        completionHandler(std::nullopt);
89
        completionHandler(std::nullopt, std::nullopt);
90
        return;
90
        return;
91
    }
91
    }
92
92
93
    auto nativeImage = m_player->nativeImageForCurrentTime();
93
    auto nativeImage = m_player->nativeImageForCurrentTime();
94
    if (!nativeImage) {
94
    if (!nativeImage) {
95
        completionHandler(std::nullopt);
95
        completionHandler(std::nullopt, std::nullopt);
96
        return;
96
        return;
97
    }
97
    }
98
98
99
    auto platformImage = nativeImage->platformImage();
99
    auto platformImage = nativeImage->platformImage();
100
    if (!platformImage) {
100
    if (!platformImage) {
101
        completionHandler(std::nullopt);
101
        completionHandler(std::nullopt, std::nullopt);
102
        return;
102
        return;
103
    }
103
    }
104
104
105
    auto surface = WebCore::IOSurface::createFromImage(platformImage.get());
105
    auto surface = WebCore::IOSurface::createFromImage(platformImage.get());
106
    if (!surface) {
106
    if (!surface) {
107
        completionHandler(std::nullopt, std::nullopt);
108
        return;
109
    }
110
111
    completionHandler(surface->createSendRight(), nativeImage->colorSpace());
112
}
113
114
void RemoteMediaPlayerProxy::colorSpace(CompletionHandler<void(std::optional<WebCore::DestinationColorSpace>&&)>&& completionHandler)
115
{
116
    if (!m_player) {
107
        completionHandler(std::nullopt);
117
        completionHandler(std::nullopt);
108
        return;
118
        return;
109
    }
119
    }
110
120
111
    completionHandler(surface->createSendRight());
121
    completionHandler(m_player->colorSpace());
112
}
122
}
113
123
114
void RemoteMediaPlayerProxy::pixelBufferForCurrentTime(CompletionHandler<void(RetainPtr<CVPixelBufferRef>&&)>&& completionHandler)
124
void RemoteMediaPlayerProxy::pixelBufferForCurrentTime(CompletionHandler<void(RetainPtr<CVPixelBufferRef>&&)>&& completionHandler)
- a/Source/WebKit/WebProcess/GPU/media/MediaPlayerPrivateRemote.cpp +6 lines
Lines 985-990 RefPtr<NativeImage> MediaPlayerPrivateRemote::nativeImageForCurrentTime() a/Source/WebKit/WebProcess/GPU/media/MediaPlayerPrivateRemote.cpp_sec1
985
    notImplemented();
985
    notImplemented();
986
    return nullptr;
986
    return nullptr;
987
}
987
}
988
989
std::optional<WebCore::DestinationColorSpace> MediaPlayerPrivateRemote::colorSpace()
990
{
991
    notImplemented();
992
    return std::nullopt;
993
}
988
#endif
994
#endif
989
995
990
bool MediaPlayerPrivateRemote::hasAvailableVideoFrame() const
996
bool MediaPlayerPrivateRemote::hasAvailableVideoFrame() const
- a/Source/WebKit/WebProcess/GPU/media/MediaPlayerPrivateRemote.h +1 lines
Lines 290-295 private: a/Source/WebKit/WebProcess/GPU/media/MediaPlayerPrivateRemote.h_sec1
290
    RetainPtr<CVPixelBufferRef> pixelBufferForCurrentTime() final;
290
    RetainPtr<CVPixelBufferRef> pixelBufferForCurrentTime() final;
291
#endif
291
#endif
292
    RefPtr<WebCore::NativeImage> nativeImageForCurrentTime() final;
292
    RefPtr<WebCore::NativeImage> nativeImageForCurrentTime() final;
293
    std::optional<WebCore::DestinationColorSpace> colorSpace() final;
293
294
294
    WebCore::MediaPlayerIdentifier identifier() const final;
295
    WebCore::MediaPlayerIdentifier identifier() const final;
295
296
- a/Source/WebKit/WebProcess/GPU/media/cocoa/MediaPlayerPrivateRemoteCocoa.mm -3 / +13 lines
Lines 49-61 PlatformLayerContainer MediaPlayerPrivateRemote::createVideoFullscreenLayer() a/Source/WebKit/WebProcess/GPU/media/cocoa/MediaPlayerPrivateRemoteCocoa.mm_sec1
49
RefPtr<NativeImage> MediaPlayerPrivateRemote::nativeImageForCurrentTime()
49
RefPtr<NativeImage> MediaPlayerPrivateRemote::nativeImageForCurrentTime()
50
{
50
{
51
    std::optional<MachSendRight> sendRight;
51
    std::optional<MachSendRight> sendRight;
52
    if (!connection().sendSync(Messages::RemoteMediaPlayerProxy::NativeImageForCurrentTime(), Messages::RemoteMediaPlayerProxy::NativeImageForCurrentTime::Reply(sendRight), m_id))
52
    std::optional<DestinationColorSpace> colorSpace;
53
    if (!connection().sendSync(Messages::RemoteMediaPlayerProxy::NativeImageForCurrentTime(), Messages::RemoteMediaPlayerProxy::NativeImageForCurrentTime::Reply(sendRight, colorSpace), m_id))
53
        return nullptr;
54
        return nullptr;
54
55
55
    if (!sendRight)
56
    if (!sendRight || !colorSpace)
56
        return nullptr;
57
        return nullptr;
57
58
58
    auto surface = WebCore::IOSurface::createFromSendRight(WTFMove(*sendRight), WebCore::DestinationColorSpace::SRGB());
59
    auto surface = WebCore::IOSurface::createFromSendRight(WTFMove(*sendRight), *colorSpace);
59
    if (!surface)
60
    if (!surface)
60
        return nullptr;
61
        return nullptr;
61
62
Lines 66-71 RefPtr<NativeImage> MediaPlayerPrivateRemote::nativeImageForCurrentTime() a/Source/WebKit/WebProcess/GPU/media/cocoa/MediaPlayerPrivateRemoteCocoa.mm_sec2
66
    return NativeImage::create(WTFMove(platformImage));
67
    return NativeImage::create(WTFMove(platformImage));
67
}
68
}
68
69
70
std::optional<WebCore::DestinationColorSpace> MediaPlayerPrivateRemote::colorSpace()
71
{
72
    std::optional<DestinationColorSpace> colorSpace;
73
    if (!connection().sendSync(Messages::RemoteMediaPlayerProxy::ColorSpace(), Messages::RemoteMediaPlayerProxy::ColorSpace::Reply(colorSpace), m_id))
74
        return std::nullopt;
75
76
    return colorSpace;
77
}
78
69
RetainPtr<CVPixelBufferRef> MediaPlayerPrivateRemote::pixelBufferForCurrentTime()
79
RetainPtr<CVPixelBufferRef> MediaPlayerPrivateRemote::pixelBufferForCurrentTime()
70
{
80
{
71
81
- a/LayoutTests/imported/w3c/ChangeLog +24 lines
Lines 1-3 a/LayoutTests/imported/w3c/ChangeLog_sec1
1
2021-09-21  Cameron McCormack  <heycam@apple.com>
2
3
        Ensure canvas.drawImage(video) uses the right color space
4
        https://bugs.webkit.org/show_bug.cgi?id=229025
5
        <rdar://problem/81828490>
6
7
        Reviewed by NOBODY (OOPS!).
8
9
        Add some new WPTs for drawImage(video).
10
11
        * web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-video-expected.txt: Added.
12
        * web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-video.html: Added.
13
        * web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-video-expected.txt: Added.
14
        * web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-video.html: Added.
15
        * web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3.js:
16
        * web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-222000000.mp4: Added.
17
        * web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-222000000.webm: Added.
18
        * web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-3FF000000.mp4: Added.
19
        * web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/resources/Rec2020-3FF000000.webm: Added.
20
        * web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000.mp4: Added.
21
        * web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-BB0000.webm: Added.
22
        * web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0100.mp4: Added.
23
        * web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/resources/sRGB-FF0100.webm: Added.
24
1
2021-09-19  Cameron McCormack  <heycam@apple.com>
25
2021-09-19  Cameron McCormack  <heycam@apple.com>
2
26
3
        Preserve color space when structured cloning ImageBitmaps
27
        Preserve color space when structured cloning ImageBitmaps
- a/LayoutTests/TestExpectations +2 lines
Lines 5259-5264 imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/can a/LayoutTests/TestExpectations_sec1
5259
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-canvas.html [ Failure ]
5259
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-canvas.html [ Failure ]
5260
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html [ Failure ]
5260
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html [ Failure ]
5261
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-image.html [ Failure ]
5261
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-image.html [ Failure ]
5262
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-video.html [ Failure ]
5263
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-video.html [ Failure ]
5262
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-canvas.html [ Failure ]
5264
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-canvas.html [ Failure ]
5263
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-image.html [ Failure ]
5265
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-image.html [ Failure ]
5264
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-settings.html [ Failure ]
5266
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-settings.html [ Failure ]
- a/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-video-expected.txt +34 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-video-expected.txt_sec1
1
2
PASS sRGB-FF0100, Context srgb, ImageData srgb, cropSource=false
3
PASS sRGB-FF0100, Context srgb, ImageData srgb, cropSource=true
4
PASS sRGB-FF0100, Context srgb, ImageData display-p3, cropSource=false
5
PASS sRGB-FF0100, Context srgb, ImageData display-p3, cropSource=true
6
PASS sRGB-FF0100, Context display-p3, ImageData srgb, cropSource=false
7
PASS sRGB-FF0100, Context display-p3, ImageData srgb, cropSource=true
8
PASS sRGB-FF0100, Context display-p3, ImageData display-p3, cropSource=false
9
PASS sRGB-FF0100, Context display-p3, ImageData display-p3, cropSource=true
10
PASS sRGB-BB0000, Context srgb, ImageData srgb, cropSource=false
11
PASS sRGB-BB0000, Context srgb, ImageData srgb, cropSource=true
12
PASS sRGB-BB0000, Context srgb, ImageData display-p3, cropSource=false
13
PASS sRGB-BB0000, Context srgb, ImageData display-p3, cropSource=true
14
PASS sRGB-BB0000, Context display-p3, ImageData srgb, cropSource=false
15
PASS sRGB-BB0000, Context display-p3, ImageData srgb, cropSource=true
16
PASS sRGB-BB0000, Context display-p3, ImageData display-p3, cropSource=false
17
PASS sRGB-BB0000, Context display-p3, ImageData display-p3, cropSource=true
18
PASS Rec2020-3FF000000, Context srgb, ImageData srgb, cropSource=false
19
PASS Rec2020-3FF000000, Context srgb, ImageData srgb, cropSource=true
20
PASS Rec2020-3FF000000, Context srgb, ImageData display-p3, cropSource=false
21
PASS Rec2020-3FF000000, Context srgb, ImageData display-p3, cropSource=true
22
PASS Rec2020-3FF000000, Context display-p3, ImageData srgb, cropSource=false
23
PASS Rec2020-3FF000000, Context display-p3, ImageData srgb, cropSource=true
24
PASS Rec2020-3FF000000, Context display-p3, ImageData display-p3, cropSource=false
25
PASS Rec2020-3FF000000, Context display-p3, ImageData display-p3, cropSource=true
26
PASS Rec2020-222000000, Context srgb, ImageData srgb, cropSource=false
27
PASS Rec2020-222000000, Context srgb, ImageData srgb, cropSource=true
28
PASS Rec2020-222000000, Context srgb, ImageData display-p3, cropSource=false
29
PASS Rec2020-222000000, Context srgb, ImageData display-p3, cropSource=true
30
PASS Rec2020-222000000, Context display-p3, ImageData srgb, cropSource=false
31
PASS Rec2020-222000000, Context display-p3, ImageData srgb, cropSource=true
32
PASS Rec2020-222000000, Context display-p3, ImageData display-p3, cropSource=false
33
PASS Rec2020-222000000, Context display-p3, ImageData display-p3, cropSource=true
34
- a/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-video.html +55 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-video.html_sec1
1
<!DOCTYPE HTML>
2
<script src="/resources/testharness.js"></script>
3
<script src="/resources/testharnessreport.js"></script>
4
<script src="canvas-display-p3.js"></script>
5
<body>
6
<script>
7
// Test that drawing ImageBitmaps with different video source color profiles
8
// into sRGB and Display P3 canvases works, by reading pixels with
9
// getImageData() as sRGB and Display P3 values.
10
for (let [filenameBase, expectedPixels] of Object.entries(videoTests)) {
11
    for (let contextColorSpace of ["srgb", "display-p3"]) {
12
        for (let imageDataColorSpace of ["srgb", "display-p3"]) {
13
            for (let cropSource of [false, true]) {
14
                async_test(function(t) {
15
                    let video = document.createElement("video");
16
                    video.onloadeddata = t.step_func(function() {
17
18
                        let canvas = document.createElement("canvas");
19
                        canvas.width = 2;
20
                        canvas.height = 2;
21
22
                        let ctx = canvas.getContext("2d", { colorSpace: contextColorSpace });
23
24
                        let imageBitmapPromise;
25
                        if (cropSource)
26
                            imageBitmapPromise = createImageBitmap(video, 1, 1, 1, 1);
27
                        else
28
                            imageBitmapPromise = createImageBitmap(video);
29
30
                        imageBitmapPromise.then(t.step_func_done(function(imageBitmap) {
31
                            video.remove();
32
                            ctx.drawImage(imageBitmap, 0, 0);
33
34
                            let imageData = ctx.getImageData(0, 0, 1, 1, { colorSpace: imageDataColorSpace });
35
36
                            let expected = expectedPixels[`${contextColorSpace} ${imageDataColorSpace}`];
37
                            assert_true(pixelsApproximatelyEqual(imageData.data, expected), `Actual pixel value ${[...imageData.data]} is approximately equal to ${expected}.`);
38
                        }), t.step_func(function(error) {
39
                            video.remove();
40
                            throw error;
41
                        }));
42
                    });
43
                    for (let format of ["mp4", "webm"]) {
44
                        let source = document.createElement("source");
45
                        source.src = `resources/${filenameBase}.${format}`;
46
                        source.type = `video/${format}`;
47
                        video.append(source);
48
                    }
49
                    document.body.append(video);
50
                }, `${filenameBase}, Context ${contextColorSpace}, ImageData ${imageDataColorSpace}, cropSource=${cropSource}`);
51
            }
52
        }
53
    }
54
}
55
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-video-expected.txt +34 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-video-expected.txt_sec1
1
2
PASS sRGB-FF0100, Context srgb, ImageData srgb, scaleImage=false
3
PASS sRGB-FF0100, Context srgb, ImageData srgb, scaleImage=true
4
PASS sRGB-FF0100, Context srgb, ImageData display-p3, scaleImage=false
5
PASS sRGB-FF0100, Context srgb, ImageData display-p3, scaleImage=true
6
PASS sRGB-FF0100, Context display-p3, ImageData srgb, scaleImage=false
7
PASS sRGB-FF0100, Context display-p3, ImageData srgb, scaleImage=true
8
PASS sRGB-FF0100, Context display-p3, ImageData display-p3, scaleImage=false
9
PASS sRGB-FF0100, Context display-p3, ImageData display-p3, scaleImage=true
10
PASS sRGB-BB0000, Context srgb, ImageData srgb, scaleImage=false
11
PASS sRGB-BB0000, Context srgb, ImageData srgb, scaleImage=true
12
PASS sRGB-BB0000, Context srgb, ImageData display-p3, scaleImage=false
13
PASS sRGB-BB0000, Context srgb, ImageData display-p3, scaleImage=true
14
PASS sRGB-BB0000, Context display-p3, ImageData srgb, scaleImage=false
15
PASS sRGB-BB0000, Context display-p3, ImageData srgb, scaleImage=true
16
PASS sRGB-BB0000, Context display-p3, ImageData display-p3, scaleImage=false
17
PASS sRGB-BB0000, Context display-p3, ImageData display-p3, scaleImage=true
18
PASS Rec2020-3FF000000, Context srgb, ImageData srgb, scaleImage=false
19
PASS Rec2020-3FF000000, Context srgb, ImageData srgb, scaleImage=true
20
PASS Rec2020-3FF000000, Context srgb, ImageData display-p3, scaleImage=false
21
PASS Rec2020-3FF000000, Context srgb, ImageData display-p3, scaleImage=true
22
PASS Rec2020-3FF000000, Context display-p3, ImageData srgb, scaleImage=false
23
PASS Rec2020-3FF000000, Context display-p3, ImageData srgb, scaleImage=true
24
PASS Rec2020-3FF000000, Context display-p3, ImageData display-p3, scaleImage=false
25
PASS Rec2020-3FF000000, Context display-p3, ImageData display-p3, scaleImage=true
26
PASS Rec2020-222000000, Context srgb, ImageData srgb, scaleImage=false
27
PASS Rec2020-222000000, Context srgb, ImageData srgb, scaleImage=true
28
PASS Rec2020-222000000, Context srgb, ImageData display-p3, scaleImage=false
29
PASS Rec2020-222000000, Context srgb, ImageData display-p3, scaleImage=true
30
PASS Rec2020-222000000, Context display-p3, ImageData srgb, scaleImage=false
31
PASS Rec2020-222000000, Context display-p3, ImageData srgb, scaleImage=true
32
PASS Rec2020-222000000, Context display-p3, ImageData display-p3, scaleImage=false
33
PASS Rec2020-222000000, Context display-p3, ImageData display-p3, scaleImage=true
34
- a/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-video.html +46 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-video.html_sec1
1
<!DOCTYPE HTML>
2
<script src="/resources/testharness.js"></script>
3
<script src="/resources/testharnessreport.js"></script>
4
<script src="canvas-display-p3.js"></script>
5
<body>
6
<script>
7
// Test that drawing videos with different color spaces into sRGB and Display P3
8
// canvases works, by reading pixels with getImageData() as sRGB and Display P3
9
// values.
10
for (let [filenameBase, expectedPixels] of Object.entries(videoTests)) {
11
    for (let contextColorSpace of ["srgb", "display-p3"]) {
12
        for (let imageDataColorSpace of ["srgb", "display-p3"]) {
13
            for (let scaleImage of [false, true]) {
14
                async_test(function(t) {
15
                    let video = document.createElement("video");
16
                    video.onloadeddata = t.step_func_done(function() {
17
18
                        let canvas = document.createElement("canvas");
19
                        canvas.width = 2;
20
                        canvas.height = 2;
21
22
                        let ctx = canvas.getContext("2d", { colorSpace: contextColorSpace });
23
                        if (scaleImage)
24
                            ctx.drawImage(video, 0, 0, 10, 10);
25
                        else
26
                            ctx.drawImage(video, 0, 0);
27
                        video.remove();
28
29
                        let imageData = ctx.getImageData(0, 0, 1, 1, { colorSpace: imageDataColorSpace });
30
31
                        let expected = expectedPixels[`${contextColorSpace} ${imageDataColorSpace}`];
32
                        assert_true(pixelsApproximatelyEqual(imageData.data, expected), `Actual pixel value ${[...imageData.data]} is approximately equal to ${expected}.`);
33
                    });
34
                    for (let format of ["mp4", "webm"]) {
35
                        let source = document.createElement("source");
36
                        source.src = `resources/${filenameBase}.${format}`;
37
                        source.type = `video/${format}`;
38
                        video.append(source);
39
                    }
40
                    document.body.append(video);
41
                }, `${filenameBase}, Context ${contextColorSpace}, ImageData ${imageDataColorSpace}, scaleImage=${scaleImage}`);
42
            }
43
        }
44
    }
45
}
46
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3.js +53 lines
Lines 177-182 const imageTests = { a/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3.js_sec1
177
    },
177
    },
178
};
178
};
179
179
180
// Each video:
181
//  * is 300x200 and has a single color
182
//  * has a filename base that indicates its contents:
183
//
184
//      <color-space>-<8-or-10-bit-color-value>
185
//
186
//  * was generated using commands like:
187
//
188
//      W=300 H=200 Y=3F Cb=66 Cr=F0 ; \
189
//        perl -e "print pack('c', 0x$Y) x ($W * $H), pack('c', 0x$Cb) x ($W * $H / 4), pack('c', 0x$Cr) x ($W * $H / 4)" | \
190
//        ffmpeg -f rawvideo -pix_fmt yuv420p -s:v ${W}x$H -r 25 -i - -pix_fmt yuv420p -colorspace bt709 -color_primaries bt709 -color_trc iec61966_2_1 sRGB-FF0100.webm
191
//
192
//      W=300 H=200 Y=0BB Cb=1BD Cr=2EF ; \
193
//        perl -e "print pack('s', 0x$Y) x ($W * $H), pack('s', 0x$Cb) x ($W * $H / 4), pack('s', 0x$Cr) x ($W * $H / 4)" | \
194
//        ffmpeg -f rawvideo -pix_fmt yuv420p10le -s:v ${W}x$H -r 25 -i - -c:v libx265 -vtag hvc1 -pix_fmt yuv420p10le -colorspace bt2020nc -color_primaries bt2020 -color_trc bt2020-10 Rec2020-222000000.mp4
195
//
196
//      W=300 H=200 Y=0BB Cb=1BD Cr=2EF ; \
197
//        perl -e "print pack('s', 0x$Y) x ($W * $H), pack('s', 0x$Cb) x ($W * $H / 4), pack('s', 0x$Cr) x ($W * $H / 4)" | \
198
//        ffmpeg -f rawvideo -pix_fmt yuv420p10le -s:v ${W}x$H -r 25 -i - -vcodec libvpx-vp9 -profile:v 2 -pix_fmt yuv420p10le -colorspace bt2020nc -color_primaries bt2020 -color_trc bt2020-10 Rec2020-222000000.webm
199
//
200
//    where the Y'CbCr values were computed using https://jdashg.github.io/misc/colors/from-coeffs.html.
201
const videoTests = {
202
    // Rec.709 Y'CbCr (0x3F, 0x66, 0xF0) = sRGB (0xFF, 0x01, 0x00)
203
    "sRGB-FF0100": {
204
        "srgb srgb": [255, 1, 0, 255],
205
        "srgb display-p3": [234, 51, 35, 255],
206
        "display-p3 srgb": [255, 0, 0, 255],
207
        "display-p3 display-p3": [234, 51, 35, 255],
208
    },
209
    // Rec.709 Y'CbCr (0x32, 0x6D, 0xD2) = sRGB (0xBB, 0x00, 0x00)
210
    "sRGB-BB0000": {
211
        "srgb srgb": [187, 0, 0, 255],
212
        "srgb display-p3": [171, 35, 23, 255],
213
        "display-p3 srgb": [187, 1, 0, 255],
214
        "display-p3 display-p3": [171, 35, 23, 255],
215
    },
216
217
    // 10 bit Rec.2020 Y'CbCr (0x126, 0x183, 0x3C0) = Rec.2020 (0x3FF, 0x000, 0x000)
218
    "Rec2020-3FF000000": {
219
        "srgb srgb": [255, 0, 0, 255],
220
        "srgb display-p3": [234, 51, 35, 255],
221
        "display-p3 srgb": [255, 0, 0, 255],
222
        "display-p3 display-p3": [255, 0, 9, 255],
223
    },
224
    // 10 bit Rec.2020 Y'CbCr (0x0BB, 0x1BD, 0x2EF) = Rec.2020 (0x222, 0x000, 0x000)
225
    "Rec2020-222000000": {
226
        "srgb srgb": [186, 0, 0, 255],
227
        "srgb display-p3": [170, 34, 23, 255],
228
        "display-p3 srgb": [186, 0, 0, 255],
229
        "display-p3 display-p3": [169, 0, 3, 255],
230
    },
231
};
232
180
const fromSRGBToDisplayP3 = {
233
const fromSRGBToDisplayP3 = {
181
    "255,0,0,255": [234, 51, 35, 255],
234
    "255,0,0,255": [234, 51, 35, 255],
182
    "255,0,0,204": [234, 51, 35, 204],
235
    "255,0,0,204": [234, 51, 35, 204],
- a/LayoutTests/platform/ios-14/TestExpectations +2 lines
Lines 78-83 imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/can a/LayoutTests/platform/ios-14/TestExpectations_sec1
78
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-canvas.html [ Failure ]
78
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-canvas.html [ Failure ]
79
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html [ Failure ]
79
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html [ Failure ]
80
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-image.html [ Failure ]
80
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-image.html [ Failure ]
81
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-video.html [ Failure ]
82
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-video.html [ Failure ]
81
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-canvas.html [ Failure ]
83
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-canvas.html [ Failure ]
82
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-image.html [ Failure ]
84
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-image.html [ Failure ]
83
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-settings.html [ Failure ]
85
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-settings.html [ Failure ]
- a/LayoutTests/platform/ios/TestExpectations +2 lines
Lines 3494-3499 imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/can a/LayoutTests/platform/ios/TestExpectations_sec1
3494
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-canvas.html [ Pass ]
3494
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-canvas.html [ Pass ]
3495
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html [ Pass ]
3495
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html [ Pass ]
3496
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-image.html [ Pass ]
3496
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-image.html [ Pass ]
3497
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-video.html [ Pass ]
3498
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-video.html [ Pass ]
3497
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-canvas.html [ Pass ]
3499
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-canvas.html [ Pass ]
3498
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-image.html [ Pass ]
3500
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-image.html [ Pass ]
3499
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-settings.html [ Pass ]
3501
imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-settings.html [ Pass ]
- a/LayoutTests/platform/mac/TestExpectations +2 lines
Lines 2357-2362 webkit.org/b/230116 imported/w3c/web-platform-tests/webrtc-extensions/transfer-d a/LayoutTests/platform/mac/TestExpectations_sec1
2357
[ Monterey+ ] imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-canvas.html [ Pass ]
2357
[ Monterey+ ] imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-canvas.html [ Pass ]
2358
[ Monterey+ ] imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html [ Pass ]
2358
[ Monterey+ ] imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html [ Pass ]
2359
[ Monterey+ ] imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-image.html [ Pass ]
2359
[ Monterey+ ] imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-image.html [ Pass ]
2360
[ Monterey+ ] imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-video.html [ Pass ]
2361
[ Monterey+ ] imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-video.html [ Pass ]
2360
[ Monterey+ ] imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-canvas.html [ Pass ]
2362
[ Monterey+ ] imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-canvas.html [ Pass ]
2361
[ Monterey+ ] imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-image.html [ Pass ]
2363
[ Monterey+ ] imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-image.html [ Pass ]
2362
[ Monterey+ ] imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-settings.html [ Pass ]
2364
[ Monterey+ ] imported/w3c/web-platform-tests/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-settings.html [ Pass ]

Return to Bug 229025