Bug 1665373 - Stop using nsCountedRef in the image container classes. r=aosmond

Instead, use NS_ReleaseOnMainThread. This requires exactly the same number of
special-cases, but let me know if you instead want a separate
MainThreadSurfaceRef which implements RefPtrTraits and releases on the main
thread or something...

Depends on D90398

Differential Revision: https://phabricator.services.mozilla.com/D90399
This commit is contained in:
Emilio Cobos Álvarez 2020-09-16 15:13:51 +00:00
parent 47f53144a5
commit 8e6234de91
5 changed files with 32 additions and 113 deletions

View File

@ -37,9 +37,7 @@ class SurfaceHelper : public Runnable {
// It retrieves a SourceSurface reference and convert color format on main
// thread and passes DataSourceSurface to caller thread.
NS_IMETHOD Run() override {
// It guarantees the reference will be released on main thread.
nsCountedRef<nsMainThreadSourceSurfaceRef> surface;
surface.own(mImage->GetAsSourceSurface().take());
RefPtr<gfx::SourceSurface> surface = mImage->GetAsSourceSurface();
if (surface->GetFormat() == gfx::SurfaceFormat::B8G8R8A8) {
mDataSourceSurface = surface->GetDataSurface();
@ -47,6 +45,9 @@ class SurfaceHelper : public Runnable {
mDataSourceSurface = gfxUtils::CopySurfaceToDataSourceSurfaceWithFormat(
surface, gfx::SurfaceFormat::B8G8R8A8);
}
// It guarantees the reference will be released on main thread.
NS_ReleaseOnMainThread("SurfaceHelper::surface", surface.forget());
return NS_OK;
}

View File

@ -665,9 +665,16 @@ already_AddRefed<gfx::SourceSurface> PlanarYCbCrImage::GetAsSourceSurface() {
return surface.forget();
}
PlanarYCbCrImage::~PlanarYCbCrImage() {
NS_ReleaseOnMainThread("PlanarYCbCrImage::mSourceSurface",
mSourceSurface.forget());
}
NVImage::NVImage() : Image(nullptr, ImageFormat::NV_IMAGE), mBufferSize(0) {}
NVImage::~NVImage() = default;
NVImage::~NVImage() {
NS_ReleaseOnMainThread("NVImage::mSourceSurface", mSourceSurface.forget());
}
IntSize NVImage::GetSize() const { return mSize; }
@ -683,13 +690,13 @@ already_AddRefed<SourceSurface> NVImage::GetAsSourceSurface() {
// logics in PlanarYCbCrImage::GetAsSourceSurface().
const int bufferLength = mData.mYSize.height * mData.mYStride +
mData.mCbCrSize.height * mData.mCbCrSize.width * 2;
auto* buffer = new uint8_t[bufferLength];
UniquePtr<uint8_t[]> buffer(new uint8_t[bufferLength]);
Data aData = mData;
aData.mCbCrStride = aData.mCbCrSize.width;
aData.mCbSkip = 0;
aData.mCrSkip = 0;
aData.mYChannel = buffer;
aData.mYChannel = buffer.get();
aData.mCbChannel = aData.mYChannel + aData.mYSize.height * aData.mYStride;
aData.mCrChannel =
aData.mCbChannel + aData.mCbCrSize.height * aData.mCbCrStride;
@ -735,9 +742,6 @@ already_AddRefed<SourceSurface> NVImage::GetAsSourceSurface() {
mSourceSurface = surface;
// Release the temporary buffer.
delete[] buffer;
return surface.forget();
}
@ -788,8 +792,8 @@ bool NVImage::SetData(const Data& aData) {
const NVImage::Data* NVImage::GetData() const { return &mData; }
UniquePtr<uint8_t> NVImage::AllocateBuffer(uint32_t aSize) {
UniquePtr<uint8_t> buffer(new uint8_t[aSize]);
UniquePtr<uint8_t[]> NVImage::AllocateBuffer(uint32_t aSize) {
UniquePtr<uint8_t[]> buffer(new uint8_t[aSize]);
return buffer;
}
@ -806,7 +810,10 @@ SourceSurfaceImage::SourceSurfaceImage(gfx::SourceSurface* aSourceSurface)
mSourceSurface(aSourceSurface),
mTextureFlags(TextureFlags::DEFAULT) {}
SourceSurfaceImage::~SourceSurfaceImage() = default;
SourceSurfaceImage::~SourceSurfaceImage() {
NS_ReleaseOnMainThread("SourceSurfaceImage::mSourceSurface",
mSourceSurface.forget());
}
TextureClient* SourceSurfaceImage::GetTextureClient(
KnowsCompositor* aKnowsCompositor) {

View File

@ -20,7 +20,6 @@
#include "mozilla/layers/LayersTypes.h" // for LayersBackend, etc
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/mozalloc.h" // for operator delete, etc
#include "nsAutoRef.h" // for nsCountedRef
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsDebug.h" // for NS_ASSERTION
#include "nsISupportsImpl.h" // for Image::Release, etc
@ -35,98 +34,6 @@
#include "mozilla/UniquePtr.h"
#include "MediaInfo.h"
#ifndef XPCOM_GLUE_AVOID_NSPR
/**
* We need to be able to hold a reference to a Moz2D SourceSurface from Image
* subclasses. Whilst SourceSurface is atomic refcounted and thus safe to
* AddRef/Release on any thread, it is potentially a problem since clean up code
* may need to run on a the main thread.
*
* We use nsCountedRef<nsMainThreadSourceSurfaceRef> to reference the
* SourceSurface. When Releasing, if we're not on the main thread, we post an
* event to the main thread to do the actual release.
*/
class nsMainThreadSourceSurfaceRef;
template <>
class nsAutoRefTraits<nsMainThreadSourceSurfaceRef> {
public:
typedef mozilla::gfx::SourceSurface* RawRef;
/**
* The XPCOM event that will do the actual release on the main thread.
*/
class SurfaceReleaser : public mozilla::Runnable {
public:
explicit SurfaceReleaser(RawRef aRef)
: mozilla::Runnable(
"nsAutoRefTraits<nsMainThreadSourceSurfaceRef>::SurfaceReleaser"),
mRef(aRef) {}
NS_IMETHOD Run() override {
mRef->Release();
return NS_OK;
}
RawRef mRef;
};
static RawRef Void() { return nullptr; }
static void Release(RawRef aRawRef) {
if (NS_IsMainThread()) {
aRawRef->Release();
return;
}
nsCOMPtr<nsIRunnable> runnable = new SurfaceReleaser(aRawRef);
NS_DispatchToMainThread(runnable);
}
static void AddRef(RawRef aRawRef) { aRawRef->AddRef(); }
};
class nsOwningThreadSourceSurfaceRef;
template <>
class nsAutoRefTraits<nsOwningThreadSourceSurfaceRef> {
public:
typedef mozilla::gfx::SourceSurface* RawRef;
/**
* The XPCOM event that will do the actual release on the creation thread.
*/
class SurfaceReleaser : public mozilla::Runnable {
public:
explicit SurfaceReleaser(RawRef aRef)
: mozilla::Runnable(
"nsAutoRefTraits<nsOwningThreadSourceSurfaceRef>::"
"SurfaceReleaser"),
mRef(aRef) {}
NS_IMETHOD Run() override {
mRef->Release();
return NS_OK;
}
RawRef mRef;
};
static RawRef Void() { return nullptr; }
void Release(RawRef aRawRef) {
MOZ_ASSERT(mOwningEventTarget);
if (mOwningEventTarget->IsOnCurrentThread()) {
aRawRef->Release();
return;
}
nsCOMPtr<nsIRunnable> runnable = new SurfaceReleaser(aRawRef);
mOwningEventTarget->Dispatch(runnable, nsIThread::DISPATCH_NORMAL);
}
void AddRef(RawRef aRawRef) {
MOZ_ASSERT(!mOwningEventTarget);
mOwningEventTarget = mozilla::GetCurrentSerialEventTarget();
aRawRef->AddRef();
}
private:
nsCOMPtr<nsISerialEventTarget> mOwningEventTarget;
};
#endif
#ifdef XP_WIN
struct ID3D10Texture2D;
struct ID3D10Device;
@ -801,7 +708,7 @@ class PlanarYCbCrImage : public Image {
enum { MAX_DIMENSION = 16384 };
virtual ~PlanarYCbCrImage() = default;
virtual ~PlanarYCbCrImage();
/**
* This makes a copy of the data buffers, in order to support functioning
@ -867,7 +774,7 @@ class PlanarYCbCrImage : public Image {
gfx::IntPoint mOrigin;
gfx::IntSize mSize;
gfxImageFormat mOffscreenFormat;
nsCountedRef<nsMainThreadSourceSurfaceRef> mSourceSurface;
RefPtr<gfx::SourceSurface> mSourceSurface;
uint32_t mBufferSize;
};
@ -921,13 +828,13 @@ class NVImage final : public Image {
/**
* Return a buffer to store image data in.
*/
mozilla::UniquePtr<uint8_t> AllocateBuffer(uint32_t aSize);
mozilla::UniquePtr<uint8_t[]> AllocateBuffer(uint32_t aSize);
mozilla::UniquePtr<uint8_t> mBuffer;
mozilla::UniquePtr<uint8_t[]> mBuffer;
uint32_t mBufferSize;
gfx::IntSize mSize;
Data mData;
nsCountedRef<nsMainThreadSourceSurfaceRef> mSourceSurface;
RefPtr<gfx::SourceSurface> mSourceSurface;
};
/**
@ -956,7 +863,7 @@ class SourceSurfaceImage final : public Image {
private:
gfx::IntSize mSize;
nsCountedRef<nsOwningThreadSourceSurfaceRef> mSourceSurface;
RefPtr<gfx::SourceSurface> mSourceSurface;
nsDataHashtable<nsUint32HashKey, RefPtr<TextureClient>> mTextureClients;
TextureFlags mTextureFlags;
};

View File

@ -55,7 +55,11 @@ SharedRGBImage::SharedRGBImage(ImageClient* aCompositable)
MOZ_COUNT_CTOR(SharedRGBImage);
}
SharedRGBImage::~SharedRGBImage() { MOZ_COUNT_DTOR(SharedRGBImage); }
SharedRGBImage::~SharedRGBImage() {
MOZ_COUNT_DTOR(SharedRGBImage);
NS_ReleaseOnMainThread("SharedRGBImage::mSourceSurface",
mSourceSurface.forget());
}
bool SharedRGBImage::Allocate(gfx::IntSize aSize, gfx::SurfaceFormat aFormat) {
static const uint32_t MAX_POOLED_VIDEO_COUNT = 5;

View File

@ -47,7 +47,7 @@ class SharedRGBImage : public Image {
gfx::IntSize mSize;
RefPtr<ImageClient> mCompositable;
RefPtr<TextureClient> mTextureClient;
nsCountedRef<nsMainThreadSourceSurfaceRef> mSourceSurface;
RefPtr<gfx::SourceSurface> mSourceSurface;
};
} // namespace layers