Skip to content

Commit

Permalink
Backed out changeset 4643e46ff8d3 (bug 1397426)
Browse files Browse the repository at this point in the history
--HG--
extra : rebase_source : 3e235d725c42300f3c8f3af51850e3c4e1aa7ddf
  • Loading branch information
mikeconley committed Dec 6, 2017
1 parent e22c618 commit 053fbea
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 46 deletions.
4 changes: 4 additions & 0 deletions docshell/base/nsDocShell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6450,6 +6450,10 @@ 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());
Expand Down
40 changes: 23 additions & 17 deletions dom/ipc/TabChild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ NS_IMPL_ISUPPORTS(TabChildSHistoryListener,

static const char BEFORE_FIRST_PAINT[] = "before-first-paint";

nsTHashtable<nsPtrHashKey<TabChild>>* TabChild::sVisibleTabs;
nsTHashtable<nsPtrHashKey<TabChild>>* TabChild::sActiveTabs;

typedef nsDataHashtable<nsUint64HashKey, TabChild*> TabChildMap;
static TabChildMap* sTabChildren;
Expand Down Expand Up @@ -1150,11 +1150,11 @@ TabChild::ActorDestroy(ActorDestroyReason why)

TabChild::~TabChild()
{
if (sVisibleTabs) {
sVisibleTabs->RemoveEntry(this);
if (sVisibleTabs->IsEmpty()) {
delete sVisibleTabs;
sVisibleTabs = nullptr;
if (sActiveTabs) {
sActiveTabs->RemoveEntry(this);
if (sActiveTabs->IsEmpty()) {
delete sActiveTabs;
sActiveTabs = nullptr;
}
}

Expand Down Expand Up @@ -2665,6 +2665,23 @@ 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)
{
Expand Down Expand Up @@ -2738,11 +2755,6 @@ 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());
Expand Down Expand Up @@ -2781,12 +2793,6 @@ 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();
}

Expand Down
32 changes: 17 additions & 15 deletions dom/ipc/TabChild.h
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,8 @@ class TabChild final : public TabChildBase,
void MakeHidden();
bool IsVisible();

void OnDocShellActivated(bool aIsActive);

nsIContentChild* Manager() const { return mManager; }

static inline TabChild*
Expand Down Expand Up @@ -776,20 +778,20 @@ class TabChild final : public TabChildBase,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId);

static bool HasVisibleTabs()
static bool HasActiveTabs()
{
return sVisibleTabs && !sVisibleTabs->IsEmpty();
return sActiveTabs && !sActiveTabs->IsEmpty();
}

// 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()
// 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()
{
MOZ_ASSERT(HasVisibleTabs());
return *sVisibleTabs;
MOZ_ASSERT(HasActiveTabs());
return *sActiveTabs;
}

protected:
Expand Down Expand Up @@ -989,11 +991,11 @@ class TabChild final : public TabChildBase,

WindowsHandle mWidgetNativeData;

// 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;
// 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;

DISALLOW_EVIL_CONSTRUCTORS(TabChild);
};
Expand Down
4 changes: 2 additions & 2 deletions ipc/glue/BackgroundChildImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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::HasVisibleTabs()) {
for (auto iter = dom::TabChild::GetVisibleTabs().ConstIter();
if (dom::TabChild::HasActiveTabs()) {
for (auto iter = dom::TabChild::GetActiveTabs().ConstIter();
!iter.Done(); iter.Next()) {
aGroups.Put(iter.Get()->GetKey()->TabGroup());
}
Expand Down
18 changes: 9 additions & 9 deletions xpcom/threads/LabeledEventQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,21 +166,21 @@ LabeledEventQueue::GetEvent(EventPriority* aPriority,
return nullptr;
}

// Move visible tabs to the front of the queue. The mAvoidVisibleTabCount field
// prevents us from preferentially processing events from visible tabs twice in
// Move active tabs to the front of the queue. The mAvoidActiveTabCount field
// prevents us from preferentially processing events from active tabs twice in
// a row. This scheme is designed to prevent starvation.
if (TabChild::HasVisibleTabs() && mAvoidVisibleTabCount <= 0) {
for (auto iter = TabChild::GetVisibleTabs().ConstIter();
if (TabChild::HasActiveTabs() && mAvoidActiveTabCount <= 0) {
for (auto iter = TabChild::GetActiveTabs().ConstIter();
!iter.Done(); iter.Next()) {
SchedulerGroup* group = iter.Get()->GetKey()->TabGroup();
if (!group->isInList() || group == sCurrentSchedulerGroup) {
continue;
}

// 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;
// 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;

// We move |group| right before sCurrentSchedulerGroup and then set
// sCurrentSchedulerGroup to group.
Expand All @@ -195,7 +195,7 @@ LabeledEventQueue::GetEvent(EventPriority* aPriority,
SchedulerGroup* firstGroup = sCurrentSchedulerGroup;
SchedulerGroup* group = firstGroup;
do {
mAvoidVisibleTabCount--;
mAvoidActiveTabCount--;

auto queueEntry = mLabeled.Lookup(group);
if (!queueEntry) {
Expand Down
6 changes: 3 additions & 3 deletions xpcom/threads/LabeledEventQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,11 @@ class LabeledEventQueue final : public AbstractEventQueue
EpochQueue mEpochs;
size_t mNumEvents = 0;

// Number of SchedulerGroups that must be processed before we prioritize a
// visible tab. This field is designed to guarantee a 1:1 interleaving between
// Number of SchedulerGroups that must be processed before we prioritize an
// active 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 mAvoidVisibleTabCount = 0;
int64_t mAvoidActiveTabCount = 0;
};

} // namespace mozilla
Expand Down

0 comments on commit 053fbea

Please sign in to comment.