Bug 1146663 (Part 3) - Make it impossible to deoptimize imgFrames. r=tn,a=lizzard
authorSeth Fowler <mark.seth.fowler@gmail.com>
Fri, 18 Sep 2015 01:13:59 -0700
changeset 296369 7ef75c70593d0f4670a3db9e5add74800c9631f2
parent 296368 dfb869dc6a74c304a0e7b012e08e2f6f3221faad
child 296370 7e0e6b83998333bc6dbfc7dbc97a3c691d9439a5
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstn, lizzard
bugs1146663
milestone43.0a2
Bug 1146663 (Part 3) - Make it impossible to deoptimize imgFrames. r=tn,a=lizzard
image/imgFrame.cpp
image/imgFrame.h
--- a/image/imgFrame.cpp
+++ b/image/imgFrame.cpp
@@ -791,98 +791,18 @@ imgFrame::LockImageData()
     return NS_OK;
   }
 
   // Paletted images don't have surfaces, so there's nothing to do.
   if (mPalettedImageData) {
     return NS_OK;
   }
 
-  return Deoptimize();
-}
-
-nsresult
-imgFrame::Deoptimize()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  mMonitor.AssertCurrentThreadOwns();
-  MOZ_ASSERT(!mImageSurface);
-
-  if (!mImageSurface) {
-    if (mVBuf) {
-      VolatileBufferPtr<uint8_t> ref(mVBuf);
-      if (ref.WasBufferPurged()) {
-        return NS_ERROR_FAILURE;
-      }
-
-      mImageSurface = CreateLockedSurface(mVBuf, mSize, mFormat);
-      if (!mImageSurface) {
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-    }
-    if (mOptSurface || mSinglePixel || mFormat == SurfaceFormat::R5G6B5) {
-      SurfaceFormat format = mFormat;
-      if (mFormat == SurfaceFormat::R5G6B5) {
-        format = SurfaceFormat::B8G8R8A8;
-      }
-
-      // Recover the pixels
-      RefPtr<VolatileBuffer> buf =
-        AllocateBufferForImage(mSize, format);
-      if (!buf) {
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-
-      RefPtr<DataSourceSurface> surf =
-        CreateLockedSurface(buf, mSize, format);
-      if (!surf) {
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-
-      DataSourceSurface::MappedSurface mapping;
-      if (!surf->Map(DataSourceSurface::MapType::WRITE, &mapping)) {
-        gfxCriticalError() << "imgFrame::Deoptimize failed to map surface";
-        return NS_ERROR_FAILURE;
-      }
-
-      RefPtr<DrawTarget> target =
-        Factory::CreateDrawTargetForData(BackendType::CAIRO,
-                                         mapping.mData,
-                                         mSize,
-                                         mapping.mStride,
-                                         format);
-      if (!target) {
-        gfxWarning() <<
-          "imgFrame::Deoptimize failed in CreateDrawTargetForData";
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-
-      Rect rect(0, 0, mSize.width, mSize.height);
-      if (mSinglePixel) {
-        target->FillRect(rect, ColorPattern(mSinglePixelColor),
-                         DrawOptions(1.0f, CompositionOp::OP_SOURCE));
-      } else if (mFormat == SurfaceFormat::R5G6B5) {
-        target->DrawSurface(mImageSurface, rect, rect);
-      } else {
-        target->DrawSurface(mOptSurface, rect, rect,
-                            DrawSurfaceOptions(),
-                            DrawOptions(1.0f, CompositionOp::OP_SOURCE));
-      }
-      target->Flush();
-      surf->Unmap();
-
-      mFormat = format;
-      mVBuf = buf;
-      mImageSurface = surf;
-      mOptSurface = nullptr;
-    }
-  }
-
-  mVBufPtr = mVBuf;
-  return NS_OK;
+  MOZ_ASSERT_UNREACHABLE("It's illegal to re-lock an optimized imgFrame");
+  return NS_ERROR_FAILURE;
 }
 
 void
 imgFrame::AssertImageDataLocked() const
 {
 #ifdef DEBUG
   MonitorAutoLock lock(mMonitor);
   MOZ_ASSERT(mLockCount > 0, "Image data should be locked");
--- a/image/imgFrame.h
+++ b/image/imgFrame.h
@@ -269,17 +269,16 @@ public:
 
 private: // methods
 
   ~imgFrame();
 
   nsresult LockImageData();
   nsresult UnlockImageData();
   nsresult Optimize();
-  nsresult Deoptimize();
 
   void AssertImageDataLocked() const;
 
   bool IsImageCompleteInternal() const;
   nsresult ImageUpdatedInternal(const nsIntRect& aUpdateRect);
   void GetImageDataInternal(uint8_t** aData, uint32_t* length) const;
   uint32_t GetImageBytesPerRow() const;
   uint32_t GetImageDataLength() const;
@@ -443,16 +442,19 @@ private:
  * |ref| and |if (ref)| is true, then calls to GetImageData(), GetPaletteData(),
  * and GetDrawTarget() are guaranteed to succeed. This guarantee is stronger
  * than DrawableFrameRef, so everything that a valid DrawableFrameRef guarantees
  * is also guaranteed by a valid RawAccessFrameRef.
  *
  * This may be considerably more expensive than is necessary just for drawing,
  * so only use this when you need to read or write the raw underlying image data
  * that the imgFrame holds.
+ *
+ * Once all an imgFrame's RawAccessFrameRefs go out of scope, new
+ * RawAccessFrameRefs cannot be created.
  */
 class RawAccessFrameRef final
 {
 public:
   RawAccessFrameRef() { }
 
   explicit RawAccessFrameRef(imgFrame* aFrame)
     : mFrame(aFrame)