b=874781; add color bars to layer diagnostics, for vsync checking; r=benwa
authorVladimir Vukicevic <vladimir@pobox.com>
Thu, 08 May 2014 16:49:01 -0400
changeset 182227 1073160bd1e442733f26f9ccb3bc3285a1de7ec6
parent 182226 c590fcb23c3c1c1bb3a41979b04fdc3031953130
child 182228 47f27d39796d592e3689d7e7d73d6e407ed3106a
push id43235
push uservladimir@pobox.com
push dateThu, 08 May 2014 20:49:29 +0000
treeherdermozilla-inbound@1073160bd1e4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbenwa
bugs874781
milestone32.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
b=874781; add color bars to layer diagnostics, for vsync checking; r=benwa
gfx/layers/composite/FPSCounter.h
gfx/layers/composite/LayerManagerComposite.cpp
gfx/thebes/gfxPrefs.h
gfx/thebes/gfxUtils.cpp
gfx/thebes/gfxUtils.h
modules/libpref/src/init/all.js
--- a/gfx/layers/composite/FPSCounter.h
+++ b/gfx/layers/composite/FPSCounter.h
@@ -72,17 +72,17 @@ private:
 };
 
 struct FPSState {
   FPSCounter mCompositionFps;
   FPSCounter mTransactionFps;
 
   FPSState() {}
 
-  void DrawFPS(TimeStamp, unsigned, Compositor* aCompositor);
+  void DrawFPS(TimeStamp, int offsetX, int offsetY, unsigned, Compositor* aCompositor);
 
   void NotifyShadowTreeTransaction() {
     mTransactionFps.AddFrame(TimeStamp::Now());
   }
 
 private:
   RefPtr<DataTextureSource> mFPSTextureSource;
 };
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -21,16 +21,17 @@
 #include "Units.h"                      // for ScreenIntRect
 #include "gfx2DGlue.h"                  // for ToMatrix4x4
 #include "gfx3DMatrix.h"                // for gfx3DMatrix
 #include "gfxPrefs.h"                   // for gfxPrefs
 #ifdef XP_MACOSX
 #include "gfxPlatformMac.h"
 #endif
 #include "gfxRect.h"                    // for gfxRect
+#include "gfxUtils.h"                   // for frame color util
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/RefPtr.h"             // for RefPtr, TemporaryRef
 #include "mozilla/gfx/2D.h"             // for DrawTarget
 #include "mozilla/gfx/Matrix.h"         // for Matrix4x4
 #include "mozilla/gfx/Point.h"          // for IntSize, Point
 #include "mozilla/gfx/Rect.h"           // for Rect
 #include "mozilla/gfx/Types.h"          // for Color, SurfaceFormat
 #include "mozilla/layers/Compositor.h"  // for Compositor
