Bug 230429 - ImageBitmap structured clone doesn't preserve color space
Summary: ImageBitmap structured clone doesn't preserve color space
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Canvas (show other bugs)
Version: WebKit Local Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Cameron McCormack (:heycam)
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2021-09-17 14:03 PDT by Cameron McCormack (:heycam)
Modified: 2021-09-30 17:02 PDT (History)
9 users (show)

See Also:


Attachments
Patch for EWS (70.06 KB, patch)
2021-09-19 22:15 PDT, Cameron McCormack (:heycam)
ews-feeder: commit-queue-
Details | Formatted Diff | Diff
Patch for EWS (70.10 KB, patch)
2021-09-19 22:30 PDT, Cameron McCormack (:heycam)
ews-feeder: commit-queue-
Details | Formatted Diff | Diff
Patch (70.45 KB, patch)
2021-09-19 22:57 PDT, Cameron McCormack (:heycam)
no flags Details | Formatted Diff | Diff
Patch (69.92 KB, patch)
2021-09-27 19:26 PDT, Cameron McCormack (:heycam)
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Cameron McCormack (:heycam) 2021-09-17 14:03:23 PDT
We need a way to serialize the DestinationColorSpace when structured cloning.
Comment 1 Radar WebKit Bug Importer 2021-09-19 22:01:31 PDT
<rdar://problem/83293533>
Comment 2 Cameron McCormack (:heycam) 2021-09-19 22:15:27 PDT
Created attachment 438634 [details]
Patch for EWS
Comment 3 EWS Watchlist 2021-09-19 22:16:24 PDT
This patch modifies the imported WPT tests. Please ensure that any changes on the tests (not coming from a WPT import) are exported to WPT. Please see https://trac.webkit.org/wiki/WPTExportProcess
Comment 4 Cameron McCormack (:heycam) 2021-09-19 22:30:25 PDT
Created attachment 438635 [details]
Patch for EWS
Comment 5 Cameron McCormack (:heycam) 2021-09-19 22:57:05 PDT
Created attachment 438637 [details]
Patch
Comment 6 Cameron McCormack (:heycam) 2021-09-26 18:14:04 PDT
I'm including the fix for the flaky WPT in https://github.com/web-platform-tests/wpt/pull/30844, which is the export from bug 229022, since without the fix that PR is blocked from merging.
Comment 7 Sam Weinig 2021-09-27 17:42:47 PDT
Comment on attachment 438637 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=438637&action=review

> Source/WebCore/bindings/js/SerializedScriptValue.cpp:36
> +#if PLATFORM(COCOA)
> +#include <CoreFoundation/CoreFoundation.h>
> +#endif
> +#if USE(CG)
> +#include <CoreGraphics/CoreGraphics.h>
> +#endif

I would put these under the rest of the #includes (they sort down their due to the "<").

> Source/WebCore/bindings/js/SerializedScriptValue.cpp:1111
> -        PixelBufferFormat format { AlphaPremultiplication::Premultiplied, PixelFormat::RGBA8, DestinationColorSpace::SRGB() };
> +        PixelBufferFormat format { AlphaPremultiplication::Premultiplied, PixelFormat::RGBA8, buffer->colorSpace() };

Probably worth putting a comment about adding support for pixel format preservation (or adding that now if it is easy enough, not sure what the canonical representations are, perhaps the CoreVideo 4 character codes?)

> Source/WebCore/bindings/js/SerializedScriptValue.cpp:1624
> +        auto colorSpace = destinationColorSpace.platformColorSpace();
> +        if (!colorSpace) {
> +            write(DestinationColorSpaceCGColorSpaceNullTag);
> +            return;
> +        }

I tried to make it so DestinationColorSpace never had a null CGColorSpaceRef (and people would use std::optional<DestinationColorSpace> for a nullable one). Do you know of any cases where this is happening?

> Source/WebCore/bindings/js/SerializedScriptValue.cpp:1667
> +#endif
> +#else
> +        switch (destinationColorSpace.platformColorSpace()) {
> +        case PlatformColorSpace::Name::SRGB:
> +            write(DestinationColorSpaceSRGBTag);
> +            break;
> +#if ENABLE(DESTINATION_COLOR_SPACE_LINEAR_SRGB)
> +        case PlatformColorSpace::Name::LinearSRGB:
> +            write(DestinationColorSpaceLinearSRGBTag);
> +            break;
> +#endif
> +#if ENABLE(DESTINATION_COLOR_SPACE_DISPLAY_P3)
> +        case PlatformColorSpace::Name::DisplayP3:
> +            write(DestinationColorSpaceDisplayP3Tag);
> +            break;
> +#endif

One option to make the common cases faster would be to have these special tags for both Cocoa and non-Cocoa (but run before the color space code above). That way, we only encode the tag in the common case, and we have better code coverage for these on all platforms.
Comment 8 Cameron McCormack (:heycam) 2021-09-27 17:45:58 PDT
(In reply to Sam Weinig from comment #7)
> I tried to make it so DestinationColorSpace never had a null CGColorSpaceRef
> (and people would use std::optional<DestinationColorSpace> for a nullable
> one). Do you know of any cases where this is happening?

I don't, but I saw some code somewhere that was checking for it explicitly.  I'll consider it more of an error case then, and add some assertions.
Comment 9 Cameron McCormack (:heycam) 2021-09-27 19:26:12 PDT
Created attachment 439426 [details]
Patch
Comment 10 EWS 2021-09-28 14:10:28 PDT
Committed r283193 (242240@main): <https://commits.webkit.org/242240@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 439426 [details].
Comment 11 Sam Weinig 2021-09-30 16:03:06 PDT
(In reply to Cameron McCormack (:heycam) from comment #8)
> (In reply to Sam Weinig from comment #7)
> > I tried to make it so DestinationColorSpace never had a null CGColorSpaceRef
> > (and people would use std::optional<DestinationColorSpace> for a nullable
> > one). Do you know of any cases where this is happening?
> 
> I don't, but I saw some code somewhere that was checking for it explicitly. 

Where was that?
Comment 12 Cameron McCormack (:heycam) 2021-09-30 16:33:24 PDT
(In reply to Sam Weinig from comment #11)
> (In reply to Cameron McCormack (:heycam) from comment #8)
> > (In reply to Sam Weinig from comment #7)
> > > I tried to make it so DestinationColorSpace never had a null CGColorSpaceRef
> > > (and people would use std::optional<DestinationColorSpace> for a nullable
> > > one). Do you know of any cases where this is happening?
> > 
> > I don't, but I saw some code somewhere that was checking for it explicitly. 
> 
> Where was that?

I think it was my misreading of DestinationColorSpace::decode's `if (!platformColorSpace)` as being a check for the PlatformColorSpace being null, rather than whether the decoder succeeded.

In the end I didn't add any new assertions, as I saw you already had one in the DestinationColorSpace constructor.
Comment 13 Sam Weinig 2021-09-30 17:02:12 PDT
Great. Thanks.