Bug 1302071 - Part 4: Pass the current transaction ID to NotifyInvalidation. r?tnikkel
MozReview-Commit-ID: AMLjzElRp1l
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -699,16 +699,18 @@ public:
virtual TextureFactoryIdentifier GetTextureFactoryIdentifier()
{
return TextureFactoryIdentifier();
}
virtual void SetTransactionIdAllocator(TransactionIdAllocator* aAllocator) {}
+ virtual uint64_t GetLastTransactionId() { return 0; }
+
virtual CompositorBridgeChild* GetCompositorBridgeChild() { return nullptr; }
protected:
RefPtr<Layer> mRoot;
gfx::UserData mUserData;
bool mDestroyed;
bool mSnapEffectiveTransforms;
--- a/gfx/layers/client/ClientLayerManager.h
+++ b/gfx/layers/client/ClientLayerManager.h
@@ -220,16 +220,18 @@ public:
// Get a copy of the compositor-side APZ test data for our layers ID.
void GetCompositorSideAPZTestData(APZTestData* aData) const;
virtual void SetTransactionIdAllocator(TransactionIdAllocator* aAllocator) override
{
mTransactionIdAllocator = aAllocator;
}
+ virtual uint64_t GetLastTransactionId() override { return mLatestTransactionId; }
+
float RequestProperty(const nsAString& aProperty) override;
bool AsyncPanZoomEnabled() const override;
void SetNextPaintSyncId(int32_t aSyncId);
virtual void SetLayerObserverEpoch(uint64_t aLayerObserverEpoch) override;
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -6409,17 +6409,17 @@ PresShell::Paint(nsView* aViewToP
nsIntRect bounds = invalid.GetBounds();
nsRect rect(presContext->DevPixelsToAppUnits(bounds.x),
presContext->DevPixelsToAppUnits(bounds.y),
presContext->DevPixelsToAppUnits(bounds.width),
presContext->DevPixelsToAppUnits(bounds.height));
if (shouldInvalidate) {
aViewToPaint->GetViewManager()->InvalidateViewNoSuppression(aViewToPaint, rect);
}
- presContext->NotifyInvalidation(bounds);
+ presContext->NotifyInvalidation(layerManager->GetLastTransactionId(), bounds);
}
} else if (shouldInvalidate) {
aViewToPaint->GetViewManager()->InvalidateView(aViewToPaint);
}
frame->UpdatePaintCountForPaintedPresShells();
return;
}
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -160,17 +160,17 @@ nsPresContext::IsDOMPaintEventPending()
if (mFireAfterPaintEvents) {
return true;
}
nsRootPresContext* drpc = GetRootPresContext();
if (drpc && drpc->mRefreshDriver->ViewManagerFlushIsPending()) {
// Since we're promising that there will be a MozAfterPaint event
// fired, we record an empty invalidation in case display list
// invalidation doesn't invalidate anything further.
- NotifyInvalidation(nsRect(0, 0, 0, 0));
+ NotifyInvalidation(drpc->mRefreshDriver->LastTransactionId() + 1, nsRect(0, 0, 0, 0));
NS_ASSERTION(mFireAfterPaintEvents, "Why aren't we planning to fire the event?");
return true;
}
return false;
}
void
nsPresContext::PrefChangedCallback(const char* aPrefName, void* instance_data)
@@ -2440,38 +2440,38 @@ nsPresContext::MayHavePaintEventListener
}
bool result = false;
mDocument->EnumerateSubDocuments(MayHavePaintEventListenerSubdocumentCallback, &result);
return result;
}
void
-nsPresContext::NotifyInvalidation(const nsIntRect& aRect)
+nsPresContext::NotifyInvalidation(uint64_t aTransactionId, const nsIntRect& aRect)
{
// Prevent values from overflow after DevPixelsToAppUnits().
//
// DevPixelsTopAppUnits() will multiple a factor (60) to the value,
// it may make the result value over the edge (overflow) of max or
// min value of int32_t. Compute the max sized dev pixel rect that
// we can support and intersect with it.
nsIntRect clampedRect = nsIntRect::MaxIntRect();
clampedRect.ScaleInverseRoundIn(AppUnitsPerDevPixel());
clampedRect = clampedRect.Intersect(aRect);
nsRect rect(DevPixelsToAppUnits(clampedRect.x),
DevPixelsToAppUnits(clampedRect.y),
DevPixelsToAppUnits(clampedRect.width),
DevPixelsToAppUnits(clampedRect.height));
- NotifyInvalidation(rect);
+ NotifyInvalidation(aTransactionId, rect);
}
void
-nsPresContext::NotifyInvalidation(const nsRect& aRect)
+nsPresContext::NotifyInvalidation(uint64_t aTransactionId, const nsRect& aRect)
{
MOZ_ASSERT(GetContainerWeak(), "Invalidation in detached pres context");
// If there is no paint event listener, then we don't need to fire
// the asynchronous event. We don't even need to record invalidation.
// MayHavePaintEventListener is pretty cheap and we could make it
// even cheaper by providing a more efficient
// nsPIDOMWindow::GetListenerManager.
@@ -2506,17 +2506,17 @@ nsPresContext::NotifySubDocInvalidation(
nsIntPoint topLeft = aContainer->GetVisibleRegion().ToUnknownRegion().GetBounds().TopLeft();
for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) {
nsIntRect rect(iter.Get());
//PresContext coordinate space is relative to the start of our visible
// region. Is this really true? This feels like the wrong way to get the right
// answer.
rect.MoveBy(-topLeft);
- data->mPresContext->NotifyInvalidation(rect);
+ data->mPresContext->NotifyInvalidation(aContainer->Manager()->GetLastTransactionId(), rect);
}
}
void
nsPresContext::SetNotifySubDocInvalidationData(ContainerLayer* aContainer)
{
ContainerLayerPresContext* pres = new ContainerLayerPresContext;
pres->mPresContext = this;
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -950,19 +950,23 @@ public:
void FlushCounterStyles();
void RebuildCounterStyles(); // asynchronously
// Ensure that it is safe to hand out CSS rules outside the layout
// engine by ensuring that all CSS style sheets have unique inners
// and, if necessary, synchronously rebuilding all style data.
void EnsureSafeToHandOutCSSRules();
- void NotifyInvalidation(const nsRect& aRect);
+ // Mark an area as invalidated, associated with a given transaction id (allocated
+ // by nsRefreshDriver::GetTransactionId).
+ // Invalidated regions will be dispatched to MozAfterPaint events when
+ // NotifyDidPaintForSubtree is called for the transaction id (or any higher id).
+ void NotifyInvalidation(uint64_t aTransactionId, const nsRect& aRect);
// aRect is in device pixels
- void NotifyInvalidation(const nsIntRect& aRect);
+ void NotifyInvalidation(uint64_t aTransactionId, const nsIntRect& aRect);
// aFlags are nsIPresShell::PAINT_ flags
void NotifyDidPaintForSubtree(uint32_t aFlags, uint64_t aTransactionId = 0,
const mozilla::TimeStamp& aTimeStamp = mozilla::TimeStamp());
void FireDOMPaintEvent(nsTArray<nsRect>* aList, uint64_t aTransactionId,
mozilla::TimeStamp aTimeStamp = mozilla::TimeStamp());
// Callback for catching invalidations in ContainerLayers
// Passed to LayerProperties::ComputeDifference
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -2252,17 +2252,17 @@ already_AddRefed<LayerManager> nsDisplay
nsIntRect bounds = invalid.GetBounds();
nsRect rect(presContext->DevPixelsToAppUnits(bounds.x),
presContext->DevPixelsToAppUnits(bounds.y),
presContext->DevPixelsToAppUnits(bounds.width),
presContext->DevPixelsToAppUnits(bounds.height));
if (shouldInvalidate) {
view->GetViewManager()->InvalidateViewNoSuppression(view, rect);
}
- presContext->NotifyInvalidation(bounds);
+ presContext->NotifyInvalidation(layerManager->GetLastTransactionId(), bounds);
}
} else if (shouldInvalidate) {
view->GetViewManager()->InvalidateView(view);
}
}
layerManager->SetUserData(&gLayerManagerLayerBuilder, oldBuilder);
return layerManager.forget();