Don't access ShadowableLayer from ClientLayer's destructor. (
bug 1323539 part 1, r=mattwoodrow)
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -891,16 +891,13 @@ ClientLayerManager::CreatePersistentBuff
}
return LayerManager::CreatePersistentBufferProvider(aSize, aFormat);
}
ClientLayer::~ClientLayer()
{
- if (HasShadow()) {
- PLayerChild::Send__delete__(GetShadow());
- }
MOZ_COUNT_DTOR(ClientLayer);
}
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/client/ClientLayerManager.h
+++ b/gfx/layers/client/ClientLayerManager.h
@@ -346,30 +346,24 @@ class ClientLayer : public ShadowableLay
public:
ClientLayer()
{
MOZ_COUNT_CTOR(ClientLayer);
}
~ClientLayer();
- void SetShadow(PLayerChild* aShadow)
- {
- MOZ_ASSERT(!mShadow, "can't have two shadows (yet)");
- mShadow = aShadow;
- }
-
virtual void Disconnect()
{
// This is an "emergency Disconnect()", called when the compositing
// process has died. |mShadow| and our Shmem buffers are
// automatically managed by IPDL, so we don't need to explicitly
// free them here (it's hard to get that right on emergency
// shutdown anyway).
- mShadow = nullptr;
+ SetShadow(nullptr);
}
virtual void ClearCachedResources() { }
// Shrink memory usage.
// Called when "memory-pressure" is observed.
virtual void HandleMemoryPressure() { }
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -1054,10 +1054,17 @@ void
ShadowLayerForwarder::SyncWithCompositor()
{
auto compositorBridge = GetCompositorBridgeChild();
if (compositorBridge && compositorBridge->IPCOpen()) {
compositorBridge->SendSyncWithCompositor();
}
}
+ShadowableLayer::~ShadowableLayer()
+{
+ if (HasShadow()) {
+ PLayerChild::Send__delete__(GetShadow());
+ }
+}
+
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/ipc/ShadowLayers.h
+++ b/gfx/layers/ipc/ShadowLayers.h
@@ -444,34 +444,41 @@ class CompositableClient;
* through a ShadowLayerForwarder. A ShadowableLayer maps to a
* Shadow*Layer in a parent context.
*
* Note that ShadowLayers can themselves be ShadowableLayers.
*/
class ShadowableLayer
{
public:
- virtual ~ShadowableLayer() {}
+ virtual ~ShadowableLayer();
virtual Layer* AsLayer() = 0;
/**
* True if this layer has a shadow in a parent process.
*/
bool HasShadow() { return !!mShadow; }
/**
* Return the IPC handle to a Shadow*Layer referring to this if one
* exists, nullptr if not.
*/
PLayerChild* GetShadow() { return mShadow; }
+ void SetShadow(PLayerChild* aShadow) {
+ MOZ_ASSERT(!mShadow || !aShadow, "can't have two shadows (yet)");
+ mShadow = aShadow;
+ }
+
virtual CompositableClient* GetCompositableClient() { return nullptr; }
+
protected:
ShadowableLayer() : mShadow(nullptr) {}
+private:
PLayerChild* mShadow;
};
} // namespace layers
} // namespace mozilla
#endif // ifndef mozilla_layers_ShadowLayers_h