зеркало из https://github.com/mozilla/gecko-dev.git
Bug 854421 - Part 8: Try find a 'root' refresh driver to see if it's blocked. r=vlad
This commit is contained in:
Родитель
de268276b8
Коммит
c9c9b9cb80
|
@ -58,7 +58,7 @@ parent:
|
|||
|
||||
// We don't need to send a sync transaction if
|
||||
// no transaction operate require a swap.
|
||||
async UpdateNoSwap(Edit[] cset, uin64_t id, TargetConfig targetConfig, bool isFirstPaint,
|
||||
async UpdateNoSwap(Edit[] cset, uint64_t id, TargetConfig targetConfig, bool isFirstPaint,
|
||||
bool scheduleComposite, uint32_t paintSequenceNumber);
|
||||
|
||||
// Testing APIs
|
||||
|
|
|
@ -4039,10 +4039,14 @@ PresShell::FlushPendingNotifications(mozilla::ChangesToFlush aFlush)
|
|||
|
||||
if (aFlush.mFlushAnimations &&
|
||||
!mPresContext->StyleUpdateForAllAnimationsIsUpToDate()) {
|
||||
mPresContext->AnimationManager()->
|
||||
FlushAnimations(CommonAnimationManager::Cannot_Throttle);
|
||||
mPresContext->TransitionManager()->
|
||||
FlushTransitions(CommonAnimationManager::Cannot_Throttle);
|
||||
if (mPresContext->AnimationManager()) {
|
||||
mPresContext->AnimationManager()->
|
||||
FlushAnimations(CommonAnimationManager::Cannot_Throttle);
|
||||
}
|
||||
if (mPresContext->TransitionManager()) {
|
||||
mPresContext->TransitionManager()->
|
||||
FlushTransitions(CommonAnimationManager::Cannot_Throttle);
|
||||
}
|
||||
mPresContext->TickLastStyleUpdateForAllAnimations();
|
||||
}
|
||||
|
||||
|
|
|
@ -686,6 +686,7 @@ nsRefreshDriver::nsRefreshDriver(nsPresContext* aPresContext)
|
|||
mReflowCause(nullptr),
|
||||
mStyleCause(nullptr),
|
||||
mPresContext(aPresContext),
|
||||
mRootRefresh(nullptr),
|
||||
mPendingTransaction(0),
|
||||
mCompletedTransaction(0),
|
||||
mFreezeCount(0),
|
||||
|
@ -707,6 +708,10 @@ nsRefreshDriver::~nsRefreshDriver()
|
|||
"observers should have unregistered");
|
||||
NS_ABORT_IF_FALSE(!mActiveTimer, "timer should be gone");
|
||||
|
||||
if (mRootRefresh) {
|
||||
mRootRefresh->RemoveRefreshObserver(this, Flush_Style);
|
||||
mRootRefresh = nullptr;
|
||||
}
|
||||
for (uint32_t i = 0; i < mPresShellsToInvalidateIfHidden.Length(); i++) {
|
||||
mPresShellsToInvalidateIfHidden[i]->InvalidatePresShellIfHidden();
|
||||
}
|
||||
|
@ -1065,13 +1070,17 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
|
|||
mMostRecentRefresh = aNowTime;
|
||||
mMostRecentRefreshEpochTime = aNowEpoch;
|
||||
|
||||
if (mWaitingForTransaction) {
|
||||
if (IsWaitingForPaint()) {
|
||||
// We're currently suspended waiting for earlier Tick's to
|
||||
// be completed (on the Compositor). Mark that we missed the paint
|
||||
// and keep waiting.
|
||||
mSkippedPaint = true;
|
||||
return;
|
||||
}
|
||||
if (mRootRefresh) {
|
||||
mRootRefresh->RemoveRefreshObserver(this, Flush_Style);
|
||||
mRootRefresh = nullptr;
|
||||
}
|
||||
mSkippedPaint = false;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell = mPresContext->GetPresShell();
|
||||
if (!presShell || (ObserverCount() == 0 && ImageRequestCount() == 0)) {
|
||||
|
@ -1424,6 +1433,49 @@ nsRefreshDriver::NotifyTransactionCompleted(uint64_t aTransactionId)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsRefreshDriver::WillRefresh(mozilla::TimeStamp aTime)
|
||||
{
|
||||
mRootRefresh->RemoveRefreshObserver(this, Flush_Style);
|
||||
mRootRefresh = nullptr;
|
||||
if (mSkippedPaint) {
|
||||
DoRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsRefreshDriver::IsWaitingForPaint()
|
||||
{
|
||||
if (mTestControllingRefreshes) {
|
||||
return false;
|
||||
}
|
||||
if (mWaitingForTransaction) {
|
||||
mSkippedPaint = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try find the 'root' refresh driver for the current window and check
|
||||
// if that is waiting for a paint.
|
||||
nsPresContext *displayRoot = PresContext()->GetDisplayRootPresContext();
|
||||
if (displayRoot) {
|
||||
nsRefreshDriver *rootRefresh = displayRoot->GetRootPresContext()->RefreshDriver();
|
||||
if (rootRefresh && rootRefresh != this) {
|
||||
if (rootRefresh->IsWaitingForPaint()) {
|
||||
if (mRootRefresh != rootRefresh) {
|
||||
if (mRootRefresh) {
|
||||
mRootRefresh->RemoveRefreshObserver(this, Flush_Style);
|
||||
}
|
||||
rootRefresh->AddRefreshObserver(this, Flush_Style);
|
||||
mRootRefresh = rootRefresh;
|
||||
}
|
||||
mSkippedPaint = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
nsRefreshDriver::SetThrottled(bool aThrottled)
|
||||
{
|
||||
|
|
|
@ -63,7 +63,8 @@ public:
|
|||
virtual void DidRefresh() = 0;
|
||||
};
|
||||
|
||||
class nsRefreshDriver MOZ_FINAL : public mozilla::layers::TransactionIdAllocator {
|
||||
class nsRefreshDriver MOZ_FINAL : public mozilla::layers::TransactionIdAllocator,
|
||||
public nsARefreshObserver {
|
||||
public:
|
||||
nsRefreshDriver(nsPresContext *aPresContext);
|
||||
~nsRefreshDriver();
|
||||
|
@ -275,6 +276,12 @@ public:
|
|||
void NotifyTransactionCompleted(uint64_t aTransactionId) MOZ_OVERRIDE;
|
||||
void RevokeTransactionId(uint64_t aTransactionId) MOZ_OVERRIDE;
|
||||
|
||||
bool IsWaitingForPaint();
|
||||
|
||||
// nsARefreshObserver
|
||||
NS_IMETHOD_(MozExternalRefCountType) AddRef(void) { return TransactionIdAllocator::AddRef(); }
|
||||
NS_IMETHOD_(MozExternalRefCountType) Release(void) { return TransactionIdAllocator::Release(); }
|
||||
virtual void WillRefresh(mozilla::TimeStamp aTime);
|
||||
private:
|
||||
typedef nsTObserverArray<nsARefreshObserver*> ObserverArray;
|
||||
typedef nsTHashtable<nsISupportsHashKey> RequestTable;
|
||||
|
@ -328,6 +335,8 @@ private:
|
|||
nsPresContext *mPresContext; // weak; pres context passed in constructor
|
||||
// and unset in Disconnect
|
||||
|
||||
nsRefPtr<nsRefreshDriver> mRootRefresh;
|
||||
|
||||
// The most recently allocated transaction id.
|
||||
uint64_t mPendingTransaction;
|
||||
// The most recently completed transaction id.
|
||||
|
|
Загрузка…
Ссылка в новой задаче