зеркало из https://github.com/mozilla/gecko-dev.git
Change PLEvent notification on WIN32 to use a native timer instead of a posted WM_APP message when documents are not loading. This fixes some DHTML paint starvation issues and lowers overall CPU usage on many pages with DHTML. bug=164931 r=rpotts@netscape.com sr=kin@netscape.com
This commit is contained in:
Родитель
67041f2b0f
Коммит
0db2c6960a
|
@ -145,6 +145,17 @@ static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
|
|||
#if defined(DEBUG_rods) || defined(DEBUG_bryner)
|
||||
//#define DEBUG_DOCSHELL_FOCUS
|
||||
#endif
|
||||
|
||||
#include "plevent.h"
|
||||
|
||||
// Number of documents currently loading
|
||||
static PRInt32 gNumberOfDocumentsLoading = 0;
|
||||
|
||||
// Hint for native dispatch of plevents on how long to delay after
|
||||
// all documents have loaded in milliseconds before favoring normal
|
||||
// native event dispatch priorites over performance
|
||||
#define NS_EVENT_STARVATION_DELAY_HINT 2000
|
||||
|
||||
//
|
||||
// Local function prototypes
|
||||
//
|
||||
|
@ -4118,6 +4129,14 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress,
|
|||
mContentViewer->LoadComplete(aStatus);
|
||||
|
||||
mEODForCurrentDocument = PR_TRUE;
|
||||
|
||||
// If all documents have completed their loading
|
||||
// favor native event dispatch priorities
|
||||
// over performance
|
||||
if (--gNumberOfDocumentsLoading == 0) {
|
||||
// Hint to use normal native event dispatch priorities
|
||||
PL_FavorPerformanceHint(PR_FALSE, NS_EVENT_STARVATION_DELAY_HINT);
|
||||
}
|
||||
}
|
||||
/* Check if the httpChannel has any cache-control related response headers,
|
||||
* like no-store, no-cache. If so, update SHEntry so that
|
||||
|
@ -4321,6 +4340,16 @@ nsDocShell::CreateContentViewer(const char *aContentType,
|
|||
|
||||
mEODForCurrentDocument = PR_FALSE;
|
||||
|
||||
// Give hint to native plevent dispatch mechanism. If a document
|
||||
// is loading the native plevent dispatch mechanism should favor
|
||||
// performance over normal native event dispatch priorities.
|
||||
if (++gNumberOfDocumentsLoading == 1) {
|
||||
// Hint to favor performance for the plevent notification mechanism.
|
||||
// We want the pages to load as fast as possible even if its means
|
||||
// native messages might be starved.
|
||||
PL_FavorPerformanceHint(PR_TRUE, NS_EVENT_STARVATION_DELAY_HINT);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -99,9 +99,12 @@
|
|||
#define WIN9X_PAINT_STARVATION_LIMIT 3000
|
||||
|
||||
#define TIMER_ID 0
|
||||
static HHOOK _md_MouseMsgFilterHook = NULL;
|
||||
static PRBool _md_MovingWindow = PR_FALSE;
|
||||
static PRInt32 _md_WindowCount = 0;
|
||||
static HHOOK _md_MouseMsgFilterHook = NULL;
|
||||
static PRBool _md_MovingWindow = PR_FALSE;
|
||||
static PRInt32 _md_WindowCount = 0;
|
||||
static PRBool _md_FavorPerformance = PR_FALSE;
|
||||
static PRUint32 _md_StarvationDelay = 0;
|
||||
static PRUint32 _md_SwitchTime = 0;
|
||||
#endif
|
||||
|
||||
static PRLogModuleInfo *event_lm = NULL;
|
||||
|
@ -714,6 +717,19 @@ PL_DequeueEvent(PLEvent* self, PLEventQueue* queue)
|
|||
PR_ExitMonitor(queue->monitor);
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
PL_FavorPerformanceHint(PRBool favorPerformanceOverEventStarvation, PRUint32 starvationDelay)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
_md_FavorPerformance = favorPerformanceOverEventStarvation;
|
||||
_md_StarvationDelay = starvationDelay;
|
||||
|
||||
if (! favorPerformanceOverEventStarvation) {
|
||||
_md_SwitchTime = PR_IntervalToMilliseconds(PR_IntervalNow());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Pure Event Queues
|
||||
*
|
||||
|
@ -955,16 +971,16 @@ static PRUint32 _md_GetPaintStarvationLimit() {
|
|||
*/
|
||||
|
||||
static PRBool _md_EventIsStarved(PRBool isPending, PRUint32 starvationLimit,
|
||||
PRBool *wasPending, PRUint32 *lastTime)
|
||||
PRBool *wasPending, PRUint32 *lastTime,
|
||||
PRUint32 currentTime)
|
||||
{
|
||||
if ((*wasPending) && (isPending)) {
|
||||
/* It was pending previously and the event is still
|
||||
* pending so check to see if the elapsed time is
|
||||
* over the limit which indicates the event was starved
|
||||
*/
|
||||
PRUint32 now = PR_IntervalToMilliseconds(PR_IntervalNow());
|
||||
|
||||
if ((now - *lastTime) > starvationLimit) {
|
||||
if ((currentTime - *lastTime) > starvationLimit) {
|
||||
return PR_TRUE; /* pending and over the limit */
|
||||
}
|
||||
|
||||
|
@ -976,7 +992,7 @@ static PRBool _md_EventIsStarved(PRBool isPending, PRUint32 starvationLimit,
|
|||
* so the elapsed time can be computed the next time this
|
||||
* function is called
|
||||
*/
|
||||
*lastTime = PR_IntervalToMilliseconds(PR_IntervalNow());
|
||||
*lastTime = currentTime;
|
||||
*wasPending = PR_TRUE;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
@ -1030,11 +1046,16 @@ _pl_NativeNotify(PLEventQueue* self)
|
|||
#ifdef USE_TIMER
|
||||
WORD qstatus;
|
||||
|
||||
if (_md_MovingWindow) {
|
||||
PRUint32 now = PR_IntervalToMilliseconds(PR_IntervalNow());
|
||||
|
||||
if (_md_MovingWindow ||
|
||||
(! _md_FavorPerformance) &&
|
||||
((now - _md_SwitchTime) > _md_StarvationDelay)) {
|
||||
SetTimer(self->eventReceiverWindow, TIMER_ID, 0 ,_md_TimerProc);
|
||||
self->timerSet = PR_TRUE;
|
||||
_md_WasInputPending = PR_FALSE;
|
||||
_md_WasPaintPending = PR_FALSE;
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1042,7 +1063,7 @@ _pl_NativeNotify(PLEventQueue* self)
|
|||
|
||||
/* Check for starved input */
|
||||
if (_md_EventIsStarved( _md_IsInputPending(qstatus), INPUT_STARVATION_LIMIT,
|
||||
&_md_WasInputPending, &_md_InputTime )) {
|
||||
&_md_WasInputPending, &_md_InputTime, now )) {
|
||||
/* Use timer for notification. Timers have the lowest priority. They are not processed
|
||||
* until all other events have been processed. This allows the starved paints and input to
|
||||
* be processed
|
||||
|
@ -1055,7 +1076,7 @@ _pl_NativeNotify(PLEventQueue* self)
|
|||
}
|
||||
|
||||
if (_md_EventIsStarved( (qstatus & QS_PAINT), _md_GetPaintStarvationLimit(),
|
||||
&_md_WasPaintPending, &_md_PaintTime) ) {
|
||||
&_md_WasPaintPending, &_md_PaintTime, now) ) {
|
||||
/* Use timer for notification. Timers have the lowest priority. They are not processed
|
||||
* until all other events have been processed. This allows the starved paints and input to
|
||||
* be processed
|
||||
|
|
|
@ -458,6 +458,22 @@ PL_DestroyEvent(PLEvent* self);
|
|||
PR_EXTERN(void)
|
||||
PL_DequeueEvent(PLEvent* self, PLEventQueue* queue);
|
||||
|
||||
|
||||
/*
|
||||
* Give hint to native PL_Event notification mechanism. If the native
|
||||
* platform needs to tradeoff performance vs. native event starvation
|
||||
* this hint tells the native dispatch code which to favor.
|
||||
* The default is to prevent event starvation.
|
||||
*
|
||||
* The starvationDelay arg is only used when
|
||||
* favorPerformanceOverEventStarvation is PR_FALSE. It is the
|
||||
* amount of time in milliseconds to wait before the PR_FALSE actually
|
||||
* takes effect.
|
||||
*/
|
||||
PR_EXTERN(void)
|
||||
PL_FavorPerformanceHint(PRBool favorPerformanceOverEventStarvation, PRUint32 starvationDelay);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Private Stuff
|
||||
******************************************************************************/
|
||||
|
|
Загрузка…
Ссылка в новой задаче