--- a/gfx/layers/LayerTreeInvalidation.cpp
+++ b/gfx/layers/LayerTreeInvalidation.cpp
@@ -19,16 +19,30 @@
#include "nsDataHashtable.h" // for nsDataHashtable
#include "nsDebug.h" // for NS_ASSERTION
#include "nsHashKeys.h" // for nsPtrHashKey
#include "nsISupportsImpl.h" // for Layer::AddRef, etc
#include "nsRect.h" // for IntRect
#include "nsTArray.h" // for AutoTArray, nsTArray_Impl
#include "mozilla/layers/ImageHost.h"
#include "mozilla/layers/LayerManagerComposite.h"
+#include "LayersLogging.h"
+
+// LayerTreeInvalidation debugging
+#define LTI_DEBUG 0
+
+#if LTI_DEBUG
+# define LTI_DEEPER(aPrefix) nsPrintfCString("%s ", aPrefix).get()
+# define LTI_DUMP(rgn, label) if (!(rgn).IsEmpty()) printf_stderr("%s%p: " label " portion is %s\n", aPrefix, mLayer.get(), Stringify(rgn).c_str());
+# define LTI_LOG(...) printf_stderr(__VA_ARGS__)
+#else
+# define LTI_DEEPER(aPrefix) nullptr
+# define LTI_DUMP(rgn, label)
+# define LTI_LOG(...)
+#endif
using namespace mozilla::gfx;
namespace mozilla {
namespace layers {
struct LayerPropertiesBase;
UniquePtr<LayerPropertiesBase> CloneLayerTreePropertiesInternal(Layer* aRoot, bool aIsMask = false);
@@ -163,17 +177,18 @@ struct LayerPropertiesBase : public Laye
}
virtual nsIntRegion ComputeDifferences(Layer* aRoot,
NotifySubDocInvalidationFunc aCallback,
bool* aGeometryChanged);
virtual void MoveBy(const IntPoint& aOffset);
- nsIntRegion ComputeChange(NotifySubDocInvalidationFunc aCallback,
+ nsIntRegion ComputeChange(const char* aPrefix,
+ NotifySubDocInvalidationFunc aCallback,
bool& aGeometryChanged)
{
bool transformChanged = !mTransform.FuzzyEqualsMultiplicative(GetTransformForInvalidation(mLayer)) ||
mLayer->GetPostXScale() != mPostXScale ||
mLayer->GetPostYScale() != mPostYScale;
const Maybe<ParentLayerIntRect>& otherClip = mLayer->GetEffectiveClipRect();
nsIntRegion result;
@@ -191,43 +206,49 @@ struct LayerPropertiesBase : public Laye
if ((mMaskLayer ? mMaskLayer->mLayer : nullptr) != otherMask ||
ancestorMaskChanged ||
(mUseClipRect != !!otherClip) ||
mLayer->GetLocalOpacity() != mOpacity ||
transformChanged)
{
aGeometryChanged = true;
result = OldTransformedBounds();
+ LTI_DUMP(result, "oldtransform");
+ LTI_DUMP(NewTransformedBounds(), "newtransform");
AddRegion(result, NewTransformedBounds());
-
// We can't bail out early because we need to update mChildrenChanged.
}
- AddRegion(result, ComputeChangeInternal(aCallback, aGeometryChanged));
+ nsIntRegion internal = ComputeChangeInternal(aPrefix, aCallback, aGeometryChanged);
+ LTI_DUMP(internal, "internal");
+ AddRegion(result, internal);
+ LTI_DUMP(mLayer->GetInvalidRegion(), "invalid");
AddTransformedRegion(result, mLayer->GetInvalidRegion(), mTransform);
if (mMaskLayer && otherMask) {
- AddTransformedRegion(result, mMaskLayer->ComputeChange(aCallback, aGeometryChanged),
- mTransform);
+ nsIntRegion mask = mMaskLayer->ComputeChange(aPrefix, aCallback, aGeometryChanged);
+ LTI_DUMP(mask, "mask");
+ AddTransformedRegion(result, mask, mTransform);
}
for (size_t i = 0;
i < std::min(mAncestorMaskLayers.Length(), mLayer->GetAncestorMaskLayerCount());
i++)
{
- AddTransformedRegion(result,
- mAncestorMaskLayers[i]->ComputeChange(aCallback, aGeometryChanged),
- mTransform);
+ nsIntRegion mask = mAncestorMaskLayers[i]->ComputeChange(aPrefix, aCallback, aGeometryChanged);
+ LTI_DUMP(mask, "ancestormask");
+ AddTransformedRegion(result, mask, mTransform);
}
if (mUseClipRect && otherClip) {
if (!mClipRect.IsEqualInterior(*otherClip)) {
aGeometryChanged = true;
nsIntRegion tmp;
tmp.Xor(mClipRect.ToUnknownRect(), otherClip->ToUnknownRect());
+ LTI_DUMP(tmp, "clip");
AddRegion(result, tmp);
}
}
mLayer->ClearInvalidRect();
return result;
}
@@ -237,17 +258,18 @@ struct LayerPropertiesBase : public Laye
GetTransformForInvalidation(mLayer));
}
virtual IntRect OldTransformedBounds()
{
return TransformRect(mVisibleRegion.ToUnknownRegion().GetBounds(), mTransform);
}
- virtual nsIntRegion ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback,
+ virtual nsIntRegion ComputeChangeInternal(const char* aPrefix,
+ NotifySubDocInvalidationFunc aCallback,
bool& aGeometryChanged)
{
return IntRect();
}
RefPtr<Layer> mLayer;
UniquePtr<LayerPropertiesBase> mMaskLayer;
nsTArray<UniquePtr<LayerPropertiesBase>> mAncestorMaskLayers;
@@ -268,17 +290,18 @@ struct ContainerLayerProperties : public
, mPreXScale(aLayer->GetPreXScale())
, mPreYScale(aLayer->GetPreYScale())
{
for (Layer* child = aLayer->GetFirstChild(); child; child = child->GetNextSibling()) {
mChildren.AppendElement(Move(CloneLayerTreePropertiesInternal(child)));
}
}
- nsIntRegion ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback,
+ nsIntRegion ComputeChangeInternal(const char* aPrefix,
+ NotifySubDocInvalidationFunc aCallback,
bool& aGeometryChanged) override
{
ContainerLayer* container = mLayer->AsContainerLayer();
nsIntRegion invalidOfLayer; // Invalid regions of this layer.
nsIntRegion result; // Invliad regions for children only.
bool childrenChanged = false;
@@ -318,19 +341,21 @@ struct ContainerLayerProperties : public
// old list mChildren (if any of those children have been reordered
// rather than removed, we will invalidate their new area when we
// encounter them in the new list):
for (uint32_t j = i; j < childsOldIndex; ++j) {
AddRegion(result, mChildren[j]->OldTransformedBounds());
childrenChanged |= true;
}
// Invalidate any regions of the child that have changed:
- nsIntRegion region = mChildren[childsOldIndex]->ComputeChange(aCallback, aGeometryChanged);
+ nsIntRegion region = mChildren[childsOldIndex]->ComputeChange(LTI_DEEPER(aPrefix), aCallback, aGeometryChanged);
i = childsOldIndex + 1;
if (!region.IsEmpty()) {
+ LTI_LOG("%s%p: child %p produced %s\n", aPrefix, mLayer.get(),
+ mChildren[childsOldIndex]->mLayer.get(), Stringify(region).c_str());
AddRegion(result, region);
childrenChanged |= true;
}
} else {
// We've already seen this child in mChildren (which means it must
// have been reordered) and invalidated its old area. We need to
// invalidate its new area too:
invalidateChildsCurrentArea = true;
@@ -340,30 +365,32 @@ struct ContainerLayerProperties : public
invalidateChildsCurrentArea = true;
}
} else {
// |child| is new, or was reordered to a higher index
invalidateChildsCurrentArea = true;
}
if (invalidateChildsCurrentArea) {
aGeometryChanged = true;
+ LTI_DUMP(child->GetLocalVisibleRegion().ToUnknownRegion(), "invalidateChildsCurrentArea");
AddTransformedRegion(result, child->GetLocalVisibleRegion().ToUnknownRegion(),
GetTransformForInvalidation(child));
if (aCallback) {
NotifySubdocumentInvalidationRecursive(child, aCallback);
} else {
ClearInvalidations(child);
}
}
childrenChanged |= invalidateChildsCurrentArea;
}
// Process remaining removed children.
while (i < mChildren.Length()) {
childrenChanged |= true;
+ LTI_DUMP(mChildren[i]->OldTransformedBounds(), "removed child");
AddRegion(result, mChildren[i]->OldTransformedBounds());
i++;
}
if (aCallback) {
aCallback(container, result);
}
@@ -372,16 +399,17 @@ struct ContainerLayerProperties : public
}
if (!mLayer->Extend3DContext()) {
// |result| contains invalid regions only of children.
result.Transform(GetTransformForInvalidation(mLayer));
}
// else, effective transforms have applied on children.
+ LTI_DUMP(invalidOfLayer, "invalidOfLayer");
result.OrWith(invalidOfLayer);
return result;
}
IntRect NewTransformedBounds() override
{
if (mLayer->Extend3DContext()) {
@@ -416,28 +444,30 @@ struct ContainerLayerProperties : public
struct ColorLayerProperties : public LayerPropertiesBase
{
explicit ColorLayerProperties(ColorLayer *aLayer)
: LayerPropertiesBase(aLayer)
, mColor(aLayer->GetColor())
, mBounds(aLayer->GetBounds())
{ }
- virtual nsIntRegion ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback,
+ virtual nsIntRegion ComputeChangeInternal(const char* aPrefix,
+ NotifySubDocInvalidationFunc aCallback,
bool& aGeometryChanged)
{
ColorLayer* color = static_cast<ColorLayer*>(mLayer.get());
if (mColor != color->GetColor()) {
aGeometryChanged = true;
return NewTransformedBounds();
}
nsIntRegion boundsDiff;
boundsDiff.Xor(mBounds, color->GetBounds());
+ LTI_DUMP(boundsDiff, "color");
nsIntRegion result;
AddTransformedRegion(result, boundsDiff, mTransform);
return result;
}
Color mColor;
@@ -467,25 +497,27 @@ struct ImageLayerProperties : public Lay
, mIsMask(aIsMask)
{
if (mImageHost) {
mLastProducerID = mImageHost->GetLastProducerID();
mLastFrameID = mImageHost->GetLastFrameID();
}
}
- virtual nsIntRegion ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback,
+ virtual nsIntRegion ComputeChangeInternal(const char* aPrefix,
+ NotifySubDocInvalidationFunc aCallback,
bool& aGeometryChanged)
{
ImageLayer* imageLayer = static_cast<ImageLayer*>(mLayer.get());
if (!imageLayer->GetLocalVisibleRegion().ToUnknownRegion().IsEqual(mVisibleRegion)) {
aGeometryChanged = true;
IntRect result = NewTransformedBounds();
result = result.Union(OldTransformedBounds());
+ LTI_DUMP(result, "image");
return result;
}
ImageContainer* container = imageLayer->GetContainer();
ImageHost* host = GetImageHost(imageLayer);
if (mContainer != container ||
mFilter != imageLayer->GetFilter() ||
mScaleToSize != imageLayer->GetScaleToSize() ||
@@ -501,18 +533,20 @@ struct ImageLayerProperties : public Lay
IntSize size;
if (container) {
size = container->GetCurrentSize();
}
if (host) {
size = host->GetImageSize();
}
IntRect rect(0, 0, size.width, size.height);
+ LTI_DUMP(rect, "mask");
return TransformRect(rect, GetTransformForInvalidation(mLayer));
}
+ LTI_DUMP(NewTransformedBounds(), "bounds");
return NewTransformedBounds();
}
return IntRect();
}
RefPtr<ImageContainer> mContainer;
RefPtr<ImageHost> mImageHost;
@@ -528,17 +562,18 @@ struct CanvasLayerProperties : public La
{
explicit CanvasLayerProperties(CanvasLayer* aCanvas)
: LayerPropertiesBase(aCanvas)
, mImageHost(GetImageHost(aCanvas))
{
mFrameID = mImageHost ? mImageHost->GetFrameID() : -1;
}
- virtual nsIntRegion ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback,
+ virtual nsIntRegion ComputeChangeInternal(const char* aPrefix,
+ NotifySubDocInvalidationFunc aCallback,
bool& aGeometryChanged)
{
CanvasLayer* canvasLayer = static_cast<CanvasLayer*>(mLayer.get());
ImageHost* host = GetImageHost(canvasLayer);
if (host && host->GetFrameID() != mFrameID) {
aGeometryChanged = true;
@@ -623,20 +658,21 @@ LayerPropertiesBase::ComputeDifferences(
aRoot->GetLocalTransform());
result = result.Union(OldTransformedBounds());
if (aGeometryChanged != nullptr) {
*aGeometryChanged = true;
}
return result;
} else {
bool geometryChanged = (aGeometryChanged != nullptr) ? *aGeometryChanged : false;
- nsIntRegion invalid = ComputeChange(aCallback, geometryChanged);
+ nsIntRegion invalid = ComputeChange(" ", aCallback, geometryChanged);
if (aGeometryChanged != nullptr) {
*aGeometryChanged = geometryChanged;
}
+ LTI_LOG("ComputeDifferences returned %s\n", Stringify(invalid).c_str());
return invalid;
}
}
void
LayerPropertiesBase::MoveBy(const IntPoint& aOffset)
{
mTransform.PostTranslate(aOffset.x, aOffset.y, 0);