Bug 1088300 - Remove mCompositableClient from TileClient, pass the compositable and layer by reference to remove the possibility of unexpectedly storing null pointers. r=milan
authorNicolas Silva <nsilva@mozilla.com>
Tue, 30 Aug 2016 13:48:20 +0200
changeset 312399 565bac97a123fa4d0e7e623a1df448085b3afec9
parent 312398 3abe6a1579f9bc79816ab781869b5232a1b3e483
child 312400 41632799ddc4a50356a837ed37a1918a5bfe59f5
push id20447
push userkwierso@gmail.com
push dateFri, 02 Sep 2016 20:36:44 +0000
treeherderfx-team@969397f22187 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmilan
bugs1088300
milestone51.0a1
Bug 1088300 - Remove mCompositableClient from TileClient, pass the compositable and layer by reference to remove the possibility of unexpectedly storing null pointers. r=milan
gfx/layers/client/ClientTiledPaintedLayer.cpp
gfx/layers/client/SingleTiledContentClient.cpp
gfx/layers/client/SingleTiledContentClient.h
gfx/layers/client/TiledContentClient.cpp
gfx/layers/client/TiledContentClient.h
--- a/gfx/layers/client/ClientTiledPaintedLayer.cpp
+++ b/gfx/layers/client/ClientTiledPaintedLayer.cpp
@@ -440,20 +440,20 @@ ClientTiledPaintedLayer::RenderLayer()
 
   if (mContentClient && mHaveSingleTiledContentClient && !wantSingleTiledContentClient) {
     mContentClient = nullptr;
     mValidRegion.SetEmpty();
   }
 
   if (!mContentClient) {
     if (wantSingleTiledContentClient) {
-      mContentClient = new SingleTiledContentClient(this, ClientManager());
+      mContentClient = new SingleTiledContentClient(*this, ClientManager());
       mHaveSingleTiledContentClient = true;
     } else {
-      mContentClient = new MultiTiledContentClient(this, ClientManager());
+      mContentClient = new MultiTiledContentClient(*this, ClientManager());
       mHaveSingleTiledContentClient = false;
     }
 
     mContentClient->Connect();
     ClientManager()->AsShadowForwarder()->Attach(mContentClient, this);
     MOZ_ASSERT(mContentClient->GetForwarder());
   }
 
