mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1118087 - Correctly sync decode even if an imgFrame is partially decoded. r=tn
This commit is contained in:
parent
62bf7a89ee
commit
fc4a5f30f0
@ -312,12 +312,14 @@ Decoder::EnsureFrame(uint32_t aFrameNum,
|
||||
aPreviousFrame->GetPaletteDepth() != aPaletteDepth,
|
||||
"Replacing first frame with the same kind of frame?");
|
||||
|
||||
// Remove the old frame from the SurfaceCache.
|
||||
// Remove the old frame from the SurfaceCache and release our reference to it.
|
||||
IntSize prevFrameSize = aPreviousFrame->GetImageSize();
|
||||
SurfaceCache::RemoveSurface(ImageKey(&mImage),
|
||||
RasterSurfaceKey(prevFrameSize, aDecodeFlags, 0));
|
||||
mFrameCount = 0;
|
||||
mInFrame = false;
|
||||
mCurrentFrame->Abort();
|
||||
mCurrentFrame = RawAccessFrameRef();
|
||||
|
||||
// Add the new frame as usual.
|
||||
return InternalAddFrame(aFrameNum, aFrameRect, aDecodeFlags, aFormat,
|
||||
@ -361,6 +363,7 @@ Decoder::InternalAddFrame(uint32_t aFrameNum,
|
||||
|
||||
RawAccessFrameRef ref = frame->RawAccessRef();
|
||||
if (!ref) {
|
||||
frame->Abort();
|
||||
return RawAccessFrameRef();
|
||||
}
|
||||
|
||||
@ -371,6 +374,7 @@ Decoder::InternalAddFrame(uint32_t aFrameNum,
|
||||
aFrameNum),
|
||||
Lifetime::Persistent);
|
||||
if (!succeeded) {
|
||||
ref->Abort();
|
||||
return RawAccessFrameRef();
|
||||
}
|
||||
|
||||
@ -514,6 +518,10 @@ void
|
||||
Decoder::PostDataError()
|
||||
{
|
||||
mDataError = true;
|
||||
|
||||
if (mInFrame && mCurrentFrame) {
|
||||
mCurrentFrame->Abort();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -526,6 +534,10 @@ Decoder::PostDecoderError(nsresult aFailureCode)
|
||||
// XXXbholley - we should report the image URI here, but imgContainer
|
||||
// needs to know its URI first
|
||||
NS_WARNING("Image decoding error - This is probably a bug!");
|
||||
|
||||
if (mInFrame && mCurrentFrame) {
|
||||
mCurrentFrame->Abort();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -89,7 +89,8 @@ FrameAnimator::AdvanceFrame(TimeStamp aTime)
|
||||
// If we're done decoding, we know we've got everything we're going to get.
|
||||
// If we aren't, we only display fully-downloaded frames; everything else
|
||||
// gets delayed.
|
||||
bool canDisplay = mDoneDecoding || (nextFrame && nextFrame->ImageComplete());
|
||||
bool canDisplay = mDoneDecoding ||
|
||||
(nextFrame && nextFrame->IsImageComplete());
|
||||
|
||||
if (!canDisplay) {
|
||||
// Uh oh, the frame we want to show is currently being decoded (partial)
|
||||
@ -595,6 +596,8 @@ FrameAnimator::DoBlend(nsIntRect* aDirtyRect,
|
||||
compositingFrameData.mRect,
|
||||
compositingPrevFrameData.mRawData,
|
||||
compositingPrevFrameData.mRect);
|
||||
|
||||
mCompositingPrevFrame->Finish();
|
||||
}
|
||||
|
||||
// blit next frame into it's correct spot
|
||||
@ -606,11 +609,7 @@ FrameAnimator::DoBlend(nsIntRect* aDirtyRect,
|
||||
nextFrameData.mBlendMethod);
|
||||
|
||||
// Tell the image that it is fully 'downloaded'.
|
||||
nsresult rv =
|
||||
mCompositingFrame->ImageUpdated(compositingFrameData.mRect);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
mCompositingFrame->Finish();
|
||||
|
||||
mLastCompositedFrameIndex = int32_t(aNextFrameIndex);
|
||||
|
||||
|
@ -204,7 +204,7 @@ public:
|
||||
if (succeeded) {
|
||||
// Mark the frame as complete and discardable.
|
||||
mDstRef->ImageUpdated(mDstRef->GetRect());
|
||||
MOZ_ASSERT(mDstRef->ImageComplete(),
|
||||
MOZ_ASSERT(mDstRef->IsImageComplete(),
|
||||
"Incomplete, but just updated the entire frame");
|
||||
}
|
||||
|
||||
@ -551,7 +551,8 @@ RasterImage::LookupFrame(uint32_t aFrameNum,
|
||||
mFrameCount = 0;
|
||||
WantDecodedFrames(aFlags, aShouldSyncNotify);
|
||||
|
||||
// See if we managed to redecode enough to get the frame we want.
|
||||
// If we were able to sync decode, we should already have the frame. If we
|
||||
// had to decode asynchronously, maybe we've gotten lucky.
|
||||
ref = LookupFrameInternal(aFrameNum, aSize, aFlags);
|
||||
|
||||
if (!ref) {
|
||||
@ -566,6 +567,14 @@ RasterImage::LookupFrame(uint32_t aFrameNum,
|
||||
|
||||
MOZ_ASSERT(!ref || !ref->GetIsPaletted(), "Should not have paletted frame");
|
||||
|
||||
// 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)) {
|
||||
ref->WaitUntilComplete();
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
@ -1911,7 +1920,7 @@ RasterImage::RequestScale(imgFrame* aFrame,
|
||||
const nsIntSize& aSize)
|
||||
{
|
||||
// We don't scale frames which aren't fully decoded.
|
||||
if (!aFrame->ImageComplete()) {
|
||||
if (!aFrame->IsImageComplete()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1960,7 +1969,7 @@ RasterImage::DrawWithPreDownscaleIfNeeded(DrawableFrameRef&& aFrameRef,
|
||||
// to aFrameRef below.
|
||||
RequestScale(aFrameRef.get(), aFlags, aSize);
|
||||
}
|
||||
if (frameRef && !frameRef->ImageComplete()) {
|
||||
if (frameRef && !frameRef->IsImageComplete()) {
|
||||
frameRef.reset(); // We're still scaling, so we can't use this yet.
|
||||
}
|
||||
}
|
||||
@ -2467,7 +2476,7 @@ RasterImage::OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame,
|
||||
DecodeFlags(aFlags),
|
||||
0));
|
||||
|
||||
if (frameRef && frameRef->ImageComplete()) {
|
||||
if (frameRef && frameRef->IsImageComplete()) {
|
||||
return destSize; // We have an existing HQ scale for this size.
|
||||
}
|
||||
if (!frameRef) {
|
||||
|
@ -130,13 +130,14 @@ static bool AllowedImageAndFrameDimensions(const nsIntSize& aImageSize,
|
||||
|
||||
|
||||
imgFrame::imgFrame()
|
||||
: mMutex("imgFrame")
|
||||
: mMonitor("imgFrame")
|
||||
, mDecoded(0, 0, 0, 0)
|
||||
, mLockCount(0)
|
||||
, mTimeout(100)
|
||||
, mDisposalMethod(DisposalMethod::NOT_SPECIFIED)
|
||||
, mBlendMethod(BlendMethod::OVER)
|
||||
, mHasNoAlpha(false)
|
||||
, mAborted(false)
|
||||
, mPalettedImageData(nullptr)
|
||||
, mPaletteDepth(0)
|
||||
, mNonPremult(false)
|
||||
@ -155,6 +156,11 @@ imgFrame::imgFrame()
|
||||
|
||||
imgFrame::~imgFrame()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
MOZ_ASSERT(mAborted || IsImageCompleteInternal());
|
||||
#endif
|
||||
|
||||
moz_free(mPalettedImageData);
|
||||
mPalettedImageData = nullptr;
|
||||
}
|
||||
@ -170,6 +176,7 @@ imgFrame::InitForDecoder(const nsIntSize& aImageSize,
|
||||
// warn for properties related to bad content.
|
||||
if (!AllowedImageAndFrameDimensions(aImageSize, aRect)) {
|
||||
NS_WARNING("Should have legal image size");
|
||||
mAborted = true;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -186,6 +193,7 @@ imgFrame::InitForDecoder(const nsIntSize& aImageSize,
|
||||
if (aPaletteDepth > 8) {
|
||||
NS_WARNING("Should have legal palette depth");
|
||||
NS_ERROR("This Depth is not supported");
|
||||
mAborted = true;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -202,6 +210,7 @@ imgFrame::InitForDecoder(const nsIntSize& aImageSize,
|
||||
|
||||
mVBuf = AllocateBufferForImage(mSize, mFormat);
|
||||
if (!mVBuf) {
|
||||
mAborted = true;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
if (mVBuf->OnHeap()) {
|
||||
@ -213,6 +222,7 @@ imgFrame::InitForDecoder(const nsIntSize& aImageSize,
|
||||
|
||||
if (!mImageSurface) {
|
||||
NS_WARNING("Failed to create VolatileDataSourceSurface");
|
||||
mAborted = true;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
@ -231,6 +241,7 @@ imgFrame::InitWithDrawable(gfxDrawable* aDrawable,
|
||||
// warn for properties related to bad content.
|
||||
if (!AllowedImageSize(aSize.width, aSize.height)) {
|
||||
NS_WARNING("Should have legal image size");
|
||||
mAborted = true;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -253,12 +264,14 @@ imgFrame::InitWithDrawable(gfxDrawable* aDrawable,
|
||||
|
||||
mVBuf = AllocateBufferForImage(mSize, mFormat);
|
||||
if (!mVBuf) {
|
||||
mAborted = true;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
int32_t stride = VolatileSurfaceStride(mSize, mFormat);
|
||||
VolatileBufferPtr<uint8_t> ptr(mVBuf);
|
||||
if (!ptr) {
|
||||
mAborted = true;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
if (mVBuf->OnHeap()) {
|
||||
@ -280,6 +293,7 @@ imgFrame::InitWithDrawable(gfxDrawable* aDrawable,
|
||||
}
|
||||
|
||||
if (!target) {
|
||||
mAborted = true;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@ -292,6 +306,7 @@ imgFrame::InitWithDrawable(gfxDrawable* aDrawable,
|
||||
|
||||
if (canUseDataSurface && !mImageSurface) {
|
||||
NS_WARNING("Failed to create VolatileDataSourceSurface");
|
||||
mAborted = true;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@ -301,13 +316,17 @@ imgFrame::InitWithDrawable(gfxDrawable* aDrawable,
|
||||
mOptSurface = target->Snapshot();
|
||||
}
|
||||
|
||||
// If we reach this point, we should regard ourselves as complete.
|
||||
mDecoded = GetRect();
|
||||
MOZ_ASSERT(IsImageComplete());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult imgFrame::Optimize()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
MOZ_ASSERT(mLockCount == 1,
|
||||
"Should only optimize when holding the lock exclusively");
|
||||
|
||||
@ -455,7 +474,7 @@ imgFrame::SurfaceForDrawing(bool aDoPadding,
|
||||
SourceSurface* aSurface)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
IntSize size(int32_t(aImageRect.Width()), int32_t(aImageRect.Height()));
|
||||
if (!aDoPadding && !aDoPartialDecode) {
|
||||
@ -516,7 +535,7 @@ bool imgFrame::Draw(gfxContext* aContext, const ImageRegion& aRegion,
|
||||
"We must be allowed to sample *some* source pixels!");
|
||||
NS_ASSERTION(!mPalettedImageData, "Directly drawing a paletted image!");
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
nsIntMargin padding(mOffset.y,
|
||||
mImageSize.width - (mOffset.x + mSize.width),
|
||||
@ -524,7 +543,7 @@ bool imgFrame::Draw(gfxContext* aContext, const ImageRegion& aRegion,
|
||||
mOffset.x);
|
||||
|
||||
bool doPadding = padding != nsIntMargin(0,0,0,0);
|
||||
bool doPartialDecode = !ImageCompleteInternal();
|
||||
bool doPartialDecode = !IsImageCompleteInternal();
|
||||
|
||||
if (mSinglePixel && !doPadding && !doPartialDecode) {
|
||||
if (mSinglePixelColor.a == 0.0) {
|
||||
@ -569,14 +588,14 @@ bool imgFrame::Draw(gfxContext* aContext, const ImageRegion& aRegion,
|
||||
nsresult
|
||||
imgFrame::ImageUpdated(const nsIntRect& aUpdateRect)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
return ImageUpdatedInternal(aUpdateRect);
|
||||
}
|
||||
|
||||
nsresult
|
||||
imgFrame::ImageUpdatedInternal(const nsIntRect& aUpdateRect)
|
||||
{
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
mDecoded.UnionRect(mDecoded, aUpdateRect);
|
||||
|
||||
@ -585,14 +604,21 @@ imgFrame::ImageUpdatedInternal(const nsIntRect& aUpdateRect)
|
||||
nsIntRect boundsRect(mOffset, nsIntSize(mSize.width, mSize.height));
|
||||
mDecoded.IntersectRect(mDecoded, boundsRect);
|
||||
|
||||
// If the image is now complete, wake up anyone who's waiting.
|
||||
if (IsImageCompleteInternal()) {
|
||||
mMonitor.NotifyAll();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
imgFrame::Finish(Opacity aFrameOpacity, DisposalMethod aDisposalMethod,
|
||||
int32_t aRawTimeout, BlendMethod aBlendMethod)
|
||||
imgFrame::Finish(Opacity aFrameOpacity /* = Opacity::SOME_TRANSPARENCY */,
|
||||
DisposalMethod aDisposalMethod /* = DisposalMethod::KEEP */,
|
||||
int32_t aRawTimeout /* = 0 */,
|
||||
BlendMethod aBlendMethod /* = BlendMethod::OVER */)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
MOZ_ASSERT(mLockCount > 0, "Image data should be locked");
|
||||
|
||||
if (aFrameOpacity == Opacity::OPAQUE) {
|
||||
@ -613,7 +639,7 @@ nsIntRect imgFrame::GetRect() const
|
||||
int32_t
|
||||
imgFrame::GetStride() const
|
||||
{
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
if (mImageSurface) {
|
||||
return mImageSurface->Stride();
|
||||
@ -624,13 +650,13 @@ imgFrame::GetStride() const
|
||||
|
||||
SurfaceFormat imgFrame::GetFormat() const
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
return mFormat;
|
||||
}
|
||||
|
||||
uint32_t imgFrame::GetImageBytesPerRow() const
|
||||
{
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
if (mVBuf)
|
||||
return mSize.width * BytesPerPixel(mFormat);
|
||||
@ -649,14 +675,14 @@ uint32_t imgFrame::GetImageDataLength() const
|
||||
void
|
||||
imgFrame::GetImageData(uint8_t** aData, uint32_t* aLength) const
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
GetImageDataInternal(aData, aLength);
|
||||
}
|
||||
|
||||
void
|
||||
imgFrame::GetImageDataInternal(uint8_t** aData, uint32_t* aLength) const
|
||||
{
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
MOZ_ASSERT(mLockCount > 0, "Image data should be locked");
|
||||
|
||||
if (mImageSurface) {
|
||||
@ -710,7 +736,7 @@ uint32_t* imgFrame::GetPaletteData() const
|
||||
nsresult
|
||||
imgFrame::LockImageData()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
MOZ_ASSERT(mLockCount >= 0, "Unbalanced locks and unlocks");
|
||||
if (mLockCount < 0) {
|
||||
@ -742,7 +768,7 @@ nsresult
|
||||
imgFrame::Deoptimize()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
MOZ_ASSERT(!mImageSurface);
|
||||
|
||||
if (!mImageSurface) {
|
||||
@ -811,7 +837,7 @@ void
|
||||
imgFrame::AssertImageDataLocked() const
|
||||
{
|
||||
#ifdef DEBUG
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
MOZ_ASSERT(mLockCount > 0, "Image data should be locked");
|
||||
#endif
|
||||
}
|
||||
@ -834,13 +860,16 @@ private:
|
||||
nsresult
|
||||
imgFrame::UnlockImageData()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
MOZ_ASSERT(mLockCount > 0, "Unlocking an unlocked image!");
|
||||
if (mLockCount <= 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mLockCount > 1 || IsImageCompleteInternal() || mAborted,
|
||||
"Should have marked complete or aborted before unlocking");
|
||||
|
||||
// If we're about to become unlocked, we don't need to hold on to our data
|
||||
// surface anymore. (But we don't need to do anything for paletted images,
|
||||
// which don't have surfaces.)
|
||||
@ -898,14 +927,14 @@ imgFrame::IsSinglePixel() const
|
||||
TemporaryRef<SourceSurface>
|
||||
imgFrame::GetSurface()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
return GetSurfaceInternal();
|
||||
}
|
||||
|
||||
TemporaryRef<SourceSurface>
|
||||
imgFrame::GetSurfaceInternal()
|
||||
{
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
if (mOptSurface) {
|
||||
if (mOptSurface->IsValid())
|
||||
@ -930,7 +959,7 @@ imgFrame::GetSurfaceInternal()
|
||||
TemporaryRef<DrawTarget>
|
||||
imgFrame::GetDrawTarget()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
uint8_t* data;
|
||||
uint32_t length;
|
||||
@ -947,7 +976,7 @@ imgFrame::GetDrawTarget()
|
||||
AnimationData
|
||||
imgFrame::GetAnimationData() const
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
MOZ_ASSERT(mLockCount > 0, "Image data should be locked");
|
||||
|
||||
uint8_t* data;
|
||||
@ -967,7 +996,7 @@ imgFrame::GetAnimationData() const
|
||||
ScalingData
|
||||
imgFrame::GetScalingData() const
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
MOZ_ASSERT(mLockCount > 0, "Image data should be locked");
|
||||
MOZ_ASSERT(!GetIsPaletted(), "GetScalingData can't handle paletted images");
|
||||
|
||||
@ -978,17 +1007,46 @@ imgFrame::GetScalingData() const
|
||||
return ScalingData(data, mSize, GetImageBytesPerRow(), mFormat);
|
||||
}
|
||||
|
||||
bool
|
||||
imgFrame::ImageComplete() const
|
||||
void
|
||||
imgFrame::Abort()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
return ImageCompleteInternal();
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
mAborted = true;
|
||||
|
||||
// Wake up anyone who's waiting.
|
||||
if (IsImageCompleteInternal()) {
|
||||
mMonitor.NotifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
imgFrame::ImageCompleteInternal() const
|
||||
imgFrame::IsImageComplete() const
|
||||
{
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
return IsImageCompleteInternal();
|
||||
}
|
||||
|
||||
void
|
||||
imgFrame::WaitUntilComplete() const
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
while (true) {
|
||||
// Return if we're aborted or complete.
|
||||
if (mAborted || IsImageCompleteInternal()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Not complete yet, so we'll have to wait.
|
||||
mMonitor.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
imgFrame::IsImageCompleteInternal() const
|
||||
{
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
return mDecoded.IsEqualInterior(nsIntRect(mOffset.x, mOffset.y,
|
||||
mSize.width, mSize.height));
|
||||
}
|
||||
@ -1009,7 +1067,7 @@ size_t
|
||||
imgFrame::SizeOfExcludingThis(gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
// aMallocSizeOf is only used if aLocation==gfxMemoryLocation::IN_PROCESS_HEAP. It
|
||||
// should be nullptr otherwise.
|
||||
|
@ -8,8 +8,8 @@
|
||||
#define imgFrame_h
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/TypedEnum.h"
|
||||
#include "mozilla/VolatileBuffer.h"
|
||||
#include "gfxDrawable.h"
|
||||
@ -182,6 +182,9 @@ public:
|
||||
/**
|
||||
* Mark this imgFrame as completely decoded, and set final options.
|
||||
*
|
||||
* You must always call either Finish() or Abort() before releasing the last
|
||||
* RawAccessFrameRef pointing to an imgFrame.
|
||||
*
|
||||
* @param aFrameOpacity Whether this imgFrame is opaque.
|
||||
* @param aDisposalMethod For animation frames, how this imgFrame is cleared
|
||||
* from the compositing frame before the next frame is
|
||||
@ -193,8 +196,34 @@ public:
|
||||
* @param aBlendMethod For animation frames, a blending method to be used
|
||||
* when compositing this frame.
|
||||
*/
|
||||
void Finish(Opacity aFrameOpacity, DisposalMethod aDisposalMethod,
|
||||
int32_t aRawTimeout, BlendMethod aBlendMethod);
|
||||
void Finish(Opacity aFrameOpacity = Opacity::SOME_TRANSPARENCY,
|
||||
DisposalMethod aDisposalMethod = DisposalMethod::KEEP,
|
||||
int32_t aRawTimeout = 0,
|
||||
BlendMethod aBlendMethod = BlendMethod::OVER);
|
||||
|
||||
/**
|
||||
* Mark this imgFrame as aborted. This informs the imgFrame that if it isn't
|
||||
* completely decoded now, it never will be.
|
||||
*
|
||||
* You must always call either Finish() or Abort() before releasing the last
|
||||
* RawAccessFrameRef pointing to an imgFrame.
|
||||
*/
|
||||
void Abort();
|
||||
|
||||
/**
|
||||
* Returns true if this imgFrame is completely decoded.
|
||||
*/
|
||||
bool IsImageComplete() const;
|
||||
|
||||
/**
|
||||
* Blocks until this imgFrame is either completely decoded, or is marked as
|
||||
* aborted.
|
||||
*
|
||||
* Note that calling this on the main thread _blocks the main thread_. Be very
|
||||
* careful in your use of this method to avoid excessive main thread jank or
|
||||
* deadlock.
|
||||
*/
|
||||
void WaitUntilComplete() const;
|
||||
|
||||
IntSize GetImageSize() { return mImageSize; }
|
||||
nsIntRect GetRect() const;
|
||||
@ -218,8 +247,6 @@ public:
|
||||
AnimationData GetAnimationData() const;
|
||||
ScalingData GetScalingData() const;
|
||||
|
||||
bool ImageComplete() const;
|
||||
|
||||
bool GetCompositingFailed() const;
|
||||
void SetCompositingFailed(bool val);
|
||||
|
||||
@ -245,7 +272,7 @@ private: // methods
|
||||
|
||||
void AssertImageDataLocked() const;
|
||||
|
||||
bool ImageCompleteInternal() const;
|
||||
bool IsImageCompleteInternal() const;
|
||||
nsresult ImageUpdatedInternal(const nsIntRect& aUpdateRect);
|
||||
void GetImageDataInternal(uint8_t **aData, uint32_t *length) const;
|
||||
uint32_t GetImageBytesPerRow() const;
|
||||
@ -283,10 +310,10 @@ private: // data
|
||||
friend class UnlockImageDataRunnable;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Thread-safe mutable data, protected by mMutex.
|
||||
// Thread-safe mutable data, protected by mMonitor.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
mutable Mutex mMutex;
|
||||
mutable Monitor mMonitor;
|
||||
|
||||
RefPtr<DataSourceSurface> mImageSurface;
|
||||
RefPtr<SourceSurface> mOptSurface;
|
||||
@ -307,6 +334,7 @@ private: // data
|
||||
SurfaceFormat mFormat;
|
||||
|
||||
bool mHasNoAlpha;
|
||||
bool mAborted;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user