Bug 1252877 Part 7: Wait for plugin updates during active animations. r=dvander, r=jimm

Also, apply plugin updates when they arrive not just during composition.

MozReview-Commit-ID: FZJYiPqb5uZ
This commit is contained in:
Bob Owen 2016-07-18 09:54:02 +01:00
Родитель 88df0f1a00
Коммит 4ec3db3eec
4 изменённых файлов: 67 добавлений и 7 удалений

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

@ -419,9 +419,7 @@ CompositorBridgeChild::RecvUpdatePluginConfigurations(const LayoutDeviceIntPoint
// 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) || defined(MOZ_WIDGET_GTK)
SendRemotePluginsReady();
#endif
return true;
#endif // !defined(XP_WIN) && !defined(MOZ_WIDGET_GTK)
}

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

@ -77,6 +77,9 @@
#include "ProfilerMarkers.h"
#endif
#include "mozilla/VsyncDispatcher.h"
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
#include "VsyncSource.h"
#endif
#include "mozilla/widget/CompositorWidget.h"
#ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
# include "mozilla/widget/CompositorWidgetParent.h"
@ -157,6 +160,15 @@ CompositorBridgeParent::ForEachIndirectLayerTree(const Lambda& aCallback)
typedef map<uint64_t,CompositorBridgeParent*> CompositorMap;
static StaticAutoPtr<CompositorMap> sCompositorMap;
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
static TimeDuration
GetGlobalVsyncRate()
{
return gfxPlatform::GetPlatform()->GetHardwareVsync()->
GetGlobalDisplay().GetVsyncRate();
}
#endif
void
CompositorBridgeParent::Setup()
{
@ -1081,13 +1093,24 @@ CompositorBridgeParent::NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstP
bool aScheduleComposite, uint32_t aPaintSequenceNumber,
bool aIsRepeatTransaction, bool aHitTestUpdate)
{
if (mApzcTreeManager &&
!aIsRepeatTransaction &&
if (!aIsRepeatTransaction &&
mLayerManager &&
mLayerManager->GetRoot()) {
AutoResolveRefLayers resolve(mCompositionManager);
// Process plugin data here to give time for them to update before the next
// composition.
bool pluginsUpdatedFlag = true;
AutoResolveRefLayers resolve(mCompositionManager, this, nullptr,
&pluginsUpdatedFlag);
if (aHitTestUpdate) {
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
// If plugins haven't been updated, stop waiting.
if (!pluginsUpdatedFlag) {
mWaitForPluginsUntil = TimeStamp();
mHaveBlockedForPlugins = false;
}
#endif
if (mApzcTreeManager && aHitTestUpdate) {
mApzcTreeManager->UpdateHitTestingTree(this, mLayerManager->GetRoot(),
aIsFirstPaint, aId, aPaintSequenceNumber);
}
@ -1164,6 +1187,15 @@ CompositorBridgeParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRec
return;
}
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
if (!mWaitForPluginsUntil.IsNull() &&
mWaitForPluginsUntil > start) {
mHaveBlockedForPlugins = true;
ScheduleComposition();
return;
}
#endif
/*
* AutoResolveRefLayers handles two tasks related to Windows and Linux
* plugin window management:
@ -1216,6 +1248,14 @@ CompositorBridgeParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRec
bool requestNextFrame = mCompositionManager->TransformShadowTree(time);
if (requestNextFrame) {
ScheduleComposition();
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
// If we have visible windowed plugins then we need to wait for content (and
// then the plugins) to have been updated by the active animation.
if (!mPluginWindowsHidden && mCachedPluginData.Length()) {
mWaitForPluginsUntil = mCompositorScheduler->GetLastComposeTime()
+ (GetGlobalVsyncRate() * 2);
}
#endif
}
RenderTraceLayers(mLayerManager->GetRoot(), "0000");
@ -1273,7 +1313,13 @@ bool
CompositorBridgeParent::RecvRemotePluginsReady()
{
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
ScheduleComposition();
mWaitForPluginsUntil = TimeStamp();
if (mHaveBlockedForPlugins) {
mHaveBlockedForPlugins = false;
ForceComposeToTarget(nullptr);
} else {
ScheduleComposition();
}
return true;
#else
NS_NOTREACHED("CompositorBridgeParent::RecvRemotePluginsReady calls "
@ -2643,6 +2689,7 @@ CompositorBridgeParent::HideAllPluginWindows()
#if defined(XP_WIN)
// We will get an async reply that this has happened and then send hide.
mWaitForPluginsUntil = TimeStamp::Now() + GetGlobalVsyncRate();
Unused << SendCaptureAllPlugins(parentWidget);
#else
Unused << SendHideAllPlugins(parentWidget);
@ -2655,6 +2702,8 @@ bool
CompositorBridgeParent::RecvAllPluginsCaptured()
{
#if defined(XP_WIN)
mWaitForPluginsUntil = TimeStamp();
mHaveBlockedForPlugins = false;
ForceComposeToTarget(nullptr);
Unused << SendHideAllPlugins(GetWidget()->GetWidgetKey());
return true;

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

@ -635,6 +635,10 @@ protected:
nsIntPoint mPluginsLayerOffset;
nsIntRegion mPluginsLayerVisibleRegion;
nsTArray<PluginWindowData> mCachedPluginData;
// Time until which we will block composition to wait for plugin updates.
TimeStamp mWaitForPluginsUntil;
// Indicates that we have actually blocked a composition waiting for plugins.
bool mHaveBlockedForPlugins = false;
// indicates if plugin window visibility and metric updates are currently
// being defered due to a scroll operation.
bool mDeferPluginWindows;

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

@ -2757,6 +2757,15 @@ ScrollFrameHelper::ScrollToImpl(nsPoint aPt, const nsRect& aRange, nsIAtom* aOri
if (!apzDisabled && !HasPluginFrames()) {
if (LastScrollOrigin() == nsGkAtoms::apz) {
schedulePaint = false;
// If we have any windowed plugins at all then schedule an empty
// transaction because the parent will be waiting for an update.
if (!gfxPrefs::HidePluginsForScroll()) {
nsRootPresContext* root = presContext->GetRootPresContext();
if (root && root->NeedToComputePluginGeometryUpdates()) {
mOuter->SchedulePaint(nsIFrame::PAINT_COMPOSITE_ONLY);
}
}
PAINT_SKIP_LOG("Skipping due to APZ scroll\n");
} else if (mScrollableByAPZ) {
nsIWidget* widget = presContext->GetNearestWidget();