Backed out 6 changesets (bug 1237454) for bc failures on /browser_toolbariconcolor_restyles.js. CLOSED TREE

Backed out changeset f8d771835fd2 (bug 1237454)
Backed out changeset 2dbbfc331bdf (bug 1237454)
Backed out changeset c481f409feaa (bug 1237454)
Backed out changeset 0b9872865f0e (bug 1237454)
Backed out changeset 43ca55e7c93b (bug 1237454)
Backed out changeset 027b0c65d944 (bug 1237454)
This commit is contained in:
Narcis Beleuzu 2018-02-06 11:19:56 +02:00
Родитель ac18ab3f13
Коммит b0e8772dcd
7 изменённых файлов: 21 добавлений и 375 удалений

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

@ -1457,9 +1457,7 @@ KeyframeEffectReadOnly::CanThrottle() const
if (presShell && !presShell->IsActive()) {
return true;
}
if (!frame->IsVisibleOrMayHaveVisibleDescendants() ||
frame->IsScrolledOutOfView()) {
if (frame->IsScrolledOutOfView()) {
// If there are transform change hints, unthrottle the animation
// periodically since it might affect the overflow region.
if (mCumulativeChangeHint & (nsChangeHint_UpdatePostTransformOverflow |

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

@ -658,7 +658,7 @@ waitForAllPaints(() => {
await ensureElementRemoval(grandParent);
});
add_task_if_omta_enabled(async function no_restyling_compositor_animations_in_visibility_hidden_element() {
add_task_if_omta_enabled(async function no_restyling_compositor_animations_in_visiblily_hidden_element() {
var div = addDiv(null,
{ style: 'animation: opacity 100s; visibility: hidden' });
var animation = div.getAnimations()[0];
@ -668,9 +668,9 @@ waitForAllPaints(() => {
var markers = await observeStyling(5);
is(markers.length, 0,
'Animations running on the compositor in visibility hidden element ' +
'should never cause restyles');
todo_is(markers.length, 0,
'Bug 1237454: Animations running on the compositor in ' +
'visibility hidden element should never cause restyles');
await ensureElementRemoval(div);
});
@ -727,296 +727,20 @@ waitForAllPaints(() => {
await ensureElementRemoval(parentElement);
});
add_task(
async function restyling_animations_on_visibility_changed_element_having_child() {
var div = addDiv(null,
{ style: 'animation: background-color 100s;' });
var childElement = addDiv(null);
div.appendChild(childElement);
var animation = div.getAnimations()[0];
await animation.ready;
// We don't check the animation causes restyles here since we already
// check it in the first test case.
div.style.visibility = 'hidden';
await waitForNextFrame();
var markers = await observeStyling(5);
todo_is(markers.length, 0,
'Animations running on visibility hidden element which ' +
'has a child whose visiblity is inherited from the element and ' +
'the element was initially visible');
await ensureElementRemoval(div);
}
);
add_task(
async function restyling_animations_on_visibility_hidden_element_which_gets_visible() {
var div = addDiv(null,
{ style: 'animation: background-color 100s; visibility: hidden' });
var animation = div.getAnimations()[0];
await animation.ready;
var markers = await observeStyling(5);
is(markers.length, 0,
'Animations running on visibility hidden element should never ' +
'cause restyles');
div.style.visibility = 'visible';
await waitForNextFrame();
var markers = await observeStyling(5);
is(markers.length, 5,
'Animations running that was on visibility hidden element which ' +
'gets visible should not throttle restyling any more');
await ensureElementRemoval(div);
}
);
add_task(async function restyling_animations_in_visibility_changed_parent() {
var parentDiv = addDiv(null, { style: 'visibility: hidden' });
var div = addDiv(null, { style: 'animation: background-color 100s;' });
parentDiv.appendChild(div);
add_task(async function no_restyling_main_thread_animations_in_visiblily_hidden_element() {
var div = addDiv(null,
{ style: 'animation: background-color 100s; visibility: hidden' });
var animation = div.getAnimations()[0];
await animation.ready;
var markers = await observeStyling(5);
is(markers.length, 0,
'Animations running in visibility hidden parent should never cause ' +
'restyles');
parentDiv.style.visibility = 'visible';
await waitForNextFrame();
var markers = await observeStyling(5);
is(markers.length, 5,
'Animations that was in visibility hidden parent should not ' +
'throttle restyling any more');
parentDiv.style.visibility = 'hidden';
await waitForNextFrame();
var markers = await observeStyling(5);
is(markers.length, 0,
'Animations that the parent element became visible should throttle ' +
'restyling again');
await ensureElementRemoval(parentDiv);
todo_is(markers.length, 0,
'Bug 1237454: Animations running on the main-thread in ' +
'visibility hidden element should never cause restyles');
await ensureElementRemoval(div);
});
add_task(
async function restyling_animations_on_visibility_hidden_element_with_visibility_changed_children() {
var div = addDiv(null,
{ style: 'animation: background-color 100s; visibility: hidden' });
var animation = div.getAnimations()[0];
await animation.ready;
var markers = await observeStyling(5);
is(markers.length, 0,
'Animations on visibility hidden element having no visible children ' +
'should never cause restyles');
var childElement = addDiv(null, { style: 'visibility: visible' });
div.appendChild(childElement);
await waitForNextFrame();
var markers = await observeStyling(5);
is(markers.length, 5,
'Animations running on visibility hidden element but the element has ' +
'a visible child should not throttle restyling');
childElement.style.visibility = 'hidden';
await waitForNextFrame();
var markers = await observeStyling(5);
todo_is(markers.length, 0,
'Animations running on visibility hidden element that a child ' +
'has become invisible should throttle restyling');
childElement.style.visibility = 'visible';
await waitForNextFrame();
var markers = await observeStyling(5);
is(markers.length, 5,
'Animations running on visibility hidden element should not throttle ' +
'restyling after the invisible element changed to visible');
childElement.remove();
await waitForNextFrame();
var markers = await observeStyling(5);
todo_is(markers.length, 0,
'Animations running on visibility hidden element should throttle ' +
'restyling again after all visible descendants were removed');
await ensureElementRemoval(div);
}
);
add_task(
async function restyling_animations_on_visiblity_hidden_element_having_oof_child() {
var div = addDiv(null,
{ style: 'animation: background-color 100s; position: absolute' });
var childElement = addDiv(null,
{ style: 'float: left; visibility: hidden' });
div.appendChild(childElement);
var animation = div.getAnimations()[0];
await animation.ready;
// We don't check the animation causes restyles here since we already
// check it in the first test case.
div.style.visibility = 'hidden';
await waitForNextFrame();
var markers = await observeStyling(5);
is(markers.length, 0,
'Animations running on visibility hidden element which has an ' +
'out-of-flow child should throttle restyling');
await ensureElementRemoval(div);
}
);
add_task(
async function restyling_animations_on_visibility_hidden_element_having_grandchild() {
// element tree:
//
// root(visibility:hidden)
// / \
// childA childB
// / \ / \
// AA AB BA BB
var div = addDiv(null,
{ style: 'animation: background-color 100s; visibility: hidden' });
var childA = addDiv(null);
div.appendChild(childA);
var childB = addDiv(null);
div.appendChild(childB);
var grandchildAA = addDiv(null);
childA.appendChild(grandchildAA);
var grandchildAB = addDiv(null);
childA.appendChild(grandchildAB);
var grandchildBA = addDiv(null);
childB.appendChild(grandchildBA);
var grandchildBB = addDiv(null);
childB.appendChild(grandchildBB);
var animation = div.getAnimations()[0];
await animation.ready;
var markers = await observeStyling(5);
is(markers.length, 0,
'Animations on visibility hidden element having no visible ' +
'descendants should never cause restyles');
childA.style.visibility = 'visible';
grandchildAA.style.visibility = 'visible';
grandchildAB.style.visibility = 'visible';
await waitForNextFrame();
var markers = await observeStyling(5);
is(markers.length, 5,
'Animations running on visibility hidden element but the element has ' +
'visible children should not throttle restyling');
// Make childA hidden again but both of grandchildAA and grandchildAB are
// still visible.
childA.style.visibility = 'hidden';
await waitForNextFrame();
var markers = await observeStyling(5);
is(markers.length, 5,
'Animations running on visibility hidden element that a child has ' +
'become invisible again but there are still visible children should ' +
'not throttle restyling');
// Make grandchildAA hidden but grandchildAB is still visible.
grandchildAA.style.visibility = 'hidden';
await waitForNextFrame();
var markers = await observeStyling(5);
is(markers.length, 5,
'Animations running on visibility hidden element that a grandchild ' +
'become invisible again but another grandchild is still visible ' +
'should not throttle restyling');
// Make childB and grandchildBA visible.
childB.style.visibility = 'visible';
grandchildBA.style.visibility = 'visible';
await waitForNextFrame();
var markers = await observeStyling(5);
is(markers.length, 5,
'Animations running on visibility hidden element but the element has ' +
'visible descendants should not throttle restyling');
// Make childB hidden but grandchildAB and grandchildBA are still visible.
childB.style.visibility = 'hidden';
await waitForNextFrame();
var markers = await observeStyling(5);
is(markers.length, 5,
'Animations running on visibility hidden element but the element has ' +
'visible grandchildren should not throttle restyling');
// Make grandchildAB hidden but grandchildBA is still visible.
grandchildAB.style.visibility = 'hidden';
await waitForNextFrame();
var markers = await observeStyling(5);
is(markers.length, 5,
'Animations running on visibility hidden element but the element has ' +
'a visible grandchild should not throttle restyling');
// Make grandchildBA hidden. Now all descedants are invisible.
grandchildBA.style.visibility = 'hidden';
await waitForNextFrame();
var markers = await observeStyling(5);
todo_is(markers.length, 0,
'Animations on visibility hidden element that all descendants have ' +
'become invisible again should never cause restyles');
// Make childB visible.
childB.style.visibility = 'visible';
await waitForNextFrame();
var markers = await observeStyling(5);
is(markers.length, 5,
'Animations on visibility hidden element that has a visible child ' +
'should never cause restyles');
// Make childB invisible again
childB.style.visibility = 'hidden';
await waitForNextFrame();
var markers = await observeStyling(5);
todo_is(markers.length, 0,
'Animations on visibility hidden element that the visible child ' +
'has become invisible again should never cause restyles');
await ensureElementRemoval(div);
}
);
add_task_if_omta_enabled(async function no_restyling_compositor_animations_after_pause_is_called() {
var div = addDiv(null, { style: 'animation: opacity 100s' });
var animation = div.getAnimations()[0];

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

@ -438,14 +438,12 @@ RestyleManager::ChangeHintToString(nsChangeHint aHint)
"ReflowChangesSizeOrPosition", "UpdateComputedBSize",
"UpdateUsesOpacity", "UpdateBackgroundPosition",
"AddOrRemoveTransform", "CSSOverflowChange",
"UpdateWidgetProperties", "UpdateTableCellSpans",
"VisibilityChange"
"UpdateWidgetProperties", "UpdateTableCellSpans"
};
static_assert(nsChangeHint_AllHints ==
static_cast<uint32_t>((1ull << ArrayLength(names)) - 1),
static_assert(nsChangeHint_AllHints == (1u << ArrayLength(names)) - 1,
"Name list doesn't match change hints.");
uint32_t hint = aHint & static_cast<uint32_t>((1ull << ArrayLength(names)) - 1);
uint32_t rest = aHint & ~static_cast<uint32_t>((1ull << ArrayLength(names)) - 1);
uint32_t hint = aHint & ((1u << ArrayLength(names)) - 1);
uint32_t rest = aHint & ~((1u << ArrayLength(names)) - 1);
if ((hint & NS_STYLE_HINT_REFLOW) == NS_STYLE_HINT_REFLOW) {
result.AppendLiteral("NS_STYLE_HINT_REFLOW");
hint = hint & ~NS_STYLE_HINT_REFLOW;
@ -460,7 +458,7 @@ RestyleManager::ChangeHintToString(nsChangeHint aHint)
any = true;
}
for (uint32_t i = 0; i < ArrayLength(names); i++) {
if (hint & (1u << i)) {
if (hint & (1 << i)) {
if (any) {
result.AppendLiteral(" | ");
}
@ -1729,9 +1727,6 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
if (hint & nsChangeHint_UpdateTableCellSpans) {
frameConstructor->UpdateTableCellSpans(content);
}
if (hint & nsChangeHint_VisibilityChange) {
frame->UpdateVisibleDescendantsState();
}
}
}

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

@ -245,14 +245,6 @@ enum nsChangeHint : uint32_t {
*/
nsChangeHint_UpdateTableCellSpans = 1 << 30,
/**
* Indicates that the visiblity property changed.
* This change hint is used for skip restyling for animations on
* visibility:hidden elements in the case where the elements have no visible
* descendants.
*/
nsChangeHint_VisibilityChange = 1u << 31,
// IMPORTANT NOTE: When adding a new hint, you will need to add it to
// one of:
//
@ -268,7 +260,7 @@ enum nsChangeHint : uint32_t {
/**
* Dummy hint value for all hints. It exists for compile time check.
*/
nsChangeHint_AllHints = uint32_t((1ull << 32) - 1),
nsChangeHint_AllHints = (1u << 31) - 1,
};
// Redefine these operators to return nothing. This will catch any use
@ -350,8 +342,7 @@ inline nsChangeHint operator^=(nsChangeHint& aLeft, nsChangeHint aRight)
nsChangeHint_SyncFrameView | \
nsChangeHint_UpdateCursor | \
nsChangeHint_UpdateSubtreeOverflow | \
nsChangeHint_UpdateTextPath | \
nsChangeHint_VisibilityChange \
nsChangeHint_UpdateTextPath \
)
// The change hints that are never handled for descendants.
@ -465,8 +456,7 @@ static_assert(!(nsChangeHint_Hints_AlwaysHandledForDescendants &
nsChangeHint_AddOrRemoveTransform | \
nsChangeHint_UpdatePostTransformOverflow | \
nsChangeHint_UpdateTransformLayer | \
nsChangeHint_UpdateUsesOpacity | \
nsChangeHint_VisibilityChange)
nsChangeHint_UpdateUsesOpacity)
// NB: Once we drop support for the old style system, this logic should be
// inlined in the Servo style system to eliminate the FFI call.

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

@ -734,12 +734,6 @@ nsFrame::Init(nsIContent* aContent,
if (::IsXULBoxWrapped(this))
::InitBoxMetrics(this, false);
// For a newly created frame, we need to update this frame's visibility state.
// Usually we update the state when the frame is restyled and has a
// VisibilityChange change hint but we don't generate any change hints for
// newly created frames.
UpdateVisibleDescendantsState();
}
void
@ -11347,39 +11341,6 @@ nsIFrame::GetCompositorHitTestInfo(nsDisplayListBuilder* aBuilder)
return result;
}
// Returns true if we can guarantee there is no visible descendants.
static bool
HasNoVisibleDescendants(const nsIFrame* aFrame)
{
for (nsIFrame::ChildListIterator lists(aFrame);
!lists.IsDone();
lists.Next()) {
for (nsIFrame* f : lists.CurrentList()) {
if (nsPlaceholderFrame::GetRealFrameFor(f)->
IsVisibleOrMayHaveVisibleDescendants()) {
return false;
}
}
}
return true;
}
void
nsIFrame::UpdateVisibleDescendantsState()
{
if (StyleVisibility()->IsVisible()) {
// Notify invisible ancestors that a visible descendant exists now.
nsIFrame* ancestor;
for (ancestor = GetInFlowParent();
ancestor && !ancestor->StyleVisibility()->IsVisible();
ancestor = ancestor->GetInFlowParent()) {
ancestor->mAllDescendantsAreInvisible = false;
}
} else {
mAllDescendantsAreInvisible = HasNoVisibleDescendants(this);
}
}
// Box layout debugging
#ifdef DEBUG_REFLOW
int32_t gIndent2 = 0;

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

@ -628,7 +628,6 @@ public:
, mIsPrimaryFrame(false)
, mMayHaveTransformAnimation(false)
, mMayHaveOpacityAnimation(false)
, mAllDescendantsAreInvisible(false)
{
mozilla::PodZero(&mOverflow);
}
@ -4090,13 +4089,6 @@ public:
mMayHaveOpacityAnimation = true;
}
// Returns true if this frame is visible or may have visible descendants.
bool IsVisibleOrMayHaveVisibleDescendants() const {
return !mAllDescendantsAreInvisible || StyleVisibility()->IsVisible();
}
// Update mAllDescendantsAreInvisible flag for this frame and ancestors.
void UpdateVisibleDescendantsState();
/**
* If this returns true, the frame it's called on should get the
* NS_FRAME_HAS_DIRTY_CHILDREN bit set on it by the caller; either directly
@ -4356,19 +4348,9 @@ private:
bool mMayHaveTransformAnimation : 1;
bool mMayHaveOpacityAnimation : 1;
/**
* True if we are certain that all descendants are not visible.
*
* This flag is conservative in that it might sometimes be false even if, in
* fact, all descendants are invisible.
* For example; an element is visibility:visible and has a visibility:hidden
* child. This flag is stil false in such case.
*/
bool mAllDescendantsAreInvisible : 1;
protected:
// There is no gap left here.
// There is a 1-bit gap left here.
// Helpers
/**

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

@ -4103,10 +4103,6 @@ nsStyleVisibility::CalcDifference(const nsStyleVisibility& aNewData) const
nsChangeHint_RepaintFrame;
}
if (mVisible != aNewData.mVisible) {
if (mVisible == NS_STYLE_VISIBILITY_VISIBLE ||
aNewData.mVisible == NS_STYLE_VISIBILITY_VISIBLE) {
hint |= nsChangeHint_VisibilityChange;
}
if ((NS_STYLE_VISIBILITY_COLLAPSE == mVisible) ||
(NS_STYLE_VISIBILITY_COLLAPSE == aNewData.mVisible)) {
hint |= NS_STYLE_HINT_REFLOW;