RESOLVED FIXED Bug 273239
[Skia] Fix corner cases involving drawing shadows
https://bugs.webkit.org/show_bug.cgi?id=273239
Summary [Skia] Fix corner cases involving drawing shadows
Pawel Lampe
Reported 2024-04-25 02:46:31 PDT
See LayoutTests failures such as: imported/w3c/web-platform-tests/html/canvas/offscreen/shadows/2d.shadow.composite.1.html imported/w3c/web-platform-tests/html/canvas/offscreen/shadows/2d.shadow.composite.1.worker.html imported/w3c/web-platform-tests/html/canvas/offscreen/shadows/2d.shadow.composite.2.html imported/w3c/web-platform-tests/html/canvas/offscreen/shadows/2d.shadow.composite.2.worker.html imported/w3c/web-platform-tests/html/canvas/offscreen/shadows/2d.shadow.enable.blur.html imported/w3c/web-platform-tests/html/canvas/offscreen/shadows/2d.shadow.enable.blur.worker.html imported/w3c/web-platform-tests/html/canvas/offscreen/shadows/2d.shadow.enable.x.html imported/w3c/web-platform-tests/html/canvas/offscreen/shadows/2d.shadow.enable.x.worker.html imported/w3c/web-platform-tests/html/canvas/offscreen/shadows/2d.shadow.enable.y.html imported/w3c/web-platform-tests/html/canvas/offscreen/shadows/2d.shadow.enable.y.worker.html imported/w3c/web-platform-tests/html/canvas/offscreen/shadows/2d.shadow.image.alpha.html imported/w3c/web-platform-tests/html/canvas/offscreen/shadows/2d.shadow.image.basic.html imported/w3c/web-platform-tests/html/canvas/offscreen/shadows/2d.shadow.image.scale.html imported/w3c/web-platform-tests/html/canvas/offscreen/shadows/2d.shadow.image.transparent.2.html
Attachments
Pawel Lampe
Comment 1 2024-04-25 03:10:27 PDT
See more LayoutTests failures such as: imported/w3c/web-platform-tests/html/canvas/element/shadows/2d.shadow.composite.1.html imported/w3c/web-platform-tests/html/canvas/element/shadows/2d.shadow.composite.2.html imported/w3c/web-platform-tests/html/canvas/element/shadows/2d.shadow.enable.blur.html imported/w3c/web-platform-tests/html/canvas/element/shadows/2d.shadow.enable.x.html imported/w3c/web-platform-tests/html/canvas/element/shadows/2d.shadow.enable.y.html css3/color-filters/color-filter-text-decoration-shadow.html fast/canvas/canvas-scale-shadowBlur.html fast/canvas/canvas-strokePath-gradient-shadow.html fast/canvas/canvas-strokeRect-alpha-shadow.html fast/canvas/canvas-strokeRect-gradient-shadow.html
Pawel Lampe
Comment 2 2024-04-25 03:32:21 PDT
In general the above failures are due to 2 distict problems: 1) Skia bug when drawing an image with a shadow filter: Currently, when we draw an image with shadow, we do this using a single call: m_canvas.drawImageRect(image, normalizedSrcRect, normalizedDestRect, toSkSamplingOptions(m_state.imageInterpolationQuality()), &paint, { }); which uses a paint (SkPaint) with SkImageFilters::DropShadow attached using paint.setImageFilter(). While this works in most of the cases, it turns out that sometimes - when SkImageFilters::DropShadow is attached, and the <canvas> size is very close to the size of image being drawn - the above call draws no shadow (or nothing if I recall correctly). So far I've observed that it happens only when the image we're drawing is using accelerated surface, so e.g. if we uncomment the line in below demo (and comment the one above) the issue is gone: <html> <head> </head> <body> <img id="img" src="/images/red.png" style="visibility:hidden"> <canvas id="canvas" width="166" height="99" style="border: 1px solid #000"/> <script> var img = document.getElementById("img"); img.onload = async () => { var canvas = document.getElementById("canvas"); var ctx = canvas.getContext('2d'); ctx.fillStyle = '#00f'; ctx.fillRect(0, 0, 100, 50); ctx.shadowColor = '#0f0'; ctx.shadowOffsetY = 50; var x = await createImageBitmap(img); // var x = img; ctx.drawImage(x, 0, -25); } </script> </body> </html the red.png comes from LayoutTests/imported/w3c/web-platform-tests/ 2) Every time we draw something with a shadow, we do it within a single draw call with shadow filter attached. While this approach is very clean and efficient, it makes it impossible to handle cases where the certain class of composite operators come into play. More precisely, the operators such as "destination-atop" etc. assume that drawing of e.g. rect with shadow is done in 2 steps: first draw the shadow, then the rect. In such case, having composite operation such as "destination-atop" would make the shadow to appear over the rect since shadow was on canvas before rect, and therefore it serves as a "desitnation" when rect is being drawn.
Pawel Lampe
Comment 3 2024-05-06 05:07:13 PDT
fast/canvas/canvas-scale-shadowBlur.html fast/canvas/canvas-strokePath-gradient-shadow.html fast/canvas/canvas-strokeRect-alpha-shadow.html fast/canvas/canvas-strokeRect-gradient-shadow.html tests were extracted to https://bugs.webkit.org/show_bug.cgi?id=273766
Pawel Lampe
Comment 4 2024-05-13 01:16:22 PDT
EWS
Comment 5 2024-06-14 03:58:46 PDT
Committed 280008@main (120f5b1d4f90): <https://commits.webkit.org/280008@main> Reviewed commits have been landed. Closing PR #28168 and removing active labels.
Note You need to log in before you can comment on or make changes to this bug.