Bug 975757 - changes to transforms in patterns do not cause an update. r=jwatt
authorRobert Longson <longsonr@gmail.com>
Tue, 04 Nov 2014 14:52:27 +0000
changeset 213932 9eb2a0bd0afc9014aa5f75e0a32a85a31906cb2d
parent 213931 4e9000715f0c15f21058a3366d4343d696ad3860
child 213933 c87ea67e88a1917d235c5c4e65e5140e722f71c8
push id27768
push userkwierso@gmail.com
push dateWed, 05 Nov 2014 02:19:03 +0000
treeherdermozilla-central@a1823d3c7365 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt
bugs975757
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 975757 - changes to transforms in patterns do not cause an update. r=jwatt
dom/svg/SVGTransformableElement.cpp
layout/base/RestyleManager.cpp
layout/base/nsChangeHint.h
layout/reftests/svg/smil/transform/reftest.list
layout/reftests/svg/smil/transform/use-1.svg
--- a/dom/svg/SVGTransformableElement.cpp
+++ b/dom/svg/SVGTransformableElement.cpp
@@ -51,22 +51,21 @@ SVGTransformableElement::IsAttributeMapp
 nsChangeHint
 SVGTransformableElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
                                                 int32_t aModType) const
 {
   nsChangeHint retval =
     nsSVGElement::GetAttributeChangeHint(aAttribute, aModType);
   if (aAttribute == nsGkAtoms::transform ||
       aAttribute == nsGkAtoms::mozAnimateMotionDummyAttr) {
-    // We add nsChangeHint_UpdateOverflow so that nsFrame::UpdateOverflow()
-    // will be called on us and our ancestors.
     nsIFrame* frame =
       const_cast<SVGTransformableElement*>(this)->GetPrimaryFrame();
+    NS_UpdateHint(retval, nsChangeHint_InvalidateRenderingObservers);
     if (!frame || (frame->GetStateBits() & NS_FRAME_IS_NONDISPLAY)) {
-      return retval; // no change
+      return retval;
     }
     if (aModType == nsIDOMMutationEvent::ADDITION ||
         aModType == nsIDOMMutationEvent::REMOVAL ||
         (aModType == nsIDOMMutationEvent::MODIFICATION &&
          !(mTransforms && mTransforms->HasTransform()))) {
       // Reconstruct the frame tree to handle stacking context changes:
       NS_UpdateHint(retval, nsChangeHint_ReconstructFrame);
     } else {
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -261,19 +261,16 @@ DoApplyRenderingChangeToTree(nsIFrame* a
         // SVG effects paints the opacity without using
         // nsDisplayOpacity. We need to invalidate manually.
         aFrame->InvalidateFrameSubtree();
       }
     }
     if ((aChange & nsChangeHint_UpdateTransformLayer) &&
         aFrame->IsTransformed()) {
       ActiveLayerTracker::NotifyRestyle(aFrame, eCSSProperty_transform);
-      if (!aFrame->GetPrevContinuation()) {
-        nsSVGEffects::InvalidateRenderingObservers(aFrame);
-      }
       // If we're not already going to do an invalidating paint, see
       // if we can get away with only updating the transform on a
       // layer for this frame, and not scheduling an invalidating
       // paint.
       if (!needInvalidatingPaint) {
         Layer* layer;
         needInvalidatingPaint |= !aFrame->TryUpdateTransformOnly(&layer);
 
@@ -773,16 +770,19 @@ RestyleManager::ProcessRestyledFrames(ns
       }
 
       if (hint & nsChangeHint_UpdateEffects) {
         for (nsIFrame *cont = frame; cont;
              cont = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(cont)) {
           nsSVGEffects::UpdateEffects(cont);
         }
       }
+      if (hint & nsChangeHint_InvalidateRenderingObservers) {
+        nsSVGEffects::InvalidateRenderingObservers(frame);
+      }
       if (hint & nsChangeHint_NeedReflow) {
         StyleChangeReflow(frame, hint);
         didReflowThisFrame = true;
       }
 
       if (hint & (nsChangeHint_RepaintFrame | nsChangeHint_SyncFrameView |
                   nsChangeHint_UpdateOpacityLayer | nsChangeHint_UpdateTransformLayer |
                   nsChangeHint_ChildrenOnlyTransform | nsChangeHint_SchedulePaint)) {
@@ -3768,17 +3768,18 @@ RestyleManager::ChangeHintToString(nsCha
   bool any = false;
   const char* names[] = {
     "RepaintFrame", "NeedReflow", "ClearAncestorIntrinsics",
     "ClearDescendantIntrinsics", "NeedDirtyReflow", "SyncFrameView",
     "UpdateCursor", "UpdateEffects", "UpdateOpacityLayer",
     "UpdateTransformLayer", "ReconstructFrame", "UpdateOverflow",
     "UpdateSubtreeOverflow", "UpdatePostTransformOverflow",
     "ChildrenOnlyTransform", "RecomputePosition", "AddOrRemoveTransform",
-    "BorderStyleNoneChange", "UpdateTextPath", "NeutralChange"
+    "BorderStyleNoneChange", "UpdateTextPath", "NeutralChange",
+    "InvalidateRenderingObservers"
   };
   uint32_t hint = aHint & ((1 << ArrayLength(names)) - 1);
   uint32_t rest = aHint & ~((1 << ArrayLength(names)) - 1);
   if (hint == nsChangeHint_Hints_NotHandledForDescendants) {
     result.AppendLiteral("nsChangeHint_Hints_NotHandledForDescendants");
     hint = 0;
     any = true;
   } else {
--- a/layout/base/nsChangeHint.h
+++ b/layout/base/nsChangeHint.h
@@ -145,17 +145,22 @@ enum nsChangeHint {
    * nsChangeHint_NeutralChange must be returned by CalcDifference on a given
    * style struct if the data in the style structs are meaningfully different
    * and if no other change hints are returned.  If any other change hints are
    * set, then nsChangeHint_NeutralChange need not also be included, but it is
    * safe to do so.  (An example of style structs having non-meaningfully
    * different data would be cached information that would be re-calculated
    * to the same values, such as nsStyleBorder::mSubImages.)
    */
-  nsChangeHint_NeutralChange = 0x100000
+  nsChangeHint_NeutralChange = 0x100000,
+
+  /**
+   * This will cause rendering observers to be invalidated.
+   */
+  nsChangeHint_InvalidateRenderingObservers = 0x200000
 
   // IMPORTANT NOTE: When adding new hints, consider whether you need to
   // add them to NS_HintsNotHandledForDescendantsIn() below.  Please also
   // add them to RestyleManager::ChangeHintToString.
 };
 
 // Redefine these operators to return nothing. This will catch any use
 // of these operators on hints. We should not be using these operators
@@ -200,30 +205,32 @@ inline bool NS_IsHintSubset(nsChangeHint
  * cases where applying a hint to an element does not necessarily result
  * in the same hint being handled on the descendants.
  */
 
 // The most hints that NS_HintsNotHandledForDescendantsIn could possibly return:
 #define nsChangeHint_Hints_NotHandledForDescendants nsChangeHint( \
           nsChangeHint_UpdateTransformLayer | \
           nsChangeHint_UpdateEffects | \
+          nsChangeHint_InvalidateRenderingObservers | \
           nsChangeHint_UpdateOpacityLayer | \
           nsChangeHint_UpdateOverflow | \
           nsChangeHint_UpdatePostTransformOverflow | \
           nsChangeHint_ChildrenOnlyTransform | \
           nsChangeHint_RecomputePosition | \
           nsChangeHint_AddOrRemoveTransform | \
           nsChangeHint_BorderStyleNoneChange | \
           nsChangeHint_NeedReflow | \
           nsChangeHint_ClearAncestorIntrinsics)
 
 inline nsChangeHint NS_HintsNotHandledForDescendantsIn(nsChangeHint aChangeHint) {
   nsChangeHint result = nsChangeHint(aChangeHint & (
     nsChangeHint_UpdateTransformLayer |
     nsChangeHint_UpdateEffects |
+    nsChangeHint_InvalidateRenderingObservers |
     nsChangeHint_UpdateOpacityLayer |
     nsChangeHint_UpdateOverflow |
     nsChangeHint_UpdatePostTransformOverflow |
     nsChangeHint_ChildrenOnlyTransform |
     nsChangeHint_RecomputePosition |
     nsChangeHint_AddOrRemoveTransform |
     nsChangeHint_BorderStyleNoneChange));
 
--- a/layout/reftests/svg/smil/transform/reftest.list
+++ b/layout/reftests/svg/smil/transform/reftest.list
@@ -10,8 +10,9 @@ fuzzy-if(cocoaWidget,1,32) fuzzy-if(winW
 == rotate-angle-4.svg rotate-angle-ref.svg
 == rotate-angle-5.svg rotate-angle-ref.svg
 fuzzy(12,27) == scale-1.svg scale-1-ref.svg  # bug 981004
 == set-transform-1.svg lime.svg
 fuzzy-if(winWidget,1,3) == skew-1.svg skew-1-ref.svg # bug 983671
 == translate-clipPath-1.svg lime.svg
 fails-if(OSX==10.6) == translate-gradient-1.svg lime.svg
 == translate-pattern-1.svg lime.svg
+== use-1.svg lime.svg
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/smil/transform/use-1.svg
@@ -0,0 +1,27 @@
+<svg width="100%" xmlns="http://www.w3.org/2000/svg"
+                  xmlns:xlink="http://www.w3.org/1999/xlink"
+                  class="reftest-wait">
+<script>
+  function run() {
+    document.documentElement.setCurrentTime(30);
+    document.documentElement.removeAttribute('class');
+  }
+  window.addEventListener("MozReftestInvalidate", run, false);
+</script>
+<defs>
+  <g id="shape">
+    <rect height="100" width="100" fill="red"/>
+    <rect x="100" height="100" width="100" fill="lime"/>
+  </g>
+
+  <pattern id="pattern" width="200" height="100" patternUnits="userSpaceOnUse">
+    <use xlink:href="#shape">
+      <animateTransform attributeName="transform" type="translate" calcMode="discrete"
+                        dur="30s" from="0 0" to="-100 0" fill="freeze"/>
+    </use>
+  </pattern>
+</defs>
+<rect height="100%" width="100%" fill="lime"/>
+<rect height="100%" width="100%" fill="url(#pattern)"/>
+</svg>
+