Skip to content

Commit

Permalink
Bug 1146663 (Part 4) - Make all RasterImages support downscale-during…
Browse files Browse the repository at this point in the history
…-decode. r=tn
  • Loading branch information
sethfowler committed Sep 19, 2015
1 parent 71ceb5e commit 95f9e45
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 76 deletions.
7 changes: 1 addition & 6 deletions image/Image.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,19 +147,14 @@ class Image : public imgIContainer
* flag is set, INIT_FLAG_DISCARDABLE and INIT_FLAG_DECODE_ONLY_ON_DRAW must
* not be set.
*
* INIT_FLAG_DOWNSCALE_DURING_DECODE: The container should attempt to
* downscale images during decoding instead of decoding them to their
* intrinsic size.
*
* INIT_FLAG_SYNC_LOAD: The container is being loaded synchronously, so
* it should avoid relying on async workers to get the container ready.
*/
static const uint32_t INIT_FLAG_NONE = 0x0;
static const uint32_t INIT_FLAG_DISCARDABLE = 0x1;
static const uint32_t INIT_FLAG_DECODE_IMMEDIATELY = 0x2;
static const uint32_t INIT_FLAG_TRANSIENT = 0x4;
static const uint32_t INIT_FLAG_DOWNSCALE_DURING_DECODE = 0x8;
static const uint32_t INIT_FLAG_SYNC_LOAD = 0x10;
static const uint32_t INIT_FLAG_SYNC_LOAD = 0x8;

virtual already_AddRefed<ProgressTracker> GetProgressTracker() = 0;
virtual void SetProgressTracker(ProgressTracker* aProgressTracker) {}
Expand Down
31 changes: 2 additions & 29 deletions image/ImageFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,6 @@ namespace image {
ImageFactory::Initialize()
{ }

static bool
ShouldDownscaleDuringDecode(const nsCString& aMimeType)
{
DecoderType type = DecoderFactory::GetDecoderType(aMimeType.get());
return type == DecoderType::JPEG ||
type == DecoderType::ICON ||
type == DecoderType::ICO ||
type == DecoderType::PNG ||
type == DecoderType::BMP ||
type == DecoderType::GIF;
}

static uint32_t
ComputeImageFlags(ImageURL* uri, const nsCString& aMimeType, bool isMultiPart)
{
Expand All @@ -52,7 +40,6 @@ ComputeImageFlags(ImageURL* uri, const nsCString& aMimeType, bool isMultiPart)
// We default to the static globals.
bool isDiscardable = gfxPrefs::ImageMemDiscardable();
bool doDecodeImmediately = gfxPrefs::ImageDecodeImmediatelyEnabled();
bool doDownscaleDuringDecode = gfxPrefs::ImageDownscaleDuringDecodeEnabled();

// We want UI to be as snappy as possible and not to flicker. Disable
// discarding for chrome URLS.
Expand All @@ -69,15 +56,10 @@ ComputeImageFlags(ImageURL* uri, const nsCString& aMimeType, bool isMultiPart)
isDiscardable = false;
}

// Downscale-during-decode is only enabled for certain content types.
if (doDownscaleDuringDecode && !ShouldDownscaleDuringDecode(aMimeType)) {
doDownscaleDuringDecode = false;
}

// For multipart/x-mixed-replace, we basically want a direct channel to the
// decoder. Disable everything for this case.
if (isMultiPart) {
isDiscardable = doDownscaleDuringDecode = false;
isDiscardable = false;
}

// We have all the information we need.
Expand All @@ -91,9 +73,6 @@ ComputeImageFlags(ImageURL* uri, const nsCString& aMimeType, bool isMultiPart)
if (isMultiPart) {
imageFlags |= Image::INIT_FLAG_TRANSIENT;
}
if (doDownscaleDuringDecode) {
imageFlags |= Image::INIT_FLAG_DOWNSCALE_DURING_DECODE;
}

return imageFlags;
}
Expand Down Expand Up @@ -143,13 +122,7 @@ ImageFactory::CreateAnonymousImage(const nsCString& aMimeType)
newTracker->SetImage(newImage);
newImage->SetProgressTracker(newTracker);

uint32_t imageFlags = Image::INIT_FLAG_SYNC_LOAD;
if (gfxPrefs::ImageDownscaleDuringDecodeEnabled() &&
ShouldDownscaleDuringDecode(aMimeType)) {
imageFlags |= Image::INIT_FLAG_DOWNSCALE_DURING_DECODE;
}

rv = newImage->Init(aMimeType.get(), imageFlags);
rv = newImage->Init(aMimeType.get(), Image::INIT_FLAG_SYNC_LOAD);
if (NS_FAILED(rv)) {
return BadImage("RasterImage::Init failed", newImage);
}
Expand Down
62 changes: 26 additions & 36 deletions image/RasterImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ RasterImage::RasterImage(ImageURL* aURI /* = nullptr */) :
mDiscardable(false),
mHasSourceData(false),
mHasBeenDecoded(false),
mDownscaleDuringDecode(false),
mPendingAnimation(false),
mAnimationFinished(false),
mWantFullDecode(false)
Expand Down Expand Up @@ -127,23 +126,15 @@ RasterImage::Init(const char* aMimeType,
}

// We want to avoid redecodes for transient images.
MOZ_ASSERT(!(aFlags & INIT_FLAG_TRANSIENT) ||
(!(aFlags & INIT_FLAG_DISCARDABLE) &&
!(aFlags & INIT_FLAG_DOWNSCALE_DURING_DECODE)),
"Illegal init flags for transient image");
MOZ_ASSERT_IF(aFlags & INIT_FLAG_TRANSIENT,
!(aFlags & INIT_FLAG_DISCARDABLE));

// Store initialization data
mDiscardable = !!(aFlags & INIT_FLAG_DISCARDABLE);
mWantFullDecode = !!(aFlags & INIT_FLAG_DECODE_IMMEDIATELY);
mTransient = !!(aFlags & INIT_FLAG_TRANSIENT);
mDownscaleDuringDecode = !!(aFlags & INIT_FLAG_DOWNSCALE_DURING_DECODE);
mSyncLoad = !!(aFlags & INIT_FLAG_SYNC_LOAD);

#ifndef MOZ_ENABLE_SKIA
// Downscale-during-decode requires Skia.
mDownscaleDuringDecode = false;
#endif

// Use the MIME type to select a decoder type, and make sure there *is* a
// decoder for this MIME type.
NS_ENSURE_ARG_POINTER(aMimeType);
Expand Down Expand Up @@ -1207,10 +1198,6 @@ RasterImage::RequestDecodeForSize(const IntSize& aSize, uint32_t aFlags)
return NS_OK;
}

// Fall back to our intrinsic size if we don't support
// downscale-during-decode.
IntSize targetSize = mDownscaleDuringDecode ? aSize : mSize;

// Decide whether to sync decode images we can decode quickly. Here we are
// explicitly trading off flashing for responsiveness in the case that we're
// redecoding an image (see bug 845147).
Expand All @@ -1223,7 +1210,7 @@ RasterImage::RequestDecodeForSize(const IntSize& aSize, uint32_t aFlags)

// Look up the first frame of the image, which will implicitly start decoding
// if it's not available right now.
LookupFrame(0, targetSize, flags);
LookupFrame(0, aSize, flags);

return NS_OK;
}
Expand Down Expand Up @@ -1273,20 +1260,14 @@ RasterImage::Decode(const IntSize& aSize, uint32_t aFlags)
return NS_OK;
}

if (mDownscaleDuringDecode) {
// We're about to decode again, which may mean that some of the previous
// sizes we've decoded at aren't useful anymore. We can allow them to
// expire from the cache by unlocking them here. When the decode finishes,
// it will send an invalidation that will cause all instances of this image
// to redraw. If this image is locked, any surfaces that are still useful
// will become locked again when LookupFrame touches them, and the remainder
// will eventually expire.
SurfaceCache::UnlockSurfaces(ImageKey(this));
}

MOZ_ASSERT(mDownscaleDuringDecode || aSize == mSize,
"Can only decode to our intrinsic size if we're not allowed to "
"downscale-during-decode");
// We're about to decode again, which may mean that some of the previous sizes
// we've decoded at aren't useful anymore. We can allow them to expire from
// the cache by unlocking them here. When the decode finishes, it will send an
// invalidation that will cause all instances of this image to redraw. If this
// image is locked, any surfaces that are still useful will become locked
// again when LookupFrame touches them, and the remainder will eventually
// expire.
SurfaceCache::UnlockSurfaces(ImageKey(this));

Maybe<IntSize> targetSize = mSize != aSize ? Some(aSize) : Nothing();

Expand Down Expand Up @@ -1411,13 +1392,23 @@ RasterImage::RecoverFromInvalidFrames(const IntSize& aSize, uint32_t aFlags)
Decode(aSize, aFlags);
}

static bool
HaveSkia()
{
#ifdef MOZ_ENABLE_SKIA
return true;
#else
return false;
#endif
}

bool
RasterImage::CanDownscaleDuringDecode(const IntSize& aSize, uint32_t aFlags)
{
// Check basic requirements: downscale-during-decode is enabled for this
// image, we have all the source data and know our size, the flags allow us to
// do it, and a 'good' filter is being used.
if (!mDownscaleDuringDecode || !mHasSize ||
// Check basic requirements: downscale-during-decode is enabled, Skia is
// available, this image isn't transient, we have all the source data and know
// our size, and the flags allow us to do it.
if (!mHasSize || mTransient || !HaveSkia() ||
!gfxPrefs::ImageDownscaleDuringDecodeEnabled() ||
!(aFlags & imgIContainer::FLAG_HIGH_QUALITY_SCALING)) {
return false;
Expand Down Expand Up @@ -1468,8 +1459,7 @@ RasterImage::DrawInternal(DrawableFrameRef&& aFrameRef,
aContext->Multiply(gfxMatrix::Scaling(scale.width, scale.height));
region.Scale(1.0 / scale.width, 1.0 / scale.height);

couldRedecodeForBetterFrame = mDownscaleDuringDecode &&
CanDownscaleDuringDecode(aSize, aFlags);
couldRedecodeForBetterFrame = CanDownscaleDuringDecode(aSize, aFlags);
}

if (!aFrameRef->Draw(aContext, region, aFilter, aFlags)) {
Expand Down
5 changes: 0 additions & 5 deletions image/RasterImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,10 +305,6 @@ class RasterImage final : public ImageResource
*
* It's an error to call Decode() before this image's intrinsic size is
* available. A metadata decode must successfully complete first.
*
* If downscale-during-decode is not enabled for this image (i.e., if
* mDownscaleDuringDecode is false), it is an error to pass an @aSize value
* different from this image's intrinsic size.
*/
NS_IMETHOD Decode(const gfx::IntSize& aSize, uint32_t aFlags);

Expand Down Expand Up @@ -398,7 +394,6 @@ class RasterImage final : public ImageResource
bool mDiscardable:1; // Is container discardable?
bool mHasSourceData:1; // Do we have source data?
bool mHasBeenDecoded:1; // Decoded at least once?
bool mDownscaleDuringDecode:1;

// Whether we're waiting to start animation. If we get a StartAnimation() call
// but we don't yet have more than one frame, mPendingAnimation is set so that
Expand Down

0 comments on commit 95f9e45

Please sign in to comment.