Closed Bug 1577566 Opened 5 years ago Closed 5 years ago

filter is not rendering in SVG (with the default hardware-accelerated graphics backend on Windows)

Categories

(Core :: Graphics, defect, P5)

Unspecified
Windows
defect

Tracking

()

RESOLVED FIXED
mozilla71
Tracking Status
firefox71 --- fixed

People

(Reporter: toddpmain, Assigned: mstange, NeedInfo)

References

Details

Attachments

(6 files)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36

Steps to reproduce:

Created an SVG with a filter applied to a shape that uses feMorphology, feGaussianBlur, and feMerge. Then I created a <use/> to copy the shape and flip it. Here is the code:
<svg name="glow only" x="100" y="50" overflow="visible" fill="green" stroke="orange" stroke-width="3.25">
<defs>
<filter id="glow" color-interpolation-filters="sRGB" x="-20%" y="-20%" width="140%" height="140%" filterUnits="objectBoundingBox">
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0.2 0 0 0 0 0.2 0 0 0 0 1 0 0 0 100 0" result="glowColor" />
<feMorphology operator="dilate" radius="5.5" in="glowColor" result="thickenify" />
<feGaussianBlur in="thickenify" stdDeviation="2.5" result="glowIt" />
<feMerge>
<feMergeNode in="glowIt" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
<g filter="url(#glow)">
<use id="mirroredContent" xlink:href="#contentForMirroringWithFilter" transform="matrix(1,0,0,-1,4.89842541528951E-16,155.25)" />
<g id="contentForMirroringWithFilter">
<path d="M0,0L60,0L72,12L72,72L0,72Z" />
</g>
</g>
</svg>

Actual results:

In the case of the filter being applied to the original shape, it never gets applied. The <use/>'d shape also does not get the filter applied.

The version of Firefox I'm using is: v.68.0.2 (64-bit) Windows 10. In the Product/Version above, I put "Core, 68 Branch". I'm assuming this maps to v.68.0.2 (64-bit) Windows 10.

Expected results:

The filter should be applied. It works completely in MS Edge and partially in Chrome. The expectation is that it should work as it does in MS Edge. See attached image.

Attachment #9089154 - Attachment mime type: text/plain → image/svg+xml

Seems OK on a mac.

