Bug 853337 - Make sure we actually call Flush and MarkDirty on frames when we've done some decoding work. r=seth

This commit is contained in:
Joe Drew 2013-03-22 22:05:44 -04:00
parent 69823dcd0f
commit 84324f86de
6 changed files with 51 additions and 3 deletions

View File

@ -610,7 +610,9 @@ nsresult
nsICODecoder::AllocateFrame()
{
if (mContainedDecoder) {
return mContainedDecoder->AllocateFrame();
nsresult rv = mContainedDecoder->AllocateFrame();
mCurrentFrame = mContainedDecoder->GetCurrentFrame();
return rv;
}
return Decoder::AllocateFrame();

View File

@ -188,6 +188,8 @@ Decoder::AllocateFrame()
MOZ_ASSERT(mNeedsNewFrame);
MOZ_ASSERT(NS_IsMainThread());
MarkFrameDirty();
nsresult rv;
if (mNewFrameData.mPaletteDepth) {
rv = mImage.EnsureFrame(mNewFrameData.mFrameNum, mNewFrameData.mOffsetX,
@ -329,8 +331,6 @@ Decoder::PostFrameStop(RasterImage::FrameAlpha aFrameAlpha /* = RasterImage::kFr
// Flush any invalidations before we finish the frame
FlushInvalidations();
mCurrentFrame = nullptr;
// Fire notifications
if (mObserver) {
mObserver->OnStopFrame();
@ -403,5 +403,15 @@ Decoder::NeedNewFrame(uint32_t framenum, uint32_t x_offset, uint32_t y_offset,
mNeedsNewFrame = true;
}
void
Decoder::MarkFrameDirty()
{
MOZ_ASSERT(NS_IsMainThread());
if (mCurrentFrame) {
mCurrentFrame->MarkImageDataDirty();
}
}
} // namespace image
} // namespace mozilla

View File

@ -162,6 +162,12 @@ public:
// status code from that attempt. Clears mNewFrameData.
virtual nsresult AllocateFrame();
// Called when a chunk of decoding has been done and the frame needs to be
// marked as dirty. Must be called only on the main thread.
void MarkFrameDirty();
imgFrame* GetCurrentFrame() const { return mCurrentFrame; }
protected:
/*

View File

@ -3399,6 +3399,8 @@ RasterImage::FinishedSomeDecoding(eShutdownIntent aIntent /* = eShutdownIntent_D
nsresult rv = NS_OK;
if (image->mDecoder) {
image->mDecoder->MarkFrameDirty();
if (request && request->mChunkCount && !image->mDecoder->IsSizeDecode()) {
Telemetry::Accumulate(Telemetry::IMAGE_DECODE_CHUNKS, request->mChunkCount);
}

View File

@ -707,9 +707,36 @@ nsresult imgFrame::UnlockImageData()
if (mQuartzSurface)
mQuartzSurface->Flush();
#endif
return NS_OK;
}
void imgFrame::MarkImageDataDirty()
{
if (mImageSurface)
mImageSurface->Flush();
#ifdef USE_WIN_SURFACE
if (mWinSurface)
mWinSurface->Flush();
#endif
if (mImageSurface)
mImageSurface->MarkDirty();
#ifdef USE_WIN_SURFACE
if (mWinSurface)
mWinSurface->MarkDirty();
#endif
#ifdef XP_MACOSX
// The quartz image surface (ab)uses the flush method to get the
// cairo_image_surface data into a CGImage, so we have to call Flush() here.
if (mQuartzSurface)
mQuartzSurface->Flush();
#endif
}
int32_t imgFrame::GetTimeout() const
{
// Ensure a minimal time between updates so we don't throttle the UI thread.

View File

@ -69,6 +69,7 @@ public:
nsresult LockImageData();
nsresult UnlockImageData();
void MarkImageDataDirty();
nsresult GetSurface(gfxASurface **aSurface) const
{