Bug 815489 - Don't let Blur() swap mData since the buffer is also used by the image surface. r=roc a=akeybl
authorMats Palmgren <matspal@gmail.com>
Sat, 01 Dec 2012 00:35:33 +0100
changeset 118512 573ea169953328802aa98d6658526a526dfeec58
parent 118511 adf3fc9e7c16dff52e1fbf43b6706e7aea388694
child 118513 19c3aa22d0ea2c2b4268a2e33793817f5882ce26
push id2829
push usermpalmgren@mozilla.com
push dateFri, 30 Nov 2012 23:35:33 +0000
treeherdermozilla-aurora@19c3aa22d0ea [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, akeybl
bugs815489
milestone19.0a2
Bug 815489 - Don't let Blur() swap mData since the buffer is also used by the image surface. r=roc a=akeybl
gfx/2d/Blur.cpp
--- a/gfx/2d/Blur.cpp
+++ b/gfx/2d/Blur.cpp
@@ -492,39 +492,41 @@ AlphaBoxBlur::Blur()
 #endif
 
     if (cIsBigEndian || (integralImageSize.width * integralImageSize.height) > (1 << 24)) {
       // Fallback to old blurring code when the surface is so large it may
       // overflow our integral image!
 
       // No need to use CheckedInt here - we have validated it in the constructor.
       size_t szB = stride * size.height;
-      unsigned char* tmpData = new uint8_t[szB];
-
+      uint8_t* tmpData = new uint8_t[szB];
       memset(tmpData, 0, szB);
 
+      uint8_t* a = mData;
+      uint8_t* b = tmpData;
       if (mBlurRadius.width > 0) {
-        BoxBlurHorizontal(mData, tmpData, horizontalLobes[0][0], horizontalLobes[0][1], stride, GetSize().height, mSkipRect);
-        BoxBlurHorizontal(tmpData, mData, horizontalLobes[1][0], horizontalLobes[1][1], stride, GetSize().height, mSkipRect);
-        BoxBlurHorizontal(mData, tmpData, horizontalLobes[2][0], horizontalLobes[2][1], stride, GetSize().height, mSkipRect);
+        BoxBlurHorizontal(a, b, horizontalLobes[0][0], horizontalLobes[0][1], stride, GetSize().height, mSkipRect);
+        BoxBlurHorizontal(b, a, horizontalLobes[1][0], horizontalLobes[1][1], stride, GetSize().height, mSkipRect);
+        BoxBlurHorizontal(a, b, horizontalLobes[2][0], horizontalLobes[2][1], stride, GetSize().height, mSkipRect);
       } else {
-        uint8_t *tmp = mData;
-        mData = tmpData;
-        tmpData = tmp;
+        a = tmpData;
+        b = mData;
       }
+      // The result is in 'b' here.
       if (mBlurRadius.height > 0) {
-        BoxBlurVertical(tmpData, mData, verticalLobes[0][0], verticalLobes[0][1], stride, GetSize().height, mSkipRect);
-        BoxBlurVertical(mData, tmpData, verticalLobes[1][0], verticalLobes[1][1], stride, GetSize().height, mSkipRect);
-        BoxBlurVertical(tmpData, mData, verticalLobes[2][0], verticalLobes[2][1], stride, GetSize().height, mSkipRect);
+        BoxBlurVertical(b, a, verticalLobes[0][0], verticalLobes[0][1], stride, GetSize().height, mSkipRect);
+        BoxBlurVertical(a, b, verticalLobes[1][0], verticalLobes[1][1], stride, GetSize().height, mSkipRect);
+        BoxBlurVertical(b, a, verticalLobes[2][0], verticalLobes[2][1], stride, GetSize().height, mSkipRect);
       } else {
-        uint8_t *tmp = mData;
-        mData = tmpData;
-        tmpData = tmp;
+        a = b;
       }
-
+      // The result is in 'a' here.
+      if (a == tmpData) {
+        memcpy(mData, tmpData, szB);
+      }
       delete [] tmpData;
     } else {
       size_t integralImageStride = GetAlignedStride<16>(integralImageSize.width * 4);
 
       // We need to leave room for an additional 12 bytes for a maximum overrun
       // of 3 pixels in the blurring code.
       AlignedArray<uint32_t> integralImage((integralImageStride / 4) * integralImageSize.height + 12);