Bug 539356 - Add HasRetainedDataFor. r=roc
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 29 Aug 2012 17:48:45 +1200
changeset 108458 ba21437b71135fd28f4dc30b7f185a88c0e8886c
parent 108457 9366a70acb1d07ca4f8d5a902914089214f9566e
child 108459 8fa21e95b22dfa47bd5a7b011fcaba52dcba138b
push id23564
push useremorley@mozilla.com
push dateFri, 28 Sep 2012 23:09:34 +0000
treeherdermozilla-central@b62b229a4d41 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs539356
milestone18.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 539356 - Add HasRetainedDataFor. r=roc
layout/base/FrameLayerBuilder.cpp
layout/base/FrameLayerBuilder.h
layout/base/nsPresShell.cpp
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -1013,46 +1013,60 @@ FrameLayerBuilder::StoreNewDisplayItemDa
  */
 static LayerManagerData*
 GetDefaultLayerManagerDataForFrame(nsIFrame* aFrame)
 {
   FrameProperties props = aFrame->Properties();
   return static_cast<LayerManagerData*>(props.Get(FrameLayerBuilder::LayerManagerDataProperty()));
 }
 
-/* static */ FrameLayerBuilder::DisplayItemData*
-FrameLayerBuilder::GetDisplayItemDataForManager(nsIFrame* aFrame, uint32_t aDisplayItemKey, LayerManager* aManager)
+static LayerManagerData*
+GetSecondaryLayerManagerDataForFrame(nsIFrame* aFrame)
 {
-  LayerManagerData *data;
-  if (!aManager) {
-    data = GetDefaultLayerManagerDataForFrame(aFrame);
-  } else {
-    data = static_cast<LayerManagerData*>(aManager->GetUserData(&gLayerManagerUserData));
-  }
-  
-  if (!data) {
-    return nullptr;
-  }
-
-  DisplayItemDataEntry *entry = data->mFramesWithLayers.GetEntry(aFrame);
+  FrameProperties props = aFrame->Properties();
+  return static_cast<LayerManagerData*>(props.Get(FrameLayerBuilder::LayerManagerSecondaryDataProperty()));
+}
+
+/* static */ FrameLayerBuilder::DisplayItemData*
+FrameLayerBuilder::GetDisplayItemDataForManager(nsIFrame* aFrame,
+                                                uint32_t aDisplayItemKey,
+                                                LayerManagerData* aData)
+{
+  DisplayItemDataEntry *entry = aData->mFramesWithLayers.GetEntry(aFrame);
   if (!entry) {
     return nullptr;
   }
 
   for (uint32_t i = 0; i < entry->mData.Length(); ++i) {
     if (entry->mData[i]->mDisplayItemKey == aDisplayItemKey) {
       return entry->mData[i];
     }
   }
   
   return nullptr;
 }
 
 /* static */ FrameLayerBuilder::DisplayItemData*
-FrameLayerBuilder::GetDisplayItemDataForManager(nsDisplayItem* aItem, LayerManager* aManager)
+FrameLayerBuilder::GetDisplayItemDataForManager(nsIFrame* aFrame, 
+                                                uint32_t aDisplayItemKey, 
+                                                LayerManager* aManager)
+{
+  LayerManagerData *data = 
+    static_cast<LayerManagerData*>(aManager->GetUserData(&gLayerManagerUserData));
+  
+  if (!data) {
+    return nullptr;
+  }
+
+  return GetDisplayItemDataForManager(aFrame, aDisplayItemKey, data);
+}
+
+/* static */ FrameLayerBuilder::DisplayItemData*
+FrameLayerBuilder::GetDisplayItemDataForManager(nsDisplayItem* aItem, 
+                                                LayerManager* aManager)
 {
   DisplayItemData* data = 
     GetDisplayItemDataForManager(aItem->GetUnderlyingFrame(), 
                                  aItem->GetPerFrameKey(), 
                                  aManager);
   if (data) {
     return data->FrameListMatches(aItem) ? data : nullptr;
   }
@@ -1066,30 +1080,57 @@ FrameLayerBuilder::GetDisplayItemDataFor
                                    aManager);
     if (data) {
       return data->FrameListMatches(aItem) ? data : nullptr;
     }
   }
   return nullptr;
 }
 
+/* static */ FrameLayerBuilder::DisplayItemData*
+FrameLayerBuilder::GetDisplayItemDataForManager(nsIFrame* aFrame, 
+                                                uint32_t aDisplayItemKey)
+{
+  LayerManagerData *data = GetDefaultLayerManagerDataForFrame(aFrame);
+  
+  if (!data) {
+    return nullptr;
+  }
+  
+  return GetDisplayItemDataForManager(aFrame, aDisplayItemKey, data);
+}
+
 bool
 FrameLayerBuilder::HasRetainedLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey, LayerManager* aManager)
 {
   DisplayItemData* data = GetDisplayItemDataForManager(aFrame, aDisplayItemKey, aManager);
   if (data) {
     Layer* layer = data->mLayer;
     if (layer->Manager()->GetUserData(&gLayerManagerUserData)) {
       // All layer managers with our user data are retained layer managers
       return true;
     }
   }
   return false;
 }
 
+bool
+FrameLayerBuilder::HasRetainedDataFor(nsIFrame* aFrame, uint32_t aDisplayItemKey)
+{
+  LayerManagerData* data = GetDefaultLayerManagerDataForFrame(aFrame);
+  if (data && GetDisplayItemDataForManager(aFrame, aDisplayItemKey, data)) {
+    return true;
+  }
+  data = GetSecondaryLayerManagerDataForFrame(aFrame);
+  if (data && GetDisplayItemDataForManager(aFrame, aDisplayItemKey, data)) {
+    return true;
+  }
+  return false;
+}
+
 FrameLayerBuilder::DisplayItemData*
 FrameLayerBuilder::GetOldLayerForFrame(nsIFrame* aFrame, uint32_t aDisplayItemKey)
 {
   // If we need to build a new layer tree, then just refuse to recycle
   // anything.
   if (!mRetainingManager || mInvalidateAllLayers)
     return nullptr;
 
@@ -2910,25 +2951,38 @@ FrameLayerBuilder::InvalidateAllLayers(L
 {
   LayerManagerData* data = static_cast<LayerManagerData*>
     (aManager->GetUserData(&gLayerManagerUserData));
   if (data) {
     data->mInvalidateAllLayers = true;
   }
 }
 
+/* static */ void
+FrameLayerBuilder::InvalidateAllLayersForFrame(nsIFrame *aFrame)
+{
+  LayerManagerData* data = GetDefaultLayerManagerDataForFrame(aFrame);
+  if (data) {
+    data->mInvalidateAllLayers = true;
+  }
+  data = GetSecondaryLayerManagerDataForFrame(aFrame);
+  if (data) {
+    data->mInvalidateAllLayers = true;
+  }
+}
+
 /* static */
 Layer*
 FrameLayerBuilder::GetDedicatedLayer(nsIFrame* aFrame, uint32_t aDisplayItemKey)
 {
   //TODO: This isn't completely correct, since a frame could exist as a layer
   // in the normal widget manager, and as a different layer (or no layer)
   // in the secondary manager
 
-  DisplayItemData *data = GetDisplayItemDataForManager(aFrame, aDisplayItemKey, nullptr);
+  DisplayItemData *data = GetDisplayItemDataForManager(aFrame, aDisplayItemKey);
   if (!data) {
     return nullptr;
   }
 
   Layer* layer = data->mLayer;
   if (!layer->HasUserData(&gColorLayerUserData) &&
       !layer->HasUserData(&gImageLayerUserData) &&
       !layer->HasUserData(&gThebesDisplayItemLayerUserData)) {
--- a/layout/base/FrameLayerBuilder.h
+++ b/layout/base/FrameLayerBuilder.h
@@ -219,16 +219,17 @@ public:
   Layer* GetLeafLayerFor(nsDisplayListBuilder* aBuilder,
                          nsDisplayItem* aItem);
 
   /**
    * Call this to force all retained layers to be discarded and recreated at
    * the next paint.
    */
   static void InvalidateAllLayers(LayerManager* aManager);
+  static void InvalidateAllLayersForFrame(nsIFrame *aFrame);
 
   /**
    * Call this to determine if a frame has a dedicated (non-Thebes) layer
    * for the given display item key. If there isn't one, we return null,
    * otherwise we return the layer.
    */
   static Layer* GetDedicatedLayer(nsIFrame* aFrame, uint32_t aDisplayItemKey);
 
@@ -377,16 +378,22 @@ public:
    * into a retained layer.
    *
    * Since display items can belong to multiple retained LayerManagers, we need to
    * specify which LayerManager to check.
    */
   static bool HasRetainedLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey, LayerManager* aManager);
 
   /**
+   * Returns true if the given display item was rendered during the previous
+   * paint. Returns false otherwise.
+   */
+  static bool HasRetainedDataFor(nsIFrame* aFrame, uint32_t aDisplayItemKey);
+
+  /**
    * Save transform that was in aLayer when we last painted, and the position
    * of the active scrolled root frame. It must be an integer
    * translation.
    */
   void SaveLastPaintOffset(ThebesLayer* aLayer);
   /**
    * Get the translation transform that was in aLayer when we last painted. It's either
    * the transform saved by SaveLastPaintTransform, or else the transform
@@ -608,17 +615,22 @@ protected:
 
   /*
    * Get the DisplayItemData associated with this frame / display item pair,
    * using the LayerManager instead of FrameLayerBuilder.
    */
   static DisplayItemData* GetDisplayItemDataForManager(nsIFrame* aFrame, 
                                                        uint32_t aDisplayItemKey, 
                                                        LayerManager* aManager);
+  static DisplayItemData* GetDisplayItemDataForManager(nsIFrame* aFrame, 
+                                                       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.
    * aClosure is ignored.
    */
   static PLDHashOperator RemoveDisplayItemDataForFrame(DisplayItemDataEntry* aEntry,
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -3965,17 +3965,17 @@ PresShell::DocumentStatesChanged(nsIDocu
     mFrameConstructor->PostRestyleEvent(mDocument->GetRootElement(),
                                         eRestyle_Subtree, NS_STYLE_HINT_NONE);
     VERIFY_STYLE_TREE;
   }
 
   if (aStateMask.HasState(NS_DOCUMENT_STATE_WINDOW_INACTIVE)) {
     nsIFrame* root = mFrameConstructor->GetRootFrame();
     if (root) {
-      root->InvalidateFrameSubtree();
+      FrameLayerBuilder::InvalidateAllLayersForFrame(root);
       if (root->HasView()) {
         root->GetView()->SetForcedRepaint(true);
       }
     }
   }
 }
 
 void