зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to fx-team
This commit is contained in:
Коммит
b06178a07e
|
@ -758,11 +758,11 @@
|
||||||
// if the error page's URI is about:blank, because that causes complete
|
// if the error page's URI is about:blank, because that causes complete
|
||||||
// loss of urlbar contents for invalid URI errors (see bug 867957).
|
// loss of urlbar contents for invalid URI errors (see bug 867957).
|
||||||
// Another reason to clear the userTypedValue is if this was an anchor
|
// Another reason to clear the userTypedValue is if this was an anchor
|
||||||
// navigation.
|
// navigation initiated by the user.
|
||||||
if (this.mBrowser.userTypedClear > 0 ||
|
if (this.mBrowser.userTypedClear > 0 ||
|
||||||
((aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) &&
|
((aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) &&
|
||||||
aLocation.spec != "about:blank") ||
|
aLocation.spec != "about:blank") ||
|
||||||
isSameDocument) {
|
(isSameDocument && this.mBrowser.inLoadURI)) {
|
||||||
this.mBrowser.userTypedValue = null;
|
this.mBrowser.userTypedValue = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
[browser_urlbar_blanking.js]
|
[browser_urlbar_blanking.js]
|
||||||
support-files =
|
support-files =
|
||||||
file_blank_but_not_blank.html
|
file_blank_but_not_blank.html
|
||||||
|
[browser_urlbar_locationchange_urlbar_edit_dos.js]
|
||||||
|
support-files =
|
||||||
|
file_urlbar_edit_dos.html
|
||||||
[browser_urlbar_stop_pending.js]
|
[browser_urlbar_stop_pending.js]
|
||||||
support-files =
|
support-files =
|
||||||
slow-page.sjs
|
slow-page.sjs
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function* checkURLBarValueStays(browser) {
|
||||||
|
gURLBar.select();
|
||||||
|
EventUtils.synthesizeKey("a", {});
|
||||||
|
is(gURLBar.value, "a", "URL bar value should match after sending a key");
|
||||||
|
yield new Promise(resolve => {
|
||||||
|
let listener = {
|
||||||
|
onLocationChange(aWebProgress, aRequest, aLocation, aFlags) {
|
||||||
|
ok(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT,
|
||||||
|
"Should only get a same document location change");
|
||||||
|
gBrowser.selectedBrowser.removeProgressListener(filter);
|
||||||
|
filter = null;
|
||||||
|
resolve();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let filter = Cc["@mozilla.org/appshell/component/browser-status-filter;1"]
|
||||||
|
.createInstance(Ci.nsIWebProgress);
|
||||||
|
filter.addProgressListener(listener, Ci.nsIWebProgress.NOTIFY_ALL);
|
||||||
|
gBrowser.selectedBrowser.addProgressListener(filter);
|
||||||
|
});
|
||||||
|
is(gURLBar.value, "a", "URL bar should not have been changed by location changes.");
|
||||||
|
}
|
||||||
|
|
||||||
|
add_task(function*() {
|
||||||
|
yield BrowserTestUtils.withNewTab({
|
||||||
|
gBrowser,
|
||||||
|
url: "http://example.com/browser/browser/base/content/test/urlbar/file_urlbar_edit_dos.html"
|
||||||
|
}, function*(browser) {
|
||||||
|
yield ContentTask.spawn(browser, "", function() {
|
||||||
|
content.wrappedJSObject.dos_hash();
|
||||||
|
});
|
||||||
|
yield checkURLBarValueStays(browser);
|
||||||
|
yield ContentTask.spawn(browser, "", function() {
|
||||||
|
content.clearTimeout(content.wrappedJSObject.dos_timeout);
|
||||||
|
content.wrappedJSObject.dos_pushState();
|
||||||
|
});
|
||||||
|
yield checkURLBarValueStays(browser);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Try editing the URL bar</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
var dos_timeout = null;
|
||||||
|
function dos_hash() {
|
||||||
|
dos_timeout = setTimeout(function() {
|
||||||
|
location.hash = "#";
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
function dos_pushState() {
|
||||||
|
dos_timeout = setTimeout(function() {
|
||||||
|
history.pushState({}, "Some title", "");
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -65,7 +65,6 @@ whitelist['nightly']['win32'] += [
|
||||||
whitelist['nightly']['win64'] += [
|
whitelist['nightly']['win64'] += [
|
||||||
'. "$topsrcdir/browser/config/mozconfigs/win64/common-win64"',
|
'. "$topsrcdir/browser/config/mozconfigs/win64/common-win64"',
|
||||||
'. "$topsrcdir/build/mozconfig.cache"',
|
'. "$topsrcdir/build/mozconfig.cache"',
|
||||||
'. "$topsrcdir/build/mozconfig.rust"',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
for platform in all_platforms:
|
for platform in all_platforms:
|
||||||
|
|
|
@ -14,4 +14,6 @@ mk_add_options MOZ_PGO=1
|
||||||
ac_add_options --enable-official-branding
|
ac_add_options --enable-official-branding
|
||||||
ac_add_options --enable-verify-mar
|
ac_add_options --enable-verify-mar
|
||||||
|
|
||||||
|
. "$topsrcdir/build/mozconfig.rust"
|
||||||
|
|
||||||
. "$topsrcdir/build/mozconfig.common.override"
|
. "$topsrcdir/build/mozconfig.common.override"
|
||||||
|
|
|
@ -20,4 +20,6 @@ ac_add_options --enable-verify-mar
|
||||||
# defines.sh during the beta cycle
|
# defines.sh during the beta cycle
|
||||||
export BUILDING_RELEASE=1
|
export BUILDING_RELEASE=1
|
||||||
|
|
||||||
|
. "$topsrcdir/build/mozconfig.rust"
|
||||||
|
|
||||||
. "$topsrcdir/build/mozconfig.common.override"
|
. "$topsrcdir/build/mozconfig.common.override"
|
||||||
|
|
|
@ -94,7 +94,12 @@ private:
|
||||||
virtual void run(const MatchFinder::MatchResult &Result);
|
virtual void run(const MatchFinder::MatchResult &Result);
|
||||||
};
|
};
|
||||||
|
|
||||||
class NonMemMovableChecker : public MatchFinder::MatchCallback {
|
class NonMemMovableTemplateArgChecker : public MatchFinder::MatchCallback {
|
||||||
|
public:
|
||||||
|
virtual void run(const MatchFinder::MatchResult &Result);
|
||||||
|
};
|
||||||
|
|
||||||
|
class NonMemMovableMemberChecker : public MatchFinder::MatchCallback {
|
||||||
public:
|
public:
|
||||||
virtual void run(const MatchFinder::MatchResult &Result);
|
virtual void run(const MatchFinder::MatchResult &Result);
|
||||||
};
|
};
|
||||||
|
@ -128,7 +133,8 @@ private:
|
||||||
ExplicitOperatorBoolChecker explicitOperatorBoolChecker;
|
ExplicitOperatorBoolChecker explicitOperatorBoolChecker;
|
||||||
NoDuplicateRefCntMemberChecker noDuplicateRefCntMemberChecker;
|
NoDuplicateRefCntMemberChecker noDuplicateRefCntMemberChecker;
|
||||||
NeedsNoVTableTypeChecker needsNoVTableTypeChecker;
|
NeedsNoVTableTypeChecker needsNoVTableTypeChecker;
|
||||||
NonMemMovableChecker nonMemMovableChecker;
|
NonMemMovableTemplateArgChecker nonMemMovableTemplateArgChecker;
|
||||||
|
NonMemMovableMemberChecker nonMemMovableMemberChecker;
|
||||||
ExplicitImplicitChecker explicitImplicitChecker;
|
ExplicitImplicitChecker explicitImplicitChecker;
|
||||||
NoAutoTypeChecker noAutoTypeChecker;
|
NoAutoTypeChecker noAutoTypeChecker;
|
||||||
NoExplicitMoveConstructorChecker noExplicitMoveConstructorChecker;
|
NoExplicitMoveConstructorChecker noExplicitMoveConstructorChecker;
|
||||||
|
@ -707,10 +713,15 @@ AST_MATCHER(QualType, isNonMemMovable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This matcher will select classes which require a memmovable template arg
|
/// This matcher will select classes which require a memmovable template arg
|
||||||
AST_MATCHER(CXXRecordDecl, needsMemMovable) {
|
AST_MATCHER(CXXRecordDecl, needsMemMovableTemplateArg) {
|
||||||
return MozChecker::hasCustomAnnotation(&Node, "moz_needs_memmovable_type");
|
return MozChecker::hasCustomAnnotation(&Node, "moz_needs_memmovable_type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This matcher will select classes which require all members to be memmovable
|
||||||
|
AST_MATCHER(CXXRecordDecl, needsMemMovableMembers) {
|
||||||
|
return MozChecker::hasCustomAnnotation(&Node, "moz_needs_memmovable_members");
|
||||||
|
}
|
||||||
|
|
||||||
AST_MATCHER(CXXConstructorDecl, isInterestingImplicitCtor) {
|
AST_MATCHER(CXXConstructorDecl, isInterestingImplicitCtor) {
|
||||||
const CXXConstructorDecl *decl = Node.getCanonicalDecl();
|
const CXXConstructorDecl *decl = Node.getCanonicalDecl();
|
||||||
return
|
return
|
||||||
|
@ -1012,10 +1023,16 @@ DiagnosticsMatcher::DiagnosticsMatcher() {
|
||||||
// Handle non-mem-movable template specializations
|
// Handle non-mem-movable template specializations
|
||||||
astMatcher.addMatcher(
|
astMatcher.addMatcher(
|
||||||
classTemplateSpecializationDecl(
|
classTemplateSpecializationDecl(
|
||||||
allOf(needsMemMovable(),
|
allOf(needsMemMovableTemplateArg(),
|
||||||
hasAnyTemplateArgument(refersToType(isNonMemMovable()))))
|
hasAnyTemplateArgument(refersToType(isNonMemMovable()))))
|
||||||
.bind("specialization"),
|
.bind("specialization"),
|
||||||
&nonMemMovableChecker);
|
&nonMemMovableTemplateArgChecker);
|
||||||
|
|
||||||
|
// Handle non-mem-movable members
|
||||||
|
astMatcher.addMatcher(
|
||||||
|
cxxRecordDecl(needsMemMovableMembers())
|
||||||
|
.bind("decl"),
|
||||||
|
&nonMemMovableMemberChecker);
|
||||||
|
|
||||||
astMatcher.addMatcher(cxxConstructorDecl(isInterestingImplicitCtor(),
|
astMatcher.addMatcher(cxxConstructorDecl(isInterestingImplicitCtor(),
|
||||||
ofClass(allOf(isConcreteClass(),
|
ofClass(allOf(isConcreteClass(),
|
||||||
|
@ -1382,7 +1399,7 @@ void DiagnosticsMatcher::NeedsNoVTableTypeChecker::run(
|
||||||
<< specialization;
|
<< specialization;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiagnosticsMatcher::NonMemMovableChecker::run(
|
void DiagnosticsMatcher::NonMemMovableTemplateArgChecker::run(
|
||||||
const MatchFinder::MatchResult &Result) {
|
const MatchFinder::MatchResult &Result) {
|
||||||
DiagnosticsEngine &Diag = Result.Context->getDiagnostics();
|
DiagnosticsEngine &Diag = Result.Context->getDiagnostics();
|
||||||
unsigned errorID = Diag.getDiagnosticIDs()->getCustomDiagID(
|
unsigned errorID = Diag.getDiagnosticIDs()->getCustomDiagID(
|
||||||
|
@ -1401,7 +1418,7 @@ void DiagnosticsMatcher::NonMemMovableChecker::run(
|
||||||
specialization->getTemplateInstantiationArgs();
|
specialization->getTemplateInstantiationArgs();
|
||||||
for (unsigned i = 0; i < args.size(); ++i) {
|
for (unsigned i = 0; i < args.size(); ++i) {
|
||||||
QualType argType = args[i].getAsType();
|
QualType argType = args[i].getAsType();
|
||||||
if (NonMemMovable.hasEffectiveAnnotation(args[i].getAsType())) {
|
if (NonMemMovable.hasEffectiveAnnotation(argType)) {
|
||||||
Diag.Report(specialization->getLocation(), errorID) << specialization
|
Diag.Report(specialization->getLocation(), errorID) << specialization
|
||||||
<< argType;
|
<< argType;
|
||||||
// XXX It would be really nice if we could get the instantiation stack
|
// XXX It would be really nice if we could get the instantiation stack
|
||||||
|
@ -1419,6 +1436,29 @@ void DiagnosticsMatcher::NonMemMovableChecker::run(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DiagnosticsMatcher::NonMemMovableMemberChecker::run(
|
||||||
|
const MatchFinder::MatchResult &Result) {
|
||||||
|
DiagnosticsEngine &Diag = Result.Context->getDiagnostics();
|
||||||
|
unsigned errorID = Diag.getDiagnosticIDs()->getCustomDiagID(
|
||||||
|
DiagnosticIDs::Error,
|
||||||
|
"class %0 cannot have non-memmovable member %1 of type %2");
|
||||||
|
|
||||||
|
// Get the specialization
|
||||||
|
const CXXRecordDecl* Decl =
|
||||||
|
Result.Nodes.getNodeAs<CXXRecordDecl>("decl");
|
||||||
|
|
||||||
|
// Report an error for every member which is non-memmovable
|
||||||
|
for (const FieldDecl *Field : Decl->fields()) {
|
||||||
|
QualType Type = Field->getType();
|
||||||
|
if (NonMemMovable.hasEffectiveAnnotation(Type)) {
|
||||||
|
Diag.Report(Field->getLocation(), errorID) << Decl
|
||||||
|
<< Field
|
||||||
|
<< Type;
|
||||||
|
NonMemMovable.dumpAnnotationReason(Diag, Type, Decl->getLocation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DiagnosticsMatcher::ExplicitImplicitChecker::run(
|
void DiagnosticsMatcher::ExplicitImplicitChecker::run(
|
||||||
const MatchFinder::MatchResult &Result) {
|
const MatchFinder::MatchResult &Result) {
|
||||||
DiagnosticsEngine &Diag = Result.Context->getDiagnostics();
|
DiagnosticsEngine &Diag = Result.Context->getDiagnostics();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#define MOZ_NON_MEMMOVABLE __attribute__((annotate("moz_non_memmovable")))
|
#define MOZ_NON_MEMMOVABLE __attribute__((annotate("moz_non_memmovable")))
|
||||||
#define MOZ_NEEDS_MEMMOVABLE_TYPE __attribute__((annotate("moz_needs_memmovable_type")))
|
#define MOZ_NEEDS_MEMMOVABLE_TYPE __attribute__((annotate("moz_needs_memmovable_type")))
|
||||||
|
#define MOZ_NEEDS_MEMMOVABLE_MEMBERS __attribute__((annotate("moz_needs_memmovable_members")))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
These are a bunch of structs with variable levels of memmovability.
|
These are a bunch of structs with variable levels of memmovability.
|
||||||
|
@ -9,12 +10,12 @@ struct MOZ_NON_MEMMOVABLE NonMovable {};
|
||||||
struct Movable {};
|
struct Movable {};
|
||||||
|
|
||||||
// Subclasses
|
// Subclasses
|
||||||
struct S_NonMovable : NonMovable {}; // expected-note 48 {{'S_NonMovable' is a non-memmove()able type because it inherits from a non-memmove()able type 'NonMovable'}}
|
struct S_NonMovable : NonMovable {}; // expected-note 51 {{'S_NonMovable' is a non-memmove()able type because it inherits from a non-memmove()able type 'NonMovable'}}
|
||||||
struct S_Movable : Movable {};
|
struct S_Movable : Movable {};
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
struct W_NonMovable {
|
struct W_NonMovable {
|
||||||
NonMovable m; // expected-note 32 {{'W_NonMovable' is a non-memmove()able type because member 'm' is a non-memmove()able type 'NonMovable'}}
|
NonMovable m; // expected-note 34 {{'W_NonMovable' is a non-memmove()able type because member 'm' is a non-memmove()able type 'NonMovable'}}
|
||||||
};
|
};
|
||||||
struct W_Movable {
|
struct W_Movable {
|
||||||
Movable m;
|
Movable m;
|
||||||
|
@ -22,17 +23,17 @@ struct W_Movable {
|
||||||
|
|
||||||
// Wrapped Subclasses
|
// Wrapped Subclasses
|
||||||
struct WS_NonMovable {
|
struct WS_NonMovable {
|
||||||
S_NonMovable m; // expected-note 32 {{'WS_NonMovable' is a non-memmove()able type because member 'm' is a non-memmove()able type 'S_NonMovable'}}
|
S_NonMovable m; // expected-note 34 {{'WS_NonMovable' is a non-memmove()able type because member 'm' is a non-memmove()able type 'S_NonMovable'}}
|
||||||
};
|
};
|
||||||
struct WS_Movable {
|
struct WS_Movable {
|
||||||
S_Movable m;
|
S_Movable m;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Combinations of the above
|
// Combinations of the above
|
||||||
struct SW_NonMovable : W_NonMovable {}; // expected-note 16 {{'SW_NonMovable' is a non-memmove()able type because it inherits from a non-memmove()able type 'W_NonMovable'}}
|
struct SW_NonMovable : W_NonMovable {}; // expected-note 17 {{'SW_NonMovable' is a non-memmove()able type because it inherits from a non-memmove()able type 'W_NonMovable'}}
|
||||||
struct SW_Movable : W_Movable {};
|
struct SW_Movable : W_Movable {};
|
||||||
|
|
||||||
struct SWS_NonMovable : WS_NonMovable {}; // expected-note 16 {{'SWS_NonMovable' is a non-memmove()able type because it inherits from a non-memmove()able type 'WS_NonMovable'}}
|
struct SWS_NonMovable : WS_NonMovable {}; // expected-note 17 {{'SWS_NonMovable' is a non-memmove()able type because it inherits from a non-memmove()able type 'WS_NonMovable'}}
|
||||||
struct SWS_Movable : WS_Movable {};
|
struct SWS_Movable : WS_Movable {};
|
||||||
|
|
||||||
// Basic templated wrapper
|
// Basic templated wrapper
|
||||||
|
@ -810,3 +811,20 @@ void specialization() {
|
||||||
Defaulted_Templated_NeedyTemplate7<S_SpecializedNonMovable> c7;
|
Defaulted_Templated_NeedyTemplate7<S_SpecializedNonMovable> c7;
|
||||||
W_Defaulted_Templated_NeedyTemplate8<S_SpecializedNonMovable> c8;
|
W_Defaulted_Templated_NeedyTemplate8<S_SpecializedNonMovable> c8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MOZ_NEEDS_MEMMOVABLE_MEMBERS NeedsMemMovableMembers {
|
||||||
|
Movable m1;
|
||||||
|
NonMovable m2; // expected-error {{class 'NeedsMemMovableMembers' cannot have non-memmovable member 'm2' of type 'NonMovable'}}
|
||||||
|
S_Movable sm1;
|
||||||
|
S_NonMovable sm2; // expected-error {{class 'NeedsMemMovableMembers' cannot have non-memmovable member 'sm2' of type 'S_NonMovable'}}
|
||||||
|
W_Movable wm1;
|
||||||
|
W_NonMovable wm2; // expected-error {{class 'NeedsMemMovableMembers' cannot have non-memmovable member 'wm2' of type 'W_NonMovable'}}
|
||||||
|
SW_Movable swm1;
|
||||||
|
SW_NonMovable swm2; // expected-error {{class 'NeedsMemMovableMembers' cannot have non-memmovable member 'swm2' of type 'SW_NonMovable'}}
|
||||||
|
WS_Movable wsm1;
|
||||||
|
WS_NonMovable wsm2; // expected-error {{class 'NeedsMemMovableMembers' cannot have non-memmovable member 'wsm2' of type 'WS_NonMovable'}}
|
||||||
|
SWS_Movable swsm1;
|
||||||
|
SWS_NonMovable swsm2; // expected-error {{class 'NeedsMemMovableMembers' cannot have non-memmovable member 'swsm2' of type 'SWS_NonMovable'}}
|
||||||
|
};
|
||||||
|
|
||||||
|
class NeedsMemMovableMembersDerived : public NeedsMemMovableMembers {};
|
||||||
|
|
|
@ -622,7 +622,7 @@ File::Constructor(const GlobalObject& aGlobal,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
if (!nsContentUtils::ThreadsafeIsCallerChrome()) {
|
if (!nsContentUtils::ThreadsafeIsCallerChrome()) {
|
||||||
aRv.Throw(NS_ERROR_FAILURE);
|
aRv.ThrowTypeError<MSG_MISSING_ARGUMENTS>(NS_LITERAL_STRING("File"));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -893,3 +893,4 @@ skip-if = buildapp == 'b2g' #no ssl support
|
||||||
[test_mozbrowser_apis_blocked.html]
|
[test_mozbrowser_apis_blocked.html]
|
||||||
[test_document_register.html]
|
[test_document_register.html]
|
||||||
[test_bug962251.html]
|
[test_bug962251.html]
|
||||||
|
[test_bug1259588.html]
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<title>Test for Bug 1259588</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<script>
|
||||||
|
test(function() {
|
||||||
|
assert_throws(new TypeError, function() {
|
||||||
|
new File("");
|
||||||
|
}, "new File(\"\") should throw TypeError exception");
|
||||||
|
}, "Test new File(\"\") should throw exception");
|
||||||
|
</script>
|
|
@ -2382,7 +2382,7 @@ nsGonkCameraControl::OnNewPreviewFrame(layers::TextureClient* aBuffer)
|
||||||
|
|
||||||
IntSize picSize(mCurrentConfiguration.mPreviewSize.width,
|
IntSize picSize(mCurrentConfiguration.mPreviewSize.width,
|
||||||
mCurrentConfiguration.mPreviewSize.height);
|
mCurrentConfiguration.mPreviewSize.height);
|
||||||
frame->SetData(aBuffer, picSize);
|
frame->AdoptData(aBuffer, picSize);
|
||||||
|
|
||||||
if (mCapturePoster.exchange(false)) {
|
if (mCapturePoster.exchange(false)) {
|
||||||
CreatePoster(frame,
|
CreatePoster(frame,
|
||||||
|
|
|
@ -247,9 +247,9 @@ bool VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
|
||||||
|
|
||||||
aVideoImage->SetDelayedConversion(true);
|
aVideoImage->SetDelayedConversion(true);
|
||||||
if (aCopyData) {
|
if (aCopyData) {
|
||||||
return aVideoImage->SetData(data);
|
return aVideoImage->CopyData(data);
|
||||||
} else {
|
} else {
|
||||||
return aVideoImage->SetDataNoCopy(data);
|
return aVideoImage->AdoptData(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,7 +480,7 @@ VideoData::Create(const VideoInfo& aInfo,
|
||||||
0));
|
0));
|
||||||
|
|
||||||
RefPtr<layers::GrallocImage> image = new layers::GrallocImage();
|
RefPtr<layers::GrallocImage> image = new layers::GrallocImage();
|
||||||
image->SetData(aBuffer, aPicture.Size());
|
image->AdoptData(aBuffer, aPicture.Size());
|
||||||
v->mImage = image;
|
v->mImage = image;
|
||||||
|
|
||||||
return v.forget();
|
return v.forget();
|
||||||
|
|
|
@ -688,11 +688,11 @@ private:
|
||||||
SeekJob mQueuedSeek;
|
SeekJob mQueuedSeek;
|
||||||
|
|
||||||
// mSeekTask is responsible for executing the current seek request.
|
// mSeekTask is responsible for executing the current seek request.
|
||||||
RefPtr<media::SeekTask> mSeekTask;
|
RefPtr<SeekTask> mSeekTask;
|
||||||
MozPromiseRequestHolder<media::SeekTask::SeekTaskPromise> mSeekTaskRequest;
|
MozPromiseRequestHolder<SeekTask::SeekTaskPromise> mSeekTaskRequest;
|
||||||
|
|
||||||
void OnSeekTaskResolved(media::SeekTaskResolveValue aValue);
|
void OnSeekTaskResolved(SeekTaskResolveValue aValue);
|
||||||
void OnSeekTaskRejected(media::SeekTaskRejectValue aValue);
|
void OnSeekTaskRejected(SeekTaskRejectValue aValue);
|
||||||
|
|
||||||
// Media Fragment end time in microseconds. Access controlled by decoder monitor.
|
// Media Fragment end time in microseconds. Access controlled by decoder monitor.
|
||||||
int64_t mFragmentEndTime;
|
int64_t mFragmentEndTime;
|
||||||
|
|
|
@ -890,7 +890,7 @@ SetImageToBlackPixel(PlanarYCbCrImage* aImage)
|
||||||
data.mCrChannel = blackPixel + 2;
|
data.mCrChannel = blackPixel + 2;
|
||||||
data.mYStride = data.mCbCrStride = 1;
|
data.mYStride = data.mCbCrStride = 1;
|
||||||
data.mPicSize = data.mYSize = data.mCbCrSize = IntSize(1, 1);
|
data.mPicSize = data.mYSize = data.mCbCrSize = IntSize(1, 1);
|
||||||
aImage->SetData(data);
|
aImage->CopyData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
class VideoFrameContainerInvalidateRunnable : public nsRunnable {
|
class VideoFrameContainerInvalidateRunnable : public nsRunnable {
|
||||||
|
|
|
@ -35,8 +35,6 @@ extern LazyLogModule gMediaSampleLog;
|
||||||
#define DECODER_WARN(x, ...) \
|
#define DECODER_WARN(x, ...) \
|
||||||
DECODER_WARN_HELPER(0, (nsPrintfCString("Decoder=%p " x, mDecoderID, ##__VA_ARGS__).get()))
|
DECODER_WARN_HELPER(0, (nsPrintfCString("Decoder=%p " x, mDecoderID, ##__VA_ARGS__).get()))
|
||||||
|
|
||||||
namespace media {
|
|
||||||
|
|
||||||
/*static*/ already_AddRefed<SeekTask>
|
/*static*/ already_AddRefed<SeekTask>
|
||||||
SeekTask::CreateSeekTask(const void* aDecoderID,
|
SeekTask::CreateSeekTask(const void* aDecoderID,
|
||||||
AbstractThread* aThread,
|
AbstractThread* aThread,
|
||||||
|
@ -725,5 +723,4 @@ SeekTask::OnVideoNotDecoded(MediaDecoderReader::NotDecodedReason aReason)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace media
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -17,8 +17,6 @@ class AbstractThread;
|
||||||
class MediaData;
|
class MediaData;
|
||||||
class MediaDecoderReaderWrapper;
|
class MediaDecoderReaderWrapper;
|
||||||
|
|
||||||
namespace media {
|
|
||||||
|
|
||||||
struct SeekTaskResolveValue
|
struct SeekTaskResolveValue
|
||||||
{
|
{
|
||||||
RefPtr<MediaData> mSeekedAudioData;
|
RefPtr<MediaData> mSeekedAudioData;
|
||||||
|
@ -178,7 +176,6 @@ protected:
|
||||||
bool mNeedToStopPrerollingVideo;
|
bool mNeedToStopPrerollingVideo;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace media
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif /* SEEK_TASK_H */
|
#endif /* SEEK_TASK_H */
|
||||||
|
|
|
@ -79,8 +79,8 @@ VideoFrame::CreateBlackImage(const gfx::IntSize& aSize)
|
||||||
data.mPicSize = gfx::IntSize(aSize.width, aSize.height);
|
data.mPicSize = gfx::IntSize(aSize.width, aSize.height);
|
||||||
data.mStereoMode = StereoMode::MONO;
|
data.mStereoMode = StereoMode::MONO;
|
||||||
|
|
||||||
// SetData copies data, so we can free data.
|
// Copies data, so we can free data.
|
||||||
if (!image->SetData(data)) {
|
if (!image->CopyData(data)) {
|
||||||
MOZ_ASSERT(false);
|
MOZ_ASSERT(false);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -421,7 +421,7 @@ AndroidMediaReader::ImageBufferCallback::CreateI420Image(size_t aWidth,
|
||||||
frameDesc.mPicY = 0;
|
frameDesc.mPicY = 0;
|
||||||
frameDesc.mPicSize = IntSize(aWidth, aHeight);
|
frameDesc.mPicSize = IntSize(aWidth, aHeight);
|
||||||
|
|
||||||
yuvImage->SetDataNoCopy(frameDesc);
|
yuvImage->AdoptData(frameDesc);
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ private:
|
||||||
data.mCbCrSize.width = halfWidth;
|
data.mCbCrSize.width = halfWidth;
|
||||||
data.mCbCrSize.height = halfHeight;
|
data.mCbCrSize.height = halfHeight;
|
||||||
|
|
||||||
image->SetData(data);
|
image->CopyData(data);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ private:
|
||||||
data.mCbCrSize.width = halfWidth;
|
data.mCbCrSize.width = halfWidth;
|
||||||
data.mCbCrSize.height = halfHeight;
|
data.mCbCrSize.height = halfHeight;
|
||||||
|
|
||||||
image->SetData(data);
|
image->CopyData(data);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ private:
|
||||||
data.mCbCrSize.width = halfWidth;
|
data.mCbCrSize.width = halfWidth;
|
||||||
data.mCbCrSize.height = halfHeight;
|
data.mCbCrSize.height = halfHeight;
|
||||||
|
|
||||||
image->SetData(data);
|
image->CopyData(data);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -489,7 +489,7 @@ OMXVideoEncoder::Encode(const Image* aImage, int aWidth, int aHeight,
|
||||||
NS_ENSURE_TRUE(aWidth == size.width, NS_ERROR_INVALID_ARG);
|
NS_ENSURE_TRUE(aWidth == size.width, NS_ERROR_INVALID_ARG);
|
||||||
NS_ENSURE_TRUE(aHeight == size.height, NS_ERROR_INVALID_ARG);
|
NS_ENSURE_TRUE(aHeight == size.height, NS_ERROR_INVALID_ARG);
|
||||||
if (format == ImageFormat::PLANAR_YCBCR) {
|
if (format == ImageFormat::PLANAR_YCBCR) {
|
||||||
// Test for data, allowing SetDataNoCopy() on an image without an mBuffer
|
// Test for data, allowing AdoptData() on an image without an mBuffer
|
||||||
// (as used from WebrtcOMXH264VideoCodec, and a few other places) - bug 1067442
|
// (as used from WebrtcOMXH264VideoCodec, and a few other places) - bug 1067442
|
||||||
const PlanarYCbCrData* yuv = static_cast<PlanarYCbCrImage*>(img)->GetData();
|
const PlanarYCbCrData* yuv = static_cast<PlanarYCbCrImage*>(img)->GetData();
|
||||||
NS_ENSURE_TRUE(yuv->mYChannel, NS_ERROR_INVALID_ARG);
|
NS_ENSURE_TRUE(yuv->mYChannel, NS_ERROR_INVALID_ARG);
|
||||||
|
|
|
@ -502,7 +502,7 @@ MediaCodecDataDecoder::QueueSample(const MediaRawData* aSample)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
mDurations.push(TimeUnit::FromMicroseconds(aSample->mDuration));
|
mDurations.push_back(TimeUnit::FromMicroseconds(aSample->mDuration));
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,7 +547,7 @@ MediaCodecDataDecoder::GetOutputDuration()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!mDurations.empty(), "Should have had a duration queued");
|
MOZ_ASSERT(!mDurations.empty(), "Should have had a duration queued");
|
||||||
const TimeUnit duration = mDurations.front();
|
const TimeUnit duration = mDurations.front();
|
||||||
mDurations.pop();
|
mDurations.pop_front();
|
||||||
return duration;
|
return duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,7 +600,7 @@ MediaCodecDataDecoder::DecoderLoop()
|
||||||
// We've fed this into the decoder, so remove it from the queue.
|
// We've fed this into the decoder, so remove it from the queue.
|
||||||
MonitorAutoLock lock(mMonitor);
|
MonitorAutoLock lock(mMonitor);
|
||||||
MOZ_RELEASE_ASSERT(mQueue.size(), "Queue may not be empty");
|
MOZ_RELEASE_ASSERT(mQueue.size(), "Queue may not be empty");
|
||||||
mQueue.pop();
|
mQueue.pop_front();
|
||||||
isOutputDone = false;
|
isOutputDone = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -698,28 +698,20 @@ MediaCodecDataDecoder::State(ModuleState aState)
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void
|
|
||||||
Clear(T& aCont)
|
|
||||||
{
|
|
||||||
T aEmpty = T();
|
|
||||||
swap(aCont, aEmpty);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaCodecDataDecoder::ClearQueue()
|
MediaCodecDataDecoder::ClearQueue()
|
||||||
{
|
{
|
||||||
mMonitor.AssertCurrentThreadOwns();
|
mMonitor.AssertCurrentThreadOwns();
|
||||||
|
|
||||||
Clear(mQueue);
|
mQueue.clear();
|
||||||
Clear(mDurations);
|
mDurations.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
MediaCodecDataDecoder::Input(MediaRawData* aSample)
|
MediaCodecDataDecoder::Input(MediaRawData* aSample)
|
||||||
{
|
{
|
||||||
MonitorAutoLock lock(mMonitor);
|
MonitorAutoLock lock(mMonitor);
|
||||||
mQueue.push(aSample);
|
mQueue.push_back(aSample);
|
||||||
lock.NotifyAll();
|
lock.NotifyAll();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -12,11 +12,11 @@
|
||||||
#include "TimeUnits.h"
|
#include "TimeUnits.h"
|
||||||
#include "mozilla/Monitor.h"
|
#include "mozilla/Monitor.h"
|
||||||
|
|
||||||
#include <queue>
|
#include <deque>
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
typedef std::queue<RefPtr<MediaRawData>> SampleQueue;
|
typedef std::deque<RefPtr<MediaRawData>> SampleQueue;
|
||||||
|
|
||||||
class AndroidDecoderModule : public PlatformDecoderModule {
|
class AndroidDecoderModule : public PlatformDecoderModule {
|
||||||
public:
|
public:
|
||||||
|
@ -134,7 +134,7 @@ protected:
|
||||||
|
|
||||||
SampleQueue mQueue;
|
SampleQueue mQueue;
|
||||||
// Durations are stored in microseconds.
|
// Durations are stored in microseconds.
|
||||||
std::queue<media::TimeUnit> mDurations;
|
std::deque<media::TimeUnit> mDurations;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -251,7 +251,7 @@ MediaEngineDefaultVideoSource::Notify(nsITimer* aTimer)
|
||||||
0, 0);
|
0, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool setData = ycbcr_image->SetData(data);
|
bool setData = ycbcr_image->CopyData(data);
|
||||||
MOZ_ASSERT(setData);
|
MOZ_ASSERT(setData);
|
||||||
|
|
||||||
// SetData copies data, so we can free the frame
|
// SetData copies data, so we can free the frame
|
||||||
|
|
|
@ -789,7 +789,7 @@ MediaEngineGonkVideoSource::RotateImage(layers::Image* aImage, uint32_t aWidth,
|
||||||
libyuv::FOURCC_NV21);
|
libyuv::FOURCC_NV21);
|
||||||
destBuffer->unlock();
|
destBuffer->unlock();
|
||||||
|
|
||||||
image->AsGrallocImage()->SetData(textureClient, gfx::IntSize(dstWidth, dstHeight));
|
image->AsGrallocImage()->AdoptData(textureClient, gfx::IntSize(dstWidth, dstHeight));
|
||||||
} else {
|
} else {
|
||||||
// Handle out of gralloc case.
|
// Handle out of gralloc case.
|
||||||
image = mImageContainer->CreatePlanarYCbCrImage();
|
image = mImageContainer->CreatePlanarYCbCrImage();
|
||||||
|
@ -821,7 +821,7 @@ MediaEngineGonkVideoSource::RotateImage(layers::Image* aImage, uint32_t aWidth,
|
||||||
data.mPicSize = IntSize(dstWidth, dstHeight);
|
data.mPicSize = IntSize(dstWidth, dstHeight);
|
||||||
data.mStereoMode = StereoMode::MONO;
|
data.mStereoMode = StereoMode::MONO;
|
||||||
|
|
||||||
image->AsPlanarYCbCrImage()->SetDataNoCopy(data);
|
image->AsPlanarYCbCrImage()->AdoptData(data);
|
||||||
}
|
}
|
||||||
graphicBuffer->unlock();
|
graphicBuffer->unlock();
|
||||||
|
|
||||||
|
|
|
@ -342,7 +342,7 @@ MediaEngineRemoteVideoSource::DeliverFrame(unsigned char* buffer,
|
||||||
data.mPicSize = IntSize(mWidth, mHeight);
|
data.mPicSize = IntSize(mWidth, mHeight);
|
||||||
data.mStereoMode = StereoMode::MONO;
|
data.mStereoMode = StereoMode::MONO;
|
||||||
|
|
||||||
if (!image->SetData(data)) {
|
if (!image->CopyData(data)) {
|
||||||
MOZ_ASSERT(false);
|
MOZ_ASSERT(false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2575,8 +2575,8 @@ public:
|
||||||
// This is coming from a ServiceWorkerRegistrationWorkerThread.
|
// This is coming from a ServiceWorkerRegistrationWorkerThread.
|
||||||
MOZ_ASSERT(registration);
|
MOZ_ASSERT(registration);
|
||||||
|
|
||||||
if (!registration->mActiveWorker ||
|
if (!registration->GetActive() ||
|
||||||
registration->mActiveWorker->ID() != mWorkerPrivate->ServiceWorkerID()) {
|
registration->GetActive()->ID() != mWorkerPrivate->ServiceWorkerID()) {
|
||||||
mRv = NS_ERROR_NOT_AVAILABLE;
|
mRv = NS_ERROR_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include "ServiceWorkerInfo.h"
|
#include "ServiceWorkerInfo.h"
|
||||||
|
|
||||||
|
#include "ServiceWorkerScriptCache.h"
|
||||||
|
|
||||||
BEGIN_WORKERS_NAMESPACE
|
BEGIN_WORKERS_NAMESPACE
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(ServiceWorkerInfo, nsIServiceWorkerInfo)
|
NS_IMPL_ISUPPORTS(ServiceWorkerInfo, nsIServiceWorkerInfo)
|
||||||
|
@ -139,6 +141,9 @@ ServiceWorkerInfo::UpdateState(ServiceWorkerState aState)
|
||||||
mState = aState;
|
mState = aState;
|
||||||
nsCOMPtr<nsIRunnable> r = new ChangeStateUpdater(mInstances, mState);
|
nsCOMPtr<nsIRunnable> r = new ChangeStateUpdater(mInstances, mState);
|
||||||
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r.forget()));
|
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r.forget()));
|
||||||
|
if (mState == ServiceWorkerState::Redundant) {
|
||||||
|
serviceWorkerScriptCache::PurgeCache(mPrincipal, mCacheName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceWorkerInfo::ServiceWorkerInfo(nsIPrincipal* aPrincipal,
|
ServiceWorkerInfo::ServiceWorkerInfo(nsIPrincipal* aPrincipal,
|
||||||
|
|
|
@ -182,9 +182,9 @@ PopulateRegistrationData(nsIPrincipal* aPrincipal,
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aRegistration->mActiveWorker) {
|
if (aRegistration->GetActive()) {
|
||||||
aData.currentWorkerURL() = aRegistration->mActiveWorker->ScriptSpec();
|
aData.currentWorkerURL() = aRegistration->GetActive()->ScriptSpec();
|
||||||
aData.cacheName() = aRegistration->mActiveWorker->CacheName();
|
aData.cacheName() = aRegistration->GetActive()->CacheName();
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -1181,7 +1181,7 @@ ServiceWorkerManager::CheckReadyPromise(nsPIDOMWindowInner* aWindow,
|
||||||
RefPtr<ServiceWorkerRegistrationInfo> registration =
|
RefPtr<ServiceWorkerRegistrationInfo> registration =
|
||||||
GetServiceWorkerRegistrationInfo(principal, aURI);
|
GetServiceWorkerRegistrationInfo(principal, aURI);
|
||||||
|
|
||||||
if (registration && registration->mActiveWorker) {
|
if (registration && registration->GetActive()) {
|
||||||
NS_ConvertUTF8toUTF16 scope(registration->mScope);
|
NS_ConvertUTF8toUTF16 scope(registration->mScope);
|
||||||
RefPtr<ServiceWorkerRegistrationMainThread> swr =
|
RefPtr<ServiceWorkerRegistrationMainThread> swr =
|
||||||
aWindow->GetServiceWorkerRegistration(scope);
|
aWindow->GetServiceWorkerRegistration(scope);
|
||||||
|
@ -1211,7 +1211,7 @@ ServiceWorkerManager::GetActiveWorkerInfoForScope(const PrincipalOriginAttribute
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return registration->mActiveWorker;
|
return registration->GetActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceWorkerInfo*
|
ServiceWorkerInfo*
|
||||||
|
@ -1226,7 +1226,7 @@ ServiceWorkerManager::GetActiveWorkerInfoForDocument(nsIDocument* aDocument)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return registration->mActiveWorker;
|
return registration->GetActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -1601,8 +1601,8 @@ ServiceWorkerManager::LoadRegistration(
|
||||||
} else {
|
} else {
|
||||||
// If active worker script matches our expectations for a "current worker",
|
// If active worker script matches our expectations for a "current worker",
|
||||||
// then we are done.
|
// then we are done.
|
||||||
if (registration->mActiveWorker &&
|
if (registration->GetActive() &&
|
||||||
registration->mActiveWorker->ScriptSpec() == aRegistration.currentWorkerURL()) {
|
registration->GetActive()->ScriptSpec() == aRegistration.currentWorkerURL()) {
|
||||||
// No needs for updates.
|
// No needs for updates.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1610,10 +1610,10 @@ ServiceWorkerManager::LoadRegistration(
|
||||||
|
|
||||||
const nsCString& currentWorkerURL = aRegistration.currentWorkerURL();
|
const nsCString& currentWorkerURL = aRegistration.currentWorkerURL();
|
||||||
if (!currentWorkerURL.IsEmpty()) {
|
if (!currentWorkerURL.IsEmpty()) {
|
||||||
registration->mActiveWorker =
|
registration->SetActive(
|
||||||
new ServiceWorkerInfo(registration->mPrincipal, registration->mScope,
|
new ServiceWorkerInfo(registration->mPrincipal, registration->mScope,
|
||||||
currentWorkerURL, aRegistration.cacheName());
|
currentWorkerURL, aRegistration.cacheName()));
|
||||||
registration->mActiveWorker->SetActivateStateUncheckedWithoutEvent(ServiceWorkerState::Activated);
|
registration->GetActive()->SetActivateStateUncheckedWithoutEvent(ServiceWorkerState::Activated);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2023,9 +2023,9 @@ ServiceWorkerManager::StopControllingADocument(ServiceWorkerRegistrationInfo* aR
|
||||||
} else {
|
} else {
|
||||||
// If the registration has an active worker that is running
|
// If the registration has an active worker that is running
|
||||||
// this might be a good time to stop it.
|
// this might be a good time to stop it.
|
||||||
if (aRegistration->mActiveWorker) {
|
if (aRegistration->GetActive()) {
|
||||||
ServiceWorkerPrivate* serviceWorkerPrivate =
|
ServiceWorkerPrivate* serviceWorkerPrivate =
|
||||||
aRegistration->mActiveWorker->WorkerPrivate();
|
aRegistration->GetActive()->WorkerPrivate();
|
||||||
serviceWorkerPrivate->NoteStoppedControllingDocuments();
|
serviceWorkerPrivate->NoteStoppedControllingDocuments();
|
||||||
}
|
}
|
||||||
aRegistration->TryToActivateAsync();
|
aRegistration->TryToActivateAsync();
|
||||||
|
@ -2158,11 +2158,11 @@ ServiceWorkerManager::GetServiceWorkerForScope(nsPIDOMWindowInner* aWindow,
|
||||||
|
|
||||||
RefPtr<ServiceWorkerInfo> info;
|
RefPtr<ServiceWorkerInfo> info;
|
||||||
if (aWhichWorker == WhichServiceWorker::INSTALLING_WORKER) {
|
if (aWhichWorker == WhichServiceWorker::INSTALLING_WORKER) {
|
||||||
info = registration->mInstallingWorker;
|
info = registration->GetInstalling();
|
||||||
} else if (aWhichWorker == WhichServiceWorker::WAITING_WORKER) {
|
} else if (aWhichWorker == WhichServiceWorker::WAITING_WORKER) {
|
||||||
info = registration->mWaitingWorker;
|
info = registration->GetWaiting();
|
||||||
} else if (aWhichWorker == WhichServiceWorker::ACTIVE_WORKER) {
|
} else if (aWhichWorker == WhichServiceWorker::ACTIVE_WORKER) {
|
||||||
info = registration->mActiveWorker;
|
info = registration->GetActive();
|
||||||
} else {
|
} else {
|
||||||
MOZ_CRASH("Invalid worker type");
|
MOZ_CRASH("Invalid worker type");
|
||||||
}
|
}
|
||||||
|
@ -2301,8 +2301,8 @@ ServiceWorkerManager::DispatchFetchEvent(const PrincipalOriginAttributes& aOrigi
|
||||||
}
|
}
|
||||||
|
|
||||||
// This should only happen if IsAvailable() returned true.
|
// This should only happen if IsAvailable() returned true.
|
||||||
MOZ_ASSERT(registration->mActiveWorker);
|
MOZ_ASSERT(registration->GetActive());
|
||||||
serviceWorker = registration->mActiveWorker;
|
serviceWorker = registration->GetActive();
|
||||||
|
|
||||||
AddNavigationInterception(serviceWorker->Scope(), aChannel);
|
AddNavigationInterception(serviceWorker->Scope(), aChannel);
|
||||||
}
|
}
|
||||||
|
@ -2343,7 +2343,7 @@ ServiceWorkerManager::IsAvailable(nsIPrincipal* aPrincipal,
|
||||||
|
|
||||||
RefPtr<ServiceWorkerRegistrationInfo> registration =
|
RefPtr<ServiceWorkerRegistrationInfo> registration =
|
||||||
GetServiceWorkerRegistrationInfo(aPrincipal, aURI);
|
GetServiceWorkerRegistrationInfo(aPrincipal, aURI);
|
||||||
return registration && registration->mActiveWorker;
|
return registration && registration->GetActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -2378,7 +2378,7 @@ ServiceWorkerManager::GetDocumentRegistration(nsIDocument* aDoc,
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the document is controlled, the current worker MUST be non-null.
|
// If the document is controlled, the current worker MUST be non-null.
|
||||||
if (!registration->mActiveWorker) {
|
if (!registration->GetActive()) {
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2406,9 +2406,9 @@ ServiceWorkerManager::GetDocumentController(nsPIDOMWindowInner* aWindow,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(registration->mActiveWorker);
|
MOZ_ASSERT(registration->GetActive());
|
||||||
RefPtr<ServiceWorker> serviceWorker =
|
RefPtr<ServiceWorker> serviceWorker =
|
||||||
registration->mActiveWorker->GetOrCreateInstance(aWindow);
|
registration->GetActive()->GetOrCreateInstance(aWindow);
|
||||||
|
|
||||||
serviceWorker.forget(aServiceWorker);
|
serviceWorker.forget(aServiceWorker);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -2523,7 +2523,7 @@ ServiceWorkerManager::SoftUpdate(const PrincipalOriginAttributes& aOriginAttribu
|
||||||
}
|
}
|
||||||
|
|
||||||
// "If registration's installing worker is not null, abort these steps."
|
// "If registration's installing worker is not null, abort these steps."
|
||||||
if (registration->mInstallingWorker) {
|
if (registration->GetInstalling()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2794,7 +2794,7 @@ ServiceWorkerManager::MaybeClaimClient(nsIDocument* aDocument,
|
||||||
ServiceWorkerRegistrationInfo* aWorkerRegistration)
|
ServiceWorkerRegistrationInfo* aWorkerRegistration)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aWorkerRegistration);
|
MOZ_ASSERT(aWorkerRegistration);
|
||||||
MOZ_ASSERT(aWorkerRegistration->mActiveWorker);
|
MOZ_ASSERT(aWorkerRegistration->GetActive());
|
||||||
|
|
||||||
// Same origin check
|
// Same origin check
|
||||||
if (!aWorkerRegistration->mPrincipal->Equals(aDocument->NodePrincipal())) {
|
if (!aWorkerRegistration->mPrincipal->Equals(aDocument->NodePrincipal())) {
|
||||||
|
@ -2829,8 +2829,8 @@ ServiceWorkerManager::ClaimClients(nsIPrincipal* aPrincipal,
|
||||||
RefPtr<ServiceWorkerRegistrationInfo> registration =
|
RefPtr<ServiceWorkerRegistrationInfo> registration =
|
||||||
GetRegistration(aPrincipal, aScope);
|
GetRegistration(aPrincipal, aScope);
|
||||||
|
|
||||||
if (!registration || !registration->mActiveWorker ||
|
if (!registration || !registration->GetActive() ||
|
||||||
!(registration->mActiveWorker->ID() == aId)) {
|
!(registration->GetActive()->ID() == aId)) {
|
||||||
// The worker is not active.
|
// The worker is not active.
|
||||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||||
}
|
}
|
||||||
|
@ -2855,13 +2855,13 @@ ServiceWorkerManager::SetSkipWaitingFlag(nsIPrincipal* aPrincipal,
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (registration->mInstallingWorker &&
|
if (registration->GetInstalling() &&
|
||||||
(registration->mInstallingWorker->ID() == aServiceWorkerID)) {
|
(registration->GetInstalling()->ID() == aServiceWorkerID)) {
|
||||||
registration->mInstallingWorker->SetSkipWaitingFlag();
|
registration->GetInstalling()->SetSkipWaitingFlag();
|
||||||
} else if (registration->mWaitingWorker &&
|
} else if (registration->GetWaiting() &&
|
||||||
(registration->mWaitingWorker->ID() == aServiceWorkerID)) {
|
(registration->GetWaiting()->ID() == aServiceWorkerID)) {
|
||||||
registration->mWaitingWorker->SetSkipWaitingFlag();
|
registration->GetWaiting()->SetSkipWaitingFlag();
|
||||||
if (registration->mWaitingWorker->State() == ServiceWorkerState::Installed) {
|
if (registration->GetWaiting()->State() == ServiceWorkerState::Installed) {
|
||||||
registration->TryToActivateAsync();
|
registration->TryToActivateAsync();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -20,36 +20,19 @@ ServiceWorkerRegistrationInfo::Clear()
|
||||||
|
|
||||||
if (mWaitingWorker) {
|
if (mWaitingWorker) {
|
||||||
mWaitingWorker->UpdateState(ServiceWorkerState::Redundant);
|
mWaitingWorker->UpdateState(ServiceWorkerState::Redundant);
|
||||||
|
|
||||||
nsresult rv = serviceWorkerScriptCache::PurgeCache(mPrincipal,
|
|
||||||
mWaitingWorker->CacheName());
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
NS_WARNING("Failed to purge the waiting cache.");
|
|
||||||
}
|
|
||||||
|
|
||||||
mWaitingWorker->WorkerPrivate()->NoteDeadServiceWorkerInfo();
|
mWaitingWorker->WorkerPrivate()->NoteDeadServiceWorkerInfo();
|
||||||
mWaitingWorker = nullptr;
|
mWaitingWorker = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mActiveWorker) {
|
if (mActiveWorker) {
|
||||||
mActiveWorker->UpdateState(ServiceWorkerState::Redundant);
|
mActiveWorker->UpdateState(ServiceWorkerState::Redundant);
|
||||||
|
|
||||||
nsresult rv = serviceWorkerScriptCache::PurgeCache(mPrincipal,
|
|
||||||
mActiveWorker->CacheName());
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
NS_WARNING("Failed to purge the active cache.");
|
|
||||||
}
|
|
||||||
|
|
||||||
mActiveWorker->WorkerPrivate()->NoteDeadServiceWorkerInfo();
|
mActiveWorker->WorkerPrivate()->NoteDeadServiceWorkerInfo();
|
||||||
mActiveWorker = nullptr;
|
mActiveWorker = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
NotifyListenersOnChange(WhichServiceWorker::INSTALLING_WORKER |
|
||||||
MOZ_ASSERT(swm);
|
WhichServiceWorker::WAITING_WORKER |
|
||||||
swm->InvalidateServiceWorkerRegistrationWorker(this,
|
WhichServiceWorker::ACTIVE_WORKER);
|
||||||
WhichServiceWorker::INSTALLING_WORKER |
|
|
||||||
WhichServiceWorker::WAITING_WORKER |
|
|
||||||
WhichServiceWorker::ACTIVE_WORKER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceWorkerRegistrationInfo::ServiceWorkerRegistrationInfo(const nsACString& aScope,
|
ServiceWorkerRegistrationInfo::ServiceWorkerRegistrationInfo(const nsACString& aScope,
|
||||||
|
@ -204,44 +187,18 @@ ServiceWorkerRegistrationInfo::TryToActivate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ServiceWorkerRegistrationInfo::PurgeActiveWorker()
|
|
||||||
{
|
|
||||||
RefPtr<ServiceWorkerInfo> exitingWorker = mActiveWorker.forget();
|
|
||||||
if (!exitingWorker)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// FIXME(jaoo): Bug 1170543 - Wait for exitingWorker to finish and terminate it.
|
|
||||||
exitingWorker->UpdateState(ServiceWorkerState::Redundant);
|
|
||||||
nsresult rv = serviceWorkerScriptCache::PurgeCache(mPrincipal,
|
|
||||||
exitingWorker->CacheName());
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
NS_WARNING("Failed to purge the activating cache.");
|
|
||||||
}
|
|
||||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
|
||||||
swm->InvalidateServiceWorkerRegistrationWorker(this, WhichServiceWorker::ACTIVE_WORKER);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorkerRegistrationInfo::Activate()
|
ServiceWorkerRegistrationInfo::Activate()
|
||||||
{
|
{
|
||||||
RefPtr<ServiceWorkerInfo> activatingWorker = mWaitingWorker;
|
if (!mWaitingWorker) {
|
||||||
if (!activatingWorker) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PurgeActiveWorker();
|
TransitionWaitingToActive();
|
||||||
|
|
||||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
|
||||||
swm->InvalidateServiceWorkerRegistrationWorker(this, WhichServiceWorker::WAITING_WORKER);
|
|
||||||
|
|
||||||
mActiveWorker = activatingWorker.forget();
|
|
||||||
mWaitingWorker = nullptr;
|
|
||||||
mActiveWorker->UpdateState(ServiceWorkerState::Activating);
|
|
||||||
NotifyListenersOnChange();
|
|
||||||
|
|
||||||
// FIXME(nsm): Unlink appcache if there is one.
|
// FIXME(nsm): Unlink appcache if there is one.
|
||||||
|
|
||||||
|
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||||
swm->CheckPendingReadyPromises();
|
swm->CheckPendingReadyPromises();
|
||||||
|
|
||||||
// "Queue a task to fire a simple event named controllerchange..."
|
// "Queue a task to fire a simple event named controllerchange..."
|
||||||
|
@ -311,8 +268,16 @@ ServiceWorkerRegistrationInfo::IsLastUpdateCheckTimeOverOneDay() const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServiceWorkerRegistrationInfo::NotifyListenersOnChange()
|
ServiceWorkerRegistrationInfo::NotifyListenersOnChange(WhichServiceWorker aChangedWorkers)
|
||||||
{
|
{
|
||||||
|
AssertIsOnMainThread();
|
||||||
|
MOZ_ASSERT(aChangedWorkers & (WhichServiceWorker::INSTALLING_WORKER |
|
||||||
|
WhichServiceWorker::WAITING_WORKER |
|
||||||
|
WhichServiceWorker::ACTIVE_WORKER));
|
||||||
|
|
||||||
|
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||||
|
swm->InvalidateServiceWorkerRegistrationWorker(this, aChangedWorkers);
|
||||||
|
|
||||||
nsTArray<nsCOMPtr<nsIServiceWorkerRegistrationInfoListener>> listeners(mListeners);
|
nsTArray<nsCOMPtr<nsIServiceWorkerRegistrationInfoListener>> listeners(mListeners);
|
||||||
for (size_t index = 0; index < listeners.Length(); ++index) {
|
for (size_t index = 0; index < listeners.Length(); ++index) {
|
||||||
listeners[index]->OnChange();
|
listeners[index]->OnChange();
|
||||||
|
@ -367,4 +332,119 @@ ServiceWorkerRegistrationInfo::CheckAndClearIfUpdateNeeded()
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServiceWorkerInfo*
|
||||||
|
ServiceWorkerRegistrationInfo::GetInstalling() const
|
||||||
|
{
|
||||||
|
AssertIsOnMainThread();
|
||||||
|
return mInstallingWorker;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServiceWorkerInfo*
|
||||||
|
ServiceWorkerRegistrationInfo::GetWaiting() const
|
||||||
|
{
|
||||||
|
AssertIsOnMainThread();
|
||||||
|
return mWaitingWorker;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServiceWorkerInfo*
|
||||||
|
ServiceWorkerRegistrationInfo::GetActive() const
|
||||||
|
{
|
||||||
|
AssertIsOnMainThread();
|
||||||
|
return mActiveWorker;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServiceWorkerRegistrationInfo::ClearInstalling()
|
||||||
|
{
|
||||||
|
AssertIsOnMainThread();
|
||||||
|
|
||||||
|
if (!mInstallingWorker) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mInstallingWorker->UpdateState(ServiceWorkerState::Redundant);
|
||||||
|
mInstallingWorker = nullptr;
|
||||||
|
NotifyListenersOnChange(WhichServiceWorker::INSTALLING_WORKER);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServiceWorkerRegistrationInfo::SetInstalling(ServiceWorkerInfo* aServiceWorker)
|
||||||
|
{
|
||||||
|
AssertIsOnMainThread();
|
||||||
|
MOZ_ASSERT(aServiceWorker);
|
||||||
|
MOZ_ASSERT(!mInstallingWorker);
|
||||||
|
MOZ_ASSERT(mWaitingWorker != aServiceWorker);
|
||||||
|
MOZ_ASSERT(mActiveWorker != aServiceWorker);
|
||||||
|
|
||||||
|
mInstallingWorker = aServiceWorker;
|
||||||
|
mInstallingWorker->UpdateState(ServiceWorkerState::Installing);
|
||||||
|
NotifyListenersOnChange(WhichServiceWorker::INSTALLING_WORKER);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServiceWorkerRegistrationInfo::TransitionInstallingToWaiting()
|
||||||
|
{
|
||||||
|
AssertIsOnMainThread();
|
||||||
|
MOZ_ASSERT(mInstallingWorker);
|
||||||
|
|
||||||
|
if (mWaitingWorker) {
|
||||||
|
MOZ_ASSERT(mInstallingWorker->CacheName() != mWaitingWorker->CacheName());
|
||||||
|
mWaitingWorker->UpdateState(ServiceWorkerState::Redundant);
|
||||||
|
}
|
||||||
|
|
||||||
|
mWaitingWorker = mInstallingWorker.forget();
|
||||||
|
mWaitingWorker->UpdateState(ServiceWorkerState::Installed);
|
||||||
|
NotifyListenersOnChange(WhichServiceWorker::INSTALLING_WORKER |
|
||||||
|
WhichServiceWorker::WAITING_WORKER);
|
||||||
|
|
||||||
|
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||||
|
swm->StoreRegistration(mPrincipal, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServiceWorkerRegistrationInfo::SetActive(ServiceWorkerInfo* aServiceWorker)
|
||||||
|
{
|
||||||
|
AssertIsOnMainThread();
|
||||||
|
MOZ_ASSERT(aServiceWorker);
|
||||||
|
|
||||||
|
// TODO: Assert installing, waiting, and active are nullptr once the SWM
|
||||||
|
// moves to the parent process. After that happens this code will
|
||||||
|
// only run for browser initialization and not for cross-process
|
||||||
|
// overrides.
|
||||||
|
MOZ_ASSERT(mInstallingWorker != aServiceWorker);
|
||||||
|
MOZ_ASSERT(mWaitingWorker != aServiceWorker);
|
||||||
|
MOZ_ASSERT(mActiveWorker != aServiceWorker);
|
||||||
|
|
||||||
|
if (mActiveWorker) {
|
||||||
|
MOZ_ASSERT(aServiceWorker->CacheName() != mActiveWorker->CacheName());
|
||||||
|
mActiveWorker->UpdateState(ServiceWorkerState::Redundant);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The active worker is being overriden due to initial load or
|
||||||
|
// another process activating a worker. Move straight to the
|
||||||
|
// Activated state.
|
||||||
|
mActiveWorker = aServiceWorker;
|
||||||
|
mActiveWorker->SetActivateStateUncheckedWithoutEvent(ServiceWorkerState::Activated);
|
||||||
|
NotifyListenersOnChange(WhichServiceWorker::ACTIVE_WORKER);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ServiceWorkerRegistrationInfo::TransitionWaitingToActive()
|
||||||
|
{
|
||||||
|
AssertIsOnMainThread();
|
||||||
|
MOZ_ASSERT(mWaitingWorker);
|
||||||
|
|
||||||
|
if (mActiveWorker) {
|
||||||
|
MOZ_ASSERT(mWaitingWorker->CacheName() != mActiveWorker->CacheName());
|
||||||
|
mActiveWorker->UpdateState(ServiceWorkerState::Redundant);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are transitioning from waiting to active normally, so go to
|
||||||
|
// the activating state.
|
||||||
|
mActiveWorker = mWaitingWorker.forget();
|
||||||
|
mActiveWorker->UpdateState(ServiceWorkerState::Activating);
|
||||||
|
NotifyListenersOnChange(WhichServiceWorker::WAITING_WORKER |
|
||||||
|
WhichServiceWorker::ACTIVE_WORKER);
|
||||||
|
}
|
||||||
|
|
||||||
END_WORKERS_NAMESPACE
|
END_WORKERS_NAMESPACE
|
||||||
|
|
|
@ -27,20 +27,20 @@ class ServiceWorkerRegistrationInfo final
|
||||||
|
|
||||||
uint64_t mLastUpdateCheckTime;
|
uint64_t mLastUpdateCheckTime;
|
||||||
|
|
||||||
|
RefPtr<ServiceWorkerInfo> mActiveWorker;
|
||||||
|
RefPtr<ServiceWorkerInfo> mWaitingWorker;
|
||||||
|
RefPtr<ServiceWorkerInfo> mInstallingWorker;
|
||||||
|
|
||||||
virtual ~ServiceWorkerRegistrationInfo();
|
virtual ~ServiceWorkerRegistrationInfo();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSISERVICEWORKERREGISTRATIONINFO
|
NS_DECL_NSISERVICEWORKERREGISTRATIONINFO
|
||||||
|
|
||||||
nsCString mScope;
|
const nsCString mScope;
|
||||||
|
|
||||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||||
|
|
||||||
RefPtr<ServiceWorkerInfo> mActiveWorker;
|
|
||||||
RefPtr<ServiceWorkerInfo> mWaitingWorker;
|
|
||||||
RefPtr<ServiceWorkerInfo> mInstallingWorker;
|
|
||||||
|
|
||||||
nsTArray<nsCOMPtr<nsIServiceWorkerRegistrationInfoListener>> mListeners;
|
nsTArray<nsCOMPtr<nsIServiceWorkerRegistrationInfoListener>> mListeners;
|
||||||
|
|
||||||
// When unregister() is called on a registration, it is not immediately
|
// When unregister() is called on a registration, it is not immediately
|
||||||
|
@ -91,9 +91,6 @@ public:
|
||||||
void
|
void
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
void
|
|
||||||
PurgeActiveWorker();
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TryToActivateAsync();
|
TryToActivateAsync();
|
||||||
|
|
||||||
|
@ -113,7 +110,7 @@ public:
|
||||||
IsLastUpdateCheckTimeOverOneDay() const;
|
IsLastUpdateCheckTimeOverOneDay() const;
|
||||||
|
|
||||||
void
|
void
|
||||||
NotifyListenersOnChange();
|
NotifyListenersOnChange(WhichServiceWorker aChangedWorkers);
|
||||||
|
|
||||||
void
|
void
|
||||||
MaybeScheduleTimeCheckAndUpdate();
|
MaybeScheduleTimeCheckAndUpdate();
|
||||||
|
@ -123,6 +120,44 @@ public:
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CheckAndClearIfUpdateNeeded();
|
CheckAndClearIfUpdateNeeded();
|
||||||
|
|
||||||
|
ServiceWorkerInfo*
|
||||||
|
GetInstalling() const;
|
||||||
|
|
||||||
|
ServiceWorkerInfo*
|
||||||
|
GetWaiting() const;
|
||||||
|
|
||||||
|
ServiceWorkerInfo*
|
||||||
|
GetActive() const;
|
||||||
|
|
||||||
|
// Remove an existing installing worker, if present. The worker will
|
||||||
|
// be transitioned to the Redundant state.
|
||||||
|
void
|
||||||
|
ClearInstalling();
|
||||||
|
|
||||||
|
// Set a new installing worker. This may only be called if there is no
|
||||||
|
// existing installing worker. The worker is transitioned to the Installing
|
||||||
|
// state.
|
||||||
|
void
|
||||||
|
SetInstalling(ServiceWorkerInfo* aServiceWorker);
|
||||||
|
|
||||||
|
// Transition the current installing worker to be the waiting worker. The
|
||||||
|
// workers state is updated to Installed.
|
||||||
|
void
|
||||||
|
TransitionInstallingToWaiting();
|
||||||
|
|
||||||
|
// Override the current active worker. This is used during browser
|
||||||
|
// initialization to load persisted workers. Its also used to propagate
|
||||||
|
// active workers across child processes in e10s. This second use will
|
||||||
|
// go away once the ServiceWorkerManager moves to the parent process.
|
||||||
|
// The worker is transitioned to the Activated state.
|
||||||
|
void
|
||||||
|
SetActive(ServiceWorkerInfo* aServiceWorker);
|
||||||
|
|
||||||
|
// Transition the current waiting worker to be the new active worker. The
|
||||||
|
// worker is updated to the Activating state.
|
||||||
|
void
|
||||||
|
TransitionWaitingToActive();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace workers
|
} // namespace workers
|
||||||
|
|
|
@ -150,19 +150,9 @@ ServiceWorkerUpdateJob::FailUpdateJob(ErrorResult& aRv)
|
||||||
mServiceWorker->CacheName());
|
mServiceWorker->CacheName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mRegistration->ClearInstalling();
|
||||||
|
|
||||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||||
|
|
||||||
if (mRegistration->mInstallingWorker) {
|
|
||||||
mRegistration->mInstallingWorker->UpdateState(ServiceWorkerState::Redundant);
|
|
||||||
serviceWorkerScriptCache::PurgeCache(mRegistration->mPrincipal,
|
|
||||||
mRegistration->mInstallingWorker->CacheName());
|
|
||||||
mRegistration->mInstallingWorker = nullptr;
|
|
||||||
if (swm) {
|
|
||||||
swm->InvalidateServiceWorkerRegistrationWorker(mRegistration,
|
|
||||||
WhichServiceWorker::INSTALLING_WORKER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (swm) {
|
if (swm) {
|
||||||
swm->MaybeRemoveRegistration(mRegistration);
|
swm->MaybeRemoveRegistration(mRegistration);
|
||||||
}
|
}
|
||||||
|
@ -242,7 +232,7 @@ ServiceWorkerUpdateJob::Update()
|
||||||
|
|
||||||
// SetRegistration() must be called before Update().
|
// SetRegistration() must be called before Update().
|
||||||
MOZ_ASSERT(mRegistration);
|
MOZ_ASSERT(mRegistration);
|
||||||
MOZ_ASSERT(!mRegistration->mInstallingWorker);
|
MOZ_ASSERT(!mRegistration->GetInstalling());
|
||||||
|
|
||||||
// Begin the script download and comparison steps starting at step 5
|
// Begin the script download and comparison steps starting at step 5
|
||||||
// of the Update algorithm.
|
// of the Update algorithm.
|
||||||
|
@ -413,20 +403,15 @@ ServiceWorkerUpdateJob::Install()
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
MOZ_ASSERT(!Canceled());
|
MOZ_ASSERT(!Canceled());
|
||||||
|
|
||||||
MOZ_ASSERT(!mRegistration->mInstallingWorker);
|
MOZ_ASSERT(!mRegistration->GetInstalling());
|
||||||
|
|
||||||
// Begin step 2 of the Install algorithm.
|
// Begin step 2 of the Install algorithm.
|
||||||
//
|
//
|
||||||
// https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#installation-algorithm
|
// https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#installation-algorithm
|
||||||
|
|
||||||
MOZ_ASSERT(mServiceWorker);
|
MOZ_ASSERT(mServiceWorker);
|
||||||
mRegistration->mInstallingWorker = mServiceWorker.forget();
|
mRegistration->SetInstalling(mServiceWorker);
|
||||||
mRegistration->mInstallingWorker->UpdateState(ServiceWorkerState::Installing);
|
mServiceWorker = nullptr;
|
||||||
mRegistration->NotifyListenersOnChange();
|
|
||||||
|
|
||||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
|
||||||
swm->InvalidateServiceWorkerRegistrationWorker(mRegistration,
|
|
||||||
WhichServiceWorker::INSTALLING_WORKER);
|
|
||||||
|
|
||||||
// Step 6 of the Install algorithm resolving the job promise.
|
// Step 6 of the Install algorithm resolving the job promise.
|
||||||
InvokeResultCallbacks(NS_OK);
|
InvokeResultCallbacks(NS_OK);
|
||||||
|
@ -434,6 +419,8 @@ ServiceWorkerUpdateJob::Install()
|
||||||
// The job promise cannot be rejected after this point, but the job can
|
// The job promise cannot be rejected after this point, but the job can
|
||||||
// still fail; e.g. if the install event handler throws, etc.
|
// still fail; e.g. if the install event handler throws, etc.
|
||||||
|
|
||||||
|
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||||
|
|
||||||
// fire the updatefound event
|
// fire the updatefound event
|
||||||
nsCOMPtr<nsIRunnable> upr =
|
nsCOMPtr<nsIRunnable> upr =
|
||||||
NS_NewRunnableMethodWithArg<RefPtr<ServiceWorkerRegistrationInfo>>(
|
NS_NewRunnableMethodWithArg<RefPtr<ServiceWorkerRegistrationInfo>>(
|
||||||
|
@ -453,7 +440,7 @@ ServiceWorkerUpdateJob::Install()
|
||||||
|
|
||||||
// Send the install event to the worker thread
|
// Send the install event to the worker thread
|
||||||
ServiceWorkerPrivate* workerPrivate =
|
ServiceWorkerPrivate* workerPrivate =
|
||||||
mRegistration->mInstallingWorker->WorkerPrivate();
|
mRegistration->GetInstalling()->WorkerPrivate();
|
||||||
nsresult rv = workerPrivate->SendLifeCycleEvent(NS_LITERAL_STRING("install"),
|
nsresult rv = workerPrivate->SendLifeCycleEvent(NS_LITERAL_STRING("install"),
|
||||||
callback, failRunnable);
|
callback, failRunnable);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
@ -468,9 +455,7 @@ ServiceWorkerUpdateJob::ContinueAfterInstallEvent(bool aInstallEventSuccess)
|
||||||
return FailUpdateJob(NS_ERROR_DOM_ABORT_ERR);
|
return FailUpdateJob(NS_ERROR_DOM_ABORT_ERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(mRegistration->mInstallingWorker);
|
MOZ_ASSERT(mRegistration->GetInstalling());
|
||||||
|
|
||||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
|
||||||
|
|
||||||
// Continue executing the Install algorithm at step 12.
|
// Continue executing the Install algorithm at step 12.
|
||||||
|
|
||||||
|
@ -481,21 +466,7 @@ ServiceWorkerUpdateJob::ContinueAfterInstallEvent(bool aInstallEventSuccess)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// "If registration's waiting worker is not null"
|
mRegistration->TransitionInstallingToWaiting();
|
||||||
if (mRegistration->mWaitingWorker) {
|
|
||||||
mRegistration->mWaitingWorker->WorkerPrivate()->TerminateWorker();
|
|
||||||
mRegistration->mWaitingWorker->UpdateState(ServiceWorkerState::Redundant);
|
|
||||||
serviceWorkerScriptCache::PurgeCache(mRegistration->mPrincipal,
|
|
||||||
mRegistration->mWaitingWorker->CacheName());
|
|
||||||
}
|
|
||||||
|
|
||||||
mRegistration->mWaitingWorker = mRegistration->mInstallingWorker.forget();
|
|
||||||
mRegistration->mWaitingWorker->UpdateState(ServiceWorkerState::Installed);
|
|
||||||
mRegistration->NotifyListenersOnChange();
|
|
||||||
swm->StoreRegistration(mPrincipal, mRegistration);
|
|
||||||
swm->InvalidateServiceWorkerRegistrationWorker(mRegistration,
|
|
||||||
WhichServiceWorker::INSTALLING_WORKER |
|
|
||||||
WhichServiceWorker::WAITING_WORKER);
|
|
||||||
|
|
||||||
Finish(NS_OK);
|
Finish(NS_OK);
|
||||||
|
|
||||||
|
|
|
@ -829,7 +829,7 @@ DrawTargetCairo::DrawSurface(SourceSurface *aSurface,
|
||||||
const DrawSurfaceOptions &aSurfOptions,
|
const DrawSurfaceOptions &aSurfOptions,
|
||||||
const DrawOptions &aOptions)
|
const DrawOptions &aOptions)
|
||||||
{
|
{
|
||||||
if (mTransformSingular) {
|
if (mTransformSingular || aDest.IsEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,6 +123,10 @@ struct IntRectTyped :
|
||||||
|
|
||||||
void InflateToMultiple(const IntSizeTyped<units>& aTileSize)
|
void InflateToMultiple(const IntSizeTyped<units>& aTileSize)
|
||||||
{
|
{
|
||||||
|
if (this->IsEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t yMost = this->YMost();
|
int32_t yMost = this->YMost();
|
||||||
int32_t xMost = this->XMost();
|
int32_t xMost = this->XMost();
|
||||||
|
|
||||||
|
|
|
@ -144,7 +144,7 @@ GrallocImage::SetData(const Data& aData)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GrallocImage::SetData(TextureClient* aGraphicBuffer, const gfx::IntSize& aSize)
|
GrallocImage::AdoptData(TextureClient* aGraphicBuffer, const gfx::IntSize& aSize)
|
||||||
{
|
{
|
||||||
mTextureClient = aGraphicBuffer;
|
mTextureClient = aGraphicBuffer;
|
||||||
mSize = aSize;
|
mSize = aSize;
|
||||||
|
|
|
@ -63,11 +63,12 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual bool SetData(const Data& aData);
|
virtual bool SetData(const Data& aData);
|
||||||
|
|
||||||
|
using RecyclingPlanarYCbCrImage::AdoptData;
|
||||||
/**
|
/**
|
||||||
* Share the SurfaceDescriptor without making the copy, in order
|
* Share the SurfaceDescriptor without making the copy, in order
|
||||||
* to support functioning in all different layer managers.
|
* to support functioning in all different layer managers.
|
||||||
*/
|
*/
|
||||||
void SetData(TextureClient* aGraphicBuffer, const gfx::IntSize& aSize);
|
void AdoptData(TextureClient* aGraphicBuffer, const gfx::IntSize& aSize);
|
||||||
|
|
||||||
// From [android 4.0.4]/hardware/msm7k/libgralloc-qsd8k/gralloc_priv.h
|
// From [android 4.0.4]/hardware/msm7k/libgralloc-qsd8k/gralloc_priv.h
|
||||||
enum {
|
enum {
|
||||||
|
|
|
@ -534,12 +534,6 @@ RecyclingPlanarYCbCrImage::CopyData(const Data& aData)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
RecyclingPlanarYCbCrImage::SetData(const Data &aData)
|
|
||||||
{
|
|
||||||
return CopyData(aData);
|
|
||||||
}
|
|
||||||
|
|
||||||
gfxImageFormat
|
gfxImageFormat
|
||||||
PlanarYCbCrImage::GetOffscreenFormat()
|
PlanarYCbCrImage::GetOffscreenFormat()
|
||||||
{
|
{
|
||||||
|
@ -549,7 +543,7 @@ PlanarYCbCrImage::GetOffscreenFormat()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PlanarYCbCrImage::SetDataNoCopy(const Data &aData)
|
PlanarYCbCrImage::AdoptData(const Data &aData)
|
||||||
{
|
{
|
||||||
mData = aData;
|
mData = aData;
|
||||||
mSize = aData.mPicSize;
|
mSize = aData.mPicSize;
|
||||||
|
|
|
@ -727,16 +727,16 @@ public:
|
||||||
* This makes a copy of the data buffers, in order to support functioning
|
* This makes a copy of the data buffers, in order to support functioning
|
||||||
* in all different layer managers.
|
* in all different layer managers.
|
||||||
*/
|
*/
|
||||||
virtual bool SetData(const Data& aData) = 0;
|
virtual bool CopyData(const Data& aData) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This doesn't make a copy of the data buffers. Can be used when mBuffer is
|
* This doesn't make a copy of the data buffers. Can be used when mBuffer is
|
||||||
* pre allocated with AllocateAndGetNewBuffer(size) and then SetDataNoCopy is
|
* pre allocated with AllocateAndGetNewBuffer(size) and then AdoptData is
|
||||||
* called to only update the picture size, planes etc. fields in mData.
|
* called to only update the picture size, planes etc. fields in mData.
|
||||||
* The GStreamer media backend uses this to decode into PlanarYCbCrImage(s)
|
* The GStreamer media backend uses this to decode into PlanarYCbCrImage(s)
|
||||||
* directly.
|
* directly.
|
||||||
*/
|
*/
|
||||||
virtual bool SetDataNoCopy(const Data &aData);
|
virtual bool AdoptData(const Data &aData);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This allocates and returns a new buffer
|
* This allocates and returns a new buffer
|
||||||
|
@ -793,16 +793,10 @@ class RecyclingPlanarYCbCrImage: public PlanarYCbCrImage {
|
||||||
public:
|
public:
|
||||||
explicit RecyclingPlanarYCbCrImage(BufferRecycleBin *aRecycleBin) : mRecycleBin(aRecycleBin) {}
|
explicit RecyclingPlanarYCbCrImage(BufferRecycleBin *aRecycleBin) : mRecycleBin(aRecycleBin) {}
|
||||||
virtual ~RecyclingPlanarYCbCrImage() override;
|
virtual ~RecyclingPlanarYCbCrImage() override;
|
||||||
virtual bool SetData(const Data& aData) override;
|
virtual bool CopyData(const Data& aData) override;
|
||||||
virtual uint8_t* AllocateAndGetNewBuffer(uint32_t aSize) override;
|
virtual uint8_t* AllocateAndGetNewBuffer(uint32_t aSize) override;
|
||||||
virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
|
virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||||
protected:
|
protected:
|
||||||
/**
|
|
||||||
* Make a copy of the YCbCr data into local storage.
|
|
||||||
*
|
|
||||||
* @param aData Input image data.
|
|
||||||
*/
|
|
||||||
bool CopyData(const Data& aData);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a buffer to store image data in.
|
* Return a buffer to store image data in.
|
||||||
|
|
|
@ -132,7 +132,6 @@ struct LayerPropertiesBase : public LayerProperties
|
||||||
: mLayer(aLayer)
|
: mLayer(aLayer)
|
||||||
, mMaskLayer(nullptr)
|
, mMaskLayer(nullptr)
|
||||||
, mVisibleRegion(mLayer->GetLocalVisibleRegion().ToUnknownRegion())
|
, mVisibleRegion(mLayer->GetLocalVisibleRegion().ToUnknownRegion())
|
||||||
, mInvalidRegion(aLayer->GetInvalidRegion())
|
|
||||||
, mPostXScale(aLayer->GetPostXScale())
|
, mPostXScale(aLayer->GetPostXScale())
|
||||||
, mPostYScale(aLayer->GetPostYScale())
|
, mPostYScale(aLayer->GetPostYScale())
|
||||||
, mOpacity(aLayer->GetLocalOpacity())
|
, mOpacity(aLayer->GetLocalOpacity())
|
||||||
|
@ -202,7 +201,7 @@ struct LayerPropertiesBase : public LayerProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
AddRegion(result, ComputeChangeInternal(aCallback, aGeometryChanged));
|
AddRegion(result, ComputeChangeInternal(aCallback, aGeometryChanged));
|
||||||
AddTransformedRegion(result, mLayer->GetInvalidRegion(), mTransform);
|
AddTransformedRegion(result, mLayer->GetInvalidRegion().GetRegion(), mTransform);
|
||||||
|
|
||||||
if (mMaskLayer && otherMask) {
|
if (mMaskLayer && otherMask) {
|
||||||
AddTransformedRegion(result, mMaskLayer->ComputeChange(aCallback, aGeometryChanged),
|
AddTransformedRegion(result, mMaskLayer->ComputeChange(aCallback, aGeometryChanged),
|
||||||
|
@ -252,7 +251,6 @@ struct LayerPropertiesBase : public LayerProperties
|
||||||
UniquePtr<LayerPropertiesBase> mMaskLayer;
|
UniquePtr<LayerPropertiesBase> mMaskLayer;
|
||||||
nsTArray<UniquePtr<LayerPropertiesBase>> mAncestorMaskLayers;
|
nsTArray<UniquePtr<LayerPropertiesBase>> mAncestorMaskLayers;
|
||||||
nsIntRegion mVisibleRegion;
|
nsIntRegion mVisibleRegion;
|
||||||
nsIntRegion mInvalidRegion;
|
|
||||||
Matrix4x4 mTransform;
|
Matrix4x4 mTransform;
|
||||||
float mPostXScale;
|
float mPostXScale;
|
||||||
float mPostYScale;
|
float mPostYScale;
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "mozilla/gfx/BaseMargin.h" // for BaseMargin
|
#include "mozilla/gfx/BaseMargin.h" // for BaseMargin
|
||||||
#include "mozilla/gfx/BasePoint.h" // for BasePoint
|
#include "mozilla/gfx/BasePoint.h" // for BasePoint
|
||||||
#include "mozilla/gfx/Point.h" // for IntSize
|
#include "mozilla/gfx/Point.h" // for IntSize
|
||||||
|
#include "mozilla/gfx/TiledRegion.h" // for TiledIntRegion
|
||||||
#include "mozilla/gfx/Types.h" // for SurfaceFormat
|
#include "mozilla/gfx/Types.h" // for SurfaceFormat
|
||||||
#include "mozilla/gfx/UserData.h" // for UserData, etc
|
#include "mozilla/gfx/UserData.h" // for UserData, etc
|
||||||
#include "mozilla/layers/LayersTypes.h"
|
#include "mozilla/layers/LayersTypes.h"
|
||||||
|
@ -1662,20 +1663,24 @@ public:
|
||||||
* Returns the current area of the layer (in layer-space coordinates)
|
* Returns the current area of the layer (in layer-space coordinates)
|
||||||
* marked as needed to be recomposited.
|
* marked as needed to be recomposited.
|
||||||
*/
|
*/
|
||||||
const nsIntRegion& GetInvalidRegion() { return mInvalidRegion; }
|
const gfx::TiledIntRegion& GetInvalidRegion() { return mInvalidRegion; }
|
||||||
void AddInvalidRegion(const nsIntRegion& aRegion) {
|
void AddInvalidRegion(const nsIntRegion& aRegion) {
|
||||||
mInvalidRegion.Or(mInvalidRegion, aRegion);
|
mInvalidRegion.Add(aRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark the entirety of the layer's visible region as being invalid.
|
* Mark the entirety of the layer's visible region as being invalid.
|
||||||
*/
|
*/
|
||||||
void SetInvalidRectToVisibleRegion() { mInvalidRegion = GetVisibleRegion().ToUnknownRegion(); }
|
void SetInvalidRectToVisibleRegion()
|
||||||
|
{
|
||||||
|
mInvalidRegion.SetEmpty();
|
||||||
|
mInvalidRegion.Add(GetVisibleRegion().ToUnknownRegion());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds to the current invalid rect.
|
* Adds to the current invalid rect.
|
||||||
*/
|
*/
|
||||||
void AddInvalidRect(const gfx::IntRect& aRect) { mInvalidRegion.Or(mInvalidRegion, aRect); }
|
void AddInvalidRect(const gfx::IntRect& aRect) { mInvalidRegion.Add(aRect); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the invalid rect, marking the layer as being identical to what is currently
|
* Clear the invalid rect, marking the layer as being identical to what is currently
|
||||||
|
@ -1833,7 +1838,7 @@ protected:
|
||||||
bool mForceIsolatedGroup;
|
bool mForceIsolatedGroup;
|
||||||
Maybe<ParentLayerIntRect> mClipRect;
|
Maybe<ParentLayerIntRect> mClipRect;
|
||||||
gfx::IntRect mTileSourceRect;
|
gfx::IntRect mTileSourceRect;
|
||||||
nsIntRegion mInvalidRegion;
|
gfx::TiledIntRegion mInvalidRegion;
|
||||||
nsTArray<RefPtr<AsyncPanZoomController> > mApzcs;
|
nsTArray<RefPtr<AsyncPanZoomController> > mApzcs;
|
||||||
uint32_t mContentFlags;
|
uint32_t mContentFlags;
|
||||||
bool mUseTileSourceRect;
|
bool mUseTileSourceRect;
|
||||||
|
|
|
@ -25,7 +25,8 @@ static uint64_t sBlockCounter = InputBlockState::NO_BLOCK_ID + 1;
|
||||||
InputBlockState::InputBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
|
InputBlockState::InputBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
|
||||||
bool aTargetConfirmed)
|
bool aTargetConfirmed)
|
||||||
: mTargetApzc(aTargetApzc)
|
: mTargetApzc(aTargetApzc)
|
||||||
, mTargetConfirmed(aTargetConfirmed)
|
, mTargetConfirmed(aTargetConfirmed ? TargetConfirmationState::eConfirmed
|
||||||
|
: TargetConfirmationState::eUnconfirmed)
|
||||||
, mBlockId(sBlockCounter++)
|
, mBlockId(sBlockCounter++)
|
||||||
, mTransformToApzc(aTargetApzc->GetTransformToThis())
|
, mTransformToApzc(aTargetApzc->GetTransformToThis())
|
||||||
{
|
{
|
||||||
|
@ -35,12 +36,23 @@ InputBlockState::InputBlockState(const RefPtr<AsyncPanZoomController>& aTargetAp
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
InputBlockState::SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc)
|
InputBlockState::SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
|
||||||
|
TargetConfirmationState aState)
|
||||||
{
|
{
|
||||||
if (mTargetConfirmed) {
|
MOZ_ASSERT(aState == TargetConfirmationState::eConfirmed
|
||||||
|
|| aState == TargetConfirmationState::eTimedOut);
|
||||||
|
|
||||||
|
if (mTargetConfirmed == TargetConfirmationState::eTimedOut &&
|
||||||
|
aState == TargetConfirmationState::eConfirmed) {
|
||||||
|
// The main thread finally responded. We had already timed out the
|
||||||
|
// confirmation, but we want to update the state internally so that we
|
||||||
|
// can record the time for telemetry purposes.
|
||||||
|
mTargetConfirmed = TargetConfirmationState::eTimedOutAndMainThreadResponded;
|
||||||
|
}
|
||||||
|
if (mTargetConfirmed != TargetConfirmationState::eUnconfirmed) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mTargetConfirmed = true;
|
mTargetConfirmed = aState;
|
||||||
|
|
||||||
TBS_LOG("%p got confirmed target APZC %p\n", this, mTargetApzc.get());
|
TBS_LOG("%p got confirmed target APZC %p\n", this, mTargetApzc.get());
|
||||||
if (mTargetApzc == aTargetApzc) {
|
if (mTargetApzc == aTargetApzc) {
|
||||||
|
@ -85,7 +97,14 @@ InputBlockState::GetBlockId() const
|
||||||
bool
|
bool
|
||||||
InputBlockState::IsTargetConfirmed() const
|
InputBlockState::IsTargetConfirmed() const
|
||||||
{
|
{
|
||||||
return mTargetConfirmed;
|
return mTargetConfirmed != TargetConfirmationState::eUnconfirmed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
InputBlockState::HasReceivedRealConfirmedTarget() const
|
||||||
|
{
|
||||||
|
return mTargetConfirmed == TargetConfirmationState::eConfirmed ||
|
||||||
|
mTargetConfirmed == TargetConfirmationState::eTimedOutAndMainThreadResponded;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -192,7 +211,7 @@ CancelableBlockState::IsDefaultPrevented() const
|
||||||
bool
|
bool
|
||||||
CancelableBlockState::HasReceivedAllContentNotifications() const
|
CancelableBlockState::HasReceivedAllContentNotifications() const
|
||||||
{
|
{
|
||||||
return IsTargetConfirmed() && mContentResponded;
|
return HasReceivedRealConfirmedTarget() && mContentResponded;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -359,7 +378,8 @@ WheelBlockState::SetContentResponse(bool aPreventDefault)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
WheelBlockState::SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc)
|
WheelBlockState::SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
|
||||||
|
TargetConfirmationState aState)
|
||||||
{
|
{
|
||||||
// The APZC that we find via APZCCallbackHelpers may not be the same APZC
|
// The APZC that we find via APZCCallbackHelpers may not be the same APZC
|
||||||
// ESM or OverscrollHandoff would have computed. Make sure we get the right
|
// ESM or OverscrollHandoff would have computed. Make sure we get the right
|
||||||
|
@ -370,7 +390,7 @@ WheelBlockState::SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aT
|
||||||
apzc = apzc->BuildOverscrollHandoffChain()->FindFirstScrollable(event);
|
apzc = apzc->BuildOverscrollHandoffChain()->FindFirstScrollable(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
InputBlockState::SetConfirmedTargetApzc(apzc);
|
InputBlockState::SetConfirmedTargetApzc(apzc, aState);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -603,7 +623,8 @@ PanGestureBlockState::PanGestureBlockState(const RefPtr<AsyncPanZoomController>&
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PanGestureBlockState::SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc)
|
PanGestureBlockState::SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
|
||||||
|
TargetConfirmationState aState)
|
||||||
{
|
{
|
||||||
// The APZC that we find via APZCCallbackHelpers may not be the same APZC
|
// The APZC that we find via APZCCallbackHelpers may not be the same APZC
|
||||||
// ESM or OverscrollHandoff would have computed. Make sure we get the right
|
// ESM or OverscrollHandoff would have computed. Make sure we get the right
|
||||||
|
@ -618,7 +639,7 @@ PanGestureBlockState::SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InputBlockState::SetConfirmedTargetApzc(apzc);
|
InputBlockState::SetConfirmedTargetApzc(apzc, aState);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,17 +39,26 @@ class InputBlockState
|
||||||
public:
|
public:
|
||||||
static const uint64_t NO_BLOCK_ID = 0;
|
static const uint64_t NO_BLOCK_ID = 0;
|
||||||
|
|
||||||
|
enum class TargetConfirmationState {
|
||||||
|
eUnconfirmed,
|
||||||
|
eTimedOut,
|
||||||
|
eTimedOutAndMainThreadResponded,
|
||||||
|
eConfirmed
|
||||||
|
};
|
||||||
|
|
||||||
explicit InputBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
|
explicit InputBlockState(const RefPtr<AsyncPanZoomController>& aTargetApzc,
|
||||||
bool aTargetConfirmed);
|
bool aTargetConfirmed);
|
||||||
virtual ~InputBlockState()
|
virtual ~InputBlockState()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual bool SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc);
|
virtual bool SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
|
||||||
|
TargetConfirmationState aState);
|
||||||
const RefPtr<AsyncPanZoomController>& GetTargetApzc() const;
|
const RefPtr<AsyncPanZoomController>& GetTargetApzc() const;
|
||||||
const RefPtr<const OverscrollHandoffChain>& GetOverscrollHandoffChain() const;
|
const RefPtr<const OverscrollHandoffChain>& GetOverscrollHandoffChain() const;
|
||||||
uint64_t GetBlockId() const;
|
uint64_t GetBlockId() const;
|
||||||
|
|
||||||
bool IsTargetConfirmed() const;
|
bool IsTargetConfirmed() const;
|
||||||
|
bool HasReceivedRealConfirmedTarget() const;
|
||||||
|
|
||||||
void SetScrolledApzc(AsyncPanZoomController* aApzc);
|
void SetScrolledApzc(AsyncPanZoomController* aApzc);
|
||||||
AsyncPanZoomController* GetScrolledApzc() const;
|
AsyncPanZoomController* GetScrolledApzc() const;
|
||||||
|
@ -65,7 +74,7 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RefPtr<AsyncPanZoomController> mTargetApzc;
|
RefPtr<AsyncPanZoomController> mTargetApzc;
|
||||||
bool mTargetConfirmed;
|
TargetConfirmationState mTargetConfirmed;
|
||||||
const uint64_t mBlockId;
|
const uint64_t mBlockId;
|
||||||
|
|
||||||
// The APZC that was actually scrolled by events in this input block.
|
// The APZC that was actually scrolled by events in this input block.
|
||||||
|
@ -227,7 +236,8 @@ public:
|
||||||
void HandleEvents() override;
|
void HandleEvents() override;
|
||||||
bool MustStayActive() override;
|
bool MustStayActive() override;
|
||||||
const char* Type() override;
|
const char* Type() override;
|
||||||
bool SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc) override;
|
bool SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
|
||||||
|
TargetConfirmationState aState) override;
|
||||||
|
|
||||||
void AddEvent(const ScrollWheelInput& aEvent);
|
void AddEvent(const ScrollWheelInput& aEvent);
|
||||||
|
|
||||||
|
@ -348,7 +358,8 @@ public:
|
||||||
void HandleEvents() override;
|
void HandleEvents() override;
|
||||||
bool MustStayActive() override;
|
bool MustStayActive() override;
|
||||||
const char* Type() override;
|
const char* Type() override;
|
||||||
bool SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc) override;
|
bool SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc,
|
||||||
|
TargetConfirmationState aState) override;
|
||||||
|
|
||||||
void AddEvent(const PanGestureInput& aEvent);
|
void AddEvent(const PanGestureInput& aEvent);
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,8 @@ InputQueue::ReceiveTouchInput(const RefPtr<AsyncPanZoomController>& aTarget,
|
||||||
// from a fast fling to a pinch state (i.e. second finger goes down while
|
// from a fast fling to a pinch state (i.e. second finger goes down while
|
||||||
// the first finger is moving).
|
// the first finger is moving).
|
||||||
block->SetDuringFastFling();
|
block->SetDuringFastFling();
|
||||||
block->SetConfirmedTargetApzc(aTarget);
|
block->SetConfirmedTargetApzc(aTarget,
|
||||||
|
InputBlockState::TargetConfirmationState::eConfirmed);
|
||||||
if (gfxPrefs::TouchActionEnabled()) {
|
if (gfxPrefs::TouchActionEnabled()) {
|
||||||
block->SetAllowedTouchBehaviors(currentBehaviors);
|
block->SetAllowedTouchBehaviors(currentBehaviors);
|
||||||
}
|
}
|
||||||
|
@ -586,7 +587,9 @@ InputQueue::MainThreadTimeout(const uint64_t& aInputBlockId) {
|
||||||
// target apzc in the case where the main thread doesn't get back to us
|
// target apzc in the case where the main thread doesn't get back to us
|
||||||
// fast enough.
|
// fast enough.
|
||||||
success = mInputBlockQueue[i]->TimeoutContentResponse();
|
success = mInputBlockQueue[i]->TimeoutContentResponse();
|
||||||
success |= mInputBlockQueue[i]->SetConfirmedTargetApzc(mInputBlockQueue[i]->GetTargetApzc());
|
success |= mInputBlockQueue[i]->SetConfirmedTargetApzc(
|
||||||
|
mInputBlockQueue[i]->GetTargetApzc(),
|
||||||
|
InputBlockState::TargetConfirmationState::eTimedOut);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -624,7 +627,8 @@ InputQueue::SetConfirmedTargetApzc(uint64_t aInputBlockId, const RefPtr<AsyncPan
|
||||||
for (size_t i = 0; i < mInputBlockQueue.Length(); i++) {
|
for (size_t i = 0; i < mInputBlockQueue.Length(); i++) {
|
||||||
CancelableBlockState* block = mInputBlockQueue[i].get();
|
CancelableBlockState* block = mInputBlockQueue[i].get();
|
||||||
if (block->GetBlockId() == aInputBlockId) {
|
if (block->GetBlockId() == aInputBlockId) {
|
||||||
success = block->SetConfirmedTargetApzc(aTargetApzc);
|
success = block->SetConfirmedTargetApzc(aTargetApzc,
|
||||||
|
InputBlockState::TargetConfirmationState::eConfirmed);
|
||||||
block->RecordContentResponseTime();
|
block->RecordContentResponseTime();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -647,7 +651,8 @@ InputQueue::ConfirmDragBlock(uint64_t aInputBlockId, const RefPtr<AsyncPanZoomCo
|
||||||
DragBlockState* block = mInputBlockQueue[i]->AsDragBlock();
|
DragBlockState* block = mInputBlockQueue[i]->AsDragBlock();
|
||||||
if (block && block->GetBlockId() == aInputBlockId) {
|
if (block && block->GetBlockId() == aInputBlockId) {
|
||||||
block->SetDragMetrics(aDragMetrics);
|
block->SetDragMetrics(aDragMetrics);
|
||||||
success = block->SetConfirmedTargetApzc(aTargetApzc);
|
success = block->SetConfirmedTargetApzc(aTargetApzc,
|
||||||
|
InputBlockState::TargetConfirmationState::eConfirmed);
|
||||||
block->RecordContentResponseTime();
|
block->RecordContentResponseTime();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool SetData(const Data& aData) override;
|
virtual bool CopyData(const Data& aData) override;
|
||||||
virtual void SetDelayedConversion(bool aDelayed) override { mDelayedConversion = aDelayed; }
|
virtual void SetDelayedConversion(bool aDelayed) override { mDelayedConversion = aDelayed; }
|
||||||
|
|
||||||
already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
|
already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
|
||||||
|
@ -86,9 +86,9 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BasicPlanarYCbCrImage::SetData(const Data& aData)
|
BasicPlanarYCbCrImage::CopyData(const Data& aData)
|
||||||
{
|
{
|
||||||
RecyclingPlanarYCbCrImage::SetData(aData);
|
RecyclingPlanarYCbCrImage::CopyData(aData);
|
||||||
|
|
||||||
if (mDelayedConversion) {
|
if (mDelayedConversion) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -54,9 +54,8 @@ public:
|
||||||
{
|
{
|
||||||
NS_ASSERTION(BasicManager()->InConstruction(),
|
NS_ASSERTION(BasicManager()->InConstruction(),
|
||||||
"Can only set properties in construction phase");
|
"Can only set properties in construction phase");
|
||||||
mInvalidRegion.Or(mInvalidRegion, aRegion);
|
mInvalidRegion.Add(aRegion);
|
||||||
mInvalidRegion.SimplifyOutward(20);
|
mValidRegion.Sub(mValidRegion, mInvalidRegion.GetRegion());
|
||||||
mValidRegion.Sub(mValidRegion, mInvalidRegion);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void PaintThebes(gfxContext* aContext,
|
virtual void PaintThebes(gfxContext* aContext,
|
||||||
|
|
|
@ -60,9 +60,8 @@ public:
|
||||||
{
|
{
|
||||||
NS_ASSERTION(ClientManager()->InConstruction(),
|
NS_ASSERTION(ClientManager()->InConstruction(),
|
||||||
"Can only set properties in construction phase");
|
"Can only set properties in construction phase");
|
||||||
mInvalidRegion.Or(mInvalidRegion, aRegion);
|
mInvalidRegion.Add(aRegion);
|
||||||
mInvalidRegion.SimplifyOutward(20);
|
mValidRegion.Sub(mValidRegion, mInvalidRegion.GetRegion());
|
||||||
mValidRegion.Sub(mValidRegion, mInvalidRegion);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void RenderLayer() override { RenderLayerWithReadback(nullptr); }
|
virtual void RenderLayer() override { RenderLayerWithReadback(nullptr); }
|
||||||
|
|
|
@ -54,10 +54,10 @@ public:
|
||||||
// PaintedLayer
|
// PaintedLayer
|
||||||
virtual Layer* AsLayer() override { return this; }
|
virtual Layer* AsLayer() override { return this; }
|
||||||
virtual void InvalidateRegion(const nsIntRegion& aRegion) override {
|
virtual void InvalidateRegion(const nsIntRegion& aRegion) override {
|
||||||
mInvalidRegion.Or(mInvalidRegion, aRegion);
|
mInvalidRegion.Add(aRegion);
|
||||||
mInvalidRegion.SimplifyOutward(20);
|
nsIntRegion invalidRegion = mInvalidRegion.GetRegion();
|
||||||
mValidRegion.Sub(mValidRegion, mInvalidRegion);
|
mValidRegion.Sub(mValidRegion, invalidRegion);
|
||||||
mLowPrecisionValidRegion.Sub(mLowPrecisionValidRegion, mInvalidRegion);
|
mLowPrecisionValidRegion.Sub(mLowPrecisionValidRegion, invalidRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shadow methods
|
// Shadow methods
|
||||||
|
|
|
@ -78,12 +78,17 @@ APZChild::Create(const dom::TabId& aTabId)
|
||||||
return apz.forget();
|
return apz.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
APZChild::APZChild()
|
||||||
|
: mDestroyed(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
APZChild::~APZChild()
|
APZChild::~APZChild()
|
||||||
{
|
{
|
||||||
if (mObserver) {
|
if (mObserver) {
|
||||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||||
os->RemoveObserver(mObserver, "tab-child-created");
|
os->RemoveObserver(mObserver, "tab-child-created");
|
||||||
} else {
|
} else if (mBrowser) {
|
||||||
mBrowser->SetAPZChild(nullptr);
|
mBrowser->SetAPZChild(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,6 +148,18 @@ APZChild::RecvNotifyFlushComplete()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
APZChild::RecvDestroy()
|
||||||
|
{
|
||||||
|
mDestroyed = true;
|
||||||
|
if (mBrowser) {
|
||||||
|
mBrowser->SetAPZChild(nullptr);
|
||||||
|
mBrowser = nullptr;
|
||||||
|
}
|
||||||
|
PAPZChild::Send__delete__(this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
APZChild::SetObserver(nsIObserver* aObserver)
|
APZChild::SetObserver(nsIObserver* aObserver)
|
||||||
{
|
{
|
||||||
|
@ -159,8 +176,13 @@ APZChild::SetBrowser(dom::TabChild* aBrowser)
|
||||||
os->RemoveObserver(mObserver, "tab-child-created");
|
os->RemoveObserver(mObserver, "tab-child-created");
|
||||||
mObserver = nullptr;
|
mObserver = nullptr;
|
||||||
}
|
}
|
||||||
mBrowser = aBrowser;
|
// We might get the tab-child-created notification after we receive a
|
||||||
mBrowser->SetAPZChild(this);
|
// Destroy message from the parent. In that case we don't want to install
|
||||||
|
// ourselves with the browser.
|
||||||
|
if (!mDestroyed) {
|
||||||
|
mBrowser = aBrowser;
|
||||||
|
mBrowser->SetAPZChild(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace layers
|
} // namespace layers
|
||||||
|
|
|
@ -48,15 +48,18 @@ public:
|
||||||
|
|
||||||
virtual bool RecvNotifyFlushComplete() override;
|
virtual bool RecvNotifyFlushComplete() override;
|
||||||
|
|
||||||
|
virtual bool RecvDestroy() override;
|
||||||
|
|
||||||
void SetBrowser(dom::TabChild* aBrowser);
|
void SetBrowser(dom::TabChild* aBrowser);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
APZChild() {};
|
APZChild();
|
||||||
|
|
||||||
void SetObserver(nsIObserver* aObserver);
|
void SetObserver(nsIObserver* aObserver);
|
||||||
|
|
||||||
RefPtr<dom::TabChild> mBrowser;
|
RefPtr<dom::TabChild> mBrowser;
|
||||||
RefPtr<nsIObserver> mObserver;
|
RefPtr<nsIObserver> mObserver;
|
||||||
|
bool mDestroyed;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace layers
|
} // namespace layers
|
||||||
|
|
|
@ -83,6 +83,8 @@ parent:
|
||||||
async UpdateZoomConstraints(uint32_t aPresShellId, ViewID aViewId,
|
async UpdateZoomConstraints(uint32_t aPresShellId, ViewID aViewId,
|
||||||
MaybeZoomConstraints aConstraints);
|
MaybeZoomConstraints aConstraints);
|
||||||
|
|
||||||
|
async __delete__();
|
||||||
|
|
||||||
child:
|
child:
|
||||||
async UpdateFrame(FrameMetrics frame);
|
async UpdateFrame(FrameMetrics frame);
|
||||||
|
|
||||||
|
@ -95,7 +97,7 @@ child:
|
||||||
async NotifyAPZStateChange(ViewID aViewId, APZStateChange aChange, int aArg);
|
async NotifyAPZStateChange(ViewID aViewId, APZStateChange aChange, int aArg);
|
||||||
async NotifyFlushComplete();
|
async NotifyFlushComplete();
|
||||||
|
|
||||||
async __delete__();
|
async Destroy();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // layers
|
} // layers
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace layers {
|
namespace layers {
|
||||||
|
|
||||||
|
static std::map<uint64_t, RefPtr<RemoteContentController>> sDestroyedControllers;
|
||||||
|
|
||||||
RemoteContentController::RemoteContentController(uint64_t aLayersId,
|
RemoteContentController::RemoteContentController(uint64_t aLayersId,
|
||||||
dom::TabParent* aBrowserParent)
|
dom::TabParent* aBrowserParent)
|
||||||
: mUILoop(MessageLoop::current())
|
: mUILoop(MessageLoop::current())
|
||||||
|
@ -37,9 +39,6 @@ RemoteContentController::RemoteContentController(uint64_t aLayersId,
|
||||||
|
|
||||||
RemoteContentController::~RemoteContentController()
|
RemoteContentController::~RemoteContentController()
|
||||||
{
|
{
|
||||||
if (mBrowserParent) {
|
|
||||||
Unused << PAPZParent::Send__delete__(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -299,17 +298,13 @@ RemoteContentController::ActorDestroy(ActorDestroyReason aWhy)
|
||||||
mApzcTreeManager = nullptr;
|
mApzcTreeManager = nullptr;
|
||||||
}
|
}
|
||||||
mBrowserParent = nullptr;
|
mBrowserParent = nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Remove once upgraded to GCC 4.8+ on linux. Calling a static member
|
uint64_t key = mLayersId;
|
||||||
// function (like PAPZParent::Send__delete__) in a lambda leads to a bogus
|
NS_DispatchToMainThread(NS_NewRunnableFunction([key]() {
|
||||||
// error: "'this' was not captured for this lambda function".
|
// sDestroyedControllers may or may not contain the key, depending on
|
||||||
//
|
// whether or not SendDestroy() was successfully sent out or not.
|
||||||
// (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51494)
|
sDestroyedControllers.erase(key);
|
||||||
static void
|
}));
|
||||||
DeletePAPZParent(PAPZParent* aPAPZ)
|
|
||||||
{
|
|
||||||
Unused << PAPZParent::Send__delete__(aPAPZ);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -318,7 +313,15 @@ RemoteContentController::Destroy()
|
||||||
RefPtr<RemoteContentController> controller = this;
|
RefPtr<RemoteContentController> controller = this;
|
||||||
NS_DispatchToMainThread(NS_NewRunnableFunction([controller] {
|
NS_DispatchToMainThread(NS_NewRunnableFunction([controller] {
|
||||||
if (controller->CanSend()) {
|
if (controller->CanSend()) {
|
||||||
DeletePAPZParent(controller);
|
// Gfx code is done with this object, and it will probably get destroyed
|
||||||
|
// soon. However, if CanSend() is true, ActorDestroy has not yet been
|
||||||
|
// called, which means IPC code still has a handle to this object. We need
|
||||||
|
// to keep it alive until we get the ActorDestroy call, either via the
|
||||||
|
// __delete__ message or via IPC shutdown on our end.
|
||||||
|
uint64_t key = controller->mLayersId;
|
||||||
|
MOZ_ASSERT(sDestroyedControllers.find(key) == sDestroyedControllers.end());
|
||||||
|
sDestroyedControllers[key] = controller;
|
||||||
|
Unused << controller->SendDestroy();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -844,7 +844,7 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies,
|
||||||
}
|
}
|
||||||
common.maskLayerParent() = nullptr;
|
common.maskLayerParent() = nullptr;
|
||||||
common.animations() = mutant->GetAnimations();
|
common.animations() = mutant->GetAnimations();
|
||||||
common.invalidRegion() = mutant->GetInvalidRegion();
|
common.invalidRegion() = mutant->GetInvalidRegion().GetRegion();
|
||||||
common.scrollMetadata() = mutant->GetAllScrollMetadata();
|
common.scrollMetadata() = mutant->GetAllScrollMetadata();
|
||||||
for (size_t i = 0; i < mutant->GetAncestorMaskLayerCount(); i++) {
|
for (size_t i = 0; i < mutant->GetAncestorMaskLayerCount(); i++) {
|
||||||
auto layer = Shadow(mutant->GetAncestorMaskLayerAt(i)->AsShadowableLayer());
|
auto layer = Shadow(mutant->GetAncestorMaskLayerAt(i)->AsShadowableLayer());
|
||||||
|
|
|
@ -82,7 +82,7 @@ SharedPlanarYCbCrImage::GetAsSourceSurface()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
SharedPlanarYCbCrImage::SetData(const PlanarYCbCrData& aData)
|
SharedPlanarYCbCrImage::CopyData(const PlanarYCbCrData& aData)
|
||||||
{
|
{
|
||||||
// If mTextureClient has not already been allocated (through Allocate(aData))
|
// If mTextureClient has not already been allocated (through Allocate(aData))
|
||||||
// allocate it. This code path is slower than the one used when Allocate has
|
// allocate it. This code path is slower than the one used when Allocate has
|
||||||
|
@ -140,9 +140,9 @@ SharedPlanarYCbCrImage::AllocateAndGetNewBuffer(uint32_t aSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
SharedPlanarYCbCrImage::SetDataNoCopy(const Data &aData)
|
SharedPlanarYCbCrImage::AdoptData(const Data &aData)
|
||||||
{
|
{
|
||||||
// SetDataNoCopy is used to update YUV plane offsets without (re)allocating
|
// AdoptData is used to update YUV plane offsets without (re)allocating
|
||||||
// memory previously allocated with AllocateAndGetNewBuffer().
|
// memory previously allocated with AllocateAndGetNewBuffer().
|
||||||
|
|
||||||
MOZ_ASSERT(mTextureClient, "This Image should have already allocated data");
|
MOZ_ASSERT(mTextureClient, "This Image should have already allocated data");
|
||||||
|
|
|
@ -34,8 +34,8 @@ public:
|
||||||
virtual uint8_t* GetBuffer() override;
|
virtual uint8_t* GetBuffer() override;
|
||||||
|
|
||||||
virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
|
virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
|
||||||
virtual bool SetData(const PlanarYCbCrData& aData) override;
|
virtual bool CopyData(const PlanarYCbCrData& aData) override;
|
||||||
virtual bool SetDataNoCopy(const Data &aData) override;
|
virtual bool AdoptData(const Data &aData) override;
|
||||||
|
|
||||||
virtual bool Allocate(PlanarYCbCrData& aData);
|
virtual bool Allocate(PlanarYCbCrData& aData);
|
||||||
virtual uint8_t* AllocateAndGetNewBuffer(uint32_t aSize) override;
|
virtual uint8_t* AllocateAndGetNewBuffer(uint32_t aSize) override;
|
||||||
|
|
|
@ -0,0 +1,357 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "TiledRegion.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "mozilla/fallible.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace gfx {
|
||||||
|
|
||||||
|
static const int32_t kTileSize = 256;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TiledRegionImpl stores an array of non-empty rectangles (pixman_box32_ts) to
|
||||||
|
* represent the region. Each rectangle is contained in a single tile;
|
||||||
|
* rectangles never cross tile boundaries. The rectangles are sorted by their
|
||||||
|
* tile's origin in top-to-bottom, left-to-right order.
|
||||||
|
* (Note that this can mean that a rectangle r1 can come before another
|
||||||
|
* rectangle r2 even if r2.y1 < r1.y1, as long as the two rects are in the same
|
||||||
|
* row of tiles and r1.x1 < r2.x1.)
|
||||||
|
* Empty tiles take up no space in the array - there is no rectangle stored for
|
||||||
|
* them. As a result, any algorithm that needs to deal with empty tiles will
|
||||||
|
* iterate through the mRects array and compare the positions of two
|
||||||
|
* consecutive rects to figure out whether there are any empty tiles between
|
||||||
|
* them.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static pixman_box32_t
|
||||||
|
IntersectionOfNonEmptyBoxes(const pixman_box32_t& aBox1,
|
||||||
|
const pixman_box32_t& aBox2)
|
||||||
|
{
|
||||||
|
return pixman_box32_t {
|
||||||
|
std::max(aBox1.x1, aBox2.x1),
|
||||||
|
std::max(aBox1.y1, aBox2.y1),
|
||||||
|
std::min(aBox1.x2, aBox2.x2),
|
||||||
|
std::min(aBox1.y2, aBox2.y2)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// A TileIterator points to a specific tile inside a certain tile range, or to
|
||||||
|
// the end of the tile range. Advancing a TileIterator will move to the next
|
||||||
|
// tile inside the range (or to the range end). The next tile is either the
|
||||||
|
// tile to the right of the current one, or the first tile of the next tile
|
||||||
|
// row if the current tile is already the last tile in the row.
|
||||||
|
class TileIterator {
|
||||||
|
public:
|
||||||
|
TileIterator(const pixman_box32_t& aTileBounds, const IntPoint& aPosition)
|
||||||
|
: mTileBounds(aTileBounds)
|
||||||
|
, mPos(aPosition)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool operator!=(const TileIterator& aOther) { return mPos != aOther.mPos; }
|
||||||
|
bool operator==(const TileIterator& aOther) { return mPos == aOther.mPos; }
|
||||||
|
|
||||||
|
IntPoint operator*() const { return mPos; }
|
||||||
|
|
||||||
|
const TileIterator& operator++() {
|
||||||
|
mPos.x += kTileSize;
|
||||||
|
if (mPos.x >= mTileBounds.x2) {
|
||||||
|
mPos.x = mTileBounds.x1;
|
||||||
|
mPos.y += kTileSize;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
TileIterator& operator=(const IntPoint& aPosition)
|
||||||
|
{
|
||||||
|
mPos = aPosition;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsBeforeTileContainingPoint(const IntPoint& aPoint) const
|
||||||
|
{
|
||||||
|
return (mPos.y + kTileSize) <= aPoint.y ||
|
||||||
|
(mPos.y <= aPoint.y && (mPos.x + kTileSize) <= aPoint.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsAtTileContainingPoint(const IntPoint& aPoint) const
|
||||||
|
{
|
||||||
|
return mPos.y <= aPoint.y && aPoint.y < (mPos.y + kTileSize) &&
|
||||||
|
mPos.x <= aPoint.x && aPoint.x < (mPos.x + kTileSize);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pixman_box32_t IntersectionWith(const pixman_box32_t& aRect) const
|
||||||
|
{
|
||||||
|
pixman_box32_t tile = { mPos.x, mPos.y,
|
||||||
|
mPos.x + kTileSize, mPos.y + kTileSize };
|
||||||
|
return IntersectionOfNonEmptyBoxes(tile, aRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const pixman_box32_t& mTileBounds;
|
||||||
|
IntPoint mPos;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A TileRange describes a range of tiles contained inside a certain tile
|
||||||
|
// bounds (which is a rectangle that includes all tiles that you're
|
||||||
|
// interested in). The tile range can start and end at any point inside a
|
||||||
|
// tile row.
|
||||||
|
// The tile range end is described by the tile that starts at the bottom
|
||||||
|
// left corner of the tile bounds, i.e. the first tile under the tile
|
||||||
|
// bounds.
|
||||||
|
class TileRange {
|
||||||
|
public:
|
||||||
|
// aTileBounds, aStart and aEnd need to be aligned with the tile grid.
|
||||||
|
TileRange(const pixman_box32_t& aTileBounds,
|
||||||
|
const IntPoint& aStart, const IntPoint& aEnd)
|
||||||
|
: mTileBounds(aTileBounds)
|
||||||
|
, mStart(aStart)
|
||||||
|
, mEnd(aEnd)
|
||||||
|
{}
|
||||||
|
// aTileBounds needs to be aligned with the tile grid.
|
||||||
|
explicit TileRange(const pixman_box32_t& aTileBounds)
|
||||||
|
: mTileBounds(aTileBounds)
|
||||||
|
, mStart(mTileBounds.x1, mTileBounds.y1)
|
||||||
|
, mEnd(mTileBounds.x1, mTileBounds.y2)
|
||||||
|
{}
|
||||||
|
|
||||||
|
TileIterator Begin() const { return TileIterator(mTileBounds, mStart); }
|
||||||
|
TileIterator End() const { return TileIterator(mTileBounds, mEnd); }
|
||||||
|
|
||||||
|
// The number of tiles in this tile range.
|
||||||
|
size_t Length() const
|
||||||
|
{
|
||||||
|
if (mEnd.y == mStart.y) {
|
||||||
|
return (mEnd.x - mStart.x) / kTileSize;
|
||||||
|
}
|
||||||
|
size_t numberOfFullRows = (mEnd.y - mStart.y) / kTileSize - 1;
|
||||||
|
return ((mTileBounds.x2 - mStart.x) +
|
||||||
|
(mTileBounds.x2 - mTileBounds.x1) * numberOfFullRows +
|
||||||
|
(mEnd.x - mTileBounds.x1)) / kTileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If aTileOrigin does not describe a tile inside our tile bounds, move it
|
||||||
|
// to the next tile that you'd encounter by "advancing" a tile iterator
|
||||||
|
// inside these tile bounds. If aTileOrigin is after the last tile inside
|
||||||
|
// our tile bounds, move it to the range end tile.
|
||||||
|
// The result of this method is a valid end tile for a tile range with our
|
||||||
|
// tile bounds.
|
||||||
|
IntPoint MoveIntoBounds(const IntPoint& aTileOrigin) const
|
||||||
|
{
|
||||||
|
IntPoint p = aTileOrigin;
|
||||||
|
if (p.x < mTileBounds.x1) {
|
||||||
|
p.x = mTileBounds.x1;
|
||||||
|
} else if (p.x >= mTileBounds.x2) {
|
||||||
|
p.x = mTileBounds.x1;
|
||||||
|
p.y += kTileSize;
|
||||||
|
}
|
||||||
|
if (p.y < mTileBounds.y1) {
|
||||||
|
p.y = mTileBounds.y1;
|
||||||
|
p.x = mTileBounds.x1;
|
||||||
|
} else if (p.y >= mTileBounds.y2) {
|
||||||
|
// There's only one valid state after the end of the tile range, and that's
|
||||||
|
// the bottom left point of the tile bounds.
|
||||||
|
p.x = mTileBounds.x1;
|
||||||
|
p.y = mTileBounds.y2;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const pixman_box32_t& mTileBounds;
|
||||||
|
const IntPoint mStart;
|
||||||
|
const IntPoint mEnd;
|
||||||
|
};
|
||||||
|
|
||||||
|
static IntPoint
|
||||||
|
TileContainingPoint(const IntPoint& aPoint)
|
||||||
|
{
|
||||||
|
return IntPoint(RoundDownToMultiple(aPoint.x, kTileSize),
|
||||||
|
RoundDownToMultiple(aPoint.y, kTileSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class IterationAction : uint8_t {
|
||||||
|
CONTINUE,
|
||||||
|
STOP
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class IterationEndReason : uint8_t {
|
||||||
|
NOT_STOPPED,
|
||||||
|
STOPPED
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename HandleEmptyTilesFunction,
|
||||||
|
typename HandleNonEmptyTileFunction,
|
||||||
|
typename RectArrayT>
|
||||||
|
IterationEndReason ProcessIntersectedTiles(const pixman_box32_t& aRect,
|
||||||
|
RectArrayT& aRectArray,
|
||||||
|
HandleEmptyTilesFunction aHandleEmptyTiles,
|
||||||
|
HandleNonEmptyTileFunction aHandleNonEmptyTile)
|
||||||
|
{
|
||||||
|
pixman_box32_t tileBounds = {
|
||||||
|
RoundDownToMultiple(aRect.x1, kTileSize),
|
||||||
|
RoundDownToMultiple(aRect.y1, kTileSize),
|
||||||
|
RoundUpToMultiple(aRect.x2, kTileSize),
|
||||||
|
RoundUpToMultiple(aRect.y2, kTileSize)
|
||||||
|
};
|
||||||
|
|
||||||
|
TileRange tileRange(tileBounds);
|
||||||
|
TileIterator rangeEnd = tileRange.End();
|
||||||
|
|
||||||
|
// tileIterator points to the next tile in tileRange, or to rangeEnd if we're
|
||||||
|
// done.
|
||||||
|
TileIterator tileIterator = tileRange.Begin();
|
||||||
|
|
||||||
|
// We iterate over the rectangle array. Depending on the position of the
|
||||||
|
// rectangle we encounter, we may need to advance tileIterator by zero, one,
|
||||||
|
// or more tiles:
|
||||||
|
// - Zero if the rectangle we encountered is outside the tiles that
|
||||||
|
// intersect aRect.
|
||||||
|
// - One if the rectangle is in the exact tile that we're interested in next
|
||||||
|
// (i.e. the tile that tileIterator points at).
|
||||||
|
// - More than one if the encountered rectangle is in a tile that's further
|
||||||
|
// to the right or to the bottom than tileIterator. In that case there is
|
||||||
|
// at least one empty tile between the last rectangle we encountered and
|
||||||
|
// the current one.
|
||||||
|
for (size_t i = 0; i < aRectArray.Length() && tileIterator != rangeEnd; i++) {
|
||||||
|
MOZ_ASSERT(aRectArray[i].x1 < aRectArray[i].x2 && aRectArray[i].y1 < aRectArray[i].y2, "empty rect");
|
||||||
|
IntPoint rectOrigin(aRectArray[i].x1, aRectArray[i].y1);
|
||||||
|
if (tileIterator.IsBeforeTileContainingPoint(rectOrigin)) {
|
||||||
|
IntPoint tileOrigin = TileContainingPoint(rectOrigin);
|
||||||
|
IntPoint afterEmptyTiles = tileRange.MoveIntoBounds(tileOrigin);
|
||||||
|
TileRange emptyTiles(tileBounds, *tileIterator, afterEmptyTiles);
|
||||||
|
if (aHandleEmptyTiles(aRectArray, i, emptyTiles) == IterationAction::STOP) {
|
||||||
|
return IterationEndReason::STOPPED;
|
||||||
|
}
|
||||||
|
tileIterator = afterEmptyTiles;
|
||||||
|
if (tileIterator == rangeEnd) {
|
||||||
|
return IterationEndReason::NOT_STOPPED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tileIterator.IsAtTileContainingPoint(rectOrigin)) {
|
||||||
|
pixman_box32_t rectIntersection = tileIterator.IntersectionWith(aRect);
|
||||||
|
if (aHandleNonEmptyTile(aRectArray, i, rectIntersection) == IterationAction::STOP) {
|
||||||
|
return IterationEndReason::STOPPED;
|
||||||
|
}
|
||||||
|
++tileIterator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tileIterator != rangeEnd) {
|
||||||
|
// We've looked at all of our existing rectangles but haven't covered all
|
||||||
|
// of the tiles that we're interested in yet. So we need to deal with the
|
||||||
|
// remaining tiles now.
|
||||||
|
size_t endIndex = aRectArray.Length();
|
||||||
|
TileRange emptyTiles(tileBounds, *tileIterator, *rangeEnd);
|
||||||
|
if (aHandleEmptyTiles(aRectArray, endIndex, emptyTiles) == IterationAction::STOP) {
|
||||||
|
return IterationEndReason::STOPPED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return IterationEndReason::NOT_STOPPED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static pixman_box32_t
|
||||||
|
UnionBoundsOfNonEmptyBoxes(const pixman_box32_t& aBox1,
|
||||||
|
const pixman_box32_t& aBox2)
|
||||||
|
{
|
||||||
|
return { std::min(aBox1.x1, aBox2.x1),
|
||||||
|
std::min(aBox1.y1, aBox2.y1),
|
||||||
|
std::max(aBox1.x2, aBox2.x2),
|
||||||
|
std::max(aBox1.y2, aBox2.y2) };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true when adding the rectangle was successful, and false if
|
||||||
|
// allocation failed.
|
||||||
|
// When this returns false, our internal state might not be consistent and we
|
||||||
|
// need to be cleared.
|
||||||
|
bool
|
||||||
|
TiledRegionImpl::AddRect(const pixman_box32_t& aRect)
|
||||||
|
{
|
||||||
|
// We are adding a rectangle that can span multiple tiles.
|
||||||
|
// For each empty tile that aRect intersects, we need to add the intersection
|
||||||
|
// of aRect with that tile to mRects, respecting the order of mRects.
|
||||||
|
// For each tile that already has a rectangle, we need to enlarge that
|
||||||
|
// existing rectangle to include the intersection of aRect with the tile.
|
||||||
|
return ProcessIntersectedTiles(aRect, mRects,
|
||||||
|
[&aRect](nsTArray<pixman_box32_t>& rects, size_t& rectIndex, TileRange emptyTiles) {
|
||||||
|
if (!rects.InsertElementsAt(rectIndex, emptyTiles.Length(), fallible)) {
|
||||||
|
return IterationAction::STOP;
|
||||||
|
}
|
||||||
|
for (TileIterator tileIt = emptyTiles.Begin();
|
||||||
|
tileIt != emptyTiles.End();
|
||||||
|
++tileIt, ++rectIndex) {
|
||||||
|
rects[rectIndex] = tileIt.IntersectionWith(aRect);
|
||||||
|
}
|
||||||
|
return IterationAction::CONTINUE;
|
||||||
|
},
|
||||||
|
[](nsTArray<pixman_box32_t>& rects, size_t rectIndex, const pixman_box32_t& rectIntersectionWithTile) {
|
||||||
|
rects[rectIndex] =
|
||||||
|
UnionBoundsOfNonEmptyBoxes(rects[rectIndex], rectIntersectionWithTile);
|
||||||
|
return IterationAction::CONTINUE;
|
||||||
|
}) == IterationEndReason::NOT_STOPPED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
NonEmptyBoxesIntersect(const pixman_box32_t& aBox1, const pixman_box32_t& aBox2)
|
||||||
|
{
|
||||||
|
return aBox1.x1 < aBox2.x2 && aBox2.x1 < aBox1.x2 &&
|
||||||
|
aBox1.y1 < aBox2.y2 && aBox2.y1 < aBox1.y2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TiledRegionImpl::Intersects(const pixman_box32_t& aRect) const
|
||||||
|
{
|
||||||
|
// aRect intersects this region if it intersects any of our rectangles.
|
||||||
|
return ProcessIntersectedTiles(aRect, mRects,
|
||||||
|
[](const nsTArray<pixman_box32_t>& rects, size_t& rectIndex, TileRange emptyTiles) {
|
||||||
|
// Ignore empty tiles and keep on iterating.
|
||||||
|
return IterationAction::CONTINUE;
|
||||||
|
},
|
||||||
|
[](const nsTArray<pixman_box32_t>& rects, size_t rectIndex, const pixman_box32_t& rectIntersectionWithTile) {
|
||||||
|
if (NonEmptyBoxesIntersect(rects[rectIndex], rectIntersectionWithTile)) {
|
||||||
|
// Found an intersecting rectangle, so aRect intersects this region.
|
||||||
|
return IterationAction::STOP;
|
||||||
|
}
|
||||||
|
return IterationAction::CONTINUE;
|
||||||
|
}) == IterationEndReason::STOPPED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
NonEmptyBoxContainsNonEmptyBox(const pixman_box32_t& aBox1, const pixman_box32_t& aBox2)
|
||||||
|
{
|
||||||
|
return aBox1.x1 <= aBox2.x1 && aBox2.x2 <= aBox1.x2 &&
|
||||||
|
aBox1.y1 <= aBox2.y1 && aBox2.y2 <= aBox1.y2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TiledRegionImpl::Contains(const pixman_box32_t& aRect) const
|
||||||
|
{
|
||||||
|
// aRect is contained in this region if aRect does not intersect any empty
|
||||||
|
// tiles and, for each non-empty tile, if the intersection of aRect with that
|
||||||
|
// tile is contained in the existing rectangle we have in that tile.
|
||||||
|
return ProcessIntersectedTiles(aRect, mRects,
|
||||||
|
[](const nsTArray<pixman_box32_t>& rects, size_t& rectIndex, TileRange emptyTiles) {
|
||||||
|
// Found an empty tile that intersects aRect, so aRect is not contained
|
||||||
|
// in this region.
|
||||||
|
return IterationAction::STOP;
|
||||||
|
},
|
||||||
|
[](const nsTArray<pixman_box32_t>& rects, size_t rectIndex, const pixman_box32_t& rectIntersectionWithTile) {
|
||||||
|
if (!NonEmptyBoxContainsNonEmptyBox(rects[rectIndex], rectIntersectionWithTile)) {
|
||||||
|
// Our existing rectangle in this tile does not cover the part of aRect that
|
||||||
|
// intersects this tile, so aRect is not contained in this region.
|
||||||
|
return IterationAction::STOP;
|
||||||
|
}
|
||||||
|
return IterationAction::CONTINUE;
|
||||||
|
}) == IterationEndReason::NOT_STOPPED;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace gfx
|
||||||
|
} // namespace mozilla
|
|
@ -0,0 +1,198 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef MOZILLA_GFX_TILEDREGION_H_
|
||||||
|
#define MOZILLA_GFX_TILEDREGION_H_
|
||||||
|
|
||||||
|
#include "mozilla/ArrayView.h"
|
||||||
|
#include "mozilla/gfx/Rect.h"
|
||||||
|
#include "mozilla/Move.h"
|
||||||
|
#include "nsRegion.h"
|
||||||
|
#include "pixman.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace gfx {
|
||||||
|
|
||||||
|
// See TiledRegion.cpp for documentation on TiledRegionImpl.
|
||||||
|
class TiledRegionImpl {
|
||||||
|
public:
|
||||||
|
void Clear() { mRects.Clear(); }
|
||||||
|
bool AddRect(const pixman_box32_t& aRect);
|
||||||
|
bool Intersects(const pixman_box32_t& aRect) const;
|
||||||
|
bool Contains(const pixman_box32_t& aRect) const;
|
||||||
|
operator ArrayView<pixman_box32_t>() const { return ArrayView<pixman_box32_t>(mRects); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsTArray<pixman_box32_t> mRects;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A auto-simplifying region type that supports one rectangle per tile.
|
||||||
|
* The virtual tile grid is anchored at (0, 0) and has quadratic tiles whose
|
||||||
|
* size is hard-coded as kTileSize in TiledRegion.cpp.
|
||||||
|
* A TiledRegion starts out empty. You can add rectangles or (regular) regions
|
||||||
|
* into it by calling Add(). Add() is a mutating union operation (similar to
|
||||||
|
* OrWith on nsRegion) that's *not* exact, because it will enlarge the region as
|
||||||
|
* necessary to satisfy the "one rectangle per tile" requirement.
|
||||||
|
* Tiled regions convert implicitly to the underlying regular region type.
|
||||||
|
* The only way to remove parts from a TiledRegion is by calling SetEmpty().
|
||||||
|
*/
|
||||||
|
template<typename RegionT>
|
||||||
|
class TiledRegion {
|
||||||
|
public:
|
||||||
|
typedef typename RegionT::RectType RectT;
|
||||||
|
|
||||||
|
TiledRegion()
|
||||||
|
: mCoversBounds(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
TiledRegion(const TiledRegion& aOther)
|
||||||
|
: mBounds(aOther.mBounds)
|
||||||
|
, mImpl(aOther.mImpl)
|
||||||
|
, mCoversBounds(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
TiledRegion(TiledRegion&& aOther)
|
||||||
|
: mBounds(aOther.mBounds)
|
||||||
|
, mImpl(Move(aOther.mImpl))
|
||||||
|
, mCoversBounds(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
RegionT GetRegion() const
|
||||||
|
{
|
||||||
|
if (mBounds.IsEmpty()) {
|
||||||
|
return RegionT();
|
||||||
|
}
|
||||||
|
if (mCoversBounds) {
|
||||||
|
// Rect limit hit or allocation failed, treat as 1 rect.
|
||||||
|
return RegionT(mBounds);
|
||||||
|
}
|
||||||
|
return RegionT(mImpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
TiledRegion& operator=(const TiledRegion& aOther)
|
||||||
|
{
|
||||||
|
if (&aOther != this) {
|
||||||
|
mBounds = aOther.mBounds;
|
||||||
|
mImpl = aOther.mImpl;
|
||||||
|
mCoversBounds = aOther.mCoversBounds;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Add(const RectT& aRect)
|
||||||
|
{
|
||||||
|
if (aRect.IsEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mBounds = mBounds.Union(aRect);
|
||||||
|
|
||||||
|
if (mCoversBounds) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ExceedsMaximumSize()) {
|
||||||
|
FallBackToBounds();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mImpl.AddRect(RectToBox(aRect))) {
|
||||||
|
FallBackToBounds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Add(const RegionT& aRegion)
|
||||||
|
{
|
||||||
|
mBounds = mBounds.Union(aRegion.GetBounds());
|
||||||
|
|
||||||
|
if (mCoversBounds) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ExceedsMaximumSize()) {
|
||||||
|
FallBackToBounds();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) {
|
||||||
|
RectT r = iter.Get();
|
||||||
|
MOZ_ASSERT(!r.IsEmpty());
|
||||||
|
if (!mImpl.AddRect(RectToBox(r))) {
|
||||||
|
FallBackToBounds();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsEmpty() const { return mBounds.IsEmpty(); }
|
||||||
|
|
||||||
|
void SetEmpty()
|
||||||
|
{
|
||||||
|
mBounds.SetEmpty();
|
||||||
|
mImpl.Clear();
|
||||||
|
mCoversBounds = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RectT GetBounds() const { return mBounds; }
|
||||||
|
|
||||||
|
bool Intersects(const RectT& aRect) const
|
||||||
|
{
|
||||||
|
if (!mBounds.Intersects(aRect)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (mCoversBounds) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mImpl.Intersects(RectToBox(aRect));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Contains(const RectT& aRect) const
|
||||||
|
{
|
||||||
|
if (!mBounds.Contains(aRect)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (mCoversBounds) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return mImpl.Contains(RectToBox(aRect));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool ExceedsMaximumSize() const
|
||||||
|
{
|
||||||
|
// This stops us from allocating insane numbers of tiles.
|
||||||
|
return mBounds.width >= 50 * 256 || mBounds.height >= 50 * 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FallBackToBounds()
|
||||||
|
{
|
||||||
|
mCoversBounds = true;
|
||||||
|
mImpl.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
static pixman_box32_t RectToBox(const RectT& aRect)
|
||||||
|
{
|
||||||
|
return { aRect.x, aRect.y, aRect.XMost(), aRect.YMost() };
|
||||||
|
}
|
||||||
|
|
||||||
|
RectT mBounds;
|
||||||
|
TiledRegionImpl mImpl;
|
||||||
|
|
||||||
|
// mCoversBounds is true if we bailed out due to a large number of tiles.
|
||||||
|
// mCoversBounds being true means that this TiledRegion is just a simple
|
||||||
|
// rectangle (our mBounds).
|
||||||
|
// Once set to true, the TiledRegion will stay in this state until SetEmpty
|
||||||
|
// is called.
|
||||||
|
bool mCoversBounds;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef TiledRegion<IntRegion> TiledIntRegion;
|
||||||
|
|
||||||
|
} // namespace gfx
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif /* MOZILLA_GFX_TILEDREGION_H_ */
|
|
@ -46,6 +46,10 @@ EXPORTS.mozilla += [
|
||||||
'ArrayView.h',
|
'ArrayView.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
EXPORTS.mozilla.gfx += [
|
||||||
|
'TiledRegion.h',
|
||||||
|
]
|
||||||
|
|
||||||
if CONFIG['MOZ_X11']:
|
if CONFIG['MOZ_X11']:
|
||||||
EXPORTS.mozilla += ['X11Util.h']
|
EXPORTS.mozilla += ['X11Util.h']
|
||||||
SOURCES += [
|
SOURCES += [
|
||||||
|
@ -66,6 +70,7 @@ UNIFIED_SOURCES += [
|
||||||
'nsThebesFontEnumerator.cpp',
|
'nsThebesFontEnumerator.cpp',
|
||||||
'nsThebesGfxFactory.cpp',
|
'nsThebesGfxFactory.cpp',
|
||||||
'nsTransform2D.cpp',
|
'nsTransform2D.cpp',
|
||||||
|
'TiledRegion.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
# nsDeviceContext.cpp cannot be built in unified mode because it pulls in OS X system headers.
|
# nsDeviceContext.cpp cannot be built in unified mode because it pulls in OS X system headers.
|
||||||
|
|
|
@ -11,8 +11,10 @@
|
||||||
#include "nsRect.h"
|
#include "nsRect.h"
|
||||||
#include "nsRegion.h"
|
#include "nsRegion.h"
|
||||||
#include "RegionBuilder.h"
|
#include "RegionBuilder.h"
|
||||||
|
#include "mozilla/gfx/TiledRegion.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace mozilla::gfx;
|
||||||
|
|
||||||
class TestLargestRegion {
|
class TestLargestRegion {
|
||||||
public:
|
public:
|
||||||
|
@ -597,6 +599,97 @@ TEST(Gfx, PingPongRegion) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The TiledRegion tests use nsIntRect / IntRegion because nsRect doesn't have
|
||||||
|
// InflateToMultiple which is required by TiledRegion.
|
||||||
|
TEST(Gfx, TiledRegionNoSimplification2Rects) {
|
||||||
|
// Add two rectangles, both rectangles are completely inside
|
||||||
|
// different tiles.
|
||||||
|
nsIntRegion region;
|
||||||
|
region.OrWith(nsIntRect(50, 50, 50, 50));
|
||||||
|
region.OrWith(nsIntRect(300, 50, 50, 50));
|
||||||
|
|
||||||
|
TiledIntRegion tiledRegion;
|
||||||
|
tiledRegion.Add(nsIntRect(50, 50, 50, 50));
|
||||||
|
tiledRegion.Add(nsIntRect(300, 50, 50, 50));
|
||||||
|
|
||||||
|
// No simplification should have happened.
|
||||||
|
EXPECT_TRUE(region.IsEqual(tiledRegion.GetRegion()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Gfx, TiledRegionNoSimplification1Region) {
|
||||||
|
// Add two rectangles, both rectangles are completely inside
|
||||||
|
// different tiles.
|
||||||
|
nsIntRegion region;
|
||||||
|
region.OrWith(nsIntRect(50, 50, 50, 50));
|
||||||
|
region.OrWith(nsIntRect(300, 50, 50, 50));
|
||||||
|
|
||||||
|
TiledIntRegion tiledRegion;
|
||||||
|
tiledRegion.Add(region);
|
||||||
|
|
||||||
|
// No simplification should have happened.
|
||||||
|
EXPECT_TRUE(region.IsEqual(tiledRegion.GetRegion()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Gfx, TiledRegionWithSimplification3Rects) {
|
||||||
|
// Add three rectangles. The first two rectangles are completely inside
|
||||||
|
// different tiles, but the third rectangle intersects both tiles.
|
||||||
|
TiledIntRegion tiledRegion;
|
||||||
|
tiledRegion.Add(nsIntRect(50, 50, 50, 50));
|
||||||
|
tiledRegion.Add(nsIntRect(300, 50, 50, 50));
|
||||||
|
tiledRegion.Add(nsIntRect(250, 70, 10, 10));
|
||||||
|
|
||||||
|
// Both tiles should have simplified their rectangles, and those two
|
||||||
|
// rectangles are adjacent to each other, so they just build up one rect.
|
||||||
|
EXPECT_TRUE(tiledRegion.GetRegion().IsEqual(nsIntRect(50, 50, 300, 50)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Gfx, TiledRegionWithSimplification1Region) {
|
||||||
|
// Add three rectangles. The first two rectangles are completely inside
|
||||||
|
// different tiles, but the third rectangle intersects both tiles.
|
||||||
|
nsIntRegion region;
|
||||||
|
region.OrWith(nsIntRect(50, 50, 50, 50));
|
||||||
|
region.OrWith(nsIntRect(300, 50, 50, 50));
|
||||||
|
region.OrWith(nsIntRect(250, 70, 10, 10));
|
||||||
|
|
||||||
|
TiledIntRegion tiledRegion;
|
||||||
|
tiledRegion.Add(region);
|
||||||
|
|
||||||
|
// Both tiles should have simplified their rectangles, and those two
|
||||||
|
// rectangles are adjacent to each other, so they just build up one rect.
|
||||||
|
EXPECT_TRUE(tiledRegion.GetRegion().IsEqual(nsIntRect(50, 50, 300, 50)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Gfx, TiledRegionContains) {
|
||||||
|
// Add three rectangles. The first two rectangles are completely inside
|
||||||
|
// different tiles, but the third rectangle intersects both tiles.
|
||||||
|
TiledIntRegion tiledRegion;
|
||||||
|
tiledRegion.Add(nsIntRect(50, 50, 50, 50));
|
||||||
|
tiledRegion.Add(nsIntRect(300, 50, 50, 50));
|
||||||
|
tiledRegion.Add(nsIntRect(250, 70, 10, 10));
|
||||||
|
|
||||||
|
// Both tiles should have simplified their rectangles, and those two
|
||||||
|
// rectangles are adjacent to each other, so they just build up one rect.
|
||||||
|
EXPECT_TRUE(tiledRegion.Contains(nsIntRect(50, 50, 300, 50)));
|
||||||
|
EXPECT_TRUE(tiledRegion.Contains(nsIntRect(50, 50, 50, 50)));
|
||||||
|
EXPECT_FALSE(tiledRegion.Contains(nsIntRect(50, 50, 301, 50)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Gfx, TiledRegionIntersects) {
|
||||||
|
// Add three rectangles. The first two rectangles are completely inside
|
||||||
|
// different tiles, but the third rectangle intersects both tiles.
|
||||||
|
TiledIntRegion tiledRegion;
|
||||||
|
tiledRegion.Add(nsIntRect(50, 50, 50, 50));
|
||||||
|
tiledRegion.Add(nsIntRect(300, 50, 50, 50));
|
||||||
|
tiledRegion.Add(nsIntRect(250, 70, 10, 10));
|
||||||
|
|
||||||
|
// Both tiles should have simplified their rectangles, and those two
|
||||||
|
// rectangles are adjacent to each other, so they just build up one rect.
|
||||||
|
EXPECT_TRUE(tiledRegion.Intersects(nsIntRect(50, 50, 300, 50)));
|
||||||
|
EXPECT_TRUE(tiledRegion.Intersects(nsIntRect(200, 10, 10, 50)));
|
||||||
|
EXPECT_TRUE(tiledRegion.Intersects(nsIntRect(50, 50, 301, 50)));
|
||||||
|
EXPECT_FALSE(tiledRegion.Intersects(nsIntRect(0, 0, 50, 500)));
|
||||||
|
}
|
||||||
|
|
||||||
MOZ_GTEST_BENCH(GfxBench, RegionOr, []{
|
MOZ_GTEST_BENCH(GfxBench, RegionOr, []{
|
||||||
const int size = 5000;
|
const int size = 5000;
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,6 @@ JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options =
|
||||||
initialShapes(zone, InitialShapeSet()),
|
initialShapes(zone, InitialShapeSet()),
|
||||||
selfHostingScriptSource(nullptr),
|
selfHostingScriptSource(nullptr),
|
||||||
objectMetadataTable(nullptr),
|
objectMetadataTable(nullptr),
|
||||||
innerViews(zone, InnerViewTable()),
|
|
||||||
lazyArrayBuffers(nullptr),
|
lazyArrayBuffers(nullptr),
|
||||||
nonSyntacticLexicalScopes_(nullptr),
|
nonSyntacticLexicalScopes_(nullptr),
|
||||||
gcIncomingGrayPointers(nullptr),
|
gcIncomingGrayPointers(nullptr),
|
||||||
|
@ -667,6 +666,12 @@ JSCompartment::sweepAfterMinorGC()
|
||||||
innerViews.sweepAfterMinorGC();
|
innerViews.sweepAfterMinorGC();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
JSCompartment::sweepInnerViews()
|
||||||
|
{
|
||||||
|
innerViews.sweep();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
JSCompartment::sweepSavedStacks()
|
JSCompartment::sweepSavedStacks()
|
||||||
{
|
{
|
||||||
|
|
|
@ -464,7 +464,7 @@ struct JSCompartment
|
||||||
js::ObjectWeakMap* objectMetadataTable;
|
js::ObjectWeakMap* objectMetadataTable;
|
||||||
|
|
||||||
// Map from array buffers to views sharing that storage.
|
// Map from array buffers to views sharing that storage.
|
||||||
JS::WeakCache<js::InnerViewTable> innerViews;
|
js::InnerViewTable innerViews;
|
||||||
|
|
||||||
// Inline transparent typed objects do not initially have an array buffer,
|
// Inline transparent typed objects do not initially have an array buffer,
|
||||||
// but can have that buffer created lazily if it is accessed later. This
|
// but can have that buffer created lazily if it is accessed later. This
|
||||||
|
@ -584,6 +584,7 @@ struct JSCompartment
|
||||||
|
|
||||||
void sweepAfterMinorGC();
|
void sweepAfterMinorGC();
|
||||||
|
|
||||||
|
void sweepInnerViews();
|
||||||
void sweepCrossCompartmentWrappers();
|
void sweepCrossCompartmentWrappers();
|
||||||
void sweepSavedStacks();
|
void sweepSavedStacks();
|
||||||
void sweepGlobalObject(js::FreeOp* fop);
|
void sweepGlobalObject(js::FreeOp* fop);
|
||||||
|
|
|
@ -2461,6 +2461,7 @@ GCRuntime::sweepZoneAfterCompacting(Zone* zone)
|
||||||
cache->sweep();
|
cache->sweep();
|
||||||
|
|
||||||
for (CompartmentsInZoneIter c(zone); !c.done(); c.next()) {
|
for (CompartmentsInZoneIter c(zone); !c.done(); c.next()) {
|
||||||
|
c->sweepInnerViews();
|
||||||
c->objectGroups.sweep(fop);
|
c->objectGroups.sweep(fop);
|
||||||
c->sweepRegExps();
|
c->sweepRegExps();
|
||||||
c->sweepSavedStacks();
|
c->sweepSavedStacks();
|
||||||
|
@ -5069,6 +5070,7 @@ class SweepWeakCacheTask : public GCSweepTask
|
||||||
explicit name (JSRuntime* rt) : GCSweepTask(rt) {} \
|
explicit name (JSRuntime* rt) : GCSweepTask(rt) {} \
|
||||||
}
|
}
|
||||||
MAKE_GC_SWEEP_TASK(SweepAtomsTask);
|
MAKE_GC_SWEEP_TASK(SweepAtomsTask);
|
||||||
|
MAKE_GC_SWEEP_TASK(SweepInnerViewsTask);
|
||||||
MAKE_GC_SWEEP_TASK(SweepCCWrappersTask);
|
MAKE_GC_SWEEP_TASK(SweepCCWrappersTask);
|
||||||
MAKE_GC_SWEEP_TASK(SweepBaseShapesTask);
|
MAKE_GC_SWEEP_TASK(SweepBaseShapesTask);
|
||||||
MAKE_GC_SWEEP_TASK(SweepInitialShapesTask);
|
MAKE_GC_SWEEP_TASK(SweepInitialShapesTask);
|
||||||
|
@ -5083,6 +5085,13 @@ SweepAtomsTask::run()
|
||||||
runtime->sweepAtoms();
|
runtime->sweepAtoms();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* virtual */ void
|
||||||
|
SweepInnerViewsTask::run()
|
||||||
|
{
|
||||||
|
for (GCCompartmentGroupIter c(runtime); !c.done(); c.next())
|
||||||
|
c->sweepInnerViews();
|
||||||
|
}
|
||||||
|
|
||||||
/* virtual */ void
|
/* virtual */ void
|
||||||
SweepCCWrappersTask::run()
|
SweepCCWrappersTask::run()
|
||||||
{
|
{
|
||||||
|
@ -5164,6 +5173,7 @@ GCRuntime::beginSweepingZoneGroup()
|
||||||
|
|
||||||
FreeOp fop(rt);
|
FreeOp fop(rt);
|
||||||
SweepAtomsTask sweepAtomsTask(rt);
|
SweepAtomsTask sweepAtomsTask(rt);
|
||||||
|
SweepInnerViewsTask sweepInnerViewsTask(rt);
|
||||||
SweepCCWrappersTask sweepCCWrappersTask(rt);
|
SweepCCWrappersTask sweepCCWrappersTask(rt);
|
||||||
SweepObjectGroupsTask sweepObjectGroupsTask(rt);
|
SweepObjectGroupsTask sweepObjectGroupsTask(rt);
|
||||||
SweepRegExpsTask sweepRegExpsTask(rt);
|
SweepRegExpsTask sweepRegExpsTask(rt);
|
||||||
|
@ -5217,6 +5227,7 @@ GCRuntime::beginSweepingZoneGroup()
|
||||||
|
|
||||||
{
|
{
|
||||||
AutoLockHelperThreadState helperLock;
|
AutoLockHelperThreadState helperLock;
|
||||||
|
startTask(sweepInnerViewsTask, gcstats::PHASE_SWEEP_INNER_VIEWS);
|
||||||
startTask(sweepCCWrappersTask, gcstats::PHASE_SWEEP_CC_WRAPPER);
|
startTask(sweepCCWrappersTask, gcstats::PHASE_SWEEP_CC_WRAPPER);
|
||||||
startTask(sweepObjectGroupsTask, gcstats::PHASE_SWEEP_TYPE_OBJECT);
|
startTask(sweepObjectGroupsTask, gcstats::PHASE_SWEEP_TYPE_OBJECT);
|
||||||
startTask(sweepRegExpsTask, gcstats::PHASE_SWEEP_REGEXP);
|
startTask(sweepRegExpsTask, gcstats::PHASE_SWEEP_REGEXP);
|
||||||
|
@ -5297,6 +5308,7 @@ GCRuntime::beginSweepingZoneGroup()
|
||||||
gcstats::AutoSCC scc(stats, zoneGroupIndex);
|
gcstats::AutoSCC scc(stats, zoneGroupIndex);
|
||||||
|
|
||||||
AutoLockHelperThreadState helperLock;
|
AutoLockHelperThreadState helperLock;
|
||||||
|
joinTask(sweepInnerViewsTask, gcstats::PHASE_SWEEP_INNER_VIEWS);
|
||||||
joinTask(sweepCCWrappersTask, gcstats::PHASE_SWEEP_CC_WRAPPER);
|
joinTask(sweepCCWrappersTask, gcstats::PHASE_SWEEP_CC_WRAPPER);
|
||||||
joinTask(sweepObjectGroupsTask, gcstats::PHASE_SWEEP_TYPE_OBJECT);
|
joinTask(sweepObjectGroupsTask, gcstats::PHASE_SWEEP_TYPE_OBJECT);
|
||||||
joinTask(sweepRegExpsTask, gcstats::PHASE_SWEEP_REGEXP);
|
joinTask(sweepRegExpsTask, gcstats::PHASE_SWEEP_REGEXP);
|
||||||
|
|
|
@ -292,11 +292,10 @@ ArrayBufferObject::detach(JSContext* cx, Handle<ArrayBufferObject*> buffer,
|
||||||
// Update all views of the buffer to account for the buffer having been
|
// Update all views of the buffer to account for the buffer having been
|
||||||
// detached, and clear the buffer's data and list of views.
|
// detached, and clear the buffer's data and list of views.
|
||||||
|
|
||||||
auto& innerViews = cx->compartment()->innerViews;
|
if (InnerViewTable::ViewVector* views = cx->compartment()->innerViews.maybeViewsUnbarriered(buffer)) {
|
||||||
if (InnerViewTable::ViewVector* views = innerViews.maybeViewsUnbarriered(buffer)) {
|
|
||||||
for (size_t i = 0; i < views->length(); i++)
|
for (size_t i = 0; i < views->length(); i++)
|
||||||
NoteViewBufferWasDetached((*views)[i], newContents, cx);
|
NoteViewBufferWasDetached((*views)[i], newContents, cx);
|
||||||
innerViews.removeViews(buffer);
|
cx->compartment()->innerViews.removeViews(buffer);
|
||||||
}
|
}
|
||||||
if (buffer->firstView()) {
|
if (buffer->firstView()) {
|
||||||
if (buffer->forInlineTypedObject()) {
|
if (buffer->forInlineTypedObject()) {
|
||||||
|
@ -365,8 +364,7 @@ ArrayBufferObject::changeContents(JSContext* cx, BufferContents newContents)
|
||||||
setNewOwnedData(cx->runtime()->defaultFreeOp(), newContents);
|
setNewOwnedData(cx->runtime()->defaultFreeOp(), newContents);
|
||||||
|
|
||||||
// Update all views.
|
// Update all views.
|
||||||
auto& innerViews = cx->compartment()->innerViews;
|
if (InnerViewTable::ViewVector* views = cx->compartment()->innerViews.maybeViewsUnbarriered(this)) {
|
||||||
if (InnerViewTable::ViewVector* views = innerViews.maybeViewsUnbarriered(this)) {
|
|
||||||
for (size_t i = 0; i < views->length(); i++)
|
for (size_t i = 0; i < views->length(); i++)
|
||||||
changeViewContents(cx, (*views)[i], oldDataPointer, newContents);
|
changeViewContents(cx, (*views)[i], oldDataPointer, newContents);
|
||||||
}
|
}
|
||||||
|
@ -857,7 +855,7 @@ ArrayBufferObject::addView(JSContext* cx, JSObject* viewArg)
|
||||||
setFirstView(view);
|
setFirstView(view);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return cx->compartment()->innerViews.get().addView(cx, this, view);
|
return cx->compartment()->innerViews.addView(cx, this, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -500,7 +500,6 @@ class InnerViewTable
|
||||||
typedef Vector<ArrayBufferViewObject*, 1, SystemAllocPolicy> ViewVector;
|
typedef Vector<ArrayBufferViewObject*, 1, SystemAllocPolicy> ViewVector;
|
||||||
|
|
||||||
friend class ArrayBufferObject;
|
friend class ArrayBufferObject;
|
||||||
friend class WeakCacheBase<InnerViewTable>;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct MapGCPolicy {
|
struct MapGCPolicy {
|
||||||
|
@ -554,35 +553,13 @@ class InnerViewTable
|
||||||
void sweep();
|
void sweep();
|
||||||
void sweepAfterMinorGC();
|
void sweepAfterMinorGC();
|
||||||
|
|
||||||
bool needsSweepAfterMinorGC() const {
|
bool needsSweepAfterMinorGC() {
|
||||||
return !nurseryKeys.empty() || !nurseryKeysValid;
|
return !nurseryKeys.empty() || !nurseryKeysValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf);
|
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
|
||||||
class WeakCacheBase<InnerViewTable>
|
|
||||||
{
|
|
||||||
InnerViewTable& table() {
|
|
||||||
return static_cast<JS::WeakCache<InnerViewTable>*>(this)->get();
|
|
||||||
}
|
|
||||||
const InnerViewTable& table() const {
|
|
||||||
return static_cast<const JS::WeakCache<InnerViewTable>*>(this)->get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
InnerViewTable::ViewVector* maybeViewsUnbarriered(ArrayBufferObject* obj) {
|
|
||||||
return table().maybeViewsUnbarriered(obj);
|
|
||||||
}
|
|
||||||
void removeViews(ArrayBufferObject* obj) { table().removeViews(obj); }
|
|
||||||
void sweepAfterMinorGC() { table().sweepAfterMinorGC(); }
|
|
||||||
bool needsSweepAfterMinorGC() const { return table().needsSweepAfterMinorGC(); }
|
|
||||||
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) {
|
|
||||||
return table().sizeOfExcludingThis(mallocSizeOf);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
extern JSObject*
|
extern JSObject*
|
||||||
InitArrayBufferClass(JSContext* cx, HandleObject obj);
|
InitArrayBufferClass(JSContext* cx, HandleObject obj);
|
||||||
|
|
||||||
|
|
|
@ -1487,16 +1487,6 @@ public:
|
||||||
nsPoint mLastAnimatedGeometryRootOrigin;
|
nsPoint mLastAnimatedGeometryRootOrigin;
|
||||||
nsPoint mAnimatedGeometryRootOrigin;
|
nsPoint mAnimatedGeometryRootOrigin;
|
||||||
|
|
||||||
// If mIgnoreInvalidationsOutsideRect is set, this contains the bounds of the
|
|
||||||
// layer's old visible region, in layer pixels.
|
|
||||||
nsIntRect mOldVisibleBounds;
|
|
||||||
|
|
||||||
// If set, invalidations that fall outside of this rect should not result in
|
|
||||||
// calls to layer->InvalidateRegion during DLBI. Instead, the parts outside
|
|
||||||
// this rectangle will be invalidated in InvalidateVisibleBoundsChangesForScrolledLayer.
|
|
||||||
// See the comment in ComputeAndSetIgnoreInvalidationRect for more information.
|
|
||||||
Maybe<nsIntRect> mIgnoreInvalidationsOutsideRect;
|
|
||||||
|
|
||||||
RefPtr<ColorLayer> mColorLayer;
|
RefPtr<ColorLayer> mColorLayer;
|
||||||
RefPtr<ImageLayer> mImageLayer;
|
RefPtr<ImageLayer> mImageLayer;
|
||||||
|
|
||||||
|
@ -1645,29 +1635,23 @@ AppendToString(nsACString& s, const nsIntRegion& r,
|
||||||
* *after* aTranslation has been applied, so we need to
|
* *after* aTranslation has been applied, so we need to
|
||||||
* apply the inverse of that transform before calling InvalidateRegion.
|
* apply the inverse of that transform before calling InvalidateRegion.
|
||||||
*/
|
*/
|
||||||
template<typename RegionOrRect> void
|
static void
|
||||||
InvalidatePostTransformRegion(PaintedLayer* aLayer, const RegionOrRect& aRegion,
|
InvalidatePostTransformRegion(PaintedLayer* aLayer, const nsIntRegion& aRegion,
|
||||||
const nsIntPoint& aTranslation,
|
const nsIntPoint& aTranslation)
|
||||||
PaintedDisplayItemLayerUserData* aData)
|
|
||||||
{
|
{
|
||||||
// Convert the region from the coordinates of the container layer
|
// Convert the region from the coordinates of the container layer
|
||||||
// (relative to the snapped top-left of the display list reference frame)
|
// (relative to the snapped top-left of the display list reference frame)
|
||||||
// to the PaintedLayer's own coordinates
|
// to the PaintedLayer's own coordinates
|
||||||
RegionOrRect rgn = aRegion;
|
nsIntRegion rgn = aRegion;
|
||||||
rgn.MoveBy(-aTranslation);
|
rgn.MoveBy(-aTranslation);
|
||||||
if (aData->mIgnoreInvalidationsOutsideRect) {
|
aLayer->InvalidateRegion(rgn);
|
||||||
rgn = rgn.Intersect(*aData->mIgnoreInvalidationsOutsideRect);
|
|
||||||
}
|
|
||||||
if (!rgn.IsEmpty()) {
|
|
||||||
aLayer->InvalidateRegion(rgn);
|
|
||||||
#ifdef MOZ_DUMP_PAINTING
|
#ifdef MOZ_DUMP_PAINTING
|
||||||
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
|
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
|
||||||
nsAutoCString str;
|
nsAutoCString str;
|
||||||
AppendToString(str, rgn);
|
AppendToString(str, rgn);
|
||||||
printf_stderr("Invalidating layer %p: %s\n", aLayer, str.get());
|
printf_stderr("Invalidating layer %p: %s\n", aLayer, str.get());
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1681,7 +1665,7 @@ InvalidatePostTransformRegion(PaintedLayer* aLayer, const nsRect& aRect,
|
||||||
nsRect rect = aClip.ApplyNonRoundedIntersection(aRect);
|
nsRect rect = aClip.ApplyNonRoundedIntersection(aRect);
|
||||||
|
|
||||||
nsIntRect pixelRect = rect.ScaleToOutsidePixels(data->mXScale, data->mYScale, data->mAppUnitsPerDevPixel);
|
nsIntRect pixelRect = rect.ScaleToOutsidePixels(data->mXScale, data->mYScale, data->mAppUnitsPerDevPixel);
|
||||||
InvalidatePostTransformRegion(aLayer, pixelRect, aTranslation, data);
|
InvalidatePostTransformRegion(aLayer, pixelRect, aTranslation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2240,89 +2224,6 @@ ContainerState::RecyclePaintedLayer(PaintedLayer* aLayer,
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
ComputeAndSetIgnoreInvalidationRect(PaintedLayer* aLayer,
|
|
||||||
PaintedDisplayItemLayerUserData* aData,
|
|
||||||
AnimatedGeometryRoot* aAnimatedGeometryRoot,
|
|
||||||
nsDisplayListBuilder* aBuilder,
|
|
||||||
const nsIntPoint& aLayerTranslation)
|
|
||||||
{
|
|
||||||
if (!aLayer->Manager()->IsWidgetLayerManager()) {
|
|
||||||
// This optimization is only useful for layers with retained content.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const nsIFrame* parentFrame = (*aAnimatedGeometryRoot)->GetParent();
|
|
||||||
|
|
||||||
// GetDirtyRectForScrolledContents will return an empty rect if parentFrame
|
|
||||||
// is not a scrollable frame.
|
|
||||||
nsRect dirtyRect = aBuilder->GetDirtyRectForScrolledContents(parentFrame);
|
|
||||||
|
|
||||||
if (dirtyRect.IsEmpty()) {
|
|
||||||
// parentFrame is not a scrollable frame, or we didn't encounter it during
|
|
||||||
// display list building (though this shouldn't happen), or it's empty.
|
|
||||||
// In all those cases this optimization is not needed.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// parentFrame is a scrollable frame, and aLayer contains the scrolled
|
|
||||||
// contents of that frame.
|
|
||||||
|
|
||||||
// maxNewVisibleBounds is a conservative approximation of the new visible
|
|
||||||
// region of aLayer.
|
|
||||||
nsIntRect maxNewVisibleBounds =
|
|
||||||
dirtyRect.ScaleToOutsidePixels(aData->mXScale, aData->mYScale,
|
|
||||||
aData->mAppUnitsPerDevPixel) - aLayerTranslation;
|
|
||||||
aData->mOldVisibleBounds = aLayer->GetVisibleRegion().ToUnknownRegion().GetBounds();
|
|
||||||
|
|
||||||
// When the visible region of aLayer changes (e.g. due to scrolling),
|
|
||||||
// three distinct types of invalidations need to be triggered:
|
|
||||||
// (1) Items (or parts of items) that have left the visible region need
|
|
||||||
// to be invalidated so that the pixels they painted are no longer
|
|
||||||
// part of the layer's valid region.
|
|
||||||
// (2) Items (or parts of items) that weren't in the old visible region
|
|
||||||
// but are in the new visible region need to be invalidated. This
|
|
||||||
// invalidation isn't required for painting the right layer
|
|
||||||
// contents, because these items weren't part of the layer's valid
|
|
||||||
// region, so they'd be painted anyway. It is, however, necessary in
|
|
||||||
// order to get an accurate invalid region for the layer tree that
|
|
||||||
// aLayer is in, for example for partial compositing.
|
|
||||||
// (3) Any changes that happened in the intersection of the old and the
|
|
||||||
// new visible region need to be invalidated. There shouldn't be any
|
|
||||||
// of these when scrolling static content.
|
|
||||||
//
|
|
||||||
// We'd like to guarantee that we won't invalidate anything in the
|
|
||||||
// intersection area of the old and the new visible region if all
|
|
||||||
// invalidation are of type (1) and (2). However, if we just call
|
|
||||||
// aLayer->InvalidateRegion for the invalidations of type (1) and (2),
|
|
||||||
// at some point we'll hit the complexity limit of the layer's invalid
|
|
||||||
// region. And the resulting region simplification can cause the region
|
|
||||||
// to intersect with the intersection of the old and the new visible
|
|
||||||
// region.
|
|
||||||
// In order to get around this problem, we're using the following approach:
|
|
||||||
// - aData->mIgnoreInvalidationsOutsideRect is set to a conservative
|
|
||||||
// approximation of the intersection of the old and the new visible
|
|
||||||
// region. At this point we don't know the layer's new visible region.
|
|
||||||
// - As long as we don't know the layer's new visible region, we ignore all
|
|
||||||
// invalidations outside that rectangle, so roughly some of the
|
|
||||||
// invalidations of type (1) and (2).
|
|
||||||
// - Once we know the layer's new visible region, which happens at some
|
|
||||||
// point during PostprocessRetainedLayers, we invalidate a conservative
|
|
||||||
// approximation of (1) and (2). Specifically, we invalidate the region
|
|
||||||
// union of the old visible bounds and the new visible bounds, minus
|
|
||||||
// aData->mIgnoreInvalidationsOutsideRect. That region is simple enough
|
|
||||||
// that it will never be simplified on its own.
|
|
||||||
// We unset mIgnoreInvalidationsOutsideRect at this point.
|
|
||||||
// - Any other invalidations that happen on the layer after this point, e.g.
|
|
||||||
// during WillEndTransaction, will just happen regularly. If they are of
|
|
||||||
// type (1) or (2), they won't change the layer's invalid region because
|
|
||||||
// they fall inside the region we invalidated in the previous step.
|
|
||||||
// Consequently, aData->mIgnoreInvalidationsOutsideRect is safe from
|
|
||||||
// invalidations as long as there are no invalidations of type (3).
|
|
||||||
aData->mIgnoreInvalidationsOutsideRect =
|
|
||||||
Some(maxNewVisibleBounds.Intersect(aData->mOldVisibleBounds));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ContainerState::PreparePaintedLayerForUse(PaintedLayer* aLayer,
|
ContainerState::PreparePaintedLayerForUse(PaintedLayer* aLayer,
|
||||||
PaintedDisplayItemLayerUserData* aData,
|
PaintedDisplayItemLayerUserData* aData,
|
||||||
|
@ -2356,8 +2257,6 @@ ContainerState::PreparePaintedLayerForUse(PaintedLayer* aLayer,
|
||||||
Matrix matrix = Matrix::Translation(pixOffset.x, pixOffset.y);
|
Matrix matrix = Matrix::Translation(pixOffset.x, pixOffset.y);
|
||||||
aLayer->SetBaseTransform(Matrix4x4::From2D(matrix));
|
aLayer->SetBaseTransform(Matrix4x4::From2D(matrix));
|
||||||
|
|
||||||
ComputeAndSetIgnoreInvalidationRect(aLayer, aData, aAnimatedGeometryRoot, mBuilder, pixOffset);
|
|
||||||
|
|
||||||
aData->mVisibilityComputedRegion.SetEmpty();
|
aData->mVisibilityComputedRegion.SetEmpty();
|
||||||
|
|
||||||
// FIXME: Temporary workaround for bug 681192 and bug 724786.
|
// FIXME: Temporary workaround for bug 681192 and bug 724786.
|
||||||
|
@ -4382,8 +4281,7 @@ FrameLayerBuilder::ComputeGeometryChangeForItem(DisplayItemData* aData)
|
||||||
}
|
}
|
||||||
InvalidatePostTransformRegion(paintedLayer,
|
InvalidatePostTransformRegion(paintedLayer,
|
||||||
combined.ScaleToOutsidePixels(layerData->mXScale, layerData->mYScale, layerData->mAppUnitsPerDevPixel),
|
combined.ScaleToOutsidePixels(layerData->mXScale, layerData->mYScale, layerData->mAppUnitsPerDevPixel),
|
||||||
layerData->mTranslation,
|
layerData->mTranslation);
|
||||||
layerData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
aData->EndUpdate(geometry);
|
aData->EndUpdate(geometry);
|
||||||
|
@ -4512,8 +4410,7 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
|
||||||
}
|
}
|
||||||
|
|
||||||
InvalidatePostTransformRegion(layer, invalid,
|
InvalidatePostTransformRegion(layer, invalid,
|
||||||
GetTranslationForPaintedLayer(layer),
|
GetTranslationForPaintedLayer(layer));
|
||||||
paintedData);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ClippedDisplayItem* cdi =
|
ClippedDisplayItem* cdi =
|
||||||
|
@ -4775,39 +4672,6 @@ ContainerState::SetupScrollingMetadata(NewLayerEntry* aEntry)
|
||||||
aEntry->mLayer->SetAncestorMaskLayers(maskLayers);
|
aEntry->mLayer->SetAncestorMaskLayers(maskLayers);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
InvalidateVisibleBoundsChangesForScrolledLayer(PaintedLayer* aLayer)
|
|
||||||
{
|
|
||||||
PaintedDisplayItemLayerUserData* data =
|
|
||||||
static_cast<PaintedDisplayItemLayerUserData*>(aLayer->GetUserData(&gPaintedDisplayItemLayerUserData));
|
|
||||||
|
|
||||||
if (data->mIgnoreInvalidationsOutsideRect) {
|
|
||||||
// We haven't invalidated anything outside *data->mIgnoreInvalidationsOutsideRect
|
|
||||||
// during DLBI. Now is the right time to do that, because at this point aLayer
|
|
||||||
// knows its new visible region.
|
|
||||||
// We use the visible regions' bounds here (as opposed to the true region)
|
|
||||||
// in order to limit rgn's complexity. The only possible disadvantage of
|
|
||||||
// this is that it might cause us to unnecessarily recomposite parts of the
|
|
||||||
// window that are in the visible region's bounds but not in the visible
|
|
||||||
// region itself, but that is acceptable for scrolled layers.
|
|
||||||
nsIntRegion rgn;
|
|
||||||
rgn.Or(data->mOldVisibleBounds, aLayer->GetVisibleRegion().ToUnknownRegion().GetBounds());
|
|
||||||
rgn.Sub(rgn, *data->mIgnoreInvalidationsOutsideRect);
|
|
||||||
if (!rgn.IsEmpty()) {
|
|
||||||
aLayer->InvalidateRegion(rgn);
|
|
||||||
#ifdef MOZ_DUMP_PAINTING
|
|
||||||
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
|
|
||||||
printf_stderr("Invalidating changes of the visible region bounds of the scrolled contents\n");
|
|
||||||
nsAutoCString str;
|
|
||||||
AppendToString(str, rgn);
|
|
||||||
printf_stderr("Invalidating layer %p: %s\n", aLayer, str.get());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
data->mIgnoreInvalidationsOutsideRect = Nothing();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const Maybe<ParentLayerIntRect>&
|
static inline const Maybe<ParentLayerIntRect>&
|
||||||
GetStationaryClipInContainer(Layer* aLayer)
|
GetStationaryClipInContainer(Layer* aLayer)
|
||||||
{
|
{
|
||||||
|
@ -4856,11 +4720,6 @@ ContainerState::PostprocessRetainedLayers(nsIntRegion* aOpaqueRegionForContainer
|
||||||
e->mLayerContentsVisibleRect.width >= 0 ? &e->mLayerContentsVisibleRect : nullptr,
|
e->mLayerContentsVisibleRect.width >= 0 ? &e->mLayerContentsVisibleRect : nullptr,
|
||||||
e->mUntransformedVisibleRegion);
|
e->mUntransformedVisibleRegion);
|
||||||
|
|
||||||
PaintedLayer* p = e->mLayer->AsPaintedLayer();
|
|
||||||
if (p) {
|
|
||||||
InvalidateVisibleBoundsChangesForScrolledLayer(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!e->mOpaqueRegion.IsEmpty()) {
|
if (!e->mOpaqueRegion.IsEmpty()) {
|
||||||
AnimatedGeometryRoot* animatedGeometryRootToCover = animatedGeometryRootForOpaqueness;
|
AnimatedGeometryRoot* animatedGeometryRootToCover = animatedGeometryRootForOpaqueness;
|
||||||
if (e->mOpaqueForAnimatedGeometryRootParent &&
|
if (e->mOpaqueForAnimatedGeometryRootParent &&
|
||||||
|
|
|
@ -1433,24 +1433,6 @@ nsDisplayListBuilder::AppendNewScrollInfoItemForHoisting(nsDisplayScrollInfoLaye
|
||||||
mScrollInfoItemsForHoisting->AppendNewToTop(aScrollInfoItem);
|
mScrollInfoItemsForHoisting->AppendNewToTop(aScrollInfoItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nsDisplayListBuilder::StoreDirtyRectForScrolledContents(const nsIFrame* aScrollableFrame,
|
|
||||||
const nsRect& aDirty)
|
|
||||||
{
|
|
||||||
mDirtyRectForScrolledContents.Put(const_cast<nsIFrame*>(aScrollableFrame),
|
|
||||||
aDirty + ToReferenceFrame(aScrollableFrame));
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRect
|
|
||||||
nsDisplayListBuilder::GetDirtyRectForScrolledContents(const nsIFrame* aScrollableFrame) const
|
|
||||||
{
|
|
||||||
nsRect result;
|
|
||||||
if (!mDirtyRectForScrolledContents.Get(const_cast<nsIFrame*>(aScrollableFrame), &result)) {
|
|
||||||
return nsRect();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsDisplayListBuilder::IsBuildingLayerEventRegions()
|
nsDisplayListBuilder::IsBuildingLayerEventRegions()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1069,22 +1069,6 @@ public:
|
||||||
|
|
||||||
void AppendNewScrollInfoItemForHoisting(nsDisplayScrollInfoLayer* aScrollInfoItem);
|
void AppendNewScrollInfoItemForHoisting(nsDisplayScrollInfoLayer* aScrollInfoItem);
|
||||||
|
|
||||||
/**
|
|
||||||
* Store the dirty rect of the scrolled contents of aScrollableFrame. This
|
|
||||||
* is a bound for the extents of the new visible region of the scrolled
|
|
||||||
* layer.
|
|
||||||
* @param aScrollableFrame the scrollable frame
|
|
||||||
* @param aDirty the dirty rect, relative to aScrollableFrame
|
|
||||||
*/
|
|
||||||
void StoreDirtyRectForScrolledContents(const nsIFrame* aScrollableFrame, const nsRect& aDirty);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the stored dirty rect for the scrolled contents of aScrollableFrame.
|
|
||||||
* @param aScrollableFrame the scroll frame
|
|
||||||
* @return the dirty rect, relative to aScrollableFrame's *reference frame*
|
|
||||||
*/
|
|
||||||
nsRect GetDirtyRectForScrolledContents(const nsIFrame* aScrollableFrame) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A helper class to install/restore nsDisplayListBuilder::mPreserves3DCtx.
|
* A helper class to install/restore nsDisplayListBuilder::mPreserves3DCtx.
|
||||||
*
|
*
|
||||||
|
@ -1221,9 +1205,6 @@ private:
|
||||||
// Set of frames already counted in budget
|
// Set of frames already counted in budget
|
||||||
nsTHashtable<nsPtrHashKey<nsIFrame> > mAGRBudgetSet;
|
nsTHashtable<nsPtrHashKey<nsIFrame> > mAGRBudgetSet;
|
||||||
|
|
||||||
// rects are relative to the frame's reference frame
|
|
||||||
nsDataHashtable<nsPtrHashKey<nsIFrame>, nsRect> mDirtyRectForScrolledContents;
|
|
||||||
|
|
||||||
// Relative to mCurrentFrame.
|
// Relative to mCurrentFrame.
|
||||||
nsRect mDirtyRect;
|
nsRect mDirtyRect;
|
||||||
nsRegion mWindowExcludeGlassRegion;
|
nsRegion mWindowExcludeGlassRegion;
|
||||||
|
|
|
@ -1218,7 +1218,7 @@ nsLayoutUtils::SetDisplayPortMargins(nsIContent* aContent,
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRect oldDisplayPort;
|
nsRect oldDisplayPort;
|
||||||
bool hadDisplayPort = GetDisplayPort(aContent, &oldDisplayPort);
|
bool hadDisplayPort = GetHighResolutionDisplayPort(aContent, &oldDisplayPort);
|
||||||
|
|
||||||
aContent->SetProperty(nsGkAtoms::DisplayPortMargins,
|
aContent->SetProperty(nsGkAtoms::DisplayPortMargins,
|
||||||
new DisplayPortMarginsPropertyData(
|
new DisplayPortMarginsPropertyData(
|
||||||
|
@ -1226,7 +1226,7 @@ nsLayoutUtils::SetDisplayPortMargins(nsIContent* aContent,
|
||||||
nsINode::DeleteProperty<DisplayPortMarginsPropertyData>);
|
nsINode::DeleteProperty<DisplayPortMarginsPropertyData>);
|
||||||
|
|
||||||
nsRect newDisplayPort;
|
nsRect newDisplayPort;
|
||||||
DebugOnly<bool> hasDisplayPort = GetDisplayPort(aContent, &newDisplayPort);
|
DebugOnly<bool> hasDisplayPort = GetHighResolutionDisplayPort(aContent, &newDisplayPort);
|
||||||
MOZ_ASSERT(hasDisplayPort);
|
MOZ_ASSERT(hasDisplayPort);
|
||||||
|
|
||||||
bool changed = !hadDisplayPort ||
|
bool changed = !hadDisplayPort ||
|
||||||
|
@ -1324,6 +1324,15 @@ nsLayoutUtils::HasCriticalDisplayPort(nsIContent* aContent)
|
||||||
return GetCriticalDisplayPort(aContent, nullptr);
|
return GetCriticalDisplayPort(aContent, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsLayoutUtils::GetHighResolutionDisplayPort(nsIContent* aContent, nsRect* aResult)
|
||||||
|
{
|
||||||
|
if (gfxPrefs::UseLowPrecisionBuffer()) {
|
||||||
|
return GetCriticalDisplayPort(aContent, aResult);
|
||||||
|
}
|
||||||
|
return GetDisplayPort(aContent, aResult);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsLayoutUtils::RemoveDisplayPort(nsIContent* aContent)
|
nsLayoutUtils::RemoveDisplayPort(nsIContent* aContent)
|
||||||
{
|
{
|
||||||
|
|
|
@ -253,6 +253,12 @@ public:
|
||||||
*/
|
*/
|
||||||
static bool HasCriticalDisplayPort(nsIContent* aContent);
|
static bool HasCriticalDisplayPort(nsIContent* aContent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If low-precision painting is turned on, delegates to GetCriticalDisplayPort.
|
||||||
|
* Otherwise, delegates to GetDisplayPort.
|
||||||
|
*/
|
||||||
|
static bool GetHighResolutionDisplayPort(nsIContent* aContent, nsRect* aResult);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the displayport for the given element.
|
* Remove the displayport for the given element.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
</head>
|
</head>
|
||||||
<body onload="setPrefAndStartTest()">
|
<body onload="setPrefAndStartTest()">
|
||||||
<div id="t" style="-moz-transform: scale(1.2, 1.2); -moz-transform-origin:top left; width:200px; height:100px; background:yellow; overflow:hidden">
|
<div id="t" style="-moz-transform: scale(1.2, 1.2); -moz-transform-origin:top left; width:200px; height:500px; background:yellow; overflow:auto">
|
||||||
<div style="height:40px;">Hello</div>
|
<div style="height:40px;">Hello</div>
|
||||||
<div id="e" style="height:30px; background:lime">Kitty</div>
|
<div id="e" style="height:30px; background:lime">Kitty</div>
|
||||||
<div style="height:300px; background:yellow">Kitty</div>
|
<div style="height:800px; background:yellow">Kitty</div>
|
||||||
</div>
|
</div>
|
||||||
<pre id="test">
|
<pre id="test">
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
</head>
|
</head>
|
||||||
<!-- Need a timeout here to allow paint unsuppression before we start the test -->
|
<!-- Need a timeout here to allow paint unsuppression before we start the test -->
|
||||||
<body onload="setTimeout(startTest,0)" style="background:white;">
|
<body onload="setTimeout(startTest,0)" style="background:white;">
|
||||||
<iframe id="t" style="-moz-transform: scale(0.48979); -moz-transform-origin:top left; width:500px; height:300px;"
|
<iframe id="t" style="-moz-transform: scale(0.48979); -moz-transform-origin:top left; width:500px; height:600px;"
|
||||||
src="data:text/html,
|
src="data:text/html,
|
||||||
<body style='background:yellow;'>
|
<body style='background:yellow;'>
|
||||||
<p>My graduate adviser was the most patient, understanding, and helpful
|
<p>My graduate adviser was the most patient, understanding, and helpful
|
||||||
|
@ -33,6 +33,38 @@ scientists.
|
||||||
person I've ever had the joy of dealing with. That doesn't change that
|
person I've ever had the joy of dealing with. That doesn't change that
|
||||||
there are some real dicks out there, and some of them happen to be
|
there are some real dicks out there, and some of them happen to be
|
||||||
scientists.
|
scientists.
|
||||||
|
<p>My graduate adviser was the most patient, understanding, and helpful
|
||||||
|
person I've ever had the joy of dealing with. That doesn't change that
|
||||||
|
there are some real dicks out there, and some of them happen to be
|
||||||
|
scientists.
|
||||||
|
<p>My graduate adviser was the most patient, understanding, and helpful
|
||||||
|
person I've ever had the joy of dealing with. That doesn't change that
|
||||||
|
there are some real dicks out there, and some of them happen to be
|
||||||
|
scientists.
|
||||||
|
<p>My graduate adviser was the most patient, understanding, and helpful
|
||||||
|
person I've ever had the joy of dealing with. That doesn't change that
|
||||||
|
there are some real dicks out there, and some of them happen to be
|
||||||
|
scientists.
|
||||||
|
<p>My graduate adviser was the most patient, understanding, and helpful
|
||||||
|
person I've ever had the joy of dealing with. That doesn't change that
|
||||||
|
there are some real dicks out there, and some of them happen to be
|
||||||
|
scientists.
|
||||||
|
<p>My graduate adviser was the most patient, understanding, and helpful
|
||||||
|
person I've ever had the joy of dealing with. That doesn't change that
|
||||||
|
there are some real dicks out there, and some of them happen to be
|
||||||
|
scientists.
|
||||||
|
<p>My graduate adviser was the most patient, understanding, and helpful
|
||||||
|
person I've ever had the joy of dealing with. That doesn't change that
|
||||||
|
there are some real dicks out there, and some of them happen to be
|
||||||
|
scientists.
|
||||||
|
<p>My graduate adviser was the most patient, understanding, and helpful
|
||||||
|
person I've ever had the joy of dealing with. That doesn't change that
|
||||||
|
there are some real dicks out there, and some of them happen to be
|
||||||
|
scientists.
|
||||||
|
<p>My graduate adviser was the most patient, understanding, and helpful
|
||||||
|
person I've ever had the joy of dealing with. That doesn't change that
|
||||||
|
there are some real dicks out there, and some of them happen to be
|
||||||
|
scientists.
|
||||||
</body>"></iframe>
|
</body>"></iframe>
|
||||||
<pre id="test">
|
<pre id="test">
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
|
|
||||||
using mozilla::dom::Element;
|
using mozilla::dom::Element;
|
||||||
|
|
||||||
nsColorControlFrame::nsColorControlFrame(nsStyleContext* aContext):
|
nsColorControlFrame::nsColorControlFrame(nsStyleContext* aContext)
|
||||||
nsColorControlFrameSuper(aContext)
|
: nsHTMLButtonControlFrame(aContext)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,14 +36,14 @@ NS_IMPL_FRAMEARENA_HELPERS(nsColorControlFrame)
|
||||||
NS_QUERYFRAME_HEAD(nsColorControlFrame)
|
NS_QUERYFRAME_HEAD(nsColorControlFrame)
|
||||||
NS_QUERYFRAME_ENTRY(nsColorControlFrame)
|
NS_QUERYFRAME_ENTRY(nsColorControlFrame)
|
||||||
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
|
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
|
||||||
NS_QUERYFRAME_TAIL_INHERITING(nsColorControlFrameSuper)
|
NS_QUERYFRAME_TAIL_INHERITING(nsHTMLButtonControlFrame)
|
||||||
|
|
||||||
|
|
||||||
void nsColorControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
void nsColorControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||||
{
|
{
|
||||||
nsFormControlFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), false);
|
nsFormControlFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), false);
|
||||||
nsContentUtils::DestroyAnonymousContent(&mColorContent);
|
nsContentUtils::DestroyAnonymousContent(&mColorContent);
|
||||||
nsColorControlFrameSuper::DestroyFrom(aDestructRoot);
|
nsHTMLButtonControlFrame::DestroyFrom(aDestructRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIAtom*
|
nsIAtom*
|
||||||
|
@ -126,7 +126,7 @@ nsColorControlFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||||
aNameSpaceID == kNameSpaceID_None && nsGkAtoms::value == aAttribute) {
|
aNameSpaceID == kNameSpaceID_None && nsGkAtoms::value == aAttribute) {
|
||||||
UpdateColor();
|
UpdateColor();
|
||||||
}
|
}
|
||||||
return nsColorControlFrameSuper::AttributeChanged(aNameSpaceID, aAttribute,
|
return nsHTMLButtonControlFrame::AttributeChanged(aNameSpaceID, aAttribute,
|
||||||
aModType);
|
aModType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,9 @@ namespace mozilla {
|
||||||
enum class CSSPseudoElementType : uint8_t;
|
enum class CSSPseudoElementType : uint8_t;
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
typedef nsHTMLButtonControlFrame nsColorControlFrameSuper;
|
|
||||||
|
|
||||||
// Class which implements the input type=color
|
// Class which implements the input type=color
|
||||||
|
|
||||||
class nsColorControlFrame final : public nsColorControlFrameSuper,
|
class nsColorControlFrame final : public nsHTMLButtonControlFrame,
|
||||||
public nsIAnonymousContentCreator
|
public nsIAnonymousContentCreator
|
||||||
{
|
{
|
||||||
typedef mozilla::CSSPseudoElementType CSSPseudoElementType;
|
typedef mozilla::CSSPseudoElementType CSSPseudoElementType;
|
||||||
|
|
|
@ -17,8 +17,8 @@ using namespace mozilla;
|
||||||
|
|
||||||
//#define FCF_NOISY
|
//#define FCF_NOISY
|
||||||
|
|
||||||
nsFormControlFrame::nsFormControlFrame(nsStyleContext* aContext) :
|
nsFormControlFrame::nsFormControlFrame(nsStyleContext* aContext)
|
||||||
nsFormControlFrameSuper(aContext)
|
: nsAtomicContainerFrame(aContext)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ nsFormControlFrame::~nsFormControlFrame()
|
||||||
nsIAtom*
|
nsIAtom*
|
||||||
nsFormControlFrame::GetType() const
|
nsFormControlFrame::GetType() const
|
||||||
{
|
{
|
||||||
return nsGkAtoms::formControlFrame;
|
return nsGkAtoms::formControlFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -37,12 +37,12 @@ nsFormControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||||
{
|
{
|
||||||
// Unregister the access key registered in reflow
|
// Unregister the access key registered in reflow
|
||||||
nsFormControlFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), false);
|
nsFormControlFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), false);
|
||||||
nsFormControlFrameSuper::DestroyFrom(aDestructRoot);
|
nsAtomicContainerFrame::DestroyFrom(aDestructRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_QUERYFRAME_HEAD(nsFormControlFrame)
|
NS_QUERYFRAME_HEAD(nsFormControlFrame)
|
||||||
NS_QUERYFRAME_ENTRY(nsIFormControlFrame)
|
NS_QUERYFRAME_ENTRY(nsIFormControlFrame)
|
||||||
NS_QUERYFRAME_TAIL_INHERITING(nsFormControlFrameSuper)
|
NS_QUERYFRAME_TAIL_INHERITING(nsAtomicContainerFrame)
|
||||||
|
|
||||||
/* virtual */ nscoord
|
/* virtual */ nscoord
|
||||||
nsFormControlFrame::GetMinISize(nsRenderingContext *aRenderingContext)
|
nsFormControlFrame::GetMinISize(nsRenderingContext *aRenderingContext)
|
||||||
|
|
|
@ -11,14 +11,12 @@
|
||||||
#include "nsAtomicContainerFrame.h"
|
#include "nsAtomicContainerFrame.h"
|
||||||
#include "nsDisplayList.h"
|
#include "nsDisplayList.h"
|
||||||
|
|
||||||
typedef nsAtomicContainerFrame nsFormControlFrameSuper;
|
/**
|
||||||
|
|
||||||
/**
|
|
||||||
* nsFormControlFrame is the base class for radio buttons and
|
* nsFormControlFrame is the base class for radio buttons and
|
||||||
* checkboxes. It also has two static methods (RegUnRegAccessKey and
|
* checkboxes. It also has two static methods (RegUnRegAccessKey and
|
||||||
* GetScreenHeight) that are used by other form controls.
|
* GetScreenHeight) that are used by other form controls.
|
||||||
*/
|
*/
|
||||||
class nsFormControlFrame : public nsFormControlFrameSuper,
|
class nsFormControlFrame : public nsAtomicContainerFrame,
|
||||||
public nsIFormControlFrame
|
public nsIFormControlFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -33,7 +31,7 @@ public:
|
||||||
|
|
||||||
virtual bool IsFrameOfType(uint32_t aFlags) const override
|
virtual bool IsFrameOfType(uint32_t aFlags) const override
|
||||||
{
|
{
|
||||||
return nsFormControlFrameSuper::IsFrameOfType(aFlags &
|
return nsAtomicContainerFrame::IsFrameOfType(aFlags &
|
||||||
~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
|
~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,11 +66,11 @@ public:
|
||||||
const mozilla::LogicalSize& aPadding,
|
const mozilla::LogicalSize& aPadding,
|
||||||
bool aShrinkWrap) override;
|
bool aShrinkWrap) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Respond to a gui event
|
* Respond to a gui event
|
||||||
* @see nsIFrame::HandleEvent
|
* @see nsIFrame::HandleEvent
|
||||||
*/
|
*/
|
||||||
virtual nsresult HandleEvent(nsPresContext* aPresContext,
|
virtual nsresult HandleEvent(nsPresContext* aPresContext,
|
||||||
mozilla::WidgetGUIEvent* aEvent,
|
mozilla::WidgetGUIEvent* aEvent,
|
||||||
nsEventStatus* aEventStatus) override;
|
nsEventStatus* aEventStatus) override;
|
||||||
|
|
||||||
|
@ -117,7 +115,7 @@ protected:
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
// Utility methods for managing checkboxes and radiobuttons
|
// Utility methods for managing checkboxes and radiobuttons
|
||||||
//-------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
/**
|
/**
|
||||||
* Get the state of the checked attribute.
|
* Get the state of the checked attribute.
|
||||||
* @param aState set to true if the checked attribute is set,
|
* @param aState set to true if the checked attribute is set,
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
typedef nsImageFrame nsImageControlFrameSuper;
|
class nsImageControlFrame : public nsImageFrame,
|
||||||
class nsImageControlFrame : public nsImageControlFrameSuper,
|
|
||||||
public nsIFormControlFrame
|
public nsIFormControlFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -56,13 +55,13 @@ public:
|
||||||
nsIFrame::Cursor& aCursor) override;
|
nsIFrame::Cursor& aCursor) override;
|
||||||
// nsIFormContromFrame
|
// nsIFormContromFrame
|
||||||
virtual void SetFocus(bool aOn, bool aRepaint) override;
|
virtual void SetFocus(bool aOn, bool aRepaint) override;
|
||||||
virtual nsresult SetFormProperty(nsIAtom* aName,
|
virtual nsresult SetFormProperty(nsIAtom* aName,
|
||||||
const nsAString& aValue) override;
|
const nsAString& aValue) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
nsImageControlFrame::nsImageControlFrame(nsStyleContext* aContext):
|
nsImageControlFrame::nsImageControlFrame(nsStyleContext* aContext)
|
||||||
nsImageControlFrameSuper(aContext)
|
: nsImageFrame(aContext)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +75,7 @@ nsImageControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||||
if (!GetPrevInFlow()) {
|
if (!GetPrevInFlow()) {
|
||||||
nsFormControlFrame::RegUnRegAccessKey(this, false);
|
nsFormControlFrame::RegUnRegAccessKey(this, false);
|
||||||
}
|
}
|
||||||
nsImageControlFrameSuper::DestroyFrom(aDestructRoot);
|
nsImageFrame::DestroyFrom(aDestructRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIFrame*
|
nsIFrame*
|
||||||
|
@ -92,12 +91,12 @@ nsImageControlFrame::Init(nsIContent* aContent,
|
||||||
nsContainerFrame* aParent,
|
nsContainerFrame* aParent,
|
||||||
nsIFrame* aPrevInFlow)
|
nsIFrame* aPrevInFlow)
|
||||||
{
|
{
|
||||||
nsImageControlFrameSuper::Init(aContent, aParent, aPrevInFlow);
|
nsImageFrame::Init(aContent, aParent, aPrevInFlow);
|
||||||
|
|
||||||
if (aPrevInFlow) {
|
if (aPrevInFlow) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mContent->SetProperty(nsGkAtoms::imageClickedPoint,
|
mContent->SetProperty(nsGkAtoms::imageClickedPoint,
|
||||||
new nsIntPoint(0, 0),
|
new nsIntPoint(0, 0),
|
||||||
nsINode::DeleteProperty<nsIntPoint>);
|
nsINode::DeleteProperty<nsIntPoint>);
|
||||||
|
@ -105,7 +104,7 @@ nsImageControlFrame::Init(nsIContent* aContent,
|
||||||
|
|
||||||
NS_QUERYFRAME_HEAD(nsImageControlFrame)
|
NS_QUERYFRAME_HEAD(nsImageControlFrame)
|
||||||
NS_QUERYFRAME_ENTRY(nsIFormControlFrame)
|
NS_QUERYFRAME_ENTRY(nsIFormControlFrame)
|
||||||
NS_QUERYFRAME_TAIL_INHERITING(nsImageControlFrameSuper)
|
NS_QUERYFRAME_TAIL_INHERITING(nsImageFrame)
|
||||||
|
|
||||||
#ifdef ACCESSIBILITY
|
#ifdef ACCESSIBILITY
|
||||||
a11y::AccType
|
a11y::AccType
|
||||||
|
@ -122,7 +121,7 @@ nsImageControlFrame::AccessibleType()
|
||||||
nsIAtom*
|
nsIAtom*
|
||||||
nsImageControlFrame::GetType() const
|
nsImageControlFrame::GetType() const
|
||||||
{
|
{
|
||||||
return nsGkAtoms::imageControlFrame;
|
return nsGkAtoms::imageControlFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -136,10 +135,10 @@ nsImageControlFrame::Reflow(nsPresContext* aPresContext,
|
||||||
if (!GetPrevInFlow() && (mState & NS_FRAME_FIRST_REFLOW)) {
|
if (!GetPrevInFlow() && (mState & NS_FRAME_FIRST_REFLOW)) {
|
||||||
nsFormControlFrame::RegUnRegAccessKey(this, true);
|
nsFormControlFrame::RegUnRegAccessKey(this, true);
|
||||||
}
|
}
|
||||||
return nsImageControlFrameSuper::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
|
return nsImageFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsImageControlFrame::HandleEvent(nsPresContext* aPresContext,
|
nsImageControlFrame::HandleEvent(nsPresContext* aPresContext,
|
||||||
WidgetGUIEvent* aEvent,
|
WidgetGUIEvent* aEvent,
|
||||||
nsEventStatus* aEventStatus)
|
nsEventStatus* aEventStatus)
|
||||||
|
@ -175,11 +174,10 @@ nsImageControlFrame::HandleEvent(nsPresContext* aPresContext,
|
||||||
TranslateEventCoords(pt, *lastClickPoint);
|
TranslateEventCoords(pt, *lastClickPoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nsImageControlFrameSuper::HandleEvent(aPresContext, aEvent,
|
return nsImageFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
||||||
aEventStatus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsImageControlFrame::SetFocus(bool aOn, bool aRepaint)
|
nsImageControlFrame::SetFocus(bool aOn, bool aRepaint)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -2030,7 +2030,7 @@ public:
|
||||||
|
|
||||||
NS_QUERYFRAME_HEAD(nsFlexContainerFrame)
|
NS_QUERYFRAME_HEAD(nsFlexContainerFrame)
|
||||||
NS_QUERYFRAME_ENTRY(nsFlexContainerFrame)
|
NS_QUERYFRAME_ENTRY(nsFlexContainerFrame)
|
||||||
NS_QUERYFRAME_TAIL_INHERITING(nsFlexContainerFrameSuper)
|
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
|
||||||
|
|
||||||
NS_IMPL_FRAMEARENA_HELPERS(nsFlexContainerFrame)
|
NS_IMPL_FRAMEARENA_HELPERS(nsFlexContainerFrame)
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,7 @@ class LogicalPoint;
|
||||||
nsContainerFrame* NS_NewFlexContainerFrame(nsIPresShell* aPresShell,
|
nsContainerFrame* NS_NewFlexContainerFrame(nsIPresShell* aPresShell,
|
||||||
nsStyleContext* aContext);
|
nsStyleContext* aContext);
|
||||||
|
|
||||||
typedef nsContainerFrame nsFlexContainerFrameSuper;
|
class nsFlexContainerFrame : public nsContainerFrame {
|
||||||
|
|
||||||
class nsFlexContainerFrame : public nsFlexContainerFrameSuper {
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_FRAMEARENA_HELPERS
|
NS_DECL_FRAMEARENA_HELPERS
|
||||||
NS_DECL_QUERYFRAME_TARGET(nsFlexContainerFrame)
|
NS_DECL_QUERYFRAME_TARGET(nsFlexContainerFrame)
|
||||||
|
@ -62,8 +60,8 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Protected constructor & destructor
|
// Protected constructor & destructor
|
||||||
explicit nsFlexContainerFrame(nsStyleContext* aContext) :
|
explicit nsFlexContainerFrame(nsStyleContext* aContext)
|
||||||
nsFlexContainerFrameSuper(aContext)
|
: nsContainerFrame(aContext)
|
||||||
{}
|
{}
|
||||||
virtual ~nsFlexContainerFrame();
|
virtual ~nsFlexContainerFrame();
|
||||||
|
|
||||||
|
|
|
@ -2709,7 +2709,7 @@ ScrollFrameHelper::ScrollToImpl(nsPoint aPt, const nsRect& aRange, nsIAtom* aOri
|
||||||
|
|
||||||
nsRect oldDisplayPort;
|
nsRect oldDisplayPort;
|
||||||
nsIContent* content = mOuter->GetContent();
|
nsIContent* content = mOuter->GetContent();
|
||||||
nsLayoutUtils::GetDisplayPort(content, &oldDisplayPort);
|
nsLayoutUtils::GetHighResolutionDisplayPort(content, &oldDisplayPort);
|
||||||
oldDisplayPort.MoveBy(-mScrolledFrame->GetPosition());
|
oldDisplayPort.MoveBy(-mScrolledFrame->GetPosition());
|
||||||
|
|
||||||
// Update frame position for scrolling
|
// Update frame position for scrolling
|
||||||
|
@ -2735,20 +2735,18 @@ ScrollFrameHelper::ScrollToImpl(nsPoint aPt, const nsRect& aRange, nsIAtom* aOri
|
||||||
// skip the paint.
|
// skip the paint.
|
||||||
nsRect displayPort;
|
nsRect displayPort;
|
||||||
bool usingDisplayPort =
|
bool usingDisplayPort =
|
||||||
nsLayoutUtils::GetDisplayPort(content, &displayPort);
|
nsLayoutUtils::GetHighResolutionDisplayPort(content, &displayPort);
|
||||||
displayPort.MoveBy(-mScrolledFrame->GetPosition());
|
displayPort.MoveBy(-mScrolledFrame->GetPosition());
|
||||||
|
|
||||||
PAINT_SKIP_LOG("New scrollpos %s usingDP %d dpEqual %d scrollableByApz %d plugins %d sle %d\n",
|
PAINT_SKIP_LOG("New scrollpos %s usingDP %d dpEqual %d scrollableByApz %d plugins %d\n",
|
||||||
Stringify(CSSPoint::FromAppUnits(GetScrollPosition())).c_str(),
|
Stringify(CSSPoint::FromAppUnits(GetScrollPosition())).c_str(),
|
||||||
usingDisplayPort, displayPort.IsEqualEdges(oldDisplayPort),
|
usingDisplayPort, displayPort.IsEqualEdges(oldDisplayPort),
|
||||||
mScrollableByAPZ, HasPluginFrames(),
|
mScrollableByAPZ, HasPluginFrames());
|
||||||
content->GetComposedDoc()->HasScrollLinkedEffect());
|
|
||||||
if (usingDisplayPort && displayPort.IsEqualEdges(oldDisplayPort)) {
|
if (usingDisplayPort && displayPort.IsEqualEdges(oldDisplayPort)) {
|
||||||
if (LastScrollOrigin() == nsGkAtoms::apz) {
|
if (LastScrollOrigin() == nsGkAtoms::apz) {
|
||||||
schedulePaint = false;
|
schedulePaint = false;
|
||||||
PAINT_SKIP_LOG("Skipping due to APZ scroll\n");
|
PAINT_SKIP_LOG("Skipping due to APZ scroll\n");
|
||||||
} else if (mScrollableByAPZ && !HasPluginFrames() &&
|
} else if (mScrollableByAPZ && !HasPluginFrames()) {
|
||||||
!content->GetComposedDoc()->HasScrollLinkedEffect()) {
|
|
||||||
nsIWidget* widget = presContext->GetNearestWidget();
|
nsIWidget* widget = presContext->GetNearestWidget();
|
||||||
LayerManager* manager = widget ? widget->GetLayerManager() : nullptr;
|
LayerManager* manager = widget ? widget->GetLayerManager() : nullptr;
|
||||||
if (manager) {
|
if (manager) {
|
||||||
|
@ -3336,7 +3334,6 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||||
MOZ_ASSERT(!inactiveScrollClip->mIsAsyncScrollable);
|
MOZ_ASSERT(!inactiveScrollClip->mIsAsyncScrollable);
|
||||||
}
|
}
|
||||||
|
|
||||||
aBuilder->StoreDirtyRectForScrolledContents(mOuter, dirtyRect);
|
|
||||||
mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, dirtyRect, scrolledContent);
|
mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, dirtyRect, scrolledContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@ NS_IMPL_FRAMEARENA_HELPERS(nsImageFrame)
|
||||||
|
|
||||||
|
|
||||||
nsImageFrame::nsImageFrame(nsStyleContext* aContext) :
|
nsImageFrame::nsImageFrame(nsStyleContext* aContext) :
|
||||||
ImageFrameSuper(aContext),
|
nsAtomicContainerFrame(aContext),
|
||||||
mComputedSize(0, 0),
|
mComputedSize(0, 0),
|
||||||
mIntrinsicRatio(0, 0),
|
mIntrinsicRatio(0, 0),
|
||||||
mDisplayingIcon(false),
|
mDisplayingIcon(false),
|
||||||
|
@ -158,7 +158,7 @@ nsImageFrame::~nsImageFrame()
|
||||||
|
|
||||||
NS_QUERYFRAME_HEAD(nsImageFrame)
|
NS_QUERYFRAME_HEAD(nsImageFrame)
|
||||||
NS_QUERYFRAME_ENTRY(nsImageFrame)
|
NS_QUERYFRAME_ENTRY(nsImageFrame)
|
||||||
NS_QUERYFRAME_TAIL_INHERITING(ImageFrameSuper)
|
NS_QUERYFRAME_TAIL_INHERITING(nsAtomicContainerFrame)
|
||||||
|
|
||||||
#ifdef ACCESSIBILITY
|
#ifdef ACCESSIBILITY
|
||||||
a11y::AccType
|
a11y::AccType
|
||||||
|
@ -222,13 +222,13 @@ nsImageFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||||
if (mDisplayingIcon)
|
if (mDisplayingIcon)
|
||||||
gIconLoad->RemoveIconObserver(this);
|
gIconLoad->RemoveIconObserver(this);
|
||||||
|
|
||||||
ImageFrameSuper::DestroyFrom(aDestructRoot);
|
nsAtomicContainerFrame::DestroyFrom(aDestructRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsImageFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
nsImageFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
||||||
{
|
{
|
||||||
ImageFrameSuper::DidSetStyleContext(aOldStyleContext);
|
nsAtomicContainerFrame::DidSetStyleContext(aOldStyleContext);
|
||||||
|
|
||||||
if (!mImage) {
|
if (!mImage) {
|
||||||
// We'll pick this change up whenever we do get an image.
|
// We'll pick this change up whenever we do get an image.
|
||||||
|
@ -258,7 +258,7 @@ nsImageFrame::Init(nsIContent* aContent,
|
||||||
nsContainerFrame* aParent,
|
nsContainerFrame* aParent,
|
||||||
nsIFrame* aPrevInFlow)
|
nsIFrame* aPrevInFlow)
|
||||||
{
|
{
|
||||||
ImageFrameSuper::Init(aContent, aParent, aPrevInFlow);
|
nsAtomicContainerFrame::Init(aContent, aParent, aPrevInFlow);
|
||||||
|
|
||||||
mListener = new nsImageListener(this);
|
mListener = new nsImageListener(this);
|
||||||
|
|
||||||
|
@ -1998,7 +1998,7 @@ nsImageFrame::HandleEvent(nsPresContext* aPresContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ImageFrameSuper::HandleEvent(aPresContext, aEvent, aEventStatus);
|
return nsAtomicContainerFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -2035,8 +2035,8 @@ nsImageFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||||
nsIAtom* aAttribute,
|
nsIAtom* aAttribute,
|
||||||
int32_t aModType)
|
int32_t aModType)
|
||||||
{
|
{
|
||||||
nsresult rv = ImageFrameSuper::AttributeChanged(aNameSpaceID,
|
nsresult rv = nsAtomicContainerFrame::AttributeChanged(aNameSpaceID,
|
||||||
aAttribute, aModType);
|
aAttribute, aModType);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -2057,7 +2057,7 @@ nsImageFrame::OnVisibilityChange(Visibility aNewVisibility,
|
||||||
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
|
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
|
||||||
if (!imageLoader) {
|
if (!imageLoader) {
|
||||||
MOZ_ASSERT_UNREACHABLE("Should have an nsIImageLoadingContent");
|
MOZ_ASSERT_UNREACHABLE("Should have an nsIImageLoadingContent");
|
||||||
ImageFrameSuper::OnVisibilityChange(aNewVisibility, aNonvisibleAction);
|
nsAtomicContainerFrame::OnVisibilityChange(aNewVisibility, aNonvisibleAction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2067,7 +2067,7 @@ nsImageFrame::OnVisibilityChange(Visibility aNewVisibility,
|
||||||
MaybeDecodeForPredictedSize();
|
MaybeDecodeForPredictedSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageFrameSuper::OnVisibilityChange(aNewVisibility, aNonvisibleAction);
|
nsAtomicContainerFrame::OnVisibilityChange(aNewVisibility, aNonvisibleAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIAtom*
|
nsIAtom*
|
||||||
|
|
|
@ -58,10 +58,8 @@ private:
|
||||||
nsImageFrame *mFrame;
|
nsImageFrame *mFrame;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef nsAtomicContainerFrame ImageFrameSuper;
|
class nsImageFrame : public nsAtomicContainerFrame
|
||||||
|
, public nsIReflowCallback {
|
||||||
class nsImageFrame : public ImageFrameSuper,
|
|
||||||
public nsIReflowCallback {
|
|
||||||
public:
|
public:
|
||||||
template <typename T> using Maybe = mozilla::Maybe<T>;
|
template <typename T> using Maybe = mozilla::Maybe<T>;
|
||||||
using Nothing = mozilla::Nothing;
|
using Nothing = mozilla::Nothing;
|
||||||
|
@ -119,7 +117,7 @@ public:
|
||||||
|
|
||||||
virtual bool IsFrameOfType(uint32_t aFlags) const override
|
virtual bool IsFrameOfType(uint32_t aFlags) const override
|
||||||
{
|
{
|
||||||
return ImageFrameSuper::IsFrameOfType(aFlags &
|
return nsAtomicContainerFrame::IsFrameOfType(aFlags &
|
||||||
~(nsIFrame::eReplaced | nsIFrame::eReplacedSizing));
|
~(nsIFrame::eReplaced | nsIFrame::eReplacedSizing));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ nsInlineFrame::InvalidateFrame(uint32_t aDisplayItemKey)
|
||||||
svgTextFrame->InvalidateFrame();
|
svgTextFrame->InvalidateFrame();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nsInlineFrameBase::InvalidateFrame(aDisplayItemKey);
|
nsContainerFrame::InvalidateFrame(aDisplayItemKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -84,7 +84,7 @@ nsInlineFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayIte
|
||||||
svgTextFrame->InvalidateFrame();
|
svgTextFrame->InvalidateFrame();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nsInlineFrameBase::InvalidateFrameWithRect(aRect, aDisplayItemKey);
|
nsContainerFrame::InvalidateFrameWithRect(aRect, aDisplayItemKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
|
@ -482,7 +482,7 @@ nsInlineFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||||
int32_t aModType)
|
int32_t aModType)
|
||||||
{
|
{
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
nsInlineFrameBase::AttributeChanged(aNameSpaceID, aAttribute, aModType);
|
nsContainerFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
|
|
|
@ -13,15 +13,13 @@
|
||||||
|
|
||||||
class nsLineLayout;
|
class nsLineLayout;
|
||||||
|
|
||||||
typedef nsContainerFrame nsInlineFrameBase;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inline frame class.
|
* Inline frame class.
|
||||||
*
|
*
|
||||||
* This class manages a list of child frames that are inline frames. Working with
|
* This class manages a list of child frames that are inline frames. Working with
|
||||||
* nsLineLayout, the class will reflow and place inline frames on a line.
|
* nsLineLayout, the class will reflow and place inline frames on a line.
|
||||||
*/
|
*/
|
||||||
class nsInlineFrame : public nsInlineFrameBase
|
class nsInlineFrame : public nsContainerFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_QUERYFRAME_TARGET(nsInlineFrame)
|
NS_DECL_QUERYFRAME_TARGET(nsInlineFrame)
|
||||||
|
|
|
@ -150,7 +150,7 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
nsPluginFrame::nsPluginFrame(nsStyleContext* aContext)
|
nsPluginFrame::nsPluginFrame(nsStyleContext* aContext)
|
||||||
: nsPluginFrameSuper(aContext)
|
: nsFrame(aContext)
|
||||||
, mInstanceOwner(nullptr)
|
, mInstanceOwner(nullptr)
|
||||||
, mReflowCallbackPosted(false)
|
, mReflowCallbackPosted(false)
|
||||||
, mIsHiddenDueToScroll(false)
|
, mIsHiddenDueToScroll(false)
|
||||||
|
@ -168,7 +168,7 @@ nsPluginFrame::~nsPluginFrame()
|
||||||
NS_QUERYFRAME_HEAD(nsPluginFrame)
|
NS_QUERYFRAME_HEAD(nsPluginFrame)
|
||||||
NS_QUERYFRAME_ENTRY(nsPluginFrame)
|
NS_QUERYFRAME_ENTRY(nsPluginFrame)
|
||||||
NS_QUERYFRAME_ENTRY(nsIObjectFrame)
|
NS_QUERYFRAME_ENTRY(nsIObjectFrame)
|
||||||
NS_QUERYFRAME_TAIL_INHERITING(nsPluginFrameSuper)
|
NS_QUERYFRAME_TAIL_INHERITING(nsFrame)
|
||||||
|
|
||||||
#ifdef ACCESSIBILITY
|
#ifdef ACCESSIBILITY
|
||||||
a11y::AccType
|
a11y::AccType
|
||||||
|
@ -194,7 +194,7 @@ nsPluginFrame::Init(nsIContent* aContent,
|
||||||
MOZ_LOG(sPluginFrameLog, LogLevel::Debug,
|
MOZ_LOG(sPluginFrameLog, LogLevel::Debug,
|
||||||
("Initializing nsPluginFrame %p for content %p\n", this, aContent));
|
("Initializing nsPluginFrame %p for content %p\n", this, aContent));
|
||||||
|
|
||||||
nsPluginFrameSuper::Init(aContent, aParent, aPrevInFlow);
|
nsFrame::Init(aContent, aParent, aPrevInFlow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -223,7 +223,7 @@ nsPluginFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||||
mBackgroundSink->Destroy();
|
mBackgroundSink->Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsPluginFrameSuper::DestroyFrom(aDestructRoot);
|
nsFrame::DestroyFrom(aDestructRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ void
|
/* virtual */ void
|
||||||
|
@ -239,7 +239,7 @@ nsPluginFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsPluginFrameSuper::DidSetStyleContext(aOldStyleContext);
|
nsFrame::DidSetStyleContext(aOldStyleContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIAtom*
|
nsIAtom*
|
||||||
|
@ -737,7 +737,7 @@ nsPluginFrame::IsFocusable(int32_t *aTabIndex, bool aWithMouse)
|
||||||
{
|
{
|
||||||
if (aTabIndex)
|
if (aTabIndex)
|
||||||
*aTabIndex = -1;
|
*aTabIndex = -1;
|
||||||
return nsPluginFrameSuper::IsFocusable(aTabIndex, aWithMouse);
|
return nsFrame::IsFocusable(aTabIndex, aWithMouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -851,7 +851,7 @@ nsPluginFrame::DidReflow(nsPresContext* aPresContext,
|
||||||
objContent->HasNewFrame(this);
|
objContent->HasNewFrame(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsPluginFrameSuper::DidReflow(aPresContext, aReflowState, aStatus);
|
nsFrame::DidReflow(aPresContext, aReflowState, aStatus);
|
||||||
|
|
||||||
// The view is created hidden; once we have reflowed it and it has been
|
// The view is created hidden; once we have reflowed it and it has been
|
||||||
// positioned then we show it.
|
// positioned then we show it.
|
||||||
|
@ -1670,7 +1670,7 @@ nsPluginFrame::HandleEvent(nsPresContext* aPresContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
rv = nsPluginFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus);
|
rv = nsFrame::HandleEvent(aPresContext, anEvent, anEventStatus);
|
||||||
return rv;
|
return rv;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1694,10 +1694,10 @@ nsPluginFrame::HandleEvent(nsPresContext* aPresContext,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rv = nsPluginFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus);
|
rv = nsFrame::HandleEvent(aPresContext, anEvent, anEventStatus);
|
||||||
|
|
||||||
// We need to be careful from this point because the call to
|
// We need to be careful from this point because the call to
|
||||||
// nsPluginFrameSuper::HandleEvent() might have killed us.
|
// nsFrame::HandleEvent() might have killed us.
|
||||||
|
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
if (anEvent->mMessage == eMouseUp) {
|
if (anEvent->mMessage == eMouseUp) {
|
||||||
|
@ -1782,7 +1782,7 @@ nsPluginFrame::GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nsPluginFrameSuper::GetCursor(aPoint, aCursor);
|
return nsFrame::GetCursor(aPoint, aCursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -42,13 +42,11 @@ class LayerManager;
|
||||||
} // namespace layers
|
} // namespace layers
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
typedef nsFrame nsPluginFrameSuper;
|
|
||||||
|
|
||||||
class PluginFrameDidCompositeObserver;
|
class PluginFrameDidCompositeObserver;
|
||||||
|
|
||||||
class nsPluginFrame : public nsPluginFrameSuper,
|
class nsPluginFrame : public nsFrame
|
||||||
public nsIObjectFrame,
|
, public nsIObjectFrame
|
||||||
public nsIReflowCallback
|
, public nsIReflowCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef mozilla::LayerState LayerState;
|
typedef mozilla::LayerState LayerState;
|
||||||
|
@ -91,7 +89,7 @@ public:
|
||||||
|
|
||||||
virtual bool IsFrameOfType(uint32_t aFlags) const override
|
virtual bool IsFrameOfType(uint32_t aFlags) const override
|
||||||
{
|
{
|
||||||
return nsPluginFrameSuper::IsFrameOfType(aFlags &
|
return nsFrame::IsFrameOfType(aFlags &
|
||||||
~(nsIFrame::eReplaced | nsIFrame::eReplacedSizing));
|
~(nsIFrame::eReplaced | nsIFrame::eReplacedSizing));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ using namespace mozilla;
|
||||||
|
|
||||||
NS_QUERYFRAME_HEAD(nsRubyBaseFrame)
|
NS_QUERYFRAME_HEAD(nsRubyBaseFrame)
|
||||||
NS_QUERYFRAME_ENTRY(nsRubyBaseFrame)
|
NS_QUERYFRAME_ENTRY(nsRubyBaseFrame)
|
||||||
NS_QUERYFRAME_TAIL_INHERITING(nsRubyBaseFrameSuper)
|
NS_QUERYFRAME_TAIL_INHERITING(nsRubyContentFrame)
|
||||||
|
|
||||||
NS_IMPL_FRAMEARENA_HELPERS(nsRubyBaseFrame)
|
NS_IMPL_FRAMEARENA_HELPERS(nsRubyBaseFrame)
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
|
|
||||||
#include "nsRubyContentFrame.h"
|
#include "nsRubyContentFrame.h"
|
||||||
|
|
||||||
typedef nsRubyContentFrame nsRubyBaseFrameSuper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory function.
|
* Factory function.
|
||||||
* @return a newly allocated nsRubyBaseFrame (infallible)
|
* @return a newly allocated nsRubyBaseFrame (infallible)
|
||||||
|
@ -20,7 +18,7 @@ typedef nsRubyContentFrame nsRubyBaseFrameSuper;
|
||||||
nsContainerFrame* NS_NewRubyBaseFrame(nsIPresShell* aPresShell,
|
nsContainerFrame* NS_NewRubyBaseFrame(nsIPresShell* aPresShell,
|
||||||
nsStyleContext* aContext);
|
nsStyleContext* aContext);
|
||||||
|
|
||||||
class nsRubyBaseFrame final : public nsRubyBaseFrameSuper
|
class nsRubyBaseFrame final : public nsRubyContentFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_FRAMEARENA_HELPERS
|
NS_DECL_FRAMEARENA_HELPERS
|
||||||
|
@ -38,7 +36,7 @@ protected:
|
||||||
friend nsContainerFrame* NS_NewRubyBaseFrame(nsIPresShell* aPresShell,
|
friend nsContainerFrame* NS_NewRubyBaseFrame(nsIPresShell* aPresShell,
|
||||||
nsStyleContext* aContext);
|
nsStyleContext* aContext);
|
||||||
explicit nsRubyBaseFrame(nsStyleContext* aContext)
|
explicit nsRubyBaseFrame(nsStyleContext* aContext)
|
||||||
: nsRubyBaseFrameSuper(aContext) {}
|
: nsRubyContentFrame(aContext) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* nsRubyBaseFrame_h___ */
|
#endif /* nsRubyBaseFrame_h___ */
|
||||||
|
|
|
@ -24,7 +24,7 @@ nsRubyContentFrame::IsFrameOfType(uint32_t aFlags) const
|
||||||
if (aFlags & eBidiInlineContainer) {
|
if (aFlags & eBidiInlineContainer) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return nsRubyContentFrameSuper::IsFrameOfType(aFlags);
|
return nsInlineFrame::IsFrameOfType(aFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -11,9 +11,7 @@
|
||||||
|
|
||||||
#include "nsInlineFrame.h"
|
#include "nsInlineFrame.h"
|
||||||
|
|
||||||
typedef nsInlineFrame nsRubyContentFrameSuper;
|
class nsRubyContentFrame : public nsInlineFrame
|
||||||
|
|
||||||
class nsRubyContentFrame : public nsRubyContentFrameSuper
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ABSTRACT_FRAME(nsRubyContentFrame)
|
NS_DECL_ABSTRACT_FRAME(nsRubyContentFrame)
|
||||||
|
@ -30,7 +28,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit nsRubyContentFrame(nsStyleContext* aContext)
|
explicit nsRubyContentFrame(nsStyleContext* aContext)
|
||||||
: nsRubyContentFrameSuper(aContext) {}
|
: nsInlineFrame(aContext) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* nsRubyContentFrame_h___ */
|
#endif /* nsRubyContentFrame_h___ */
|
||||||
|
|
|
@ -26,7 +26,7 @@ using namespace mozilla;
|
||||||
|
|
||||||
NS_QUERYFRAME_HEAD(nsRubyFrame)
|
NS_QUERYFRAME_HEAD(nsRubyFrame)
|
||||||
NS_QUERYFRAME_ENTRY(nsRubyFrame)
|
NS_QUERYFRAME_ENTRY(nsRubyFrame)
|
||||||
NS_QUERYFRAME_TAIL_INHERITING(nsRubyFrameSuper)
|
NS_QUERYFRAME_TAIL_INHERITING(nsInlineFrame)
|
||||||
|
|
||||||
NS_IMPL_FRAMEARENA_HELPERS(nsRubyFrame)
|
NS_IMPL_FRAMEARENA_HELPERS(nsRubyFrame)
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ nsRubyFrame::IsFrameOfType(uint32_t aFlags) const
|
||||||
if (aFlags & eBidiInlineContainer) {
|
if (aFlags & eBidiInlineContainer) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return nsRubyFrameSuper::IsFrameOfType(aFlags);
|
return nsInlineFrame::IsFrameOfType(aFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_FRAME_DUMP
|
#ifdef DEBUG_FRAME_DUMP
|
||||||
|
|
|
@ -13,8 +13,6 @@
|
||||||
|
|
||||||
class nsRubyBaseContainerFrame;
|
class nsRubyBaseContainerFrame;
|
||||||
|
|
||||||
typedef nsInlineFrame nsRubyFrameSuper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory function.
|
* Factory function.
|
||||||
* @return a newly allocated nsRubyFrame (infallible)
|
* @return a newly allocated nsRubyFrame (infallible)
|
||||||
|
@ -22,7 +20,7 @@ typedef nsInlineFrame nsRubyFrameSuper;
|
||||||
nsContainerFrame* NS_NewRubyFrame(nsIPresShell* aPresShell,
|
nsContainerFrame* NS_NewRubyFrame(nsIPresShell* aPresShell,
|
||||||
nsStyleContext* aContext);
|
nsStyleContext* aContext);
|
||||||
|
|
||||||
class nsRubyFrame final : public nsRubyFrameSuper
|
class nsRubyFrame final : public nsInlineFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_FRAMEARENA_HELPERS
|
NS_DECL_FRAMEARENA_HELPERS
|
||||||
|
@ -55,7 +53,7 @@ protected:
|
||||||
friend nsContainerFrame* NS_NewRubyFrame(nsIPresShell* aPresShell,
|
friend nsContainerFrame* NS_NewRubyFrame(nsIPresShell* aPresShell,
|
||||||
nsStyleContext* aContext);
|
nsStyleContext* aContext);
|
||||||
explicit nsRubyFrame(nsStyleContext* aContext)
|
explicit nsRubyFrame(nsStyleContext* aContext)
|
||||||
: nsRubyFrameSuper(aContext) {}
|
: nsInlineFrame(aContext) {}
|
||||||
|
|
||||||
void ReflowSegment(nsPresContext* aPresContext,
|
void ReflowSegment(nsPresContext* aPresContext,
|
||||||
const nsHTMLReflowState& aReflowState,
|
const nsHTMLReflowState& aReflowState,
|
||||||
|
|
|
@ -60,14 +60,14 @@ nsRubyTextContainerFrame::IsFrameOfType(uint32_t aFlags) const
|
||||||
if (aFlags & eSupportsCSSTransforms) {
|
if (aFlags & eSupportsCSSTransforms) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return nsRubyTextContainerFrameSuper::IsFrameOfType(aFlags);
|
return nsContainerFrame::IsFrameOfType(aFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ void
|
/* virtual */ void
|
||||||
nsRubyTextContainerFrame::SetInitialChildList(ChildListID aListID,
|
nsRubyTextContainerFrame::SetInitialChildList(ChildListID aListID,
|
||||||
nsFrameList& aChildList)
|
nsFrameList& aChildList)
|
||||||
{
|
{
|
||||||
nsRubyTextContainerFrameSuper::SetInitialChildList(aListID, aChildList);
|
nsContainerFrame::SetInitialChildList(aListID, aChildList);
|
||||||
if (aListID == kPrincipalList) {
|
if (aListID == kPrincipalList) {
|
||||||
UpdateSpanFlag();
|
UpdateSpanFlag();
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ nsRubyTextContainerFrame::SetInitialChildList(ChildListID aListID,
|
||||||
nsRubyTextContainerFrame::AppendFrames(ChildListID aListID,
|
nsRubyTextContainerFrame::AppendFrames(ChildListID aListID,
|
||||||
nsFrameList& aFrameList)
|
nsFrameList& aFrameList)
|
||||||
{
|
{
|
||||||
nsRubyTextContainerFrameSuper::AppendFrames(aListID, aFrameList);
|
nsContainerFrame::AppendFrames(aListID, aFrameList);
|
||||||
UpdateSpanFlag();
|
UpdateSpanFlag();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ nsRubyTextContainerFrame::InsertFrames(ChildListID aListID,
|
||||||
nsIFrame* aPrevFrame,
|
nsIFrame* aPrevFrame,
|
||||||
nsFrameList& aFrameList)
|
nsFrameList& aFrameList)
|
||||||
{
|
{
|
||||||
nsRubyTextContainerFrameSuper::InsertFrames(aListID, aPrevFrame, aFrameList);
|
nsContainerFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
|
||||||
UpdateSpanFlag();
|
UpdateSpanFlag();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ nsRubyTextContainerFrame::InsertFrames(ChildListID aListID,
|
||||||
nsRubyTextContainerFrame::RemoveFrame(ChildListID aListID,
|
nsRubyTextContainerFrame::RemoveFrame(ChildListID aListID,
|
||||||
nsIFrame* aOldFrame)
|
nsIFrame* aOldFrame)
|
||||||
{
|
{
|
||||||
nsRubyTextContainerFrameSuper::RemoveFrame(aListID, aOldFrame);
|
nsContainerFrame::RemoveFrame(aListID, aOldFrame);
|
||||||
UpdateSpanFlag();
|
UpdateSpanFlag();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
|
|
||||||
#include "nsBlockFrame.h"
|
#include "nsBlockFrame.h"
|
||||||
|
|
||||||
typedef nsContainerFrame nsRubyTextContainerFrameSuper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory function.
|
* Factory function.
|
||||||
* @return a newly allocated nsRubyTextContainerFrame (infallible)
|
* @return a newly allocated nsRubyTextContainerFrame (infallible)
|
||||||
|
@ -20,7 +18,7 @@ typedef nsContainerFrame nsRubyTextContainerFrameSuper;
|
||||||
nsContainerFrame* NS_NewRubyTextContainerFrame(nsIPresShell* aPresShell,
|
nsContainerFrame* NS_NewRubyTextContainerFrame(nsIPresShell* aPresShell,
|
||||||
nsStyleContext* aContext);
|
nsStyleContext* aContext);
|
||||||
|
|
||||||
class nsRubyTextContainerFrame final : public nsRubyTextContainerFrameSuper
|
class nsRubyTextContainerFrame final : public nsContainerFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_FRAMEARENA_HELPERS
|
NS_DECL_FRAMEARENA_HELPERS
|
||||||
|
@ -59,7 +57,7 @@ protected:
|
||||||
NS_NewRubyTextContainerFrame(nsIPresShell* aPresShell,
|
NS_NewRubyTextContainerFrame(nsIPresShell* aPresShell,
|
||||||
nsStyleContext* aContext);
|
nsStyleContext* aContext);
|
||||||
explicit nsRubyTextContainerFrame(nsStyleContext* aContext)
|
explicit nsRubyTextContainerFrame(nsStyleContext* aContext)
|
||||||
: nsRubyTextContainerFrameSuper(aContext)
|
: nsContainerFrame(aContext)
|
||||||
, mISize(0) {}
|
, mISize(0) {}
|
||||||
|
|
||||||
void UpdateSpanFlag();
|
void UpdateSpanFlag();
|
||||||
|
|
|
@ -22,7 +22,7 @@ using namespace mozilla;
|
||||||
|
|
||||||
NS_QUERYFRAME_HEAD(nsRubyTextFrame)
|
NS_QUERYFRAME_HEAD(nsRubyTextFrame)
|
||||||
NS_QUERYFRAME_ENTRY(nsRubyTextFrame)
|
NS_QUERYFRAME_ENTRY(nsRubyTextFrame)
|
||||||
NS_QUERYFRAME_TAIL_INHERITING(nsRubyTextFrameSuper)
|
NS_QUERYFRAME_TAIL_INHERITING(nsRubyContentFrame)
|
||||||
|
|
||||||
NS_IMPL_FRAMEARENA_HELPERS(nsRubyTextFrame)
|
NS_IMPL_FRAMEARENA_HELPERS(nsRubyTextFrame)
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ nsRubyTextFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRubyTextFrameSuper::BuildDisplayList(aBuilder, aDirtyRect, aLists);
|
nsRubyContentFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ void
|
/* virtual */ void
|
||||||
|
@ -85,8 +85,7 @@ nsRubyTextFrame::Reflow(nsPresContext* aPresContext,
|
||||||
// the content is no longer the same, until next reflow triggered by
|
// the content is no longer the same, until next reflow triggered by
|
||||||
// some other change. In general, we always reflow all the frames we
|
// some other change. In general, we always reflow all the frames we
|
||||||
// created. There might be other problems if we don't do that.
|
// created. There might be other problems if we don't do that.
|
||||||
nsRubyTextFrameSuper::Reflow(aPresContext, aDesiredSize,
|
nsRubyContentFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||||
aReflowState, aStatus);
|
|
||||||
|
|
||||||
if (IsAutoHidden()) {
|
if (IsAutoHidden()) {
|
||||||
// Reset the ISize. The BSize is not changed so that it won't
|
// Reset the ISize. The BSize is not changed so that it won't
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
|
|
||||||
#include "nsRubyContentFrame.h"
|
#include "nsRubyContentFrame.h"
|
||||||
|
|
||||||
typedef nsRubyContentFrame nsRubyTextFrameSuper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory function.
|
* Factory function.
|
||||||
* @return a newly allocated nsRubyTextFrame (infallible)
|
* @return a newly allocated nsRubyTextFrame (infallible)
|
||||||
|
@ -20,7 +18,7 @@ typedef nsRubyContentFrame nsRubyTextFrameSuper;
|
||||||
nsContainerFrame* NS_NewRubyTextFrame(nsIPresShell* aPresShell,
|
nsContainerFrame* NS_NewRubyTextFrame(nsIPresShell* aPresShell,
|
||||||
nsStyleContext* aContext);
|
nsStyleContext* aContext);
|
||||||
|
|
||||||
class nsRubyTextFrame final : public nsRubyTextFrameSuper
|
class nsRubyTextFrame final : public nsRubyContentFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_FRAMEARENA_HELPERS
|
NS_DECL_FRAMEARENA_HELPERS
|
||||||
|
@ -53,7 +51,7 @@ protected:
|
||||||
friend nsContainerFrame* NS_NewRubyTextFrame(nsIPresShell* aPresShell,
|
friend nsContainerFrame* NS_NewRubyTextFrame(nsIPresShell* aPresShell,
|
||||||
nsStyleContext* aContext);
|
nsStyleContext* aContext);
|
||||||
explicit nsRubyTextFrame(nsStyleContext* aContext)
|
explicit nsRubyTextFrame(nsStyleContext* aContext)
|
||||||
: nsRubyTextFrameSuper(aContext) {}
|
: nsRubyContentFrame(aContext) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* nsRubyTextFrame_h___ */
|
#endif /* nsRubyTextFrame_h___ */
|
||||||
|
|
|
@ -56,7 +56,7 @@ GetDocumentFromView(nsView* aView)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsSubDocumentFrame::nsSubDocumentFrame(nsStyleContext* aContext)
|
nsSubDocumentFrame::nsSubDocumentFrame(nsStyleContext* aContext)
|
||||||
: nsSubDocumentFrameSuper(aContext)
|
: nsAtomicContainerFrame(aContext)
|
||||||
, mIsInline(false)
|
, mIsInline(false)
|
||||||
, mPostedReflowCallback(false)
|
, mPostedReflowCallback(false)
|
||||||
, mDidCreateDoc(false)
|
, mDidCreateDoc(false)
|
||||||
|
@ -74,7 +74,7 @@ nsSubDocumentFrame::AccessibleType()
|
||||||
|
|
||||||
NS_QUERYFRAME_HEAD(nsSubDocumentFrame)
|
NS_QUERYFRAME_HEAD(nsSubDocumentFrame)
|
||||||
NS_QUERYFRAME_ENTRY(nsSubDocumentFrame)
|
NS_QUERYFRAME_ENTRY(nsSubDocumentFrame)
|
||||||
NS_QUERYFRAME_TAIL_INHERITING(nsSubDocumentFrameSuper)
|
NS_QUERYFRAME_TAIL_INHERITING(nsAtomicContainerFrame)
|
||||||
|
|
||||||
class AsyncFrameInit : public nsRunnable
|
class AsyncFrameInit : public nsRunnable
|
||||||
{
|
{
|
||||||
|
@ -107,7 +107,7 @@ nsSubDocumentFrame::Init(nsIContent* aContent,
|
||||||
nsCOMPtr<nsIDOMHTMLFrameElement> frameElem = do_QueryInterface(aContent);
|
nsCOMPtr<nsIDOMHTMLFrameElement> frameElem = do_QueryInterface(aContent);
|
||||||
mIsInline = frameElem ? false : true;
|
mIsInline = frameElem ? false : true;
|
||||||
|
|
||||||
nsSubDocumentFrameSuper::Init(aContent, aParent, aPrevInFlow);
|
nsAtomicContainerFrame::Init(aContent, aParent, aPrevInFlow);
|
||||||
|
|
||||||
// We are going to create an inner view. If we need a view for the
|
// We are going to create an inner view. If we need a view for the
|
||||||
// OuterFrame but we wait for the normal view creation path in
|
// OuterFrame but we wait for the normal view creation path in
|
||||||
|
@ -689,7 +689,7 @@ nsSubDocumentFrame::GetIntrinsicSize()
|
||||||
if (subDocRoot) {
|
if (subDocRoot) {
|
||||||
return subDocRoot->GetIntrinsicSize();
|
return subDocRoot->GetIntrinsicSize();
|
||||||
}
|
}
|
||||||
return nsSubDocumentFrameSuper::GetIntrinsicSize();
|
return nsAtomicContainerFrame::GetIntrinsicSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */ nsSize
|
/* virtual */ nsSize
|
||||||
|
@ -699,7 +699,7 @@ nsSubDocumentFrame::GetIntrinsicRatio()
|
||||||
if (subDocRoot) {
|
if (subDocRoot) {
|
||||||
return subDocRoot->GetIntrinsicRatio();
|
return subDocRoot->GetIntrinsicRatio();
|
||||||
}
|
}
|
||||||
return nsSubDocumentFrameSuper::GetIntrinsicRatio();
|
return nsAtomicContainerFrame::GetIntrinsicRatio();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual */
|
/* virtual */
|
||||||
|
@ -747,10 +747,10 @@ nsSubDocumentFrame::ComputeSize(nsRenderingContext *aRenderingContext,
|
||||||
aBorder,
|
aBorder,
|
||||||
aPadding);
|
aPadding);
|
||||||
}
|
}
|
||||||
return nsSubDocumentFrameSuper::ComputeSize(aRenderingContext, aWM,
|
return nsAtomicContainerFrame::ComputeSize(aRenderingContext, aWM,
|
||||||
aCBSize, aAvailableISize,
|
aCBSize, aAvailableISize,
|
||||||
aMargin, aBorder, aPadding,
|
aMargin, aBorder, aPadding,
|
||||||
aFlags);
|
aFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -995,7 +995,7 @@ nsSubDocumentFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||||
(mDidCreateDoc || mCallingShow)));
|
(mDidCreateDoc || mCallingShow)));
|
||||||
}
|
}
|
||||||
|
|
||||||
nsSubDocumentFrameSuper::DestroyFrom(aDestructRoot);
|
nsAtomicContainerFrame::DestroyFrom(aDestructRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSSIntSize
|
CSSIntSize
|
||||||
|
|
|
@ -12,12 +12,10 @@
|
||||||
#include "nsFrameLoader.h"
|
#include "nsFrameLoader.h"
|
||||||
#include "Units.h"
|
#include "Units.h"
|
||||||
|
|
||||||
typedef nsAtomicContainerFrame nsSubDocumentFrameSuper;
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* nsSubDocumentFrame
|
* nsSubDocumentFrame
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
class nsSubDocumentFrame : public nsSubDocumentFrameSuper,
|
class nsSubDocumentFrame : public nsAtomicContainerFrame,
|
||||||
public nsIReflowCallback
|
public nsIReflowCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -37,7 +35,7 @@ public:
|
||||||
|
|
||||||
virtual bool IsFrameOfType(uint32_t aFlags) const override
|
virtual bool IsFrameOfType(uint32_t aFlags) const override
|
||||||
{
|
{
|
||||||
return nsSubDocumentFrameSuper::IsFrameOfType(aFlags &
|
return nsAtomicContainerFrame::IsFrameOfType(aFlags &
|
||||||
~(nsIFrame::eReplaced |
|
~(nsIFrame::eReplaced |
|
||||||
nsIFrame::eReplacedSizing |
|
nsIFrame::eReplacedSizing |
|
||||||
nsIFrame::eReplacedContainsBlock));
|
nsIFrame::eReplacedContainsBlock));
|
||||||
|
|
|
@ -42,7 +42,7 @@ NS_NewHTMLVideoFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
|
||||||
NS_IMPL_FRAMEARENA_HELPERS(nsVideoFrame)
|
NS_IMPL_FRAMEARENA_HELPERS(nsVideoFrame)
|
||||||
|
|
||||||
nsVideoFrame::nsVideoFrame(nsStyleContext* aContext)
|
nsVideoFrame::nsVideoFrame(nsStyleContext* aContext)
|
||||||
: nsVideoFrameBase(aContext)
|
: nsContainerFrame(aContext)
|
||||||
{
|
{
|
||||||
EnableVisibilityTracking();
|
EnableVisibilityTracking();
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ nsVideoFrame::~nsVideoFrame()
|
||||||
NS_QUERYFRAME_HEAD(nsVideoFrame)
|
NS_QUERYFRAME_HEAD(nsVideoFrame)
|
||||||
NS_QUERYFRAME_ENTRY(nsVideoFrame)
|
NS_QUERYFRAME_ENTRY(nsVideoFrame)
|
||||||
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
|
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
|
||||||
NS_QUERYFRAME_TAIL_INHERITING(nsVideoFrameBase)
|
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsVideoFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
|
nsVideoFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
|
||||||
|
@ -145,7 +145,7 @@ nsVideoFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||||
nsContentUtils::DestroyAnonymousContent(&mCaptionDiv);
|
nsContentUtils::DestroyAnonymousContent(&mCaptionDiv);
|
||||||
nsContentUtils::DestroyAnonymousContent(&mVideoControls);
|
nsContentUtils::DestroyAnonymousContent(&mVideoControls);
|
||||||
nsContentUtils::DestroyAnonymousContent(&mPosterImage);
|
nsContentUtils::DestroyAnonymousContent(&mPosterImage);
|
||||||
nsVideoFrameBase::DestroyFrom(aDestructRoot);
|
nsContainerFrame::DestroyFrom(aDestructRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -612,7 +612,7 @@ nsVideoFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||||
if (aAttribute == nsGkAtoms::poster && HasVideoElement()) {
|
if (aAttribute == nsGkAtoms::poster && HasVideoElement()) {
|
||||||
UpdatePosterSource(true);
|
UpdatePosterSource(true);
|
||||||
}
|
}
|
||||||
return nsVideoFrameBase::AttributeChanged(aNameSpaceID,
|
return nsContainerFrame::AttributeChanged(aNameSpaceID,
|
||||||
aAttribute,
|
aAttribute,
|
||||||
aModType);
|
aModType);
|
||||||
}
|
}
|
||||||
|
@ -623,13 +623,13 @@ nsVideoFrame::OnVisibilityChange(Visibility aNewVisibility,
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mPosterImage);
|
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mPosterImage);
|
||||||
if (!imageLoader) {
|
if (!imageLoader) {
|
||||||
nsVideoFrameBase::OnVisibilityChange(aNewVisibility, aNonvisibleAction);
|
nsContainerFrame::OnVisibilityChange(aNewVisibility, aNonvisibleAction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
imageLoader->OnVisibilityChange(aNewVisibility, aNonvisibleAction);
|
imageLoader->OnVisibilityChange(aNewVisibility, aNonvisibleAction);
|
||||||
|
|
||||||
nsVideoFrameBase::OnVisibilityChange(aNewVisibility, aNonvisibleAction);
|
nsContainerFrame::OnVisibilityChange(aNewVisibility, aNonvisibleAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsVideoFrame::HasVideoElement() {
|
bool nsVideoFrame::HasVideoElement() {
|
||||||
|
|
|
@ -26,9 +26,8 @@ class nsAString;
|
||||||
class nsPresContext;
|
class nsPresContext;
|
||||||
class nsDisplayItem;
|
class nsDisplayItem;
|
||||||
|
|
||||||
typedef nsContainerFrame nsVideoFrameBase;
|
class nsVideoFrame : public nsContainerFrame
|
||||||
|
, public nsIAnonymousContentCreator
|
||||||
class nsVideoFrame : public nsVideoFrameBase, public nsIAnonymousContentCreator
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template <typename T> using Maybe = mozilla::Maybe<T>;
|
template <typename T> using Maybe = mozilla::Maybe<T>;
|
||||||
|
|
|
@ -36,7 +36,7 @@ ViewportFrame::Init(nsIContent* aContent,
|
||||||
nsContainerFrame* aParent,
|
nsContainerFrame* aParent,
|
||||||
nsIFrame* aPrevInFlow)
|
nsIFrame* aPrevInFlow)
|
||||||
{
|
{
|
||||||
Super::Init(aContent, aParent, aPrevInFlow);
|
nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
|
||||||
|
|
||||||
nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrame(this);
|
nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrame(this);
|
||||||
if (parent) {
|
if (parent) {
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче