зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1445570 - Remove EnsureEventualAfterPaint timer. r=tnikkel
MozReview-Commit-ID: C7WICJ5Q0ES Differential Revision: https://phabricator.services.mozilla.com/D5005 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
aef6842da1
Коммит
1deccd7ac1
|
@ -392,6 +392,7 @@ nsDOMWindowUtils::UpdateLayerTree()
|
|||
RefPtr<nsViewManager> vm = presShell->GetViewManager();
|
||||
nsView* view = vm->GetRootView();
|
||||
if (view) {
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
presShell->Paint(view, view->GetBounds(),
|
||||
nsIPresShell::PAINT_LAYERS | nsIPresShell::PAINT_SYNC_DECODE_IMAGES);
|
||||
presShell->GetLayerManager()->WaitOnTransactionProcessed();
|
||||
|
|
|
@ -138,6 +138,7 @@ nsPresContext::IsDOMPaintEventPending()
|
|||
if (!mTransactions.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRootPresContext* drpc = GetRootPresContext();
|
||||
if (drpc && drpc->mRefreshDriver->ViewManagerFlushIsPending()) {
|
||||
// Since we're promising that there will be a MozAfterPaint event
|
||||
|
@ -342,9 +343,6 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE(nsPresContext, LastRelease())
|
|||
void
|
||||
nsPresContext::LastRelease()
|
||||
{
|
||||
if (IsRoot()) {
|
||||
static_cast<nsRootPresContext*>(this)->CancelAllDidPaintTimers();
|
||||
}
|
||||
if (mMissingFonts) {
|
||||
mMissingFonts->Clear();
|
||||
}
|
||||
|
@ -963,9 +961,6 @@ nsPresContext::DetachShell()
|
|||
// Have to cancel our plugin geometry timer, because the
|
||||
// callback for that depends on a non-null presshell.
|
||||
thisRoot->CancelApplyPluginGeometryTimer();
|
||||
|
||||
// The did-paint timer also depends on a non-null pres shell.
|
||||
thisRoot->CancelAllDidPaintTimers();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2434,12 +2429,6 @@ nsPresContext::NotifyInvalidation(TransactionId aTransactionId, const nsRect& aR
|
|||
transaction->mTransactionId = aTransactionId;
|
||||
}
|
||||
}
|
||||
if (!pc) {
|
||||
nsRootPresContext* rpc = GetRootPresContext();
|
||||
if (rpc) {
|
||||
rpc->EnsureEventualDidPaintEvent(aTransactionId);
|
||||
}
|
||||
}
|
||||
|
||||
TransactionInvalidations* transaction = GetInvalidations(aTransactionId);
|
||||
MOZ_ASSERT(transaction);
|
||||
|
@ -2508,6 +2497,18 @@ nsPresContext::NotifyDidPaintSubdocumentCallback(nsIDocument* aDocument, void* a
|
|||
return true;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
nsPresContext::NotifyRevokingDidPaintSubdocumentCallback(nsIDocument* aDocument, void* aData)
|
||||
{
|
||||
NotifyDidPaintSubdocumentCallbackClosure* closure =
|
||||
static_cast<NotifyDidPaintSubdocumentCallbackClosure*>(aData);
|
||||
nsPresContext* pc = aDocument->GetPresContext();
|
||||
if (pc) {
|
||||
pc->NotifyRevokingDidPaint(closure->mTransactionId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
class DelayedFireDOMPaintEvent : public Runnable {
|
||||
public:
|
||||
DelayedFireDOMPaintEvent(
|
||||
|
@ -2540,16 +2541,52 @@ public:
|
|||
nsTArray<nsRect> mList;
|
||||
};
|
||||
|
||||
void
|
||||
nsPresContext::NotifyRevokingDidPaint(TransactionId aTransactionId)
|
||||
{
|
||||
if ((IsRoot() || !PresShell()->IsVisible()) && mTransactions.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
TransactionInvalidations* transaction = nullptr;
|
||||
for (auto& t : mTransactions) {
|
||||
if (t.mTransactionId == aTransactionId) {
|
||||
transaction = &t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If there are no transaction invalidations (which imply callers waiting
|
||||
// on the event) for this revoked id, then we don't need to fire a
|
||||
// MozAfterPaint.
|
||||
if (!transaction) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If there are queued transactions with an earlier id, we can't send
|
||||
// our event now since it will arrive out of order. Set the waiting for
|
||||
// previous transaction flag to true, and we'll send the event when
|
||||
// the others are completed.
|
||||
// If this is the only transaction, then we can send it immediately.
|
||||
if (mTransactions.Length() == 1) {
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
new DelayedFireDOMPaintEvent(this, &transaction->mInvalidations,
|
||||
transaction->mTransactionId, mozilla::TimeStamp());
|
||||
nsContentUtils::AddScriptRunner(ev);
|
||||
mTransactions.RemoveElementAt(0);
|
||||
} else {
|
||||
transaction->mIsWaitingForPreviousTransaction = true;
|
||||
}
|
||||
|
||||
NotifyDidPaintSubdocumentCallbackClosure closure = { aTransactionId, mozilla::TimeStamp() };
|
||||
mDocument->EnumerateSubDocuments(nsPresContext::NotifyRevokingDidPaintSubdocumentCallback, &closure);
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::NotifyDidPaintForSubtree(TransactionId aTransactionId,
|
||||
const mozilla::TimeStamp& aTimeStamp)
|
||||
{
|
||||
if (IsRoot()) {
|
||||
static_cast<nsRootPresContext*>(this)->CancelDidPaintTimers(aTransactionId);
|
||||
|
||||
if (mTransactions.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (IsRoot() && mTransactions.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PresShell()->IsVisible() && mTransactions.IsEmpty()) {
|
||||
|
@ -2575,6 +2612,17 @@ nsPresContext::NotifyDidPaintForSubtree(TransactionId aTransactionId,
|
|||
}
|
||||
mTransactions.RemoveElementAt(i);
|
||||
} else {
|
||||
// If there are transaction which is waiting for this transaction,
|
||||
// we should fire a MozAfterPaint immediately.
|
||||
if (sent && mTransactions[i].mIsWaitingForPreviousTransaction) {
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
new DelayedFireDOMPaintEvent(this, &mTransactions[i].mInvalidations,
|
||||
mTransactions[i].mTransactionId, aTimeStamp);
|
||||
nsContentUtils::AddScriptRunner(ev);
|
||||
sent = true;
|
||||
mTransactions.RemoveElementAt(i);
|
||||
continue;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
@ -2956,14 +3004,12 @@ nsRootPresContext::~nsRootPresContext()
|
|||
{
|
||||
NS_ASSERTION(mRegisteredPlugins.Count() == 0,
|
||||
"All plugins should have been unregistered");
|
||||
CancelAllDidPaintTimers();
|
||||
CancelApplyPluginGeometryTimer();
|
||||
}
|
||||
|
||||
/* virtual */ void
|
||||
nsRootPresContext::Detach()
|
||||
{
|
||||
CancelAllDidPaintTimers();
|
||||
// XXXmats maybe also CancelApplyPluginGeometryTimer(); ?
|
||||
nsPresContext::Detach();
|
||||
}
|
||||
|
@ -3218,55 +3264,6 @@ nsRootPresContext::CollectPluginGeometryUpdates(LayerManager* aLayerManager)
|
|||
#endif // #ifndef XP_MACOSX
|
||||
}
|
||||
|
||||
void
|
||||
nsRootPresContext::EnsureEventualDidPaintEvent(TransactionId aTransactionId)
|
||||
{
|
||||
for (NotifyDidPaintTimer& t : mNotifyDidPaintTimers) {
|
||||
if (t.mTransactionId == aTransactionId) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITimer> timer;
|
||||
RefPtr<nsRootPresContext> self = this;
|
||||
nsresult rv = NS_NewTimerWithCallback(
|
||||
getter_AddRefs(timer),
|
||||
NewNamedTimerCallback([self, aTransactionId](){
|
||||
nsAutoScriptBlocker blockScripts;
|
||||
self->NotifyDidPaintForSubtree(aTransactionId);
|
||||
}, "NotifyDidPaintForSubtree"), 100, nsITimer::TYPE_ONE_SHOT,
|
||||
Document()->EventTargetFor(TaskCategory::Other));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NotifyDidPaintTimer* t = mNotifyDidPaintTimers.AppendElement();
|
||||
t->mTransactionId = aTransactionId;
|
||||
t->mTimer = timer;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsRootPresContext::CancelDidPaintTimers(TransactionId aTransactionId)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
while (i < mNotifyDidPaintTimers.Length()) {
|
||||
if (mNotifyDidPaintTimers[i].mTransactionId <= aTransactionId) {
|
||||
mNotifyDidPaintTimers[i].mTimer->Cancel();
|
||||
mNotifyDidPaintTimers.RemoveElementAt(i);
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsRootPresContext::CancelAllDidPaintTimers()
|
||||
{
|
||||
for (uint32_t i = 0; i < mNotifyDidPaintTimers.Length(); i++) {
|
||||
mNotifyDidPaintTimers[i].mTimer->Cancel();
|
||||
}
|
||||
mNotifyDidPaintTimers.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
nsRootPresContext::AddWillPaintObserver(nsIRunnable* aRunnable)
|
||||
{
|
||||
|
@ -3299,7 +3296,6 @@ nsRootPresContext::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
|||
|
||||
// Measurement of the following members may be added later if DMD finds it is
|
||||
// worthwhile:
|
||||
// - mNotifyDidPaintTimer
|
||||
// - mRegisteredPlugins
|
||||
// - mWillPaintObservers
|
||||
// - mWillPaintFallbackEvent
|
||||
|
|
|
@ -1017,6 +1017,7 @@ public:
|
|||
void NotifyInvalidation(TransactionId aTransactionId, const nsIntRect& aRect);
|
||||
void NotifyDidPaintForSubtree(TransactionId aTransactionId = TransactionId{0},
|
||||
const mozilla::TimeStamp& aTimeStamp = mozilla::TimeStamp());
|
||||
void NotifyRevokingDidPaint(TransactionId aTransactionId);
|
||||
void FireDOMPaintEvent(nsTArray<nsRect>* aList,
|
||||
TransactionId aTransactionId,
|
||||
mozilla::TimeStamp aTimeStamp = mozilla::TimeStamp());
|
||||
|
@ -1215,6 +1216,8 @@ protected:
|
|||
void UpdateCharSet(NotNull<const Encoding*> aCharSet);
|
||||
|
||||
static bool NotifyDidPaintSubdocumentCallback(nsIDocument* aDocument, void* aData);
|
||||
static bool NotifyRevokingDidPaintSubdocumentCallback(nsIDocument* aDocument, void* aData);
|
||||
|
||||
|
||||
public:
|
||||
// Used by the PresShell to force a reflow when some aspect of font info
|
||||
|
@ -1254,6 +1257,7 @@ protected:
|
|||
struct TransactionInvalidations {
|
||||
TransactionId mTransactionId;
|
||||
nsTArray<nsRect> mInvalidations;
|
||||
bool mIsWaitingForPreviousTransaction = false;
|
||||
};
|
||||
TransactionInvalidations* GetInvalidations(TransactionId aTransactionId);
|
||||
|
||||
|
@ -1500,23 +1504,6 @@ public:
|
|||
virtual ~nsRootPresContext();
|
||||
virtual void Detach() override;
|
||||
|
||||
/**
|
||||
* Ensure that NotifyDidPaintForSubtree is eventually called on this
|
||||
* object after a timeout.
|
||||
*/
|
||||
void EnsureEventualDidPaintEvent(TransactionId aTransactionId);
|
||||
|
||||
/**
|
||||
* Cancels any pending eventual did paint timer for transaction
|
||||
* ids up to and including aTransactionId.
|
||||
*/
|
||||
void CancelDidPaintTimers(TransactionId aTransactionId);
|
||||
|
||||
/**
|
||||
* Cancel all pending eventual did paint timers.
|
||||
*/
|
||||
void CancelAllDidPaintTimers();
|
||||
|
||||
/**
|
||||
* Registers a plugin to receive geometry updates (position and clip
|
||||
* region) so it can update its widget.
|
||||
|
@ -1608,12 +1595,6 @@ protected:
|
|||
|
||||
friend class nsPresContext;
|
||||
|
||||
struct NotifyDidPaintTimer {
|
||||
TransactionId mTransactionId;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
};
|
||||
AutoTArray<NotifyDidPaintTimer, 4> mNotifyDidPaintTimers;
|
||||
|
||||
nsCOMPtr<nsITimer> mApplyPluginGeometryTimer;
|
||||
nsTHashtable<nsRefPtrHashKey<nsIContent> > mRegisteredPlugins;
|
||||
nsTArray<nsCOMPtr<nsIRunnable> > mWillPaintObservers;
|
||||
|
|
|
@ -1110,7 +1110,8 @@ nsRefreshDriver::nsRefreshDriver(nsPresContext* aPresContext)
|
|||
: mActiveTimer(nullptr),
|
||||
mPresContext(aPresContext),
|
||||
mRootRefresh(nullptr),
|
||||
mPendingTransaction{0},
|
||||
mNextTransactionId{0},
|
||||
mOutstandingTransactionId{0},
|
||||
mCompletedTransaction{0},
|
||||
mFreezeCount(0),
|
||||
mThrottledFrameRequestInterval(TimeDuration::FromMilliseconds(
|
||||
|
@ -1187,7 +1188,7 @@ nsRefreshDriver::RestoreNormalRefresh()
|
|||
{
|
||||
mTestControllingRefreshes = false;
|
||||
EnsureTimerStarted(eAllowTimeToGoBackwards);
|
||||
mCompletedTransaction = mPendingTransaction;
|
||||
mCompletedTransaction = mOutstandingTransactionId = mNextTransactionId;
|
||||
}
|
||||
|
||||
TimeStamp
|
||||
|
@ -2155,10 +2156,11 @@ nsRefreshDriver::FinishedWaitingForTransaction()
|
|||
mozilla::layers::TransactionId
|
||||
nsRefreshDriver::GetTransactionId(bool aThrottle)
|
||||
{
|
||||
mPendingTransaction = mPendingTransaction.Next();
|
||||
mOutstandingTransactionId = mOutstandingTransactionId.Next();
|
||||
mNextTransactionId = mNextTransactionId.Next();
|
||||
|
||||
if (aThrottle &&
|
||||
mPendingTransaction - mCompletedTransaction >= 2 &&
|
||||
mOutstandingTransactionId - mCompletedTransaction >= 2 &&
|
||||
!mWaitingForTransaction &&
|
||||
!mTestControllingRefreshes) {
|
||||
mWaitingForTransaction = true;
|
||||
|
@ -2166,38 +2168,48 @@ nsRefreshDriver::GetTransactionId(bool aThrottle)
|
|||
mWarningThreshold = 1;
|
||||
}
|
||||
|
||||
return mPendingTransaction;
|
||||
return mNextTransactionId;
|
||||
}
|
||||
|
||||
mozilla::layers::TransactionId
|
||||
nsRefreshDriver::LastTransactionId() const
|
||||
{
|
||||
return mPendingTransaction;
|
||||
return mNextTransactionId;
|
||||
}
|
||||
|
||||
void
|
||||
nsRefreshDriver::RevokeTransactionId(mozilla::layers::TransactionId aTransactionId)
|
||||
{
|
||||
MOZ_ASSERT(aTransactionId == mPendingTransaction);
|
||||
if (mPendingTransaction - mCompletedTransaction == 2 &&
|
||||
MOZ_ASSERT(aTransactionId == mNextTransactionId);
|
||||
if (mOutstandingTransactionId - mCompletedTransaction == 2 &&
|
||||
mWaitingForTransaction) {
|
||||
MOZ_ASSERT(!mSkippedPaints, "How did we skip a paint when we're in the middle of one?");
|
||||
FinishedWaitingForTransaction();
|
||||
}
|
||||
mPendingTransaction = mPendingTransaction.Prev();
|
||||
|
||||
// Notify the pres context so that it can deliver MozAfterPaint for this
|
||||
// id if any caller was expecting it.
|
||||
nsPresContext* pc = GetPresContext();
|
||||
if (pc) {
|
||||
pc->NotifyRevokingDidPaint(aTransactionId);
|
||||
}
|
||||
// Revert the outstanding transaction since we're no longer waiting on it to be
|
||||
// completed, but don't revert mNextTransactionId since we can't use the id
|
||||
// again.
|
||||
mOutstandingTransactionId = mOutstandingTransactionId.Prev();
|
||||
}
|
||||
|
||||
void
|
||||
nsRefreshDriver::ClearPendingTransactions()
|
||||
{
|
||||
mCompletedTransaction = mPendingTransaction;
|
||||
mCompletedTransaction = mOutstandingTransactionId = mNextTransactionId;
|
||||
mWaitingForTransaction = false;
|
||||
}
|
||||
|
||||
void
|
||||
nsRefreshDriver::ResetInitialTransactionId(mozilla::layers::TransactionId aTransactionId)
|
||||
{
|
||||
mCompletedTransaction = mPendingTransaction = aTransactionId;
|
||||
mCompletedTransaction = mOutstandingTransactionId = mNextTransactionId = aTransactionId;
|
||||
}
|
||||
|
||||
mozilla::TimeStamp
|
||||
|
@ -2210,7 +2222,7 @@ void
|
|||
nsRefreshDriver::NotifyTransactionCompleted(mozilla::layers::TransactionId aTransactionId)
|
||||
{
|
||||
if (aTransactionId > mCompletedTransaction) {
|
||||
if (mPendingTransaction - mCompletedTransaction > 1 &&
|
||||
if (mOutstandingTransactionId - mCompletedTransaction > 1 &&
|
||||
mWaitingForTransaction) {
|
||||
mCompletedTransaction = aTransactionId;
|
||||
FinishedWaitingForTransaction();
|
||||
|
@ -2218,6 +2230,11 @@ nsRefreshDriver::NotifyTransactionCompleted(mozilla::layers::TransactionId aTran
|
|||
mCompletedTransaction = aTransactionId;
|
||||
}
|
||||
}
|
||||
|
||||
// If completed transaction id get ahead of outstanding id, reset to distance id.
|
||||
if (mCompletedTransaction > mOutstandingTransactionId) {
|
||||
mOutstandingTransactionId = mCompletedTransaction;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -465,7 +465,12 @@ private:
|
|||
RefPtr<nsRefreshDriver> mRootRefresh;
|
||||
|
||||
// The most recently allocated transaction id.
|
||||
TransactionId mPendingTransaction;
|
||||
TransactionId mNextTransactionId;
|
||||
// This number is mCompletedTransaction + (pending transaction count).
|
||||
// When we revoke a transaction id, we revert this number (since it's
|
||||
// no longer outstanding), but not mNextTransactionId (since we don't
|
||||
// want to reuse the number).
|
||||
TransactionId mOutstandingTransactionId;
|
||||
// The most recently completed transaction id.
|
||||
TransactionId mCompletedTransaction;
|
||||
|
||||
|
|
|
@ -321,7 +321,7 @@ pref(gfx.font_rendering.graphite.enabled,true) == glyph-decomposition-graphite.h
|
|||
== hyphenation-control-2.html hyphenation-control-2-ref.html
|
||||
== hyphenation-control-3.html hyphenation-control-3-ref.html
|
||||
== hyphenation-control-4.html hyphenation-control-4-ref.html
|
||||
fuzzy-if(winWidget,0-47,0-6) == hyphenation-control-5.html hyphenation-control-5-ref.html
|
||||
fuzzy-if(winWidget,0-56,0-6) == hyphenation-control-5.html hyphenation-control-5-ref.html
|
||||
random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == hyphenation-control-6.html hyphenation-control-6-ref.html # Bug 1392106
|
||||
== hyphenation-control-7.html hyphenation-control-7-ref.html
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ add_task(async function smil_is_in_display_none_subtree() {
|
|||
animate.setAttribute("repeatCount", "indefinite");
|
||||
document.getElementById("svg-rect").appendChild(animate);
|
||||
|
||||
await waitForPaintFlushed();
|
||||
await waitForAnimationFrames(2);
|
||||
|
||||
var displayMarkers = await observeStyling(5);
|
||||
// FIXME: Bug 866411: SMIL animations sometimes skip restyles when the target
|
||||
|
@ -97,7 +97,7 @@ add_task(async function smil_is_in_display_none_subtree() {
|
|||
|
||||
div.style.display = "";
|
||||
getComputedStyle(div).display;
|
||||
await waitForPaintFlushed();
|
||||
await waitForAnimationFrames(2);
|
||||
|
||||
var displayAgainMarkers = await observeStyling(5);
|
||||
// FIXME: Bug 866411: SMIL animations sometimes skip restyles when the target
|
||||
|
|
Загрузка…
Ссылка в новой задаче