Bug 1196114 - Part 3: Set AnimationPerformanceWarning messages. r?birtles draft
authorHiroyuki Ikezoe <hiikezoe@mozilla-japan.org>
Fri, 04 Mar 2016 15:07:04 +0900
changeset 336800 6536260cf7f7e2c532336e930ea0759a0237c20b
parent 336794 29f2ddc6cc2d15871d4071b07f4e632ccedf2942
child 336801 6a696ce77605caeb338966655b935ab652f1cafe
push id12185
push userhiikezoe@mozilla-japan.org
push dateFri, 04 Mar 2016 07:03:48 +0000
reviewersbirtles
bugs1196114
milestone47.0a1
Bug 1196114 - Part 3: Set AnimationPerformanceWarning messages. r?birtles Those message will be modified in part 4 (localization). MozReview-Commit-ID: 6TMUxemVLcu
dom/animation/EffectCompositor.cpp
dom/animation/KeyframeEffect.cpp
dom/animation/KeyframeEffect.h
dom/animation/test/chrome/test_animation_property_state.html
layout/base/nsDisplayList.cpp
layout/base/nsDisplayList.h
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -104,20 +104,24 @@ FindAnimationsForCompositor(const nsIFra
   for (KeyframeEffectReadOnly* effect : *effects) {
     MOZ_ASSERT(effect && effect->GetAnimation());
     Animation* animation = effect->GetAnimation();
 
     if (!animation->IsPlaying()) {
       continue;
     }
 
-    if (effect->ShouldBlockCompositorAnimations(aFrame)) {
+    nsAutoString performanceWarning;
+    if (effect->ShouldBlockCompositorAnimations(aFrame,
+                                                performanceWarning)) {
       if (aMatches) {
         aMatches->Clear();
       }
+      effect->SetPerformanceWarning(aProperty,
+                                    performanceWarning);
       return false;
     }
 
     if (!effect->HasAnimationOfProperty(aProperty)) {
       continue;
     }
 
     if (aMatches) {
--- a/dom/animation/KeyframeEffect.cpp
+++ b/dom/animation/KeyframeEffect.cpp
@@ -2094,108 +2094,101 @@ KeyframeEffectReadOnly::IsGeometricPrope
     default:
       return false;
   }
 }
 
 /* static */ bool
 KeyframeEffectReadOnly::CanAnimateTransformOnCompositor(
   const nsIFrame* aFrame,
-  const nsIContent* aContent)
+  nsAString& aPerformanceWarning)
 {
   // Disallow OMTA for preserve-3d transform. Note that we check the style property
   // rather than Extend3DContext() since that can recurse back into this function
   // via HasOpacity().
   if (aFrame->Combines3DTransformWithAncestors() ||
       aFrame->StyleDisplay()->mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D) {
-    if (aContent) {
-      nsCString message;
-      message.AppendLiteral("Gecko bug: Async animation of 'preserve-3d' "
-        "transforms is not supported.  See bug 779598");
-      AnimationUtils::LogAsyncAnimationFailure(message, aContent);
-    }
+    aPerformanceWarning.AssignLiteral(
+      "Gecko bug: Async animation of 'preserve-3d' "
+      "transforms is not supported.  See bug 779598");
     return false;
   }
   // Note that testing BackfaceIsHidden() is not a sufficient test for
   // what we need for animating backface-visibility correctly if we
   // remove the above test for Extend3DContext(); that would require
   // looking at backface-visibility on descendants as well.
   if (aFrame->StyleDisplay()->BackfaceIsHidden()) {
-    if (aContent) {
-      nsCString message;
-      message.AppendLiteral("Gecko bug: Async animation of "
-        "'backface-visibility: hidden' transforms is not supported."
-        "  See bug 1186204.");
-      AnimationUtils::LogAsyncAnimationFailure(message, aContent);
-    }
+    aPerformanceWarning.AssignLiteral(
+      "Gecko bug: Async animation of "
+      "'backface-visibility: hidden' transforms is not supported."
+      "  See bug 1186204");
     return false;
   }
   if (aFrame->IsSVGTransformed()) {
-    if (aContent) {
-      nsCString message;
-      message.AppendLiteral("Gecko bug: Async 'transform' animations of "
-        "aFrames with SVG transforms is not supported.  See bug 779599");
-      AnimationUtils::LogAsyncAnimationFailure(message, aContent);
-    }
+    aPerformanceWarning.AssignLiteral(
+      "Gecko bug: Async 'transform' animations of "
+      "aFrames with SVG transforms is not supported.  See bug 779599");
     return false;
   }
 
   return true;
 }
 
 bool
-KeyframeEffectReadOnly::ShouldBlockCompositorAnimations(const nsIFrame*
-                                                          aFrame) const
+KeyframeEffectReadOnly::ShouldBlockCompositorAnimations(
+  const nsIFrame* aFrame,
+  nsAString& aPerformanceWarning) const
 {
   // We currently only expect this method to be called when this effect
   // is attached to a playing Animation. If that ever changes we'll need
   // to update this to only return true when that is the case since paused,
   // filling, cancelled Animations etc. shouldn't stop other Animations from
   // running on the compositor.
   MOZ_ASSERT(mAnimation && mAnimation->IsPlaying());
 
-  bool shouldLog = nsLayoutUtils::IsAnimationLoggingEnabled();
-
   for (const AnimationProperty& property : mProperties) {
     // If a property is overridden in the CSS cascade, it should not block other
     // animations from running on the compositor.
     if (!property.mWinsInCascade) {
       continue;
     }
     // Check for geometric properties
     if (IsGeometricProperty(property.mProperty)) {
-      if (shouldLog) {
-        nsCString message;
-        message.AppendLiteral("Performance warning: Async animation of "
-          "'transform' or 'opacity' not possible due to animation of geometric"
-          "properties on the same element");
-        AnimationUtils::LogAsyncAnimationFailure(message, aFrame->GetContent());
-      }
+      aPerformanceWarning.AssignLiteral(
+        "Performance warning: Async animation of "
+        "'transform' or 'opacity' not possible due to animation of geometric "
+        "properties on the same element");
       return true;
     }
 
     // Check for unsupported transform animations
     if (property.mProperty == eCSSProperty_transform) {
       if (!CanAnimateTransformOnCompositor(aFrame,
-            shouldLog ? aFrame->GetContent() : nullptr)) {
+                                           aPerformanceWarning)) {
         return true;
       }
     }
   }
 
   return false;
 }
 
 void
 KeyframeEffectReadOnly::SetPerformanceWarning(nsCSSProperty aProperty,
                                               const nsAString &aMessage)
 {
   for (AnimationProperty& property : mProperties) {
     if (property.mProperty == aProperty) {
+      property.mPerformanceWarning.reset();
       property.mPerformanceWarning.emplace(aMessage);
+
+      if (nsLayoutUtils::IsAnimationLoggingEnabled()) {
+        nsAutoCString logMessage = NS_ConvertUTF16toUTF8(aMessage);
+        AnimationUtils::LogAsyncAnimationFailure(logMessage, mTarget);
+      }
       return;
     }
   }
 }
 
 //---------------------------------------------------------------------
 //
 // KeyframeEffect
--- a/dom/animation/KeyframeEffect.h
+++ b/dom/animation/KeyframeEffect.h
@@ -319,17 +319,21 @@ public:
   // running at the same time on the same element to run on the main thread.
   //
   // Similarly, some transform animations cannot be run on the compositor and
   // when that is the case we simply disable all compositor animations
   // on the same element.
   //
   // Bug 1218620 - It seems like we don't need to be this restrictive. Wouldn't
   // it be ok to do 'opacity' animations on the compositor in either case?
-  bool ShouldBlockCompositorAnimations(const nsIFrame* aFrame) const;
+  //
+  // When returning true, |aOutPerformanceWarning| stores the reason why
+  // we shouldn't run the compositor animations.
+  bool ShouldBlockCompositorAnimations(const nsIFrame* aFrame,
+                                       nsAString& aPerformanceWarning) const;
 
   nsIDocument* GetRenderedDocument() const;
   nsPresContext* GetPresContext() const;
 
   // Associates a warning string with the animated property on the specified
   // frame indicating why, for example, the property could not be animated
   // on the compositor.
   void SetPerformanceWarning(nsCSSProperty aProperty,
@@ -391,21 +395,20 @@ protected:
 
 private:
   nsIFrame* GetAnimationFrame() const;
 
   bool CanThrottle() const;
   bool CanThrottleTransformChanges(nsIFrame& aFrame) const;
 
   // Returns true unless Gecko limitations prevent performing transform
-  // animations for |aFrame|. Any limitations that are encountered are
-  // logged using |aContent| to describe the affected content.
-  // If |aContent| is nullptr, no logging is performed
+  // animations for |aFrame|. When returning true, the reason for the
+  // limitation is stored in |aOutPerformanceWarning|.
   static bool CanAnimateTransformOnCompositor(const nsIFrame* aFrame,
-                                              const nsIContent* aContent);
+                                              nsAString& aPerformanceWarning);
   static bool IsGeometricProperty(const nsCSSProperty aProperty);
 
   static const TimeDuration OverflowRegionRefreshInterval();
 };
 
 class KeyframeEffect : public KeyframeEffectReadOnly
 {
 public:
--- a/dom/animation/test/chrome/test_animation_property_state.html
+++ b/dom/animation/test/chrome/test_animation_property_state.html
@@ -2,17 +2,17 @@
 <head>
 <meta charset=utf-8>
 <title>Bug 1196114 - Animation property which indicates
        running on the compositor or not</title>
 <script type="application/javascript" src="../testharness.js"></script>
 <script type="application/javascript" src="../testharnessreport.js"></script>
 <script type="application/javascript" src="../testcommon.js"></script>
 <style>
-div {
+.compositable {
   /* Element needs geometry to be eligible for layerization */
   width: 100px;
   height: 100px;
   background-color: white;
 }
 </style>
 </head>
 <body>
@@ -42,16 +42,45 @@ function assert_animation_property_state
 
   for (var i = 0; i < sortedActual.length; i++) {
     assert_equals(sortedActual[i].property,
                   sortedExpected[i].property,
                   'CSS property name should match');
     assert_equals(sortedActual[i].runningOnCompositor,
                   sortedExpected[i].runningOnCompositor,
                   'runningOnCompositor property should match');
+    if (sortedExpected[i].warning instanceof RegExp) {
+      assert_regexp_match(sortedActual[i].warning,
+                          sortedExpected[i].warning,
+                          'warning message should match');
+    } else if (sortedExpected[i].warning) {
+      assert_equals(sortedActual[i].warning,
+                    sortedExpected[i].warning,
+                    'warning message should match');
+    }
+  }
+}
+
+// Check that the animation is running on compositor and
+// warning property is not set for the CSS property regardless
+// expected values.
+function assert_property_state_on_compositor(actual, expected) {
+  assert_equals(actual.length, expected.length);
+
+  var sortedActual = actual.sort(compare_property_state);
+  var sortedExpected = expected.sort(compare_property_state);
+
+  for (var i = 0; i < sortedActual.length; i++) {
+    assert_equals(sortedActual[i].property,
+                  sortedExpected[i].property,
+                  'CSS property name should match');
+    assert_true(sortedActual[i].runningOnCompositor,
+                'runningOnCompositor property should be true');
+    assert_not_exists(sortedActual[i], 'warning',
+                      'warning property should not be set');
   }
 }
 
 var gAnimationsTests = [
   {
     desc: 'animations on compositor',
     frames: {
       opacity: [0, 1]
@@ -103,25 +132,181 @@ var gAnimationsTests = [
         property: 'opacity',
         runningOnCompositor: true
       },
       {
         property: 'transform',
         runningOnCompositor: true
       }
     ]
-  }
+  },
+  {
+    // FIXME: Once we have KeyframeEffect.setFrames, we should rewrite
+    // this test case to check that runningOnCompositor is restored to true
+    // after 'width' keyframe is removed from the keyframes.
+    desc: 'animation on compositor with animation of geometric properties',
+    frames: {
+      width: ['100px', '200px'],
+      transform: ['translate(0px)', 'translate(100px)']
+    },
+    expected: [
+      {
+        property: 'width',
+        runningOnCompositor: false
+      },
+      {
+        property: 'transform',
+        runningOnCompositor: false,
+        warning: "Performance warning: Async animation of " +
+                 "'transform' or 'opacity' not possible due to animation " +
+                 "of geometric properties on the same element"
+      }
+    ]
+  },
 ];
 
 gAnimationsTests.forEach(function(subtest) {
   promise_test(function(t) {
-    var div = addDiv(t);
+    var div = addDiv(t, { class: 'compositable' });
     var animation = div.animate(subtest.frames, 100000);
     return animation.ready.then(t.step_func(function() {
       assert_animation_property_state_equals(
         animation.effect.getPropertyState(),
         subtest.expected);
     }));
   }, subtest.desc);
 });
 
