mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 16:55:40 +00:00
Bug 1312148 - report memory allocation while creating ImageBitmap; r=mtseng,smaug
Creating ImageBitmap from the following sources includes allocating new memory: (1) from ImageData. (2) from Blob. (3) from HTMLCanvasElement. (4) from CanvasRenderingContext2D. (5) from Structured-clone. (6) from Transferring. (7) from OffscreenCanvas. (8) from ArrayBuffer/TypedArray. We need to report to DOM so that the GC would be triggered appropriately. MozReview-Commit-ID: 7rvNsjVNqpz --HG-- extra : rebase_source : 25760f91bd71fe2150fa3ae37dfc1fb8b53c15a4
This commit is contained in:
parent
6acb5b36ed
commit
de99dd7b42
@ -34,6 +34,19 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ImageBitmap)
|
|||||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||||
NS_INTERFACE_MAP_END
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This helper function is used to notify DOM that aBytes memory is allocated
|
||||||
|
* here so that we could trigger GC appropriately.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
RegisterAllocation(nsIGlobalObject* aGlobal, size_t aBytes)
|
||||||
|
{
|
||||||
|
AutoJSAPI jsapi;
|
||||||
|
if (jsapi.Init(aGlobal)) {
|
||||||
|
JS_updateMallocCounter(jsapi.cx(), aBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If either aRect.width or aRect.height are negative, then return a new IntRect
|
* If either aRect.width or aRect.height are negative, then return a new IntRect
|
||||||
* which represents the same rectangle as the aRect does but with positive width
|
* which represents the same rectangle as the aRect does but with positive width
|
||||||
@ -707,6 +720,9 @@ ImageBitmap::CreateFromCloneData(nsIGlobalObject* aGlobal,
|
|||||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data,
|
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data,
|
||||||
aData->mIsPremultipliedAlpha);
|
aData->mIsPremultipliedAlpha);
|
||||||
|
|
||||||
|
// Report memory allocation.
|
||||||
|
RegisterAllocation(aGlobal, ret->mDataWrapper->GetBufferLength());
|
||||||
|
|
||||||
ret->mIsCroppingAreaOutSideOfSourceImage =
|
ret->mIsCroppingAreaOutSideOfSourceImage =
|
||||||
aData->mIsCroppingAreaOutSideOfSourceImage;
|
aData->mIsCroppingAreaOutSideOfSourceImage;
|
||||||
|
|
||||||
@ -741,6 +757,10 @@ ImageBitmap::CreateFromOffscreenCanvas(nsIGlobalObject* aGlobal,
|
|||||||
CreateImageFromSurface(surface);
|
CreateImageFromSurface(surface);
|
||||||
|
|
||||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
|
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
|
||||||
|
|
||||||
|
// Report memory allocation.
|
||||||
|
RegisterAllocation(aGlobal, ret->mDataWrapper->GetBufferLength());
|
||||||
|
|
||||||
return ret.forget();
|
return ret.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -865,6 +885,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvas
|
|||||||
// If the HTMLCanvasElement's rendering context is WebGL, then the snapshot
|
// If the HTMLCanvasElement's rendering context is WebGL, then the snapshot
|
||||||
// we got from the HTMLCanvasElement is a DataSourceSurface which is a copy
|
// we got from the HTMLCanvasElement is a DataSourceSurface which is a copy
|
||||||
// of the rendering context. We handle cropping in this case.
|
// of the rendering context. We handle cropping in this case.
|
||||||
|
bool needToReportMemoryAllocation = false;
|
||||||
if ((aCanvasEl.GetCurrentContextType() == CanvasContextType::WebGL1 ||
|
if ((aCanvasEl.GetCurrentContextType() == CanvasContextType::WebGL1 ||
|
||||||
aCanvasEl.GetCurrentContextType() == CanvasContextType::WebGL2) &&
|
aCanvasEl.GetCurrentContextType() == CanvasContextType::WebGL2) &&
|
||||||
aCropRect.isSome()) {
|
aCropRect.isSome()) {
|
||||||
@ -875,6 +896,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvas
|
|||||||
RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
|
RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
|
||||||
croppedSurface = CropAndCopyDataSourceSurface(dataSurface, cropRect);
|
croppedSurface = CropAndCopyDataSourceSurface(dataSurface, cropRect);
|
||||||
cropRect.MoveTo(0, 0);
|
cropRect.MoveTo(0, 0);
|
||||||
|
needToReportMemoryAllocation = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
croppedSurface = surface;
|
croppedSurface = surface;
|
||||||
@ -895,6 +917,11 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvas
|
|||||||
|
|
||||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
|
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
|
||||||
|
|
||||||
|
// Report memory allocation if needed.
|
||||||
|
if (needToReportMemoryAllocation) {
|
||||||
|
RegisterAllocation(aGlobal, ret->mDataWrapper->GetBufferLength());
|
||||||
|
}
|
||||||
|
|
||||||
// Set the picture rectangle.
|
// Set the picture rectangle.
|
||||||
if (ret && aCropRect.isSome()) {
|
if (ret && aCropRect.isSome()) {
|
||||||
ret->SetPictureRect(cropRect, aRv);
|
ret->SetPictureRect(cropRect, aRv);
|
||||||
@ -958,6 +985,9 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageData& aImageData,
|
|||||||
// ImageData's underlying data is not alpha-premultiplied.
|
// ImageData's underlying data is not alpha-premultiplied.
|
||||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, false);
|
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, false);
|
||||||
|
|
||||||
|
// Report memory allocation.
|
||||||
|
RegisterAllocation(aGlobal, ret->mDataWrapper->GetBufferLength());
|
||||||
|
|
||||||
// The cropping information has been handled in the CreateImageFromRawData()
|
// The cropping information has been handled in the CreateImageFromRawData()
|
||||||
// function.
|
// function.
|
||||||
|
|
||||||
@ -999,6 +1029,9 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, CanvasRenderingContext2D&
|
|||||||
|
|
||||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
|
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
|
||||||
|
|
||||||
|
// Report memory allocation.
|
||||||
|
RegisterAllocation(aGlobal, ret->mDataWrapper->GetBufferLength());
|
||||||
|
|
||||||
// Set the picture rectangle.
|
// Set the picture rectangle.
|
||||||
if (ret && aCropRect.isSome()) {
|
if (ret && aCropRect.isSome()) {
|
||||||
ret->SetPictureRect(aCropRect.ref(), aRv);
|
ret->SetPictureRect(aCropRect.ref(), aRv);
|
||||||
@ -1240,6 +1273,9 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Report memory allocation.
|
||||||
|
RegisterAllocation(mGlobalObject, imageBitmap->mDataWrapper->GetBufferLength());
|
||||||
|
|
||||||
mPromise->MaybeResolve(imageBitmap);
|
mPromise->MaybeResolve(imageBitmap);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1524,6 +1560,9 @@ ImageBitmap::ReadStructuredClone(JSContext* aCx,
|
|||||||
if (!GetOrCreateDOMReflector(aCx, imageBitmap, &value)) {
|
if (!GetOrCreateDOMReflector(aCx, imageBitmap, &value)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Report memory allocation.
|
||||||
|
RegisterAllocation(aParent, imageBitmap->mDataWrapper->GetBufferLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
return &(value.toObject());
|
return &(value.toObject());
|
||||||
@ -2112,6 +2151,9 @@ ImageBitmap::Create(nsIGlobalObject* aGlobal,
|
|||||||
// Assume the data from an external buffer is not alpha-premultiplied.
|
// Assume the data from an external buffer is not alpha-premultiplied.
|
||||||
RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(aGlobal, data, false);
|
RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(aGlobal, data, false);
|
||||||
|
|
||||||
|
// Report memory allocation.
|
||||||
|
RegisterAllocation(aGlobal, imageBitmap->mDataWrapper->GetBufferLength());
|
||||||
|
|
||||||
// We don't need to call SetPictureRect() here because there is no cropping
|
// We don't need to call SetPictureRect() here because there is no cropping
|
||||||
// supported and the ImageBitmap's mPictureRect is the size of the source
|
// supported and the ImageBitmap's mPictureRect is the size of the source
|
||||||
// image in default
|
// image in default
|
||||||
|
Loading…
Reference in New Issue
Block a user