Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit 2e93a2b

Browse files
committed
Bug 869125 - Use the preallocated first frame in the PNG and GIF decoders when possible so we don't flash unnecessarily. r=seth
--HG-- extra : rebase_source : b2b914fd86c7946392588726082b885b09a97b37
1 parent 443fc2f commit 2e93a2b

2 files changed

Lines changed: 42 additions & 13 deletions

File tree

image/decoders/nsGIFDecoder2.cpp

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -165,18 +165,31 @@ void nsGIFDecoder2::BeginImageFrame(uint16_t aDepth)
165165
else
166166
format = gfxASurface::ImageFormatRGB24;
167167

168+
MOZ_ASSERT(HasSize());
169+
168170
// Use correct format, RGB for first frame, PAL for following frames
169171
// and include transparency to allow for optimization of opaque images
170172
if (mGIFStruct.images_decoded) {
171173
// Image data is stored with original depth and palette
172174
NeedNewFrame(mGIFStruct.images_decoded, mGIFStruct.x_offset,
173175
mGIFStruct.y_offset, mGIFStruct.width, mGIFStruct.height,
174176
format, aDepth);
175-
} else {
177+
}
178+
179+
// Our first full frame is automatically created by the image decoding
180+
// infrastructure. Just use it as long as we're not creating a subframe.
181+
else if (mGIFStruct.x_offset != 0 || mGIFStruct.y_offset != 0 ||
182+
int32_t(mGIFStruct.width) != mImageMetadata.GetWidth() ||
183+
int32_t(mGIFStruct.height) != mImageMetadata.GetHeight()) {
176184
// Regardless of depth of input, image is decoded into 24bit RGB
177185
NeedNewFrame(mGIFStruct.images_decoded, mGIFStruct.x_offset,
178186
mGIFStruct.y_offset, mGIFStruct.width, mGIFStruct.height,
179187
format);
188+
} else {
189+
// Our preallocated frame matches up, with the possible exception of alpha.
190+
if (format == gfxASurface::ImageFormatRGB24) {
191+
GetCurrentFrame()->SetHasNoAlpha();
192+
}
180193
}
181194

182195
mCurrentFrame = mGIFStruct.images_decoded;
@@ -893,19 +906,23 @@ nsGIFDecoder2::WriteInternal(const char *aBuffer, uint32_t aCount)
893906
mColorMask = 0xFF >> (8 - realDepth);
894907
BeginImageFrame(realDepth);
895908

896-
// We now need a new frame from the decoder framework. We leave all our
897-
// data in the buffer as if it wasn't consumed, copy to our hold and return
898-
// to the decoder framework.
899-
uint32_t size = len + mGIFStruct.bytes_to_consume + mGIFStruct.bytes_in_hold;
900-
if (size) {
901-
if (SetHold(q, mGIFStruct.bytes_to_consume + mGIFStruct.bytes_in_hold, buf, len)) {
902-
// Back into the decoder infrastructure so we can get called again.
903-
GETN(9, gif_image_header_continue);
904-
return;
909+
if (NeedsNewFrame()) {
910+
// We now need a new frame from the decoder framework. We leave all our
911+
// data in the buffer as if it wasn't consumed, copy to our hold and return
912+
// to the decoder framework.
913+
uint32_t size = len + mGIFStruct.bytes_to_consume + mGIFStruct.bytes_in_hold;
914+
if (size) {
915+
if (SetHold(q, mGIFStruct.bytes_to_consume + mGIFStruct.bytes_in_hold, buf, len)) {
916+
// Back into the decoder infrastructure so we can get called again.
917+
GETN(9, gif_image_header_continue);
918+
return;
919+
}
905920
}
921+
break;
922+
} else {
923+
// FALL THROUGH
906924
}
907925
}
908-
break;
909926

910927
case gif_image_header_continue:
911928
{

image/decoders/nsPNGDecoder.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,19 @@ void nsPNGDecoder::CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset,
140140
int32_t width, int32_t height,
141141
gfxASurface::gfxImageFormat format)
142142
{
143-
NeedNewFrame(mNumFrames, x_offset, y_offset, width, height, format);
143+
// Our first full frame is automatically created by the image decoding
144+
// infrastructure. Just use it as long as we're not creating a subframe.
145+
MOZ_ASSERT(HasSize());
146+
if (mNumFrames != 0 ||
147+
x_offset != 0 || y_offset != 0 ||
148+
width != mImageMetadata.GetWidth() || height != mImageMetadata.GetHeight()) {
149+
NeedNewFrame(mNumFrames, x_offset, y_offset, width, height, format);
150+
} else if (mNumFrames == 0) {
151+
// Our preallocated frame matches up, with the possible exception of alpha.
152+
if (format == gfxASurface::ImageFormatRGB24) {
153+
GetCurrentFrame()->SetHasNoAlpha();
154+
}
155+
}
144156

145157
mFrameRect.x = x_offset;
146158
mFrameRect.y = y_offset;
@@ -651,7 +663,7 @@ nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr)
651663
}
652664
}
653665

654-
if (!decoder->mFrameIsHidden) {
666+
if (!decoder->mFrameIsHidden && decoder->NeedsNewFrame()) {
655667
/* We know that we need a new frame, so pause input so the decoder
656668
* infrastructure can give it to us.
657669
*/

0 commit comments

Comments
 (0)