Bug 925448 - Stop CGImageRef external data being deleted prematurely. r=bgirard,bas

This commit is contained in:
Steven Michaud 2013-11-26 12:41:32 -06:00
parent 0fbc72736a
commit 2b53cc9d58
2 changed files with 20 additions and 20 deletions

View File

@ -278,21 +278,8 @@ void SourceSurfaceCGBitmapContext::EnsureImage() const
// memcpy when the bitmap context is modified gives us more predictable
// performance characteristics.
if (!mImage) {
void *info;
if (mCg) {
// if we have an mCg than it owns the data
// and we don't want to tranfer ownership
// to the CGDataProviderCreateWithData
info = nullptr;
} else {
// otherwise we transfer ownership to
// the dataProvider
info = mData;
}
if (!mData) abort();
mImage = CreateCGImage(info, mData, mSize, mStride, mFormat);
mImage = CreateCGImage(nullptr, mData, mSize, mStride, mFormat);
}
}
@ -310,8 +297,8 @@ SourceSurfaceCGBitmapContext::DrawTargetWillChange()
size_t stride = CGBitmapContextGetBytesPerRow(mCg);
size_t height = CGBitmapContextGetHeight(mCg);
//XXX: infalliable malloc?
mData = malloc(stride * height);
mDataHolder.Realloc(stride * height);
mData = mDataHolder;
// copy out the data from the CGBitmapContext
// we'll maintain ownership of mData until
@ -330,10 +317,6 @@ SourceSurfaceCGBitmapContext::DrawTargetWillChange()
SourceSurfaceCGBitmapContext::~SourceSurfaceCGBitmapContext()
{
if (!mImage && !mCg) {
// neither mImage or mCg owns the data
free(mData);
}
if (mImage)
CGImageRelease(mImage);
}

View File

@ -94,6 +94,20 @@ public:
virtual SurfaceType GetType() const { return SURFACE_COREGRAPHICS_CGCONTEXT; }
virtual IntSize GetSize() const;
virtual SurfaceFormat GetFormat() const { return mFormat; }
virtual TemporaryRef<DataSourceSurface> GetDataSurface()
{
// This call to DrawTargetWillChange() is needed to make a local copy of
// the data from mDrawTarget. If we don't do that, the data can end up
// getting deleted before the CGImageRef it belongs to.
//
// Another reason we need a local copy of the data is that the data in
// mDrawTarget could change when someone touches the original DrawTargetCG
// object. But a SourceSurface object should be immutable.
//
// For more information see bug 925448.
DrawTargetWillChange();
return this;
}
CGImageRef GetImage() { EnsureImage(); return mImage; }
@ -119,6 +133,9 @@ private:
// mImage, mCg or SourceSurfaceCGBitmapContext
void *mData;
// The image buffer, if the buffer is owned by this class.
AlignedArray<uint8_t> mDataHolder;
int32_t mStride;
IntSize mSize;
};