Remove easily-removed cases of DataSourceSurface::GetData(). (bug 1405390 part 1, r=bas)
authorDavid Anderson <danderson@mozilla.com>
Thu, 09 Nov 2017 00:43:29 -0800
changeset 441807 21cfd71761e89ac83fb84bc80fa08a56aff8c4ce
parent 441806 94d45591fe6002cf19259cc2fd80a4a394831d36
child 441808 3ae8914a63408662ab4fc26f93e14b8976e33d71
push id8134
push userryanvm@gmail.com
push dateFri, 10 Nov 2017 21:18:48 +0000
treeherdermozilla-beta@6c6c0e855154 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbas
bugs1405390
milestone58.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
Remove easily-removed cases of DataSourceSurface::GetData(). (bug 1405390 part 1, r=bas)
gfx/2d/DrawTargetSkia.cpp
gfx/2d/FilterProcessingSIMD-inl.h
gfx/2d/RecordedEventImpl.h
gfx/2d/SVGTurbulenceRenderer-inl.h
gfx/2d/unittest/TestBugs.cpp
gfx/layers/AsyncCanvasRenderer.cpp
gfx/layers/LayerScope.cpp
gfx/layers/d3d11/TextureD3D11.cpp
gfx/tests/gtest/TestCompositor.cpp
gfx/tests/gtest/TestTextures.cpp
gfx/thebes/gfxImageSurface.cpp
gfx/thebes/gfxUtils.cpp
image/test/gtest/Common.cpp
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -1568,22 +1568,24 @@ DrawTarget::Draw3DTransformedSurface(Sou
   RefPtr<DataSourceSurface> dstSurf =
     Factory::CreateDataSourceSurface(xformBounds.Size(),
                                      !srcImage->isOpaque() ?
                                        aSurface->GetFormat() : SurfaceFormat::A8R8G8B8_UINT32,
                                      true);
   if (!dstSurf) {
     return false;
   }
+
+  DataSourceSurface::ScopedMap map(dstSurf, DataSourceSurface::READ_WRITE);
   std::unique_ptr<SkCanvas> dstCanvas(
     SkCanvas::MakeRasterDirect(
                         SkImageInfo::Make(xformBounds.Width(), xformBounds.Height(),
                         GfxFormatToSkiaColorType(dstSurf->GetFormat()),
                         kPremul_SkAlphaType),
-      dstSurf->GetData(), dstSurf->Stride()));
+      map.GetData(), dstSurf->Stride()));
   if (!dstCanvas) {
     return false;
   }
 
   // Do the transform.
   SkPaint paint;
   paint.setAntiAlias(true);
   paint.setFilterQuality(kLow_SkFilterQuality);
@@ -1741,22 +1743,23 @@ DrawTargetSkia::OptimizeSourceSurfaceFor
 #endif
 
   if (aSurface->GetType() == SurfaceType::SKIA) {
     RefPtr<SourceSurface> surface(aSurface);
     return surface.forget();
   }
 
   RefPtr<DataSourceSurface> dataSurface = aSurface->GetDataSurface();
+  DataSourceSurface::ScopedMap map(dataSurface, DataSourceSurface::READ_WRITE);
 
   // For plugins, GDI can sometimes just write 0 to the alpha channel
   // even for RGBX formats. In this case, we have to manually write
   // the alpha channel to make Skia happy with RGBX and in case GDI
   // writes some bad data. Luckily, this only happens on plugins.
