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:
kmcclusk%netscape.com 2002-09-19 02:53:05 +00:00
Родитель 67041f2b0f
Коммит 0db2c6960a
3 изменённых файлов: 76 добавлений и 10 удалений

Просмотреть файл

@ -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
******************************************************************************/