mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1054076 - Make imgFrame reference counted. r=tn
This commit is contained in:
parent
5e8ae2d9fc
commit
0339df9d8d
@ -174,22 +174,24 @@ void nsGIFDecoder2::BeginImageFrame(uint16_t aDepth)
|
||||
NeedNewFrame(mGIFStruct.images_decoded, mGIFStruct.x_offset,
|
||||
mGIFStruct.y_offset, mGIFStruct.width, mGIFStruct.height,
|
||||
format, aDepth);
|
||||
}
|
||||
|
||||
// Our first full frame is automatically created by the image decoding
|
||||
// infrastructure. Just use it as long as it matches up.
|
||||
else if (!GetCurrentFrame()->GetRect().IsEqualEdges(nsIntRect(mGIFStruct.x_offset,
|
||||
mGIFStruct.y_offset,
|
||||
mGIFStruct.width,
|
||||
mGIFStruct.height))) {
|
||||
// Regardless of depth of input, image is decoded into 24bit RGB
|
||||
NeedNewFrame(mGIFStruct.images_decoded, mGIFStruct.x_offset,
|
||||
mGIFStruct.y_offset, mGIFStruct.width, mGIFStruct.height,
|
||||
format);
|
||||
} else {
|
||||
// Our preallocated frame matches up, with the possible exception of alpha.
|
||||
if (format == gfx::SurfaceFormat::B8G8R8X8) {
|
||||
GetCurrentFrame()->SetHasNoAlpha();
|
||||
nsRefPtr<imgFrame> currentFrame = GetCurrentFrame();
|
||||
|
||||
// Our first full frame is automatically created by the image decoding
|
||||
// infrastructure. Just use it as long as it matches up.
|
||||
if (!currentFrame->GetRect().IsEqualEdges(nsIntRect(mGIFStruct.x_offset,
|
||||
mGIFStruct.y_offset,
|
||||
mGIFStruct.width,
|
||||
mGIFStruct.height))) {
|
||||
// Regardless of depth of input, image is decoded into 24bit RGB
|
||||
NeedNewFrame(mGIFStruct.images_decoded, mGIFStruct.x_offset,
|
||||
mGIFStruct.y_offset, mGIFStruct.width, mGIFStruct.height,
|
||||
format);
|
||||
} else {
|
||||
// Our preallocated frame matches up, with the possible exception of alpha.
|
||||
if (format == gfx::SurfaceFormat::B8G8R8X8) {
|
||||
currentFrame->SetHasNoAlpha();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,20 +145,19 @@ void nsPNGDecoder::CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset,
|
||||
// Our first full frame is automatically created by the image decoding
|
||||
// infrastructure. Just use it as long as it matches up.
|
||||
MOZ_ASSERT(HasSize());
|
||||
if (mNumFrames != 0 ||
|
||||
!GetCurrentFrame()->GetRect().IsEqualEdges(nsIntRect(x_offset, y_offset, width, height))) {
|
||||
nsIntRect neededRect(x_offset, y_offset, width, height);
|
||||
nsRefPtr<imgFrame> currentFrame = GetCurrentFrame();
|
||||
if (mNumFrames != 0 || !currentFrame->GetRect().IsEqualEdges(neededRect)) {
|
||||
NeedNewFrame(mNumFrames, x_offset, y_offset, width, height, format);
|
||||
} else if (mNumFrames == 0) {
|
||||
// Our preallocated frame matches up, with the possible exception of alpha.
|
||||
if (format == gfx::SurfaceFormat::B8G8R8X8) {
|
||||
GetCurrentFrame()->SetHasNoAlpha();
|
||||
currentFrame->SetHasNoAlpha();
|
||||
}
|
||||
}
|
||||
|
||||
mFrameRect.x = x_offset;
|
||||
mFrameRect.y = y_offset;
|
||||
mFrameRect.width = width;
|
||||
mFrameRect.height = height;
|
||||
mFrameRect = neededRect;
|
||||
mFrameHasNoAlpha = true;
|
||||
|
||||
PR_LOG(GetPNGDecoderAccountingLog(), PR_LOG_DEBUG,
|
||||
("PNGDecoderAccounting: nsPNGDecoder::CreateFrame -- created "
|
||||
@ -166,8 +165,6 @@ void nsPNGDecoder::CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset,
|
||||
width, height,
|
||||
&mImage));
|
||||
|
||||
mFrameHasNoAlpha = true;
|
||||
|
||||
#ifdef PNG_APNG_SUPPORTED
|
||||
if (png_get_valid(mPNG, mInfo, PNG_INFO_acTL)) {
|
||||
mAnimInfo = AnimFrameInfo(mPNG, mInfo);
|
||||
|
@ -204,19 +204,21 @@ Decoder::AllocateFrame()
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsresult rv;
|
||||
imgFrame* frame = nullptr;
|
||||
nsRefPtr<imgFrame> frame;
|
||||
if (mNewFrameData.mPaletteDepth) {
|
||||
rv = mImage.EnsureFrame(mNewFrameData.mFrameNum, mNewFrameData.mOffsetX,
|
||||
mNewFrameData.mOffsetY, mNewFrameData.mWidth,
|
||||
mNewFrameData.mHeight, mNewFrameData.mFormat,
|
||||
mNewFrameData.mPaletteDepth,
|
||||
&mImageData, &mImageDataLength,
|
||||
&mColormap, &mColormapSize, &frame);
|
||||
&mColormap, &mColormapSize,
|
||||
getter_AddRefs(frame));
|
||||
} else {
|
||||
rv = mImage.EnsureFrame(mNewFrameData.mFrameNum, mNewFrameData.mOffsetX,
|
||||
mNewFrameData.mOffsetY, mNewFrameData.mWidth,
|
||||
mNewFrameData.mHeight, mNewFrameData.mFormat,
|
||||
&mImageData, &mImageDataLength, &frame);
|
||||
&mImageData, &mImageDataLength,
|
||||
getter_AddRefs(frame));
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -171,7 +171,11 @@ public:
|
||||
// status code from that attempt. Clears mNewFrameData.
|
||||
virtual nsresult AllocateFrame();
|
||||
|
||||
imgFrame* GetCurrentFrame() const { return mCurrentFrame; }
|
||||
already_AddRefed<imgFrame> GetCurrentFrame() const
|
||||
{
|
||||
nsRefPtr<imgFrame> frame = mCurrentFrame;
|
||||
return frame.forget();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
@ -230,7 +234,7 @@ protected:
|
||||
*
|
||||
*/
|
||||
RasterImage &mImage;
|
||||
imgFrame* mCurrentFrame;
|
||||
nsRefPtr<imgFrame> mCurrentFrame;
|
||||
RefPtr<imgDecoderObserver> mObserver;
|
||||
ImageMetadata mImageMetadata;
|
||||
|
||||
|
@ -85,13 +85,12 @@ FrameAnimator::AdvanceFrame(TimeStamp aTime)
|
||||
int32_t timeout = 0;
|
||||
|
||||
RefreshResult ret;
|
||||
nsRefPtr<imgFrame> nextFrame = mFrameBlender.RawGetFrame(nextFrameIndex);
|
||||
|
||||
// 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 ||
|
||||
(mFrameBlender.RawGetFrame(nextFrameIndex) &&
|
||||
mFrameBlender.RawGetFrame(nextFrameIndex)->ImageComplete());
|
||||
bool canDisplay = mDoneDecoding || (nextFrame && nextFrame->ImageComplete());
|
||||
|
||||
if (!canDisplay) {
|
||||
// Uh oh, the frame we want to show is currently being decoded (partial)
|
||||
@ -138,10 +137,14 @@ FrameAnimator::AdvanceFrame(TimeStamp aTime)
|
||||
ret.dirtyRect = mFirstFrameRefreshArea;
|
||||
} else {
|
||||
// Change frame
|
||||
if (nextFrameIndex != currentFrameIndex + 1) {
|
||||
nextFrame = mFrameBlender.RawGetFrame(nextFrameIndex);
|
||||
}
|
||||
|
||||
if (!mFrameBlender.DoBlend(&ret.dirtyRect, currentFrameIndex, nextFrameIndex)) {
|
||||
// something went wrong, move on to next
|
||||
NS_WARNING("FrameAnimator::AdvanceFrame(): Compositing of frame failed");
|
||||
mFrameBlender.RawGetFrame(nextFrameIndex)->SetCompositingFailed(true);
|
||||
nextFrame->SetCompositingFailed(true);
|
||||
mCurrentAnimationFrameTime = GetCurrentImgFrameEndTime();
|
||||
mCurrentAnimationFrameIndex = nextFrameIndex;
|
||||
|
||||
@ -149,7 +152,7 @@ FrameAnimator::AdvanceFrame(TimeStamp aTime)
|
||||
return ret;
|
||||
}
|
||||
|
||||
mFrameBlender.RawGetFrame(nextFrameIndex)->SetCompositingFailed(false);
|
||||
nextFrame->SetCompositingFailed(false);
|
||||
}
|
||||
|
||||
mCurrentAnimationFrameTime = GetCurrentImgFrameEndTime();
|
||||
|
@ -35,27 +35,27 @@ FrameBlender::GetFrameSequence()
|
||||
return seq.forget();
|
||||
}
|
||||
|
||||
imgFrame*
|
||||
already_AddRefed<imgFrame>
|
||||
FrameBlender::GetFrame(uint32_t framenum) const
|
||||
{
|
||||
if (!mAnim) {
|
||||
NS_ASSERTION(framenum == 0, "Don't ask for a frame > 0 if we're not animated!");
|
||||
return mFrames->GetFrame(0);
|
||||
return mFrames->GetFrame(0).GetFrame();
|
||||
}
|
||||
if (mAnim->lastCompositedFrameIndex == int32_t(framenum))
|
||||
return mAnim->compositingFrame;
|
||||
return mFrames->GetFrame(framenum);
|
||||
if (mAnim->lastCompositedFrameIndex == int32_t(framenum)) {
|
||||
return mAnim->compositingFrame.GetFrame();
|
||||
}
|
||||
return mFrames->GetFrame(framenum).GetFrame();
|
||||
}
|
||||
|
||||
imgFrame*
|
||||
already_AddRefed<imgFrame>
|
||||
FrameBlender::RawGetFrame(uint32_t framenum) const
|
||||
{
|
||||
if (!mAnim) {
|
||||
NS_ASSERTION(framenum == 0, "Don't ask for a frame > 0 if we're not animated!");
|
||||
return mFrames->GetFrame(0);
|
||||
return mFrames->GetFrame(0).GetFrame();
|
||||
}
|
||||
|
||||
return mFrames->GetFrame(framenum);
|
||||
return mFrames->GetFrame(framenum).GetFrame();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@ -67,7 +67,8 @@ FrameBlender::GetNumFrames() const
|
||||
int32_t
|
||||
FrameBlender::GetTimeoutForFrame(uint32_t framenum) const
|
||||
{
|
||||
const int32_t timeout = RawGetFrame(framenum)->GetRawTimeout();
|
||||
nsRefPtr<imgFrame> frame = RawGetFrame(framenum);
|
||||
const int32_t timeout = frame->GetRawTimeout();
|
||||
// Ensure a minimal time between updates so we don't throttle the UI thread.
|
||||
// consider 0 == unspecified and make it fast but not too fast. Unless we have
|
||||
// a single loop GIF. See bug 890743, bug 125137, bug 139677, and bug 207059.
|
||||
@ -123,23 +124,23 @@ FrameBlender::InsertFrame(uint32_t framenum, imgFrame* aFrame)
|
||||
}
|
||||
}
|
||||
|
||||
imgFrame*
|
||||
already_AddRefed<imgFrame>
|
||||
FrameBlender::SwapFrame(uint32_t framenum, imgFrame* aFrame)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(framenum < GetNumFrames(), "Swapping invalid frame!");
|
||||
|
||||
imgFrame* ret;
|
||||
nsRefPtr<imgFrame> ret;
|
||||
|
||||
// Steal the imgFrame from wherever it's currently stored
|
||||
if (mAnim && mAnim->lastCompositedFrameIndex == int32_t(framenum)) {
|
||||
ret = mAnim->compositingFrame.Forget();
|
||||
mAnim->lastCompositedFrameIndex = -1;
|
||||
nsAutoPtr<imgFrame> toDelete(mFrames->SwapFrame(framenum, aFrame));
|
||||
nsRefPtr<imgFrame> toDelete(mFrames->SwapFrame(framenum, aFrame));
|
||||
} else {
|
||||
ret = mFrames->SwapFrame(framenum, aFrame);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret.forget();
|
||||
}
|
||||
|
||||
void
|
||||
@ -307,18 +308,18 @@ FrameBlender::DoBlend(nsIntRect* aDirtyRect,
|
||||
// If we just created the composite, it could have anything in its
|
||||
// buffer. Clear whole frame
|
||||
ClearFrame(mAnim->compositingFrame.GetFrameData(),
|
||||
mAnim->compositingFrame.GetFrame()->GetRect());
|
||||
mAnim->compositingFrame->GetRect());
|
||||
} else {
|
||||
// Only blank out previous frame area (both color & Mask/Alpha)
|
||||
ClearFrame(mAnim->compositingFrame.GetFrameData(),
|
||||
mAnim->compositingFrame.GetFrame()->GetRect(),
|
||||
mAnim->compositingFrame->GetRect(),
|
||||
prevFrameRect);
|
||||
}
|
||||
break;
|
||||
|
||||
case FrameBlender::kDisposeClearAll:
|
||||
ClearFrame(mAnim->compositingFrame.GetFrameData(),
|
||||
mAnim->compositingFrame.GetFrame()->GetRect());
|
||||
mAnim->compositingFrame->GetRect());
|
||||
break;
|
||||
|
||||
case FrameBlender::kDisposeRestorePrevious:
|
||||
@ -326,16 +327,16 @@ FrameBlender::DoBlend(nsIntRect* aDirtyRect,
|
||||
// compositingFrame.
|
||||
if (mAnim->compositingPrevFrame) {
|
||||
CopyFrameImage(mAnim->compositingPrevFrame.GetFrameData(),
|
||||
mAnim->compositingPrevFrame.GetFrame()->GetRect(),
|
||||
mAnim->compositingPrevFrame->GetRect(),
|
||||
mAnim->compositingFrame.GetFrameData(),
|
||||
mAnim->compositingFrame.GetFrame()->GetRect());
|
||||
mAnim->compositingFrame->GetRect());
|
||||
|
||||
// destroy only if we don't need it for this frame's disposal
|
||||
if (nextFrameDisposalMethod != FrameBlender::kDisposeRestorePrevious)
|
||||
mAnim->compositingPrevFrame.SetFrame(nullptr);
|
||||
} else {
|
||||
ClearFrame(mAnim->compositingFrame.GetFrameData(),
|
||||
mAnim->compositingFrame.GetFrame()->GetRect());
|
||||
mAnim->compositingFrame->GetRect());
|
||||
}
|
||||
break;
|
||||
|
||||
@ -350,23 +351,23 @@ FrameBlender::DoBlend(nsIntRect* aDirtyRect,
|
||||
if (isFullPrevFrame && !prevFrame->GetIsPaletted()) {
|
||||
// Just copy the bits
|
||||
CopyFrameImage(prevFrame.GetFrameData(),
|
||||
prevFrame.GetFrame()->GetRect(),
|
||||
prevFrame->GetRect(),
|
||||
mAnim->compositingFrame.GetFrameData(),
|
||||
mAnim->compositingFrame.GetFrame()->GetRect());
|
||||
mAnim->compositingFrame->GetRect());
|
||||
} else {
|
||||
if (needToBlankComposite) {
|
||||
// Only blank composite when prev is transparent or not full.
|
||||
if (prevFrame->GetHasAlpha() || !isFullPrevFrame) {
|
||||
ClearFrame(mAnim->compositingFrame.GetFrameData(),
|
||||
mAnim->compositingFrame.GetFrame()->GetRect());
|
||||
mAnim->compositingFrame->GetRect());
|
||||
}
|
||||
}
|
||||
DrawFrameTo(prevFrame.GetFrameData(), prevFrameRect,
|
||||
prevFrame.GetFrame()->PaletteDataLength(),
|
||||
prevFrame.GetFrame()->GetHasAlpha(),
|
||||
prevFrame->PaletteDataLength(),
|
||||
prevFrame->GetHasAlpha(),
|
||||
mAnim->compositingFrame.GetFrameData(),
|
||||
mAnim->compositingFrame.GetFrame()->GetRect(),
|
||||
FrameBlendMethod(prevFrame.GetFrame()->GetBlendMethod()));
|
||||
mAnim->compositingFrame->GetRect(),
|
||||
FrameBlendMethod(prevFrame->GetBlendMethod()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -374,7 +375,7 @@ FrameBlender::DoBlend(nsIntRect* aDirtyRect,
|
||||
// If we just created the composite, it could have anything in it's
|
||||
// buffers. Clear them
|
||||
ClearFrame(mAnim->compositingFrame.GetFrameData(),
|
||||
mAnim->compositingFrame.GetFrame()->GetRect());
|
||||
mAnim->compositingFrame->GetRect());
|
||||
}
|
||||
|
||||
// Check if the frame we are composing wants the previous image restored afer
|
||||
@ -398,18 +399,18 @@ FrameBlender::DoBlend(nsIntRect* aDirtyRect,
|
||||
}
|
||||
|
||||
CopyFrameImage(mAnim->compositingFrame.GetFrameData(),
|
||||
mAnim->compositingFrame.GetFrame()->GetRect(),
|
||||
mAnim->compositingFrame->GetRect(),
|
||||
mAnim->compositingPrevFrame.GetFrameData(),
|
||||
mAnim->compositingPrevFrame.GetFrame()->GetRect());
|
||||
mAnim->compositingPrevFrame->GetRect());
|
||||
}
|
||||
|
||||
// blit next frame into it's correct spot
|
||||
DrawFrameTo(nextFrame.GetFrameData(), nextFrameRect,
|
||||
nextFrame.GetFrame()->PaletteDataLength(),
|
||||
nextFrame.GetFrame()->GetHasAlpha(),
|
||||
nextFrame->PaletteDataLength(),
|
||||
nextFrame->GetHasAlpha(),
|
||||
mAnim->compositingFrame.GetFrameData(),
|
||||
mAnim->compositingFrame.GetFrame()->GetRect(),
|
||||
FrameBlendMethod(nextFrame.GetFrame()->GetBlendMethod()));
|
||||
mAnim->compositingFrame->GetRect(),
|
||||
FrameBlendMethod(nextFrame->GetBlendMethod()));
|
||||
|
||||
// Set timeout of CompositeFrame to timeout of frame we just composed
|
||||
// Bug 177948
|
||||
@ -417,7 +418,8 @@ FrameBlender::DoBlend(nsIntRect* aDirtyRect,
|
||||
mAnim->compositingFrame->SetRawTimeout(timeout);
|
||||
|
||||
// Tell the image that it is fully 'downloaded'.
|
||||
nsresult rv = mAnim->compositingFrame->ImageUpdated(mAnim->compositingFrame->GetRect());
|
||||
nsresult rv =
|
||||
mAnim->compositingFrame->ImageUpdated(mAnim->compositingFrame->GetRect());
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -44,16 +44,16 @@ public:
|
||||
* Get the @aIndex-th frame, including (if applicable) any results of
|
||||
* blending.
|
||||
*/
|
||||
imgFrame* GetFrame(uint32_t aIndex) const;
|
||||
already_AddRefed<imgFrame> GetFrame(uint32_t aIndex) const;
|
||||
|
||||
/**
|
||||
* Get the @aIndex-th frame in the frame index, ignoring results of blending.
|
||||
*/
|
||||
imgFrame* RawGetFrame(uint32_t aIndex) const;
|
||||
already_AddRefed<imgFrame> RawGetFrame(uint32_t aIndex) const;
|
||||
|
||||
void InsertFrame(uint32_t framenum, imgFrame* aFrame);
|
||||
void RemoveFrame(uint32_t framenum);
|
||||
imgFrame* SwapFrame(uint32_t framenum, imgFrame* aFrame);
|
||||
already_AddRefed<imgFrame> SwapFrame(uint32_t framenum, imgFrame* aFrame);
|
||||
void ClearFrames();
|
||||
|
||||
/* The total number of frames in this image. */
|
||||
|
@ -64,7 +64,7 @@ FrameSequence::InsertFrame(uint32_t framenum, imgFrame* aFrame)
|
||||
}
|
||||
}
|
||||
|
||||
imgFrame*
|
||||
already_AddRefed<imgFrame>
|
||||
FrameSequence::SwapFrame(uint32_t framenum, imgFrame* aFrame)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(framenum < mFrames.Length(), "Swapping invalid frame!");
|
||||
@ -82,7 +82,7 @@ FrameSequence::SwapFrame(uint32_t framenum, imgFrame* aFrame)
|
||||
mFrames.RemoveElementAt(framenum);
|
||||
}
|
||||
|
||||
return ret.Forget();
|
||||
return ret.GetFrame();
|
||||
}
|
||||
|
||||
size_t
|
||||
@ -91,9 +91,9 @@ FrameSequence::SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation aLocati
|
||||
{
|
||||
size_t n = 0;
|
||||
for (uint32_t i = 0; i < mFrames.Length(); ++i) {
|
||||
imgFrame* frame = mFrames.SafeElementAt(i, FrameDataPair());
|
||||
NS_ABORT_IF_FALSE(frame, "Null frame in frame array!");
|
||||
n += frame->SizeOfExcludingThisWithComputedFallbackIfHeap(aLocation, aMallocSizeOf);
|
||||
FrameDataPair fdp = mFrames.SafeElementAt(i, FrameDataPair());
|
||||
NS_ABORT_IF_FALSE(fdp, "Null frame in frame array!");
|
||||
n += fdp->SizeOfExcludingThisWithComputedFallbackIfHeap(aLocation, aMallocSizeOf);
|
||||
}
|
||||
|
||||
return n;
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "gfxTypes.h"
|
||||
#include "imgFrame.h"
|
||||
|
||||
@ -32,19 +33,19 @@ public:
|
||||
{}
|
||||
|
||||
FrameDataPair()
|
||||
: mFrame(nullptr)
|
||||
: mFrameData(nullptr)
|
||||
{}
|
||||
|
||||
FrameDataPair(const FrameDataPair& aOther)
|
||||
: mFrame(aOther.mFrame)
|
||||
, mFrameData(nullptr)
|
||||
{}
|
||||
|
||||
FrameDataPair(FrameDataPair& other)
|
||||
FrameDataPair(FrameDataPair&& aOther)
|
||||
: mFrame(Move(aOther.mFrame))
|
||||
, mFrameData(aOther.mFrameData)
|
||||
{
|
||||
mFrame = other.mFrame;
|
||||
mFrameData = other.mFrameData;
|
||||
|
||||
// since mFrame is an nsAutoPtr, the assignment operator above actually
|
||||
// nulls out other.mFrame. In order to fully assume ownership over the
|
||||
// frame, we also null out the other's mFrameData.
|
||||
other.mFrameData = nullptr;
|
||||
aOther.mFrameData = nullptr;
|
||||
}
|
||||
|
||||
~FrameDataPair()
|
||||
@ -54,6 +55,24 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
FrameDataPair& operator=(const FrameDataPair& aOther)
|
||||
{
|
||||
if (&aOther != this) {
|
||||
mFrame = aOther.mFrame;
|
||||
mFrameData = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
FrameDataPair& operator=(FrameDataPair&& aOther)
|
||||
{
|
||||
MOZ_ASSERT(&aOther != this, "Moving to self");
|
||||
mFrame = Move(aOther.mFrame);
|
||||
mFrameData = aOther.mFrameData;
|
||||
aOther.mFrameData = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Lock the frame and store its mFrameData. The frame will be unlocked (and
|
||||
// deleted) when this FrameDataPair is deleted.
|
||||
void LockAndGetData()
|
||||
@ -71,15 +90,14 @@ public:
|
||||
|
||||
// Null out this FrameDataPair and return its frame. You must ensure the
|
||||
// frame will be deleted separately.
|
||||
imgFrame* Forget()
|
||||
already_AddRefed<imgFrame> Forget()
|
||||
{
|
||||
if (mFrameData) {
|
||||
mFrame->UnlockImageData();
|
||||
}
|
||||
|
||||
imgFrame* frame = mFrame.forget();
|
||||
mFrameData = nullptr;
|
||||
return frame;
|
||||
return mFrame.forget();
|
||||
}
|
||||
|
||||
bool HasFrameData() const
|
||||
@ -95,9 +113,10 @@ public:
|
||||
return mFrameData;
|
||||
}
|
||||
|
||||
imgFrame* GetFrame() const
|
||||
already_AddRefed<imgFrame> GetFrame() const
|
||||
{
|
||||
return mFrame;
|
||||
nsRefPtr<imgFrame> frame = mFrame;
|
||||
return frame.forget();
|
||||
}
|
||||
|
||||
// Resets this FrameDataPair to work with a different frame. Takes ownership
|
||||
@ -112,14 +131,9 @@ public:
|
||||
mFrameData = nullptr;
|
||||
}
|
||||
|
||||
operator imgFrame*() const
|
||||
{
|
||||
return GetFrame();
|
||||
}
|
||||
|
||||
imgFrame* operator->() const
|
||||
{
|
||||
return GetFrame();
|
||||
return mFrame.get();
|
||||
}
|
||||
|
||||
bool operator==(imgFrame* other) const
|
||||
@ -127,8 +141,13 @@ public:
|
||||
return mFrame == other;
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return mFrame != nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
nsAutoPtr<imgFrame> mFrame;
|
||||
nsRefPtr<imgFrame> mFrame;
|
||||
uint8_t* mFrameData;
|
||||
};
|
||||
|
||||
@ -163,7 +182,7 @@ public:
|
||||
* Swap aFrame with the frame at sequence framenum, and return that frame.
|
||||
* You take ownership over the frame returned.
|
||||
*/
|
||||
imgFrame* SwapFrame(uint32_t framenum, imgFrame* aFrame);
|
||||
already_AddRefed<imgFrame> SwapFrame(uint32_t framenum, imgFrame* aFrame);
|
||||
|
||||
/**
|
||||
* Remove (and delete) all frames.
|
||||
|
@ -271,7 +271,7 @@ public:
|
||||
|
||||
// These values may only be touched on the main thread.
|
||||
WeakPtr<RasterImage> weakImage;
|
||||
nsAutoPtr<imgFrame> dstFrame;
|
||||
nsRefPtr<imgFrame> dstFrame;
|
||||
RefPtr<SourceSurface> srcSurface;
|
||||
RefPtr<SourceSurface> dstSurface;
|
||||
|
||||
@ -390,7 +390,6 @@ RasterImage::RasterImage(imgStatusTracker* aStatusTracker,
|
||||
ImageResource(aURI), // invoke superclass's constructor
|
||||
mSize(0,0),
|
||||
mFrameDecodeFlags(DECODE_FLAGS_DEFAULT),
|
||||
mMultipartDecodedFrame(nullptr),
|
||||
mAnim(nullptr),
|
||||
mLockCount(0),
|
||||
mDecodeCount(0),
|
||||
@ -459,14 +458,13 @@ RasterImage::~RasterImage()
|
||||
// This would be done in ShutdownDecoder, but since mDecoder is non-null,
|
||||
// we didn't call ShutdownDecoder and we need to do it manually.
|
||||
if (GetNumFrames() > 0) {
|
||||
imgFrame *curframe = mFrameBlender.RawGetFrame(GetNumFrames() - 1);
|
||||
nsRefPtr<imgFrame> curframe = mFrameBlender.RawGetFrame(GetNumFrames() - 1);
|
||||
curframe->UnlockImageData();
|
||||
}
|
||||
}
|
||||
|
||||
delete mAnim;
|
||||
mAnim = nullptr;
|
||||
delete mMultipartDecodedFrame;
|
||||
|
||||
// Total statistics
|
||||
num_containers--;
|
||||
@ -660,7 +658,7 @@ RasterImage::GetType()
|
||||
return imgIContainer::TYPE_RASTER;
|
||||
}
|
||||
|
||||
imgFrame*
|
||||
already_AddRefed<imgFrame>
|
||||
RasterImage::GetImgFrameNoDecode(uint32_t framenum)
|
||||
{
|
||||
if (!mAnim) {
|
||||
@ -670,7 +668,7 @@ RasterImage::GetImgFrameNoDecode(uint32_t framenum)
|
||||
return mFrameBlender.GetFrame(framenum);
|
||||
}
|
||||
|
||||
imgFrame*
|
||||
already_AddRefed<imgFrame>
|
||||
RasterImage::GetImgFrame(uint32_t framenum)
|
||||
{
|
||||
nsresult rv = WantDecodedFrames();
|
||||
@ -678,10 +676,10 @@ RasterImage::GetImgFrame(uint32_t framenum)
|
||||
return GetImgFrameNoDecode(framenum);
|
||||
}
|
||||
|
||||
imgFrame*
|
||||
already_AddRefed<imgFrame>
|
||||
RasterImage::GetDrawableImgFrame(uint32_t framenum)
|
||||
{
|
||||
imgFrame* frame = nullptr;
|
||||
nsRefPtr<imgFrame> frame;
|
||||
|
||||
if (mMultipart && framenum == GetCurrentImgFrameIndex()) {
|
||||
// In the multipart case we prefer to use mMultipartDecodedFrame, which is
|
||||
@ -699,7 +697,7 @@ RasterImage::GetDrawableImgFrame(uint32_t framenum)
|
||||
if (frame && frame->GetCompositingFailed())
|
||||
return nullptr;
|
||||
|
||||
return frame;
|
||||
return frame.forget();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@ -711,7 +709,7 @@ RasterImage::GetCurrentImgFrameIndex() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
imgFrame*
|
||||
already_AddRefed<imgFrame>
|
||||
RasterImage::GetCurrentImgFrame()
|
||||
{
|
||||
return GetImgFrame(GetCurrentImgFrameIndex());
|
||||
@ -731,8 +729,9 @@ RasterImage::FrameIsOpaque(uint32_t aWhichFrame)
|
||||
return false;
|
||||
|
||||
// See if we can get an image frame.
|
||||
imgFrame* frame = aWhichFrame == FRAME_FIRST ? GetImgFrameNoDecode(0)
|
||||
: GetImgFrameNoDecode(GetCurrentImgFrameIndex());
|
||||
nsRefPtr<imgFrame> frame = aWhichFrame == FRAME_FIRST
|
||||
? GetImgFrameNoDecode(0)
|
||||
: GetImgFrameNoDecode(GetCurrentImgFrameIndex());
|
||||
|
||||
// If we don't get a frame, the safe answer is "not opaque".
|
||||
if (!frame)
|
||||
@ -755,8 +754,9 @@ RasterImage::FrameRect(uint32_t aWhichFrame)
|
||||
}
|
||||
|
||||
// Get the requested frame.
|
||||
imgFrame* frame = aWhichFrame == FRAME_FIRST ? GetImgFrameNoDecode(0)
|
||||
: GetImgFrameNoDecode(GetCurrentImgFrameIndex());
|
||||
nsRefPtr<imgFrame> frame = aWhichFrame == FRAME_FIRST
|
||||
? GetImgFrameNoDecode(0)
|
||||
: GetImgFrameNoDecode(GetCurrentImgFrameIndex());
|
||||
|
||||
// If we have the frame, use that rectangle.
|
||||
if (frame) {
|
||||
@ -855,7 +855,7 @@ RasterImage::CopyFrame(uint32_t aWhichFrame,
|
||||
// FLAG_SYNC_DECODE
|
||||
uint32_t frameIndex = (aWhichFrame == FRAME_FIRST) ?
|
||||
0 : GetCurrentImgFrameIndex();
|
||||
imgFrame *frame = GetDrawableImgFrame(frameIndex);
|
||||
nsRefPtr<imgFrame> frame = GetDrawableImgFrame(frameIndex);
|
||||
if (!frame) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -929,7 +929,7 @@ RasterImage::GetFrame(uint32_t aWhichFrame,
|
||||
// FLAG_SYNC_DECODE
|
||||
uint32_t frameIndex = (aWhichFrame == FRAME_FIRST) ?
|
||||
0 : GetCurrentImgFrameIndex();
|
||||
imgFrame *frame = GetDrawableImgFrame(frameIndex);
|
||||
nsRefPtr<imgFrame> frame = GetDrawableImgFrame(frameIndex);
|
||||
if (!frame) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -1149,7 +1149,7 @@ RasterImage::InternalAddFrameHelper(uint32_t framenum, imgFrame *aFrame,
|
||||
if (framenum > GetNumFrames())
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsAutoPtr<imgFrame> frame(aFrame);
|
||||
nsRefPtr<imgFrame> frame(aFrame);
|
||||
|
||||
// We are in the middle of decoding. This will be unlocked when we finish
|
||||
// decoding or switch to another frame.
|
||||
@ -1160,10 +1160,9 @@ RasterImage::InternalAddFrameHelper(uint32_t framenum, imgFrame *aFrame,
|
||||
|
||||
frame->GetImageData(imageData, imageLength);
|
||||
|
||||
*aRetFrame = frame;
|
||||
|
||||
mFrameBlender.InsertFrame(framenum, frame.forget());
|
||||
mFrameBlender.InsertFrame(framenum, frame);
|
||||
|
||||
frame.forget(aRetFrame);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1188,7 +1187,7 @@ RasterImage::InternalAddFrame(uint32_t framenum,
|
||||
if (framenum > GetNumFrames())
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsAutoPtr<imgFrame> frame(new imgFrame());
|
||||
nsRefPtr<imgFrame> frame(new imgFrame());
|
||||
|
||||
nsresult rv = frame->Init(aX, aY, aWidth, aHeight, aFormat, aPaletteDepth);
|
||||
if (!(mSize.width > 0 && mSize.height > 0))
|
||||
@ -1200,12 +1199,12 @@ RasterImage::InternalAddFrame(uint32_t framenum,
|
||||
// We know we are in a decoder. Therefore, we must unlock the previous frame
|
||||
// when we move on to decoding into the next frame.
|
||||
if (GetNumFrames() > 0) {
|
||||
imgFrame *prevframe = mFrameBlender.RawGetFrame(GetNumFrames() - 1);
|
||||
nsRefPtr<imgFrame> prevframe = mFrameBlender.RawGetFrame(GetNumFrames() - 1);
|
||||
prevframe->UnlockImageData();
|
||||
}
|
||||
|
||||
if (GetNumFrames() == 0) {
|
||||
return InternalAddFrameHelper(framenum, frame.forget(), imageData, imageLength,
|
||||
return InternalAddFrameHelper(framenum, frame, imageData, imageLength,
|
||||
paletteData, paletteLength, aRetFrame);
|
||||
}
|
||||
|
||||
@ -1216,10 +1215,11 @@ RasterImage::InternalAddFrame(uint32_t framenum,
|
||||
// If we dispose of the first frame by clearing it, then the
|
||||
// First Frame's refresh area is all of itself.
|
||||
// RESTORE_PREVIOUS is invalid (assumed to be DISPOSE_CLEAR)
|
||||
int32_t frameDisposalMethod = mFrameBlender.RawGetFrame(0)->GetFrameDisposalMethod();
|
||||
nsRefPtr<imgFrame> firstFrame = mFrameBlender.RawGetFrame(0);
|
||||
int32_t frameDisposalMethod = firstFrame->GetFrameDisposalMethod();
|
||||
if (frameDisposalMethod == FrameBlender::kDisposeClear ||
|
||||
frameDisposalMethod == FrameBlender::kDisposeRestorePrevious)
|
||||
mAnim->SetFirstFrameRefreshArea(mFrameBlender.RawGetFrame(0)->GetRect());
|
||||
mAnim->SetFirstFrameRefreshArea(firstFrame->GetRect());
|
||||
}
|
||||
|
||||
// Calculate firstFrameRefreshArea
|
||||
@ -1227,7 +1227,7 @@ RasterImage::InternalAddFrame(uint32_t framenum,
|
||||
// We only need to refresh that small area when Frame 0 comes around again
|
||||
mAnim->UnionFirstFrameRefreshArea(frame->GetRect());
|
||||
|
||||
rv = InternalAddFrameHelper(framenum, frame.forget(), imageData, imageLength,
|
||||
rv = InternalAddFrameHelper(framenum, frame, imageData, imageLength,
|
||||
paletteData, paletteLength, aRetFrame);
|
||||
|
||||
return rv;
|
||||
@ -1337,7 +1337,7 @@ RasterImage::EnsureFrame(uint32_t aFrameNum, int32_t aX, int32_t aY,
|
||||
paletteData, paletteLength, aRetFrame);
|
||||
}
|
||||
|
||||
imgFrame *frame = mFrameBlender.RawGetFrame(aFrameNum);
|
||||
nsRefPtr<imgFrame> frame = mFrameBlender.RawGetFrame(aFrameNum);
|
||||
if (!frame) {
|
||||
return InternalAddFrame(aFrameNum, aX, aY, aWidth, aHeight, aFormat,
|
||||
aPaletteDepth, imageData, imageLength,
|
||||
@ -1354,13 +1354,13 @@ RasterImage::EnsureFrame(uint32_t aFrameNum, int32_t aX, int32_t aY,
|
||||
frame->GetPaletteData(paletteData, paletteLength);
|
||||
}
|
||||
|
||||
*aRetFrame = frame;
|
||||
|
||||
// We can re-use the frame if it has image data.
|
||||
if (*imageData && paletteData && *paletteData) {
|
||||
frame.forget(aRetFrame);
|
||||
return NS_OK;
|
||||
}
|
||||
if (*imageData && !paletteData) {
|
||||
frame.forget(aRetFrame);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
@ -1372,12 +1372,11 @@ RasterImage::EnsureFrame(uint32_t aFrameNum, int32_t aX, int32_t aY,
|
||||
frame->UnlockImageData();
|
||||
|
||||
mFrameBlender.RemoveFrame(aFrameNum);
|
||||
nsAutoPtr<imgFrame> newFrame(new imgFrame());
|
||||
nsRefPtr<imgFrame> newFrame(new imgFrame());
|
||||
nsresult rv = newFrame->Init(aX, aY, aWidth, aHeight, aFormat, aPaletteDepth);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return InternalAddFrameHelper(aFrameNum, newFrame.forget(), imageData,
|
||||
imageLength, paletteData, paletteLength,
|
||||
aRetFrame);
|
||||
return InternalAddFrameHelper(aFrameNum, newFrame, imageData, imageLength,
|
||||
paletteData, paletteLength, aRetFrame);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -1404,7 +1403,7 @@ RasterImage::SetFrameAsNonPremult(uint32_t aFrameNum, bool aIsNonPremult)
|
||||
if (aFrameNum >= GetNumFrames())
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
imgFrame* frame = mFrameBlender.RawGetFrame(aFrameNum);
|
||||
nsRefPtr<imgFrame> frame = mFrameBlender.RawGetFrame(aFrameNum);
|
||||
NS_ABORT_IF_FALSE(frame, "Calling SetFrameAsNonPremult on frame that doesn't exist!");
|
||||
NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
|
||||
|
||||
@ -1446,10 +1445,11 @@ RasterImage::DecodingComplete()
|
||||
// CanForciblyDiscard is used instead of CanForciblyDiscardAndRedecode
|
||||
// because we know decoding is complete at this point and this is not
|
||||
// an animation
|
||||
nsRefPtr<imgFrame> firstFrame = mFrameBlender.RawGetFrame(0);
|
||||
if (DiscardingEnabled() && CanForciblyDiscard()) {
|
||||
mFrameBlender.RawGetFrame(0)->SetDiscardable();
|
||||
firstFrame->SetDiscardable();
|
||||
}
|
||||
rv = mFrameBlender.RawGetFrame(0)->Optimize();
|
||||
rv = firstFrame->Optimize();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
@ -1464,7 +1464,6 @@ RasterImage::DecodingComplete()
|
||||
// complexity and it's not really needed since we already are smart about
|
||||
// not displaying the still-decoding frame of an animated image. We may
|
||||
// have already stored an extra frame, though, so we'll release it here.
|
||||
delete mMultipartDecodedFrame;
|
||||
mMultipartDecodedFrame = nullptr;
|
||||
}
|
||||
}
|
||||
@ -1497,7 +1496,7 @@ RasterImage::StartAnimation()
|
||||
|
||||
EnsureAnimExists();
|
||||
|
||||
imgFrame* currentFrame = GetCurrentImgFrame();
|
||||
nsRefPtr<imgFrame> currentFrame = GetCurrentImgFrame();
|
||||
// A timeout of -1 means we should display this frame forever.
|
||||
if (currentFrame && mFrameBlender.GetTimeoutForFrame(GetCurrentImgFrameIndex()) < 0) {
|
||||
mAnimationFinished = true;
|
||||
@ -1964,7 +1963,6 @@ RasterImage::Discard(bool force)
|
||||
mScaleResult.frame = nullptr;
|
||||
|
||||
// Clear the last decoded multipart frame.
|
||||
delete mMultipartDecodedFrame;
|
||||
mMultipartDecodedFrame = nullptr;
|
||||
|
||||
// Flag that we no longer have decoded frames for this image
|
||||
@ -2089,7 +2087,7 @@ RasterImage::InitDecoder(bool aDoSizeDecode)
|
||||
// case. Regardless, we need to lock the last frame. Our invariant is that,
|
||||
// while we have a decoder open, the last frame is always locked.
|
||||
if (GetNumFrames() > 0) {
|
||||
imgFrame *curframe = mFrameBlender.RawGetFrame(GetNumFrames() - 1);
|
||||
nsRefPtr<imgFrame> curframe = mFrameBlender.RawGetFrame(GetNumFrames() - 1);
|
||||
curframe->LockImageData();
|
||||
}
|
||||
|
||||
@ -2171,7 +2169,7 @@ RasterImage::ShutdownDecoder(eShutdownIntent aIntent)
|
||||
// Unlock the last frame (if we have any). Our invariant is that, while we
|
||||
// have a decoder open, the last frame is always locked.
|
||||
if (GetNumFrames() > 0) {
|
||||
imgFrame *curframe = mFrameBlender.RawGetFrame(GetNumFrames() - 1);
|
||||
nsRefPtr<imgFrame> curframe = mFrameBlender.RawGetFrame(GetNumFrames() - 1);
|
||||
curframe->UnlockImageData();
|
||||
}
|
||||
|
||||
@ -2563,16 +2561,15 @@ RasterImage::ScalingDone(ScaleRequest* request, ScaleStatus status)
|
||||
if (status == SCALE_DONE) {
|
||||
MOZ_ASSERT(request->done);
|
||||
|
||||
imgFrame *scaledFrame = request->dstFrame.forget();
|
||||
scaledFrame->ImageUpdated(scaledFrame->GetRect());
|
||||
mScaleResult.status = SCALE_DONE;
|
||||
mScaleResult.frame = request->dstFrame.forget();
|
||||
mScaleResult.scaledSize = request->dstSize;
|
||||
|
||||
mScaleResult.frame->ImageUpdated(mScaleResult.frame->GetRect());
|
||||
|
||||
if (mStatusTracker) {
|
||||
mStatusTracker->FrameChanged(&request->srcRect);
|
||||
}
|
||||
|
||||
mScaleResult.status = SCALE_DONE;
|
||||
mScaleResult.frame = scaledFrame;
|
||||
mScaleResult.scaledSize = request->dstSize;
|
||||
} else {
|
||||
mScaleResult.status = SCALE_INVALID;
|
||||
mScaleResult.frame = nullptr;
|
||||
@ -2627,7 +2624,7 @@ RasterImage::DrawWithPreDownscaleIfNeeded(imgFrame *aFrame,
|
||||
GraphicsFilter aFilter,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
imgFrame *frame = aFrame;
|
||||
nsRefPtr<imgFrame> frame = aFrame;
|
||||
nsIntRect framerect = frame->GetRect();
|
||||
|
||||
gfxContextMatrixAutoSaveRestore saveMatrix(aContext);
|
||||
@ -2764,7 +2761,7 @@ RasterImage::Draw(gfxContext* aContext,
|
||||
|
||||
uint32_t frameIndex = aWhichFrame == FRAME_FIRST ? 0
|
||||
: GetCurrentImgFrameIndex();
|
||||
imgFrame* frame = GetDrawableImgFrame(frameIndex);
|
||||
nsRefPtr<imgFrame> frame = GetDrawableImgFrame(frameIndex);
|
||||
if (!frame) {
|
||||
return NS_OK; // Getting the frame (above) touches the image and kicks off decoding
|
||||
}
|
||||
@ -3695,7 +3692,7 @@ RasterImage::OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame,
|
||||
uint32_t frameIndex = aWhichFrame == FRAME_FIRST ? 0
|
||||
: GetCurrentImgFrameIndex();
|
||||
|
||||
imgFrame* frame = GetDrawableImgFrame(frameIndex);
|
||||
nsRefPtr<imgFrame> frame = GetDrawableImgFrame(frameIndex);
|
||||
if (frame) {
|
||||
RequestScale(frame, destSize);
|
||||
}
|
||||
|
@ -576,10 +576,10 @@ private:
|
||||
*/
|
||||
void DeleteImgFrame(uint32_t framenum);
|
||||
|
||||
imgFrame* GetImgFrameNoDecode(uint32_t framenum);
|
||||
imgFrame* GetImgFrame(uint32_t framenum);
|
||||
imgFrame* GetDrawableImgFrame(uint32_t framenum);
|
||||
imgFrame* GetCurrentImgFrame();
|
||||
already_AddRefed<imgFrame> GetImgFrameNoDecode(uint32_t framenum);
|
||||
already_AddRefed<imgFrame> GetImgFrame(uint32_t framenum);
|
||||
already_AddRefed<imgFrame> GetDrawableImgFrame(uint32_t framenum);
|
||||
already_AddRefed<imgFrame> GetCurrentImgFrame();
|
||||
uint32_t GetCurrentImgFrameIndex() const;
|
||||
|
||||
size_t SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation aLocation,
|
||||
@ -637,9 +637,9 @@ private: // data
|
||||
FrameBlender mFrameBlender;
|
||||
|
||||
// The last frame we decoded for multipart images.
|
||||
imgFrame* mMultipartDecodedFrame;
|
||||
nsRefPtr<imgFrame> mMultipartDecodedFrame;
|
||||
|
||||
nsCOMPtr<nsIProperties> mProperties;
|
||||
nsCOMPtr<nsIProperties> mProperties;
|
||||
|
||||
// IMPORTANT: if you use mAnim in a method, call EnsureImageIsDecoded() first to ensure
|
||||
// that the frames actually exist (they may have been discarded to save memory, or
|
||||
@ -748,7 +748,7 @@ private: // data
|
||||
{}
|
||||
|
||||
nsIntSize scaledSize;
|
||||
nsAutoPtr<imgFrame> frame;
|
||||
nsRefPtr<imgFrame> frame;
|
||||
ScaleStatus status;
|
||||
};
|
||||
|
||||
|
@ -438,6 +438,16 @@ nsIntRect imgFrame::GetRect() const
|
||||
return nsIntRect(mOffset, nsIntSize(mSize.width, mSize.height));
|
||||
}
|
||||
|
||||
int32_t
|
||||
imgFrame::GetStride() const
|
||||
{
|
||||
if (mImageSurface) {
|
||||
return mImageSurface->Stride();
|
||||
}
|
||||
|
||||
return VolatileSurfaceStride(mSize, mFormat);
|
||||
}
|
||||
|
||||
SurfaceFormat imgFrame::GetFormat() const
|
||||
{
|
||||
return mFormat;
|
||||
@ -665,6 +675,21 @@ imgFrame::GetSurface()
|
||||
return CreateLockedSurface(mVBuf, mSize, mFormat);
|
||||
}
|
||||
|
||||
TemporaryRef<DrawTarget>
|
||||
imgFrame::GetDrawTarget()
|
||||
{
|
||||
MOZ_ASSERT(mLockCount >= 1, "Should lock before requesting a DrawTarget");
|
||||
|
||||
uint8_t* data = GetImageData();
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32_t stride = GetStride();
|
||||
return gfxPlatform::GetPlatform()->
|
||||
CreateDrawTargetForData(data, mSize, stride, mFormat);
|
||||
}
|
||||
|
||||
int32_t imgFrame::GetRawTimeout() const
|
||||
{
|
||||
return mTimeout;
|
||||
|
@ -22,13 +22,16 @@ class imgFrame
|
||||
{
|
||||
typedef gfx::Color Color;
|
||||
typedef gfx::DataSourceSurface DataSourceSurface;
|
||||
typedef gfx::DrawTarget DrawTarget;
|
||||
typedef gfx::IntSize IntSize;
|
||||
typedef gfx::SourceSurface SourceSurface;
|
||||
typedef gfx::SurfaceFormat SurfaceFormat;
|
||||
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_TYPENAME(imgFrame)
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(imgFrame)
|
||||
|
||||
imgFrame();
|
||||
~imgFrame();
|
||||
|
||||
nsresult Init(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight, SurfaceFormat aFormat, uint8_t aPaletteDepth = 0);
|
||||
nsresult Optimize();
|
||||
@ -40,6 +43,8 @@ public:
|
||||
nsresult ImageUpdated(const nsIntRect &aUpdateRect);
|
||||
|
||||
nsIntRect GetRect() const;
|
||||
IntSize GetSize() const { return mSize; }
|
||||
int32_t GetStride() const;
|
||||
SurfaceFormat GetFormat() const;
|
||||
bool GetNeedsBackground() const;
|
||||
uint32_t GetImageBytesPerRow() const;
|
||||
@ -72,6 +77,7 @@ public:
|
||||
void SetDiscardable();
|
||||
|
||||
TemporaryRef<SourceSurface> GetSurface();
|
||||
TemporaryRef<DrawTarget> GetDrawTarget();
|
||||
|
||||
Color
|
||||
SinglePixelColor()
|
||||
@ -100,6 +106,8 @@ public:
|
||||
|
||||
private: // methods
|
||||
|
||||
~imgFrame();
|
||||
|
||||
struct SurfaceWithFormat {
|
||||
nsRefPtr<gfxDrawable> mDrawable;
|
||||
SurfaceFormat mFormat;
|
||||
@ -180,7 +188,7 @@ private: // data
|
||||
bool Succeeded() { return mSucceeded; }
|
||||
|
||||
private:
|
||||
imgFrame* mFrame;
|
||||
nsRefPtr<imgFrame> mFrame;
|
||||
bool mSucceeded;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user