Bug 1251615 - Add poison values to Layer to check for errors. r=mstange
MozReview-Commit-ID: l22oL5b9oB
--- a/gfx/layers/LayerTreeInvalidation.cpp
+++ b/gfx/layers/LayerTreeInvalidation.cpp
@@ -16,16 +16,17 @@
#include "mozilla/gfx/Point.h" // for IntSize
#include "mozilla/mozalloc.h" // for operator new, etc
#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/Poison.h"
#include "mozilla/layers/ImageHost.h"
#include "mozilla/layers/LayerManagerComposite.h"
#include "TreeTraversal.h" // for ForEachNode
using namespace mozilla::gfx;
namespace mozilla {
namespace layers {
@@ -165,16 +166,17 @@ struct LayerPropertiesBase : public Laye
NotifySubDocInvalidationFunc aCallback,
bool* aGeometryChanged);
virtual void MoveBy(const IntPoint& aOffset);
nsIntRegion ComputeChange(NotifySubDocInvalidationFunc aCallback,
bool& aGeometryChanged)
{
+ mCanary.Check();
bool transformChanged = !mTransform.FuzzyEqual(GetTransformForInvalidation(mLayer)) ||
mLayer->GetPostXScale() != mPostXScale ||
mLayer->GetPostYScale() != mPostYScale;
const Maybe<ParentLayerIntRect>& otherClip = mLayer->GetLocalClipRect();
nsIntRegion result;
bool ancestorMaskChanged = mAncestorMaskLayers.Length() != mLayer->GetAncestorMaskLayerCount();
if (!ancestorMaskChanged) {
@@ -252,37 +254,41 @@ struct LayerPropertiesBase : public Laye
nsTArray<UniquePtr<LayerPropertiesBase>> mAncestorMaskLayers;
nsIntRegion mVisibleRegion;
Matrix4x4 mTransform;
float mPostXScale;
float mPostYScale;
float mOpacity;
ParentLayerIntRect mClipRect;
bool mUseClipRect;
+ mozilla::CorruptionCanary mCanary;
};
struct ContainerLayerProperties : public LayerPropertiesBase
{
explicit ContainerLayerProperties(ContainerLayer* aLayer)
: LayerPropertiesBase(aLayer)
, mPreXScale(aLayer->GetPreXScale())
, mPreYScale(aLayer->GetPreYScale())
{
for (Layer* child = aLayer->GetFirstChild(); child; child = child->GetNextSibling()) {
+ child->CheckCanary();
mChildren.AppendElement(Move(CloneLayerTreePropertiesInternal(child)));
}
}
nsIntRegion ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback,
bool& aGeometryChanged) override
{
ContainerLayer* container = mLayer->AsContainerLayer();
nsIntRegion invalidOfLayer; // Invalid regions of this layer.
nsIntRegion result; // Invliad regions for children only.
+ container->CheckCanary();
+
bool childrenChanged = false;
if (mPreXScale != container->GetPreXScale() ||
mPreYScale != container->GetPreYScale()) {
aGeometryChanged = true;
invalidOfLayer = OldTransformedBounds();
AddRegion(invalidOfLayer, NewTransformedBounds());
childrenChanged = true;
@@ -296,16 +302,17 @@ struct ContainerLayerProperties : public
// other children are added to or removed from our container layer, since
// that may be caused by children being scrolled in or out of view. We are
// less concerned with children changing order.
// TODO: Consider how we could avoid unnecessary invalidation when children
// change order, and whether the overhead would be worth it.
nsDataHashtable<nsPtrHashKey<Layer>, uint32_t> oldIndexMap(mChildren.Length());
for (uint32_t i = 0; i < mChildren.Length(); ++i) {
+ mChildren[i]->mLayer->CheckCanary();
oldIndexMap.Put(mChildren[i]->mLayer, i);
}
uint32_t i = 0; // cursor into the old child list mChildren
for (Layer* child = container->GetFirstChild(); child; child = child->GetNextSibling()) {
bool invalidateChildsCurrentArea = false;
if (i < mChildren.Length()) {
uint32_t childsOldIndex;
@@ -554,16 +561,18 @@ UniquePtr<LayerPropertiesBase>
CloneLayerTreePropertiesInternal(Layer* aRoot, bool aIsMask /* = false */)
{
if (!aRoot) {
return MakeUnique<LayerPropertiesBase>();
}
MOZ_ASSERT(!aIsMask || aRoot->GetType() == Layer::TYPE_IMAGE);
+ aRoot->CheckCanary();
+
switch (aRoot->GetType()) {
case Layer::TYPE_CONTAINER:
case Layer::TYPE_REF:
return MakeUnique<ContainerLayerProperties>(aRoot->AsContainerLayer());
case Layer::TYPE_COLOR:
return MakeUnique<ColorLayerProperties>(static_cast<ColorLayer*>(aRoot));
case Layer::TYPE_IMAGE:
return MakeUnique<ImageLayerProperties>(static_cast<ImageLayer*>(aRoot), aIsMask);
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -16,16 +16,17 @@
#include "gfxTypes.h"
#include "gfxPoint.h" // for gfxPoint
#include "gfxRect.h" // for gfxRect
#include "gfx2DGlue.h"
#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2, etc
#include "mozilla/DebugOnly.h" // for DebugOnly
#include "mozilla/EventForwards.h" // for nsPaintEvent
#include "mozilla/Maybe.h" // for Maybe
+#include "mozilla/Poison.h"
#include "mozilla/RefPtr.h" // for already_AddRefed
#include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue, etc
#include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration
#include "mozilla/UniquePtr.h" // for UniquePtr
#include "mozilla/gfx/BaseMargin.h" // for BaseMargin
#include "mozilla/gfx/BasePoint.h" // for BasePoint
#include "mozilla/gfx/Point.h" // for IntSize
#include "mozilla/gfx/TiledRegion.h" // for TiledIntRegion
@@ -1310,18 +1311,28 @@ public:
const ScrollMetadata& GetScrollMetadata(uint32_t aIndex) const;
const FrameMetrics& GetFrameMetrics(uint32_t aIndex) const;
uint32_t GetScrollMetadataCount() const { return mScrollMetadata.Length(); }
const nsTArray<ScrollMetadata>& GetAllScrollMetadata() { return mScrollMetadata; }
bool HasScrollableFrameMetrics() const;
bool IsScrollInfoLayer() const;
const EventRegions& GetEventRegions() const { return mEventRegions; }
ContainerLayer* GetParent() { return mParent; }
- Layer* GetNextSibling() { return mNextSibling; }
- const Layer* GetNextSibling() const { return mNextSibling; }
+ Layer* GetNextSibling() {
+ if (mNextSibling) {
+ mNextSibling->CheckCanary();
+ }
+ return mNextSibling;
+ }
+ const Layer* GetNextSibling() const {
+ if (mNextSibling) {
+ mNextSibling->CheckCanary();
+ }
+ return mNextSibling;
+ }
Layer* GetPrevSibling() { return mPrevSibling; }
const Layer* GetPrevSibling() const { return mPrevSibling; }
virtual Layer* GetFirstChild() const { return nullptr; }
virtual Layer* GetLastChild() const { return nullptr; }
gfx::Matrix4x4 GetTransform() const;
// Same as GetTransform(), but returns the transform as a strongly-typed
// matrix. Eventually this will replace GetTransform().
const CSSTransformMatrix GetTransformTyped() const;
@@ -1338,16 +1349,17 @@ public:
FrameMetrics::ViewID GetStickyScrollContainerId() { return mStickyPositionData->mScrollId; }
const LayerRect& GetStickyScrollRangeOuter() { return mStickyPositionData->mOuter; }
const LayerRect& GetStickyScrollRangeInner() { return mStickyPositionData->mInner; }
FrameMetrics::ViewID GetScrollbarTargetContainerId() { return mScrollbarTargetId; }
ScrollDirection GetScrollbarDirection() { return mScrollbarDirection; }
float GetScrollbarThumbRatio() { return mScrollbarThumbRatio; }
bool IsScrollbarContainer() { return mIsScrollbarContainer; }
Layer* GetMaskLayer() const { return mMaskLayer; }
+ void CheckCanary() const { mCanary.Check(); }
// Ancestor mask layers are associated with FrameMetrics, but for simplicity
// in maintaining the layer tree structure we attach them to the layer.
size_t GetAncestorMaskLayerCount() const {
return mAncestorMaskLayers.Length();
}
Layer* GetAncestorMaskLayerAt(size_t aIndex) const {
return mAncestorMaskLayers.ElementAt(aIndex);
@@ -1849,16 +1861,18 @@ protected:
LayerManager* mManager;
ContainerLayer* mParent;
Layer* mNextSibling;
Layer* mPrevSibling;
void* mImplData;
RefPtr<Layer> mMaskLayer;
nsTArray<RefPtr<Layer>> mAncestorMaskLayers;
+ // Look for out-of-bound in the middle of the structure
+ mozilla::CorruptionCanary mCanary;
gfx::UserData mUserData;
gfx::IntRect mLayerBounds;
LayerIntRegion mVisibleRegion;
nsTArray<ScrollMetadata> mScrollMetadata;
EventRegions mEventRegions;
gfx::Matrix4x4 mTransform;
// A mutation of |mTransform| that we've queued to be applied at the
// end of the next transaction (if nothing else overrides it in the