@@ -315,19 +316,19 @@ static const float FontHeight = 7.f;
 static const float FontWidth = 4.f;
 static const float FontStride = 4.f;
 
 // Scale the font when drawing it to the viewport for better readability.
 static const float FontScaleX = 2.f;
 static const float FontScaleY = 3.f;
 
 static void DrawDigits(unsigned int aValue,
-		       int aOffsetX, int aOffsetY,
+                       int aOffsetX, int aOffsetY,
                        Compositor* aCompositor,
-		       EffectChain& aEffectChain)
+                       EffectChain& aEffectChain)
 {
   if (aValue > 999) {
     aValue = 999;
   }
 
   unsigned int divisor = 100;
   float textureWidth = FontWidth * 10;
   gfx::Float opacity = 1;
@@ -344,16 +345,17 @@ static void DrawDigits(unsigned int aVal
     Rect drawRect = Rect(aOffsetX + n * FontWidth, aOffsetY, FontWidth, FontHeight);
     Rect clipRect = Rect(0, 0, 300, 100);
     aCompositor->DrawQuad(drawRect, clipRect,
 	aEffectChain, opacity, transform);
   }
 }
 
 void FPSState::DrawFPS(TimeStamp aNow,
+                       int aOffsetX, int aOffsetY,
                        unsigned int aFillRatio,
                        Compositor* aCompositor)
 {
   if (!mFPSTextureSource) {
     const char *text =
       "                                        "
       " XXX XX  XXX XXX X X XXX XXX XXX XXX XXX"
       " X X  X    X   X X X X   X     X X X X X"
@@ -382,37 +384,53 @@ void FPSState::DrawFPS(TimeStamp aNow,
   }
 
   EffectChain effectChain;
   effectChain.mPrimaryEffect = CreateTexturedEffect(SurfaceFormat::B8G8R8A8, mFPSTextureSource, Filter::POINT);
 
   unsigned int fps = unsigned(mCompositionFps.AddFrameAndGetFps(aNow));
   unsigned int txnFps = unsigned(mTransactionFps.GetFpsAt(aNow));
 
-  DrawDigits(fps, 0, 0, aCompositor, effectChain);
-  DrawDigits(txnFps, FontWidth * 4, 0, aCompositor, effectChain);
-  DrawDigits(aFillRatio, FontWidth * 8, 0, aCompositor, effectChain);
+  DrawDigits(fps, aOffsetX + 0, aOffsetY, aCompositor, effectChain);
+  DrawDigits(txnFps, aOffsetX + FontWidth * 4, aOffsetY, aCompositor, effectChain);
+  DrawDigits(aFillRatio, aOffsetX + FontWidth * 8, aOffsetY, aCompositor, effectChain);
 }
 
 static uint16_t sFrameCount = 0;
 void
 LayerManagerComposite::RenderDebugOverlay(const Rect& aBounds)
 {
-  if (gfxPrefs::LayersDrawFPS()) {
+  bool drawFps = gfxPrefs::LayersDrawFPS();
+  bool drawFrameCounter = gfxPrefs::DrawFrameCounter();
+  bool drawFrameColorBars = gfxPrefs::CompositorDrawColorBars();
+
+  if (drawFps) {
     if (!mFPS) {
       mFPS = new FPSState();
     }
 
     float fillRatio = mCompositor->GetFillRatio();
-    mFPS->DrawFPS(TimeStamp::Now(), unsigned(fillRatio), mCompositor);
+    mFPS->DrawFPS(TimeStamp::Now(), drawFrameColorBars ? 10 : 0, 0, unsigned(fillRatio), mCompositor);
   } else {
     mFPS = nullptr;
   }
 
-  if (gfxPrefs::DrawFrameCounter()) {
+  if (drawFrameColorBars) {
+    gfx::Rect sideRect(0, 0, 10, aBounds.height);
+
+    EffectChain effects;
+    effects.mPrimaryEffect = new EffectSolidColor(gfxUtils::GetColorForFrameNumber(sFrameCount));
+    mCompositor->DrawQuad(sideRect,
+                          sideRect,
+                          effects,
+                          1.0,
+                          gfx::Matrix4x4());
+  }
+
+  if (drawFrameCounter) {
     profiler_set_frame_number(sFrameCount);
 
     uint16_t frameNumber = sFrameCount;
     const uint16_t bitWidth = 3;
     float opacity = 1.0;
     gfx::Rect clip(0,0, bitWidth*16, bitWidth);
     for (size_t i = 0; i < 16; i++) {
 
@@ -425,16 +443,19 @@ LayerManagerComposite::RenderDebugOverla
       EffectChain effects;
       effects.mPrimaryEffect = new EffectSolidColor(bitColor);
       mCompositor->DrawQuad(gfx::Rect(bitWidth*i, 0, bitWidth, bitWidth),
                             clip,
                             effects,
                             opacity,
                             gfx::Matrix4x4());
     }
+  }
+
+  if (drawFrameColorBars || drawFrameCounter) {
     // We intentionally overflow at 2^16.
     sFrameCount++;
   }
 }
 
 void
 LayerManagerComposite::Render()
 {
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -147,16 +147,18 @@ private:
 
   DECL_GFX_PREF(Once, "gfx.direct2d.disabled",                 Direct2DDisabled, bool, false);
   DECL_GFX_PREF(Once, "gfx.direct2d.force-enabled",            Direct2DForceEnabled, bool, false);
   DECL_GFX_PREF(Live, "gfx.gralloc.fence-with-readpixels",     GrallocFenceWithReadPixels, bool, false);
   DECL_GFX_PREF(Live, "gfx.layerscope.enabled",                LayerScopeEnabled, bool, false);
   DECL_GFX_PREF(Live, "gfx.layerscope.port",                   LayerScopePort, int32_t, 23456);
   DECL_GFX_PREF(Once, "gfx.work-around-driver-bugs",           WorkAroundDriverBugs, bool, true);
 
+  DECL_GFX_PREF(Live, "gfx.draw-color-bars",                   CompositorDrawColorBars, bool, false);
+
   DECL_GFX_PREF(Live, "gl.msaa-level",                         MSAALevel, uint32_t, 2);
 
   DECL_GFX_PREF(Once, "layers.acceleration.disabled",          LayersAccelerationDisabled, bool, false);
   DECL_GFX_PREF(Live, "layers.acceleration.draw-fps",          LayersDrawFPS, bool, false);
   DECL_GFX_PREF(Once, "layers.acceleration.force-enabled",     LayersAccelerationForceEnabled, bool, false);
 #ifdef XP_WIN
   // On windows, ignore the preference value, forcing async video to false.
   DECL_GFX_PREF(Skip, "layers.async-video.enabled",            AsyncVideoEnabled, bool, false);
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -994,16 +994,41 @@ gfxUtils::CopySurfaceToDataSourceSurface
   // Using OP_OVER since in our case it's equivalent to OP_SOURCE and
   // generally more optimized.
   dt->DrawSurface(aSurface, bounds, bounds, DrawSurfaceOptions(),
                   DrawOptions(1.0f, CompositionOp::OP_OVER));
   dataSurface->Unmap();
   return dataSurface.forget();
 }
 
+const uint32_t gfxUtils::sNumFrameColors = 8;
+
+/* static */ const gfx::Color&
+gfxUtils::GetColorForFrameNumber(uint64_t aFrameNumber)
+{
+    static bool initialized = false;
+    static gfx::Color colors[sNumFrameColors];
+
+    if (!initialized) {
+        uint32_t i = 0;
+        colors[i++] = gfx::Color::FromABGR(0xffff0000);
+        colors[i++] = gfx::Color::FromABGR(0xffcc00ff);
+        colors[i++] = gfx::Color::FromABGR(0xff0066cc);
+        colors[i++] = gfx::Color::FromABGR(0xff00ff00);
+        colors[i++] = gfx::Color::FromABGR(0xff33ffff);
+        colors[i++] = gfx::Color::FromABGR(0xffff0099);
+        colors[i++] = gfx::Color::FromABGR(0xff0000ff);
+        colors[i++] = gfx::Color::FromABGR(0xff999999);
+        MOZ_ASSERT(i == sNumFrameColors);
+        initialized = true;
+    }
+
+    return colors[aFrameNumber % sNumFrameColors];
+}
+
 #ifdef MOZ_DUMP_PAINTING
 /* static */ void
 gfxUtils::WriteAsPNG(DrawTarget* aDT, const char* aFile)
 {
   aDT->Flush();
   nsRefPtr<gfxASurface> surf = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(aDT);
   if (surf) {
     surf->WriteAsPNG(aFile);
--- a/gfx/thebes/gfxUtils.h
+++ b/gfx/thebes/gfxUtils.h
@@ -205,16 +205,25 @@ public:
      * readback.)
      */
     static mozilla::TemporaryRef<DataSourceSurface>
     CopySurfaceToDataSourceSurfaceWithFormat(SourceSurface* aSurface,
                                              SurfaceFormat aFormat);
 
     static const uint8_t sUnpremultiplyTable[256*256];
     static const uint8_t sPremultiplyTable[256*256];
+
+    /**
+     * Return a color that can be used to identify a frame with a given frame number.
+     * The colors will cycle after sNumFrameColors.  You can query colors 0 .. sNumFrameColors-1
+     * to get all the colors back.
+     */
+    static const mozilla::gfx::Color& GetColorForFrameNumber(uint64_t aFrameNumber);
+    static const uint32_t sNumFrameColors;
+
 #ifdef MOZ_DUMP_PAINTING
     /**
      * Writes a binary PNG file.
      */
     static void WriteAsPNG(mozilla::gfx::DrawTarget* aDT, const char* aFile);
 
     /**
      * Write as a PNG encoded Data URL to stdout.
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -444,16 +444,18 @@ pref("gfx.content.azure.backends", "cair
 #endif
 #ifdef ANDROID
 pref("gfx.content.azure.backends", "cairo");
 #endif
 
 pref("gfx.work-around-driver-bugs", true);
 pref("gfx.prefer-mesa-llvmpipe", false);
 
+pref("gfx.draw-color-bars", false);
+
 pref("accessibility.browsewithcaret", false);
 pref("accessibility.warn_on_browsewithcaret", true);
 
 pref("accessibility.browsewithcaret_shortcut.enabled", true);
 
 #ifndef XP_MACOSX
 // Tab focus model bit field:
 // 1 focuses text controls, 2 focuses other form elements, 4 adds links.