Bug 1290293 - Part 2c. Make nsGIFDecoder2 use B8G8R8X8 only for unpaletted frames. r=tnikkel
authorAndrew Osmond <aosmond@mozilla.com>
Thu, 03 Nov 2016 10:32:21 -0400
changeset 342537 8fe86f3a5af2050abd915560c6c4336a00ca2612
parent 342536 76c26eaf4f183ed3653861da7fb8f354566a5f0f
child 342538 5e64b3ea513afcc72840d778807cdd7342ee27c2
push id86899
push useraosmond@gmail.com
push dateMon, 13 Feb 2017 19:00:24 +0000
treeherdermozilla-inbound@5e64b3ea513a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel
bugs1290293
milestone54.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 1290293 - Part 2c. Make nsGIFDecoder2 use B8G8R8X8 only for unpaletted frames. r=tnikkel
image/SurfacePipe.cpp
image/decoders/nsGIFDecoder2.cpp
--- a/image/SurfacePipe.cpp
+++ b/image/SurfacePipe.cpp
@@ -142,16 +142,18 @@ SurfaceSink::GetRowPointer() const
 
   return rowPtr;
 }
 
 
 nsresult
 PalettedSurfaceSink::Configure(const PalettedSurfaceConfig& aConfig)
 {
+  MOZ_ASSERT(aConfig.mFormat == SurfaceFormat::B8G8R8A8);
+
   // For paletted surfaces, the surface size is the size of the frame rect.
   IntSize surfaceSize = aConfig.mFrameRect.Size();
 
   // Allocate the frame.
   // XXX(seth): Once every Decoder subclass uses SurfacePipe, we probably want
   // to allocate the frame directly here and get rid of Decoder::AllocateFrame
   // altogether.
   nsresult rv = aConfig.mDecoder->AllocateFrame(aConfig.mFrameNum,
--- a/image/decoders/nsGIFDecoder2.cpp
+++ b/image/decoders/nsGIFDecoder2.cpp
@@ -176,43 +176,51 @@ nsGIFDecoder2::CheckForTransparency(cons
 nsresult
 nsGIFDecoder2::BeginImageFrame(const IntRect& aFrameRect,
                                uint16_t aDepth,
                                bool aIsInterlaced)
 {
   MOZ_ASSERT(HasSize());
 
   bool hasTransparency = CheckForTransparency(aFrameRect);
-  gfx::SurfaceFormat format = hasTransparency ? SurfaceFormat::B8G8R8A8
-                                              : SurfaceFormat::B8G8R8X8;
 
   // Make sure there's no animation if we're downscaling.
   MOZ_ASSERT_IF(Size() != OutputSize(), !GetImageMetadata().HasAnimation());
 
   SurfacePipeFlags pipeFlags = aIsInterlaced
                              ? SurfacePipeFlags::DEINTERLACE
                              : SurfacePipeFlags();
 
   Maybe<SurfacePipe> pipe;
   if (mGIFStruct.images_decoded == 0) {
+    gfx::SurfaceFormat format = hasTransparency ? SurfaceFormat::B8G8R8A8
+                                                : SurfaceFormat::B8G8R8X8;
+
     // 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,
                                             Size(), 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.
+    //
+    // We should never use paletted surfaces with a draw target directly, so
+    // the only practical difference between B8G8R8A8 and B8G8R8X8 is the
+    // cleared pixel value if we get truncated. We want 0 in that case to
+    // ensure it is an acceptable value for the color map as was the case
+    // historically.
     MOZ_ASSERT(Size() == OutputSize());
     pipe =
       SurfacePipeFactory::CreatePalettedSurfacePipe(this, mGIFStruct.images_decoded,
-                                                    Size(), aFrameRect, format,
+                                                    Size(), aFrameRect,
+                                                    SurfaceFormat::B8G8R8A8,
                                                     aDepth, pipeFlags);
   }
 
   mCurrentFrameIndex = mGIFStruct.images_decoded;
 
   if (!pipe) {
     mPipe = SurfacePipe();
     return NS_ERROR_FAILURE;