Bug 539356 - Fix mActiveScrolledRootOffset to be offset to the reference frame. r=mattwoodrow
authorRobert O'Callahan <robert@ocallahan.org>
Fri, 28 Sep 2012 01:07:40 +1200
changeset 108406 920cf04e0fe08b8cd6188c45d2b8016e2fa9b495
parent 108405 66f6deffdc70c9f8a9d129d2cbfc113c82bbdb1c
child 108407 e70defa600998189fbccb642e214e51c44468d43
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersmattwoodrow
bugs539356
milestone18.0a1
Bug 539356 - Fix mActiveScrolledRootOffset to be offset to the reference frame. r=mattwoodrow
layout/base/FrameLayerBuilder.cpp
layout/base/FrameLayerBuilder.h
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -133,26 +133,30 @@ static inline MaskLayerImageCache* GetMa
  * a ContainerLayer.
  */
 class ContainerState {
 public:
   ContainerState(nsDisplayListBuilder* aBuilder,
                  LayerManager* aManager,
                  FrameLayerBuilder* aLayerBuilder,
                  nsIFrame* aContainerFrame,
+                 nsDisplayItem* aContainerItem,
                  ContainerLayer* aContainerLayer,
                  const FrameLayerBuilder::ContainerParameters& aParameters) :
     mBuilder(aBuilder), mManager(aManager),
     mLayerBuilder(aLayerBuilder),
-    mContainerFrame(aContainerFrame), mContainerLayer(aContainerLayer),
+    mContainerFrame(aContainerFrame),
+    mContainerLayer(aContainerLayer),
     mParameters(aParameters),
     mNextFreeRecycledThebesLayer(0)
   {
     nsPresContext* presContext = aContainerFrame->PresContext();
     mAppUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
+    mContainerReferenceFrame = aContainerItem ? aContainerItem->ReferenceFrame() :
+      mBuilder->FindReferenceFrameFor(mContainerFrame);
     // When AllowResidualTranslation is false, display items will be drawn
     // scaled with a translation by integer pixels, so we know how the snapping
     // will work.
     mSnappingEnabled = aManager->IsSnappingEffectiveTransforms() &&
       !mParameters.AllowResidualTranslation();
     mRecycledMaskImageLayers.Init();
     CollectOldLayers();
   }
@@ -301,17 +305,17 @@ protected:
      * Same coordinate system as mVisibleRegion.
      */
     nsIntRegion  mOpaqueRegion;
     /**
      * The "active scrolled root" for all content in the layer. Must
      * be non-null; all content in a ThebesLayer must have the same
      * active scrolled root.
      */
-    const nsIFrame*    mActiveScrolledRoot;
+    const nsIFrame* mActiveScrolledRoot;
     ThebesLayer* mLayer;
     /**
      * If mIsSolidColorInVisibleRegion is true, this is the color of the visible
      * region.
      */
     nscolor      mSolidColor;
     /**
      * True if every pixel in mVisibleRegion will have color mSolidColor.
@@ -362,17 +366,19 @@ protected:
   friend class ThebesLayerData;
 
   /**
    * Grab the next recyclable ThebesLayer, or create one if there are no
    * more recyclable ThebesLayers. Does any necessary invalidation of
    * a recycled ThebesLayer, and sets up the transform on the ThebesLayer
    * to account for scrolling.
    */
-  already_AddRefed<ThebesLayer> CreateOrRecycleThebesLayer(const nsIFrame* aActiveScrolledRoot, const nsIFrame *aReferenceFrame);
+  already_AddRefed<ThebesLayer> CreateOrRecycleThebesLayer(const nsIFrame* aActiveScrolledRoot, 
+                                                           const nsIFrame *aReferenceFrame, 
+                                                           const nsPoint& aTopLeft);
   /**
    * Grab the next recyclable ColorLayer, or create one if there are no
    * more recyclable ColorLayers.
    */
   already_AddRefed<ColorLayer> CreateOrRecycleColorLayer(ThebesLayer* aThebes);
   /**
    * Grab the next recyclable ImageLayer, or create one if there are no
    * more recyclable ImageLayers.
@@ -427,17 +433,18 @@ protected:
    * @param aOpaqueRect if non-null, a region of the display item that is opaque
    * @param aSolidColor if non-null, indicates that every pixel in aVisibleRect
    * will be painted with aSolidColor by the item
    */
   ThebesLayerData* FindThebesLayerFor(nsDisplayItem* aItem,
                                                    const nsIntRect& aVisibleRect,
                                                    const nsIntRect& aDrawRect,
                                                    const FrameLayerBuilder::Clip& aClip,
-                                                   const nsIFrame* aActiveScrolledRoot);
+                                                   const nsIFrame* aActiveScrolledRoot,
+                                                   const nsPoint& aTopLeft);
   ThebesLayerData* GetTopThebesLayerData()
   {
     return mThebesLayerDataStack.IsEmpty() ? nullptr
         : mThebesLayerDataStack[mThebesLayerDataStack.Length() - 1].get();
   }
 
   /* Build a mask layer to represent the clipping region. Will return null if
    * there is no clipping specified or a mask layer cannot be built.
@@ -450,16 +457,17 @@ protected:
    */
   void SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aClip,
                       uint32_t aRoundedRectClipCount = PR_UINT32_MAX);
 
   nsDisplayListBuilder*            mBuilder;
   LayerManager*                    mManager;
   FrameLayerBuilder*               mLayerBuilder;
   nsIFrame*                        mContainerFrame;
