Bug 1668875 - Invalidate images for media query changes more granularly. r=heycam

The SVG code invalidating too much causes hangs with pages that have
lots of SVGs.

Differential Revision: https://phabricator.services.mozilla.com/D94186
This commit is contained in:
Emilio Cobos Álvarez 2020-10-20 21:24:30 +00:00
Родитель ce1d1adc9a
Коммит 15c2b41a78
3 изменённых файлов: 26 добавлений и 24 удалений

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

@ -1556,20 +1556,16 @@ void VectorImage::MediaFeatureValuesChangedAllDocuments(
}
if (Document* doc = mSVGDocumentWrapper->GetDocument()) {
if (nsPresContext* presContext = doc->GetPresContext()) {
if (RefPtr<nsPresContext> presContext = doc->GetPresContext()) {
presContext->MediaFeatureValuesChangedAllDocuments(aChange);
// Media feature value changes don't happen in the middle of layout,
// so we don't need to call InvalidateObserversOnNextRefreshDriverTick
// to invalidate asynchronously.
//
// Ideally we would not invalidate images if the media feature value
// change did not cause any updates to the document, but since non-
// animated SVG images do not have their refresh driver ticked, it
// is the invalidation (and then the painting) which is what causes
// the document to be flushed. Theme and system metrics changes are
// rare, though, so it's not a big deal to invalidate even if it
// doesn't cause any change.
SendInvalidationNotifications();
if (presContext->FlushPendingMediaFeatureValuesChanged()) {
// NOTE(emilio): SendInvalidationNotifications flushes layout via
// VectorImage::CreateSurface -> FlushImageTransformInvalidation.
SendInvalidationNotifications();
}
}
}
}

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

@ -1562,9 +1562,9 @@ void nsPresContext::MediaFeatureValuesChangedAllDocuments(
}
}
void nsPresContext::FlushPendingMediaFeatureValuesChanged() {
bool nsPresContext::FlushPendingMediaFeatureValuesChanged() {
if (!mPendingMediaFeatureValuesChange) {
return;
return false;
}
MediaFeatureChange change = *mPendingMediaFeatureValuesChange;
@ -1576,13 +1576,14 @@ void nsPresContext::FlushPendingMediaFeatureValuesChanged() {
mPresShell->StyleSet()->MediumFeaturesChanged(change.mReason);
}
if (change.mRestyleHint || change.mChangeHint) {
const bool changedStyle = change.mRestyleHint || change.mChangeHint;
if (changedStyle) {
RebuildAllStyleData(change.mChangeHint, change.mRestyleHint);
}
if (mDocument->IsBeingUsedAsImage()) {
MOZ_ASSERT(mDocument->MediaQueryLists().isEmpty());
return;
return changedStyle;
}
mDocument->NotifyMediaFeatureValuesChanged();
@ -1600,7 +1601,7 @@ void nsPresContext::FlushPendingMediaFeatureValuesChanged() {
// style sheets has been computed.
if (mDocument->MediaQueryLists().isEmpty()) {
return;
return changedStyle;
}
// We build a list of all the notifications we're going to send
@ -1613,14 +1614,18 @@ void nsPresContext::FlushPendingMediaFeatureValuesChanged() {
}
}
nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
"nsPresContext::FlushPendingMediaFeatureValuesChanged",
[list = std::move(listsToNotify)] {
for (const auto& mql : list) {
nsAutoMicroTask mt;
mql->FireChangeEvent();
}
}));
if (!listsToNotify.IsEmpty()) {
nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
"nsPresContext::FlushPendingMediaFeatureValuesChanged",
[list = std::move(listsToNotify)] {
for (const auto& mql : list) {
nsAutoMicroTask mt;
mql->FireChangeEvent();
}
}));
}
return changedStyle;
}
void nsPresContext::SizeModeChanged(nsSizeMode aSizeMode) {

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

@ -290,7 +290,8 @@ class nsPresContext : public nsISupports, public mozilla::SupportsWeakPtr {
*/
void MediaFeatureValuesChanged(const mozilla::MediaFeatureChange& aChange);
void FlushPendingMediaFeatureValuesChanged();
/** Returns whether any media query changed. */
bool FlushPendingMediaFeatureValuesChanged();
/**
* Calls MediaFeatureValuesChanged for this pres context and all descendant