Bug 629799, part 2: Ensure that gfxImageSurfaces are aligned well for alpha recovery. r=roc
authorChris Jones <jones.chris.g@gmail.com>
Wed, 16 Feb 2011 16:43:30 -0600
changeset 62693 2be3da6a6531090be8a1c31ff643c54c726cdfa3
parent 62692 22a8b2770f45718e24f0cddcc3d5f2b54d93dd58
child 62694 7e8fb5a646dae92615a816e856b8f403b5cd3a77
push id18833
push usercjones@mozilla.com
push dateWed, 16 Feb 2011 22:44:38 +0000
treeherdermozilla-central@0f777e59d48c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs629799
milestone2.0b12pre
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 629799, part 2: Ensure that gfxImageSurfaces are aligned well for alpha recovery. r=roc
gfx/thebes/gfxImageSurface.cpp
--- a/gfx/thebes/gfxImageSurface.cpp
+++ b/gfx/thebes/gfxImageSurface.cpp
@@ -32,16 +32,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "prmem.h"
 
+#include "gfxAlphaRecovery.h"
 #include "gfxImageSurface.h"
 
 #include "cairo.h"
 
 gfxImageSurface::gfxImageSurface()
   : mSize(0, 0),
     mOwnsData(PR_FALSE),
     mFormat(ImageFormatUnknown),
@@ -91,29 +92,48 @@ gfxImageSurface::InitWithData(unsigned c
     // cairo_image_surface_create_for_data can return a 'null' surface
     // in out of memory conditions. The gfxASurface::Init call checks
     // the surface it receives to see if there is an error with the
     // surface and handles it appropriately. That is why there is
     // no check here.
     Init(surface);
 }
 
+static void*
+TryAllocAlignedBytes(size_t aSize)
+{
+    // Use fallible allocators here
+#if defined(HAVE_POSIX_MEMALIGN) || defined(HAVE_JEMALLOC_POSIX_MEMALIGN)
+    void* ptr;
+    // Try to align for fast alpha recovery.  This should only help
+    // cairo too, can't hurt.
+    return moz_posix_memalign(&ptr,
+                              1 << gfxAlphaRecovery::GoodAlignmentLog2(),
+                              aSize) ?
+             nsnull : ptr;
+#else
+    // Oh well, hope that luck is with us in the allocator
+    return moz_malloc(aSize);
+#endif
+}
+
 gfxImageSurface::gfxImageSurface(const gfxIntSize& size, gfxImageFormat format) :
     mSize(size), mOwnsData(PR_FALSE), mData(nsnull), mFormat(format)
 {
     mStride = ComputeStride();
 
     if (!CheckSurfaceSize(size))
         return;
 
     // if we have a zero-sized surface, just leave mData nsnull
     if (mSize.height * mStride > 0) {
 
-        // Use the fallible allocator here
-        mData = (unsigned char *) moz_malloc(mSize.height * mStride);
+        // This can fail to allocate memory aligned as we requested,
+        // or it can fail to allocate any memory at all.
+        mData = (unsigned char *) TryAllocAlignedBytes(mSize.height * mStride);
         if (!mData)
             return;
         memset(mData, 0, mSize.height * mStride);
     }
 
     mOwnsData = PR_TRUE;
 
     cairo_surface_t *surface =