Bug 930033 - Draw layer borders for the bounding box of the visible region for ThebesLayers. r=nical
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 24 Oct 2013 16:35:29 +0200
changeset 165787 f73cf917219c25250b0d6857369196f3c691725a
parent 165786 c37138aadb0c0d5d7ddd8db9232ca5697d45f3b2
child 165788 89c119add8920a5d15a2459c75bb43ba375a0807
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs930033
milestone27.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 930033 - Draw layer borders for the bounding box of the visible region for ThebesLayers. r=nical
gfx/layers/Compositor.cpp
gfx/layers/Compositor.h
gfx/layers/CompositorTypes.h
gfx/layers/composite/ContentHost.cpp
gfx/thebes/gfx2DGlue.h
--- a/gfx/layers/Compositor.cpp
+++ b/gfx/layers/Compositor.cpp
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/layers/Compositor.h"
 #include "base/message_loop.h"          // for MessageLoop
 #include "mozilla/layers/CompositorParent.h"  // for CompositorParent
 #include "mozilla/layers/Effects.h"     // for Effect, EffectChain, etc
 #include "mozilla/mozalloc.h"           // for operator delete, etc
+#include "gfx2DGlue.h"
 
 namespace mozilla {
 namespace gfx {
 class Matrix4x4;
 }
 
 namespace layers {
 
@@ -27,33 +28,80 @@ Compositor::GetBackend()
 /* static */ void
 Compositor::AssertOnCompositorThread()
 {
   MOZ_ASSERT(CompositorParent::CompositorLoop() ==
              MessageLoop::current(),
              "Can only call this from the compositor thread!");
 }
 
+bool
+Compositor::ShouldDrawDiagnostics(DiagnosticFlags aFlags)
+{
+  if ((aFlags & DIAGNOSTIC_TILE) && !(mDiagnosticTypes & DIAGNOSTIC_TILE_BORDERS)) {
+    return false;
+  }
+  if ((aFlags & DIAGNOSTIC_BIGIMAGE) &&
+      !(mDiagnosticTypes & DIAGNOSTIC_BIGIMAGE_BORDERS)) {
+    return false;
+  }
+  if (!mDiagnosticTypes) {
+    return false;
+  }
+  return true;
+}
+
 void
 Compositor::DrawDiagnostics(DiagnosticFlags aFlags,
-                            const gfx::Rect& rect,
+                            const nsIntRegion& aVisibleRegion,
                             const gfx::Rect& aClipRect,
                             const gfx::Matrix4x4& aTransform,
                             const gfx::Point& aOffset)
 {
-  if ((aFlags & DIAGNOSTIC_TILE) && !(mDiagnosticTypes & DIAGNOSTIC_TILE_BORDERS)) {
-    return;
-  }
-  if ((aFlags & DIAGNOSTIC_BIGIMAGE) && !(mDiagnosticTypes & DIAGNOSTIC_BIGIMAGE_BORDERS)) {
-    return;
-  }
-  if (!mDiagnosticTypes) {
+  if (!ShouldDrawDiagnostics(aFlags)) {
     return;
   }
 
+  if (aVisibleRegion.GetNumRects() > 1) {
+    nsIntRegionRectIterator screenIter(aVisibleRegion);
+
+    while (const nsIntRect* rect = screenIter.Next())
+    {
+      DrawDiagnostics(aFlags | DIAGNOSTIC_REGION_RECT,
+                      ToRect(*rect), aClipRect, aTransform, aOffset);
+    }
+  }
+
+  DrawDiagnostics(aFlags, ToRect(aVisibleRegion.GetBounds()),
+                  aClipRect, aTransform, aOffset);
+}
+
+void
+Compositor::DrawDiagnostics(DiagnosticFlags aFlags,
+                            const gfx::Rect& aVisibleRect,
+                            const gfx::Rect& aClipRect,
+                            const gfx::Matrix4x4& aTransform,
+                            const gfx::Point& aOffset)
+{
+  if (!ShouldDrawDiagnostics(aFlags)) {
+    return;
+  }
+
+  DrawDiagnosticsInternal(aFlags, aVisibleRect,
+                          aClipRect, aTransform,
+                          aOffset);
+}
+
+void
+Compositor::DrawDiagnosticsInternal(DiagnosticFlags aFlags,
+                                    const gfx::Rect& aVisibleRect,
+                                    const gfx::Rect& aClipRect,
+                                    const gfx::Matrix4x4& aTransform,
+                                    const gfx::Point& aOffset)
+{
 #ifdef MOZ_B2G
   int lWidth = 4;
 #elif defined(ANDROID)
   int lWidth = 10;
 #else
   int lWidth = 2;
 #endif
   float opacity = 0.7;
@@ -68,43 +116,45 @@ Compositor::DrawDiagnostics(DiagnosticFl
     color = gfx::Color(1.0, 0.0, 0.0, 1.0); // red
   } else if (aFlags & DIAGNOSTIC_COLOR) {
     color = gfx::Color(0.0, 0.0, 1.0, 1.0); // blue
   } else if (aFlags & DIAGNOSTIC_CONTAINER) {
     color = gfx::Color(0.8, 0.0, 0.8, 1.0); // purple
   }
 
   // make tile borders a bit more transparent to keep layer borders readable.
-  if (aFlags & DIAGNOSTIC_TILE || aFlags & DIAGNOSTIC_BIGIMAGE) {
+  if (aFlags & DIAGNOSTIC_TILE ||
+      aFlags & DIAGNOSTIC_BIGIMAGE ||
+      aFlags & DIAGNOSTIC_REGION_RECT) {
     lWidth = 1;
     opacity = 0.5;
     color.r *= 0.7;
     color.g *= 0.7;
     color.b *= 0.7;
   }
 
   EffectChain effects;
 
   effects.mPrimaryEffect = new EffectSolidColor(color);
   // left
-  this->DrawQuad(gfx::Rect(rect.x, rect.y,
-                           lWidth, rect.height),
+  this->DrawQuad(gfx::Rect(aVisibleRect.x, aVisibleRect.y,
+                           lWidth, aVisibleRect.height),
                  aClipRect, effects, opacity,
                  aTransform, aOffset);
   // top
-  this->DrawQuad(gfx::Rect(rect.x + lWidth, rect.y,
-                           rect.width - 2 * lWidth, lWidth),
+  this->DrawQuad(gfx::Rect(aVisibleRect.x + lWidth, aVisibleRect.y,
+                           aVisibleRect.width - 2 * lWidth, lWidth),
                  aClipRect, effects, opacity,
                  aTransform, aOffset);
   // right
-  this->DrawQuad(gfx::Rect(rect.x + rect.width - lWidth, rect.y,
-                           lWidth, rect.height),
+  this->DrawQuad(gfx::Rect(aVisibleRect.x + aVisibleRect.width - lWidth, aVisibleRect.y,
+                           lWidth, aVisibleRect.height),
                  aClipRect, effects, opacity,
                  aTransform, aOffset);
   // bottom
-  this->DrawQuad(gfx::Rect(rect.x + lWidth, rect.y + rect.height-lWidth,
-                           rect.width - 2 * lWidth, lWidth),
+  this->DrawQuad(gfx::Rect(aVisibleRect.x + lWidth, aVisibleRect.y + aVisibleRect.height-lWidth,
+                           aVisibleRect.width - 2 * lWidth, lWidth),
                  aClipRect, effects, opacity,
                  aTransform, aOffset);
 }
 
 } // namespace
 } // namespace
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -99,16 +99,17 @@
  * - TextureHost (ex. SharedTextureHostOGL)
  * Depending on the type of data that needs to be serialized, you may need to
  * add specific TextureClient implementations.
  */
 
 class nsIWidget;
 struct gfxMatrix;
 struct nsIntSize;
+class nsIntRegion;
 
 namespace mozilla {
 namespace gfx {
 class Matrix4x4;
 class DrawTarget;
 }
 
 namespace layers {
@@ -346,16 +347,22 @@ public:
   }
 
   void DrawDiagnostics(DiagnosticFlags aFlags,
                        const gfx::Rect& visibleRect,
                        const gfx::Rect& aClipRect,
                        const gfx::Matrix4x4& transform,
                        const gfx::Point& aOffset);
 
+  void DrawDiagnostics(DiagnosticFlags aFlags,
+                       const nsIntRegion& visibleRegion,
+                       const gfx::Rect& aClipRect,
+                       const gfx::Matrix4x4& transform,
+                       const gfx::Point& aOffset);
+
 
 #ifdef MOZ_DUMP_PAINTING
   virtual const char* Name() const = 0;
 #endif // MOZ_DUMP_PAINTING
 
 
   /**
    * Each Compositor has a unique ID.
@@ -417,16 +424,24 @@ public:
    * static method. We need this for creating texture clients/hosts etc. when we
    * don't have a reference to a Compositor.
    *
    * This can only be used from the compositor thread!
    */
   static LayersBackend GetBackend();
 
 protected:
+  void DrawDiagnosticsInternal(DiagnosticFlags aFlags,
+                               const gfx::Rect& aVisibleRect,
+                               const gfx::Rect& aClipRect,
+                               const gfx::Matrix4x4& transform,
+                               const gfx::Point& aOffset);
+
+  bool ShouldDrawDiagnostics(DiagnosticFlags);
+
   uint32_t mCompositorID;
   static LayersBackend sBackend;
   DiagnosticTypes mDiagnosticTypes;
 
   /**
    * We keep track of the total number of pixels filled as we composite the
    * current frame. This value is an approximation and is not accurate,
    * especially in the presence of transforms.
--- a/gfx/layers/CompositorTypes.h
+++ b/gfx/layers/CompositorTypes.h
@@ -107,16 +107,17 @@ typedef uint32_t DiagnosticFlags;
 const DiagnosticFlags DIAGNOSTIC_IMAGE      = 1 << 0;
 const DiagnosticFlags DIAGNOSTIC_CONTENT    = 1 << 1;
 const DiagnosticFlags DIAGNOSTIC_CANVAS     = 1 << 2;
 const DiagnosticFlags DIAGNOSTIC_COLOR      = 1 << 3;
 const DiagnosticFlags DIAGNOSTIC_CONTAINER  = 1 << 4;
 const DiagnosticFlags DIAGNOSTIC_TILE       = 1 << 5;
 const DiagnosticFlags DIAGNOSTIC_BIGIMAGE   = 1 << 6;
 const DiagnosticFlags DIAGNOSTIC_COMPONENT_ALPHA = 1 << 7;
+const DiagnosticFlags DIAGNOSTIC_REGION_RECT = 1 << 8;
 
 /**
  * See gfx/layers/Effects.h
  */
 enum EffectTypes
 {
   EFFECT_MASK,
   EFFECT_MAX_SECONDARY, // sentinel for the count of secondary effect types
--- a/gfx/layers/composite/ContentHost.cpp
+++ b/gfx/layers/composite/ContentHost.cpp
@@ -201,35 +201,41 @@ ContentHostBase::Composite(EffectChain& 
             gfx::Rect rect(tileScreenRect.x, tileScreenRect.y,
                            tileScreenRect.width, tileScreenRect.height);
 
             effect->mTextureCoords = Rect(Float(tileRegionRect.x) / texRect.width,
                                           Float(tileRegionRect.y) / texRect.height,
                                           Float(tileRegionRect.width) / texRect.width,
                                           Float(tileRegionRect.height) / texRect.height);
             GetCompositor()->DrawQuad(rect, aClipRect, aEffectChain, aOpacity, aTransform, aOffset);
-            DiagnosticTypes diagnostics = DIAGNOSTIC_CONTENT;
-            diagnostics |= usingTiles ? DIAGNOSTIC_BIGIMAGE : 0;
-            diagnostics |= iterOnWhite ? DIAGNOSTIC_COMPONENT_ALPHA : 0;
-            GetCompositor()->DrawDiagnostics(diagnostics, rect, aClipRect, aTransform, aOffset);
+            if (usingTiles) {
+              DiagnosticTypes diagnostics = DIAGNOSTIC_CONTENT | DIAGNOSTIC_BIGIMAGE;
+              diagnostics |= iterOnWhite ? DIAGNOSTIC_COMPONENT_ALPHA : 0;
+              GetCompositor()->DrawDiagnostics(diagnostics, rect, aClipRect,
+                                               aTransform, aOffset);
+            }
         }
       }
     }
 
     if (iterOnWhite) {
       iterOnWhite->NextTile();
     }
   } while (usingTiles && tileIter->NextTile());
 
   if (tileIter) {
     tileIter->EndTileIteration();
   }
   if (iterOnWhite) {
     iterOnWhite->EndTileIteration();
   }
+
+  DiagnosticTypes diagnostics = DIAGNOSTIC_CONTENT;
+  diagnostics |= iterOnWhite ? DIAGNOSTIC_COMPONENT_ALPHA : 0;
+  GetCompositor()->DrawDiagnostics(diagnostics, *aVisibleRegion, aClipRect, aTransform, aOffset);
 }
 
 void
 ContentHostBase::SetCompositor(Compositor* aCompositor)
 {
   CompositableHost::SetCompositor(aCompositor);
   if (mDeprecatedTextureHost) {
     mDeprecatedTextureHost->SetCompositor(aCompositor);
--- a/gfx/thebes/gfx2DGlue.h
+++ b/gfx/thebes/gfx2DGlue.h
@@ -28,16 +28,21 @@ namespace mozilla {
 namespace gfx {
 
 inline Rect ToRect(const gfxRect &aRect)
 {
   return Rect(Float(aRect.x), Float(aRect.y),
               Float(aRect.width), Float(aRect.height));
 }
 
+inline Rect ToRect(const nsIntRect &aRect)
+{
+  return Rect(aRect.x, aRect.y, aRect.width, aRect.height);
+}
+
 inline IntRect ToIntRect(const nsIntRect &aRect)
 {
   return IntRect(aRect.x, aRect.y, aRect.width, aRect.height);
 }
 
 inline Color ToColor(const gfxRGBA &aRGBA)
 {
   return Color(Float(aRGBA.r), Float(aRGBA.g),