Bug 1279063. Part 3: Memset RGBX surfaces to 0xFF in Factory::CreateDataSourceSurface. r=lsalzman
authorMason Chang <mchang@mozilla.com>
Mon, 25 Jul 2016 16:36:36 -0700
changeset 331665 fe0c6517b2157b95549a53b25ce2b073ee4f0985
parent 331664 9bbf47e4f280bb654257b0d88c0a2baea2c1ffb9
child 331666 0a83bbcbf688560f0c42d3fce165649ba94e7aa7
push id9858
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 14:37:10 +0000
treeherdermozilla-aurora@203106ef6cb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslsalzman
bugs1279063
milestone50.0a1
Bug 1279063. Part 3: Memset RGBX surfaces to 0xFF in Factory::CreateDataSourceSurface. r=lsalzman
gfx/2d/Factory.cpp
gfx/2d/SourceSurfaceRawData.cpp
gfx/2d/SourceSurfaceRawData.h
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -822,18 +822,22 @@ Factory::CreateDataSourceSurface(const I
                                  SurfaceFormat aFormat,
                                  bool aZero)
 {
   if (!AllowedSurfaceSize(aSize)) {
     gfxCriticalError(LoggerOptionsBasedOnSize(aSize)) << "Failed to allocate a surface due to invalid size (DSS) " << aSize;
     return nullptr;
   }
 
+  // Skia doesn't support RGBX, so memset RGBX to 0xFF
+  bool clearSurface = aZero || aFormat == SurfaceFormat::B8G8R8X8;
+  uint8_t clearValue = aFormat == SurfaceFormat::B8G8R8X8 ? 0xFF : 0;
+
   RefPtr<SourceSurfaceAlignedRawData> newSurf = new SourceSurfaceAlignedRawData();
-  if (newSurf->Init(aSize, aFormat, aZero)) {
+  if (newSurf->Init(aSize, aFormat, clearSurface, clearValue)) {
     return newSurf.forget();
   }
 
   gfxWarning() << "CreateDataSourceSurface failed in init";
   return nullptr;
 }
 
 already_AddRefed<DataSourceSurface>
@@ -842,18 +846,22 @@ Factory::CreateDataSourceSurfaceWithStri
                                            int32_t aStride,
                                            bool aZero)
 {
   if (aStride < aSize.width * BytesPerPixel(aFormat)) {
     gfxCriticalError(LoggerOptionsBasedOnSize(aSize)) << "CreateDataSourceSurfaceWithStride failed with bad stride " << aStride << ", " << aSize << ", " << aFormat;
     return nullptr;
   }
 
+  // Skia doesn't support RGBX, so memset RGBX to 0xFF
+  bool clearSurface = aZero || aFormat == SurfaceFormat::B8G8R8X8;
+  uint8_t clearValue = aFormat == SurfaceFormat::B8G8R8X8 ? 0xFF : 0;
+
   RefPtr<SourceSurfaceAlignedRawData> newSurf = new SourceSurfaceAlignedRawData();
-  if (newSurf->InitWithStride(aSize, aFormat, aStride, aZero)) {
+  if (newSurf->Init(aSize, aFormat, clearSurface, clearValue, aStride)) {
     return newSurf.forget();
   }
 
   gfxCriticalError(LoggerOptionsBasedOnSize(aSize)) << "CreateDataSourceSurfaceWithStride failed to initialize " << aSize << ", " << aFormat << ", " << aStride << ", " << aZero;
   return nullptr;
 }
 
 static uint16_t
--- a/gfx/2d/SourceSurfaceRawData.cpp
+++ b/gfx/2d/SourceSurfaceRawData.cpp
@@ -44,50 +44,36 @@ SourceSurfaceRawData::GuaranteePersistan
 
   memcpy(mRawData, oldData, mStride * mSize.height);
   mOwnData = true;
 }
 
 bool
 SourceSurfaceAlignedRawData::Init(const IntSize &aSize,
                                   SurfaceFormat aFormat,
-                                  bool aZero)
+                                  bool aClearMem,
+                                  uint8_t aClearValue,
+                                  int32_t aStride)
 {
   mFormat = aFormat;
-  mStride = GetAlignedStride<16>(aSize.width * BytesPerPixel(aFormat));
+  mStride = aStride ? aStride : GetAlignedStride<16>(aSize.width * BytesPerPixel(aFormat));
 
   size_t bufLen = BufferSizeFromStrideAndHeight(mStride, aSize.height);
   if (bufLen > 0) {
+    bool zeroMem = aClearMem && !aClearValue;
     static_assert(sizeof(decltype(mArray[0])) == 1,
                   "mArray.Realloc() takes an object count, so its objects must be 1-byte sized if we use bufLen");
-    mArray.Realloc(/* actually an object count */ bufLen, aZero);
-    mSize = aSize;
-  } else {
-    mArray.Dealloc();
-    mSize.SizeTo(0, 0);
-  }
-
-  return mArray != nullptr;
-}
 
-bool
-SourceSurfaceAlignedRawData::InitWithStride(const IntSize &aSize,
-                                            SurfaceFormat aFormat,
-                                            int32_t aStride,
-                                            bool aZero)
-{
-  mFormat = aFormat;
-  mStride = aStride;
+    // AlignedArray uses cmalloc to zero mem for a fast path.
+    mArray.Realloc(/* actually an object count */ bufLen, zeroMem);
+    mSize = aSize;
 
-  size_t bufLen = BufferSizeFromStrideAndHeight(mStride, aSize.height);
-  if (bufLen > 0) {
-    static_assert(sizeof(decltype(mArray[0])) == 1,
-                  "mArray.Realloc() takes an object count, so its objects must be 1-byte sized if we use bufLen");
-    mArray.Realloc(/* actually an object count */ bufLen, aZero);
-    mSize = aSize;
+    if (mArray && aClearMem && aClearValue) {
+      memset(mArray, aClearValue, mStride * aSize.height);
+    }
   } else {
     mArray.Dealloc();
     mSize.SizeTo(0, 0);
   }
 
   return mArray != nullptr;
 }
 
--- a/gfx/2d/SourceSurfaceRawData.h
+++ b/gfx/2d/SourceSurfaceRawData.h
@@ -108,17 +108,17 @@ public:
     , mFormat(SurfaceFormat::UNKNOWN)
     , mMapCount(0)
   {}
   ~SourceSurfaceAlignedRawData()
   {
     MOZ_ASSERT(mMapCount == 0);
   }
 
-  virtual uint8_t *GetData() override { return mArray; }
+  virtual uint8_t* GetData() override { return mArray; }
   virtual int32_t Stride() override { return mStride; }
 
   virtual SurfaceType GetType() const override { return SurfaceType::DATA; }
   virtual IntSize GetSize() const override { return mSize; }
   virtual SurfaceFormat GetFormat() const override { return mFormat; }
 
   virtual bool Map(MapType, MappedSurface *aMappedSurface) override
   {
@@ -137,21 +137,19 @@ public:
     MOZ_ASSERT(mMapCount >= 0);
   }
 
 private:
   friend class Factory;
 
   bool Init(const IntSize &aSize,
             SurfaceFormat aFormat,
-            bool aZero);
-  bool InitWithStride(const IntSize &aSize,
-                      SurfaceFormat aFormat,
-                      int32_t aStride,
-                      bool aZero);
+            bool aClearMem,
+            uint8_t aClearValue,
+            int32_t aStride = 0);
 
   AlignedArray<uint8_t> mArray;
   int32_t mStride;
   SurfaceFormat mFormat;
   IntSize mSize;
   Atomic<int32_t> mMapCount;
 };