Bug 1409440. r=tnikkel, a=RyanVM
authorAndrew Osmond <aosmond@mozilla.com>
Tue, 27 Mar 2018 09:01:14 -0400
changeset 462904 e724c32284b2f36ced44da4a3493b3634d8352f2
parent 462903 a125dbf2164331723be980d0454975cd81b9ed85
child 462905 16307dd2fdf1afc83ca85eb60fa22ad3ee05df16
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel, RyanVM
bugs1409440
milestone60.0
Bug 1409440. r=tnikkel, a=RyanVM
image/Downscaler.cpp
image/DownscalingFilter.h
--- a/image/Downscaler.cpp
+++ b/image/Downscaler.cpp
@@ -190,23 +190,24 @@ Downscaler::CommitRow()
     int32_t filterOffset = 0;
     int32_t filterLength = 0;
     mYFilter.GetFilterOffsetAndLength(mCurrentOutLine,
                                       &filterOffset, &filterLength);
 
     int32_t inLineToRead = filterOffset + mLinesInBuffer;
     MOZ_ASSERT(mCurrentInLine <= inLineToRead, "Reading past end of input");
     if (mCurrentInLine == inLineToRead) {
+      MOZ_RELEASE_ASSERT(mLinesInBuffer < mWindowCapacity, "Need more rows than capacity!");
       mXFilter.ConvolveHorizontally(mRowBuffer.get(), mWindow[mLinesInBuffer++], mHasAlpha);
     }
 
     MOZ_ASSERT(mCurrentOutLine < mTargetSize.height,
                "Writing past end of output");
 
-    while (mLinesInBuffer == filterLength) {
+    while (mLinesInBuffer >= filterLength) {
       DownscaleInputLine();
 
       if (mCurrentOutLine == mTargetSize.height) {
         break;  // We're done.
       }
 
       mYFilter.GetFilterOffsetAndLength(mCurrentOutLine,
                                         &filterOffset, &filterLength);
@@ -292,18 +293,23 @@ Downscaler::DownscaleInputLine()
   mYFilter.GetFilterOffsetAndLength(mCurrentOutLine,
                                     &newFilterOffset, &newFilterLength);
 
   int diff = newFilterOffset - filterOffset;
   MOZ_ASSERT(diff >= 0, "Moving backwards in the filter?");
 
   // Shift the buffer. We're just moving pointers here, so this is cheap.
   mLinesInBuffer -= diff;
-  mLinesInBuffer = max(mLinesInBuffer, 0);
-  for (int32_t i = 0; i < mLinesInBuffer; ++i) {
-    swap(mWindow[i], mWindow[filterLength - mLinesInBuffer + i]);
+  mLinesInBuffer = min(max(mLinesInBuffer, 0), mWindowCapacity);
+
+  // If we already have enough rows to satisfy the filter, there is no need
+  // to swap as we won't be writing more before the next convolution.
+  if (filterLength > mLinesInBuffer) {
+    for (int32_t i = 0; i < mLinesInBuffer; ++i) {
+      swap(mWindow[i], mWindow[filterLength - mLinesInBuffer + i]);
+    }
   }
 }
 
 
 
 } // namespace image
 } // namespace mozilla
--- a/image/DownscalingFilter.h
+++ b/image/DownscalingFilter.h
@@ -227,23 +227,24 @@ protected:
     int32_t filterOffset = 0;
     int32_t filterLength = 0;
     mYFilter.GetFilterOffsetAndLength(mOutputRow,
                                       &filterOffset, &filterLength);
 
     int32_t inputRowToRead = filterOffset + mRowsInWindow;
     MOZ_ASSERT(mInputRow <= inputRowToRead, "Reading past end of input");
     if (mInputRow == inputRowToRead) {
+      MOZ_RELEASE_ASSERT(mRowsInWindow < mWindowCapacity, "Need more rows than capacity!");
       mXFilter.ConvolveHorizontally(mRowBuffer.get(), mWindow[mRowsInWindow++], mHasAlpha);
     }
 
     MOZ_ASSERT(mOutputRow < mNext.InputSize().height,
                "Writing past end of output");
 
-    while (mRowsInWindow == filterLength) {
+    while (mRowsInWindow >= filterLength) {
       DownscaleInputRow();
 
       if (mOutputRow == mNext.InputSize().height) {
         break;  // We're done.
       }
 
       mYFilter.GetFilterOffsetAndLength(mOutputRow,
                                         &filterOffset, &filterLength);
@@ -292,19 +293,24 @@ private:
     mYFilter.GetFilterOffsetAndLength(mOutputRow,
                                       &newFilterOffset, &newFilterLength);
 
     int diff = newFilterOffset - filterOffset;
     MOZ_ASSERT(diff >= 0, "Moving backwards in the filter?");
 
     // Shift the buffer. We're just moving pointers here, so this is cheap.
     mRowsInWindow -= diff;
-    mRowsInWindow = std::max(mRowsInWindow, 0);
-    for (int32_t i = 0; i < mRowsInWindow; ++i) {
-      std::swap(mWindow[i], mWindow[filterLength - mRowsInWindow + i]);
+    mRowsInWindow = std::min(std::max(mRowsInWindow, 0), mWindowCapacity);
+
+    // If we already have enough rows to satisfy the filter, there is no need
+    // to swap as we won't be writing more before the next convolution.
+    if (filterLength > mRowsInWindow) {
+      for (int32_t i = 0; i < mRowsInWindow; ++i) {
+        std::swap(mWindow[i], mWindow[filterLength - mRowsInWindow + i]);
+      }
     }
   }
 
   void ReleaseWindow()
   {
     if (!mWindow) {
       return;
     }