+var gPerformanceWarningTests = [
+  {
+    desc: 'preserve-3d transform',
+    frames: {
+      transform: ['translate(0px)', 'translate(100px)']
+    },
+    style: 'transform-style: preserve-3d',
+    expected: [
+      {
+        property: 'transform',
+        runningOnCompositor: false,
+        warning: "Gecko bug: Async animation of 'preserve-3d' " +
+                 "transforms is not supported.  See bug 779598"
+      }
+    ]
+  },
+  {
+    desc: 'transform with backface-visibility:hidden',
+    frames: {
+      transform: ['translate(0px)', 'translate(100px)']
+    },
+    style: 'backface-visibility: hidden;',
+    expected: [
+      {
+        property: 'transform',
+        runningOnCompositor: false,
+        warning: "Gecko bug: Async animation of " +
+                 "'backface-visibility: hidden' transforms is not " +
+                 "supported.  See bug 1186204"
+      }
+    ]
+  },
+];
+
+gPerformanceWarningTests.forEach(function(subtest) {
+  promise_test(function(t) {
+    var div = addDiv(t, { class: 'compositable' });
+    var animation = div.animate(subtest.frames, 100000);
+    return animation.ready.then(t.step_func(function() {
+      assert_property_state_on_compositor(
+        animation.effect.getPropertyState(),
+        subtest.expected);
+      div.style = subtest.style;
+      return waitForFrame();
+    })).then(t.step_func(function() {
+      assert_animation_property_state_equals(
+        animation.effect.getPropertyState(),
+        subtest.expected);
+      div.style = '';
+      return waitForFrame();
+    })).then(t.step_func(function() {
+      assert_property_state_on_compositor(
+        animation.effect.getPropertyState(),
+        subtest.expected);
+    }));
+  }, subtest.desc);
+});
+
+promise_test(function(t) {
+  var div = addDiv(t, { class: 'compositable' });
+  var animation = div.animate(
+    { transform: ['translate(0px)', 'translate(100px)'] }, 100000);
+  return animation.ready.then(t.step_func(function() {
+    assert_animation_property_state_equals(
+      animation.effect.getPropertyState(),
+      [ { property: 'transform', runningOnCompositor: true } ]);
+    div.style = 'width: 10000px; height: 10000px';
+    return waitForFrame();
+  })).then(t.step_func(function() {
+    // viewport depends on test environment.
+    var expectedWarning = new RegExp(
+      "Performance warning: Async animation disabled because frame size " +
+      "\\(10000, 10000\\) is bigger than the viewport \\(\\d+, \\d+\\) " +
+      "or the visual rectangle \\(10000, 10000\\) is larger than the max " +
+      "allowable value \\(\\d+\\)");
+    assert_animation_property_state_equals(
+      animation.effect.getPropertyState(),
+      [ {
+        property: 'transform',
+        runningOnCompositor: false,
+        warning: expectedWarning
+      } ]);
+    div.style = 'width: 100px; height: 100px';
+    return waitForFrame();
+  })).then(t.step_func(function() {
+    // FIXME: Bug 1253164: the animation should get back on compositor.
+    assert_animation_property_state_equals(
+      animation.effect.getPropertyState(),
+      [ { property: 'transform', runningOnCompositor: false } ]);
+  }));
+}, 'transform on too big element');
+
+promise_test(function(t) {
+  var svg  = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
+  svg.setAttribute('width', '100');
+  svg.setAttribute('height', '100');
+  var rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
+  rect.setAttribute('width', '100');
+  rect.setAttribute('height', '100');
+  rect.setAttribute('fill', 'red');
+  svg.appendChild(rect);
+  document.body.appendChild(svg);
+  t.add_cleanup(function() {
+    svg.remove();
+  });
+
+  var animation = svg.animate(
+    { transform: ['translate(0px)', 'translate(100px)'] }, 100000);
+  return animation.ready.then(t.step_func(function() {
+    assert_animation_property_state_equals(
+      animation.effect.getPropertyState(),
+      [ { property: 'transform', runningOnCompositor: true } ]);
+    svg.setAttribute('transform', 'translate(10, 20)');
+    return waitForFrame();
+  })).then(t.step_func(function() {
+    assert_animation_property_state_equals(
+      animation.effect.getPropertyState(),
+      [ {
+        property: 'transform',
+        runningOnCompositor: false,
+        warning: "Gecko bug: Async 'transform' animations of aFrames " +
+                 "with SVG transforms is not supported.  See bug 779599"
+      } ]);
+    svg.removeAttribute('transform');
+    return waitForFrame();
+  })).then(t.step_func(function() {
+    assert_animation_property_state_equals(
+      animation.effect.getPropertyState(),
+      [ { property: 'transform', runningOnCompositor: true } ]);
+  }));
+}, 'transform of nsIFrame with SVG transform');
+
 </script>
