Bug 1291054 (Part 2) - Add a Decoder::OutputSize() getter and use it in the decoders. r=edwin
authorSeth Fowler <mark.seth.fowler@gmail.com>
Fri, 29 Jul 2016 15:45:58 -0700
changeset 307668 5c5ceb44358d1839180ad7220d3c233c0bd25c09
parent 307667 5e94e5cf47ef7c29697619ae4e22b6162be23d18
child 307669 a2f8694f12c890db95ccfecd929a201d03ddb99d
push id80158
push userseth.bugzilla@blackhail.net
push dateTue, 02 Aug 2016 11:11:09 +0000
treeherdermozilla-inbound@8248ff77be0f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersedwin
bugs1291054
milestone51.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 1291054 (Part 2) - Add a Decoder::OutputSize() getter and use it in the decoders. r=edwin
image/Decoder.h
image/decoders/nsBMPDecoder.cpp
image/decoders/nsGIFDecoder2.cpp
image/decoders/nsIconDecoder.cpp
image/decoders/nsJPEGDecoder.cpp
image/decoders/nsPNGDecoder.cpp
--- a/image/Decoder.h
+++ b/image/Decoder.h
@@ -124,16 +124,20 @@ public:
    * This must be called before Init() is called.
    */
   nsresult SetTargetSize(const gfx::IntSize& aSize);
 
   /**
    * If this decoder supports downscale-during-decode and is configured to
    * downscale, returns the target size that the output size will be decoded to.
    * Otherwise, returns Nothing().
+   *
+   * Note that virtually all callers don't care whether a decoder is configured
+   * to downscale; they just want to know what the decoder's output size is.
+   * Such callers should use OutputSize() instead.
    */
   Maybe<gfx::IntSize> GetTargetSize();
 
   /**
    * Set the requested sample size for this decoder. Used to implement the
    * -moz-sample-size media fragment.
    *
    *  XXX(seth): Support for -moz-sample-size will be removed in bug 1120056.
@@ -263,16 +267,29 @@ public:
    * Illegal to call if HasSize() returns false.
    */
   gfx::IntSize GetSize() const
   {
     MOZ_ASSERT(HasSize());
     return mImageMetadata.GetSize();
   }
 
+  /**
+   * @return the output size of this decoder. If this is different than the
+   * intrinsic size, then the image will be downscaled during the decoding
+   * process.
+   *
+   * Illegal to call if HasSize() returns false.
+   */
+  gfx::IntSize OutputSize() const
+  {
+    return mDownscaler ? mDownscaler->TargetSize()
+                       : GetSize();
+  }
+
   virtual Telemetry::ID SpeedHistogram();
 
   ImageMetadata& GetImageMetadata() { return mImageMetadata; }
 
   /**
    * @return a weak pointer to the image associated with this decoder. Illegal
    * to call if this decoder is not associated with an image.
    */
--- a/image/decoders/nsBMPDecoder.cpp
+++ b/image/decoders/nsBMPDecoder.cpp
@@ -669,19 +669,18 @@ nsBMPDecoder::ReadBitfields(const char* 
     mColors = MakeUnique<ColorTableEntry[]>(256);
     memset(mColors.get(), 0, 256 * sizeof(ColorTableEntry));
 
     // OS/2 Bitmaps have no padding byte.
     mBytesPerColor = (mH.mBIHSize == InfoHeaderLength::WIN_V2) ? 3 : 4;
   }
 
   MOZ_ASSERT(!mImageData, "Already have a buffer allocated?");
