Bug 1301136 - make Skia VerifyRGBXFormat assertions give more useful information. r=mchang
authorLee Salzman <lsalzman@mozilla.com>
Wed, 07 Sep 2016 14:42:15 -0400
changeset 313071 0e851843cf5a65f8570dbc3f99ab16243b2bb307
parent 313070 8edc64f3a6e40c5f8aa67ed2255c49a4a1a2a386
child 313072 15dfa78b6aabea262599bcb452ab606d876d78c3
push id30669
push userkwierso@gmail.com
push dateThu, 08 Sep 2016 00:56:12 +0000
treeherdermozilla-central@77940cbf0c2a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmchang
bugs1301136
milestone51.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 1301136 - make Skia VerifyRGBXFormat assertions give more useful information. r=mchang MozReview-Commit-ID: 2En9Unt2LMM
gfx/2d/DrawTargetSkia.cpp
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -6,16 +6,18 @@
 #include "DrawTargetSkia.h"
 #include "SourceSurfaceSkia.h"
 #include "ScaledFontBase.h"
 #include "ScaledFontCairo.h"
 #include "skia/include/core/SkBitmapDevice.h"
 #include "FilterNodeSoftware.h"
 #include "HelpersSkia.h"
 
+#include "mozilla/ArrayUtils.h"
+
 #include "skia/include/core/SkSurface.h"
 #include "skia/include/core/SkTypeface.h"
 #include "skia/include/effects/SkGradientShader.h"
 #include "skia/include/core/SkColorFilter.h"
 #include "skia/include/effects/SkBlurImageFilter.h"
 #include "skia/include/effects/SkLayerRasterizer.h"
 #include "Blur.h"
 #include "Logging.h"
@@ -98,34 +100,36 @@ static void
 ReleaseTemporarySurface(void* aPixels, void* aContext)
 {
   DataSourceSurface* surf = static_cast<DataSourceSurface*>(aContext);
   if (surf) {
     surf->Release();
   }
 }
 
+#ifdef IS_BIG_ENDIAN
+static const int kARGBAlphaOffset = 0;
+#else
+static const int kARGBAlphaOffset = 3;
+#endif
+
 static void
 WriteRGBXFormat(uint8_t* aData, const IntSize &aSize,
                 const int32_t aStride, SurfaceFormat aFormat)
 {
   if (aFormat != SurfaceFormat::B8G8R8X8 || aSize.IsEmpty()) {
     return;
   }
 
   int height = aSize.height;
   int width = aSize.width * 4;
 
   for (int row = 0; row < height; ++row) {
     for (int column = 0; column < width; column += 4) {
-#ifdef IS_BIG_ENDIAN
-      aData[column] = 0xFF;
-#else
-      aData[column + 3] = 0xFF;
-#endif
+      aData[column + kARGBAlphaOffset] = 0xFF;
     }
     aData += aStride;
   }
 
   return;
 }
 
 #ifdef DEBUG
@@ -137,21 +141,24 @@ VerifyRGBXFormat(uint8_t* aData, const I
   }
   // We should've initialized the data to be opaque already
   // On debug builds, verify that this is actually true.
   int height = aSize.height;
   int width = aSize.width * 4;
 
   for (int row = 0; row < height; ++row) {
     for (int column = 0; column < width; column += 4) {
-#ifdef IS_BIG_ENDIAN
-      MOZ_ASSERT(aData[column] == 0xFF);
-#else
-      MOZ_ASSERT(aData[column + 3] == 0xFF);
-#endif
+      if (aData[column + kARGBAlphaOffset] != 0xFF) {
+        gfxCriticalError() << "RGBX pixel at (" << column << "," << row << ") in "
+                           << width << "x" << height << " surface is not opaque: "
+                           << int(aData[column]) << ","
+                           << int(aData[column+1]) << ","
+                           << int(aData[column+2]) << ","
+                           << int(aData[column+3]);
+      }
     }
     aData += aStride;
   }
 
   return true;
 }
 
 // Since checking every pixel is expensive, this only checks the four corners and center
@@ -164,37 +171,40 @@ VerifyRGBXCorners(uint8_t* aData, const 
   }
 
   int height = aSize.height;
   int width = aSize.width;
   const int pixelSize = 4;
   const int strideDiff = aStride - (width * pixelSize);
   MOZ_ASSERT(width * pixelSize <= aStride);
 
-#ifdef IS_BIG_ENDIAN
-  const int alphaOffset = 0;
-#else
-  const int alphaOffset = 3;
-#endif
-
-  const int topLeft = alphaOffset;
-  const int topRight = width * pixelSize + alphaOffset - pixelSize;
-  const int bottomRight = aStride * height - strideDiff + alphaOffset - pixelSize;
-  const int bottomLeft = aStride * height - aStride + alphaOffset;
+  const int topLeft = kARGBAlphaOffset;
+  const int topRight = width * pixelSize + kARGBAlphaOffset - pixelSize;
+  const int bottomRight = aStride * height - strideDiff + kARGBAlphaOffset - pixelSize;
+  const int bottomLeft = aStride * height - aStride + kARGBAlphaOffset;
 
   // Lastly the center pixel
   int middleRowHeight = height / 2;
   int middleRowWidth = (width / 2) * pixelSize;
-  const int middle = aStride * middleRowHeight + middleRowWidth + alphaOffset;
+  const int middle = aStride * middleRowHeight + middleRowWidth + kARGBAlphaOffset;
 
-  MOZ_ASSERT(aData[topLeft] == 0xFF);
-  MOZ_ASSERT(aData[topRight] == 0xFF);
-  MOZ_ASSERT(aData[bottomRight] == 0xFF);
-  MOZ_ASSERT(aData[bottomLeft] == 0xFF);
-  MOZ_ASSERT(aData[middle] == 0xFF);
+  const int offsets[] = { topLeft, topRight, bottomRight, bottomLeft, middle };
+  for (size_t i = 0; i < MOZ_ARRAY_LENGTH(offsets); i++) {
+    int offset = offsets[i];
+    if (aData[offset] != 0xFF) {
+        int row = offset / aStride;
+        int column = (offset % aStride) / pixelSize;
+        gfxCriticalError() << "RGBX corner pixel at (" << column << "," << row << ") in "
+                           << width << "x" << height << " surface is not opaque: "
+                           << int(aData[column]) << ","
+                           << int(aData[column+1]) << ","
+                           << int(aData[column+2]) << ","
+                           << int(aData[column+3]);
+    }
+  }
 
   return true;
 }
 #endif
 
 static SkBitmap
 GetBitmapForSurface(SourceSurface* aSurface)
 {