зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1904048 - Add prototype for ImageBitmap's BindingJSObjectMallocBytes. r=aosmond
It looks like there was never a prototype for ImageBitmap's BindingJSObjectMallocBytes function. Even though it was defined and expected to associate ImageBitmap's internally allocated surface memory for the GC to track, the bindings generator never actually tried to call it because the lack of the prototype caused the default non-specialized version of this function to be called instead. With the protoype in place, this actually gets called and the GC is able to properly clean out ImageBitmap's in a more timely fashion. Differential Revision: https://phabricator.services.mozilla.com/D216250
This commit is contained in:
Родитель
de8b5d0e01
Коммит
196ef8360e
|
@ -38,6 +38,7 @@
|
|||
#include "nsStreamUtils.h"
|
||||
#include "imgLoader.h"
|
||||
#include "imgTools.h"
|
||||
#include "jsapi.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::layers;
|
||||
|
@ -651,13 +652,14 @@ static already_AddRefed<SourceSurface> GetSurfaceFromElement(
|
|||
}
|
||||
|
||||
ImageBitmap::ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
|
||||
bool aWriteOnly, gfxAlphaType aAlphaType)
|
||||
bool aAllocatedImageData, bool aWriteOnly,
|
||||
gfxAlphaType aAlphaType)
|
||||
: mParent(aGlobal),
|
||||
mData(aData),
|
||||
mSurface(nullptr),
|
||||
mPictureRect(aData->GetPictureRect()),
|
||||
mAlphaType(aAlphaType),
|
||||
mAllocatedImageData(false),
|
||||
mAllocatedImageData(aAllocatedImageData),
|
||||
mWriteOnly(aWriteOnly) {
|
||||
MOZ_ASSERT(aData, "aData is null in ImageBitmap constructor.");
|
||||
|
||||
|
@ -689,6 +691,7 @@ JSObject* ImageBitmap::WrapObject(JSContext* aCx,
|
|||
}
|
||||
|
||||
void ImageBitmap::Close() {
|
||||
RemoveAssociatedMemory();
|
||||
mData = nullptr;
|
||||
mSurface = nullptr;
|
||||
mPictureRect.SetEmpty();
|
||||
|
@ -969,8 +972,7 @@ already_AddRefed<ImageBitmap> ImageBitmap::CreateFromSourceSurface(
|
|||
nsIGlobalObject* aGlobal, gfx::SourceSurface* aSource, ErrorResult& aRv) {
|
||||
RefPtr<layers::Image> data = CreateImageFromSurface(aSource);
|
||||
RefPtr<ImageBitmap> ret =
|
||||
new ImageBitmap(aGlobal, data, false /* writeOnly */);
|
||||
ret->mAllocatedImageData = true;
|
||||
new ImageBitmap(aGlobal, data, true, false /* writeOnly */);
|
||||
return ret.forget();
|
||||
}
|
||||
|
||||
|
@ -979,10 +981,8 @@ already_AddRefed<ImageBitmap> ImageBitmap::CreateFromCloneData(
|
|||
nsIGlobalObject* aGlobal, ImageBitmapCloneData* aData) {
|
||||
RefPtr<layers::Image> data = CreateImageFromSurface(aData->mSurface);
|
||||
|
||||
RefPtr<ImageBitmap> ret =
|
||||
new ImageBitmap(aGlobal, data, aData->mWriteOnly, aData->mAlphaType);
|
||||
|
||||
ret->mAllocatedImageData = true;
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(
|
||||
aGlobal, data, true, aData->mWriteOnly, aData->mAlphaType);
|
||||
|
||||
ErrorResult rv;
|
||||
ret->SetPictureRect(aData->mPictureRect, rv);
|
||||
|
@ -1010,9 +1010,7 @@ already_AddRefed<ImageBitmap> ImageBitmap::CreateFromOffscreenCanvas(
|
|||
|
||||
RefPtr<layers::Image> data = CreateImageFromSurface(surface);
|
||||
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
|
||||
|
||||
ret->mAllocatedImageData = true;
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, true, writeOnly);
|
||||
|
||||
return ret.forget();
|
||||
}
|
||||
|
@ -1128,12 +1126,8 @@ already_AddRefed<ImageBitmap> ImageBitmap::CreateImageBitmapInternal(
|
|||
|
||||
// Create an Image from the SourceSurface.
|
||||
RefPtr<layers::Image> data = CreateImageFromSurface(surface);
|
||||
RefPtr<ImageBitmap> ret =
|
||||
new ImageBitmap(aGlobal, data, aWriteOnly, alphaType);
|
||||
|
||||
if (needToReportMemoryAllocation) {
|
||||
ret->mAllocatedImageData = true;
|
||||
}
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(
|
||||
aGlobal, data, needToReportMemoryAllocation, aWriteOnly, alphaType);
|
||||
|
||||
// Set the picture rectangle.
|
||||
ret->SetPictureRect(cropRect, aRv);
|
||||
|
@ -1232,7 +1226,7 @@ already_AddRefed<ImageBitmap> ImageBitmap::CreateInternal(
|
|||
RefPtr<SourceSurface> surface = data->GetAsSourceSurface();
|
||||
if (!surface) {
|
||||
// preserve original behavior in case of unavailble surface
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, false, writeOnly);
|
||||
return ret.forget();
|
||||
}
|
||||
|
||||
|
@ -1399,9 +1393,8 @@ already_AddRefed<ImageBitmap> ImageBitmap::CreateInternal(
|
|||
}
|
||||
|
||||
// Create an ImageBitmap.
|
||||
RefPtr<ImageBitmap> ret =
|
||||
new ImageBitmap(aGlobal, data, false /* write-only */, alphaType);
|
||||
ret->mAllocatedImageData = true;
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(
|
||||
aGlobal, data, true, false /* write-only */, alphaType);
|
||||
|
||||
// The cropping information has been handled in the
|
||||
// CreateImageFromRawData() function.
|
||||
|
@ -1911,7 +1904,7 @@ JSObject* ImageBitmap::ReadStructuredClone(
|
|||
#endif
|
||||
RefPtr<layers::Image> img = CreateImageFromSurface(aClonedSurfaces[aIndex]);
|
||||
RefPtr<ImageBitmap> imageBitmap =
|
||||
new ImageBitmap(aParent, img, !!writeOnly, alphaType);
|
||||
new ImageBitmap(aParent, img, true, !!writeOnly, alphaType);
|
||||
|
||||
ErrorResult error;
|
||||
imageBitmap->SetPictureRect(
|
||||
|
@ -1924,8 +1917,6 @@ JSObject* ImageBitmap::ReadStructuredClone(
|
|||
if (!GetOrCreateDOMReflector(aCx, imageBitmap, &value)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
imageBitmap->mAllocatedImageData = true;
|
||||
}
|
||||
|
||||
return &(value.toObject());
|
||||
|
@ -2000,32 +1991,42 @@ void ImageBitmap::WriteStructuredClone(
|
|||
}
|
||||
|
||||
size_t ImageBitmap::GetAllocatedSize() const {
|
||||
if (!mAllocatedImageData) {
|
||||
if (!mAllocatedImageData || !mData) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculate how many bytes are used.
|
||||
if (mData->GetFormat() == mozilla::ImageFormat::PLANAR_YCBCR) {
|
||||
return mData->AsPlanarYCbCrImage()->GetDataSize();
|
||||
switch (mData->GetFormat()) {
|
||||
case ImageFormat::PLANAR_YCBCR:
|
||||
return mData->AsPlanarYCbCrImage()->GetDataSize();
|
||||
case ImageFormat::NV_IMAGE:
|
||||
return mData->AsNVImage()->GetBufferSize();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (mData->GetFormat() == mozilla::ImageFormat::NV_IMAGE) {
|
||||
return mData->AsNVImage()->GetBufferSize();
|
||||
}
|
||||
|
||||
RefPtr<SourceSurface> surface = mData->GetAsSourceSurface();
|
||||
if (NS_WARN_IF(!surface)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const int bytesPerPixel = BytesPerPixel(surface->GetFormat());
|
||||
return surface->GetSize().height * surface->GetSize().width * bytesPerPixel;
|
||||
IntSize size = mData->GetSize();
|
||||
CheckedInt<uint32_t> bytes =
|
||||
CheckedInt<uint32_t>(size.width) * size.height * 4;
|
||||
return bytes.isValid() ? bytes.value() : 0;
|
||||
}
|
||||
|
||||
size_t BindingJSObjectMallocBytes(ImageBitmap* aBitmap) {
|
||||
return aBitmap->GetAllocatedSize();
|
||||
}
|
||||
|
||||
void ImageBitmap::RemoveAssociatedMemory() {
|
||||
if (!mAllocatedImageData) {
|
||||
return;
|
||||
}
|
||||
if (JSObject* wrapper = GetWrapperMaybeDead()) {
|
||||
if (size_t bytes = BindingJSObjectMallocBytes(this)) {
|
||||
JS::RemoveAssociatedMemory(wrapper, bytes, JS::MemoryUse::DOMBinding);
|
||||
}
|
||||
}
|
||||
mAllocatedImageData = false;
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<CreateImageBitmapFromBlob> CreateImageBitmapFromBlob::Create(
|
||||
Promise* aPromise, nsIGlobalObject* aGlobal, Blob& aBlob,
|
||||
|
@ -2338,8 +2339,8 @@ void CreateImageBitmapFromBlob::
|
|||
}
|
||||
|
||||
// Create ImageBitmap object.
|
||||
RefPtr<ImageBitmap> imageBitmap =
|
||||
new ImageBitmap(mGlobalObject, aImage, false /* write-only */, alphaType);
|
||||
RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(
|
||||
mGlobalObject, aImage, true, false /* write-only */, alphaType);
|
||||
|
||||
if (mCropRect.isSome()) {
|
||||
ErrorResult rv;
|
||||
|
@ -2351,8 +2352,6 @@ void CreateImageBitmapFromBlob::
|
|||
}
|
||||
}
|
||||
|
||||
imageBitmap->mAllocatedImageData = true;
|
||||
|
||||
mPromise->MaybeResolve(imageBitmap);
|
||||
}
|
||||
|
||||
|
|
|
@ -172,13 +172,16 @@ class ImageBitmap final : public nsISupports, public nsWrapperCache {
|
|||
* the aIsPremultipliedAlpha to be false in the
|
||||
* CreateInternal(from ImageData) method.
|
||||
*/
|
||||
ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData, bool aWriteOnly,
|
||||
ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
|
||||
bool aAllocatedImageData, bool aWriteOnly,
|
||||
gfxAlphaType aAlphaType = gfxAlphaType::Premult);
|
||||
|
||||
virtual ~ImageBitmap();
|
||||
|
||||
void SetPictureRect(const gfx::IntRect& aRect, ErrorResult& aRv);
|
||||
|
||||
void RemoveAssociatedMemory();
|
||||
|
||||
static already_AddRefed<ImageBitmap> CreateImageBitmapInternal(
|
||||
nsIGlobalObject* aGlobal, gfx::SourceSurface* aSurface,
|
||||
const Maybe<gfx::IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
|
||||
|
@ -279,6 +282,8 @@ class ImageBitmap final : public nsISupports, public nsWrapperCache {
|
|||
bool mWriteOnly;
|
||||
};
|
||||
|
||||
size_t BindingJSObjectMallocBytes(ImageBitmap* aBitmap);
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче