Bug 1167235 - Part 4 - Forward the shutdown notification to CanvasRenderingContext2D. r=Bas

This commit is contained in:
Nicolas Silva 2016-07-01 10:58:18 +02:00
Родитель d7bdab458f
Коммит 6837c5c2f2
6 изменённых файлов: 107 добавлений и 12 удалений

Просмотреть файл

@ -745,6 +745,36 @@ NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(CanvasPattern, Release)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CanvasPattern, mContext)
class CanvasShutdownObserver final : public nsIObserver
{
public:
explicit CanvasShutdownObserver(CanvasRenderingContext2D* aCanvas)
: mCanvas(aCanvas)
{}
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
private:
~CanvasShutdownObserver() {}
CanvasRenderingContext2D* mCanvas;
};
NS_IMPL_ISUPPORTS(CanvasShutdownObserver, nsIObserver)
NS_IMETHODIMP
CanvasShutdownObserver::Observe(nsISupports *aSubject,
const char *aTopic,
const char16_t *aData)
{
if (mCanvas && strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
mCanvas->OnShutdown();
nsContentUtils::UnregisterShutdownObserver(this);
}
return NS_OK;
}
class CanvasDrawObserver
{
public:
@ -1044,6 +1074,9 @@ CanvasRenderingContext2D::CanvasRenderingContext2D()
{
sNumLivingContexts++;
mShutdownObserver = new CanvasShutdownObserver(this);
nsContentUtils::RegisterShutdownObserver(mShutdownObserver);
// The default is to use OpenGL mode
if (gfxPlatform::GetPlatform()->UseAcceleratedCanvas()) {
mDrawObserver = new CanvasDrawObserver(this);
@ -1056,6 +1089,7 @@ CanvasRenderingContext2D::~CanvasRenderingContext2D()
{
RemoveDrawObserver();
RemovePostRefreshObserver();
RemoveShutdownObserver();
Reset();
// Drop references from all CanvasRenderingContext2DUserData to this context
for (uint32_t i = 0; i < mUserDatas.Length(); ++i) {
@ -1148,6 +1182,29 @@ CanvasRenderingContext2D::Reset()
return NS_OK;
}
void
CanvasRenderingContext2D::OnShutdown()
{
mShutdownObserver = nullptr;
RefPtr<PersistentBufferProvider> provider = mBufferProvider;
Reset();
if (provider) {
provider->OnShutdown();
}
}
void
CanvasRenderingContext2D::RemoveShutdownObserver()
{
if (mShutdownObserver) {
nsContentUtils::UnregisterShutdownObserver(mShutdownObserver);
mShutdownObserver = nullptr;
}
}
void
CanvasRenderingContext2D::SetStyleFromString(const nsAString& aStr,
Style aWhichStyle)
@ -1456,6 +1513,13 @@ CanvasRenderingContext2D::RenderingMode
CanvasRenderingContext2D::EnsureTarget(const gfx::Rect* aCoveredRect,
RenderingMode aRenderingMode)
{
if (AlreadyShutDown()) {
gfxCriticalError() << "Attempt to render into a Canvas2d after shutdown.";
EnsureErrorTarget();
mTarget = sErrorTarget;
return aRenderingMode;
}
// This would make no sense, so make sure we don't get ourselves in a mess
MOZ_ASSERT(mRenderingMode != RenderingMode::DefaultBackendMode);
@ -5691,6 +5755,10 @@ void CanvasRenderingContext2D::RemoveDrawObserver()
PersistentBufferProvider*
CanvasRenderingContext2D::GetBufferProvider(LayerManager* aManager)
{
if (AlreadyShutDown()) {
return nullptr;
}
if (mBufferProvider) {
return mBufferProvider;
}

Просмотреть файл

@ -54,6 +54,7 @@ template<typename T> class Optional;
struct CanvasBidiProcessor;
class CanvasRenderingContext2DUserData;
class CanvasDrawObserver;
class CanvasShutdownObserver;
/**
** CanvasRenderingContext2D
@ -545,6 +546,7 @@ public:
// return true and fills in the bound rect if element has a hit region.
bool GetHitRegionRect(Element* aElement, nsRect& aRect) override;
void OnShutdown();
protected:
nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
uint32_t aWidth, uint32_t aHeight,
@ -749,6 +751,10 @@ protected:
CanvasDrawObserver* mDrawObserver;
void RemoveDrawObserver();
RefPtr<CanvasShutdownObserver> mShutdownObserver;
void RemoveShutdownObserver();
bool AlreadyShutDown() const { return !mShutdownObserver; }
/**
* Flag to avoid duplicate calls to InvalidateFrame. Set to true whenever
* Redraw is called, reset to false when Render is called.

Просмотреть файл

@ -353,8 +353,7 @@ HTMLCanvasElement::HTMLCanvasElement(already_AddRefed<mozilla::dom::NodeInfo>& a
: nsGenericHTMLElement(aNodeInfo),
mResetLayer(true) ,
mWriteOnly(false)
{
}
{}
HTMLCanvasElement::~HTMLCanvasElement()
{

Просмотреть файл

@ -126,16 +126,7 @@ PersistentBufferProviderShared::~PersistentBufferProviderShared()
mFwd->GetActiveResourceTracker().RemoveObject(this);
}
mDrawTarget = nullptr;
if (mBack && mBack->IsLocked()) {
mBack->Unlock();
}
if (mFront && mFront->IsLocked()) {
mFront->Unlock();
}
if (mBuffer && mBuffer->IsLocked()) {
mBuffer->Unlock();
}
Destroy();
}
already_AddRefed<gfx::DrawTarget>
@ -276,5 +267,28 @@ PersistentBufferProviderShared::NotifyInactive()
mBuffer = nullptr;
}
void
PersistentBufferProviderShared::Destroy()
{
mSnapshot = nullptr;
mDrawTarget = nullptr;
if (mFront && mFront->IsLocked()) {
mFront->Unlock();
}
if (mBack && mBack->IsLocked()) {
mBack->Unlock();
}
if (mBuffer && mBuffer->IsLocked()) {
mBuffer->Unlock();
}
mFront = nullptr;
mBack = nullptr;
mBuffer = nullptr;
}
} // namespace layers
} // namespace mozilla

Просмотреть файл

@ -60,6 +60,8 @@ public:
virtual void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) = 0;
virtual TextureClient* GetTextureClient() { return nullptr; }
virtual void OnShutdown() {}
};
@ -121,6 +123,8 @@ public:
virtual void NotifyInactive() override;
virtual void OnShutdown() override { Destroy(); }
protected:
PersistentBufferProviderShared(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
CompositableForwarder* aFwd,
@ -128,6 +132,8 @@ protected:
~PersistentBufferProviderShared();
void Destroy();
gfx::IntSize mSize;
gfx::SurfaceFormat mFormat;
RefPtr<CompositableForwarder> mFwd;

Просмотреть файл

@ -364,6 +364,8 @@ void TextureClient::Destroy(bool aForceSync)
mActor->Lock();
}
mReadLock = nullptr;
CancelWaitFenceHandleOnImageBridge();
RefPtr<TextureChild> actor = mActor;
mActor = nullptr;