Bug 1137944 - On Windows defer composition until we receive confirmation plugin window metrics have been updated. r=roc

This commit is contained in:
Jim Mathies 2015-10-06 14:23:24 -05:00
parent 7701df2c7e
commit 84b34afc13
4 changed files with 88 additions and 3 deletions

View File

@ -318,6 +318,9 @@ CompositorChild::RecvUpdatePluginConfigurations(const nsIntPoint& aContentOffset
// Any plugins we didn't update need to be hidden, as they are
// not associated with visible content.
nsIWidget::UpdateRegisteredPluginWindowVisibility((uintptr_t)parent, visiblePluginIds);
#if defined(XP_WIN)
SendRemotePluginsReady();
#endif
return true;
#endif // !defined(XP_WIN) && !defined(MOZ_WIDGET_GTK)
}
@ -333,6 +336,9 @@ CompositorChild::RecvHideAllPlugins(const uintptr_t& aParentWidget)
MOZ_ASSERT(NS_IsMainThread());
nsTArray<uintptr_t> list;
nsIWidget::UpdateRegisteredPluginWindowVisibility(aParentWidget, list);
#if defined(XP_WIN)
SendRemotePluginsReady();
#endif
return true;
#endif // !defined(XP_WIN) && !defined(MOZ_WIDGET_GTK)
}

View File

@ -56,6 +56,7 @@
#include "nsTArray.h" // for nsTArray
#include "nsThreadUtils.h" // for NS_IsMainThread
#include "nsXULAppAPI.h" // for XRE_GetIOMessageLoop
#include "nsIXULRuntime.h" // for BrowserTabsRemoteAutostart
#ifdef XP_WIN
#include "mozilla/layers/CompositorD3D11.h"
#include "mozilla/layers/CompositorD3D9.h"
@ -554,6 +555,9 @@ CompositorParent::CompositorParent(nsIWidget* aWidget,
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
, mLastPluginUpdateLayerTreeId(0)
#endif
#if defined(XP_WIN)
, mPluginUpdateResponsePending(false)
#endif
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(CompositorThread(),
@ -1043,13 +1047,57 @@ CompositorParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRe
return;
}
AutoResolveRefLayers resolve(mCompositionManager, true);
#if defined(XP_WIN)
// Still waiting on plugin update confirmation
if (mPluginUpdateResponsePending) {
return;
}
#endif
bool hasRemoteContent = false;
bool pluginsUpdatedFlag = true;
AutoResolveRefLayers resolve(mCompositionManager, this,
&hasRemoteContent,
&pluginsUpdatedFlag);
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
/*
* AutoResolveRefLayers handles two tasks related to Windows and Linux
* plugin window management:
* 1) calculating if we have remote content in the view. If we do not have
* remote content, all plugin windows for this CompositorParent (window)
* can be hidden since we do not support plugins in chrome when running
* under e10s.
* 2) Updating plugin position, size, and clip. We do this here while the
* remote layer tree is hooked up to to chrome layer tree. This is needed
* since plugin clipping can depend on chrome (for example, due to tab modal
* prompts). Updates in step 2 are applied via an async ipc message sent
* to the main thread.
* Windows specific: The compositor will wait for confirmation that plugin
* updates have been applied before painting. Deferment of painting is
* indicated by the mPluginUpdateResponsePending flag. The main thread
* messages back using the RemotePluginsReady async ipc message.
* This is neccessary since plugin windows can leave remnants of window
* content if moved after the underlying window paints.
*/
#if defined(XP_WIN)
if (pluginsUpdatedFlag) {
mPluginUpdateResponsePending = true;
return;
}
#endif
// We do not support plugins in local content. When switching tabs
// to local pages, hide every plugin associated with the window.
if (!mCompositionManager->HasRemoteContent()) {
if (!hasRemoteContent && BrowserTabsRemoteAutostart() &&
mCachedPluginData.Length()) {
unused << SendHideAllPlugins((uintptr_t)GetWidget());
mCachedPluginData.Clear();
#if defined(XP_WIN)
// Wait for confirmation the hide operation is complete.
mPluginUpdateResponsePending = true;
return;
#endif
}
#endif
@ -1129,6 +1177,20 @@ CompositorParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRe
profiler_tracing("Paint", "Composite", TRACING_INTERVAL_END);
}
bool
CompositorParent::RecvRemotePluginsReady()
{
#if defined(XP_WIN)
mPluginUpdateResponsePending = false;
ScheduleComposition();
return true;
#else
NS_NOTREACHED("CompositorParent::RecvRemotePluginsReady calls "
"unexpected on this platform.");
return false;
#endif
}
void
CompositorParent::ForceComposeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRect)
{
@ -1744,6 +1806,7 @@ public:
const nsTArray<ScrollableLayerGuid>& aTargets) override;
virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aParent) override;
virtual bool RecvRemotePluginsReady() override { return false; }
void DidComposite(uint64_t aId,
TimeStamp& aCompositeStart,

View File

@ -386,9 +386,15 @@ public:
* Calculates and requests the main thread update plugin positioning, clip,
* and visibility via ipc.
*/
void UpdatePluginWindowState(uint64_t aId);
bool UpdatePluginWindowState(uint64_t aId);
#endif
/**
* Main thread response for a plugin visibility request made by the
* compositor thread.
*/
virtual bool RecvRemotePluginsReady() override;
/**
* Used by the profiler to denote when a vsync occured
*/
@ -485,6 +491,11 @@ protected:
nsIntRegion mPluginsLayerVisibleRegion;
nsTArray<PluginWindowData> mCachedPluginData;
#endif
#if defined(XP_WIN)
// indicates if we are currently waiting on a plugin update confirmation.
// When this is true, composition is currently on hold.
bool mPluginUpdateResponsePending;
#endif
DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
};

View File

@ -82,6 +82,11 @@ child:
async ClearCachedResources(uint64_t id);
parent:
/**
* Confirmation callback for UpdatePluginConfigurations and HideAllPlugins.
*/
async RemotePluginsReady();
// Child sends the parent a request for fill ratio numbers.
async RequestOverfill();