-  WriteRGBXFormat(dataSurface->GetData(), dataSurface->GetSize(),
+  WriteRGBXFormat(map.GetData(), dataSurface->GetSize(),
                   dataSurface->Stride(), dataSurface->GetFormat());
   return dataSurface.forget();
 }
 
 already_AddRefed<SourceSurface>
 DrawTargetSkia::OptimizeSourceSurface(SourceSurface *aSurface) const
 {
 #ifdef USE_SKIA_GPU
@@ -1770,18 +1773,21 @@ DrawTargetSkia::OptimizeSourceSurface(So
     return surface.forget();
   }
 
   // If we're not using skia-gl then drawing doesn't require any
   // uploading, so any data surface is fine. Call GetDataSurface
   // to trigger any required readback so that it only happens
   // once.
   RefPtr<DataSourceSurface> dataSurface = aSurface->GetDataSurface();
-  MOZ_ASSERT(VerifyRGBXFormat(dataSurface->GetData(), dataSurface->GetSize(),
+#ifdef DEBUG
+  DataSourceSurface::ScopedMap map(dataSurface, DataSourceSurface::READ);
+  MOZ_ASSERT(VerifyRGBXFormat(map.GetData(), dataSurface->GetSize(),
                               dataSurface->Stride(), dataSurface->GetFormat()));
+#endif
   return dataSurface.forget();
 }
 
 already_AddRefed<SourceSurface>
 DrawTargetSkia::CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const
 {
 #ifdef USE_SKIA_GPU
   if (aSurface.mType == NativeSurfaceType::OPENGL_TEXTURE && UsingSkiaGPU()) {
--- a/gfx/2d/FilterProcessingSIMD-inl.h
+++ b/gfx/2d/FilterProcessingSIMD-inl.h
@@ -15,18 +15,20 @@ namespace gfx {
 template<typename u8x16_t>
 inline already_AddRefed<DataSourceSurface>
 ConvertToB8G8R8A8_SIMD(SourceSurface* aSurface)
 {
   IntSize size = aSurface->GetSize();
   RefPtr<DataSourceSurface> input = aSurface->GetDataSurface();
   RefPtr<DataSourceSurface> output =
     Factory::CreateDataSourceSurface(size, SurfaceFormat::B8G8R8A8);
-  uint8_t *inputData = input->GetData();
-  uint8_t *outputData = output->GetData();
+  DataSourceSurface::ScopedMap inputMap(input, DataSourceSurface::READ);
+  DataSourceSurface::ScopedMap outputMap(output, DataSourceSurface::READ_WRITE);
+  uint8_t *inputData = inputMap.GetData();
+  uint8_t *outputData = outputMap.GetData();
   int32_t inputStride = input->Stride();
   int32_t outputStride = output->Stride();
   switch (input->GetFormat()) {
     case SurfaceFormat::B8G8R8A8:
       output = input;
       break;
     case SurfaceFormat::B8G8R8X8:
       for (int32_t y = 0; y < size.height; y++) {
@@ -290,19 +292,23 @@ ApplyBlending_SIMD(DataSourceSurface* aI
 {
   IntSize size = aInput1->GetSize();
   RefPtr<DataSourceSurface> target =
     Factory::CreateDataSourceSurface(size, SurfaceFormat::B8G8R8A8);
   if (!target) {
     return nullptr;
   }
 
-  uint8_t* source1Data = aInput1->GetData();
-  uint8_t* source2Data = aInput2->GetData();
-  uint8_t* targetData = target->GetData();
+  DataSourceSurface::ScopedMap inputMap1(aInput1, DataSourceSurface::READ);
+  DataSourceSurface::ScopedMap inputMap2(aInput2, DataSourceSurface::READ);
+  DataSourceSurface::ScopedMap outputMap(target, DataSourceSurface::READ_WRITE);
+
+  uint8_t* source1Data = inputMap1.GetData();
+  uint8_t* source2Data = inputMap2.GetData();
+  uint8_t* targetData = outputMap.GetData();
   int32_t targetStride = target->Stride();
   int32_t source1Stride = aInput1->Stride();
   int32_t source2Stride = aInput2->Stride();
 
   for (int32_t y = 0; y < size.height; y++) {
     for (int32_t x = 0; x < size.width; x += 4) {
       int32_t targetIndex = y * targetStride + 4 * x;
       int32_t source1Index = y * source1Stride + 4 * x;
@@ -515,18 +521,21 @@ ApplyColorMatrix_SIMD(DataSourceSurface*
 {
   IntSize size = aInput->GetSize();
   RefPtr<DataSourceSurface> target =
     Factory::CreateDataSourceSurface(size, SurfaceFormat::B8G8R8A8);
   if (!target) {
     return nullptr;
   }
 
-  uint8_t* sourceData = aInput->GetData();
-  uint8_t* targetData = target->GetData();
+  DataSourceSurface::ScopedMap inputMap(aInput, DataSourceSurface::READ);
+  DataSourceSurface::ScopedMap outputMap(target, DataSourceSurface::READ_WRITE);
+
+  uint8_t* sourceData = inputMap.GetData();
+  uint8_t* targetData = outputMap.GetData();
   int32_t sourceStride = aInput->Stride();
   int32_t targetStride = target->Stride();
 
   const int16_t factor = 128;
   const Float floatElementMax = INT16_MAX / factor; // 255
   MOZ_ASSERT((floatElementMax * factor) <= INT16_MAX, "badly chosen float-to-int scale");
 
   const Float *floats = &aMatrix._11;
@@ -697,18 +706,21 @@ CompositeTwoPixels(u16x8_t source, u16x8
 }
 
 template<typename i32x4_t, typename u16x8_t, typename u8x16_t, uint32_t op>
 static void
 ApplyComposition(DataSourceSurface* aSource, DataSourceSurface* aDest)
 {
   IntSize size = aDest->GetSize();
 
-  uint8_t* sourceData = aSource->GetData();
-  uint8_t* destData = aDest->GetData();
+  DataSourceSurface::ScopedMap input(aSource, DataSourceSurface::READ);
+  DataSourceSurface::ScopedMap output(aDest, DataSourceSurface::READ_WRITE);
+
+  uint8_t* sourceData = input.GetData();
+  uint8_t* destData = output.GetData();
   uint32_t sourceStride = aSource->Stride();
   uint32_t destStride = aDest->Stride();
 
   for (int32_t y = 0; y < size.height; y++) {
     for (int32_t x = 0; x < size.width; x += 4) {
       uint32_t sourceIndex = y * sourceStride + 4 * x;
       uint32_t destIndex = y * destStride + 4 * x;
 
@@ -1020,19 +1032,23 @@ ApplyArithmeticCombine_SIMD(DataSourceSu
 {
   IntSize size = aInput1->GetSize();
   RefPtr<DataSourceSurface> target =
   Factory::CreateDataSourceSurface(size, SurfaceFormat::B8G8R8A8);
   if (!target) {
     return nullptr;
   }
 
-  uint8_t* source1Data = aInput1->GetData();
-  uint8_t* source2Data = aInput2->GetData();
-  uint8_t* targetData = target->GetData();
+  DataSourceSurface::ScopedMap inputMap1(aInput1, DataSourceSurface::READ);
+  DataSourceSurface::ScopedMap inputMap2(aInput2, DataSourceSurface::READ);
+  DataSourceSurface::ScopedMap outputMap(target, DataSourceSurface::READ_WRITE);
+
+  uint8_t* source1Data = inputMap1.GetData();
+  uint8_t* source2Data = inputMap2.GetData();
+  uint8_t* targetData = outputMap.GetData();
   uint32_t source1Stride = aInput1->Stride();
   uint32_t source2Stride = aInput2->Stride();
   uint32_t targetStride = target->Stride();
 
   // The arithmetic combine filter does the following calculation:
   // result = k1 * in1 * in2 + k2 * in1 + k3 * in2 + k4
   //
   // Or, with in1/2 integers between 0 and 255:
--- a/gfx/2d/RecordedEventImpl.h
+++ b/gfx/2d/RecordedEventImpl.h
@@ -1528,18 +1528,20 @@ RecordedDrawTargetCreation::Record(S &aS
   WriteElement(aStream, mSize);
   WriteElement(aStream, mFormat);
   WriteElement(aStream, mHasExistingData);
 
   if (mHasExistingData) {
     MOZ_ASSERT(mExistingData);
     MOZ_ASSERT(mExistingData->GetSize() == mSize);
     RefPtr<DataSourceSurface> dataSurf = mExistingData->GetDataSurface();
+
+    DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ);
     for (int y = 0; y < mSize.height; y++) {
-      aStream.write((const char*)dataSurf->GetData() + y * dataSurf->Stride(),
+      aStream.write((const char*)map.GetData() + y * dataSurf->Stride(),
                     BytesPerPixel(mFormat) * mSize.width);
     }
   }
 }
 
 template<class S>
 RecordedDrawTargetCreation::RecordedDrawTargetCreation(S &aStream)
   : RecordedEventDerived(DRAWTARGETCREATION)
@@ -1554,18 +1556,19 @@ RecordedDrawTargetCreation::RecordedDraw
   if (mHasExistingData) {
     RefPtr<DataSourceSurface> dataSurf = Factory::CreateDataSourceSurface(mSize, mFormat);
     if (!dataSurf) {
       gfxWarning() << "RecordedDrawTargetCreation had to reset mHasExistingData";
       mHasExistingData = false;
       return;
     }
 
+    DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ);
     for (int y = 0; y < mSize.height; y++) {
-      aStream.read((char*)dataSurf->GetData() + y * dataSurf->Stride(),
+      aStream.read((char*)map.GetData() + y * dataSurf->Stride(),
                     BytesPerPixel(mFormat) * mSize.width);
     }
     mExistingData = dataSurf;
   }
 }
 
 inline void
 RecordedDrawTargetCreation::OutputSimpleEventInfo(std::stringstream &aStringStream) const
--- a/gfx/2d/SVGTurbulenceRenderer-inl.h
+++ b/gfx/2d/SVGTurbulenceRenderer-inl.h
@@ -324,17 +324,18 @@ already_AddRefed<DataSourceSurface>
 SVGTurbulenceRenderer<Type,Stitch,f32x4_t,i32x4_t,u8x16_t>::Render(const IntSize &aSize, const Point &aOffset) const
 {
   RefPtr<DataSourceSurface> target =
     Factory::CreateDataSourceSurface(aSize, SurfaceFormat::B8G8R8A8);
   if (!target) {
     return nullptr;
   }
 
-  uint8_t* targetData = target->GetData();
+  DataSourceSurface::ScopedMap map(target, DataSourceSurface::READ_WRITE);
+  uint8_t* targetData = map.GetData();
   uint32_t stride = target->Stride();
 
   Point startOffset = EquivalentNonNegativeOffset(aOffset);
 
   for (int32_t y = 0; y < aSize.height; y++) {
     for (int32_t x = 0; x < aSize.width; x += 4) {
       int32_t targIndex = y * stride + x * 4;
       i32x4_t a = Turbulence(startOffset + Point(x, y));
--- a/gfx/2d/unittest/TestBugs.cpp
+++ b/gfx/2d/unittest/TestBugs.cpp
@@ -56,19 +56,21 @@ TestBugs::CairoClip918671()
   dt->FillRect(Rect(0, 0, 100, 100), ColorPattern(Color(1,0,0)));
 
   RefPtr<SourceSurface> surf1 = dt->Snapshot();
   RefPtr<SourceSurface> surf2 = ref->Snapshot();
 
   RefPtr<DataSourceSurface> dataSurf1 = surf1->GetDataSurface();
   RefPtr<DataSourceSurface> dataSurf2 = surf2->GetDataSurface();
 
+  DataSourceSurface::ScopedMap map1(dataSurf1, DataSourceSurface::READ);
+  DataSourceSurface::ScopedMap map2(dataSurf2, DataSourceSurface::READ);
   for (int y = 0; y < dt->GetSize().height; y++) {
-    VERIFY(memcmp(dataSurf1->GetData() + y * dataSurf1->Stride(),
-                  dataSurf2->GetData() + y * dataSurf2->Stride(),
+    VERIFY(memcmp(map1.GetData() + y * dataSurf1->Stride(),
+                  map2.GetData() + y * dataSurf2->Stride(),
                   dataSurf1->GetSize().width * 4) == 0);
   }
 
 }
 
 void
 TestBugs::PushPopClip950550()
 {
--- a/gfx/layers/AsyncCanvasRenderer.cpp
+++ b/gfx/layers/AsyncCanvasRenderer.cpp
@@ -233,22 +233,23 @@ AsyncCanvasRenderer::UpdateTarget()
 
 already_AddRefed<gfx::DataSourceSurface>
 AsyncCanvasRenderer::GetSurface()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MutexAutoLock lock(mMutex);
   if (mSurfaceForBasic) {
     // Since SourceSurface isn't thread-safe, we need copy to a new SourceSurface.
+    gfx::DataSourceSurface::ScopedMap srcMap(mSurfaceForBasic, gfx::DataSourceSurface::READ);
+
     RefPtr<gfx::DataSourceSurface> result =
       gfx::Factory::CreateDataSourceSurfaceWithStride(mSurfaceForBasic->GetSize(),
                                                       mSurfaceForBasic->GetFormat(),
-                                                      mSurfaceForBasic->Stride());
+                                                      srcMap.GetStride());
 
-    gfx::DataSourceSurface::ScopedMap srcMap(mSurfaceForBasic, gfx::DataSourceSurface::READ);
     gfx::DataSourceSurface::ScopedMap dstMap(result, gfx::DataSourceSurface::WRITE);
 
     if (NS_WARN_IF(!srcMap.IsMapped()) ||
         NS_WARN_IF(!dstMap.IsMapped())) {
       return nullptr;
     }
 
     memcpy(dstMap.GetData(),
--- a/gfx/layers/LayerScope.cpp
+++ b/gfx/layers/LayerScope.cpp
@@ -498,38 +498,39 @@ private:
         tp->set_layerref(mLayerRef);
         tp->set_name(mName);
         tp->set_target(mTarget);
         tp->set_dataformat(LOCAL_GL_RGBA);
         tp->set_glcontext(static_cast<uint64_t>(mContextAddress));
         tp->set_ismask(mIsMask);
 
         if (aImage) {
+            DataSourceSurface::ScopedMap map(aImage, DataSourceSurface::READ);
             tp->set_width(aImage->GetSize().width);
             tp->set_height(aImage->GetSize().height);
             tp->set_stride(aImage->Stride());
 
             mDatasize = aImage->GetSize().height * aImage->Stride();
 
             auto compresseddata = MakeUnique<char[]>(LZ4::maxCompressedSize(mDatasize));
             if (compresseddata) {
-                int ndatasize = LZ4::compress((char*)aImage->GetData(),
+                int ndatasize = LZ4::compress((char*)map.GetData(),
                                               mDatasize,
                                               compresseddata.get());
                 if (ndatasize > 0) {
                     mDatasize = ndatasize;
                     tp->set_dataformat((1 << 16 | tp->dataformat()));
                     tp->set_data(compresseddata.get(), mDatasize);
                 } else {
                     NS_WARNING("Compress data failed");
-                    tp->set_data(aImage->GetData(), mDatasize);
+                    tp->set_data(map.GetData(), mDatasize);
                 }
             } else {
                 NS_WARNING("Couldn't new compressed data.");
-                tp->set_data(aImage->GetData(), mDatasize);
+                tp->set_data(map.GetData(), mDatasize);
             }
         } else {
             tp->set_width(0);
             tp->set_height(0);
             tp->set_stride(0);
         }
     }
 
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -1443,39 +1443,46 @@ DataTextureSourceD3D11::Update(DataSourc
         box.right = rect.XMost();
         box.bottom = rect.YMost();
 
         void* data = map.mData + map.mStride * rect.y + BytesPerPixel(aSurface->GetFormat()) * rect.x;
 
         context->UpdateSubresource(mTexture, 0, &box, data, map.mStride, map.mStride * rect.Height());
       }
     } else {
-      context->UpdateSubresource(mTexture, 0, nullptr, aSurface->GetData(),
+      context->UpdateSubresource(mTexture, 0, nullptr, map.mData,
                                  aSurface->Stride(), aSurface->Stride() * mSize.height);
     }
 
     aSurface->Unmap();
   } else {
     mIsTiled = true;
     uint32_t tileCount = GetRequiredTilesD3D11(mSize.width, maxSize) *
                          GetRequiredTilesD3D11(mSize.height, maxSize);
 
     mTileTextures.resize(tileCount);
     mTileSRVs.resize(tileCount);
     mTexture = nullptr;
 
+    DataSourceSurface::ScopedMap map(aSurface, DataSourceSurface::READ);
+    if (!map.IsMapped()) {
+      gfxCriticalError() << "Failed to map surface.";
+      Reset();
+      return false;
+    }
+
     for (uint32_t i = 0; i < tileCount; i++) {
       IntRect tileRect = GetTileRect(i);
 
       desc.Width = tileRect.Width();
       desc.Height = tileRect.Height();
       desc.Usage = D3D11_USAGE_IMMUTABLE;
 
       D3D11_SUBRESOURCE_DATA initData;
-      initData.pSysMem = aSurface->GetData() +
+      initData.pSysMem = map.GetData() +
                          tileRect.y * aSurface->Stride() +
                          tileRect.x * bpp;
       initData.SysMemPitch = aSurface->Stride();
 
       hr = mDevice->CreateTexture2D(&desc, &initData, getter_AddRefs(mTileTextures[i]));
       if (FAILED(hr) || !mTileTextures[i]) {
         Reset();
         return false;
--- a/gfx/tests/gtest/TestCompositor.cpp
+++ b/gfx/tests/gtest/TestCompositor.cpp
@@ -125,21 +125,23 @@ static bool CompositeAndCompare(RefPtr<L
 {
   RefPtr<DrawTarget> drawTarget = CreateDT();
 
   layerManager->BeginTransactionWithDrawTarget(drawTarget, IntRect(0, 0, gCompWidth, gCompHeight));
   layerManager->EndTransaction(TimeStamp::Now());
 
   RefPtr<SourceSurface> ss = drawTarget->Snapshot();
   RefPtr<DataSourceSurface> dss = ss->GetDataSurface();
-  uint8_t* bitmap = dss->GetData();
+  DataSourceSurface::ScopedMap dssMap(dss, DataSourceSurface::READ);
+  uint8_t* bitmap = dssMap.GetData();
 
   RefPtr<SourceSurface> ssRef = refDT->Snapshot();
   RefPtr<DataSourceSurface> dssRef = ssRef->GetDataSurface();
-  uint8_t* bitmapRef = dssRef->GetData();
+  DataSourceSurface::ScopedMap dssRefMap(dssRef, DataSourceSurface::READ);
+  uint8_t* bitmapRef = dssRefMap.GetData();
 
   for (int y = 0; y < gCompHeight; y++) {
     for (int x = 0; x < gCompWidth; x++) {
       for (size_t channel = 0; channel < 4; channel++) {
         uint8_t bit = bitmap[y * dss->Stride() + x * 4 + channel];
         uint8_t bitRef = bitmapRef[y * dss->Stride() + x * 4 + channel];
         if (bit != bitRef) {
           printf("Layer Tree:\n");
--- a/gfx/tests/gtest/TestTextures.cpp
+++ b/gfx/tests/gtest/TestTextures.cpp
@@ -158,18 +158,19 @@ void TestTextureClientSurface(TextureCli
 
   // XXX - this can fail because lock tries to upload the texture but it needs a
   // Compositor to do that. We could add a DummyComposior for testing but I am
   // not sure it'll be worth it. Maybe always test against a BasicCompositor,
   // but the latter needs a widget...
   if (host->Lock()) {
     RefPtr<mozilla::gfx::DataSourceSurface> hostDataSurface = host->GetAsSurface();
 
+    DataSourceSurface::ScopedMap map(hostDataSurface, DataSourceSurface::READ);
     RefPtr<gfxImageSurface> hostSurface =
-      new gfxImageSurface(hostDataSurface->GetData(),
+      new gfxImageSurface(map.GetData(),
                           hostDataSurface->GetSize(),
                           hostDataSurface->Stride(),
                           SurfaceFormatToImageFormat(hostDataSurface->GetFormat()));
     AssertSurfacesEqual(surface, hostSurface.get());
     host->Unlock();
   }
 }
 
--- a/gfx/thebes/gfxImageSurface.cpp
+++ b/gfx/thebes/gfxImageSurface.cpp
@@ -274,17 +274,18 @@ gfxImageSurface::CopyFrom (SourceSurface
         return false;
     }
 
     if (!FormatsAreCompatible(SurfaceFormatToImageFormat(aSurface->GetFormat()),
                               mFormat)) {
         return false;
     }
 
-    CopyForStride(mData, data->GetData(), size, mStride, data->Stride());
+    DataSourceSurface::ScopedMap map(data, DataSourceSurface::READ);
+    CopyForStride(mData, map.GetData(), size, mStride, data->Stride());
 
     return true;
 }
 
 
 bool
 gfxImageSurface::CopyFrom(gfxImageSurface *other)
 {
@@ -314,17 +315,18 @@ gfxImageSurface::CopyTo(SourceSurface *a
         return false;
     }
 
     if (!FormatsAreCompatible(SurfaceFormatToImageFormat(aSurface->GetFormat()),
                               mFormat)) {
         return false;
     }
 
-    CopyForStride(data->GetData(), mData, size, data->Stride(), mStride);
+    DataSourceSurface::ScopedMap map(data, DataSourceSurface::READ_WRITE);
+    CopyForStride(map.GetData(), mData, size, data->Stride(), mStride);
 
     return true;
 }
 
 already_AddRefed<DataSourceSurface>
 gfxImageSurface::CopyToB8G8R8A8DataSourceSurface()
 {
   RefPtr<DataSourceSurface> dataSurface =
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -1296,17 +1296,18 @@ gfxUtils::DumpAsDataURI(DrawTarget* aDT,
 }
 
 /* static */ nsCString
 gfxUtils::GetAsLZ4Base64Str(DataSourceSurface* aSourceSurface)
 {
   int32_t dataSize = aSourceSurface->GetSize().height * aSourceSurface->Stride();
   auto compressedData = MakeUnique<char[]>(LZ4::maxCompressedSize(dataSize));
   if (compressedData) {
-    int nDataSize = LZ4::compress((char*)aSourceSurface->GetData(),
+    DataSourceSurface::ScopedMap map(aSourceSurface, DataSourceSurface::READ);
+    int nDataSize = LZ4::compress((char*)map.GetData(),
                                   dataSize,
                                   compressedData.get());
     if (nDataSize > 0) {
       nsCString encodedImg;
       nsresult rv = Base64Encode(Substring(compressedData.get(), nDataSize), encodedImg);
       if (rv == NS_OK) {
         nsCString string("");
         string.AppendPrintf("data:image/lz4bgra;base64,%i,%i,%i,",
--- a/image/test/gtest/Common.cpp
+++ b/image/test/gtest/Common.cpp
@@ -188,17 +188,17 @@ RectIsSolidColor(SourceSurface* aSurface
   ASSERT_TRUE_OR_RETURN(dataSurface != nullptr, false);
 
   ASSERT_EQ_OR_RETURN(dataSurface->Stride(), surfaceSize.width * 4, false);
 
   DataSourceSurface::ScopedMap mapping(dataSurface,
                                        DataSourceSurface::MapType::READ);
   ASSERT_TRUE_OR_RETURN(mapping.IsMapped(), false);
 
-  uint8_t* data = dataSurface->GetData();
+  uint8_t* data = mapping.GetData();
   ASSERT_TRUE_OR_RETURN(data != nullptr, false);
 
   int32_t rowLength = dataSurface->Stride();
   for (int32_t row = rect.y; row < rect.YMost(); ++row) {
     for (int32_t col = rect.x; col < rect.XMost(); ++col) {
       int32_t i = row * rowLength + col * 4;
       if (aFuzz != 0) {
         ASSERT_LE_OR_RETURN(abs(aColor.mBlue - data[i + 0]), aFuzz, false);
@@ -269,17 +269,17 @@ RowHasPixels(SourceSurface* aSurface,
   ASSERT_TRUE_OR_RETURN(dataSurface, false);
 
   ASSERT_EQ_OR_RETURN(dataSurface->Stride(), surfaceSize.width * 4, false);
 
   DataSourceSurface::ScopedMap mapping(dataSurface,
                                        DataSourceSurface::MapType::READ);
   ASSERT_TRUE_OR_RETURN(mapping.IsMapped(), false);
 
-  uint8_t* data = dataSurface->GetData();
+  uint8_t* data = mapping.GetData();
   ASSERT_TRUE_OR_RETURN(data != nullptr, false);
 
   int32_t rowLength = dataSurface->Stride();
   for (int32_t col = 0; col < surfaceSize.width; ++col) {
     int32_t i = aRow * rowLength + col * 4;
     ASSERT_EQ_OR_RETURN(aPixels[col].mBlue,  data[i + 0], false);
     ASSERT_EQ_OR_RETURN(aPixels[col].mGreen, data[i + 1], false);
     ASSERT_EQ_OR_RETURN(aPixels[col].mRed,   data[i + 2], false);