Bug 1186662 - Part 1: Add SuppressDisplayport painting and use it during tab switch. r=kats,mconley

--HG--
extra : commitid : 9fUfVIK8ikm
extra : rebase_source : e45570f97a25f965d2caf24f152da02efcf6495f
This commit is contained in:
Benoit Girard 2015-08-19 17:08:41 -04:00
Родитель 9ed94ff6cd
Коммит 074eb08eb1
10 изменённых файлов: 112 добавлений и 2 удалений

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

@ -3077,6 +3077,11 @@
// Map from tabs to STATE_* (below).
tabState: new Map(),
// Keep an exact list of content processes (tabParent) in which
// we're actively suppressing the display port. This gives a robust
// way to make sure we don't forget to un-suppress.
activeSuppressDisplayport: new Set(),
// Set of tabs that might be visible right now. We maintain
// this set because we can't be sure when a tab is actually
// drawn. A tab is added to this set when we ask to make it
@ -3140,6 +3145,11 @@
window.removeEventListener("TabRemotenessChange", this);
this.tabbrowser._switcher = null;
this.activeSuppressDisplayport.forEach(function(tabParent) {
tabParent.suppressDisplayport(false);
});
this.activeSuppressDisplayport.clear();
},
finish: function() {
@ -3438,6 +3448,13 @@
this.requestedTab = tab;
let browser = this.requestedTab.linkedBrowser;
let fl = browser.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader;
if (fl && fl.tabParent && !this.activeSuppressDisplayport.has(fl.tabParent)) {
fl.tabParent.suppressDisplayport(true);
this.activeSuppressDisplayport.add(fl.tabParent);
}
this.preActions();
clearTimeout(this.unloadTimer);

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

@ -5,7 +5,7 @@
#include "domstubs.idl"
[scriptable, uuid(CE6F563B-BD77-4EF2-9D7C-A94C587353E4)]
[scriptable, uuid(531b902b-b551-4faa-9814-1a73e8299ac4)]
interface nsITabParent : nsISupports
{
void injectTouchEvent(in AString aType,
@ -25,6 +25,14 @@ interface nsITabParent : nsISupports
void setIsDocShellActive(in bool aIsActive);
/**
* During interactions where painting performance
* is more important than scrolling, we may temporarily
* suppress the displayport. Each enable called must be matched
* with a disable call.
*/
void suppressDisplayport(in bool aEnabled);
readonly attribute uint64_t tabId;
/**

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

@ -709,6 +709,17 @@ child:
*/
SetIsDocShellActive(bool aIsActive);
/**
* Notify the child that it shouldn't paint the offscreen displayport.
* This is useful to speed up interactive operations over async
* scrolling performance like resize, tabswitch, pageload.
*
* Each enable call must be matched with a disable call. The child
* will remain in the suppress mode as long as there's
* a single unmatched call.
*/
async SuppressDisplayport(bool aEnabled);
/**
* Navigate by key (Tab/Shift+Tab/F6/Shift+f6).
*/

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

@ -554,6 +554,7 @@ TabChild::TabChild(nsIContentChild* aManager,
, mRemoteFrame(nullptr)
, mManager(aManager)
, mChromeFlags(aChromeFlags)
, mActiveSuppressDisplayport(0)
, mLayersId(0)
, mActivePointerId(-1)
, mAppPackageFileDescriptorRecved(false)
@ -1693,6 +1694,20 @@ TabChild::RecvUpdateFrame(const FrameMetrics& aFrameMetrics)
return TabChildBase::UpdateFrameHandler(aFrameMetrics);
}
bool
TabChild::RecvSuppressDisplayport(const bool& aEnabled)
{
if (aEnabled) {
mActiveSuppressDisplayport++;
} else {
mActiveSuppressDisplayport--;
}
MOZ_ASSERT(mActiveSuppressDisplayport >= 0);
APZCCallbackHelper::SuppressDisplayport(aEnabled);
return true;
}
bool
TabChild::RecvRequestFlingSnap(const FrameMetrics::ViewID& aScrollId,
const mozilla::CSSPoint& aDestination)
@ -2413,6 +2428,11 @@ TabChild::RecvDestroy()
MOZ_ASSERT(mDestroyed == false);
mDestroyed = true;
while (mActiveSuppressDisplayport > 0) {
APZCCallbackHelper::SuppressDisplayport(false);
mActiveSuppressDisplayport--;
}
if (mTabChildGlobal) {
// Message handlers are called from the event loop, so it better be safe to
// run script.

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

@ -512,6 +512,8 @@ protected:
virtual bool RecvRequestNotifyAfterRemotePaint() override;
virtual bool RecvSuppressDisplayport(const bool& aEnabled) override;
virtual bool RecvParentActivated(const bool& aActivated) override;
virtual bool RecvStopIMEStateManagement() override;
@ -608,6 +610,7 @@ private:
RenderFrameChild* mRemoteFrame;
nsRefPtr<nsIContentChild> mManager;
uint32_t mChromeFlags;
int32_t mActiveSuppressDisplayport;
uint64_t mLayersId;
CSSRect mUnscaledOuterRect;
// When we're tracking a possible tap gesture, this is the "down"

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

@ -287,6 +287,7 @@ TabParent::TabParent(nsIContentParent* aManager,
, mCursor(nsCursor(-1))
, mTabSetsCursor(false)
, mHasContentOpener(false)
, mActiveSupressDisplayportCount(0)
{
MOZ_ASSERT(aManager);
}
@ -2955,6 +2956,25 @@ TabParent::SetIsDocShellActive(bool isActive)
return NS_OK;
}
NS_IMETHODIMP
TabParent::SuppressDisplayport(bool aEnabled)
{
if (IsDestroyed()) {
return NS_OK;
}
if (aEnabled) {
mActiveSupressDisplayportCount++;
} else {
mActiveSupressDisplayportCount--;
}
MOZ_ASSERT(mActiveSupressDisplayportCount >= 0);
unused << SendSuppressDisplayport(aEnabled);
return NS_OK;
}
NS_IMETHODIMP
TabParent::GetTabId(uint64_t* aId)
{

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

@ -609,6 +609,8 @@ private:
nsRefPtr<nsIPresShell> mPresShellWithRefreshListener;
bool mHasContentOpener;
DebugOnly<int32_t> mActiveSupressDisplayportCount;
private:
// This is used when APZ needs to find the TabParent associated with a layer
// to dispatch events.

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

@ -810,6 +810,27 @@ APZCCallbackHelper::NotifyFlushComplete()
observerService->NotifyObservers(nullptr, "apz-repaints-flushed", nullptr);
}
static int32_t sActiveSuppressDisplayport = 0;
void
APZCCallbackHelper::SuppressDisplayport(const bool& aEnabled)
{
if (aEnabled) {
sActiveSuppressDisplayport++;
} else {
sActiveSuppressDisplayport--;
}
MOZ_ASSERT(sActiveSuppressDisplayport >= 0);
}
bool
APZCCallbackHelper::IsDisplayportSuppressed()
{
return sActiveSuppressDisplayport > 0;
}
} // namespace layers
} // namespace mozilla

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

@ -169,6 +169,10 @@ public:
/* Notify content that the repaint flush is complete. */
static void NotifyFlushComplete();
/* Temporarily ignore the Displayport for better paint performance. */
static void SuppressDisplayport(const bool& aEnabled);
static bool IsDisplayportSuppressed();
};
} // namespace layers

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

@ -62,6 +62,7 @@
#include "mozilla/dom/HTMLImageElement.h"
#include "mozilla/dom/DOMRect.h"
#include "mozilla/dom/KeyframeEffect.h"
#include "mozilla/layers/APZCCallbackHelper.h"
#include "imgIRequest.h"
#include "nsIImageLoadingContent.h"
#include "nsCOMPtr.h"
@ -1038,7 +1039,10 @@ GetDisplayPortImpl(nsIContent* aContent, nsRect *aResult, float aMultiplier)
"Only one of rectData or marginsData should be set!");
nsRect result;
if (rectData) {
if (APZCCallbackHelper::IsDisplayportSuppressed()) {
DisplayPortMarginsPropertyData noMargins(ScreenMargin(), 1);
result = GetDisplayPortFromMarginsData(aContent, &noMargins, aMultiplier);
} else if (rectData) {
result = GetDisplayPortFromRectData(aContent, rectData, aMultiplier);
} else {
result = GetDisplayPortFromMarginsData(aContent, marginsData, aMultiplier);