зеркало из https://github.com/mozilla/gecko-dev.git
Bug 696248. Flush pending onscroll events before painting. r=mats
This commit is contained in:
Родитель
2e602e5305
Коммит
91cce0a191
|
@ -2700,3 +2700,27 @@ nsRootPresContext::EnsureEventualDidPaintEvent()
|
|||
mNotifyDidPaintTimer->InitWithFuncCallback(NotifyDidPaintForSubtreeCallback,
|
||||
(void*)this, 100, nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
void
|
||||
nsRootPresContext::AddWillPaintObserver(nsIRunnable* aRunnable)
|
||||
{
|
||||
if (!mWillPaintFallbackEvent.IsPending()) {
|
||||
mWillPaintFallbackEvent = new RunWillPaintObservers(this);
|
||||
NS_DispatchToMainThread(mWillPaintFallbackEvent.get());
|
||||
}
|
||||
mWillPaintObservers.AppendElement(aRunnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run all runnables that need to get called before the next paint.
|
||||
*/
|
||||
void
|
||||
nsRootPresContext::FlushWillPaintObservers()
|
||||
{
|
||||
mWillPaintFallbackEvent = nsnull;
|
||||
nsTArray<nsCOMPtr<nsIRunnable> > observers;
|
||||
observers.SwapElements(mWillPaintObservers);
|
||||
for (PRUint32 i = 0; i < observers.Length(); ++i) {
|
||||
observers[i]->Run();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1304,12 +1304,40 @@ public:
|
|||
*/
|
||||
PRUint32 GetDOMGeneration() { return mDOMGeneration; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Add a runnable that will get called before the next paint. They will get
|
||||
* run eventually even if painting doesn't happen. They might run well before
|
||||
* painting happens.
|
||||
*/
|
||||
void AddWillPaintObserver(nsIRunnable* aRunnable);
|
||||
|
||||
/**
|
||||
* Run all runnables that need to get called before the next paint.
|
||||
*/
|
||||
void FlushWillPaintObservers();
|
||||
|
||||
protected:
|
||||
class RunWillPaintObservers : public nsRunnable {
|
||||
public:
|
||||
RunWillPaintObservers(nsRootPresContext* aPresContext) : mPresContext(aPresContext) {}
|
||||
void Revoke() { mPresContext = nsnull; }
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
if (mPresContext) {
|
||||
mPresContext->FlushWillPaintObservers();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
nsRootPresContext* mPresContext;
|
||||
};
|
||||
|
||||
nsCOMPtr<nsITimer> mNotifyDidPaintTimer;
|
||||
nsTHashtable<nsPtrHashKey<nsObjectFrame> > mRegisteredPlugins;
|
||||
// if mNeedsToUpdatePluginGeometry is set, then this is the frame to
|
||||
// use as the root of the subtree to search for plugin updates, or
|
||||
// null to use the root frame of this prescontext
|
||||
nsTArray<nsCOMPtr<nsIRunnable> > mWillPaintObservers;
|
||||
nsRevocableEventPtr<RunWillPaintObservers> mWillPaintFallbackEvent;
|
||||
nsIFrame* mUpdatePluginGeometryForFrame;
|
||||
PRUint32 mDOMGeneration;
|
||||
bool mNeedsToUpdatePluginGeometry;
|
||||
|
|
|
@ -4460,6 +4460,13 @@ PresShell::RenderDocument(const nsRect& aRect, PRUint32 aFlags,
|
|||
|
||||
NS_ENSURE_TRUE(!(aFlags & RENDER_IS_UNTRUSTED), NS_ERROR_NOT_IMPLEMENTED);
|
||||
|
||||
nsRootPresContext* rootPresContext = mPresContext->GetRootPresContext();
|
||||
if (rootPresContext) {
|
||||
rootPresContext->FlushWillPaintObservers();
|
||||
if (mIsDestroying)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoScriptBlocker blockScripts;
|
||||
|
||||
// Set up the rectangle as the path in aThebesContext
|
||||
|
@ -6861,16 +6868,18 @@ PresShell::WillPaint(bool aWillSendDidPaint)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!aWillSendDidPaint) {
|
||||
nsRootPresContext* rootPresContext = mPresContext->GetRootPresContext();
|
||||
if (!rootPresContext) {
|
||||
return;
|
||||
}
|
||||
if (rootPresContext == mPresContext) {
|
||||
rootPresContext->UpdatePluginGeometry();
|
||||
}
|
||||
nsRootPresContext* rootPresContext = mPresContext->GetRootPresContext();
|
||||
if (!rootPresContext) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!aWillSendDidPaint && rootPresContext == mPresContext) {
|
||||
rootPresContext->UpdatePluginGeometry();
|
||||
}
|
||||
rootPresContext->FlushWillPaintObservers();
|
||||
if (mIsDestroying)
|
||||
return;
|
||||
|
||||
// Process reflows, if we have them, to reduce flicker due to invalidates and
|
||||
// reflow being interspersed. Note that we _do_ allow this to be
|
||||
// interruptible; if we can't do all the reflows it's better to flicker a bit
|
||||
|
|
|
@ -2643,12 +2643,11 @@ nsGfxScrollFrameInner::PostScrollEvent()
|
|||
if (mScrollEvent.IsPending())
|
||||
return;
|
||||
|
||||
nsRefPtr<ScrollEvent> ev = new ScrollEvent(this);
|
||||
if (NS_FAILED(NS_DispatchToCurrentThread(ev))) {
|
||||
NS_WARNING("failed to dispatch ScrollEvent");
|
||||
} else {
|
||||
mScrollEvent = ev;
|
||||
}
|
||||
nsRootPresContext* rpc = mOuter->PresContext()->GetRootPresContext();
|
||||
if (!rpc)
|
||||
return;
|
||||
mScrollEvent = new ScrollEvent(this);
|
||||
rpc->AddWillPaintObserver(mScrollEvent.get());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
Загрузка…
Ссылка в новой задаче