Bug 1368386 - Only call mInvalidRegion.GetRegion() when an up-to-date valid region is requested. r?mattwoodrow
MozReview-Commit-ID: IHb0fNAzyjj
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -1795,17 +1795,17 @@ public:
* Adds to the current invalid rect.
*/
void AddInvalidRect(const gfx::IntRect& aRect) { mInvalidRegion.Add(aRect); }
/**
* Clear the invalid rect, marking the layer as being identical to what is currently
* composited.
*/
- void ClearInvalidRect() { mInvalidRegion.SetEmpty(); }
+ virtual void ClearInvalidRect() { mInvalidRegion.SetEmpty(); }
// These functions allow attaching an AsyncPanZoomController to this layer,
// and can be used anytime.
// A layer has an APZC at index aIndex only-if GetFrameMetrics(aIndex).IsScrollable();
// attempting to get an APZC for a non-scrollable metrics will return null.
// The aIndex for these functions must be less than GetScrollMetadataCount().
void SetAsyncPanZoomController(uint32_t aIndex, AsyncPanZoomController *controller);
AsyncPanZoomController* GetAsyncPanZoomController(uint32_t aIndex) const;
@@ -1992,41 +1992,64 @@ public:
* performance.
*/
void SetAllowResidualTranslation(bool aAllow) { mAllowResidualTranslation = aAllow; }
void SetValidRegion(const nsIntRegion& aRegion)
{
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ValidRegion", this));
mValidRegion = aRegion;
+ mValidRegionIsCurrent = true;
Mutated();
}
/**
* Can be used anytime
*/
- const nsIntRegion& GetValidRegion() const { return mValidRegion; }
+ const nsIntRegion& GetValidRegion() const
+ {
+ EnsureValidRegionIsCurrent();
+ return mValidRegion;
+ }
void InvalidateWholeLayer()
{
- InvalidateRegion(GetValidRegion().GetBounds());
+ mInvalidRegion.Add(GetValidRegion().GetBounds());
+ ClearValidRegion();
}
- void ClearValidRegion() { mValidRegion.SetEmpty(); }
+ void ClearValidRegion()
+ {
+ mValidRegion.SetEmpty();
+ mValidRegionIsCurrent = true;
+ }
void AddToValidRegion(const nsIntRegion& aRegion)
{
+ EnsureValidRegionIsCurrent();
mValidRegion.OrWith(aRegion);
}
void SubtractFromValidRegion(const nsIntRegion& aRegion)
{
+ EnsureValidRegionIsCurrent();
mValidRegion.SubOut(aRegion);
}
void UpdateValidRegionAfterInvalidRegionChanged()
{
- SubtractFromValidRegion(mInvalidRegion.GetRegion());
+ // Changes to mInvalidRegion will be applied to mValidRegion on the next
+ // call to EnsureValidRegionIsCurrent().
+ mValidRegionIsCurrent = false;
+ }
+
+ void ClearInvalidRect() override
+ {
+ // mInvalidRegion is about to be reset. This is the last chance to apply
+ // any pending changes from it to mValidRegion. Do that by calling
+ // EnsureValidRegionIsCurrent().
+ EnsureValidRegionIsCurrent();
+ mInvalidRegion.SetEmpty();
}
virtual PaintedLayer* AsPaintedLayer() override { return this; }
MOZ_LAYER_DECL_NAME("PaintedLayer", TYPE_PAINTED)
virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override
{
@@ -2076,16 +2099,17 @@ public:
*/
gfxPoint GetResidualTranslation() const { return mResidualTranslation; }
protected:
PaintedLayer(LayerManager* aManager, void* aImplData,
LayerManager::PaintedLayerCreationHint aCreationHint = LayerManager::NONE)
: Layer(aManager, aImplData)
, mValidRegion()
+ , mValidRegionIsCurrent(true)
, mCreationHint(aCreationHint)
, mUsedForReadback(false)
, mAllowResidualTranslation(false)
{
}
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
@@ -2094,17 +2118,44 @@ protected:
/**
* ComputeEffectiveTransforms snaps the ideal transform to get mEffectiveTransform.
* mResidualTranslation is the translation that should be applied *before*
* mEffectiveTransform to get the ideal transform.
*/
gfxPoint mResidualTranslation;
private:
- nsIntRegion mValidRegion;
+ /**
+ * Needs to be called prior to accessing mValidRegion, unless mValidRegion is
+ * being completely overwritten.
+ */
+ void EnsureValidRegionIsCurrent() const
+ {
+ if (!mValidRegionIsCurrent) {
+ // Apply any pending mInvalidRegion changes to mValidRegion.
+ if (!mValidRegion.IsEmpty()) {
+ // Calling mInvalidRegion.GetRegion() is expensive.
+ // That's why we delay the adjustment of mValidRegion for as long as
+ // possible, so that multiple modifications to mInvalidRegion can be
+ // applied to mValidRegion in one go.
+ mValidRegion.SubOut(mInvalidRegion.GetRegion());
+ }
+ mValidRegionIsCurrent = true;
+ }
+ }
+
+ /**
+ * The layer's valid region. If mValidRegionIsCurrent is false, then
+ * mValidRegion has not yet been updated for recent changes to
+ * mInvalidRegion. Those pending changes can be applied by calling
+ * EnsureValidRegionIsCurrent().
+ */
+ mutable nsIntRegion mValidRegion;
+
+ mutable bool mValidRegionIsCurrent;
protected:
/**
* The creation hint that was used when constructing this layer.
*/
const LayerManager::PaintedLayerCreationHint mCreationHint;
/**
* Set when this PaintedLayer is participating in readback, i.e. some