+  const nsIFrame*                  mContainerReferenceFrame;
   ContainerLayer*                  mContainerLayer;
   FrameLayerBuilder::ContainerParameters mParameters;
   /**
    * The region of ThebesLayers that should be invalidated every time
    * we recycle one.
    */
   nsIntRegion                      mInvalidThebesContent;
   nsRect                           mBounds;
@@ -530,18 +538,19 @@ public:
    * 0,0 may not be exactly the top-left of the active scrolled root. Here we
    * store the coordinates in ThebesLayer space of the top-left of the
    * active scrolled root.
    */
   gfxPoint mActiveScrolledRootPosition;
 
   nsIntRegion mRegionToInvalidate;
 
-  // The result of GetPosition() for the active scrolled root of this layer
-  // for the previous and current paints respectively.
+  // The offset between the active scrolled root of this layer
+  // and the root of the container for the previous and current 
+  // paints respectively.
   nsPoint mLastActiveScrolledRootOrigin;
   nsPoint mActiveScrolledRootOrigin;
 
   nsRefPtr<ColorLayer> mColorLayer;
   nsRefPtr<ImageLayer> mImageLayer;
 };
 
 /*
@@ -850,16 +859,17 @@ FrameLayerBuilder::RemoveFrameFromLayerM
       if (data) {
         nsRegion old = entry->mData[i]->mGeometry->ComputeInvalidationRegion();
         nsIntRegion rgn = old.ScaleToOutsidePixels(data->mXScale, data->mYScale, data->mAppUnitsPerDevPixel);
         rgn.MoveBy(-GetTranslationForThebesLayer(t));
         data->mRegionToInvalidate.Or(data->mRegionToInvalidate, rgn);
       }
     }
   }
+
   sDestroyedFrame = aFrame;
   data->mFramesWithLayers.RemoveEntry(aFrame);
   sDestroyedFrame = NULL;
 }
 
 void
 FrameLayerBuilder::DidBeginRetainedLayerTransaction(LayerManager* aManager)
 {
@@ -1356,17 +1366,19 @@ InvalidateEntireThebesLayer(ThebesLayer*
   printf("Invalidating entire layer %p\n", aLayer);
 #endif
   nsIntRect invalidate = aLayer->GetValidRegion().GetBounds();
   aLayer->InvalidateRegion(invalidate);
   ResetScrollPositionForLayerPixelAlignment(aActiveScrolledRoot);
 }
 
 already_AddRefed<ThebesLayer>
-ContainerState::CreateOrRecycleThebesLayer(const nsIFrame* aActiveScrolledRoot, const nsIFrame* aReferenceFrame)
+ContainerState::CreateOrRecycleThebesLayer(const nsIFrame* aActiveScrolledRoot,
+                                           const nsIFrame* aReferenceFrame,
+                                           const nsPoint& aTopLeft)
 {
   // We need a new thebes layer
   nsRefPtr<ThebesLayer> layer;
   ThebesDisplayItemLayerUserData* data;
   bool didResetScrollPositionForLayerPixelAlignment = false;
   if (mNextFreeRecycledThebesLayer < mRecycledThebesLayers.Length()) {
     // Recycle a layer
     layer = mRecycledThebesLayers[mNextFreeRecycledThebesLayer];
@@ -1418,17 +1430,17 @@ ContainerState::CreateOrRecycleThebesLay
     data = new ThebesDisplayItemLayerUserData();
     layer->SetUserData(&gThebesDisplayItemLayerUserData, data);
     ResetScrollPositionForLayerPixelAlignment(aActiveScrolledRoot);
     didResetScrollPositionForLayerPixelAlignment = true;
   }
   data->mXScale = mParameters.mXScale;
   data->mYScale = mParameters.mYScale;
   data->mLastActiveScrolledRootOrigin = data->mActiveScrolledRootOrigin;
-  data->mActiveScrolledRootOrigin = aActiveScrolledRoot->GetPosition();
+  data->mActiveScrolledRootOrigin = aTopLeft;
   data->mAppUnitsPerDevPixel = mAppUnitsPerDevPixel;
   layer->SetAllowResidualTranslation(mParameters.AllowResidualTranslation());
 
   mLayerBuilder->SaveLastPaintOffset(layer);
 
   // Set up transform so that 0,0 in the Thebes layer corresponds to the
   // (pixel-snapped) top-left of the aActiveScrolledRoot.
   nsPoint offset = aActiveScrolledRoot->GetOffsetToCrossDoc(aReferenceFrame);
@@ -1508,40 +1520,16 @@ RestrictVisibleRegionForLayer(Layer* aLa
 
   nsIntRegion rgn = aLayer->GetVisibleRegion();
   if (!visibleRect.Contains(rgn.GetBounds())) {
     rgn.And(rgn, visibleRect);
     aLayer->SetVisibleRegion(rgn);
   }
 }
 
-static void
-SetVisibleRegionForLayer(Layer* aLayer, const nsIntRect& aItemVisible, const nsIntRect& aChildBounds)
-{
-  gfx3DMatrix transform = aLayer->GetTransform();
-
-  // if 'transform' is not invertible, then nothing will be displayed
-  // for the layer, so it doesn't really matter what we do here
-  gfxRect itemVisible(aItemVisible.x, aItemVisible.y, aItemVisible.width, aItemVisible.height);
-  gfxRect layerVisible = transform.Inverse().ProjectRectBounds(itemVisible);
-  layerVisible.RoundOut();
-
-  nsIntRect visibleRect;
-  if (!gfxUtils::GfxRectToIntRect(layerVisible, &visibleRect))
-    return;
-
-  nsIntRegion rgn = aChildBounds;
-  if (!visibleRect.Contains(aChildBounds)) {
-    rgn.And(rgn, visibleRect);
-    aLayer->SetVisibleRegion(rgn);
-  } else {
-    aLayer->SetVisibleRegion(aChildBounds);
-  }
-}
-
 nscolor
 ContainerState::FindOpaqueBackgroundColorFor(int32_t aThebesLayerIndex)
 {
   ThebesLayerData* target = mThebesLayerDataStack[aThebesLayerIndex];
   for (int32_t i = aThebesLayerIndex - 1; i >= 0; --i) {
     ThebesLayerData* candidate = mThebesLayerDataStack[i];
     nsIntRegion visibleAboveIntersection;
     visibleAboveIntersection.And(candidate->mVisibleAboveRegion, target->mVisibleRegion);
@@ -1912,17 +1900,18 @@ ContainerState::ThebesLayerData::Accumul
   }
 }
 
 ContainerState::ThebesLayerData*
 ContainerState::FindThebesLayerFor(nsDisplayItem* aItem,
                                    const nsIntRect& aVisibleRect,
                                    const nsIntRect& aDrawRect,
                                    const FrameLayerBuilder::Clip& aClip,
-                                   const nsIFrame* aActiveScrolledRoot)
+                                   const nsIFrame* aActiveScrolledRoot,
+                                   const nsPoint& aTopLeft)
 {
   int32_t i;
   int32_t lowestUsableLayerWithScrolledRoot = -1;
   int32_t topmostLayerWithScrolledRoot = -1;
   for (i = mThebesLayerDataStack.Length() - 1; i >= 0; --i) {
     ThebesLayerData* data = mThebesLayerDataStack[i];
     if (data->mDrawAboveRegion.Intersects(aVisibleRect)) {
       ++i;
@@ -1952,17 +1941,17 @@ ContainerState::FindThebesLayerFor(nsDis
     while (uint32_t(topmostLayerWithScrolledRoot + 1) < mThebesLayerDataStack.Length()) {
       PopThebesLayerData();
     }
   }
 
   nsRefPtr<ThebesLayer> layer;
   ThebesLayerData* thebesLayerData = nullptr;
   if (lowestUsableLayerWithScrolledRoot < 0) {
-    layer = CreateOrRecycleThebesLayer(aActiveScrolledRoot, aItem->ReferenceFrame());
+    layer = CreateOrRecycleThebesLayer(aActiveScrolledRoot, aItem->ReferenceFrame(), aTopLeft);
 
     NS_ASSERTION(!mNewChildLayers.Contains(layer), "Layer already in list???");
     mNewChildLayers.AppendElement(layer);
 
     thebesLayerData = new ThebesLayerData();
     mThebesLayerDataStack.AppendElement(thebesLayerData);
     thebesLayerData->mLayer = layer;
     thebesLayerData->mActiveScrolledRoot = aActiveScrolledRoot;
@@ -2091,28 +2080,30 @@ ContainerState::ProcessDisplayItems(cons
     mBounds.UnionRect(mBounds, itemContent);
     itemVisibleRect.IntersectRect(itemVisibleRect, itemDrawRect);
 
     LayerState layerState = item->GetLayerState(mBuilder, mManager, mParameters);
 
     bool isFixed;
     bool forceInactive;
     const nsIFrame* activeScrolledRoot;
+    nsPoint topLeft;
     if (aFlags & NO_COMPONENT_ALPHA) {
       // When NO_COMPONENT_ALPHA is set, items will be flattened onto the
       // reference frame. In this case, force the active scrolled root to
       // that frame.
       forceInactive = true;
-      activeScrolledRoot = mBuilder->FindReferenceFrameFor(mContainerFrame);
+      activeScrolledRoot = mContainerReferenceFrame;
+      topLeft = nsPoint(0, 0);
       isFixed = mBuilder->IsFixedItem(item, nullptr, activeScrolledRoot);
     } else {
       forceInactive = false;
       isFixed = mBuilder->IsFixedItem(item, &activeScrolledRoot);
+      topLeft = activeScrolledRoot->GetOffsetToCrossDoc(mContainerReferenceFrame);
     }
-    nsPoint topLeft = activeScrolledRoot->GetPosition();
 
     // Assign the item to a layer
     if (layerState == LAYER_ACTIVE_FORCE ||
         (!forceInactive &&
          (layerState == LAYER_ACTIVE_EMPTY ||
           layerState == LAYER_ACTIVE))) {
 
       // LAYER_ACTIVE_EMPTY means the layer is created just for its metadata.
@@ -2195,17 +2186,17 @@ ContainerState::ProcessDisplayItems(cons
 
       mNewChildLayers.AppendElement(ownLayer);
       mLayerBuilder->AddLayerDisplayItem(ownLayer, item, 
                                          aClip, layerState, 
                                          topLeft, nullptr);
     } else {
       ThebesLayerData* data =
         FindThebesLayerFor(item, itemVisibleRect, itemDrawRect, aClip,
-                           activeScrolledRoot);
+                           activeScrolledRoot, topLeft);
 
       data->mLayer->SetIsFixedPosition(isFixed);
 
       InvalidateForLayerChange(item, data->mLayer, aClip, topLeft);
 
       mLayerBuilder->AddThebesDisplayItem(data->mLayer, item, aClip,
                                           mContainerFrame,
                                           layerState, topLeft);
@@ -2228,20 +2219,17 @@ ContainerState::InvalidateForLayerChange
   uint32_t key = aItem->GetPerFrameKey();
   NS_ASSERTION(key, "Display items that render using Thebes must have a key");
   nsDisplayItemGeometry *oldGeometry = NULL;
   FrameLayerBuilder::Clip* oldClip = NULL;
   nsAutoPtr<nsDisplayItemGeometry> geometry(aItem->AllocateGeometry(mBuilder));
   Layer* oldLayer = mLayerBuilder->GetOldLayerFor(aItem, &oldGeometry, &oldClip);
   if (aNewLayer != oldLayer && oldLayer) {
     // The item has changed layers.
-    // Invalidate the bounds in the old layer and new layer.
-    // The bounds might have changed, but we assume that any difference
-    // in the bounds will have been invalidated for all Thebes layers
-    // in the container via regular frame invalidation.
+    // Invalidate the old bounds in the old layer and new bounds in the new layer.
     ThebesLayer* t = oldLayer->AsThebesLayer();
     if (t) {
       // Note that whenever the layer's scale changes, we invalidate the whole thing,
       // so it doesn't matter whether we are using the old scale at last paint
       // or a new scale here
 #ifdef DEBUG_INVALIDATIONS
       printf("Display item type %s(%p) changed layers %p to %p!\n", aItem->Name(), f, t, aNewLayer);
 #endif
@@ -2749,56 +2737,25 @@ FrameLayerBuilder::RestoreThebesLayerIte
       aEntry->mItems.TruncateLength(i);
       return PL_DHASH_NEXT;
     }
   }
 
   return PL_DHASH_NEXT;
 }
 
-static nsDisplayTransform* FindTransformForContainerFrame(nsIFrame* aContainerFrame,
-                                                          nsDisplayItem* aContainerItem)
-{
-  if (!aContainerFrame->IsTransformed() ||
-      aContainerItem->GetType() == nsDisplayItem::TYPE_TRANSFORM)
-    return nullptr;
-
-  nsTArray<nsDisplayItem*> queue;
-  queue.AppendElement(aContainerItem);
-  while (queue.Length()) {
-    nsDisplayItem* item = queue[queue.Length() - 1];
-    queue.RemoveElementAt(queue.Length() - 1);
-
-    if (item->GetType() == nsDisplayItem::TYPE_TRANSFORM) {
-      return static_cast<nsDisplayTransform*>(item);
-    }
-
-    if (item->GetList()) {
-      for (nsDisplayItem* child = item->GetList()->GetBottom(); child;
-           child = child->GetAbove()) {
-        if (child->GetUnderlyingFrame() == aContainerFrame) {
-          queue.AppendElement(child);
-        }
-      }
-    }
-  }
-
-  return nullptr;
-}
-
 already_AddRefed<ContainerLayer>
 FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
                                           LayerManager* aManager,
                                           nsIFrame* aContainerFrame,
                                           nsDisplayItem* aContainerItem,
                                           const nsDisplayList& aChildren,
                                           const ContainerParameters& aParameters,
                                           const gfx3DMatrix* aTransform)
 {
-  FrameProperties props = aContainerFrame->Properties();
   uint32_t containerDisplayItemKey =
     aContainerItem ? aContainerItem->GetPerFrameKey() : 0;
   NS_ASSERTION(aContainerFrame, "Container display items here should have a frame");
   NS_ASSERTION(!aContainerItem ||
                aContainerItem->GetUnderlyingFrame() == aContainerFrame,
                "Container display item must match given frame");
 
   nsRefPtr<ContainerLayer> containerLayer;
@@ -2899,17 +2856,18 @@ FrameLayerBuilder::BuildContainerLayerFo
     (aContainerFrame->GetStateBits() & NS_FRAME_NO_COMPONENT_ALPHA) ?
       ContainerState::NO_COMPONENT_ALPHA : 0;
   uint32_t flags;
   
   LayerManagerData* data = static_cast<LayerManagerData*>
     (aManager->GetUserData(&gLayerManagerUserData));
   while (true) {
     ContainerState state(aBuilder, aManager, aManager->GetLayerBuilder(),
-                         aContainerFrame, containerLayer, scaleParameters);
+                         aContainerFrame, aContainerItem,
+                         containerLayer, scaleParameters);
     
     Clip clip;
     state.ProcessDisplayItems(aChildren, clip, stateFlags);
 
     // Set CONTENT_COMPONENT_ALPHA if any of our children have it.
     // This is suboptimal ... a child could have text that's over transparent
     // pixels in its own layer, but over opaque parts of previous siblings.
     state.Finish(&flags, data);
--- a/layout/base/FrameLayerBuilder.h
+++ b/layout/base/FrameLayerBuilder.h
@@ -59,19 +59,17 @@ public:
 /**
  * The FrameLayerBuilder is responsible for converting display lists 
  * into layer trees. Every LayerManager needs a unique FrameLayerBuilder
  * to build layers.
  * 
  * The most important API in this class is BuildContainerLayerFor. This
  * method takes a display list as input and constructs a ContainerLayer
  * with child layers that render the contents of the display list. It
- * also updates userdata for the retained layer manager, and
- * DisplayItemDataProperty data for frames, to record the relationship
- * between frames and layers.
+ * records the relationship between frames and layers.
  * 
  * That data enables us to retain layer trees. When constructing a
  * ContainerLayer, we first check to see if there's an existing
  * ContainerLayer for the same frame that can be recycled. If we recycle
  * it, we also try to reuse its existing ThebesLayer children to render
  * the display items without layers of their own. The idea is that by
  * recycling layers deterministically, we can ensure that when nothing
  * changes in a display list, we will reuse the existing layers without
@@ -80,17 +78,17 @@ public:
  * We expose a GetLeafLayerFor method that can be called by display items
  * that make their own layers (e.g. canvas and video); this method
  * locates the last layer used to render the display item, if any, and
  * return it as a candidate for recycling.
  * 
  * FrameLayerBuilder sets up ThebesLayers so that 0,0 in the Thebes layer
  * corresponds to the (pixel-snapped) top-left of the aActiveScrolledRoot.
  * It sets up ContainerLayers so that 0,0 in the container layer
- * corresponds to the snapped top-left of the display list reference frame.
+ * corresponds to the snapped top-left of the display item reference frame.
  *
  * When we construct a container layer, we know the transform that will be
  * applied to the layer. If the transform scales the content, we can get
  * better results when intermediate buffers are used by pushing some scale
  * from the container's transform down to the children. For ThebesLayer
  * children, the scaling can be achieved by changing the size of the layer
  * and drawing into it with increased or decreased resolution. By convention,
  * integer types (nsIntPoint/nsIntSize/nsIntRect/nsIntRegion) are all in layer
@@ -261,32 +259,34 @@ public:
    */
 
   /**
    * Record aItem as a display item that is rendered by aLayer.
    *
    * @param aLayer Layer that the display item will be rendered into
    * @param aItem Display item to be drawn.
    * @param aLayerState What LayerState the item is using.
+   * @param aTopLeft offset from active scrolled root to reference frame
    * @param aManager If the layer is in the LAYER_INACTIVE state,
    * then this is the temporary layer manager to draw with.
    */
   struct Clip;
   void AddLayerDisplayItem(Layer* aLayer,
                            nsDisplayItem* aItem,
                            const Clip& aClip,
                            LayerState aLayerState,
                            const nsPoint& aTopLeft,
                            LayerManager* aManager = nullptr);
 
   /**
    * Record aItem as a display item that is rendered by the ThebesLayer
    * aLayer, with aClipRect, where aContainerLayerFrame is the frame
    * for the container layer this ThebesItem belongs to.
    * aItem must have an underlying frame.
+   * @param aTopLeft offset from active scrolled root to reference frame
    */
   void AddThebesDisplayItem(ThebesLayer* aLayer,
                             nsDisplayItem* aItem,
                             const Clip& aClip,
                             nsIFrame* aContainerLayerFrame,
                             LayerState aLayerState,
                             const nsPoint& aTopLeft);
 
@@ -569,18 +569,19 @@ protected:
    * render that display item. Returns null if there is no such layer.
    * This could be a dedicated layer for the display item, or a ThebesLayer
    * that renders many display items.
    */
   DisplayItemData* GetOldLayerForFrame(nsIFrame* aFrame, uint32_t aDisplayItemKey);
 
   /**
    * We accumulate DisplayItemData elements in a hashtable during
-   * the paint process, and store them in the frame property only when
-   * paint is complete. This is the hashentry for that hashtable.
+   * the paint process, one per visible display item.
+   * There is one hashtable per layer manager, and one entry
+   * per frame. This is the hashentry for that hashtable.
    */
   class DisplayItemDataEntry : public nsPtrHashKey<nsIFrame> {
   public:
     DisplayItemDataEntry(const nsIFrame *key)
       : nsPtrHashKey<nsIFrame>(key)
     { 
       MOZ_COUNT_CTOR(DisplayItemDataEntry); 
     }
@@ -635,18 +636,17 @@ protected:
                                                        uint32_t aDisplayItemKey);
   static DisplayItemData* GetDisplayItemDataForManager(nsDisplayItem* aItem, LayerManager* aManager);
   static DisplayItemData* GetDisplayItemDataForManager(nsIFrame* aFrame, 
                                                        uint32_t aDisplayItemKey, 
                                                        LayerManagerData* aData);
 
   /**
    * A useful hashtable iteration function that removes the
-   * DisplayItemData property for the frame, clears its
-   * NS_FRAME_HAS_CONTAINER_LAYER bit and returns PL_DHASH_REMOVE.
+   * DisplayItemData property for the frame and returns PL_DHASH_REMOVE.
    * aClosure is ignored.
    */
   static PLDHashOperator RemoveDisplayItemDataForFrame(DisplayItemDataEntry* aEntry,
                                                        void* aClosure);
 
   /**
    * We store one of these for each display item associated with a
    * ThebesLayer, in a hashtable that maps each ThebesLayer to an array