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
milestone56.0
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.
image/imgFrame.cpp
--- 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
+#define ANIMATED_FRAMES_USE_HEAP
+#endif
 
 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);
+
+#ifdef ANIMATED_FRAMES_USE_HEAP
   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);
   }
 #endif
 
-  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)) {