Bug 1358961 - IsPartOfOpaqueLayer should consider ColorLayer as well. r=mattwoodrow draft
authorMorris Tseng <mtseng@mozilla.com>
Fri, 21 Apr 2017 15:21:58 +0800
changeset 566952 c5ee10f129c2481eb9d80c8bff9df0d3a832fd0a
parent 566789 8e969cc9aff49f845678cba5b35d9dd8aa340f16
child 625471 079c058e6cd150e4cf55749a7bcc4e778385a060
push id55387
push userbmo:mtseng@mozilla.com
push dateMon, 24 Apr 2017 07:04:23 +0000
reviewersmattwoodrow
bugs1358961
milestone55.0a1
Bug 1358961 - IsPartOfOpaqueLayer should consider ColorLayer as well. r=mattwoodrow MozReview-Commit-ID: 9PUKdz7m1uJ
dom/base/nsDOMWindowUtils.cpp
gfx/layers/Layers.h
layout/painting/FrameLayerBuilder.cpp
layout/painting/FrameLayerBuilder.h
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -3044,23 +3044,30 @@ nsDOMWindowUtils::IsPartOfOpaqueLayer(ns
   nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsIFrame* frame = content->GetPrimaryFrame();
   if (!frame) {
     return NS_ERROR_FAILURE;
   }
 
-  PaintedLayer* layer = FrameLayerBuilder::GetDebugSingleOldPaintedLayerForFrame(frame);
-  if (!layer) {
-    return NS_ERROR_FAILURE;
+  ColorLayer* colorLayer = FrameLayerBuilder::GetDebugSingleOldLayerForFrame<ColorLayer>(frame);
+  if (colorLayer) {
+    auto color = colorLayer->GetColor();
+    *aResult = color.a == 1.0f;
+    return NS_OK;
   }
 
-  *aResult = (layer->GetContentFlags() & Layer::CONTENT_OPAQUE);
-  return NS_OK;
+  PaintedLayer* paintedLayer = FrameLayerBuilder::GetDebugSingleOldLayerForFrame<PaintedLayer>(frame);
+  if (paintedLayer) {
+    *aResult = paintedLayer->IsOpaque();
+    return NS_OK;
+  }
+
+  return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::NumberOfAssignedPaintedLayers(nsIDOMElement** aElements,
                                                 uint32_t aCount,
                                                 uint32_t* aResult)
 {
   if (!aElements) {
@@ -3073,17 +3080,17 @@ nsDOMWindowUtils::NumberOfAssignedPainte
     nsCOMPtr<nsIContent> content = do_QueryInterface(aElements[i], &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsIFrame* frame = content->GetPrimaryFrame();
     if (!frame) {
       return NS_ERROR_FAILURE;
     }
 
-    PaintedLayer* layer = FrameLayerBuilder::GetDebugSingleOldPaintedLayerForFrame(frame);
+    PaintedLayer* layer = FrameLayerBuilder::GetDebugSingleOldLayerForFrame<PaintedLayer>(frame);
     if (!layer) {
       return NS_ERROR_FAILURE;
     }
 
     layers.PutEntry(layer);
   }
 
   *aResult = layers.Count();
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -111,17 +111,18 @@ class WebRenderLayerManager;
 struct AnimData;
 
 namespace layerscope {
 class LayersPacket;
 } // namespace layerscope
 
 #define MOZ_LAYER_DECL_NAME(n, e)                              \
   virtual const char* Name() const override { return n; }  \
-  virtual LayerType GetType() const override { return e; }
+  virtual LayerType GetType() const override { return e; } \
+  static LayerType Type() { return e; }
 
 // Defined in LayerUserData.h; please include that file instead.
 class LayerUserData;
 
 class DidCompositeObserver {
   public:
     virtual void DidComposite() = 0;
 };
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -296,16 +296,25 @@ FrameLayerBuilder::DisplayItemData::Clea
 }
 
 const nsTArray<nsIFrame*>&
 FrameLayerBuilder::DisplayItemData::GetFrameListChanges()
 {
   return mFrameListChanges;
 }
 
+FrameLayerBuilder::DisplayItemData*
+FrameLayerBuilder::DisplayItemData::AssertDisplayItemData(FrameLayerBuilder::DisplayItemData* aData)
+{
+  MOZ_RELEASE_ASSERT(aData);
+  MOZ_RELEASE_ASSERT(sAliveDisplayItemDatas && sAliveDisplayItemDatas->Contains(aData));
+  MOZ_RELEASE_ASSERT(aData->mLayer);
+  return aData;
+}
+
 /**
  * This is the userdata we associate with a layer manager.
  */
 class LayerManagerData : public LayerUserData {
 public:
   explicit LayerManagerData(LayerManager *aManager)
     : mLayerManager(aManager)
 #ifdef DEBUG_DISPLAY_ITEM_DATA
@@ -1798,33 +1807,24 @@ FrameLayerBuilder::FlashPaint(gfxContext
 {
   float r = float(rand()) / RAND_MAX;
   float g = float(rand()) / RAND_MAX;
   float b = float(rand()) / RAND_MAX;
   aContext->SetColor(Color(r, g, b, 0.4f));
   aContext->Paint();
 }
 
-static FrameLayerBuilder::DisplayItemData*
-AssertDisplayItemData(FrameLayerBuilder::DisplayItemData* aData)
-{
-  MOZ_RELEASE_ASSERT(aData);
-  MOZ_RELEASE_ASSERT(sAliveDisplayItemDatas && sAliveDisplayItemDatas->Contains(aData));
-  MOZ_RELEASE_ASSERT(aData->mLayer);
-  return aData;
-}
-
 FrameLayerBuilder::DisplayItemData*
 FrameLayerBuilder::GetDisplayItemData(nsIFrame* aFrame, uint32_t aKey)
 {
   const nsTArray<DisplayItemData*>* array =
     aFrame->Properties().Get(LayerManagerDataProperty());
   if (array) {
     for (uint32_t i = 0; i < array->Length(); i++) {
-      DisplayItemData* item = AssertDisplayItemData(array->ElementAt(i));
+      DisplayItemData* item = DisplayItemData::AssertDisplayItemData(array->ElementAt(i));
       if (item->mDisplayItemKey == aKey &&
           item->mLayer->Manager() == mRetainingManager) {
         return item;
       }
     }
   }
   return nullptr;
 }
@@ -2044,34 +2044,34 @@ FrameLayerBuilder::WillEndTransaction()
 /* static */ FrameLayerBuilder::DisplayItemData*
 FrameLayerBuilder::GetDisplayItemDataForManager(nsDisplayItem* aItem,
                                                 LayerManager* aManager)
 {
   const nsTArray<DisplayItemData*>* array =
     aItem->Frame()->Properties().Get(LayerManagerDataProperty());
   if (array) {
     for (uint32_t i = 0; i < array->Length(); i++) {
-      DisplayItemData* item = AssertDisplayItemData(array->ElementAt(i));
+      DisplayItemData* item = DisplayItemData::AssertDisplayItemData(array->ElementAt(i));
       if (item->mDisplayItemKey == aItem->GetPerFrameKey() &&
           item->mLayer->Manager() == aManager) {
         return item;
       }
     }
   }
   return nullptr;
 }
 
 bool
 FrameLayerBuilder::HasRetainedDataFor(nsIFrame* aFrame, uint32_t aDisplayItemKey)
 {
   const nsTArray<DisplayItemData*>* array =
     aFrame->Properties().Get(LayerManagerDataProperty());
   if (array) {
     for (uint32_t i = 0; i < array->Length(); i++) {
-      if (AssertDisplayItemData(array->ElementAt(i))->mDisplayItemKey == aDisplayItemKey) {
+      if (DisplayItemData::AssertDisplayItemData(array->ElementAt(i))->mDisplayItemKey == aDisplayItemKey) {
         return true;
       }
     }
   }
   return false;
 }
 
 void
@@ -2079,17 +2079,17 @@ FrameLayerBuilder::IterateRetainedDataFo
 {
   const nsTArray<DisplayItemData*>* array =
     aFrame->Properties().Get(LayerManagerDataProperty());
   if (!array) {
     return;
   }
 
   for (uint32_t i = 0; i < array->Length(); i++) {
-    DisplayItemData* data = AssertDisplayItemData(array->ElementAt(i));
+    DisplayItemData* data = DisplayItemData::AssertDisplayItemData(array->ElementAt(i));
     if (data->mDisplayItemKey != nsDisplayItem::TYPE_ZERO) {
       aCallback(aFrame, data);
     }
   }
 }
 
 FrameLayerBuilder::DisplayItemData*
 FrameLayerBuilder::GetOldLayerForFrame(nsIFrame* aFrame, uint32_t aDisplayItemKey)
@@ -2147,55 +2147,25 @@ FrameLayerBuilder::GetDebugOldLayerFor(n
   const nsTArray<DisplayItemData*>* array =
     aFrame->Properties().Get(LayerManagerDataProperty());
 
   if (!array) {
     return nullptr;
   }
 
   for (uint32_t i = 0; i < array->Length(); i++) {
-    DisplayItemData *data = AssertDisplayItemData(array->ElementAt(i));
+    DisplayItemData *data = DisplayItemData::AssertDisplayItemData(array->ElementAt(i));
 
     if (data->mDisplayItemKey == aDisplayItemKey) {
       return data->mLayer;
     }
   }
   return nullptr;
 }
 
-/* static */ PaintedLayer*
-FrameLayerBuilder::GetDebugSingleOldPaintedLayerForFrame(nsIFrame* aFrame)
-{
-  const nsTArray<DisplayItemData*>* array =
-    aFrame->Properties().Get(LayerManagerDataProperty());
-
-  if (!array) {
-    return nullptr;
-  }
-
-  Layer* layer = nullptr;
-  for (DisplayItemData* data : *array) {
-    AssertDisplayItemData(data);
-    if (!data->mLayer->AsPaintedLayer()) {
-      continue;
-    }
-    if (layer && layer != data->mLayer) {
-      // More than one layer assigned, bail.
-      return nullptr;
-    }
-    layer = data->mLayer;
-  }
-
-  if (!layer) {
-    return nullptr;
-  }
-
-  return layer->AsPaintedLayer();
-}
-
 // Reset state that should not persist when a layer is recycled.
 static void
 ResetLayerStateForRecycling(Layer* aLayer) {
   // Currently, this clears the mask layer and ancestor mask layers.
   // Other cleanup may be added here.
   aLayer->SetMaskLayer(nullptr);
   aLayer->SetAncestorMaskLayers({});
 }
@@ -5806,34 +5776,34 @@ FrameLayerBuilder::InvalidateAllLayers(L
 
 /* static */ void
 FrameLayerBuilder::InvalidateAllLayersForFrame(nsIFrame *aFrame)
 {
   const nsTArray<DisplayItemData*>* array =
     aFrame->Properties().Get(LayerManagerDataProperty());
   if (array) {
     for (uint32_t i = 0; i < array->Length(); i++) {
-      AssertDisplayItemData(array->ElementAt(i))->mParent->mInvalidateAllLayers = true;
+      DisplayItemData::AssertDisplayItemData(array->ElementAt(i))->mParent->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
 
   const nsTArray<DisplayItemData*>* array =
     aFrame->Properties().Get(LayerManagerDataProperty());
   if (array) {
     for (uint32_t i = 0; i < array->Length(); i++) {
-      DisplayItemData *element = AssertDisplayItemData(array->ElementAt(i));
+      DisplayItemData *element = DisplayItemData::AssertDisplayItemData(array->ElementAt(i));
       if (!element->mParent->mLayerManager->IsWidgetLayerManager()) {
         continue;
       }
       if (element->mDisplayItemKey == aDisplayItemKey) {
         if (element->mOptLayer) {
           return element->mOptLayer;
         }
 
@@ -5882,17 +5852,17 @@ FrameLayerBuilder::GetPaintedLayerScaleF
 
     const nsTArray<DisplayItemData*>* array =
       f->Properties().Get(LayerManagerDataProperty());
     if (!array) {
       continue;
     }
 
     for (uint32_t i = 0; i < array->Length(); i++) {
-      Layer* layer = AssertDisplayItemData(array->ElementAt(i))->mLayer;
+      Layer* layer = DisplayItemData::AssertDisplayItemData(array->ElementAt(i))->mLayer;
       ContainerLayer* container = layer->AsContainerLayer();
       if (!container ||
           !layer->Manager()->IsWidgetLayerManager()) {
         continue;
       }
       for (Layer* l = container->GetFirstChild(); l; l = l->GetNextSibling()) {
         PaintedDisplayItemLayerUserData* data =
             static_cast<PaintedDisplayItemLayerUserData*>
@@ -6322,17 +6292,17 @@ FrameLayerBuilder::GetMostRecentGeometry
     properties.Get(LayerManagerDataProperty());
   if (!dataArray) {
     return nullptr;
   }
 
   // Find our display item data, if it exists, and return its geometry.
   uint32_t itemPerFrameKey = aItem->GetPerFrameKey();
   for (uint32_t i = 0; i < dataArray->Length(); i++) {
-    DisplayItemData* data = AssertDisplayItemData(dataArray->ElementAt(i));
+    DisplayItemData* data = DisplayItemData::AssertDisplayItemData(dataArray->ElementAt(i));
     if (data->GetDisplayItemKey() == itemPerFrameKey) {
       return data->GetGeometry();
     }
   }
 
   return nullptr;
 }
 
--- a/layout/painting/FrameLayerBuilder.h
+++ b/layout/painting/FrameLayerBuilder.h
@@ -365,17 +365,46 @@ public:
   static Layer* GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey);
 
   /**
    * Return the layer that all display items of aFrame were assigned to in the
    * last paint, or nullptr if there was no single layer assigned to all of the
    * frame's display items (i.e. zero, or more than one).
    * This function is for testing purposes and not performance sensitive.
    */
-  static PaintedLayer* GetDebugSingleOldPaintedLayerForFrame(nsIFrame* aFrame);
+  template<class T>
+  static T*
+  GetDebugSingleOldLayerForFrame(nsIFrame* aFrame)
+  {
+    const nsTArray<DisplayItemData*>* array =
+      aFrame->Properties().Get(LayerManagerDataProperty());
+
+    if (!array) {
+      return nullptr;
+    }
+
+    Layer* layer = nullptr;
+    for (DisplayItemData* data : *array) {
+      DisplayItemData::AssertDisplayItemData(data);
+      if (data->mLayer->GetType() != T::Type()) {
+        continue;
+      }
+      if (layer && layer != data->mLayer) {
+        // More than one layer assigned, bail.
+        return nullptr;
+      }
+      layer = data->mLayer;
+    }
+
+    if (!layer) {
+      return nullptr;
+    }
+
+    return static_cast<T*>(layer);
+  }
 
   /**
    * Destroy any stored LayerManagerDataProperty and the associated data for
    * aFrame.
    */
   static void DestroyDisplayItemDataFor(nsIFrame* aFrame);
 
   LayerManager* GetRetainingLayerManager() { return mRetainingManager; }
@@ -446,16 +475,18 @@ public:
     friend class FrameLayerBuilder;
 
     uint32_t GetDisplayItemKey() { return mDisplayItemKey; }
     Layer* GetLayer() { return mLayer; }
     nsDisplayItemGeometry* GetGeometry() const { return mGeometry.get(); }
     void Invalidate() { mIsInvalid = true; }
     void ClearAnimationCompositorState();
 
+    static DisplayItemData* AssertDisplayItemData(DisplayItemData* aData);
+
   private:
     DisplayItemData(LayerManagerData* aParent,
                     uint32_t aKey,
                     Layer* aLayer,
                     nsIFrame* aFrame = nullptr);
 
     /**
      * Removes any references to this object from frames