зеркало из https://github.com/mozilla/gecko-dev.git
Bug 519590. Don't interrupt reflow until some time has passed. r=roc
This commit is contained in:
Родитель
e1ef46ba15
Коммит
628a6ad230
|
@ -4375,10 +4375,14 @@ nsDocShell::GetPositionAndSize(PRInt32 * x, PRInt32 * y, PRInt32 * cx,
|
|||
{
|
||||
// We should really consider just getting this information from
|
||||
// our window instead of duplicating the storage and code...
|
||||
nsCOMPtr<nsIDOMDocument> document(do_GetInterface(GetAsSupports(mParent)));
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(document));
|
||||
if (doc) {
|
||||
doc->FlushPendingNotifications(Flush_Layout);
|
||||
if (cx || cy) {
|
||||
// Caller wants to know our size; make sure to give them up to
|
||||
// date information.
|
||||
nsCOMPtr<nsIDOMDocument> document(do_GetInterface(GetAsSupports(mParent)));
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(document));
|
||||
if (doc) {
|
||||
doc->FlushPendingNotifications(Flush_Layout);
|
||||
}
|
||||
}
|
||||
|
||||
DoGetPositionAndSize(x, y, cx, cy);
|
||||
|
|
|
@ -112,6 +112,9 @@
|
|||
//needed for resetting of image service color
|
||||
#include "nsLayoutCID.h"
|
||||
|
||||
using mozilla::TimeDuration;
|
||||
using mozilla::TimeStamp;
|
||||
|
||||
static nscolor
|
||||
MakeColorPref(const char *colstr)
|
||||
{
|
||||
|
@ -2062,18 +2065,33 @@ nsPresContext::HasCachedStyleData()
|
|||
return mShell && mShell->StyleSet()->HasCachedStyleData();
|
||||
}
|
||||
|
||||
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
|
||||
static PRBool sGotInterruptEnv = PR_FALSE;
|
||||
static PRUint32 sInterruptSeed = 1;
|
||||
static PRUint32 sInterruptChecksToSkip = 200;
|
||||
enum InterruptMode {
|
||||
ModeRandom,
|
||||
ModeCounter,
|
||||
ModeEvent
|
||||
};
|
||||
// Controlled by the GECKO_REFLOW_INTERRUPT_MODE env var; allowed values are
|
||||
// "random" (except on Windows) or "counter". If neither is used, the mode is
|
||||
// ModeEvent.
|
||||
static InterruptMode sInterruptMode = ModeEvent;
|
||||
static PRUint32 sInterruptCounter;
|
||||
// Used for the "random" mode. Controlled by the GECKO_REFLOW_INTERRUPT_SEED
|
||||
// env var.
|
||||
static PRUint32 sInterruptSeed = 1;
|
||||
// Used for the "counter" mode. This is the number of unskipped interrupt
|
||||
// checks that have to happen before we interrupt. Controlled by the
|
||||
// GECKO_REFLOW_INTERRUPT_FREQUENCY env var.
|
||||
static PRUint32 sInterruptMaxCounter = 10;
|
||||
// Used for the "counter" mode. This counts up to sInterruptMaxCounter and is
|
||||
// then reset to 0.
|
||||
static PRUint32 sInterruptCounter;
|
||||
// Number of interrupt checks to skip before really trying to interrupt.
|
||||
// Controlled by the GECKO_REFLOW_INTERRUPT_CHECKS_TO_SKIP env var.
|
||||
static PRUint32 sInterruptChecksToSkip = 200;
|
||||
// Number of milliseconds that a reflow should be allowed to run for before we
|
||||
// actually allow interruption. Controlled by the
|
||||
// GECKO_REFLOW_MIN_NOINTERRUPT_DURATION env var.
|
||||
static TimeDuration sInterruptTimeout = TimeDuration::FromMilliseconds(100);
|
||||
|
||||
static void GetInterruptEnv()
|
||||
{
|
||||
|
@ -2102,6 +2120,11 @@ static void GetInterruptEnv()
|
|||
if (ev) {
|
||||
sInterruptChecksToSkip = atoi(ev);
|
||||
}
|
||||
|
||||
ev = PR_GetEnv("GECKO_REFLOW_MIN_NOINTERRUPT_DURATION");
|
||||
if (ev) {
|
||||
sInterruptTimeout = TimeDuration::FromMilliseconds(atoi(ev));
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -2136,6 +2159,11 @@ nsPresContext::HavePendingInputEvent()
|
|||
void
|
||||
nsPresContext::ReflowStarted(PRBool aInterruptible)
|
||||
{
|
||||
#ifdef NOISY_INTERRUPTIBLE_REFLOW
|
||||
if (!aInterruptible) {
|
||||
printf("STARTING NONINTERRUPTIBLE REFLOW\n");
|
||||
}
|
||||
#endif
|
||||
// We don't support interrupting in paginated contexts, since page
|
||||
// sequences only handle initial reflow
|
||||
mInterruptsEnabled = aInterruptible && !IsPaginated();
|
||||
|
@ -2149,6 +2177,10 @@ nsPresContext::ReflowStarted(PRBool aInterruptible)
|
|||
mHasPendingInterrupt = PR_FALSE;
|
||||
|
||||
mInterruptChecksToSkip = sInterruptChecksToSkip;
|
||||
|
||||
if (mInterruptsEnabled) {
|
||||
mReflowStartTime = TimeStamp::Now();
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -2174,7 +2206,12 @@ nsPresContext::CheckForInterrupt(nsIFrame* aFrame)
|
|||
}
|
||||
mInterruptChecksToSkip = sInterruptChecksToSkip;
|
||||
|
||||
mHasPendingInterrupt = HavePendingInputEvent();
|
||||
// Don't interrupt if it's been less than sInterruptTimeout since we started
|
||||
// the reflow.
|
||||
mHasPendingInterrupt =
|
||||
TimeStamp::Now() - mReflowStartTime > sInterruptTimeout &&
|
||||
HavePendingInputEvent() &&
|
||||
!IsChrome();
|
||||
if (mHasPendingInterrupt) {
|
||||
#ifdef NOISY_INTERRUPTIBLE_REFLOW
|
||||
printf("*** DETECTED pending interrupt (time=%lld)\n", PR_Now());
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
class nsImageLoader;
|
||||
#ifdef IBMBIDI
|
||||
|
@ -1015,6 +1016,8 @@ protected:
|
|||
|
||||
PRUint32 mInterruptChecksToSkip;
|
||||
|
||||
mozilla::TimeStamp mReflowStartTime;
|
||||
|
||||
unsigned mHasPendingInterrupt : 1;
|
||||
unsigned mInterruptsEnabled : 1;
|
||||
unsigned mUseDocumentFonts : 1;
|
||||
|
|
|
@ -7229,6 +7229,11 @@ PresShell::PostReflowEventOffTimer()
|
|||
PRBool
|
||||
PresShell::DoReflow(nsIFrame* target, PRBool aInterruptible)
|
||||
{
|
||||
if (mReflowContinueTimer) {
|
||||
mReflowContinueTimer->Cancel();
|
||||
mReflowContinueTimer = nsnull;
|
||||
}
|
||||
|
||||
nsIFrame* rootFrame = FrameManager()->GetRootFrame();
|
||||
|
||||
nsCOMPtr<nsIRenderingContext> rcx;
|
||||
|
|
Загрузка…
Ссылка в новой задаче