Bug 1213744 - (Part 1) - Support zero-size frame rects and detecting the end of the frame in Downscaler. r=tn, a=al
authorSeth Fowler <mark.seth.fowler@gmail.com>
Sun, 25 Oct 2015 13:14:14 -0700
changeset 296570 0e2d662bbd0bddda142bfdecadf01ef2d1e7ac40
parent 296569 0aebad4cd674cddfb849da22f137a35c57b807ad
child 296571 577862d704279c3e005d61a064030edd8dd65c2b
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, al
bugs1213744
milestone43.0a2
Bug 1213744 - (Part 1) - Support zero-size frame rects and detecting the end of the frame in Downscaler. r=tn, a=al
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() { }
 };