зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1397426 - Rename TabChild's notion of "active tabs" to "visible tabs" and move logic into renderLayers. r=billm
MozReview-Commit-ID: 1bBNwew7uCk --HG-- extra : rebase_source : 0e59b548c6c01d7feaf9f40c282ab2f55e47bab7 extra : source : 4643e46ff8d3e84d10ff178e15a1be7f734b020f
This commit is contained in:
Родитель
26b5553c8a
Коммит
921cb8735c
|
@ -5824,10 +5824,6 @@ nsDocShell::SetIsActive(bool aIsActive)
|
|||
// Keep track ourselves.
|
||||
mIsActive = aIsActive;
|
||||
|
||||
if (TabChild* tc = TabChild::GetFrom(this)) {
|
||||
tc->OnDocShellActivated(aIsActive);
|
||||
}
|
||||
|
||||
// Clear prerender flag if necessary.
|
||||
if (mIsPrerendered && aIsActive) {
|
||||
MOZ_ASSERT(mPrerenderGlobalHistory.get());
|
||||
|
|
|
@ -165,7 +165,7 @@ NS_IMPL_ISUPPORTS(TabChildSHistoryListener,
|
|||
|
||||
static const char BEFORE_FIRST_PAINT[] = "before-first-paint";
|
||||
|
||||
nsTHashtable<nsPtrHashKey<TabChild>>* TabChild::sActiveTabs;
|
||||
nsTHashtable<nsPtrHashKey<TabChild>>* TabChild::sVisibleTabs;
|
||||
|
||||
typedef nsDataHashtable<nsUint64HashKey, TabChild*> TabChildMap;
|
||||
static TabChildMap* sTabChildren;
|
||||
|
@ -1150,11 +1150,11 @@ TabChild::ActorDestroy(ActorDestroyReason why)
|
|||
|
||||
TabChild::~TabChild()
|
||||
{
|
||||
if (sActiveTabs) {
|
||||
sActiveTabs->RemoveEntry(this);
|
||||
if (sActiveTabs->IsEmpty()) {
|
||||
delete sActiveTabs;
|
||||
sActiveTabs = nullptr;
|
||||
if (sVisibleTabs) {
|
||||
sVisibleTabs->RemoveEntry(this);
|
||||
if (sVisibleTabs->IsEmpty()) {
|
||||
delete sVisibleTabs;
|
||||
sVisibleTabs = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2665,23 +2665,6 @@ TabChild::RemovePendingDocShellBlocker()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
TabChild::OnDocShellActivated(bool aIsActive)
|
||||
{
|
||||
if (aIsActive) {
|
||||
if (!sActiveTabs) {
|
||||
sActiveTabs = new nsTHashtable<nsPtrHashKey<TabChild>>();
|
||||
}
|
||||
sActiveTabs->PutEntry(this);
|
||||
} else {
|
||||
if (sActiveTabs) {
|
||||
sActiveTabs->RemoveEntry(this);
|
||||
// We don't delete sActiveTabs here when it's empty since that
|
||||
// could cause a lot of churn. Instead, we wait until ~TabChild.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TabChild::InternalSetDocShellIsActive(bool aIsActive)
|
||||
{
|
||||
|
@ -2755,6 +2738,11 @@ TabChild::RecvRenderLayers(const bool& aEnabled, const uint64_t& aLayerObserverE
|
|||
}
|
||||
}
|
||||
|
||||
if (!sVisibleTabs) {
|
||||
sVisibleTabs = new nsTHashtable<nsPtrHashKey<TabChild>>();
|
||||
}
|
||||
sVisibleTabs->PutEntry(this);
|
||||
|
||||
MakeVisible();
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
|
||||
|
@ -2793,6 +2781,12 @@ TabChild::RecvRenderLayers(const bool& aEnabled, const uint64_t& aLayerObserverE
|
|||
APZCCallbackHelper::SuppressDisplayport(false, presShell);
|
||||
}
|
||||
} else {
|
||||
if (sVisibleTabs) {
|
||||
sVisibleTabs->RemoveEntry(this);
|
||||
// We don't delete sVisibleTabs here when it's empty since that
|
||||
// could cause a lot of churn. Instead, we wait until ~TabChild.
|
||||
}
|
||||
|
||||
MakeHidden();
|
||||
}
|
||||
|
||||
|
|
|
@ -581,8 +581,6 @@ public:
|
|||
void MakeHidden();
|
||||
bool IsVisible();
|
||||
|
||||
void OnDocShellActivated(bool aIsActive);
|
||||
|
||||
nsIContentChild* Manager() const { return mManager; }
|
||||
|
||||
static inline TabChild*
|
||||
|
@ -778,20 +776,20 @@ public:
|
|||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId);
|
||||
|
||||
static bool HasActiveTabs()
|
||||
static bool HasVisibleTabs()
|
||||
{
|
||||
return sActiveTabs && !sActiveTabs->IsEmpty();
|
||||
return sVisibleTabs && !sVisibleTabs->IsEmpty();
|
||||
}
|
||||
|
||||
// Returns the set of TabChilds that are currently in the foreground. There
|
||||
// can be multiple foreground TabChilds if Firefox has multiple windows
|
||||
// open. There can also be zero foreground TabChilds if the foreground tab is
|
||||
// in a different content process. Note that this function should only be
|
||||
// called if HasActiveTabs() returns true.
|
||||
static const nsTHashtable<nsPtrHashKey<TabChild>>& GetActiveTabs()
|
||||
// Returns the set of TabChilds that are currently rendering layers. There
|
||||
// can be multiple TabChilds in this state if Firefox has multiple windows
|
||||
// open or is warming tabs up. There can also be zero TabChilds in this
|
||||
// state. Note that this function should only be called if HasVisibleTabs()
|
||||
// returns true.
|
||||
static const nsTHashtable<nsPtrHashKey<TabChild>>& GetVisibleTabs()
|
||||
{
|
||||
MOZ_ASSERT(HasActiveTabs());
|
||||
return *sActiveTabs;
|
||||
MOZ_ASSERT(HasVisibleTabs());
|
||||
return *sVisibleTabs;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -991,11 +989,11 @@ private:
|
|||
|
||||
WindowsHandle mWidgetNativeData;
|
||||
|
||||
// This state is used to keep track of the current active tabs (the ones in
|
||||
// the foreground). There may be more than one if there are multiple browser
|
||||
// windows open. There may be none if this process does not host any
|
||||
// foreground tabs.
|
||||
static nsTHashtable<nsPtrHashKey<TabChild>>* sActiveTabs;
|
||||
// This state is used to keep track of the current visible tabs (the ones rendering
|
||||
// layers). There may be more than one if there are multiple browser windows open, or
|
||||
// tabs are being warmed up. There may be none if this process does not host any
|
||||
// visible or warming tabs.
|
||||
static nsTHashtable<nsPtrHashKey<TabChild>>* sVisibleTabs;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
|
||||
};
|
||||
|
|
|
@ -662,8 +662,8 @@ BackgroundChildImpl::GetMessageSchedulerGroups(const Message& aMsg, SchedulerGro
|
|||
if (aMsg.type() == layout::PVsync::MessageType::Msg_Notify__ID) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
aGroups.Clear();
|
||||
if (dom::TabChild::HasActiveTabs()) {
|
||||
for (auto iter = dom::TabChild::GetActiveTabs().ConstIter();
|
||||
if (dom::TabChild::HasVisibleTabs()) {
|
||||
for (auto iter = dom::TabChild::GetVisibleTabs().ConstIter();
|
||||
!iter.Done(); iter.Next()) {
|
||||
aGroups.Put(iter.Get()->GetKey()->TabGroup());
|
||||
}
|
||||
|
|
|
@ -171,21 +171,21 @@ LabeledEventQueue::GetEvent(EventPriority* aPriority,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// Move active tabs to the front of the queue. The mAvoidActiveTabCount field
|
||||
// prevents us from preferentially processing events from active tabs twice in
|
||||
// Move visible tabs to the front of the queue. The mAvoidVisibleTabCount field
|
||||
// prevents us from preferentially processing events from visible tabs twice in
|
||||
// a row. This scheme is designed to prevent starvation.
|
||||
if (TabChild::HasActiveTabs() && mAvoidActiveTabCount <= 0) {
|
||||
for (auto iter = TabChild::GetActiveTabs().ConstIter();
|
||||
if (TabChild::HasVisibleTabs() && mAvoidVisibleTabCount <= 0) {
|
||||
for (auto iter = TabChild::GetVisibleTabs().ConstIter();
|
||||
!iter.Done(); iter.Next()) {
|
||||
SchedulerGroup* group = iter.Get()->GetKey()->TabGroup();
|
||||
if (!group->isInList() || group == sCurrentSchedulerGroup) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// For each active tab we move to the front of the queue, we have to
|
||||
// process two SchedulerGroups (the active tab and another one, presumably
|
||||
// a background group) before we prioritize active tabs again.
|
||||
mAvoidActiveTabCount += 2;
|
||||
// For each visible tab we move to the front of the queue, we have to
|
||||
// process two SchedulerGroups (the visible tab and another one, presumably
|
||||
// a background group) before we prioritize visible tabs again.
|
||||
mAvoidVisibleTabCount += 2;
|
||||
|
||||
// We move |group| right before sCurrentSchedulerGroup and then set
|
||||
// sCurrentSchedulerGroup to group.
|
||||
|
@ -200,7 +200,7 @@ LabeledEventQueue::GetEvent(EventPriority* aPriority,
|
|||
SchedulerGroup* firstGroup = sCurrentSchedulerGroup;
|
||||
SchedulerGroup* group = firstGroup;
|
||||
do {
|
||||
mAvoidActiveTabCount--;
|
||||
mAvoidVisibleTabCount--;
|
||||
|
||||
RunnableEpochQueue& queue = group->GetQueue(mPriority);
|
||||
|
||||
|
|
|
@ -137,11 +137,11 @@ private:
|
|||
EpochQueue mEpochs;
|
||||
size_t mNumEvents = 0;
|
||||
|
||||
// Number of SchedulerGroups that must be processed before we prioritize an
|
||||
// active tab. This field is designed to guarantee a 1:1 interleaving between
|
||||
// Number of SchedulerGroups that must be processed before we prioritize a
|
||||
// visible tab. This field is designed to guarantee a 1:1 interleaving between
|
||||
// foreground and background SchedulerGroups. For details, see its usage in
|
||||
// LabeledEventQueue.cpp.
|
||||
int64_t mAvoidActiveTabCount = 0;
|
||||
int64_t mAvoidVisibleTabCount = 0;
|
||||
EventPriority mPriority;
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче