Bug 1128223 (Part 3) - Add FLAG_ASYNC_NOTIFY. r=tn

This commit is contained in:
Seth Fowler 2015-02-02 21:40:35 -08:00
parent 6a678ed5a6
commit 4a9f55168d
4 changed files with 37 additions and 51 deletions

View File

@ -69,7 +69,7 @@ native nsIntSizeByVal(nsIntSize);
*
* Internally, imgIContainer also manages animation of images.
*/
[scriptable, builtinclass, uuid(60e07aae-8500-46c7-b305-9a35ad7e6665)]
[scriptable, builtinclass, uuid(3a630c1d-3365-4873-bc01-54468decf8c6)]
interface imgIContainer : nsISupports
{
/**
@ -154,6 +154,9 @@ interface imgIContainer : nsISupports
* FLAG_SYNC_DECODE_IF_FAST: Like FLAG_SYNC_DECODE, but requests a sync decode
* be performed only if ImageLib estimates it can be completed very quickly.
*
* FLAG_ASYNC_NOTIFY: Send notifications asynchronously, even if we decode
* synchronously beause of FLAG_SYNC_DECODE or FLAG_SYNC_DECODE_IF_FAST.
*
* FLAG_DECODE_NO_PREMULTIPLY_ALPHA: Do not premultiply alpha if
* it's not already premultiplied in the image data.
*
@ -181,12 +184,13 @@ interface imgIContainer : nsISupports
const unsigned long FLAG_NONE = 0x0;
const unsigned long FLAG_SYNC_DECODE = 0x1;
const unsigned long FLAG_SYNC_DECODE_IF_FAST = 0x2;
const unsigned long FLAG_DECODE_NO_PREMULTIPLY_ALPHA = 0x4;
const unsigned long FLAG_DECODE_NO_COLORSPACE_CONVERSION = 0x8;
const unsigned long FLAG_CLAMP = 0x10;
const unsigned long FLAG_HIGH_QUALITY_SCALING = 0x20;
const unsigned long FLAG_WANT_DATA_SURFACE = 0x40;
const unsigned long FLAG_BYPASS_SURFACE_CACHE = 0x80;
const unsigned long FLAG_ASYNC_NOTIFY = 0x4;
const unsigned long FLAG_DECODE_NO_PREMULTIPLY_ALPHA = 0x8;
const unsigned long FLAG_DECODE_NO_COLORSPACE_CONVERSION = 0x10;
const unsigned long FLAG_CLAMP = 0x20;
const unsigned long FLAG_HIGH_QUALITY_SCALING = 0x40;
const unsigned long FLAG_WANT_DATA_SURFACE = 0x80;
const unsigned long FLAG_BYPASS_SURFACE_CACHE = 0x100;
/**
* A constant specifying the default set of decode flags (i.e., the default

View File

@ -345,7 +345,8 @@ DecodePool::NotifyProgress(Decoder* aDecoder)
{
MOZ_ASSERT(aDecoder);
if (!NS_IsMainThread()) {
if (!NS_IsMainThread() ||
(aDecoder->GetFlags() & imgIContainer::FLAG_ASYNC_NOTIFY)) {
NotifyProgressWorker::Dispatch(aDecoder->GetImage(),
aDecoder->TakeProgress(),
aDecoder->TakeInvalidRect(),
@ -363,7 +364,8 @@ DecodePool::NotifyDecodeComplete(Decoder* aDecoder)
{
MOZ_ASSERT(aDecoder);
if (!NS_IsMainThread()) {
if (!NS_IsMainThread() ||
(aDecoder->GetFlags() & imgIContainer::FLAG_ASYNC_NOTIFY)) {
NotifyDecodeCompleteWorker::Dispatch(aDecoder);
return;
}

View File

@ -506,8 +506,7 @@ RasterImage::LookupFrameInternal(uint32_t aFrameNum,
DrawableFrameRef
RasterImage::LookupFrame(uint32_t aFrameNum,
const nsIntSize& aSize,
uint32_t aFlags,
bool aShouldSyncNotify /* = true */)
uint32_t aFlags)
{
MOZ_ASSERT(NS_IsMainThread());
@ -526,10 +525,10 @@ RasterImage::LookupFrame(uint32_t aFrameNum,
// The OS threw this frame away. We need to redecode if we can.
MOZ_ASSERT(!mAnim, "Animated frames should be locked");
WantDecodedFrames(ThebesIntSize(requestedSize), aFlags, aShouldSyncNotify);
WantDecodedFrames(ThebesIntSize(requestedSize), aFlags);
// If we can sync decode, we should already have the frame.
if ((aFlags & FLAG_SYNC_DECODE) && aShouldSyncNotify) {
if (aFlags & FLAG_SYNC_DECODE) {
ref = LookupFrameInternal(aFrameNum, requestedSize, aFlags);
}
}
@ -548,8 +547,7 @@ RasterImage::LookupFrame(uint32_t aFrameNum,
// Sync decoding guarantees that we got the frame, but if it's owned by an
// async decoder that's currently running, the contents of the frame may not
// be available yet. Make sure we get everything.
if (ref && mHasSourceData && aShouldSyncNotify &&
(aFlags & FLAG_SYNC_DECODE)) {
if (ref && mHasSourceData && (aFlags & FLAG_SYNC_DECODE)) {
ref->WaitUntilComplete();
}
@ -655,9 +653,7 @@ RasterImage::GetFirstFrameDelay()
}
TemporaryRef<SourceSurface>
RasterImage::CopyFrame(uint32_t aWhichFrame,
uint32_t aFlags,
bool aShouldSyncNotify /* = true */)
RasterImage::CopyFrame(uint32_t aWhichFrame, uint32_t aFlags)
{
if (aWhichFrame > FRAME_MAX_VALUE)
return nullptr;
@ -668,8 +664,8 @@ RasterImage::CopyFrame(uint32_t aWhichFrame,
// Get the frame. If it's not there, it's probably the caller's fault for
// not waiting for the data to be loaded from the network or not passing
// FLAG_SYNC_DECODE
DrawableFrameRef frameRef = LookupFrame(GetRequestedFrameIndex(aWhichFrame),
mSize, aFlags, aShouldSyncNotify);
DrawableFrameRef frameRef =
LookupFrame(GetRequestedFrameIndex(aWhichFrame), mSize, aFlags);
if (!frameRef) {
// The OS threw this frame away and we couldn't redecode it right now.
return nullptr;
@ -727,9 +723,7 @@ RasterImage::GetFrame(uint32_t aWhichFrame,
}
TemporaryRef<SourceSurface>
RasterImage::GetFrameInternal(uint32_t aWhichFrame,
uint32_t aFlags,
bool aShouldSyncNotify /* = true */)
RasterImage::GetFrameInternal(uint32_t aWhichFrame, uint32_t aFlags)
{
MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE);
@ -742,8 +736,8 @@ RasterImage::GetFrameInternal(uint32_t aWhichFrame,
// Get the frame. If it's not there, it's probably the caller's fault for
// not waiting for the data to be loaded from the network or not passing
// FLAG_SYNC_DECODE
DrawableFrameRef frameRef = LookupFrame(GetRequestedFrameIndex(aWhichFrame),
mSize, aFlags, aShouldSyncNotify);
DrawableFrameRef frameRef =
LookupFrame(GetRequestedFrameIndex(aWhichFrame), mSize, aFlags);
if (!frameRef) {
// The OS threw this frame away and we couldn't redecode it.
return nullptr;
@ -762,7 +756,7 @@ RasterImage::GetFrameInternal(uint32_t aWhichFrame,
// The image doesn't have a usable surface because it's been optimized away or
// because it's a partial update frame from an animation. Create one.
if (!frameSurf) {
frameSurf = CopyFrame(aWhichFrame, aFlags, aShouldSyncNotify);
frameSurf = CopyFrame(aWhichFrame, aFlags);
}
return frameSurf;
@ -775,7 +769,7 @@ RasterImage::GetCurrentImage(ImageContainer* aContainer)
MOZ_ASSERT(aContainer);
RefPtr<SourceSurface> surface =
GetFrameInternal(FRAME_CURRENT, FLAG_NONE, /* aShouldSyncNotify = */ false);
GetFrameInternal(FRAME_CURRENT, FLAG_ASYNC_NOTIFY);
if (!surface) {
// The OS threw out some or all of our buffer. We'll need to wait for the
// redecode (which was automatically triggered by GetFrame) to complete.
@ -1406,8 +1400,7 @@ RasterImage::CreateDecoder(const Maybe<nsIntSize>& aSize, uint32_t aFlags)
}
void
RasterImage::WantDecodedFrames(const nsIntSize& aSize, uint32_t aFlags,
bool aShouldSyncNotify)
RasterImage::WantDecodedFrames(const nsIntSize& aSize, uint32_t aFlags)
{
if (mDownscaleDuringDecode) {
// We're about to decode again, which may mean that some of the previous
@ -1421,14 +1414,10 @@ RasterImage::WantDecodedFrames(const nsIntSize& aSize, uint32_t aFlags,
}
DecodeStrategy strategy = DecodeStrategy::ASYNC;
if (aShouldSyncNotify) {
// We can sync notify, which means we can also sync decode.
if (aFlags & FLAG_SYNC_DECODE) {
strategy = DecodeStrategy::SYNC_IF_POSSIBLE;
} else if (aFlags & FLAG_SYNC_DECODE_IF_FAST) {
strategy = DecodeStrategy::SYNC_FOR_SMALL_IMAGES;
}
if (aFlags & FLAG_SYNC_DECODE) {
strategy = DecodeStrategy::SYNC_IF_POSSIBLE;
} else if (aFlags & FLAG_SYNC_DECODE_IF_FAST) {
strategy = DecodeStrategy::SYNC_FOR_SMALL_IMAGES;
}
Decode(strategy, Some(aSize), aFlags);
@ -1494,12 +1483,7 @@ RasterImage::RequestDecodeForSize(const nsIntSize& aSize, uint32_t aFlags)
// Look up the first frame of the image, which will implicitly start decoding
// if it's not available right now.
// XXX(seth): Passing true for aShouldSyncNotify here has the effect of
// synchronously decoding small images, while passing false has the effect of
// decoding asynchronously, but that's not obvious from the argument name.
// This API needs to be reworked.
LookupFrame(0, targetSize, flags,
/* aShouldSyncNotify = */ shouldSyncDecodeIfFast);
LookupFrame(0, targetSize, flags);
return NS_OK;
}

View File

@ -302,19 +302,16 @@ private:
uint32_t aFlags);
TemporaryRef<gfx::SourceSurface> CopyFrame(uint32_t aWhichFrame,
uint32_t aFlags,
bool aShouldSyncNotify = true);
uint32_t aFlags);
TemporaryRef<gfx::SourceSurface> GetFrameInternal(uint32_t aWhichFrame,
uint32_t aFlags,
bool aShouldSyncNotify = true);
uint32_t aFlags);
DrawableFrameRef LookupFrameInternal(uint32_t aFrameNum,
const gfx::IntSize& aSize,
uint32_t aFlags);
DrawableFrameRef LookupFrame(uint32_t aFrameNum,
const nsIntSize& aSize,
uint32_t aFlags,
bool aShouldSyncNotify = true);
uint32_t aFlags);
uint32_t GetCurrentFrameIndex() const;
uint32_t GetRequestedFrameIndex(uint32_t aWhichFrame) const;
@ -356,8 +353,7 @@ private:
already_AddRefed<Decoder> CreateDecoder(const Maybe<nsIntSize>& aSize,
uint32_t aFlags);
void WantDecodedFrames(const nsIntSize& aSize, uint32_t aFlags,
bool aShouldSyncNotify);
void WantDecodedFrames(const nsIntSize& aSize, uint32_t aFlags);
private: // data
nsIntSize mSize;