+
 </body>
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -5583,21 +5583,24 @@ nsDisplayTransform::GetResultingTransfor
 
 bool
 nsDisplayOpacity::CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder)
 {
   if (ActiveLayerTracker::IsStyleAnimated(aBuilder, mFrame, eCSSProperty_opacity)) {
     return true;
   }
 
-  if (nsLayoutUtils::IsAnimationLoggingEnabled()) {
-    nsCString message;
-    message.AppendLiteral("Performance warning: Async animation disabled because frame was not marked active for opacity animation");
-    AnimationUtils::LogAsyncAnimationFailure(message, Frame()->GetContent());
-  }
+  nsString message;
+  message.AppendLiteral(
+    "Performance warning: Async animation disabled because frame was not "
+    "marked active for opacity animation");
+  EffectCompositor::SetPerformanceWarning(mFrame,
+                                          eCSSProperty_opacity,
+                                          message);
+
   return false;
 }
 
 bool
 nsDisplayTransform::ShouldPrerender(nsDisplayListBuilder* aBuilder) {
   if (!mMaybePrerender) {
     return false;
   }
@@ -5618,38 +5621,39 @@ nsDisplayTransform::ShouldPrerender(nsDi
 bool
 nsDisplayTransform::CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder)
 {
   if (mMaybePrerender) {
     // TODO We need to make sure that if we use async animation we actually
     // pre-render even if we're out of will change budget.
     return true;
   }
-  DebugOnly<bool> prerender = ShouldPrerenderTransformedContent(aBuilder, mFrame, true);
+  DebugOnly<bool> prerender = ShouldPrerenderTransformedContent(aBuilder, mFrame);
   NS_ASSERTION(!prerender, "Something changed under us!");
   return false;
 }
 
 /* static */ bool
 nsDisplayTransform::ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBuilder,
-                                                      nsIFrame* aFrame,
-                                                      bool aLogAnimations)
+                                                      nsIFrame* aFrame)
 {
   // Elements whose transform has been modified recently, or which
   // have a compositor-animated transform, can be prerendered. An element
   // might have only just had its transform animated in which case
   // the ActiveLayerManager may not have been notified yet.
   if (!ActiveLayerTracker::IsStyleMaybeAnimated(aFrame, eCSSProperty_transform) &&
       !EffectCompositor::HasAnimationsForCompositor(aFrame,
                                                     eCSSProperty_transform)) {
-    if (aLogAnimations) {
-      nsCString message;
-      message.AppendLiteral("Performance warning: Async animation disabled because frame was not marked active for transform animation");
-      AnimationUtils::LogAsyncAnimationFailure(message, aFrame->GetContent());
-    }
+    nsString message;
+    message.AppendLiteral(
+      "Performance warning: Async animation disabled because frame was not "
+      "marked active for transform animation");
+    EffectCompositor::SetPerformanceWarning(aFrame,
+                                            eCSSProperty_transform,
+                                            message);
     return false;
   }
 
   nsSize refSize = aBuilder->RootReferenceFrame()->GetSize();
   // Only prerender if the transformed frame's size is <= the
   // reference frame size (~viewport), allowing a 1/8th fuzz factor
   // for shadows, borders, etc.
   refSize += nsSize(refSize.width / 8, refSize.height / 8);
@@ -5658,37 +5662,38 @@ nsDisplayTransform::ShouldPrerenderTrans
   if (frameSize <= refSize) {
     maxInAppUnits = aFrame->PresContext()->DevPixelsToAppUnits(4096);
     nsRect visual = aFrame->GetVisualOverflowRect();
     if (visual.width <= maxInAppUnits && visual.height <= maxInAppUnits) {
       return true;
     }
   }
 
-  if (aLogAnimations) {
-    nsRect visual = aFrame->GetVisualOverflowRect();
-
-    nsCString message;
-    message.AppendLiteral("Performance warning: Async animation disabled because frame size (");
-    message.AppendInt(nsPresContext::AppUnitsToIntCSSPixels(frameSize.width));
-    message.AppendLiteral(", ");
-    message.AppendInt(nsPresContext::AppUnitsToIntCSSPixels(frameSize.height));
-    message.AppendLiteral(") is bigger than the viewport (");
-    message.AppendInt(nsPresContext::AppUnitsToIntCSSPixels(refSize.width));
-    message.AppendLiteral(", ");
-    message.AppendInt(nsPresContext::AppUnitsToIntCSSPixels(refSize.height));
-    message.AppendLiteral(") or the visual rectangle (");
-    message.AppendInt(nsPresContext::AppUnitsToIntCSSPixels(visual.width));
-    message.AppendLiteral(", ");
-    message.AppendInt(nsPresContext::AppUnitsToIntCSSPixels(visual.height));
-    message.AppendLiteral(") is larger than the max allowable value (");
-    message.AppendInt(nsPresContext::AppUnitsToIntCSSPixels(maxInAppUnits));
-    message.Append(')');
-    AnimationUtils::LogAsyncAnimationFailure(message, aFrame->GetContent());
-  }
+  nsRect visual = aFrame->GetVisualOverflowRect();
+
+  nsAutoString message;
+  message.AppendLiteral(
+    "Performance warning: Async animation disabled because frame size (");
+  message.AppendInt(nsPresContext::AppUnitsToIntCSSPixels(frameSize.width));
+  message.AppendLiteral(", ");
+  message.AppendInt(nsPresContext::AppUnitsToIntCSSPixels(frameSize.height));
+  message.AppendLiteral(") is bigger than the viewport (");
+  message.AppendInt(nsPresContext::AppUnitsToIntCSSPixels(refSize.width));
+  message.AppendLiteral(", ");
+  message.AppendInt(nsPresContext::AppUnitsToIntCSSPixels(refSize.height));
+  message.AppendLiteral(") or the visual rectangle (");
+  message.AppendInt(nsPresContext::AppUnitsToIntCSSPixels(visual.width));
+  message.AppendLiteral(", ");
+  message.AppendInt(nsPresContext::AppUnitsToIntCSSPixels(visual.height));
+  message.AppendLiteral(") is larger than the max allowable value (");
+  message.AppendInt(nsPresContext::AppUnitsToIntCSSPixels(maxInAppUnits));
+  message.Append(')');
+  EffectCompositor::SetPerformanceWarning(aFrame,
+                                          eCSSProperty_transform,
+                                          message);
   return false;
 }
 
 /* If the matrix is singular, or a hidden backface is shown, the frame won't be visible or hit. */
 static bool IsFrameVisible(nsIFrame* aFrame, const Matrix4x4& aMatrix)
 {
   if (aMatrix.IsSingular()) {
     return false;
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -4080,18 +4080,17 @@ public:
                                                uint32_t aFlags,
                                                const nsRect* aBoundsOverride = nullptr,
                                                nsIFrame** aOutAncestor = nullptr);
   /**
    * Return true when we should try to prerender the entire contents of the
    * transformed frame even when it's not completely visible (yet).
    */
   static bool ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBuilder,
-                                                nsIFrame* aFrame,
-                                                bool aLogAnimations = false);
+                                                nsIFrame* aFrame);
   bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) override;
 
   bool MayBeAnimated(nsDisplayListBuilder* aBuilder);
 
   /**
    * This will return if it's possible for this element to be prerendered.
    * This should never return false if we're going to prerender.
    */