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 348701 fe0c6517b2157b95549a53b25ce2b073ee4f0985
parent 348700 9bbf47e4f280bb654257b0d88c0a2baea2c1ffb9
child 348702 0a83bbcbf688560f0c42d3fce165649ba94e7aa7
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslsalzman
bugs1279063
milestone50.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 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;
 };