WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
NEW
282530
mask-image broken with mask-mode: luminance
https://bugs.webkit.org/show_bug.cgi?id=282530
Summary
mask-image broken with mask-mode: luminance
Tuur Martens
Reported
2024-11-04 02:42:16 PST
Created
attachment 473123
[details]
minimal reproduction file Sorry for the bad title. I've been trying to find out exactly what is going on, but it hasn't been easy. Anyhow, I'm not sure of exactly what triggers this bug, which I realize isn't very helpful. I'll post this here so perhaps more eyes could look into it, as will I, as much as is possible. Scenario sketch: I want a gradient "blob". I tried to use a blurred out SVG for that, but that caused rendering issues in every single browser I tried. So we opted to use a solid color div with a mask applied to it. I got the mask small enough to fit in 1.5KiB, so it's part of the html file because I can only seem to attach one attachment. For some reason this mask works only sometimes, and the only browsers where I encounter issues are webkit-based. In the attached file it seems to work on some window widths, but not others, so try messing with the window size. Once again my apologies for making such a vague report, but my intention is to bring more eyes upon the issue. What actually happens: The result SOMETIMES is a solid color, as if the mask was never applied. Other times, it behaves as expected. Possibly related to image size. What is supposed to happen: The mask is visually applied. Reproduced in: WebKitGTK 2.46.1 GStreamer 1.24.7 GTK 4.17.0 Libadwaita 1.7.0 Distributor: GNOME
Attachments
minimal reproduction file
(2.50 KB, text/html)
2024-11-04 02:42 PST
,
Tuur Martens
no flags
Details
Clearer testcase
(4.70 KB, text/html)
2024-11-05 09:55 PST
,
Simon Fraser (smfr)
no flags
Details
Svg minimal Reproduction
(1.05 KB, text/html)
2024-11-27 02:53 PST
,
derplayer2001
no flags
Details
rendering in safari, firefox, chrome
(2.34 MB, image/png)
2025-05-19 18:54 PDT
,
Karl Dubost
no flags
Details
View All
Add attachment
proposed patch, testcase, etc.
Alexey Proskuryakov
Comment 1
2024-11-04 13:14:21 PST
I can reproduce this in Safari too.
Simon Fraser (smfr)
Comment 2
2024-11-05 09:55:40 PST
Created
attachment 473145
[details]
Clearer testcase Seems to happen when things go above a certain size.
Radar WebKit Bug Importer
Comment 3
2024-11-05 09:56:57 PST
<
rdar://problem/139292158
>
Simon Fraser (smfr)
Comment 4
2024-11-05 09:58:01 PST
It's not about the WebP image; this happens with a gradient too.
Simon Fraser (smfr)
Comment 5
2024-11-05 10:04:04 PST
Drawing commands for the good state: handleItem save handleItem clip (rect (8,50) width=1272 height=833) handleItem begin-transparency-layer (opacity 1.00) handleItem fill-composited-rect (rect (8,50) width=1272 height=833) (color #FF0000) (composite-operation source-over) (blend-mode normal) handleItem set-state (change-flags [composite-mode]) (composite-mode (composite-operation destination-in) (blend-mode normal)) handleItem begin-transparency-layer (opacity 1.00) handleItem set-state (change-flags [draw-luminance-mask]) (draw-luminance-mask 1) handleItem save handleItem clip (rect (8,50) width=1272 height=833) handleItem save handleItem set-state (change-flags [composite-mode]) (composite-mode (composite-operation source-over) (blend-mode normal)) handleItem clip (rect (8,50) width=1272 height=833) handleItem translate (x 8.00) (y 50.00) handleItem fill-rect-with-gradient (rect (0,0) width=1272 height=833) handleItem restore handleItem restore handleItem end-transparency-layer handleItem end-transparency-layer handleItem restore Drawing commands for the bad state: handleItem save handleItem clip (rect (8,50) width=1199 height=833) handleItem begin-transparency-layer (opacity 1.00) handleItem fill-composited-rect (rect (8,50) width=1199 height=833) (color #FF0000) (composite-operation source-over) (blend-mode normal) handleItem set-state (change-flags [composite-mode]) (composite-mode (composite-operation destination-in) (blend-mode normal)) handleItem begin-transparency-layer (opacity 1.00) handleItem set-state (change-flags [draw-luminance-mask]) (draw-luminance-mask 0) handleItem draw-pattern (image-identifier 479) (pattern-transform {m=((0.50,0.00)(0.00,0.50)) t=(0.00,0.00)}) (tile-rect (0,0) width=2 height=1666) (dest-rect (8,50) width=1199 height=833) (phase (8,50)) (spacing width=0 height=0) handleItem end-transparency-layer handleItem end-transparency-layer handleItem restore
Simon Fraser (smfr)
Comment 6
2024-11-05 17:16:05 PST
Here's the reason for the divergence: const float maxPatternTilePixels = 2048 * 2048;
Simon Fraser (smfr)
Comment 7
2024-11-05 17:51:46 PST
Comment hidden (obsolete)
drawPattern always turns off the luminance mask state: destContext.setDrawLuminanceMask(false); destContext.drawPattern(Ref { *m_cachedImage }, destRect, adjustedSrcRect, adjustedPatternCTM, phase, spacing, options);
Simon Fraser (smfr)
Comment 8
2024-11-05 18:09:07 PST
`mask-mode: luminance` just seems broken in general.
derplayer2001
Comment 9
2024-11-25 10:55:35 PST
I'm having the same bug with a very lightweight svg that im masking, curiously the result changes from Safari on IOS to Safari on OSX as I only encounter it on IOS... smaller size seems to fix the problem though.
derplayer2001
Comment 10
2024-11-27 02:53:46 PST
Created
attachment 473379
[details]
Svg minimal Reproduction
Estelle Weyl
Comment 11
2025-05-19 18:10:06 PDT
mask-mode is broken in safari because mask-type for `<mask>` defaults to `alpha` when it should default to luminance, therefore `mask-mode: match-source` is usually incorrect. See
https://github.com/mdn/browser-compat-data/issues/26632
Karl Dubost
Comment 12
2025-05-19 18:53:34 PDT
Strange.
https://searchfox.org/wubkat/rev/46bcbfb3cf5ebc591f1c02f41c178e1d13062554/Source/WebCore/rendering/style/RenderStyleConstants.h#376-382
```cpp // CSS3 Mask Mode enum class MaskMode : uint8_t { Alpha, Luminance, MatchSource, }; ```
https://searchfox.org/wubkat/rev/46bcbfb3cf5ebc591f1c02f41c178e1d13062554/Source/WebCore/rendering/style/SVGRenderStyleDefs.h#140-143
```cpp enum class MaskType : uint8_t { Luminance, Alpha }; ``` and
https://searchfox.org/wubkat/rev/46bcbfb3cf5ebc591f1c02f41c178e1d13062554/Source/WebCore/rendering/style/SVGRenderStyle.h#95
```cpp static MaskType initialMaskType() { return MaskType::Luminance; } ```
https://drafts.fxtf.org/css-masking/#the-mask-mode
<masking-mode> = alpha | luminance | match-source Initial: match-source
https://drafts.fxtf.org/css-masking/#propdef-mask-type
Value: luminance | alpha Initial: luminance
Karl Dubost
Comment 13
2025-05-19 18:54:30 PDT
Created
attachment 475312
[details]
rendering in safari, firefox, chrome Safari Technology Preview 18.4 20622.1.12 Firefox Nightly 140.0a1 14025.5.8 Google Chrome Canary 138.0.7189.0 7189.0
Karl Dubost
Comment 14
2025-05-19 19:00:05 PDT
https://searchfox.org/wubkat/rev/46bcbfb3cf5ebc591f1c02f41c178e1d13062554/Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp#137-138
```cpp if (svgStyle->maskType() == MaskType::Luminance) maskImage->convertToLuminanceMask(); ```
https://searchfox.org/wubkat/rev/46bcbfb3cf5ebc591f1c02f41c178e1d13062554/Source/WebCore/platform/graphics/ImageBuffer.cpp#501-505
```cpp void ImageBuffer::convertToLuminanceMask() { if (auto* backend = ensureBackend()) backend->convertToLuminanceMask(); } ```
https://searchfox.org/wubkat/rev/46bcbfb3cf5ebc591f1c02f41c178e1d13062554/Source/WebCore/platform/graphics/ImageBufferBackend.cpp#74-97
```cpp void ImageBufferBackend::convertToLuminanceMask() { IntRect sourceRect { { }, size() }; PixelBufferFormat format { AlphaPremultiplication::Unpremultiplied, PixelFormat::RGBA8, colorSpace() }; auto pixelBuffer = ImageBufferAllocator().createPixelBuffer(format, sourceRect.size()); if (!pixelBuffer) return; getPixelBuffer(sourceRect, *pixelBuffer); unsigned pixelArrayLength = pixelBuffer->bytes().size(); for (unsigned pixelOffset = 0; pixelOffset < pixelArrayLength; pixelOffset += 4) { uint8_t a = pixelBuffer->item(pixelOffset + 3); if (!a) continue; uint8_t r = pixelBuffer->item(pixelOffset); uint8_t g = pixelBuffer->item(pixelOffset + 1); uint8_t b = pixelBuffer->item(pixelOffset + 2); double luma = (r * 0.2125 + g * 0.7154 + b * 0.0721) * ((double)a / 255.0); pixelBuffer->set(pixelOffset + 3, luma); } putPixelBuffer(*pixelBuffer, sourceRect, IntPoint::zero(), AlphaPremultiplication::Premultiplied); } ```
Karl Dubost
Comment 15
2025-05-19 19:02:39 PDT
(In reply to derplayer2001 from
comment #9
)
> I'm having the same bug with a very lightweight svg that im masking, > curiously the result changes from Safari on IOS to Safari on OSX as I only > encounter it on IOS... smaller size seems to fix the problem though.
this would align with what Simon was mentioning.
https://searchfox.org/wubkat/rev/46bcbfb3cf5ebc591f1c02f41c178e1d13062554/Source/WebCore/platform/graphics/Image.cpp#253-261
```cpp // Patterned images and gradients can use lots of memory for caching when the // tile size is large (<
rdar://problem/4691859
>, <
rdar://problem/6239505
>). // Memory consumption depends on the transformed tile size which can get // larger than the original tile if user zooms in enough. #if PLATFORM(IOS_FAMILY) const float maxPatternTilePixels = 512 * 512; #else const float maxPatternTilePixels = 2048 * 2048; #endif ```
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug