Closed
Bug 1378710
Opened 7 years ago
Closed 7 years ago
SVG: mask renders incorrectly when clipped group has animated contents
Categories
(Core :: SVG, defect, P1)
Tracking
()
RESOLVED
FIXED
mozilla56
Tracking | Status | |
---|---|---|
firefox-esr52 | --- | unaffected |
firefox54 | --- | wontfix |
firefox55 | --- | wontfix |
firefox56 | --- | fixed |
People
(Reporter: paul.lebeau, Assigned: u459114)
References
(Blocks 1 open bug)
Details
(Keywords: regression)
Attachments
(3 files, 1 obsolete file)
488 bytes,
image/svg+xml
|
Details | |
59 bytes,
text/x-review-board-request
|
mstange
:
review+
jcristau
:
approval-mozilla-beta-
|
Details |
1023 bytes,
text/html
|
Details |
User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0
Build ID: 20170628075643
Steps to reproduce:
Related to bug #1378707. Also see: https://stackoverflow.com/questions/44935822/svg-text-clippath-in-firefox
If a mask is applies to a group that contains only animated elements, then it does not render correctly.
Actual results:
See: https://jsfiddle.net/q770saez/1/
<svg viewBox="0 0 600 150">
<mask id="m">
<rect width="100%" height="100%" fill="black"/>
<polygon points="0,0, 600,75, 0,150" fill="white"/>
</mask>
<g mask="url(#m)">
<rect width="100%" height="100%" class="anim-shape"/>
</g>
</svg>
.anim-shape {
transform: translate(-600px, 0);
animation: moving-panel 4s forwards ease-out;
}
@keyframes moving-panel {
100% {
transform: translate(0, 0);
}
}
Expected results:
But if you apply the same workaround as suggested in bug #1378707 (non-animated transparent rect in the group), the animation renders correctly.
https://jsfiddle.net/q770saez/3/
<g mask="url(#m)">
<rect x="0" y="0" width="100%" height="100%" fill="transparent" />
<rect width="100%" height="100%" class="anim-shape"/>
</g>
Updated•7 years ago
|
Component: Untriaged → SVG
Product: Firefox → Core
Comment 1•7 years ago
|
||
Regression window:
https://hg.mozilla.org/integration/autoland/pushloghtml?fromchange=0005d0bfadf72746ce36f4e8d09d9504b814557e&tochange=ba20391edbec448b56725ef01158176614706b4f
Regressed by: Bug 1313898
Blocks: 1313898
Status: UNCONFIRMED → NEW
Ever confirmed: true
Flags: needinfo?(cku)
Keywords: regression
Updated•7 years ago
|
Has Regression Range: --- → yes
status-firefox54:
--- → affected
status-firefox55:
--- → affected
status-firefox56:
--- → affected
The mask we generate in ContainerState::SetupMaskLayerForCSSMask is not correct. Attach a simpler test case
Comment 3•7 years ago
|
||
Not a new regression in 54. Mark 54 won't fix and see if we can fix it in 55.
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Attachment #8885179 -
Attachment is obsolete: true
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Updated•7 years ago
|
Status: NEW → ASSIGNED
Priority: -- → P1
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Attachment #8885577 -
Flags: review?(mstange)
Comment 14•7 years ago
|
||
mozreview-review |
Comment on attachment 8885577 [details]
Bug 1378710 - Disable OMTA if there is a mask applied on any ancestor of the animation target.
https://reviewboard.mozilla.org/r/156428/#review161632
::: layout/painting/nsDisplayList.cpp:7419
(Diff revision 6)
> AnimationPerformanceWarning::Type::TransformFrameInactive));
>
> return NoPrerender;
> }
>
> + // We should not allow prerender if any ancestor container element carries
...if any ancestor container element has mask/clip-path effects.
::: layout/painting/nsDisplayList.cpp:7423
(Diff revision 6)
>
> + // We should not allow prerender if any ancestor container element carries
> + // mask/clip-path effects.
> + //
> + // With prerender and sync transform animation, we do not need to restyle
> + // animated element to respect position change, since that transform is done
...need to restyle an animated element to respect position changes, since...
::: layout/painting/nsDisplayList.cpp:7425
(Diff revision 6)
> + // mask/clip-path effects.
> + //
> + // With prerender and sync transform animation, we do not need to restyle
> + // animated element to respect position change, since that transform is done
> + // by layer animation. As a result, the container element is not aware of
> + // position change of that containing element and lose chance to update
and loses the chance to...
::: layout/painting/nsDisplayList.cpp:7426
(Diff revision 6)
> + //
> + // With prerender and sync transform animation, we do not need to restyle
> + // animated element to respect position change, since that transform is done
> + // by layer animation. As a result, the container element is not aware of
> + // position change of that containing element and lose chance to update
> + // the content of mask/clip-path accordingly.
the content of the mask/clip-path
::: layout/painting/nsDisplayList.cpp:7428
(Diff revision 6)
> + // animated element to respect position change, since that transform is done
> + // by layer animation. As a result, the container element is not aware of
> + // position change of that containing element and lose chance to update
> + // the content of mask/clip-path accordingly.
> + //
> + // But why need updating mask? This is relative to how we generate a mask
Why do we need to update a mask? rather than But why need updating...
::: layout/painting/nsDisplayList.cpp:7432
(Diff revision 6)
> + //
> + // But why need updating mask? This is relative to how we generate a mask
> + // layer in ContainerState::SetupMaskLayerForCSSMask. While creating a mask
> + // layer, to reduce memory usage, we did not choose the size of the masked
> + // element as mask size. Instead, we read the union of bounds of all children
> + // display items by nsDisplayWrapList::GetBounds, which is smaller then or
smaller than
::: layout/painting/nsDisplayList.cpp:7433
(Diff revision 6)
> + // But why need updating mask? This is relative to how we generate a mask
> + // layer in ContainerState::SetupMaskLayerForCSSMask. While creating a mask
> + // layer, to reduce memory usage, we did not choose the size of the masked
> + // element as mask size. Instead, we read the union of bounds of all children
> + // display items by nsDisplayWrapList::GetBounds, which is smaller then or
> + // equal to the masked element's boundary, and use it as position/size of
as the position/size
::: layout/painting/nsDisplayList.cpp:7435
(Diff revision 6)
> + // layer, to reduce memory usage, we did not choose the size of the masked
> + // element as mask size. Instead, we read the union of bounds of all children
> + // display items by nsDisplayWrapList::GetBounds, which is smaller then or
> + // equal to the masked element's boundary, and use it as position/size of
> + // the mask layer. That union bounds is actually effected by the geometry of
> + // the animated element. To keep the content of mask up to date, forbid
forbidding of prerender is required
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment 17•7 years ago
|
||
mozreview-review |
Comment on attachment 8885577 [details]
Bug 1378710 - Disable OMTA if there is a mask applied on any ancestor of the animation target.
https://reviewboard.mozilla.org/r/156428/#review164930
I'm not very happy about this patch, but I don't have any better ideas. I guess this is not a regression compared to before we had layerized masks, so it's ok.
::: layout/painting/nsDisplayList.cpp:7434
(Diff revision 8)
> + // mask layer in ContainerState::SetupMaskLayerForCSSMask. While creating a
> + // mask layer, to reduce memory usage, we did not choose the size of the
> + // masked element as mask size. Instead, we read the union of bounds of all
> + // children display items by nsDisplayWrapList::GetBounds, which is smaller
> + // than or equal to the masked element's boundary, and use it as the position
> + ///size of the mask layer. That union bounds is actually effected by the
affected
::: layout/painting/nsDisplayList.cpp:7438
(Diff revision 8)
> + // than or equal to the masked element's boundary, and use it as the position
> + ///size of the mask layer. That union bounds is actually effected by the
> + // geometry of the animated element. To keep the content of mask up to date,
> + // forbidding of prerender is required.
> + for (nsIFrame* container = aFrame->GetParent(); container;
> + container = container->GetParent()) {
Should this be using nsLayoutUtils::GetCrossDocParentFrame? Otherwise I think you could have an OMTA animation inside a transparent iframe where the iframe has a mask.
Attachment #8885577 -
Flags: review?(mstange) → review+
Assignee | ||
Comment 18•7 years ago
|
||
mozreview-review-reply |
Comment on attachment 8885577 [details]
Bug 1378710 - Disable OMTA if there is a mask applied on any ancestor of the animation target.
https://reviewboard.mozilla.org/r/156428/#review164930
I don't like it either, since it's bad for rendering smoothness of animation. Base on my understanding of gecko, that what I can do so far, let me file a follow up to unblock this limitation later.
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment 22•7 years ago
|
||
Pushed by cku@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/41c7ad2d0326
Disable OMTA if there is a mask applied on any ancestor of the animation target. r=mstange
Comment 23•7 years ago
|
||
bugherder |
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla56
Comment 24•7 years ago
|
||
Please request Beta approval on this when you get a chance.
Assignee | ||
Comment 25•7 years ago
|
||
Comment on attachment 8885577 [details]
Bug 1378710 - Disable OMTA if there is a mask applied on any ancestor of the animation target.
Approval Request Comment
[Feature/Bug causing the regression]: Bug 1313898
[User impact if declined]: the shape of mask may not be correct during a transform animation of a masked descedant.
[Is this code covered by automated tests?]: no
[Has the fix been verified in Nightly?]:
[Needs manual test from QE? If yes, steps to reproduce]:
1. verify the renering result of anim-mask.svg during the animation, and compare with chrome
2. virify the renering result of https://jsfiddle.net/q770saez/1/, and compare with chrome
[List of other uplifts needed for the feature/fix]: NA
[Is the change risky?]: no
[Why is the change risky/not risky?]: small change.
[String changes made/needed]: NA
I did not create a test case for this bug since reftest harness can not capture this glich. Glitch we saw on the screen is vanished while we do a snapshot in reftest.
Flags: needinfo?(cku)
Attachment #8885577 -
Flags: approval-mozilla-beta?
Comment 26•7 years ago
|
||
Comment on attachment 8885577 [details]
Bug 1378710 - Disable OMTA if there is a mask applied on any ancestor of the animation target.
We shipped this in 54, we're almost at RC week, I'd prefer to punt on this for 55, unless somebody tells me this is really critical.
Attachment #8885577 -
Flags: approval-mozilla-beta? → approval-mozilla-beta-
Updated•7 years ago
|
Comment 27•7 years ago
|
||
Pushed by cku@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/72873c109b1b
(followup) Correct typo in the comment. r=me DONTBUILD
Comment 28•7 years ago
|
||
bugherder |
Comment 29•7 years ago
|
||
https://hg.mozilla.org/projects/date/rev/72873c109b1b74ddd329d2e9f0a9506be3b05556
Bug 1378710 - (followup) Correct typo in the comment. r=me DONTBUILD
You need to log in
before you can comment on or make changes to this bug.
Description
•