-  IntSize targetSize = mDownscaler ? mDownscaler->TargetSize() : GetSize();
-  nsresult rv = AllocateFrame(/* aFrameNum = */ 0, targetSize,
-                              IntRect(IntPoint(), targetSize),
+  nsresult rv = AllocateFrame(/* aFrameNum = */ 0, OutputSize(),
+                              IntRect(IntPoint(), OutputSize()),
                               SurfaceFormat::B8G8R8A8);
   if (NS_FAILED(rv)) {
     return Transition::TerminateFailure();
   }
   MOZ_ASSERT(mImageData, "Should have a buffer now");
 
   if (mDownscaler) {
     // BMPs store their rows in reverse order, so the downscaler needs to
--- a/image/decoders/nsGIFDecoder2.cpp
+++ b/image/decoders/nsGIFDecoder2.cpp
@@ -188,28 +188,23 @@ nsGIFDecoder2::BeginImageFrame(const Int
   MOZ_ASSERT_IF(mDownscaler, !GetImageMetadata().HasAnimation());
 
   SurfacePipeFlags pipeFlags = aIsInterlaced
                              ? SurfacePipeFlags::DEINTERLACE
                              : SurfacePipeFlags();
 
   Maybe<SurfacePipe> pipe;
   if (mGIFStruct.images_decoded == 0) {
-    // This is the first frame. We may be downscaling, so compute the target
-    // size.
-    IntSize targetSize = mDownscaler ? mDownscaler->TargetSize()
-                                     : GetSize();
-
     // The first frame may be displayed progressively.
     pipeFlags |= SurfacePipeFlags::PROGRESSIVE_DISPLAY;
 
     // The first frame is always decoded into an RGB surface.
     pipe =
       SurfacePipeFactory::CreateSurfacePipe(this, mGIFStruct.images_decoded,
-                                            GetSize(), targetSize,
+                                            GetSize(), OutputSize(),
                                             aFrameRect, format, pipeFlags);
   } else {
     // This is an animation frame (and not the first). To minimize the memory
     // usage of animations, the image data is stored in paletted form.
     MOZ_ASSERT(!mDownscaler);
     pipe =
       SurfacePipeFactory::CreatePalettedSurfacePipe(this, mGIFStruct.images_decoded,
                                                     GetSize(), aFrameRect, format,
--- a/image/decoders/nsIconDecoder.cpp
+++ b/image/decoders/nsIconDecoder.cpp
@@ -64,22 +64,20 @@ nsIconDecoder::ReadHeader(const char* aD
   PostHasTransparency();
 
   // If we're doing a metadata decode, we're done.
   if (IsMetadataDecode()) {
     return Transition::TerminateSuccess();
   }
 
   MOZ_ASSERT(!mImageData, "Already have a buffer allocated?");
-  IntSize targetSize = mDownscaler ? mDownscaler->TargetSize() : GetSize();
-  IntRect frameRect(IntPoint(0, 0), GetSize());
-
   Maybe<SurfacePipe> pipe =
-    SurfacePipeFactory::CreateSurfacePipe(this, 0, GetSize(), targetSize,
-                                          frameRect, SurfaceFormat::B8G8R8A8,
+    SurfacePipeFactory::CreateSurfacePipe(this, 0, GetSize(), OutputSize(),
+                                          IntRect(IntPoint(), GetSize()),
+                                          SurfaceFormat::B8G8R8A8,
                                           SurfacePipeFlags());
   if (!pipe) {
     return Transition::TerminateFailure();
   }
 
   mPipe = Move(*pipe);
 
   MOZ_ASSERT(mImageData, "Should have a buffer now");
--- a/image/decoders/nsJPEGDecoder.cpp
+++ b/image/decoders/nsJPEGDecoder.cpp
@@ -383,20 +383,19 @@ nsJPEGDecoder::ReadJPEGData(const char* 
     }
 
     // Don't allocate a giant and superfluous memory buffer
     // when not doing a progressive decode.
     mInfo.buffered_image = mDecodeStyle == PROGRESSIVE &&
                            jpeg_has_multiple_scans(&mInfo);
 
     MOZ_ASSERT(!mImageData, "Already have a buffer allocated?");
-    nsIntSize targetSize = mDownscaler ? mDownscaler->TargetSize() : GetSize();
-    nsresult rv = AllocateFrame(0, targetSize,
-                                nsIntRect(nsIntPoint(), targetSize),
-                                gfx::SurfaceFormat::B8G8R8A8);
+    nsresult rv = AllocateFrame(/* aFrameNum = */ 0, OutputSize(),
+                                IntRect(IntPoint(), OutputSize()),
+                                SurfaceFormat::B8G8R8A8);
     if (NS_FAILED(rv)) {
       mState = JPEG_ERROR;
       MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
              ("} (could not initialize image frame)"));
       return Transition::TerminateFailure();
     }
 
     MOZ_ASSERT(mImageData, "Should have a buffer now");
--- a/image/decoders/nsPNGDecoder.cpp
+++ b/image/decoders/nsPNGDecoder.cpp
@@ -196,33 +196,30 @@ nsPNGDecoder::CreateFrame(const FrameInf
                        ? SurfaceFormat::B8G8R8X8
                        : SurfaceFormat::B8G8R8A8;
 
   // Make sure there's no animation or padding if we're downscaling.
   MOZ_ASSERT_IF(mDownscaler, mNumFrames == 0);
   MOZ_ASSERT_IF(mDownscaler, !GetImageMetadata().HasAnimation());
   MOZ_ASSERT_IF(mDownscaler, transparency != TransparencyType::eFrameRect);
 
-  IntSize targetSize = mDownscaler ? mDownscaler->TargetSize()
-                                   : GetSize();
-
   // If this image is interlaced, we can display better quality intermediate
   // results to the user by post processing them with ADAM7InterpolatingFilter.
   SurfacePipeFlags pipeFlags = aFrameInfo.mIsInterlaced
                              ? SurfacePipeFlags::ADAM7_INTERPOLATE
                              : SurfacePipeFlags();
 
   if (mNumFrames == 0) {
     // The first frame may be displayed progressively.
     pipeFlags |= SurfacePipeFlags::PROGRESSIVE_DISPLAY;
   }
 
   Maybe<SurfacePipe> pipe =
     SurfacePipeFactory::CreateSurfacePipe(this, mNumFrames, GetSize(),
-                                          targetSize, aFrameInfo.mFrameRect,
+                                          OutputSize(), aFrameInfo.mFrameRect,
                                           format, pipeFlags);
 
   if (!pipe) {
     mPipe = SurfacePipe();
     return NS_ERROR_FAILURE;
   }
 
   mPipe = Move(*pipe);