Bug 1053992 - Add a red square in the top-right corner of FPS display for unused APZ transforms (i.e. when content is sync-scrolling). r=BenWa
authorKartikaya Gupta <kgupta@mozilla.com>
Thu, 04 Sep 2014 13:54:54 -0400
changeset 226861 c1285c2f44081fa99ea97388843e34f23ac02e97
parent 226860 c3773aeab2f8791dcfd6213226b983eae6b276cb
child 226862 07d1e106d2504eee316b41afcbded24f31138452
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBenWa
bugs1053992
milestone35.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 1053992 - Add a red square in the top-right corner of FPS display for unused APZ transforms (i.e. when content is sync-scrolling). r=BenWa
gfx/layers/composite/ContainerLayerComposite.cpp
gfx/layers/composite/LayerManagerComposite.cpp
gfx/layers/composite/LayerManagerComposite.h
--- a/gfx/layers/composite/ContainerLayerComposite.cpp
+++ b/gfx/layers/composite/ContainerLayerComposite.cpp
@@ -419,16 +419,34 @@ ContainerRender(ContainerT* aContainer,
     gfx::Rect rect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height);
     gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height);
     aManager->GetCompositor()->DrawQuad(rect, clipRect, effectChain, opacity,
                                         aContainer->GetEffectiveTransform());
   } else {
     RenderLayers(aContainer, aManager, RenderTargetPixel::FromUntyped(aClipRect));
   }
   aContainer->mPrepared = nullptr;
+
+  // If it is a scrollable container layer with no child layers, and one of the APZCs
+  // attached to it has a nonempty async transform, then that transform is not applied
+  // to any visible content. Display a warning box (conditioned on the FPS display being
+  // enabled).
+  if (gfxPrefs::LayersDrawFPS() && aContainer->IsScrollInfoLayer()) {
+    // Since aContainer doesn't have any children we can just iterate from the top metrics
+    // on it down to the bottom using GetFirstChild and not worry about walking onto another
+    // underlying layer.
+    for (LayerMetricsWrapper i(aContainer); i; i = i.GetFirstChild()) {
+      if (AsyncPanZoomController* apzc = i.GetApzc()) {
+        if (!Matrix4x4(apzc->GetCurrentAsyncTransform()).IsIdentity()) {
+          aManager->UnusedApzTransformWarning();
+          break;
+        }
+      }
+    }
+  }
 }
 
 ContainerLayerComposite::ContainerLayerComposite(LayerManagerComposite *aManager)
   : ContainerLayer(aManager, nullptr)
   , LayerComposite(aManager)
 {
   MOZ_COUNT_CTOR(ContainerLayerComposite);
   mImplData = static_cast<LayerComposite*>(this);
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -98,17 +98,19 @@ LayerManagerComposite::ClearCachedResour
   // XXX the old LayerManagerOGL code had a mMaybeInvalidTree that it set to true here.
   // Do we need that?
 }
 
 /**
  * LayerManagerComposite
  */
 LayerManagerComposite::LayerManagerComposite(Compositor* aCompositor)
-: mCompositor(aCompositor)
+: mWarningLevel(0.0f)
+, mUnusedApzTransformWarning(false)
+, mCompositor(aCompositor)
 , mInTransaction(false)
 , mIsCompositorReady(false)
 , mDebugOverlayWantsNextFrame(false)
 , mGeometryChanged(true)
 {
   mTextRenderer = new TextRenderer(aCompositor);
   MOZ_ASSERT(aCompositor);
 }
@@ -341,21 +343,21 @@ LayerManagerComposite::RenderDebugOverla
 
   TimeStamp now = TimeStamp::Now();
 
   if (drawFps) {
     if (!mFPS) {
       mFPS = MakeUnique<FPSState>();
     }
 
+    float alpha = 1;
 #ifdef ANDROID
     // Draw a translation delay warning overlay
     int width;
     int border;
-    float alpha = 1;
     if ((now - mWarnTime).ToMilliseconds() < kVisualWarningDuration) {
       EffectChain effects;
 
       // Black blorder
       border = 4;
       width = 6;
       effects.mPrimaryEffect = new EffectSolidColor(gfx::Color(0, 0, 0, 1));
       mCompositor->DrawQuad(gfx::Rect(border, border, aBounds.width - 2 * border, width),
@@ -380,16 +382,28 @@ LayerManagerComposite::RenderDebugOverla
       mCompositor->DrawQuad(gfx::Rect(aBounds.width - border - width, border + width, width, aBounds.height - 2 * border - 2 * width),
                             aBounds, effects, alpha, gfx::Matrix4x4());
       SetDebugOverlayWantsNextFrame(true);
     }
 #endif
 
     float fillRatio = mCompositor->GetFillRatio();
     mFPS->DrawFPS(now, drawFrameColorBars ? 10 : 0, 0, unsigned(fillRatio), mCompositor);
+
+    if (mUnusedApzTransformWarning) {
+      // If we have an unused APZ transform on this composite, draw a 20x20 red box
+      // in the top-right corner
+      EffectChain effects;
+      effects.mPrimaryEffect = new EffectSolidColor(gfx::Color(1, 0, 0, 1));
+      mCompositor->DrawQuad(gfx::Rect(aBounds.width - 20, 0, aBounds.width, 20),
+                            aBounds, effects, alpha, gfx::Matrix4x4());
+
+      mUnusedApzTransformWarning = false;
+      SetDebugOverlayWantsNextFrame(true);
+    }
   } else {
     mFPS = nullptr;
   }
 
   if (drawFrameColorBars) {
     gfx::Rect sideRect(0, 0, 10, aBounds.height);
 
     EffectChain effects;
--- a/gfx/layers/composite/LayerManagerComposite.h
+++ b/gfx/layers/composite/LayerManagerComposite.h
@@ -252,16 +252,20 @@ public:
     if (mWarnTime.IsNull() ||
         severity > mWarningLevel ||
         mWarnTime + TimeDuration::FromMilliseconds(kVisualWarningDuration) < now) {
       mWarnTime = now;
       mWarningLevel = severity;
     }
   }
 
+  void UnusedApzTransformWarning() {
+    mUnusedApzTransformWarning = true;
+  }
+
 private:
   /** Region we're clipping our current drawing to. */
   nsIntRegion mClippingRegion;
   nsIntRect mRenderBounds;
 
   /** Current root layer. */
   LayerComposite* RootLayer() const;
 
@@ -292,16 +296,17 @@ private:
   void PopGroupForLayerEffects(RefPtr<CompositingRenderTarget> aPreviousTarget,
                                nsIntRect aClipRect,
                                bool aGrayscaleEffect,
                                bool aInvertEffect,
                                float aContrastEffect);
 
   float mWarningLevel;
   mozilla::TimeStamp mWarnTime;
+  bool mUnusedApzTransformWarning;
   RefPtr<Compositor> mCompositor;
   UniquePtr<LayerProperties> mClonedLayerTreeProperties;
 
   /**
    * Context target, nullptr when drawing directly to our swap chain.
    */
   RefPtr<gfx::DrawTarget> mTarget;
   nsIntRect mTargetBounds;