Does turning off hardware acceleration make any difference? (https://techdows.com/2017/08/firefox-55-disable-hardware-acceleration.html)

I've turned off hardware acceleration - no difference. Still no glow on original or mirrored shape.

Did you restart Firefox after turning off hardware acceleration? (I believe you need to do that, for it to take effect.)

I can reproduce this issue on Windows 10 -- but for me, the bug does go away (i.e. the blue glow does end up showing) if I turn off hardware acceleration and restart Firefox.

Flags: needinfo?(toddpmain)

The bug also goes away if I force-enable WebRender (i.e. if I visit about:config, search for gfx.webrender.all and set it to true, and restart Firefox).

So this seems to be a bug in our Windows non-webrender hardware-accelerated graphics-library wrapper code. (which I think is our Direct2D code?) I think this belongs in the Graphics component, probably - SVG happens to be the way to trigger it, but it's likely a bug in our graphics code.

Status: UNCONFIRMED → NEW
Component: SVG → Graphics
Ever confirmed: true
Summary: filter is not created in SVG for original and <use/> shape → filter is not rendering in SVG (with the default hardware-accelerated graphics backend on Windows)
Version: 68 Branch → Trunk

I turned off hardware acceleration, closed Firefox, and restarted it. In this case, the blue glow does render correctly.

I visited about:config, searched for gfx.webrender.all and set it to true, closed Firefox, and restarted it. In this case, the blue glow does render correctly.

Neither of those settings are default in Firefox, right?

Flags: needinfo?(toddpmain)

Not yet but webrender is intended to become default on at some future point.

I did a quick moz-regression run and found that this has been broken for over 3 years (gave up at that point).

The bug is specifically with our direct2d backend. If I remove direct2d from gfx.content.azure.backends the problem is fixed.

So this is a clear correctness issue, but it's been wrong for years with seemingly no one noticing, and is fixed by the new webrender backend. In addition, we apparently don't really have anyone actively maintaining the d2d backend these days (used to primarily be handled by Bas).

Note that it works fine with skia, so "disable d2d" is technically a fix, although probably an unacceptable one.

Has Regression Range: --- → irrelevant
Has STR: --- → yes
OS: Unspecified → Windows
Priority: -- → P5

Todd, could you reduce the testcase to the bare minimum that shows the bug? That would make it easier to debug. (I'm not promising to debug it, but maybe it'll be easy to find the bug once we know exactly what aspect of the testcase causes it.) It would also make for a good regression test case that we could land into the tree.

Markus,
It's about as simple as I can make it. That said, the "blur" can be removed.

I think I've discovered the exact problem. It is with <feColorMatrix/>. The issue seems to be with the alpha boost I applied - which is "100". Note that this doesn't work:
<svg x="100" y="50" overflow="visible" fill="green" stroke="orange" stroke-width="3.25">
<defs>
<filter id="glow" color-interpolation-filters="sRGB" x="-20%" y="-20%" width="140%" height="140%" filterUnits="objectBoundingBox">
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0.2 0 0 0 0 0.2 0 0 0 0 1 0 0 0 100 0" result="glowColor" />
<feMorphology operator="dilate" radius="5.5" in="glowColor" result="thickenify" />
<feMerge>
<feMergeNode in="glowIt" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
<g filter="url(#glow)">
<use id="mirroredContent" xlink:href="#contentForMirroringWithFilter" transform="matrix(1,0,0,-1,4.89842541528951E-16,155.25)" />
<g id="contentForMirroringWithFilter">
<path d="M0,0L60,0L72,12L72,72L0,72Z" />
</g>
</g>
</svg>

But this one does:
<svg x="100" y="50" overflow="visible" fill="green" stroke="orange" stroke-width="3.25">
<defs>
<filter id="glow" color-interpolation-filters="sRGB" x="-20%" y="-20%" width="140%" height="140%" filterUnits="objectBoundingBox">
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0.2 0 0 0 0 0.2 0 0 0 0 1 0 0 0 1 0" result="glowColor" />
<feMorphology operator="dilate" radius="5.5" in="glowColor" result="thickenify" />
<feMerge>
<feMergeNode in="glowIt" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
<g filter="url(#glow)">
<use id="mirroredContent" xlink:href="#contentForMirroringWithFilter" transform="matrix(1,0,0,-1,4.89842541528951E-16,155.25)" />
<g id="contentForMirroringWithFilter">
<path d="M0,0L60,0L72,12L72,72L0,72Z" />
</g>
</g>
</svg>

In short (look at second to last number "100" vs "1" in "values"):
Doesn't work: <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0.2 0 0 0 0 0.2 0 0 0 0 1 0 0 0 100 0" result="glowColor" />
Does work: <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0.2 0 0 0 0 0.2 0 0 0 0 1 0 0 0 1 0" result="glowColor" />

That said, I still think there is an issue with this alpha component, as setting to anything other than equal to or less than "1" results in some color weirdness. It appears to set the opacity lower. Like try with "2", "3", and "5".

The problem is that the color channels become white. This is somehow caused by the alpha multiplier. I think this happens because the output value of the alpha channel isn't clamped before we feed the unpremultiplied filter result into premultiplication.

There is a D2D property that we can use to ask for clamping at the right time. That seems to fix it.

Attachment #9091321 - Attachment description: Reduced testcase → Reduced testcase - Square should be black, but is red on D2D
Pushed by mstange@themasta.com:
https://hg.mozilla.org/integration/autoland/rev/672050b0b4fd
Enforce appropriate output channel clamping in D2D1 ColorMatrix filters. r=bas
Status: ASSIGNED → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla71

Bugbug thinks this bug is a regression, but please revert this change in case of error.

Keywords: regression

AFAICT, this was always broken for non-WebRender since this code was first added.

Flags: in-testsuite+
Keywords: regression

I believe that this is still an issue. I have a problem that only manifests in 64bit version of FF on Windows. I have provided an example of an issue.

I am attempting to change color of SVG's using a feColorMatrix transformation

What should happen is that SVG cross in the example should be of blue color, but is instead red.

Attached file FF64bitBug.zip

The problem goes away if hardware acceleration is disabled.

Attached file FF64bitBug-working.zip

I have since found that if the SVG has fill color (white) and if I take out invert(100%) from transformation that the filter applies correctly

Please raise a new bug with your testcase.

Flags: needinfo?(janez)
No longer blocks: fixed-by-webrender
Depends on: fixed-by-webrender
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: