Bug 946929 - Part 1, Don't schedule paint related events in a detached pres context. r=roc

This commit is contained in:
Mats Palmgren 2014-02-03 23:47:57 +00:00
parent 7dc9fbe59e
commit 0fffe71735
4 changed files with 37 additions and 8 deletions

View File

@ -1498,8 +1498,7 @@ DetachContainerRecurse(nsIDocShell *aShell)
nsRefPtr<nsPresContext> pc;
viewer->GetPresContext(getter_AddRefs(pc));
if (pc) {
pc->SetContainer(nullptr);
pc->SetLinkHandler(nullptr);
pc->Detach();
}
nsCOMPtr<nsIPresShell> presShell;
viewer->GetPresShell(getter_AddRefs(presShell));
@ -1622,8 +1621,7 @@ nsDocumentViewer::Destroy()
mDocument->SetContainer(nullptr);
}
if (mPresContext) {
mPresContext->SetLinkHandler(nullptr);
mPresContext->SetContainer(nullptr);
mPresContext->Detach();
}
if (mPresShell) {
mPresShell->SetForwardingContainer(mContainer);
@ -4339,8 +4337,7 @@ nsDocumentViewer::DestroyPresShell()
void
nsDocumentViewer::DestroyPresContext()
{
mPresContext->SetContainer(nullptr);
mPresContext->SetLinkHandler(nullptr);
mPresContext->Detach();
mPresContext = nullptr;
}

View File

@ -1574,6 +1574,13 @@ nsPresContext::GetDocShell() const
return mContainer;
}
/* virtual */ void
nsPresContext::Detach()
{
SetContainer(nullptr);
SetLinkHandler(nullptr);
}
bool
nsPresContext::ThrottledTransitionStyleIsUpToDate() const
{
@ -2355,6 +2362,8 @@ nsPresContext::NotifyInvalidation(const nsIntRect& aRect, uint32_t aFlags)
void
nsPresContext::NotifyInvalidation(const nsRect& aRect, uint32_t aFlags)
{
MOZ_ASSERT(GetContainerWeak(), "Invalidation in detached pres context");
// If there is no paint event listener, then we don't need to fire
// the asynchronous event. We don't even need to record invalidation.
// MayHavePaintEventListener is pretty cheap and we could make it
@ -2454,11 +2463,17 @@ public:
nsInvalidateRequestList* aList)
: mPresContext(aPresContext)
{
MOZ_ASSERT(mPresContext->GetContainerWeak(),
"DOMPaintEvent requested for a detached pres context");
mList.TakeFrom(aList);
}
NS_IMETHOD Run()
{
// The pres context might have been detached during the delay -
// that's fine, just don't fire the event.
if (mPresContext->GetContainerWeak()) {
mPresContext->FireDOMPaintEvent(&mList);
}
return NS_OK;
}
@ -2795,6 +2810,14 @@ nsRootPresContext::~nsRootPresContext()
CancelApplyPluginGeometryTimer();
}
/* virtual */ void
nsRootPresContext::Detach()
{
CancelDidPaintTimer();
// XXXmats maybe also CancelApplyPluginGeometryTimer(); ?
nsPresContext::Detach();
}
void
nsRootPresContext::RegisterPluginForGeometryUpdates(nsIContent* aPlugin)
{

View File

@ -433,6 +433,13 @@ public:
void SetLinkHandler(nsILinkHandler* aHandler) { mLinkHandler = aHandler; }
nsILinkHandler* GetLinkHandler() { return mLinkHandler; }
/**
* Detach this pres context - i.e. cancel relevant timers,
* SetLinkHandler(null), SetContainer(null) etc.
* Only to be used by the DocumentViewer.
*/
virtual void Detach();
/**
* Get the visible area associated with this presentation context.
* This is the size of the visible area that is used for
@ -1355,10 +1362,11 @@ public:
};
class nsRootPresContext : public nsPresContext {
class nsRootPresContext MOZ_FINAL : public nsPresContext {
public:
nsRootPresContext(nsIDocument* aDocument, nsPresContextType aType) NS_HIDDEN;
virtual ~nsRootPresContext();
virtual void Detach() MOZ_OVERRIDE;
/**
* Ensure that NotifyDidPaintForSubtree is eventually called on this

View File

@ -4896,6 +4896,7 @@ nsIFrame::SchedulePaint(PaintType aType)
return;
}
MOZ_ASSERT(pres->GetContainerWeak(), "SchedulePaint in a detached pres context");
pres->PresShell()->ScheduleViewManagerFlush(aType == PAINT_DELAYED_COMPRESS ?
nsIPresShell::PAINT_DELAYED_COMPRESS :
nsIPresShell::PAINT_DEFAULT);