Bug 617152. Part 4: Make sure to always fire a balancing MozPaintWaitFinished, even if the plugin dies suddenly, and make sure events are dispatched safely. r=dbaron

This commit is contained in:
Robert O'Callahan 2010-12-20 14:37:43 +13:00
Родитель 9dc0710759
Коммит ad4ca370a9
2 изменённых файлов: 42 добавлений и 12 удалений

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

@ -5274,6 +5274,8 @@ PresShell::RenderDocument(const nsRect& aRect, PRUint32 aFlags,
NS_ENSURE_TRUE(!(aFlags & RENDER_IS_UNTRUSTED), NS_ERROR_NOT_IMPLEMENTED);
nsAutoScriptBlocker blockScripts;
// Set up the rectangle as the path in aThebesContext
gfxRect r(0, 0,
nsPresContext::AppUnitsToFloatCSSPixels(aRect.width),

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

@ -1702,15 +1702,36 @@ nsObjectFrame::GetImageContainer()
return mImageContainer;
}
class AsyncPaintWaitEvent : public nsRunnable
{
public:
AsyncPaintWaitEvent(nsIContent* aContent, PRBool aFinished) :
mContent(aContent), mFinished(aFinished)
{
}
NS_IMETHOD Run()
{
nsContentUtils::DispatchTrustedEvent(mContent->GetOwnerDoc(), mContent,
mFinished ? NS_LITERAL_STRING("MozPaintWaitFinished") : NS_LITERAL_STRING("MozPaintWait"),
PR_TRUE, PR_TRUE);
return NS_OK;
}
private:
nsCOMPtr<nsIContent> mContent;
PRPackedBool mFinished;
};
void
nsPluginInstanceOwner::NotifyPaintWaiter(nsDisplayListBuilder* aBuilder)
{
// This is notification for reftests about async plugin paint start
if (!mWaitingForPaint && !IsUpToDate() && aBuilder->ShouldSyncDecodeImages()) {
nsContentUtils::DispatchTrustedEvent(mContent->GetOwnerDoc(), mContent,
NS_LITERAL_STRING("MozPaintWait"),
PR_TRUE, PR_TRUE);
mWaitingForPaint = PR_TRUE;
nsCOMPtr<nsIRunnable> event = new AsyncPaintWaitEvent(mContent, PR_FALSE);
// Run this event as soon as it's safe to do so, since listeners need to
// receive it immediately
mWaitingForPaint = nsContentUtils::AddScriptRunner(event);
}
}
@ -2852,6 +2873,13 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner()
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG,
("nsPluginInstanceOwner %p deleted\n", this));
if (mWaitingForPaint) {
// We don't care when the event is dispatched as long as it's "soon",
// since whoever needs it will be wwaiting for it
nsCOMPtr<nsIRunnable> event = new AsyncPaintWaitEvent(mContent, PR_TRUE);
NS_DispatchToMainThread(event);
}
#ifdef MAC_CARBON_PLUGINS
CancelTimer();
#endif
@ -3112,10 +3140,17 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetDocument(nsIDocument* *aDocument)
NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect)
{
if (mWaitingForPaint && IsUpToDate()) {
// We don't care when the event is dispatched as long as it's "soon",
// since whoever needs it will be wwaiting for it
nsCOMPtr<nsIRunnable> event = new AsyncPaintWaitEvent(mContent, PR_TRUE);
NS_DispatchToMainThread(event);
mWaitingForPaint = false;
}
if (!mObjectFrame || !invalidRect || !mWidgetVisible)
return NS_ERROR_FAILURE;
// Each time an asynchronously-drawing plugin sends a new surface to display,
// InvalidateRect is called. We notify reftests that painting is up to
// date and update our ImageContainer with the new surface.
@ -3124,13 +3159,6 @@ NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect)
SetCurrentImage(container);
}
if (mWaitingForPaint && IsUpToDate()) {
nsContentUtils::DispatchTrustedEvent(mContent->GetOwnerDoc(), mContent,
NS_LITERAL_STRING("MozPaintWaitFinished"),
PR_TRUE, PR_TRUE);
mWaitingForPaint = false;
}
#ifdef MOZ_USE_IMAGE_EXPOSE
PRBool simpleImageRender = PR_FALSE;
mInstance->GetValueFromPlugin(NPPVpluginWindowlessLocalBool,