Skip to content

Commit

Permalink
Greatly reduce the number of timers firing when multiple Carbon plugi…
Browse files Browse the repository at this point in the history
…n instances are active on Mac OS X. Should reduce CPU usage. Make all instances use the same (at most two) timers for idle events. b=519598 r=roc
  • Loading branch information
Josh Aas committed Dec 15, 2009
1 parent 8403813 commit 1e57594
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 52 deletions.
6 changes: 6 additions & 0 deletions dom/base/nsGlobalWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ class nsDummyJavaPluginOwner : public nsIPluginInstanceOwner
NPError ShowNativeContextMenu(NPMenu* menu, void* event);
NPBool ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
double *destX, double *destY, NPCoordinateSpace destSpace);
void SendIdleEvent();

NS_DECL_CYCLE_COLLECTION_CLASS(nsDummyJavaPluginOwner)

Expand Down Expand Up @@ -563,6 +564,11 @@ nsDummyJavaPluginOwner::SetEventModel(PRInt32 eventModel)
return NS_ERROR_NOT_IMPLEMENTED;
}

void
nsDummyJavaPluginOwner::SendIdleEvent()
{
}

/**
* An indirect observer object that means we don't have to implement nsIObserver
* on nsGlobalWindow, where any script could see it.
Expand Down
83 changes: 34 additions & 49 deletions layout/generic/nsObjectFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,9 @@ enum { XKeyPress = KeyPress };
static PRLogModuleInfo *nsObjectFrameLM = PR_NewLogModule("nsObjectFrame");
#endif /* PR_LOGGING */

#define NORMAL_PLUGIN_DELAY 20
// must avoid audio skipping/delays
#define HIDDEN_PLUGIN_DELAY 125
#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
#define MAC_CARBON_PLUGINS
#endif

// special class for handeling DOM context menu events because for
// some reason it starves other mouse events if implemented on the
Expand Down Expand Up @@ -257,7 +257,6 @@ class nsPluginDOMContextMenuListener : public nsIDOMContextMenuListener

class nsPluginInstanceOwner : public nsIPluginInstanceOwner,
public nsIPluginTagInfo,
public nsITimerCallback,
public nsIDOMMouseListener,
public nsIDOMMouseMotionListener,
public nsIDOMKeyListener,
Expand Down Expand Up @@ -325,11 +324,11 @@ class nsPluginInstanceOwner : public nsIPluginInstanceOwner,
void Paint(const nsRect& aDirtyRect, HPS aHPS);
#endif

// nsITimerCallback interface
NS_DECL_NSITIMERCALLBACK

#ifdef MAC_CARBON_PLUGINS
void CancelTimer();
void StartTimer(unsigned int aDelay);
void StartTimer(PRBool isVisible);
#endif
void SendIdleEvent();

// nsIScrollPositionListener interface
NS_IMETHOD ScrollPositionWillChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY);
Expand Down Expand Up @@ -432,7 +431,6 @@ class nsPluginInstanceOwner : public nsIPluginInstanceOwner,
nsCString mDocumentBase;
char *mTagText;
nsCOMPtr<nsIWidget> mWidget;
nsCOMPtr<nsITimer> mPluginTimer;
nsCOMPtr<nsIPluginHost> mPluginHost;

#ifdef XP_MACOSX
Expand All @@ -452,7 +450,6 @@ class nsPluginInstanceOwner : public nsIPluginInstanceOwner,
// If true, destroy the widget on destruction. Used when plugin stop
// is being delayed to a safer point in time.
PRPackedBool mDestroyWidget;
PRPackedBool mTimerCanceled;
PRUint16 mNumCachedAttrs;
PRUint16 mNumCachedParams;
char **mCachedAttrParamNames;
Expand Down Expand Up @@ -1368,7 +1365,7 @@ nsObjectFrame::PrintPlugin(nsIRenderingContext& aRenderingContext,
window.clipRect.left = 0; window.clipRect.right = 0;

// platform specific printing code
#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
#ifdef MAC_CARBON_PLUGINS
nsSize contentSize = GetContentRect().Size();
window.x = 0;
window.y = 0;
Expand Down Expand Up @@ -1932,7 +1929,9 @@ nsObjectFrame::HandleEvent(nsPresContext* aPresContext,
#endif

if (anEvent->message == NS_DESTROY) {
#ifdef MAC_CARBON_PLUGINS
mInstanceOwner->CancelTimer();
#endif
return rv;
}

Expand Down Expand Up @@ -2432,7 +2431,6 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
mCachedAttrParamNames = nsnull;
mCachedAttrParamValues = nsnull;
mDestroyWidget = PR_FALSE;
mTimerCanceled = PR_TRUE;

#ifdef MOZ_COMPOSITED_PLUGINS
mLastPoint = nsIntPoint(0,0);
Expand Down Expand Up @@ -2463,8 +2461,9 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner()
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG,
("nsPluginInstanceOwner %p deleted\n", this));

// shut off the timer.
#ifdef MAC_CARBON_PLUGINS
CancelTimer();
#endif

mObjectFrame = nsnull;

Expand Down Expand Up @@ -2521,7 +2520,6 @@ NS_IMPL_RELEASE(nsPluginInstanceOwner)
NS_INTERFACE_MAP_BEGIN(nsPluginInstanceOwner)
NS_INTERFACE_MAP_ENTRY(nsIPluginInstanceOwner)
NS_INTERFACE_MAP_ENTRY(nsIPluginTagInfo)
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
NS_INTERFACE_MAP_ENTRY(nsIDOMMouseListener)
NS_INTERFACE_MAP_ENTRY(nsIDOMMouseMotionListener)
NS_INTERFACE_MAP_ENTRY(nsIDOMKeyListener)
Expand Down Expand Up @@ -3571,7 +3569,7 @@ nsPluginInstanceOwner::GetEventloopNestingLevel()

nsresult nsPluginInstanceOwner::ScrollPositionWillChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY)
{
#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
#ifdef MAC_CARBON_PLUGINS
if (GetEventModel() != NPEventModelCarbon)
return NS_OK;

Expand All @@ -3598,7 +3596,7 @@ nsresult nsPluginInstanceOwner::ScrollPositionWillChange(nsIScrollableView* aScr

nsresult nsPluginInstanceOwner::ScrollPositionDidChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY)
{
#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
#ifdef MAC_CARBON_PLUGINS
if (GetEventModel() != NPEventModelCarbon)
return NS_OK;

Expand All @@ -3617,9 +3615,9 @@ nsresult nsPluginInstanceOwner::ScrollPositionDidChange(nsIScrollableView* aScro
pluginWidget->EndDrawPlugin();
}
}
#endif

StartTimer(NORMAL_PLUGIN_DELAY);
StartTimer(PR_TRUE);
#endif
return NS_OK;
}

Expand Down Expand Up @@ -3679,7 +3677,7 @@ nsresult nsPluginInstanceOwner::KeyUp(nsIDOMEvent* aKeyEvent)

nsresult nsPluginInstanceOwner::KeyPress(nsIDOMEvent* aKeyEvent)
{
#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
#ifdef MAC_CARBON_PLUGINS
// send KeyPress events only for Mac OS X Carbon event model
if (GetEventModel() != NPEventModelCarbon)
return aKeyEvent->PreventDefault();
Expand Down Expand Up @@ -4634,8 +4632,10 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent)
nsresult
nsPluginInstanceOwner::Destroy()
{
#ifdef MAC_CARBON_PLUGINS
// stop the timer explicitly to reduce reference count.
CancelTimer();
#endif

// unregister context menu listener
if (mCXMenuListener) {
Expand Down Expand Up @@ -5361,14 +5361,9 @@ nsPluginInstanceOwner::Renderer::NativeDraw(QWidget * drawable,
}
#endif

// Here's how we give idle time to plugins.

NS_IMETHODIMP nsPluginInstanceOwner::Notify(nsITimer* timer)
void nsPluginInstanceOwner::SendIdleEvent()
{
#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
if (GetEventModel() != NPEventModelCarbon)
return NS_OK;

#ifdef MAC_CARBON_PLUGINS
// validate the plugin clipping information by syncing the plugin window info to
// reflect the current widget location. This makes sure that everything is updated
// correctly in the event of scrolling in the window.
Expand All @@ -5394,36 +5389,22 @@ NS_IMETHODIMP nsPluginInstanceOwner::Notify(nsITimer* timer)
}
}
#endif
return NS_OK;
}

void nsPluginInstanceOwner::StartTimer(unsigned int aDelay)
#ifdef MAC_CARBON_PLUGINS
void nsPluginInstanceOwner::StartTimer(PRBool isVisible)
{
#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
if (GetEventModel() != NPEventModelCarbon)
return;

if (!mTimerCanceled)
return;

// start a periodic timer to provide null events to the plugin instance.
if (!mPluginTimer) {
mPluginTimer = do_CreateInstance("@mozilla.org/timer;1");
}
if (mPluginTimer) {
mTimerCanceled = PR_FALSE;
mPluginTimer->InitWithCallback(this, aDelay, nsITimer::TYPE_REPEATING_SLACK);
}
#endif
mPluginHost->AddIdleTimeTarget(this, isVisible);
}

void nsPluginInstanceOwner::CancelTimer()
{
if (mPluginTimer) {
mPluginTimer->Cancel();
}
mTimerCanceled = PR_TRUE;
mPluginHost->RemoveIdleTimeTarget(this);
}
#endif

nsresult nsPluginInstanceOwner::Init(nsPresContext* aPresContext,
nsObjectFrame* aFrame,
Expand Down Expand Up @@ -5596,8 +5577,10 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
mPluginWindow->type = NPWindowTypeWindow;
mPluginWindow->window = GetPluginPort();

#ifdef MAC_CARBON_PLUGINS
// start the idle timer.
StartTimer(NORMAL_PLUGIN_DELAY);
StartTimer(PR_TRUE);
#endif

// tell the plugin window about the widget
mPluginWindow->SetPluginWidget(mWidget);
Expand Down Expand Up @@ -5638,7 +5621,7 @@ PRBool nsPluginInstanceOwner::UpdateVisibility()
}
#endif

// Mac specific code to fix up the port location and clipping region
// Mac specific code to fix up the port location and clipping region
#ifdef XP_MACOSX

void* nsPluginInstanceOwner::FixUpPluginWindow(PRInt32 inPaintState)
Expand Down Expand Up @@ -5734,15 +5717,17 @@ void* nsPluginInstanceOwner::FixUpPluginWindow(PRInt32 inPaintState)
{
mInstance->SetWindow(mPluginWindow);
mPluginPortChanged = PR_FALSE;
#ifdef MAC_CARBON_PLUGINS
// if the clipRect is of size 0, make the null timer fire less often
CancelTimer();
if (mPluginWindow->clipRect.left == mPluginWindow->clipRect.right ||
mPluginWindow->clipRect.top == mPluginWindow->clipRect.bottom) {
StartTimer(HIDDEN_PLUGIN_DELAY);
StartTimer(PR_FALSE);
}
else {
StartTimer(NORMAL_PLUGIN_DELAY);
StartTimer(PR_TRUE);
}
#endif
} else if (mPluginPortChanged) {
mInstance->SetWindow(mPluginWindow);
mPluginPortChanged = PR_FALSE;
Expand Down
7 changes: 6 additions & 1 deletion modules/plugin/base/public/nsIPluginHost.idl
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ interface nsIPluginStreamListener;
[ref] native nsIStreamListenerRef(nsIStreamListener *);
[ptr] native nsPluginNativeWindowPtr(nsPluginNativeWindow);

[scriptable, uuid(30C7C529-B05C-4950-B5B8-9AF673E46521)]
[scriptable, uuid(AA13B116-2AFC-4F23-8395-913C0475D173)]
interface nsIPluginHost : nsISupports
{
[noscript] void init();
Expand Down Expand Up @@ -285,6 +285,11 @@ interface nsIPluginHost : nsISupports
* @return plugin tag object
*/
[noscript] nsIPluginTag getPluginTagForInstance(in nsIPluginInstance aInstance);

%{C++
virtual void AddIdleTimeTarget(nsIPluginInstanceOwner* objectFrame, PRBool isVisible) = 0;
virtual void RemoveIdleTimeTarget(nsIPluginInstanceOwner* objectFrame) = 0;
%}
};

%{C++
Expand Down
6 changes: 5 additions & 1 deletion modules/plugin/base/public/nsIPluginInstanceOwner.idl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class nsPluginEvent;

[ref] native nsIPluginInstanceRef(nsIPluginInstance*);

[uuid(8080E717-7261-4707-B8B4-48250F47055F)]
[uuid(D8776CDC-00DF-4395-A432-2E78EBCC12B6)]
interface nsIPluginInstanceOwner : nsISupports
{
/**
Expand Down Expand Up @@ -137,4 +137,8 @@ interface nsIPluginInstanceOwner : nsISupports
%}

void setEventModel(in PRInt32 eventModel);

%{C++
virtual void SendIdleEvent() = 0;
%}
};
Loading

0 comments on commit 1e57594

Please sign in to comment.