Merge mozilla-central to fx-team

This commit is contained in:
Carsten "Tomcat" Book 2016-04-19 12:09:01 +02:00
Родитель 38f77c7856 7fb6b01181
Коммит b06178a07e
177 изменённых файлов: 2194 добавлений и 1149 удалений

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

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

357
gfx/src/TiledRegion.cpp Normal file
Просмотреть файл

@ -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

198
gfx/src/TiledRegion.h Normal file
Просмотреть файл

@ -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) {

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше