Bug 1358961 - IsPartOfOpaqueLayer should consider ColorLayer as well. r=mattwoodrow
MozReview-Commit-ID: 9PUKdz7m1uJ
--- 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