Bug 1391430 - Force heap allocated surfaces for image decoding to use an unaligned stride. r=tnikkel, a=gchang
authorAndrew Osmond <aosmond@mozilla.com>
Thu, 31 Aug 2017 06:38:55 -0400
changeset 424009 e8a9bb8e42a2d062a7359d398191a73066af29b5
parent 424008 1dea2184e5fcf7d23103c8c7045b9c73a221a65b
child 424010 21a6d6d4581987dbea486263716f8ee2b877408e
push id1517
push userjlorenzo@mozilla.com
push dateThu, 14 Sep 2017 16:50:54 +0000
treeherdermozilla-release@3b41fd564418 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel, gchang
bugs1391430, 1383499
Bug 1391430 - Force heap allocated surfaces for image decoding to use an unaligned stride. r=tnikkel, a=gchang In bug 1383499 we fixed the case where on Android, animated images could consume all of the available file handles. This is because each volatile buffer will contain a file handle on Android, and animated images can contain many, many frames. However in doing so we introduced a bug where the stride of replacement surface was aligned to a 16-byte boundary. We do not currently support any stride value but pixel size * image width in the image decoding framework. This may be something we correct in the future but for now, we should just ensure all surfaces follow the expected stride value.
--- a/image/imgFrame.cpp
+++ b/image/imgFrame.cpp
@@ -9,29 +9,31 @@
 #include "ShutdownTracker.h"
 #include "prenv.h"
 #include "gfx2DGlue.h"
 #include "gfxPlatform.h"
 #include "gfxPrefs.h"
 #include "gfxUtils.h"
-#include "gfxAlphaRecovery.h"
 #include "GeckoProfiler.h"
 #include "MainThreadUtils.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/gfx/Tools.h"
 #include "mozilla/layers/SourceSurfaceSharedData.h"
 #include "mozilla/layers/SourceSurfaceVolatileData.h"
 #include "mozilla/Likely.h"
 #include "mozilla/MemoryReporting.h"
 #include "nsMargin.h"
 #include "nsThreadUtils.h"
+#ifdef ANDROID
 namespace mozilla {
 using namespace gfx;
 namespace image {
 static void
@@ -78,30 +80,32 @@ CreateLockedSurface(DataSourceSurface *a
   return nullptr;
 static already_AddRefed<DataSourceSurface>
 AllocateBufferForImage(const IntSize& size,
                        SurfaceFormat format,
                        bool aIsAnimated = false)
-#ifdef ANDROID
+  int32_t stride = VolatileSurfaceStride(size, format);
   if (aIsAnimated) {
     // For as long as an animated image is retained, its frames will never be
     // released to let the OS purge volatile buffers. On Android, a volatile
     // buffer actually keeps a file handle active, which we would like to avoid
     // since many images and frames could easily exhaust the pool. As such, we
     // use the heap. On the other platforms we do not have the file handle
     // problem, and additionally we may avoid a superfluous memset since the
     // volatile memory starts out as zero-filled.
-    return Factory::CreateDataSourceSurface(size, format, false);
+    return Factory::CreateDataSourceSurfaceWithStride(size, format,
+                                                      stride, false);
-  int32_t stride = VolatileSurfaceStride(size, format);
   if (!aIsAnimated && gfxPrefs::ImageMemShared()) {
     RefPtr<SourceSurfaceSharedData> newSurf = new SourceSurfaceSharedData();
     if (newSurf->Init(size, stride, format)) {
       return newSurf.forget();
   } else {
     RefPtr<SourceSurfaceVolatileData> newSurf= new SourceSurfaceVolatileData();
     if (newSurf->Init(size, stride, format)) {