mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Back out 965fe5b195ab (bug 962670) for leaking
This commit is contained in:
parent
32b0dc613c
commit
b932e52022
@ -26,7 +26,6 @@
|
||||
#include "nsSize.h" // for nsIntSize
|
||||
#include "nsTArray.h" // for nsTArray
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "nsDataHashtable.h"
|
||||
@ -381,7 +380,7 @@ struct RemoteImageData {
|
||||
* updates the shared state to point to the new image and the old image
|
||||
* is immediately released (not true in Normal or Asynchronous modes).
|
||||
*/
|
||||
class ImageContainer : public SupportsWeakPtr<ImageContainer> {
|
||||
class ImageContainer {
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageContainer)
|
||||
public:
|
||||
|
||||
|
@ -922,24 +922,8 @@ RasterImage::GetFrame(uint32_t aWhichFrame,
|
||||
nsIntRect framerect = frame->GetRect();
|
||||
if (framerect.x == 0 && framerect.y == 0 &&
|
||||
framerect.width == mSize.width &&
|
||||
framerect.height == mSize.height) {
|
||||
framerect.height == mSize.height)
|
||||
frame->GetSurface(getter_AddRefs(framesurf));
|
||||
if (!framesurf && !frame->IsSinglePixel()) {
|
||||
// No reason to be optimized away here - the OS threw out the data
|
||||
if (!(aFlags & FLAG_SYNC_DECODE))
|
||||
return nullptr;
|
||||
|
||||
// Unconditionally call ForceDiscard() here because GetSurface can only
|
||||
// return null when we can forcibly discard and redecode. There are two
|
||||
// other cases where GetSurface() can return null - when it is a single
|
||||
// pixel image, which we check before getting here, or when this is an
|
||||
// indexed image, in which case we shouldn't be in this function at all.
|
||||
// The only remaining possibility is that SetDiscardable() was called on
|
||||
// this imgFrame, which implies the image can be redecoded.
|
||||
ForceDiscard();
|
||||
return GetFrame(aWhichFrame, aFlags);
|
||||
}
|
||||
}
|
||||
|
||||
// The image doesn't have a surface because it's been optimized away. Create
|
||||
// one.
|
||||
@ -963,15 +947,7 @@ RasterImage::GetCurrentImage()
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> imageSurface = GetFrame(FRAME_CURRENT, FLAG_NONE);
|
||||
if (!imageSurface) {
|
||||
// The OS threw out some or all of our buffer. Start decoding again.
|
||||
// GetFrame will only return null in the case that the image was
|
||||
// discarded. We already checked that the image is decoded, so other
|
||||
// error paths are not possible.
|
||||
ForceDiscard();
|
||||
RequestDecodeCore(ASYNCHRONOUS);
|
||||
return nullptr;
|
||||
}
|
||||
NS_ENSURE_TRUE(imageSurface, nullptr);
|
||||
|
||||
if (!mImageContainer) {
|
||||
mImageContainer = LayerManager::CreateImageContainer();
|
||||
@ -1005,10 +981,6 @@ RasterImage::GetImageContainer(LayerManager* aManager, ImageContainer **_retval)
|
||||
mStatusTracker->OnUnlockedDraw();
|
||||
}
|
||||
|
||||
if (!mImageContainer) {
|
||||
mImageContainer = mImageContainerCache;
|
||||
}
|
||||
|
||||
if (mImageContainer) {
|
||||
*_retval = mImageContainer;
|
||||
NS_ADDREF(*_retval);
|
||||
@ -1023,13 +995,6 @@ RasterImage::GetImageContainer(LayerManager* aManager, ImageContainer **_retval)
|
||||
|
||||
*_retval = mImageContainer;
|
||||
NS_ADDREF(*_retval);
|
||||
// We only need to be careful about holding on to the image when it is
|
||||
// discardable by the OS.
|
||||
if (CanForciblyDiscardAndRedecode()) {
|
||||
mImageContainerCache = mImageContainer->asWeakPtr();
|
||||
mImageContainer = nullptr;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1427,12 +1392,6 @@ RasterImage::DecodingComplete()
|
||||
// We don't optimize the frame for multipart images because we reuse
|
||||
// the frame.
|
||||
if ((GetNumFrames() == 1) && !mMultipart) {
|
||||
// CanForciblyDiscard is used instead of CanForciblyDiscardAndRedecode
|
||||
// because we know decoding is complete at this point and this is not
|
||||
// an animation
|
||||
if (DiscardingEnabled() && CanForciblyDiscard()) {
|
||||
mFrameBlender.RawGetFrame(0)->SetDiscardable();
|
||||
}
|
||||
rv = mFrameBlender.RawGetFrame(0)->Optimize();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
@ -2134,6 +2093,13 @@ RasterImage::ShutdownDecoder(eShutdownIntent aIntent)
|
||||
// Figure out what kind of decode we were doing before we get rid of our decoder
|
||||
bool wasSizeDecode = mDecoder->IsSizeDecode();
|
||||
|
||||
// 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);
|
||||
curframe->UnlockImageData();
|
||||
}
|
||||
|
||||
// Finalize the decoder
|
||||
// null out mDecoder, _then_ check for errors on the close (otherwise the
|
||||
// error routine might re-invoke ShutdownDecoder)
|
||||
@ -2146,13 +2112,6 @@ RasterImage::ShutdownDecoder(eShutdownIntent aIntent)
|
||||
mInDecoder = false;
|
||||
mFinishing = false;
|
||||
|
||||
// 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);
|
||||
curframe->UnlockImageData();
|
||||
}
|
||||
|
||||
// Kill off our decode request, if it's pending. (If not, this call is
|
||||
// harmless.)
|
||||
DecodePool::StopDecoding(this);
|
||||
@ -2718,17 +2677,6 @@ RasterImage::Draw(gfxContext *aContext,
|
||||
return NS_OK; // Getting the frame (above) touches the image and kicks off decoding
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> surf;
|
||||
if (!frame->IsSinglePixel()) {
|
||||
frame->GetSurface(getter_AddRefs(surf));
|
||||
if (!surf) {
|
||||
// The OS threw out some or all of our buffer. Start decoding again.
|
||||
ForceDiscard();
|
||||
WantDecodedFrames();
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
DrawWithPreDownscaleIfNeeded(frame, aContext, aFilter, aUserSpaceToImageSpace, aFill, aSubimage, aFlags);
|
||||
|
||||
if (mDecoded && !mDrawStartTime.IsNull()) {
|
||||
|
@ -659,9 +659,6 @@ private: // data
|
||||
// Cached value for GetImageContainer.
|
||||
nsRefPtr<mozilla::layers::ImageContainer> mImageContainer;
|
||||
|
||||
// If not cached in mImageContainer, this might have our image container
|
||||
WeakPtr<mozilla::layers::ImageContainer> mImageContainerCache;
|
||||
|
||||
#ifdef DEBUG
|
||||
uint32_t mFramesNotified;
|
||||
#endif
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "gfx2DGlue.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "gfxAlphaRecovery.h"
|
||||
|
||||
static bool gDisableOptimize = false;
|
||||
|
||||
@ -36,48 +35,6 @@ using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::image;
|
||||
|
||||
static cairo_user_data_key_t kVolatileBuffer;
|
||||
|
||||
static void
|
||||
VolatileBufferRelease(void *vbuf)
|
||||
{
|
||||
delete static_cast<VolatileBufferPtr<unsigned char>*>(vbuf);
|
||||
}
|
||||
|
||||
gfxImageSurface *
|
||||
LockedImageSurface::CreateSurface(VolatileBuffer *vbuf,
|
||||
const gfxIntSize& size,
|
||||
gfxImageFormat format)
|
||||
{
|
||||
VolatileBufferPtr<unsigned char> *vbufptr =
|
||||
new VolatileBufferPtr<unsigned char>(vbuf);
|
||||
MOZ_ASSERT(!vbufptr->WasBufferPurged(), "Expected image data!");
|
||||
|
||||
long stride = gfxImageSurface::ComputeStride(size, format);
|
||||
gfxImageSurface *img = new gfxImageSurface(*vbufptr, size, stride, format);
|
||||
if (!img || img->CairoStatus()) {
|
||||
delete img;
|
||||
delete vbufptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
img->SetData(&kVolatileBuffer, vbufptr, VolatileBufferRelease);
|
||||
return img;
|
||||
}
|
||||
|
||||
TemporaryRef<VolatileBuffer>
|
||||
LockedImageSurface::AllocateBuffer(const gfxIntSize& size,
|
||||
gfxImageFormat format)
|
||||
{
|
||||
long stride = gfxImageSurface::ComputeStride(size, format);
|
||||
RefPtr<VolatileBuffer> buf = new VolatileBuffer();
|
||||
if (buf->Init(stride * size.height,
|
||||
1 << gfxAlphaRecovery::GoodAlignmentLog2()))
|
||||
return buf;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Returns true if an image of aWidth x aHeight is allowed and legal.
|
||||
static bool AllowedImageSize(int32_t aWidth, int32_t aHeight)
|
||||
{
|
||||
@ -151,7 +108,6 @@ imgFrame::imgFrame() :
|
||||
mFormatChanged(false),
|
||||
mCompositingFailed(false),
|
||||
mNonPremult(false),
|
||||
mDiscardable(false),
|
||||
mInformedDiscardTracker(false),
|
||||
mDirty(false)
|
||||
{
|
||||
@ -218,17 +174,12 @@ nsresult imgFrame::Init(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight,
|
||||
}
|
||||
#endif
|
||||
|
||||
// For other platforms, space for the image surface is first allocated in
|
||||
// a volatile buffer and then wrapped by a LockedImageSurface.
|
||||
// This branch is also used on Windows if we're not using device surfaces
|
||||
// or if we couldn't create one.
|
||||
if (!mImageSurface) {
|
||||
mVBuf = LockedImageSurface::AllocateBuffer(mSize, mFormat);
|
||||
if (!mVBuf) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
mImageSurface = LockedImageSurface::CreateSurface(mVBuf, mSize, mFormat);
|
||||
}
|
||||
// For other platforms we create the image surface first and then
|
||||
// possibly wrap it in a device surface. This branch is also used
|
||||
// on Windows if we're not using device surfaces or if we couldn't
|
||||
// create one.
|
||||
if (!mImageSurface)
|
||||
mImageSurface = new gfxImageSurface(gfxIntSize(mSize.width, mSize.height), mFormat);
|
||||
|
||||
if (!mImageSurface || mImageSurface->CairoStatus()) {
|
||||
mImageSurface = nullptr;
|
||||
@ -300,7 +251,6 @@ nsresult imgFrame::Optimize()
|
||||
mSinglePixel = true;
|
||||
|
||||
// blow away the older surfaces (if they exist), to release their memory
|
||||
mVBuf = nullptr;
|
||||
mImageSurface = nullptr;
|
||||
mOptSurface = nullptr;
|
||||
#ifdef USE_WIN_SURFACE
|
||||
@ -350,7 +300,6 @@ nsresult imgFrame::Optimize()
|
||||
mOptSurface = gfxPlatform::GetPlatform()->OptimizeImage(mImageSurface, mFormat);
|
||||
|
||||
if (mOptSurface) {
|
||||
mVBuf = nullptr;
|
||||
mImageSurface = nullptr;
|
||||
#ifdef USE_WIN_SURFACE
|
||||
mWinSurface = nullptr;
|
||||
@ -534,13 +483,10 @@ uint32_t imgFrame::GetImageBytesPerRow() const
|
||||
if (mImageSurface)
|
||||
return mImageSurface->Stride();
|
||||
|
||||
if (mVBuf)
|
||||
return gfxImageSurface::ComputeStride(mSize, mFormat);
|
||||
|
||||
if (mPaletteDepth)
|
||||
return mSize.width;
|
||||
|
||||
NS_ERROR("GetImageBytesPerRow called with mImageSurface == null, mVBuf == null and mPaletteDepth == 0");
|
||||
NS_ERROR("GetImageBytesPerRow called with mImageSurface == null and mPaletteDepth == 0");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -623,42 +569,28 @@ nsresult imgFrame::LockImageData()
|
||||
if (mPalettedImageData)
|
||||
return NS_OK;
|
||||
|
||||
if (!mImageSurface) {
|
||||
if (mVBuf) {
|
||||
VolatileBufferPtr<uint8_t> ref(mVBuf);
|
||||
if (ref.WasBufferPurged())
|
||||
return NS_ERROR_FAILURE;
|
||||
if ((mOptSurface || mSinglePixel) && !mImageSurface) {
|
||||
// Recover the pixels
|
||||
mImageSurface = new gfxImageSurface(gfxIntSize(mSize.width, mSize.height),
|
||||
gfxImageFormat::ARGB32);
|
||||
if (!mImageSurface || mImageSurface->CairoStatus())
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mImageSurface = LockedImageSurface::CreateSurface(mVBuf, mSize, mFormat);
|
||||
if (!mImageSurface || mImageSurface->CairoStatus())
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
} else if (mOptSurface || mSinglePixel) {
|
||||
// Recover the pixels
|
||||
mVBuf = LockedImageSurface::AllocateBuffer(mSize, mFormat);
|
||||
if (!mVBuf) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
gfxContext context(mImageSurface);
|
||||
context.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
if (mSinglePixel)
|
||||
context.SetDeviceColor(mSinglePixelColor);
|
||||
else
|
||||
context.SetSource(mOptSurface);
|
||||
context.Paint();
|
||||
|
||||
mImageSurface = LockedImageSurface::CreateSurface(mVBuf, mSize, mFormat);
|
||||
if (!mImageSurface || mImageSurface->CairoStatus())
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
gfxContext context(mImageSurface);
|
||||
context.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
if (mSinglePixel)
|
||||
context.SetDeviceColor(mSinglePixelColor);
|
||||
else
|
||||
context.SetSource(mOptSurface);
|
||||
context.Paint();
|
||||
|
||||
mOptSurface = nullptr;
|
||||
mOptSurface = nullptr;
|
||||
#ifdef USE_WIN_SURFACE
|
||||
mWinSurface = nullptr;
|
||||
mWinSurface = nullptr;
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
mQuartzSurface = nullptr;
|
||||
mQuartzSurface = nullptr;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// We might write to the bits in this image surface, so we need to make the
|
||||
@ -671,12 +603,6 @@ nsresult imgFrame::LockImageData()
|
||||
mWinSurface->Flush();
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (!mQuartzSurface && !ShouldUseImageSurfaces()) {
|
||||
mQuartzSurface = new gfxQuartzImageSurface(mImageSurface);
|
||||
}
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -732,13 +658,6 @@ nsresult imgFrame::UnlockImageData()
|
||||
mQuartzSurface->Flush();
|
||||
#endif
|
||||
|
||||
if (mVBuf && mDiscardable) {
|
||||
mImageSurface = nullptr;
|
||||
#ifdef XP_MACOSX
|
||||
mQuartzSurface = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -778,12 +697,6 @@ void imgFrame::ApplyDirtToSurfaces()
|
||||
}
|
||||
}
|
||||
|
||||
void imgFrame::SetDiscardable()
|
||||
{
|
||||
MOZ_ASSERT(mLockCount, "Expected to be locked when SetDiscardable is called");
|
||||
mDiscardable = true;
|
||||
}
|
||||
|
||||
int32_t imgFrame::GetRawTimeout() const
|
||||
{
|
||||
return mTimeout;
|
||||
@ -882,8 +795,8 @@ imgFrame::SizeOfExcludingThisWithComputedFallbackIfHeap(gfxMemoryLocation aLocat
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
if (mQuartzSurface && aLocation == gfxMemoryLocation::IN_PROCESS_HEAP) {
|
||||
n += aMallocSizeOf(mQuartzSurface);
|
||||
}
|
||||
n += mSize.width * mSize.height * 4;
|
||||
} else
|
||||
#endif
|
||||
if (mImageSurface && aLocation == mImageSurface->GetMemoryLocation()) {
|
||||
size_t n2 = 0;
|
||||
@ -896,11 +809,6 @@ imgFrame::SizeOfExcludingThisWithComputedFallbackIfHeap(gfxMemoryLocation aLocat
|
||||
n += n2;
|
||||
}
|
||||
|
||||
if (mVBuf && aLocation == gfxMemoryLocation::IN_PROCESS_HEAP) {
|
||||
n += aMallocSizeOf(mVBuf);
|
||||
n += mVBuf->HeapSizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
if (mOptSurface && aLocation == mOptSurface->GetMemoryLocation()) {
|
||||
size_t n2 = 0;
|
||||
if (aLocation == gfxMemoryLocation::IN_PROCESS_HEAP &&
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/VolatileBuffer.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsPoint.h"
|
||||
#include "nsSize.h"
|
||||
@ -25,21 +24,6 @@
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxColor.h"
|
||||
|
||||
/*
|
||||
* This creates a gfxImageSurface which will unlock the buffer on destruction
|
||||
*/
|
||||
|
||||
class LockedImageSurface
|
||||
{
|
||||
public:
|
||||
static gfxImageSurface *
|
||||
CreateSurface(mozilla::VolatileBuffer *vbuf,
|
||||
const gfxIntSize& size,
|
||||
gfxImageFormat format);
|
||||
static mozilla::TemporaryRef<mozilla::VolatileBuffer>
|
||||
AllocateBuffer(const gfxIntSize& size, gfxImageFormat format);
|
||||
};
|
||||
|
||||
class imgFrame
|
||||
{
|
||||
public:
|
||||
@ -88,16 +72,14 @@ public:
|
||||
nsresult UnlockImageData();
|
||||
void ApplyDirtToSurfaces();
|
||||
|
||||
void SetDiscardable();
|
||||
|
||||
nsresult GetSurface(gfxASurface **aSurface)
|
||||
nsresult GetSurface(gfxASurface **aSurface) const
|
||||
{
|
||||
*aSurface = ThebesSurface();
|
||||
NS_IF_ADDREF(*aSurface);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult GetPattern(gfxPattern **aPattern)
|
||||
nsresult GetPattern(gfxPattern **aPattern) const
|
||||
{
|
||||
if (mSinglePixel)
|
||||
*aPattern = new gfxPattern(mSinglePixelColor);
|
||||
@ -107,12 +89,7 @@ public:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool IsSinglePixel()
|
||||
{
|
||||
return mSinglePixel;
|
||||
}
|
||||
|
||||
gfxASurface* ThebesSurface()
|
||||
gfxASurface* ThebesSurface() const
|
||||
{
|
||||
if (mOptSurface)
|
||||
return mOptSurface;
|
||||
@ -123,27 +100,7 @@ public:
|
||||
if (mQuartzSurface)
|
||||
return mQuartzSurface;
|
||||
#endif
|
||||
if (mImageSurface)
|
||||
return mImageSurface;
|
||||
if (mVBuf) {
|
||||
mozilla::VolatileBufferPtr<uint8_t> ref(mVBuf);
|
||||
if (ref.WasBufferPurged())
|
||||
return nullptr;
|
||||
|
||||
gfxImageSurface *sur =
|
||||
LockedImageSurface::CreateSurface(mVBuf, mSize, mFormat);
|
||||
#if defined(XP_MACOSX)
|
||||
return new gfxQuartzImageSurface(sur);
|
||||
#else
|
||||
return sur;
|
||||
#endif
|
||||
}
|
||||
// We can return null here if we're single pixel optimized
|
||||
// or a paletted image. However, one has to check for paletted
|
||||
// image data first before attempting to get a surface, so
|
||||
// this is only valid for single pixel optimized images
|
||||
MOZ_ASSERT(mSinglePixel, "No image surface and not a single pixel!");
|
||||
return nullptr;
|
||||
return mImageSurface;
|
||||
}
|
||||
|
||||
size_t SizeOfExcludingThisWithComputedFallbackIfHeap(
|
||||
@ -210,8 +167,6 @@ private: // data
|
||||
/** Indicates how many readers currently have locked this frame */
|
||||
int32_t mLockCount;
|
||||
|
||||
mozilla::RefPtr<mozilla::VolatileBuffer> mVBuf;
|
||||
|
||||
gfxImageFormat mFormat;
|
||||
uint8_t mPaletteDepth;
|
||||
int8_t mBlendMethod;
|
||||
@ -219,7 +174,6 @@ private: // data
|
||||
bool mFormatChanged;
|
||||
bool mCompositingFailed;
|
||||
bool mNonPremult;
|
||||
bool mDiscardable;
|
||||
|
||||
/** Have we called DiscardTracker::InformAllocation()? */
|
||||
bool mInformedDiscardTracker;
|
||||
|
Loading…
Reference in New Issue
Block a user