зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1079627 (Part 1) - Make image decoders hold a strong reference to their image. r=tn
This commit is contained in:
Родитель
b6d9258843
Коммит
66b57f086b
|
@ -38,7 +38,7 @@ GetBMPLog()
|
|||
#define LINE(row) ((mBIH.height < 0) ? (-mBIH.height - (row)) : ((row) - 1))
|
||||
#define PIXEL_OFFSET(row, col) (LINE(row) * mBIH.width + col)
|
||||
|
||||
nsBMPDecoder::nsBMPDecoder(RasterImage& aImage)
|
||||
nsBMPDecoder::nsBMPDecoder(RasterImage* aImage)
|
||||
: Decoder(aImage)
|
||||
, mPos(0)
|
||||
, mLOH(WIN_V3_HEADER_LENGTH)
|
||||
|
|
|
@ -23,7 +23,7 @@ class nsBMPDecoder : public Decoder
|
|||
{
|
||||
public:
|
||||
|
||||
explicit nsBMPDecoder(RasterImage& aImage);
|
||||
explicit nsBMPDecoder(RasterImage* aImage);
|
||||
~nsBMPDecoder();
|
||||
|
||||
// Specifies whether or not the BMP file will contain alpha data
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace image {
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
// GIF Decoder Implementation
|
||||
|
||||
nsGIFDecoder2::nsGIFDecoder2(RasterImage& aImage)
|
||||
nsGIFDecoder2::nsGIFDecoder2(RasterImage* aImage)
|
||||
: Decoder(aImage)
|
||||
, mCurrentRow(-1)
|
||||
, mLastFlushedRow(-1)
|
||||
|
|
|
@ -23,7 +23,7 @@ class nsGIFDecoder2 : public Decoder
|
|||
{
|
||||
public:
|
||||
|
||||
explicit nsGIFDecoder2(RasterImage& aImage);
|
||||
explicit nsGIFDecoder2(RasterImage* aImage);
|
||||
~nsGIFDecoder2();
|
||||
|
||||
virtual void WriteInternal(const char* aBuffer, uint32_t aCount) MOZ_OVERRIDE;
|
||||
|
|
|
@ -58,7 +58,7 @@ nsICODecoder::GetNumColors()
|
|||
}
|
||||
|
||||
|
||||
nsICODecoder::nsICODecoder(RasterImage& aImage)
|
||||
nsICODecoder::nsICODecoder(RasterImage* aImage)
|
||||
: Decoder(aImage)
|
||||
{
|
||||
mPos = mImageOffset = mCurrIcon = mNumIcons = mBPP = mRowBytes = 0;
|
||||
|
@ -249,7 +249,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
|||
}
|
||||
|
||||
uint16_t colorDepth = 0;
|
||||
nsIntSize prefSize = mImage.GetRequestedResolution();
|
||||
nsIntSize prefSize = mImage->GetRequestedResolution();
|
||||
if (prefSize.width == 0 && prefSize.height == 0) {
|
||||
prefSize.SizeTo(PREFICONSIZE, PREFICONSIZE);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ class nsICODecoder : public Decoder
|
|||
{
|
||||
public:
|
||||
|
||||
explicit nsICODecoder(RasterImage& aImage);
|
||||
explicit nsICODecoder(RasterImage* aImage);
|
||||
virtual ~nsICODecoder();
|
||||
|
||||
// Obtains the width of the icon directory entry
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
namespace mozilla {
|
||||
namespace image {
|
||||
|
||||
nsIconDecoder::nsIconDecoder(RasterImage& aImage)
|
||||
nsIconDecoder::nsIconDecoder(RasterImage* aImage)
|
||||
: Decoder(aImage),
|
||||
mWidth(-1),
|
||||
mHeight(-1),
|
||||
|
|
|
@ -38,7 +38,7 @@ class nsIconDecoder : public Decoder
|
|||
{
|
||||
public:
|
||||
|
||||
explicit nsIconDecoder(RasterImage& aImage);
|
||||
explicit nsIconDecoder(RasterImage* aImage);
|
||||
virtual ~nsIconDecoder();
|
||||
|
||||
virtual void WriteInternal(const char* aBuffer, uint32_t aCount) MOZ_OVERRIDE;
|
||||
|
|
|
@ -84,7 +84,7 @@ METHODDEF(void) my_error_exit (j_common_ptr cinfo);
|
|||
#define MAX_JPEG_MARKER_LENGTH (((uint32_t)1 << 16) - 1)
|
||||
|
||||
|
||||
nsJPEGDecoder::nsJPEGDecoder(RasterImage& aImage,
|
||||
nsJPEGDecoder::nsJPEGDecoder(RasterImage* aImage,
|
||||
Decoder::DecodeStyle aDecodeStyle)
|
||||
: Decoder(aImage)
|
||||
, mDecodeStyle(aDecodeStyle)
|
||||
|
@ -237,7 +237,7 @@ nsJPEGDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
|||
return; // I/O suspension
|
||||
}
|
||||
|
||||
int sampleSize = mImage.GetRequestedSampleSize();
|
||||
int sampleSize = mImage->GetRequestedSampleSize();
|
||||
if (sampleSize > 0) {
|
||||
mInfo.scale_num = 1;
|
||||
mInfo.scale_denom = sampleSize;
|
||||
|
|
|
@ -52,7 +52,7 @@ struct Orientation;
|
|||
class nsJPEGDecoder : public Decoder
|
||||
{
|
||||
public:
|
||||
nsJPEGDecoder(RasterImage& aImage, Decoder::DecodeStyle aDecodeStyle);
|
||||
nsJPEGDecoder(RasterImage* aImage, Decoder::DecodeStyle aDecodeStyle);
|
||||
virtual ~nsJPEGDecoder();
|
||||
|
||||
virtual void InitInternal() MOZ_OVERRIDE;
|
||||
|
|
|
@ -107,7 +107,7 @@ nsPNGDecoder::AnimFrameInfo::AnimFrameInfo(png_structp aPNG, png_infop aInfo)
|
|||
const uint8_t
|
||||
nsPNGDecoder::pngSignatureBytes[] = { 137, 80, 78, 71, 13, 10, 26, 10 };
|
||||
|
||||
nsPNGDecoder::nsPNGDecoder(RasterImage& aImage)
|
||||
nsPNGDecoder::nsPNGDecoder(RasterImage* aImage)
|
||||
: Decoder(aImage),
|
||||
mPNG(nullptr), mInfo(nullptr),
|
||||
mCMSLine(nullptr), interlacebuf(nullptr),
|
||||
|
|
|
@ -24,7 +24,7 @@ class RasterImage;
|
|||
class nsPNGDecoder : public Decoder
|
||||
{
|
||||
public:
|
||||
explicit nsPNGDecoder(RasterImage& aImage);
|
||||
explicit nsPNGDecoder(RasterImage* aImage);
|
||||
virtual ~nsPNGDecoder();
|
||||
|
||||
virtual void InitInternal() MOZ_OVERRIDE;
|
||||
|
|
|
@ -20,7 +20,7 @@ using mozilla::gfx::SurfaceFormat;
|
|||
namespace mozilla {
|
||||
namespace image {
|
||||
|
||||
Decoder::Decoder(RasterImage &aImage)
|
||||
Decoder::Decoder(RasterImage* aImage)
|
||||
: mImage(aImage)
|
||||
, mProgress(NoProgress)
|
||||
, mImageData(nullptr)
|
||||
|
@ -48,6 +48,21 @@ Decoder::~Decoder()
|
|||
MOZ_ASSERT(mInvalidRect.IsEmpty(),
|
||||
"Destroying Decoder without taking all its invalidations");
|
||||
mInitialized = false;
|
||||
|
||||
if (!NS_IsMainThread()) {
|
||||
// Dispatch mImage to main thread to prevent it from being destructed by the
|
||||
// decode thread.
|
||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
||||
NS_WARN_IF_FALSE(mainThread, "Couldn't get the main thread!");
|
||||
if (mainThread) {
|
||||
// Handle ambiguous nsISupports inheritance.
|
||||
RasterImage* rawImg = nullptr;
|
||||
mImage.swap(rawImg);
|
||||
DebugOnly<nsresult> rv =
|
||||
NS_ProxyRelease(mainThread, NS_ISUPPORTS_CAST(ImageResource*, rawImg));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed to proxy release to main thread");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -181,13 +196,13 @@ Decoder::Finish(ShutdownReason aReason)
|
|||
|
||||
if (consoleService && errorObject && !HasDecoderError()) {
|
||||
nsAutoString msg(NS_LITERAL_STRING("Image corrupt or truncated: ") +
|
||||
NS_ConvertUTF8toUTF16(mImage.GetURIString()));
|
||||
NS_ConvertUTF8toUTF16(mImage->GetURIString()));
|
||||
|
||||
if (NS_SUCCEEDED(errorObject->InitWithWindowID(
|
||||
msg,
|
||||
NS_ConvertUTF8toUTF16(mImage.GetURIString()),
|
||||
NS_ConvertUTF8toUTF16(mImage->GetURIString()),
|
||||
EmptyString(), 0, 0, nsIScriptError::errorFlag,
|
||||
"Image", mImage.InnerWindowID()
|
||||
"Image", mImage->InnerWindowID()
|
||||
))) {
|
||||
consoleService->LogMessage(errorObject);
|
||||
}
|
||||
|
@ -218,11 +233,11 @@ Decoder::Finish(ShutdownReason aReason)
|
|||
|
||||
// Set image metadata before calling DecodingComplete, because
|
||||
// DecodingComplete calls Optimize().
|
||||
mImageMetadata.SetOnImage(&mImage);
|
||||
mImageMetadata.SetOnImage(mImage);
|
||||
|
||||
if (mDecodeDone) {
|
||||
MOZ_ASSERT(HasError() || mCurrentFrame, "Should have an error or a frame");
|
||||
mImage.DecodingComplete(mCurrentFrame.get());
|
||||
mImage->DecodingComplete(mCurrentFrame.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -369,7 +384,7 @@ Decoder::InternalAddFrame(uint32_t aFrameNum,
|
|||
}
|
||||
|
||||
InsertOutcome outcome =
|
||||
SurfaceCache::Insert(frame, ImageKey(&mImage),
|
||||
SurfaceCache::Insert(frame, ImageKey(mImage.get()),
|
||||
RasterSurfaceKey(imageSize.ToIntSize(),
|
||||
aDecodeFlags,
|
||||
aFrameNum),
|
||||
|
@ -405,7 +420,7 @@ Decoder::InternalAddFrame(uint32_t aFrameNum,
|
|||
}
|
||||
|
||||
mFrameCount++;
|
||||
mImage.OnAddedFrame(mFrameCount, refreshArea);
|
||||
mImage->OnAddedFrame(mFrameCount, refreshArea);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
@ -416,9 +431,9 @@ Decoder::SetSizeOnImage()
|
|||
MOZ_ASSERT(mImageMetadata.HasSize(), "Should have size");
|
||||
MOZ_ASSERT(mImageMetadata.HasOrientation(), "Should have orientation");
|
||||
|
||||
mImage.SetSize(mImageMetadata.GetWidth(),
|
||||
mImageMetadata.GetHeight(),
|
||||
mImageMetadata.GetOrientation());
|
||||
mImage->SetSize(mImageMetadata.GetWidth(),
|
||||
mImageMetadata.GetHeight(),
|
||||
mImageMetadata.GetOrientation());
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -22,7 +22,7 @@ class Decoder
|
|||
{
|
||||
public:
|
||||
|
||||
explicit Decoder(RasterImage& aImage);
|
||||
explicit Decoder(RasterImage* aImage);
|
||||
|
||||
/**
|
||||
* Initialize an image decoder. Decoders may not be re-initialized.
|
||||
|
@ -187,6 +187,11 @@ public:
|
|||
|
||||
ImageMetadata& GetImageMetadata() { return mImageMetadata; }
|
||||
|
||||
/**
|
||||
* Returns a weak pointer to the image associated with this decoder.
|
||||
*/
|
||||
RasterImage* GetImage() const { MOZ_ASSERT(mImage); return mImage.get(); }
|
||||
|
||||
// Tell the decoder infrastructure to allocate a frame. By default, frame 0
|
||||
// is created as an ARGB frame with no offset and with size width * height.
|
||||
// If decoders need something different, they must ask for it.
|
||||
|
@ -312,7 +317,7 @@ protected:
|
|||
* Member variables.
|
||||
*
|
||||
*/
|
||||
RasterImage &mImage;
|
||||
nsRefPtr<RasterImage> mImage;
|
||||
RawAccessFrameRef mCurrentFrame;
|
||||
ImageMetadata mImageMetadata;
|
||||
nsIntRect mInvalidRect; // Tracks an invalidation region in the current frame.
|
||||
|
|
|
@ -1458,32 +1458,32 @@ RasterImage::InitDecoder(bool aDoSizeDecode)
|
|||
eDecoderType type = GetDecoderType(mSourceDataMimeType.get());
|
||||
CONTAINER_ENSURE_TRUE(type != eDecoderType_unknown, NS_IMAGELIB_ERROR_NO_DECODER);
|
||||
|
||||
// Instantiate the appropriate decoder
|
||||
// Instantiate the appropriate decoder.
|
||||
switch (type) {
|
||||
case eDecoderType_png:
|
||||
mDecoder = new nsPNGDecoder(*this);
|
||||
mDecoder = new nsPNGDecoder(this);
|
||||
break;
|
||||
case eDecoderType_gif:
|
||||
mDecoder = new nsGIFDecoder2(*this);
|
||||
mDecoder = new nsGIFDecoder2(this);
|
||||
break;
|
||||
case eDecoderType_jpeg:
|
||||
// If we have all the data we don't want to waste cpu time doing
|
||||
// a progressive decode
|
||||
mDecoder = new nsJPEGDecoder(*this,
|
||||
// a progressive decode.
|
||||
mDecoder = new nsJPEGDecoder(this,
|
||||
mHasBeenDecoded ? Decoder::SEQUENTIAL :
|
||||
Decoder::PROGRESSIVE);
|
||||
break;
|
||||
case eDecoderType_bmp:
|
||||
mDecoder = new nsBMPDecoder(*this);
|
||||
mDecoder = new nsBMPDecoder(this);
|
||||
break;
|
||||
case eDecoderType_ico:
|
||||
mDecoder = new nsICODecoder(*this);
|
||||
mDecoder = new nsICODecoder(this);
|
||||
break;
|
||||
case eDecoderType_icon:
|
||||
mDecoder = new nsIconDecoder(*this);
|
||||
mDecoder = new nsIconDecoder(this);
|
||||
break;
|
||||
default:
|
||||
NS_ABORT_IF_FALSE(0, "Shouldn't get here!");
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown decoder type");
|
||||
}
|
||||
|
||||
// Initialize the decoder
|
||||
|
|
Загрузка…
Ссылка в новой задаче