Bug 1409440. r=tnikkel
authorAndrew Osmond <aosmond@mozilla.com>
Tue, 27 Mar 2018 09:01:14 -0400
changeset 410169 52c14d32d9812951c12d92b2594056fc15c5de80
parent 410168 d91b03764f7808379a9692ec6af3ed951bb46c68
child 410170 30e5d3a233bee9183134dce041e7c0ad99f3c60e
push id101401
push useraosmond@gmail.com
push dateTue, 27 Mar 2018 13:01:29 +0000
treeherdermozilla-inbound@52c14d32d981 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel
bugs1409440
milestone61.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 1409440. r=tnikkel
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;
     }