Bug 803826 - Restore the layer builder pointer on return from PaintForFrame. r=mattwoodrow, a=bajaj
authorChris Lord <chrislord.net@gmail.com>
Tue, 23 Oct 2012 12:01:23 +0100
changeset 113715 0633ae7db53fd1b89c870b1213e39ff8e50e0bf8
parent 113714 3b3c91fdbbb91487fc5ba3f6db72d172705ab2f6
child 113716 fde0347f1e03242d12b5d37ea87fc153da445524
push id2481
push userryanvm@gmail.com
push dateSat, 27 Oct 2012 23:58:38 +0000
treeherdermozilla-aurora@8447e7c219ca [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow, bajaj
bugs803826
milestone18.0a2
Bug 803826 - Restore the layer builder pointer on return from PaintForFrame. r=mattwoodrow, a=bajaj It's possible for nsDisplayList::PaintForFrame to reset the layer builder pointer on a layer manager it didn't create. Instead of setting it to null, store the existing pointer and restore it on return.
layout/base/nsDisplayList.cpp
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -1008,16 +1008,19 @@ void nsDisplayList::PaintForFrame(nsDisp
   if (!layerManager) {
     if (!aCtx) {
       NS_WARNING("Nowhere to paint into");
       return;
     }
     layerManager = new BasicLayerManager();
   }
 
+  // Store the existing layer builder to reinstate it on return.
+  FrameLayerBuilder *oldBuilder = layerManager->GetLayerBuilder();
+
   FrameLayerBuilder *layerBuilder = new FrameLayerBuilder();
   layerBuilder->Init(aBuilder, layerManager);
 
   if (aFlags & PAINT_FLUSH_LAYERS) {
     FrameLayerBuilder::InvalidateAllLayers(layerManager);
   }
 
   if (doBeginTransaction) {
@@ -1044,23 +1047,23 @@ void nsDisplayList::PaintForFrame(nsDisp
                                      LayerProperties::CloneFrom(layerManager->GetRoot()) : 
                                      nullptr);
 
   nsDisplayItem::ContainerParameters containerParameters
     (presShell->GetXResolution(), presShell->GetYResolution());
   nsRefPtr<ContainerLayer> root = layerBuilder->
     BuildContainerLayerFor(aBuilder, layerManager, aForFrame, nullptr, *this,
                            containerParameters, nullptr);
-  
+
   if (widgetTransaction) {
     aForFrame->ClearInvalidationStateBits();
   }
 
   if (!root) {
-    layerManager->RemoveUserData(&gLayerManagerLayerBuilder);
+    layerManager->SetUserData(&gLayerManagerLayerBuilder, oldBuilder);
     return;
   }
   // Root is being scaled up by the X/Y resolution. Scale it back down.
   root->SetPostScale(1.0f/containerParameters.mXScale,
                      1.0f/containerParameters.mYScale);
 
   ViewID id = presContext->IsRootContentDocument() ? FrameMetrics::ROOT_SCROLL_ID
                                                    : FrameMetrics::NULL_SCROLL_ID;
@@ -1129,17 +1132,17 @@ void nsDisplayList::PaintForFrame(nsDisp
     }
   }
 
   if (aFlags & PAINT_FLUSH_LAYERS) {
     FrameLayerBuilder::InvalidateAllLayers(layerManager);
   }
 
   nsCSSRendering::DidPaint();
-  layerManager->RemoveUserData(&gLayerManagerLayerBuilder);
+  layerManager->SetUserData(&gLayerManagerLayerBuilder, oldBuilder);
 }
 
 uint32_t nsDisplayList::Count() const {
   uint32_t count = 0;
   for (nsDisplayItem* i = GetBottom(); i; i = i->GetAbove()) {
     ++count;
   }
   return count;