Bug 717872 - Make FrameSequences be refcounted, and store a RefPtr to FrameSequence on FrameBlender. r=seth

This makes it possible for us to share FrameSequences by refcounting them. We
don't do anything smart when inserting/removing/swapping frames, but we do
carefully handle the "discard" case (by just reallocating a new
FrameSequence).

Note that, currently, nothing actually *shares* FrameSequences.

--HG--
extra : rebase_source : 9facdf8930297888f2ee77e0816543c6ad703f80
This commit is contained in:
Joe Drew 2013-07-09 14:53:12 -04:00
Родитель 171c658f3e
Коммит 31f323b1d6
3 изменённых файлов: 43 добавлений и 20 удалений

Просмотреть файл

@ -16,27 +16,37 @@ using namespace mozilla::image;
namespace mozilla {
namespace image {
FrameBlender::FrameBlender()
: mAnim(nullptr)
{}
FrameBlender::FrameBlender(FrameSequence* aSequenceToUse /* = nullptr */)
: mFrames(aSequenceToUse)
, mAnim(nullptr)
{
if (!mFrames) {
mFrames = new FrameSequence();
}
}
FrameBlender::~FrameBlender()
{
ClearFrames();
delete mAnim;
}
already_AddRefed<FrameSequence>
FrameBlender::GetFrameSequence()
{
nsRefPtr<FrameSequence> seq(mFrames);
return seq.forget();
}
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);
}
if (mAnim->lastCompositedFrameIndex == int32_t(framenum))
return mAnim->compositingFrame;
return mFrames.GetFrame(framenum);
return mFrames->GetFrame(framenum);
}
imgFrame*
@ -44,16 +54,16 @@ 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);
}
return mFrames.GetFrame(framenum);
return mFrames->GetFrame(framenum);
}
uint32_t
FrameBlender::GetNumFrames() const
{
return mFrames.GetNumFrames();
return mFrames->GetNumFrames();
}
void
@ -61,20 +71,21 @@ FrameBlender::RemoveFrame(uint32_t framenum)
{
NS_ABORT_IF_FALSE(framenum < GetNumFrames(), "Deleting invalid frame!");
mFrames.RemoveFrame(framenum);
mFrames->RemoveFrame(framenum);
}
void
FrameBlender::ClearFrames()
{
mFrames.ClearFrames();
// Forget our old frame sequence, letting whoever else has it deal with it.
mFrames = new FrameSequence();
}
void
FrameBlender::InsertFrame(uint32_t framenum, imgFrame* aFrame)
{
NS_ABORT_IF_FALSE(framenum <= GetNumFrames(), "Inserting invalid frame!");
mFrames.InsertFrame(framenum, aFrame);
mFrames->InsertFrame(framenum, aFrame);
if (GetNumFrames() > 1) {
EnsureAnimExists();
}
@ -91,9 +102,9 @@ FrameBlender::SwapFrame(uint32_t framenum, imgFrame* aFrame)
if (mAnim && mAnim->lastCompositedFrameIndex == int32_t(framenum)) {
ret = mAnim->compositingFrame.Forget();
mAnim->lastCompositedFrameIndex = -1;
nsAutoPtr<imgFrame> toDelete(mFrames.SwapFrame(framenum, aFrame));
nsAutoPtr<imgFrame> toDelete(mFrames->SwapFrame(framenum, aFrame));
} else {
ret = mFrames.SwapFrame(framenum, aFrame);
ret = mFrames->SwapFrame(framenum, aFrame);
}
return ret;
@ -124,8 +135,8 @@ FrameBlender::DoBlend(nsIntRect* aDirtyRect,
return false;
}
const FrameDataPair& prevFrame = mFrames.GetFrame(aPrevFrameIndex);
const FrameDataPair& nextFrame = mFrames.GetFrame(aNextFrameIndex);
const FrameDataPair& prevFrame = mFrames->GetFrame(aPrevFrameIndex);
const FrameDataPair& nextFrame = mFrames->GetFrame(aNextFrameIndex);
if (!prevFrame.HasFrameData() || !nextFrame.HasFrameData()) {
return false;
}
@ -541,7 +552,7 @@ size_t
FrameBlender::SizeOfDecodedWithComputedFallbackIfHeap(gfxASurface::MemoryLocation aLocation,
MallocSizeOf aMallocSizeOf) const
{
size_t n = mFrames.SizeOfDecodedWithComputedFallbackIfHeap(aLocation, aMallocSizeOf);
size_t n = mFrames->SizeOfDecodedWithComputedFallbackIfHeap(aLocation, aMallocSizeOf);
if (mAnim) {
if (mAnim->compositingFrame) {

Просмотреть файл

@ -12,6 +12,8 @@
#include "gfxASurface.h"
#include "imgFrame.h"
#include "FrameSequence.h"
#include "nsCOMPtr.h"
#include "nsISupportsImpl.h"
namespace mozilla {
namespace image {
@ -26,12 +28,19 @@ class FrameBlender
{
public:
FrameBlender();
/**
* Create a new FrameBlender with a given frame sequence.
*
* If aSequenceToUse is not specified, it will be allocated automatically.
*/
FrameBlender(FrameSequence* aSequenceToUse = nullptr);
~FrameBlender();
bool DoBlend(nsIntRect* aDirtyRect, uint32_t aPrevFrameIndex,
uint32_t aNextFrameIndex);
already_AddRefed<FrameSequence> GetFrameSequence();
/**
* Get the @aIndex-th frame, including (if applicable) any results of
* blending.
@ -158,7 +167,7 @@ private:
private: // data
//! All the frames of the image
FrameSequence mFrames;
nsRefPtr<FrameSequence> mFrames;
nsIntSize mSize;
Anim* mAnim;
};

Просмотреть файл

@ -11,6 +11,7 @@
#include "mozilla/MemoryReporting.h"
#include "gfxASurface.h"
#include "imgFrame.h"
#include "nsISupportsImpl.h"
namespace mozilla {
namespace image {
@ -142,6 +143,8 @@ public:
~FrameSequence();
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FrameSequence)
/**
* Get the read-only (frame, data) pair at index aIndex.
*/