Bug 1213744 (Part 1) - Support zero-size frame rects and detecting the end of the frame in Downscaler. r=tn
authorSeth Fowler <mark.seth.fowler@gmail.com>
Sun, 25 Oct 2015 13:14:14 -0700
changeset 304597 1059ad52078ec19fdf29bfc416dbeb3ebe2c68c4
parent 304596 c0e1ef583bb9d5d33fdb034f597e0b0737aae949
child 304598 61d1f8675fc39e0fd1abb9828bbd30e324eb3234
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstn
bugs1213744
milestone44.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 1213744 (Part 1) - Support zero-size frame rects and detecting the end of the frame in Downscaler. r=tn
image/Downscaler.cpp
image/Downscaler.h
--- a/image/Downscaler.cpp
+++ b/image/Downscaler.cpp
@@ -69,18 +69,18 @@ Downscaler::BeginFrame(const nsIntSize& 
              "Created a downscaler, but width is larger");
   MOZ_ASSERT(mTargetSize.height <= aOriginalSize.height,
              "Created a downscaler, but height is larger");
   MOZ_ASSERT(aOriginalSize.width > 0 && aOriginalSize.height > 0,
              "Invalid original size");
 
   mFrameRect = aFrameRect.valueOr(nsIntRect(nsIntPoint(), aOriginalSize));
   MOZ_ASSERT(mFrameRect.x >= 0 && mFrameRect.y >= 0 &&
-             mFrameRect.width > 0 && mFrameRect.height > 0,
-             "Frame rect must have positive components");
+             mFrameRect.width >= 0 && mFrameRect.height >= 0,
+             "Frame rect must have non-negative components");
   MOZ_ASSERT(nsIntRect(0, 0, aOriginalSize.width, aOriginalSize.height)
                .Contains(mFrameRect),
              "Frame rect must fit inside image");
   MOZ_ASSERT_IF(!nsIntRect(0, 0, aOriginalSize.width, aOriginalSize.height)
                   .IsEqualEdges(mFrameRect),
                 aHasAlpha);
 
   mOriginalSize = aOriginalSize;
@@ -154,18 +154,23 @@ Downscaler::SkipToRow(int32_t aRow)
 void
 Downscaler::ResetForNextProgressivePass()
 {
   mPrevInvalidatedLine = 0;
   mCurrentOutLine = 0;
   mCurrentInLine = 0;
   mLinesInBuffer = 0;
 
-  // If we have a vertical offset, commit rows to shift us past it.
-  SkipToRow(mFrameRect.y);
+  if (mFrameRect.IsEmpty()) {
+    // Our frame rect is zero size; commit rows until the end of the image.
+    SkipToRow(mOriginalSize.height - 1);
+  } else {
+    // If we have a vertical offset, commit rows to shift us past it.
+    SkipToRow(mFrameRect.y);
+  }
 }
 
 static void
 GetFilterOffsetAndLength(UniquePtr<skia::ConvolutionFilter1D>& aFilter,
                          int32_t aOutputImagePosition,
                          int32_t* aFilterOffsetOut,
                          int32_t* aFilterLengthOut)
 {
--- a/image/Downscaler.h
+++ b/image/Downscaler.h
@@ -78,16 +78,18 @@ public:
    *                        the way they are stored in some image formats.
    */
   nsresult BeginFrame(const nsIntSize& aOriginalSize,
                       const Maybe<nsIntRect>& aFrameRect,
                       uint8_t* aOutputBuffer,
                       bool aHasAlpha,
                       bool aFlipVertically = false);
 
+  bool IsFrameComplete() const { return mCurrentInLine >= mOriginalSize.height; }
+
   /// Retrieves the buffer into which the Decoder should write each row.
   uint8_t* RowBuffer()
   {
     return mRowBuffer.get() + mFrameRect.x * sizeof(uint32_t);
   }
 
   /// Clears the current row buffer (optionally starting at @aStartingAtCol).
   void ClearRow(uint32_t aStartingAtCol = 0);
@@ -156,16 +158,17 @@ public:
   const nsIntSize& TargetSize() const { return nsIntSize(); }
   const gfxSize& Scale() const { return gfxSize(1.0, 1.0); }
 
   nsresult BeginFrame(const nsIntSize&, const Maybe<nsIntRect>&, uint8_t*, bool, bool = false)
   {
     return NS_ERROR_FAILURE;
   }
 
+  bool IsFrameComplete() const { return false; }
   uint8_t* RowBuffer() { return nullptr; }
   void ClearRow(uint32_t = 0) { }
   void CommitRow() { }
   bool HasInvalidation() const { return false; }
   DownscalerInvalidRect TakeInvalidRect() { return DownscalerInvalidRect(); }
   void ResetForNextProgressivePass() { }
 };