--- a/gfx/layers/client/SingleTiledContentClient.cpp
+++ b/gfx/layers/client/SingleTiledContentClient.cpp
@@ -6,23 +6,23 @@
 #include "mozilla/layers/SingleTiledContentClient.h"
 
 #include "ClientTiledPaintedLayer.h"
 
 namespace mozilla {
 namespace layers {
 
 
-SingleTiledContentClient::SingleTiledContentClient(ClientTiledPaintedLayer* aPaintedLayer,
+SingleTiledContentClient::SingleTiledContentClient(ClientTiledPaintedLayer& aPaintedLayer,
                                                    ClientLayerManager* aManager)
   : TiledContentClient(aManager, "Single")
 {
   MOZ_COUNT_CTOR(SingleTiledContentClient);
 
-  mTiledBuffer = new ClientSingleTiledLayerBuffer(aPaintedLayer, this, aManager);
+  mTiledBuffer = new ClientSingleTiledLayerBuffer(aPaintedLayer, *this, aManager);
 }
 
 void
 SingleTiledContentClient::ClearCachedResources()
 {
   CompositableClient::ClearCachedResources();
   mTiledBuffer->DiscardBuffers();
 }
@@ -36,21 +36,20 @@ SingleTiledContentClient::UpdatedBuffer(
 
 /* static */ bool
 SingleTiledContentClient::ClientSupportsLayerSize(const gfx::IntSize& aSize, ClientLayerManager* aManager)
 {
   int32_t maxTextureSize = aManager->GetMaxTextureSize();
   return aSize.width <= maxTextureSize && aSize.height <= maxTextureSize;
 }
 
-ClientSingleTiledLayerBuffer::ClientSingleTiledLayerBuffer(ClientTiledPaintedLayer* aPaintedLayer,
-                                                           CompositableClient* aCompositableClient,
+ClientSingleTiledLayerBuffer::ClientSingleTiledLayerBuffer(ClientTiledPaintedLayer& aPaintedLayer,
+                                                           CompositableClient& aCompositableClient,
                                                            ClientLayerManager* aManager)
   : ClientTiledLayerBuffer(aPaintedLayer, aCompositableClient)
-  , mManager(aManager)
   , mWasLastPaintProgressive(false)
   , mFormat(gfx::SurfaceFormat::UNKNOWN)
 {
 }
 
 void
 ClientSingleTiledLayerBuffer::ReleaseTiles()
 {
@@ -88,17 +87,17 @@ ClientSingleTiledLayerBuffer::GetSurface
                                 mFrameResolution.yScale,
                                 mWasLastPaintProgressive);
 }
 
 already_AddRefed<TextureClient>
 ClientSingleTiledLayerBuffer::GetTextureClient()
 {
   MOZ_ASSERT(mFormat != gfx::SurfaceFormat::UNKNOWN);
-  return mCompositableClient->CreateTextureClientForDrawing(
+  return mCompositableClient.CreateTextureClientForDrawing(
     gfx::ImageFormatToSurfaceFormat(mFormat), mSize, BackendSelector::Content,
     TextureFlags::DISALLOW_BIGIMAGE | TextureFlags::IMMEDIATE_UPLOAD);
 }
 
 void
 ClientSingleTiledLayerBuffer::PaintThebes(const nsIntRegion& aNewValidRegion,
                                           const nsIntRegion& aPaintRegion,
                                           const nsIntRegion& aDirtyRegion,
@@ -120,28 +119,27 @@ ClientSingleTiledLayerBuffer::PaintThebe
     paintRegion = aNewValidRegion;
   }
 
   SurfaceMode mode;
   gfxContentType content = GetContentType(&mode);
   mFormat = gfxPlatform::GetPlatform()->OptimalFormatForContent(content);
 
   if (mTile.IsPlaceholderTile()) {
-    mTile.SetLayerManager(mManager);
     mTile.SetTextureAllocator(this);
   }
-  mTile.SetCompositableClient(mCompositableClient);
 
   // The dirty region relative to the top-left of the tile.
   nsIntRegion tileDirtyRegion = paintRegion.MovedBy(-mTilingOrigin);
 
   nsIntRegion extraPainted;
   RefPtr<TextureClient> backBufferOnWhite;
   RefPtr<TextureClient> backBuffer =
-    mTile.GetBackBuffer(tileDirtyRegion,
+    mTile.GetBackBuffer(mCompositableClient,
+                        tileDirtyRegion,
                         content, mode,
                         extraPainted,
                         &backBufferOnWhite);
 
   mTile.mUpdateRect = tileDirtyRegion.GetBounds().Union(extraPainted.GetBounds());
 
   extraPainted.MoveBy(mTilingOrigin);
   extraPainted.And(extraPainted, aNewValidRegion);
@@ -180,17 +178,17 @@ ClientSingleTiledLayerBuffer::PaintThebe
   {
     RefPtr<gfxContext> ctx = gfxContext::CreateOrNull(dt);
     if (!ctx) {
       gfxDevCrash(gfx::LogReason::InvalidContext) << "SingleTiledContextClient context problem " << gfx::hexa(dt);
       return;
     }
     ctx->SetMatrix(ctx->CurrentMatrix().Translate(-mTilingOrigin.x, -mTilingOrigin.y));
 
-    aCallback(mPaintedLayer, ctx, paintRegion, paintRegion, DrawRegionClip::DRAW, nsIntRegion(), aCallbackData);
+    aCallback(&mPaintedLayer, ctx, paintRegion, paintRegion, DrawRegionClip::DRAW, nsIntRegion(), aCallbackData);
   }
 
   // Mark the area we just drew into the back buffer as invalid in the front buffer as they're
   // now out of sync.
   mTile.mInvalidFront.OrWith(tileDirtyRegion);
 
   // The new buffer is now validated, remove the dirty region from it.
   mTile.mInvalidBack.SubOut(tileDirtyRegion);
--- a/gfx/layers/client/SingleTiledContentClient.h
+++ b/gfx/layers/client/SingleTiledContentClient.h
@@ -22,18 +22,18 @@ class ClientLayerManager;
  * gfxPrefs::PerTileDrawing().
  */
 class ClientSingleTiledLayerBuffer
   : public ClientTiledLayerBuffer
   , public TextureClientAllocator
 {
   virtual ~ClientSingleTiledLayerBuffer() {}
 public:
-  ClientSingleTiledLayerBuffer(ClientTiledPaintedLayer* aPaintedLayer,
-                               CompositableClient* aCompositableClient,
+  ClientSingleTiledLayerBuffer(ClientTiledPaintedLayer& aPaintedLayer,
+                               CompositableClient& aCompositableClient,
                                ClientLayerManager* aManager);
 
   // TextureClientAllocator
   already_AddRefed<TextureClient> GetTextureClient() override;
   void ReturnTextureClientDeferred(TextureClient* aClient) override {}
   void ReportClientLost() override {}
 
   // ClientTiledLayerBuffer
@@ -78,18 +78,16 @@ public:
 
   void ClearPaintedRegion() {
     mPaintedRegion.SetEmpty();
   }
 
 private:
   TileClient mTile;
 
-  ClientLayerManager* mManager;
-
   nsIntRegion mPaintedRegion;
   nsIntRegion mValidRegion;
   bool mWasLastPaintProgressive;
 
   /**
    * While we're adding tiles, this is used to keep track of the position of
    * the top-left of the top-left-most tile.  When we come to wrap the tiles in
    * TiledDrawTarget we subtract the value of this member from each tile's
@@ -101,17 +99,17 @@ private:
   gfx::IntPoint mTilingOrigin;
   gfx::IntSize mSize;
   gfxImageFormat mFormat;
 };
 
 class SingleTiledContentClient : public TiledContentClient
 {
 public:
-  SingleTiledContentClient(ClientTiledPaintedLayer* aPaintedLayer,
+  SingleTiledContentClient(ClientTiledPaintedLayer& aPaintedLayer,
                            ClientLayerManager* aManager);
 
 protected:
   ~SingleTiledContentClient()
   {
     MOZ_COUNT_DTOR(SingleTiledContentClient);
 
     mTiledBuffer->ReleaseTiles();
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -82,27 +82,23 @@ static void DrawDebugOverlay(mozilla::gf
 
 namespace mozilla {
 
 using namespace gfx;
 
 namespace layers {
 
 
-MultiTiledContentClient::MultiTiledContentClient(ClientTiledPaintedLayer* aPaintedLayer,
+MultiTiledContentClient::MultiTiledContentClient(ClientTiledPaintedLayer& aPaintedLayer,
                                                  ClientLayerManager* aManager)
   : TiledContentClient(aManager, "Multi")
+  , mTiledBuffer(aPaintedLayer, *this, aManager, &mSharedFrameMetricsHelper)
+  , mLowPrecisionTiledBuffer(aPaintedLayer, *this, aManager, &mSharedFrameMetricsHelper)
 {
   MOZ_COUNT_CTOR(MultiTiledContentClient);
-
-  mTiledBuffer = ClientMultiTiledLayerBuffer(aPaintedLayer, this, aManager,
-                                             &mSharedFrameMetricsHelper);
-  mLowPrecisionTiledBuffer = ClientMultiTiledLayerBuffer(aPaintedLayer, this, aManager,
-                                                         &mSharedFrameMetricsHelper);
-
   mLowPrecisionTiledBuffer.SetResolution(gfxPrefs::LowPrecisionResolution());
   mHasLowPrecision = gfxPrefs::UseLowPrecisionBuffer();
 }
 
 void
 MultiTiledContentClient::ClearCachedResources()
 {
   CompositableClient::ClearCachedResources();
@@ -276,18 +272,18 @@ SharedFrameMetricsHelper::AboutToChecker
     TILING_LOG("TILING: About to checkerboard; painted %s\n", Stringify(painted).c_str());
     TILING_LOG("TILING: About to checkerboard; compositor %s\n", Stringify(aCompositorMetrics).c_str());
     TILING_LOG("TILING: About to checkerboard; showing %s\n", Stringify(showing).c_str());
     return true;
   }
   return false;
 }
 
-ClientMultiTiledLayerBuffer::ClientMultiTiledLayerBuffer(ClientTiledPaintedLayer* aPaintedLayer,
-                                                         CompositableClient* aCompositableClient,
+ClientMultiTiledLayerBuffer::ClientMultiTiledLayerBuffer(ClientTiledPaintedLayer& aPaintedLayer,
+                                                         CompositableClient& aCompositableClient,
                                                          ClientLayerManager* aManager,
                                                          SharedFrameMetricsHelper* aHelper)
   : ClientTiledLayerBuffer(aPaintedLayer, aCompositableClient)
   , mManager(aManager)
   , mCallback(nullptr)
   , mCallbackData(nullptr)
   , mSharedFrameMetricsHelper(aHelper)
 {
@@ -302,41 +298,41 @@ ClientTiledLayerBuffer::HasFormatChanged
          mode != mLastPaintSurfaceMode;
 }
 
 
 gfxContentType
 ClientTiledLayerBuffer::GetContentType(SurfaceMode* aMode) const
 {
   gfxContentType content =
-    mPaintedLayer->CanUseOpaqueSurface() ? gfxContentType::COLOR :
+    mPaintedLayer.CanUseOpaqueSurface() ? gfxContentType::COLOR :
                                           gfxContentType::COLOR_ALPHA;
-  SurfaceMode mode = mPaintedLayer->GetSurfaceMode();
+  SurfaceMode mode = mPaintedLayer.GetSurfaceMode();
 
   if (mode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
 #if defined(MOZ_GFX_OPTIMIZE_MOBILE) || defined(MOZ_WIDGET_GONK)
     mode = SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA;
 #else
-    if (!mPaintedLayer->GetParent() ||
-        !mPaintedLayer->GetParent()->SupportsComponentAlphaChildren()) {
+    if (!mPaintedLayer.GetParent() ||
+        !mPaintedLayer.GetParent()->SupportsComponentAlphaChildren()) {
       mode = SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA;
     } else {
       content = gfxContentType::COLOR;
     }
 #endif
   } else if (mode == SurfaceMode::SURFACE_OPAQUE) {
 #if defined(MOZ_GFX_OPTIMIZE_MOBILE) || defined(MOZ_WIDGET_GONK)
     if (IsLowPrecision()) {
       // If we're in low-res mode, drawing can sample from outside the visible
       // region. Make sure that we only sample transparency if that happens.
       mode = SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA;
       content = gfxContentType::COLOR_ALPHA;
     }
 #else
-    if (mPaintedLayer->MayResample()) {
+    if (mPaintedLayer.MayResample()) {
       mode = SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA;
       content = gfxContentType::COLOR_ALPHA;
     }
 #endif
   }
 
   if (aMode) {
     *aMode = mode;
@@ -397,17 +393,17 @@ TileClient::PrivateProtector::Set(TileCl
 void
 TileClient::PrivateProtector::Set(TileClient * const aContainer, TextureClient* aNewValue)
 {
   Set(aContainer, RefPtr<TextureClient>(aNewValue));
 }
 
 // Placeholder
 TileClient::TileClient()
-  : mCompositableClient(nullptr), mWasPlaceholder(false)
+  : mWasPlaceholder(false)
 {
 }
 
 TileClient::~TileClient()
 {
   if (mExpirationState.IsTracked()) {
     MOZ_ASSERT(mBackBuffer);
     TileExpiry::RemoveTile(this);
@@ -415,43 +411,39 @@ TileClient::~TileClient()
 }
 
 TileClient::TileClient(const TileClient& o)
 {
   mBackBuffer.Set(this, o.mBackBuffer);
   mBackBufferOnWhite = o.mBackBufferOnWhite;
   mFrontBuffer = o.mFrontBuffer;
   mFrontBufferOnWhite = o.mFrontBufferOnWhite;
-  mCompositableClient = o.mCompositableClient;
   mWasPlaceholder = o.mWasPlaceholder;
   mUpdateRect = o.mUpdateRect;
 #ifdef GFX_TILEDLAYER_DEBUG_OVERLAY
   mLastUpdate = o.mLastUpdate;
 #endif
-  mManager = o.mManager;
   mAllocator = o.mAllocator;
   mInvalidFront = o.mInvalidFront;
   mInvalidBack = o.mInvalidBack;
 }
 
 TileClient&
 TileClient::operator=(const TileClient& o)
 {
   if (this == &o) return *this;
   mBackBuffer.Set(this, o.mBackBuffer);
   mBackBufferOnWhite = o.mBackBufferOnWhite;
   mFrontBuffer = o.mFrontBuffer;
   mFrontBufferOnWhite = o.mFrontBufferOnWhite;
-  mCompositableClient = o.mCompositableClient;
   mWasPlaceholder = o.mWasPlaceholder;
   mUpdateRect = o.mUpdateRect;
 #ifdef GFX_TILEDLAYER_DEBUG_OVERLAY
   mLastUpdate = o.mLastUpdate;
 #endif
-  mManager = o.mManager;
   mAllocator = o.mAllocator;
   mInvalidFront = o.mInvalidFront;
   mInvalidBack = o.mInvalidBack;
   return *this;
 }
 
 void
 TileClient::Dump(std::stringstream& aStream)
@@ -589,17 +581,17 @@ TileClient::DiscardBackBuffer()
   DiscardTexture(mBackBuffer, mAllocator);
   mBackBuffer.Set(this, nullptr);
   DiscardTexture(mBackBufferOnWhite, mAllocator);
   mBackBufferOnWhite = nullptr;
 }
 
 static already_AddRefed<TextureClient>
 CreateBackBufferTexture(TextureClient* aCurrentTexture,
-                        CompositableClient* aCompositable,
+                        CompositableClient& aCompositable,
                         TextureClientAllocator* aAllocator)
 {
   if (aCurrentTexture) {
     // Our current back-buffer is still locked by the compositor. This can occur
     // when the client is producing faster than the compositor can consume. In
     // this case we just want to drop it and not return it to the pool.
     aAllocator->ReportClientLost();
   }
@@ -608,26 +600,27 @@ CreateBackBufferTexture(TextureClient* a
 
   if (!texture) {
     gfxCriticalError() << "[Tiling:Client] Failed to allocate a TextureClient";
     return nullptr;
   }
 
   texture->EnableReadLock();
 
-  if (!aCompositable->AddTextureClient(texture)) {
+  if (!aCompositable.AddTextureClient(texture)) {
     gfxCriticalError() << "[Tiling:Client] Failed to connect a TextureClient";
     return nullptr;
   }
 
   return texture.forget();
 }
 
 TextureClient*
-TileClient::GetBackBuffer(const nsIntRegion& aDirtyRegion,
+TileClient::GetBackBuffer(CompositableClient& aCompositable,
+                          const nsIntRegion& aDirtyRegion,
                           gfxContentType aContent,
                           SurfaceMode aMode,
                           nsIntRegion& aAddPaintedRegion,
                           RefPtr<TextureClient>* aBackBufferOnWhite)
 {
   if (aMode != SurfaceMode::SURFACE_COMPONENT_ALPHA) {
     // It can happen that a component-alpha layer stops being on component alpha
     // on the next frame, just drop the buffers on white if that happens.
@@ -649,30 +642,30 @@ TileClient::GetBackBuffer(const nsIntReg
         mFrontBufferOnWhite && !mFrontBufferOnWhite->IsReadLocked()))) {
     // If we had a backbuffer we no longer care about it since we'll
     // re-use the front buffer.
     DiscardBackBuffer();
     Flip();
   } else {
     if (!mBackBuffer || mBackBuffer->IsReadLocked()) {
       mBackBuffer.Set(this,
-        CreateBackBufferTexture(mBackBuffer, mCompositableClient, mAllocator)
+        CreateBackBufferTexture(mBackBuffer, aCompositable, mAllocator)
       );
       if (!mBackBuffer) {
         DiscardBackBuffer();
         DiscardFrontBuffer();
         return nullptr;
       }
       mInvalidBack = IntRect(IntPoint(), mBackBuffer->GetSize());
     }
 
     if (aMode == SurfaceMode::SURFACE_COMPONENT_ALPHA
         && (!mBackBufferOnWhite || mBackBufferOnWhite->IsReadLocked())) {
       mBackBufferOnWhite = CreateBackBufferTexture(
-        mBackBufferOnWhite, mCompositableClient, mAllocator
+        mBackBufferOnWhite, aCompositable, mAllocator
       );
       if (!mBackBufferOnWhite) {
         DiscardBackBuffer();
         DiscardFrontBuffer();
         return nullptr;
       }
       mInvalidBack = IntRect(IntPoint(), mBackBufferOnWhite->GetSize());
     }
@@ -759,18 +752,18 @@ ClientMultiTiledLayerBuffer::GetSurfaceD
 void
 ClientMultiTiledLayerBuffer::PaintThebes(const nsIntRegion& aNewValidRegion,
                                          const nsIntRegion& aPaintRegion,
                                          const nsIntRegion& aDirtyRegion,
                                          LayerManager::DrawPaintedLayerCallback aCallback,
                                          void* aCallbackData,
                                          bool aIsProgressive)
 {
-  TILING_LOG("TILING %p: PaintThebes painting region %s\n", mPaintedLayer, Stringify(aPaintRegion).c_str());
-  TILING_LOG("TILING %p: PaintThebes new valid region %s\n", mPaintedLayer, Stringify(aNewValidRegion).c_str());
+  TILING_LOG("TILING %p: PaintThebes painting region %s\n", &mPaintedLayer, Stringify(aPaintRegion).c_str());
+  TILING_LOG("TILING %p: PaintThebes new valid region %s\n", &mPaintedLayer, Stringify(aNewValidRegion).c_str());
 
   mCallback = aCallback;
   mCallbackData = aCallbackData;
   mWasLastPaintProgressive = aIsProgressive;
 
 #ifdef GFX_TILEDLAYER_PREF_WARNINGS
   long start = PR_IntervalNow();
 #endif
@@ -890,21 +883,21 @@ void PadDrawTargetOutFromRegion(RefPtr<D
 }
 
 void
 ClientTiledLayerBuffer::UnlockTile(TileClient& aTile)
 {
   // We locked the back buffer, and flipped so we now need to unlock the front
   if (aTile.mFrontBuffer && aTile.mFrontBuffer->IsLocked()) {
     aTile.mFrontBuffer->Unlock();
-    aTile.mFrontBuffer->SyncWithObject(mCompositableClient->GetForwarder()->GetSyncObject());
+    aTile.mFrontBuffer->SyncWithObject(mCompositableClient.GetForwarder()->GetSyncObject());
   }
   if (aTile.mFrontBufferOnWhite && aTile.mFrontBufferOnWhite->IsLocked()) {
     aTile.mFrontBufferOnWhite->Unlock();
-    aTile.mFrontBufferOnWhite->SyncWithObject(mCompositableClient->GetForwarder()->GetSyncObject());
+    aTile.mFrontBufferOnWhite->SyncWithObject(mCompositableClient.GetForwarder()->GetSyncObject());
   }
   if (aTile.mBackBuffer && aTile.mBackBuffer->IsLocked()) {
     aTile.mBackBuffer->Unlock();
   }
   if (aTile.mBackBufferOnWhite && aTile.mBackBufferOnWhite->IsLocked()) {
     aTile.mBackBufferOnWhite->Unlock();
   }
 }
@@ -979,17 +972,17 @@ void ClientMultiTiledLayerBuffer::Update
       }
       drawTarget->SetTransform(Matrix());
 
       RefPtr<gfxContext> ctx = gfxContext::CreateOrNull(drawTarget);
       MOZ_ASSERT(ctx); // already checked the draw target above
       ctx->SetMatrix(
         ctx->CurrentMatrix().Scale(mResolution, mResolution).Translate(ThebesPoint(-mTilingOrigin)));
 
-      mCallback(mPaintedLayer, ctx, aPaintRegion, aDirtyRegion,
+      mCallback(&mPaintedLayer, ctx, aPaintRegion, aDirtyRegion,
                 DrawRegionClip::DRAW, nsIntRegion(), mCallbackData);
       mMoz2DTiles.clear();
       // Reset:
       mTilingOrigin = IntPoint(std::numeric_limits<int32_t>::max(),
                                std::numeric_limits<int32_t>::max());
     }
 
     bool edgePaddingEnabled = gfxPrefs::TileEdgePaddingEnabled();
@@ -1047,31 +1040,30 @@ ClientMultiTiledLayerBuffer::ValidateTil
     printf_stderr("Complex region\n");
   }
 #endif
 
   SurfaceMode mode;
   gfxContentType content = GetContentType(&mode);
 
   if (aTile.IsPlaceholderTile()) {
-    aTile.SetLayerManager(mManager);
     aTile.SetTextureAllocator(mManager->GetCompositorBridgeChild()->GetTexturePool(
       mManager->GetCompositorBackendType(),
       gfxPlatform::GetPlatform()->Optimal2DFormatForContent(content),
       TextureFlags::DISALLOW_BIGIMAGE | TextureFlags::IMMEDIATE_UPLOAD));
   }
-  aTile.SetCompositableClient(mCompositableClient);
 
   nsIntRegion offsetScaledDirtyRegion = aDirtyRegion.MovedBy(-aTileOrigin);
   offsetScaledDirtyRegion.ScaleRoundOut(mResolution, mResolution);
 
   nsIntRegion extraPainted;
   RefPtr<TextureClient> backBufferOnWhite;
   RefPtr<TextureClient> backBuffer =
-    aTile.GetBackBuffer(offsetScaledDirtyRegion,
+    aTile.GetBackBuffer(mCompositableClient,
+                        offsetScaledDirtyRegion,
                         content, mode,
                         extraPainted,
                         &backBufferOnWhite);
 
   aTile.mUpdateRect = offsetScaledDirtyRegion.GetBounds().Union(extraPainted.GetBounds());
 
   extraPainted.MoveBy(aTileOrigin);
   extraPainted.And(extraPainted, mNewValidRegion);
@@ -1173,36 +1165,36 @@ ClientMultiTiledLayerBuffer::ComputeProg
   // assumption is that the contents is less important, so visual coherency
   // is lower priority than speed.
   bool drawingLowPrecision = IsLowPrecision();
 
   // Find out if we have any non-stale content to update.
   nsIntRegion staleRegion;
   staleRegion.And(aInvalidRegion, aOldValidRegion);
 
-  TILING_LOG("TILING %p: Progressive update stale region %s\n", mPaintedLayer, Stringify(staleRegion).c_str());
+  TILING_LOG("TILING %p: Progressive update stale region %s\n", &mPaintedLayer, Stringify(staleRegion).c_str());
 
   LayerMetricsWrapper scrollAncestor;
-  mPaintedLayer->GetAncestorLayers(&scrollAncestor, nullptr, nullptr);
+  mPaintedLayer.GetAncestorLayers(&scrollAncestor, nullptr, nullptr);
 
   // Find out the current view transform to determine which tiles to draw
   // first, and see if we should just abort this paint. Aborting is usually
   // caused by there being an incoming, more relevant paint.
   AsyncTransform viewTransform;
   MOZ_ASSERT(mSharedFrameMetricsHelper);
 
   bool abortPaint =
     mSharedFrameMetricsHelper->UpdateFromCompositorFrameMetrics(
       scrollAncestor,
       !staleRegion.Contains(aInvalidRegion),
       drawingLowPrecision,
       viewTransform);
 
   TILING_LOG("TILING %p: Progressive update view transform %s zoom %f abort %d\n",
-      mPaintedLayer, ToString(viewTransform.mTranslation).c_str(), viewTransform.mScale.scale, abortPaint);
+      &mPaintedLayer, ToString(viewTransform.mTranslation).c_str(), viewTransform.mScale.scale, abortPaint);
 
   if (abortPaint) {
     // We ignore if front-end wants to abort if this is the first,
     // non-low-precision paint, as in that situation, we're about to override
     // front-end's page/viewport metrics.
     if (!aPaintData->mFirstPaint || drawingLowPrecision) {
       PROFILER_LABEL("ClientMultiTiledLayerBuffer", "ComputeProgressiveUpdateRegion",
         js::ProfileEntry::Category::GRAPHICS);
@@ -1211,24 +1203,24 @@ ClientMultiTiledLayerBuffer::ComputeProg
       return aIsRepeated;
     }
   }
 
   Maybe<LayerRect> transformedCompositionBounds =
     GetCompositorSideCompositionBounds(scrollAncestor,
                                        aPaintData->mTransformToCompBounds,
                                        viewTransform,
-                                       ViewAs<LayerPixel>(Rect(mPaintedLayer->GetLayerBounds())));
+                                       ViewAs<LayerPixel>(Rect(mPaintedLayer.GetLayerBounds())));
 
   if (!transformedCompositionBounds) {
     aPaintData->mPaintFinished = true;
     return false;
   }
 
-  TILING_LOG("TILING %p: Progressive update transformed compositor bounds %s\n", mPaintedLayer, Stringify(*transformedCompositionBounds).c_str());
+  TILING_LOG("TILING %p: Progressive update transformed compositor bounds %s\n", &mPaintedLayer, Stringify(*transformedCompositionBounds).c_str());
 
   // Compute a "coherent update rect" that we should paint all at once in a
   // single transaction. This is to avoid rendering glitches on animated
   // page content, and when layers change size/shape.
   // On Fennec uploads are more expensive because we're not using gralloc, so
   // we use a coherent update rect that is intersected with the screen at the
   // time of issuing the draw command. This will paint faster but also potentially
   // make the progressive paint more visible to the user while scrolling.
@@ -1237,40 +1229,40 @@ ClientMultiTiledLayerBuffer::ComputeProg
   IntRect coherentUpdateRect(RoundedOut(
 #ifdef MOZ_WIDGET_ANDROID
     transformedCompositionBounds->Intersect(aPaintData->mCompositionBounds)
 #else
     *transformedCompositionBounds
 #endif
   ).ToUnknownRect());
 
-  TILING_LOG("TILING %p: Progressive update final coherency rect %s\n", mPaintedLayer, Stringify(coherentUpdateRect).c_str());
+  TILING_LOG("TILING %p: Progressive update final coherency rect %s\n", &mPaintedLayer, Stringify(coherentUpdateRect).c_str());
 
   aRegionToPaint.And(aInvalidRegion, coherentUpdateRect);
   aRegionToPaint.Or(aRegionToPaint, staleRegion);
   bool drawingStale = !aRegionToPaint.IsEmpty();
   if (!drawingStale) {
     aRegionToPaint = aInvalidRegion;
   }
 
   // Prioritise tiles that are currently visible on the screen.
   bool paintingVisible = false;
   if (aRegionToPaint.Intersects(coherentUpdateRect)) {
     aRegionToPaint.And(aRegionToPaint, coherentUpdateRect);
     paintingVisible = true;
   }
 
-  TILING_LOG("TILING %p: Progressive update final paint region %s\n", mPaintedLayer, Stringify(aRegionToPaint).c_str());
+  TILING_LOG("TILING %p: Progressive update final paint region %s\n", &mPaintedLayer, Stringify(aRegionToPaint).c_str());
 
   // Paint area that's visible and overlaps previously valid content to avoid
   // visible glitches in animated elements, such as gifs.
   bool paintInSingleTransaction = paintingVisible && (drawingStale || aPaintData->mFirstPaint);
 
   TILING_LOG("TILING %p: paintingVisible %d drawingStale %d firstPaint %d singleTransaction %d\n",
-    mPaintedLayer, paintingVisible, drawingStale, aPaintData->mFirstPaint, paintInSingleTransaction);
+    &mPaintedLayer, paintingVisible, drawingStale, aPaintData->mFirstPaint, paintInSingleTransaction);
 
   // The following code decides what order to draw tiles in, based on the
   // current scroll direction of the primary scrollable layer.
   NS_ASSERTION(!aRegionToPaint.IsEmpty(), "Unexpectedly empty paint region!");
   IntRect paintBounds = aRegionToPaint.GetBounds();
 
   int startX, incX, startY, incY;
   gfx::IntSize scaledTileSize = GetScaledTileSize();
@@ -1338,33 +1330,33 @@ ClientMultiTiledLayerBuffer::ComputeProg
 bool
 ClientMultiTiledLayerBuffer::ProgressiveUpdate(nsIntRegion& aValidRegion,
                                                nsIntRegion& aInvalidRegion,
                                                const nsIntRegion& aOldValidRegion,
                                                BasicTiledLayerPaintData* aPaintData,
                                                LayerManager::DrawPaintedLayerCallback aCallback,
                                                void* aCallbackData)
 {
-  TILING_LOG("TILING %p: Progressive update valid region %s\n", mPaintedLayer, Stringify(aValidRegion).c_str());
-  TILING_LOG("TILING %p: Progressive update invalid region %s\n", mPaintedLayer, Stringify(aInvalidRegion).c_str());
-  TILING_LOG("TILING %p: Progressive update old valid region %s\n", mPaintedLayer, Stringify(aOldValidRegion).c_str());
+  TILING_LOG("TILING %p: Progressive update valid region %s\n", &mPaintedLayer, Stringify(aValidRegion).c_str());
+  TILING_LOG("TILING %p: Progressive update invalid region %s\n", &mPaintedLayer, Stringify(aInvalidRegion).c_str());
+  TILING_LOG("TILING %p: Progressive update old valid region %s\n", &mPaintedLayer, Stringify(aOldValidRegion).c_str());
 
   bool repeat = false;
   bool isBufferChanged = false;
   do {
     // Compute the region that should be updated. Repeat as many times as
     // is required.
     nsIntRegion regionToPaint;
     repeat = ComputeProgressiveUpdateRegion(aInvalidRegion,
                                             aOldValidRegion,
                                             regionToPaint,
                                             aPaintData,
                                             repeat);
 
-    TILING_LOG("TILING %p: Progressive update computed paint region %s repeat %d\n", mPaintedLayer, Stringify(regionToPaint).c_str(), repeat);
+    TILING_LOG("TILING %p: Progressive update computed paint region %s repeat %d\n", &mPaintedLayer, Stringify(regionToPaint).c_str(), repeat);
 
     // There's no further work to be done.
     if (regionToPaint.IsEmpty()) {
       break;
     }
 
     isBufferChanged = true;
 
@@ -1378,18 +1370,18 @@ ClientMultiTiledLayerBuffer::Progressive
     validOrStale.Or(aValidRegion, aOldValidRegion);
 
     // Paint the computed region and subtract it from the invalid region.
     PaintThebes(validOrStale, regionToPaint, aInvalidRegion,
                 aCallback, aCallbackData, true);
     aInvalidRegion.Sub(aInvalidRegion, regionToPaint);
   } while (repeat);
 
-  TILING_LOG("TILING %p: Progressive update final valid region %s buffer changed %d\n", mPaintedLayer, Stringify(aValidRegion).c_str(), isBufferChanged);
-  TILING_LOG("TILING %p: Progressive update final invalid region %s\n", mPaintedLayer, Stringify(aInvalidRegion).c_str());
+  TILING_LOG("TILING %p: Progressive update final valid region %s buffer changed %d\n", &mPaintedLayer, Stringify(aValidRegion).c_str(), isBufferChanged);
+  TILING_LOG("TILING %p: Progressive update final invalid region %s\n", &mPaintedLayer, Stringify(aInvalidRegion).c_str());
 
   // Return false if nothing has been drawn, or give what has been drawn
   // to the shadow layer to upload.
   return isBufferChanged;
 }
 
 void
 TiledContentClient::PrintInfo(std::stringstream& aStream, const char* aPrefix)
--- a/gfx/layers/client/TiledContentClient.h
+++ b/gfx/layers/client/TiledContentClient.h
@@ -65,30 +65,21 @@ struct TileClient
     return mFrontBuffer == o.mFrontBuffer;
   }
 
   bool operator!= (const TileClient& o) const
   {
     return mFrontBuffer != o.mFrontBuffer;
   }
 
-  void SetLayerManager(ClientLayerManager *aManager)
-  {
-    mManager = aManager;
-  }
   void SetTextureAllocator(TextureClientAllocator* aAllocator)
   {
     mAllocator = aAllocator;
   }
 
-  void SetCompositableClient(CompositableClient* aCompositableClient)
-  {
-    mCompositableClient = aCompositableClient;
-  }
-
   bool IsPlaceholderTile() const
   {
     return mBackBuffer == nullptr && mFrontBuffer == nullptr;
   }
 
   void DiscardBuffers()
   {
     DiscardFrontBuffer();
@@ -121,17 +112,18 @@ struct TileClient
   * internal buffer (and so will always be locked).
   *
   * If getting the back buffer required copying pixels from the front buffer
   * then the copied region is stored in aAddPaintedRegion so the host side
   * knows to upload it.
   *
   * If nullptr is returned, aTextureClientOnWhite is undefined.
   */
-  TextureClient* GetBackBuffer(const nsIntRegion& aDirtyRegion,
+  TextureClient* GetBackBuffer(CompositableClient&,
+                               const nsIntRegion& aDirtyRegion,
                                gfxContentType aContent, SurfaceMode aMode,
                                nsIntRegion& aAddPaintedRegion,
                                RefPtr<TextureClient>* aTextureClientOnWhite);
 
   void DiscardFrontBuffer();
 
   void DiscardBackBuffer();
 
@@ -148,20 +140,18 @@ struct TileClient
       RefPtr<TextureClient> operator ->() { return mBuffer; }
     private:
       PrivateProtector& operator=(const PrivateProtector &);
       RefPtr<TextureClient> mBuffer;
   } mBackBuffer;
   RefPtr<TextureClient> mBackBufferOnWhite;
   RefPtr<TextureClient> mFrontBuffer;
   RefPtr<TextureClient> mFrontBufferOnWhite;
-  RefPtr<ClientLayerManager> mManager;
   RefPtr<TextureClientAllocator> mAllocator;
   gfx::IntRect mUpdateRect;
-  CompositableClient* mCompositableClient;
   bool mWasPlaceholder;
 #ifdef GFX_TILEDLAYER_DEBUG_OVERLAY
   TimeStamp        mLastUpdate;
 #endif
   nsIntRegion mInvalidFront;
   nsIntRegion mInvalidBack;
   nsExpirationState mExpirationState;
 private:
@@ -284,18 +274,18 @@ private:
  * This buffer provides an implementation of ValidateTile using a
  * thebes callback and can support painting using a single paint buffer.
  * Whether a single paint buffer is used is controlled by
  * gfxPrefs::PerTileDrawing().
  */
 class ClientTiledLayerBuffer
 {
 public:
-  ClientTiledLayerBuffer(ClientTiledPaintedLayer* aPaintedLayer,
-                         CompositableClient* aCompositableClient)
+  ClientTiledLayerBuffer(ClientTiledPaintedLayer& aPaintedLayer,
+                         CompositableClient& aCompositableClient)
     : mPaintedLayer(aPaintedLayer)
     , mCompositableClient(aCompositableClient)
     , mLastPaintContentType(gfxContentType::COLOR)
     , mLastPaintSurfaceMode(SurfaceMode::SURFACE_OPAQUE)
     , mWasLastPaintProgressive(false)
   {}
 
   virtual void PaintThebes(const nsIntRegion& aNewValidRegion,
@@ -327,45 +317,36 @@ public:
   void SetFrameResolution(const CSSToParentLayerScale2D& aResolution) { mFrameResolution = aResolution; }
 
   bool HasFormatChanged() const;
 
 protected:
   void UnlockTile(TileClient& aTile);
   gfxContentType GetContentType(SurfaceMode* aMode = nullptr) const;
 
-  ClientTiledPaintedLayer* mPaintedLayer;
-  CompositableClient* mCompositableClient;
+  ClientTiledPaintedLayer& mPaintedLayer;
+  CompositableClient& mCompositableClient;
 
   gfxContentType mLastPaintContentType;
   SurfaceMode mLastPaintSurfaceMode;
   CSSToParentLayerScale2D mFrameResolution;
 
   bool mWasLastPaintProgressive;
 };
 
 class ClientMultiTiledLayerBuffer
   : public TiledLayerBuffer<ClientMultiTiledLayerBuffer, TileClient>
   , public ClientTiledLayerBuffer
 {
   friend class TiledLayerBuffer<ClientMultiTiledLayerBuffer, TileClient>;
 public:
-  ClientMultiTiledLayerBuffer(ClientTiledPaintedLayer* aPaintedLayer,
-                              CompositableClient* aCompositableClient,
+  ClientMultiTiledLayerBuffer(ClientTiledPaintedLayer& aPaintedLayer,
+                              CompositableClient& aCompositableClient,
                               ClientLayerManager* aManager,
                               SharedFrameMetricsHelper* aHelper);
-  ClientMultiTiledLayerBuffer()
-    : ClientTiledLayerBuffer(nullptr, nullptr)
-    , mManager(nullptr)
-    , mCallback(nullptr)
-    , mCallbackData(nullptr)
-    , mSharedFrameMetricsHelper(nullptr)
-    , mTilingOrigin(std::numeric_limits<int32_t>::max(),
-                    std::numeric_limits<int32_t>::max())
-  {}
 
   void PaintThebes(const nsIntRegion& aNewValidRegion,
                    const nsIntRegion& aPaintRegion,
                    const nsIntRegion& aDirtyRegion,
                    LayerManager::DrawPaintedLayerCallback aCallback,
                    void* aCallbackData,
                    bool aIsProgressive = false) override;
 
@@ -430,17 +411,17 @@ protected:
   
   void Update(const nsIntRegion& aNewValidRegion,
               const nsIntRegion& aPaintRegion,
               const nsIntRegion& aDirtyRegion);
 
   TileClient GetPlaceholderTile() const { return TileClient(); }
 
 private:
-  ClientLayerManager* mManager;
+  RefPtr<ClientLayerManager> mManager;
   LayerManager::DrawPaintedLayerCallback mCallback;
   void* mCallbackData;
 
   // The region that will be made valid during Update(). Once Update() is
   // completed then this is identical to mValidRegion.
   nsIntRegion mNewValidRegion;
 
   SharedFrameMetricsHelper*  mSharedFrameMetricsHelper;
@@ -522,17 +503,17 @@ private:
 
 /**
  * An implementation of TiledContentClient that supports
  * multiple tiles and a low precision buffer.
  */
 class MultiTiledContentClient : public TiledContentClient
 {
 public:
-  MultiTiledContentClient(ClientTiledPaintedLayer* aPaintedLayer,
+  MultiTiledContentClient(ClientTiledPaintedLayer& aPaintedLayer,
                           ClientLayerManager* aManager);
 
 protected:
   ~MultiTiledContentClient()
   {
     MOZ_COUNT_DTOR(MultiTiledContentClient);
 
       mTiledBuffer.DiscardBuffers();