Bug 1146663 (Part 3) - Make it impossible to deoptimize imgFrames. r=tn
☠☠ backed out by 968702bfd84b ☠ ☠
authorSeth Fowler <mark.seth.fowler@gmail.com>
Sat, 19 Sep 2015 16:21:02 -0700
changeset 296042 77357a5a1ad1a0306b1f1f4688baf2d5312b315b
parent 296041 83a6dc9ee30c1c97314ea8a342154cba4a523ed1
child 296043 07d6fcc70e7c0476088f45264963505a63ebec53
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
bugs1146663
milestone43.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 1146663 (Part 3) - Make it impossible to deoptimize imgFrames. r=tn
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)