From 7097957d08a2fd05112f515c8feda08c107dbcf2 Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Sat, 1 Aug 2015 01:20:11 +1000 Subject: [PATCH 01/56] Bug 1189776: Store our audio decode time in TimeUnits. r=cpearce Decode time were stored in number of samples ; which could cause integer overflow when performing the conversion. --- dom/media/platforms/wmf/WMFAudioMFTManager.cpp | 6 ++---- dom/media/platforms/wmf/WMFAudioMFTManager.h | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/dom/media/platforms/wmf/WMFAudioMFTManager.cpp b/dom/media/platforms/wmf/WMFAudioMFTManager.cpp index c54f3d228acf..bbb428170e5b 100644 --- a/dom/media/platforms/wmf/WMFAudioMFTManager.cpp +++ b/dom/media/platforms/wmf/WMFAudioMFTManager.cpp @@ -68,7 +68,6 @@ WMFAudioMFTManager::WMFAudioMFTManager( const AudioInfo& aConfig) : mAudioChannels(aConfig.mChannels) , mAudioRate(aConfig.mRate) - , mAudioFrameOffset(0) , mAudioFrameSum(0) , mMustRecaptureAudioPosition(true) { @@ -267,8 +266,7 @@ WMFAudioMFTManager::Output(int64_t aStreamOffset, LONGLONG timestampHns = 0; hr = sample->GetSampleTime(×tampHns); NS_ENSURE_TRUE(SUCCEEDED(hr), hr); - hr = HNsToFrames(timestampHns, mAudioRate, &mAudioFrameOffset); - NS_ENSURE_TRUE(SUCCEEDED(hr), hr); + mAudioTimeOffset = media::TimeUnit::FromMicroseconds(timestampHns / 10); mMustRecaptureAudioPosition = false; } // We can assume PCM 16 output. @@ -292,7 +290,7 @@ WMFAudioMFTManager::Output(int64_t aStreamOffset, buffer->Unlock(); media::TimeUnit timestamp = - FramesToTimeUnit(mAudioFrameOffset + mAudioFrameSum, mAudioRate); + mAudioTimeOffset + FramesToTimeUnit(mAudioFrameSum, mAudioRate); NS_ENSURE_TRUE(timestamp.IsValid(), E_FAIL); mAudioFrameSum += numFrames; diff --git a/dom/media/platforms/wmf/WMFAudioMFTManager.h b/dom/media/platforms/wmf/WMFAudioMFTManager.h index 95d6aab469f3..25ef38a36498 100644 --- a/dom/media/platforms/wmf/WMFAudioMFTManager.h +++ b/dom/media/platforms/wmf/WMFAudioMFTManager.h @@ -42,9 +42,9 @@ private: uint32_t mAudioRate; nsTArray mUserData; - // The offset, in audio frames, at which playback started since the + // The offset, at which playback started since the // last discontinuity. - int64_t mAudioFrameOffset; + media::TimeUnit mAudioTimeOffset; // The number of audio frames that we've played since the last // discontinuity. int64_t mAudioFrameSum; @@ -59,7 +59,7 @@ private: const GUID& GetMFTGUID(); const GUID& GetMediaSubtypeGUID(); - // True if we need to re-initialize mAudioFrameOffset and mAudioFrameSum + // True if we need to re-initialize mAudioTimeOffset and mAudioFrameSum // from the next audio packet we decode. This happens after a seek, since // WMF doesn't mark a stream as having a discontinuity after a seek(0). bool mMustRecaptureAudioPosition; From 8905370e556cd06c8a44acdc3ed43a4b1c371eb6 Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Tue, 4 Aug 2015 13:25:47 +1000 Subject: [PATCH 02/56] Bug 1190019: [MSE] P1. Remove cycle between SourceBuffer and TrackBuffersManager. r=cpearce Instead we use a a ref-counted attribute holder to store those arguments. --- dom/media/mediasource/SourceBuffer.cpp | 62 +++++----- dom/media/mediasource/SourceBuffer.h | 111 +++++++++++++++--- .../SourceBufferContentManager.cpp | 4 +- .../mediasource/SourceBufferContentManager.h | 4 +- dom/media/mediasource/TrackBuffersManager.cpp | 37 +++--- dom/media/mediasource/TrackBuffersManager.h | 11 +- 6 files changed, 154 insertions(+), 75 deletions(-) diff --git a/dom/media/mediasource/SourceBuffer.cpp b/dom/media/mediasource/SourceBuffer.cpp index d707e2b51d5d..7976c8d8aefc 100644 --- a/dom/media/mediasource/SourceBuffer.cpp +++ b/dom/media/mediasource/SourceBuffer.cpp @@ -76,7 +76,7 @@ SourceBuffer::SetMode(SourceBufferAppendMode aMode, ErrorResult& aRv) aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); return; } - if (mIsUsingFormatReader && mGenerateTimestamps && + if (mIsUsingFormatReader && mAttributes->mGenerateTimestamps && aMode == SourceBufferAppendMode::Segments) { aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); return; @@ -96,7 +96,7 @@ SourceBuffer::SetMode(SourceBufferAppendMode aMode, ErrorResult& aRv) mContentManager->RestartGroupStartTimestamp(); } - mAppendMode = aMode; + mAttributes->SetAppendMode(aMode); } void @@ -119,22 +119,13 @@ SourceBuffer::SetTimestampOffset(double aTimestampOffset, ErrorResult& aRv) aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return; } - mApparentTimestampOffset = aTimestampOffset; - mTimestampOffset = TimeUnit::FromSeconds(aTimestampOffset); - if (mIsUsingFormatReader && mAppendMode == SourceBufferAppendMode::Sequence) { - mContentManager->SetGroupStartTimestamp(mTimestampOffset); + mAttributes->SetApparentTimestampOffset(aTimestampOffset); + if (mIsUsingFormatReader && + mAttributes->GetAppendMode() == SourceBufferAppendMode::Sequence) { + mContentManager->SetGroupStartTimestamp(mAttributes->GetTimestampOffset()); } } -void -SourceBuffer::SetTimestampOffset(const TimeUnit& aTimestampOffset) -{ - MOZ_ASSERT(NS_IsMainThread()); - - mTimestampOffset = aTimestampOffset; - mApparentTimestampOffset = aTimestampOffset.ToSeconds(); -} - already_AddRefed SourceBuffer::GetBuffered(ErrorResult& aRv) { @@ -165,11 +156,12 @@ SourceBuffer::SetAppendWindowStart(double aAppendWindowStart, ErrorResult& aRv) aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return; } - if (aAppendWindowStart < 0 || aAppendWindowStart >= mAppendWindowEnd) { + if (aAppendWindowStart < 0 || + aAppendWindowStart >= mAttributes->GetAppendWindowEnd()) { aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); return; } - mAppendWindowStart = aAppendWindowStart; + mAttributes->SetAppendWindowStart(aAppendWindowStart); } void @@ -181,11 +173,12 @@ SourceBuffer::SetAppendWindowEnd(double aAppendWindowEnd, ErrorResult& aRv) aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return; } - if (IsNaN(aAppendWindowEnd) || aAppendWindowEnd <= mAppendWindowStart) { + if (IsNaN(aAppendWindowEnd) || + aAppendWindowEnd <= mAttributes->GetAppendWindowStart()) { aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); return; } - mAppendWindowEnd = aAppendWindowEnd; + mAttributes->SetAppendWindowEnd(aAppendWindowEnd); } void @@ -221,8 +214,8 @@ SourceBuffer::Abort(ErrorResult& aRv) } AbortBufferAppend(); mContentManager->ResetParserState(); - mAppendWindowStart = 0; - mAppendWindowEnd = PositiveInfinity(); + mAttributes->SetAppendWindowStart(0); + mAttributes->SetAppendWindowEnd(PositiveInfinity()); } void @@ -312,10 +305,6 @@ SourceBuffer::Ended() SourceBuffer::SourceBuffer(MediaSource* aMediaSource, const nsACString& aType) : DOMEventTargetHelper(aMediaSource->GetParentObject()) , mMediaSource(aMediaSource) - , mAppendWindowStart(0) - , mAppendWindowEnd(PositiveInfinity()) - , mApparentTimestampOffset(0) - , mAppendMode(SourceBufferAppendMode::Segments) , mUpdating(false) , mActive(false) , mUpdateID(0) @@ -326,22 +315,24 @@ SourceBuffer::SourceBuffer(MediaSource* aMediaSource, const nsACString& aType) MOZ_ASSERT(aMediaSource); mEvictionThreshold = Preferences::GetUint("media.mediasource.eviction_threshold", 100 * (1 << 20)); + bool generateTimestamps = false; + if (aType.LowerCaseEqualsLiteral("audio/mpeg") || + aType.LowerCaseEqualsLiteral("audio/aac")) { + generateTimestamps = true; + } + mAttributes = new SourceBufferAttributes(generateTimestamps); + mContentManager = - SourceBufferContentManager::CreateManager(this, + SourceBufferContentManager::CreateManager(mAttributes, aMediaSource->GetDecoder(), aType); MSE_DEBUG("Create mContentManager=%p", mContentManager.get()); - if (aType.LowerCaseEqualsLiteral("audio/mpeg") || - aType.LowerCaseEqualsLiteral("audio/aac")) { - mGenerateTimestamps = true; - } else { - mGenerateTimestamps = false; - } + mIsUsingFormatReader = Preferences::GetBool("media.mediasource.format-reader", false); ErrorResult dummy; - if (mGenerateTimestamps) { + if (mAttributes->mGenerateTimestamps) { SetMode(SourceBufferAppendMode::Sequence, dummy); } else { SetMode(SourceBufferAppendMode::Segments, dummy); @@ -446,11 +437,12 @@ SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aR if (!data) { return; } - mContentManager->AppendData(data, mTimestampOffset); + mContentManager->AppendData(data, mAttributes->GetTimestampOffset()); StartUpdating(); - MOZ_ASSERT(mIsUsingFormatReader || mAppendMode == SourceBufferAppendMode::Segments, + MOZ_ASSERT(mIsUsingFormatReader || + mAttributes->GetAppendMode() == SourceBufferAppendMode::Segments, "We don't handle timestampOffset for sequence mode yet"); nsCOMPtr task = new BufferAppendRunnable(this, mUpdateID); NS_DispatchToMainThread(task); diff --git a/dom/media/mediasource/SourceBuffer.h b/dom/media/mediasource/SourceBuffer.h index 400d0c6a25b6..51e4786ea026 100644 --- a/dom/media/mediasource/SourceBuffer.h +++ b/dom/media/mediasource/SourceBuffer.h @@ -25,6 +25,7 @@ #include "nsString.h" #include "nscore.h" #include "SourceBufferContentManager.h" +#include "mozilla/Monitor.h" class JSObject; struct JSContext; @@ -40,13 +41,103 @@ namespace dom { class TimeRanges; +class SourceBufferAttributes { +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SourceBufferAttributes); + explicit SourceBufferAttributes(bool aGenerateTimestamp) + : mGenerateTimestamps(aGenerateTimestamp) + , mMonitor("SourceBufferAttributes") + , mAppendWindowStart(0) + , mAppendWindowEnd(PositiveInfinity()) + , mAppendMode(SourceBufferAppendMode::Segments) + , mApparentTimestampOffset(0) + {} + + double GetAppendWindowStart() + { + MonitorAutoLock mon(mMonitor); + return mAppendWindowStart; + } + + double GetAppendWindowEnd() + { + MonitorAutoLock mon(mMonitor); + return mAppendWindowEnd; + } + + void SetAppendWindowStart(double aWindowStart) + { + MonitorAutoLock mon(mMonitor); + mAppendWindowStart = aWindowStart; + } + + void SetAppendWindowEnd(double aWindowEnd) + { + MonitorAutoLock mon(mMonitor); + mAppendWindowEnd = aWindowEnd; + } + + double GetApparentTimestampOffset() + { + MonitorAutoLock mon(mMonitor); + return mApparentTimestampOffset; + } + + void SetApparentTimestampOffset(double aTimestampOffset) + { + MonitorAutoLock mon(mMonitor); + mApparentTimestampOffset = aTimestampOffset; + mTimestampOffset = media::TimeUnit::FromSeconds(aTimestampOffset); + } + + media::TimeUnit GetTimestampOffset() + { + MonitorAutoLock mon(mMonitor); + return mTimestampOffset; + } + + void SetTimestampOffset(media::TimeUnit& aTimestampOffset) + { + MonitorAutoLock mon(mMonitor); + mTimestampOffset = aTimestampOffset; + mApparentTimestampOffset = aTimestampOffset.ToSeconds(); + } + + SourceBufferAppendMode GetAppendMode() + { + MonitorAutoLock mon(mMonitor); + return mAppendMode; + } + + void SetAppendMode(SourceBufferAppendMode aAppendMode) + { + MonitorAutoLock mon(mMonitor); + mAppendMode = aAppendMode; + } + + // mGenerateTimestamp isn't mutable once the source buffer has been constructed + // We don't need a monitor to protect it across threads. + const bool mGenerateTimestamps; + +private: + ~SourceBufferAttributes() {}; + + // Monitor protecting all members below. + Monitor mMonitor; + double mAppendWindowStart; + double mAppendWindowEnd; + SourceBufferAppendMode mAppendMode; + double mApparentTimestampOffset; + media::TimeUnit mTimestampOffset; +}; + class SourceBuffer final : public DOMEventTargetHelper { public: /** WebIDL Methods. */ SourceBufferAppendMode Mode() const { - return mAppendMode; + return mAttributes->GetAppendMode(); } void SetMode(SourceBufferAppendMode aMode, ErrorResult& aRv); @@ -61,21 +152,21 @@ public: double TimestampOffset() const { - return mApparentTimestampOffset; + return mAttributes->GetApparentTimestampOffset(); } void SetTimestampOffset(double aTimestampOffset, ErrorResult& aRv); double AppendWindowStart() const { - return mAppendWindowStart; + return mAttributes->GetAppendWindowStart(); } void SetAppendWindowStart(double aAppendWindowStart, ErrorResult& aRv); double AppendWindowEnd() const { - return mAppendWindowEnd; + return mAttributes->GetAppendWindowEnd(); } void SetAppendWindowEnd(double aAppendWindowEnd, ErrorResult& aRv); @@ -164,24 +255,14 @@ private: void AppendDataCompletedWithSuccess(bool aHasActiveTracks); void AppendDataErrored(nsresult aError); - // Set timestampOffset, must be called on the main thread. - void SetTimestampOffset(const media::TimeUnit& aTimestampOffset); - nsRefPtr mMediaSource; uint32_t mEvictionThreshold; nsRefPtr mContentManager; + nsRefPtr mAttributes; - double mAppendWindowStart; - double mAppendWindowEnd; - - double mApparentTimestampOffset; - media::TimeUnit mTimestampOffset; - - SourceBufferAppendMode mAppendMode; bool mUpdating; - bool mGenerateTimestamps; bool mIsUsingFormatReader; mozilla::Atomic mActive; diff --git a/dom/media/mediasource/SourceBufferContentManager.cpp b/dom/media/mediasource/SourceBufferContentManager.cpp index a8d31138e183..775edff45e5b 100644 --- a/dom/media/mediasource/SourceBufferContentManager.cpp +++ b/dom/media/mediasource/SourceBufferContentManager.cpp @@ -18,7 +18,7 @@ namespace mozilla { #endif already_AddRefed -SourceBufferContentManager::CreateManager(dom::SourceBuffer* aParent, +SourceBufferContentManager::CreateManager(dom::SourceBufferAttributes* aAttributes, MediaSourceDecoder* aParentDecoder, const nsACString &aType) { @@ -26,7 +26,7 @@ SourceBufferContentManager::CreateManager(dom::SourceBuffer* aParent, bool useFormatReader = Preferences::GetBool("media.mediasource.format-reader", false); if (useFormatReader) { - manager = new TrackBuffersManager(aParent, aParentDecoder, aType); + manager = new TrackBuffersManager(aAttributes, aParentDecoder, aType); } else { manager = new TrackBuffer(aParentDecoder, aType); } diff --git a/dom/media/mediasource/SourceBufferContentManager.h b/dom/media/mediasource/SourceBufferContentManager.h index 37c739b32ef9..da60dcd4427c 100644 --- a/dom/media/mediasource/SourceBufferContentManager.h +++ b/dom/media/mediasource/SourceBufferContentManager.h @@ -18,6 +18,7 @@ namespace mozilla { namespace dom { class SourceBuffer; +class SourceBufferAttributes; } class SourceBufferContentManager { @@ -28,7 +29,8 @@ public: typedef AppendPromise RangeRemovalPromise; static already_AddRefed - CreateManager(dom::SourceBuffer* aParent, MediaSourceDecoder* aParentDecoder, + CreateManager(dom::SourceBufferAttributes* aAttributes, + MediaSourceDecoder* aParentDecoder, const nsACString& aType); // Add data to the end of the input buffer. diff --git a/dom/media/mediasource/TrackBuffersManager.cpp b/dom/media/mediasource/TrackBuffersManager.cpp index 246bbde4c72b..44c055e95ebb 100644 --- a/dom/media/mediasource/TrackBuffersManager.cpp +++ b/dom/media/mediasource/TrackBuffersManager.cpp @@ -90,7 +90,9 @@ private: }; #endif // MOZ_EME -TrackBuffersManager::TrackBuffersManager(dom::SourceBuffer* aParent, MediaSourceDecoder* aParentDecoder, const nsACString& aType) +TrackBuffersManager::TrackBuffersManager(dom::SourceBufferAttributes* aAttributes, + MediaSourceDecoder* aParentDecoder, + const nsACString& aType) : mInputBuffer(new MediaByteBuffer) , mAppendState(AppendState::WAITING_FOR_SEGMENT) , mBufferFull(false) @@ -101,7 +103,7 @@ TrackBuffersManager::TrackBuffersManager(dom::SourceBuffer* aParent, MediaSource , mProcessedInput(0) , mAppendRunning(false) , mTaskQueue(aParentDecoder->GetDemuxer()->GetTaskQueue()) - , mParent(new nsMainThreadPtrHolder(aParent, false /* strict */)) + , mSourceBufferAttributes(aAttributes) , mParentDecoder(new nsMainThreadPtrHolder(aParentDecoder, false /* strict */)) , mMediaSourceDemuxer(mParentDecoder->GetDemuxer()) , mMediaSourceDuration(mTaskQueue, Maybe(), "TrackBuffersManager::mMediaSourceDuration (Mirror)") @@ -620,8 +622,8 @@ TrackBuffersManager::AppendIncomingBuffers() mIncomingBuffers.Clear(); mAppendWindow = - TimeInterval(TimeUnit::FromSeconds(mParent->AppendWindowStart()), - TimeUnit::FromSeconds(mParent->AppendWindowEnd())); + TimeInterval(TimeUnit::FromSeconds(mSourceBufferAttributes->GetAppendWindowStart()), + TimeUnit::FromSeconds(mSourceBufferAttributes->GetAppendWindowEnd())); } void @@ -1239,7 +1241,7 @@ TrackBuffersManager::ResolveProcessing(bool aResolveValue, const char* aName) void TrackBuffersManager::CheckSequenceDiscontinuity() { - if (mParent->mAppendMode == SourceBufferAppendMode::Sequence && + if (mSourceBufferAttributes->GetAppendMode() == SourceBufferAppendMode::Sequence && mGroupStartTimestamp.isSome()) { mTimestampOffset = mGroupStartTimestamp.ref(); mGroupEndTimestamp = mGroupStartTimestamp.ref(); @@ -1314,13 +1316,13 @@ TrackBuffersManager::ProcessFrames(TrackBuffer& aSamples, TrackData& aTrackData) // 4. If timestampOffset is not 0, then run the following steps: TimeInterval sampleInterval = - mParent->mGenerateTimestamps + mSourceBufferAttributes->mGenerateTimestamps ? TimeInterval(mTimestampOffset, mTimestampOffset + TimeUnit::FromMicroseconds(sample->mDuration)) : TimeInterval(TimeUnit::FromMicroseconds(sample->mTime) + mTimestampOffset, TimeUnit::FromMicroseconds(sample->GetEndTime()) + mTimestampOffset); TimeUnit decodeTimestamp = - mParent->mGenerateTimestamps + mSourceBufferAttributes->mGenerateTimestamps ? mTimestampOffset : TimeUnit::FromMicroseconds(sample->mTimecode) + mTimestampOffset; @@ -1332,13 +1334,15 @@ TrackBuffersManager::ProcessFrames(TrackBuffer& aSamples, TrackData& aTrackData) (decodeTimestamp < trackBuffer.mLastDecodeTimestamp.ref() || decodeTimestamp - trackBuffer.mLastDecodeTimestamp.ref() > 2*trackBuffer.mLongestFrameDuration.ref())) { MSE_DEBUG("Discontinuity detected."); + SourceBufferAppendMode appendMode = mSourceBufferAttributes->GetAppendMode(); + // 1a. If mode equals "segments": - if (mParent->mAppendMode == SourceBufferAppendMode::Segments) { + if (appendMode == SourceBufferAppendMode::Segments) { // Set group end timestamp to presentation timestamp. mGroupEndTimestamp = sampleInterval.mStart; } // 1b. If mode equals "sequence": - if (mParent->mAppendMode == SourceBufferAppendMode::Sequence) { + if (appendMode == SourceBufferAppendMode::Sequence) { // Set group start timestamp equal to the group end timestamp. mGroupStartTimestamp = Some(mGroupEndTimestamp); } @@ -1358,17 +1362,17 @@ TrackBuffersManager::ProcessFrames(TrackBuffer& aSamples, TrackData& aTrackData) if (!sample->mKeyframe) { continue; } - if (mParent->mAppendMode == SourceBufferAppendMode::Sequence) { + if (appendMode == SourceBufferAppendMode::Sequence) { // mTimestampOffset was modified during CheckSequenceDiscontinuity. // We need to update our variables. sampleInterval = - mParent->mGenerateTimestamps + mSourceBufferAttributes->mGenerateTimestamps ? TimeInterval(mTimestampOffset, mTimestampOffset + TimeUnit::FromMicroseconds(sample->mDuration)) : TimeInterval(TimeUnit::FromMicroseconds(sample->mTime) + mTimestampOffset, TimeUnit::FromMicroseconds(sample->GetEndTime()) + mTimestampOffset); decodeTimestamp = - mParent->mGenerateTimestamps + mSourceBufferAttributes->mGenerateTimestamps ? mTimestampOffset : TimeUnit::FromMicroseconds(sample->mTimecode) + mTimestampOffset; } @@ -1428,7 +1432,7 @@ TrackBuffersManager::ProcessFrames(TrackBuffer& aSamples, TrackData& aTrackData) mGroupEndTimestamp = sampleInterval.mEnd; } // 21. If generate timestamps flag equals true, then set timestampOffset equal to frame end timestamp. - if (mParent->mGenerateTimestamps) { + if (mSourceBufferAttributes->mGenerateTimestamps) { mTimestampOffset = sampleInterval.mEnd; } } @@ -1679,12 +1683,7 @@ TrackBuffersManager::RestoreCachedVariables() { MOZ_ASSERT(OnTaskQueue()); if (mTimestampOffset != mLastTimestampOffset) { - nsRefPtr self = this; - nsCOMPtr task = - NS_NewRunnableFunction([self] { - self->mParent->SetTimestampOffset(self->mTimestampOffset); - }); - AbstractThread::MainThread()->Dispatch(task.forget()); + mSourceBufferAttributes->SetTimestampOffset(mTimestampOffset); } } diff --git a/dom/media/mediasource/TrackBuffersManager.h b/dom/media/mediasource/TrackBuffersManager.h index 9ab73602eead..b061b5558367 100644 --- a/dom/media/mediasource/TrackBuffersManager.h +++ b/dom/media/mediasource/TrackBuffersManager.h @@ -25,9 +25,12 @@ class ContainerParser; class MediaByteBuffer; class MediaRawData; class MediaSourceDemuxer; -class SourceBuffer; class SourceBufferResource; +namespace dom { + class SourceBufferAttributes; +} + class TrackBuffersManager : public SourceBufferContentManager { public: typedef MozPromise CodedFrameProcessingPromise; @@ -35,7 +38,9 @@ public: typedef MediaData::Type MediaType; typedef nsTArray> TrackBuffer; - TrackBuffersManager(dom::SourceBuffer* aParent, MediaSourceDecoder* aParentDecoder, const nsACString& aType); + TrackBuffersManager(dom::SourceBufferAttributes* aAttributes, + MediaSourceDecoder* aParentDecoder, + const nsACString& aType); bool AppendData(MediaByteBuffer* aData, media::TimeUnit aTimestampOffset) override; @@ -315,7 +320,7 @@ private: void RestoreCachedVariables(); // Strong references to external objects. - nsMainThreadPtrHandle mParent; + nsRefPtr mSourceBufferAttributes; nsMainThreadPtrHandle mParentDecoder; nsRefPtr mMediaSourceDemuxer; From 38f40fd81987ef1f125a42fdda63cbadb7ffc242 Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Tue, 4 Aug 2015 15:36:47 +1000 Subject: [PATCH 03/56] Bug 1190019: [MSE] P2. Remove cycle between TrackBuffersManager and MediaSourceDemuxer. r=gerald --- dom/media/mediasource/TrackBuffersManager.cpp | 1 - dom/media/mediasource/TrackBuffersManager.h | 1 - 2 files changed, 2 deletions(-) diff --git a/dom/media/mediasource/TrackBuffersManager.cpp b/dom/media/mediasource/TrackBuffersManager.cpp index 44c055e95ebb..6eed298ce96e 100644 --- a/dom/media/mediasource/TrackBuffersManager.cpp +++ b/dom/media/mediasource/TrackBuffersManager.cpp @@ -105,7 +105,6 @@ TrackBuffersManager::TrackBuffersManager(dom::SourceBufferAttributes* aAttribute , mTaskQueue(aParentDecoder->GetDemuxer()->GetTaskQueue()) , mSourceBufferAttributes(aAttributes) , mParentDecoder(new nsMainThreadPtrHolder(aParentDecoder, false /* strict */)) - , mMediaSourceDemuxer(mParentDecoder->GetDemuxer()) , mMediaSourceDuration(mTaskQueue, Maybe(), "TrackBuffersManager::mMediaSourceDuration (Mirror)") , mAbort(false) , mEvictionThreshold(Preferences::GetUint("media.mediasource.eviction_threshold", diff --git a/dom/media/mediasource/TrackBuffersManager.h b/dom/media/mediasource/TrackBuffersManager.h index b061b5558367..dfa5c67d549c 100644 --- a/dom/media/mediasource/TrackBuffersManager.h +++ b/dom/media/mediasource/TrackBuffersManager.h @@ -322,7 +322,6 @@ private: // Strong references to external objects. nsRefPtr mSourceBufferAttributes; nsMainThreadPtrHandle mParentDecoder; - nsRefPtr mMediaSourceDemuxer; // MediaSource duration mirrored from MediaDecoder on the main thread.. Mirror> mMediaSourceDuration; From 14f2250058ca0b9650d4dd956e34477a9910670e Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Thu, 23 Jul 2015 17:31:32 +1200 Subject: [PATCH 04/56] bug 1190285 remove unused GetCurrentTime() r=padenot --HG-- extra : rebase_source : d976d69b6fd6d6584b6a43214b203608357c7c55 --- dom/media/GraphDriver.cpp | 25 ------------------------- dom/media/GraphDriver.h | 6 ------ 2 files changed, 31 deletions(-) diff --git a/dom/media/GraphDriver.cpp b/dom/media/GraphDriver.cpp index 9c69b423d4f2..4b54bdaf27b0 100644 --- a/dom/media/GraphDriver.cpp +++ b/dom/media/GraphDriver.cpp @@ -336,12 +336,6 @@ SystemClockDriver::GetIntervalForIteration(GraphTime& aFrom, GraphTime& aTo) } } -GraphTime -SystemClockDriver::GetCurrentTime() -{ - return IterationEnd(); -} - TimeStamp OfflineClockDriver::GetCurrentTimeStamp() { @@ -450,13 +444,6 @@ OfflineClockDriver::GetIntervalForIteration(GraphTime& aFrom, GraphTime& aTo) } } -GraphTime -OfflineClockDriver::GetCurrentTime() -{ - return mIterationEnd; -} - - void OfflineClockDriver::WaitForNextIteration() { @@ -711,18 +698,6 @@ AudioCallbackDriver::GetIntervalForIteration(GraphTime& aFrom, { } -GraphTime -AudioCallbackDriver::GetCurrentTime() -{ - uint64_t position = 0; - - if (cubeb_stream_get_position(mAudioStream, &position) != CUBEB_OK) { - NS_WARNING("Could not get current time from cubeb."); - } - - return mSampleRate * position; -} - void AudioCallbackDriver::WaitForNextIteration() { } diff --git a/dom/media/GraphDriver.h b/dom/media/GraphDriver.h index f46737f53e68..7421f14f622c 100644 --- a/dom/media/GraphDriver.h +++ b/dom/media/GraphDriver.h @@ -88,9 +88,6 @@ public: * that will be processed. */ virtual void GetIntervalForIteration(GraphTime& aFrom, GraphTime& aTo) = 0; - /* Returns the current time for this graph. This is the end of the current - * iteration. */ - virtual GraphTime GetCurrentTime() = 0; /* For real-time graphs, this waits until it's time to process more data. For * offline graphs, this is a no-op. */ virtual void WaitForNextIteration() = 0; @@ -292,7 +289,6 @@ public: virtual ~SystemClockDriver(); virtual void GetIntervalForIteration(GraphTime& aFrom, GraphTime& aTo) override; - virtual GraphTime GetCurrentTime() override; virtual void WaitForNextIteration() override; virtual void WakeUp() override; @@ -313,7 +309,6 @@ public: virtual ~OfflineClockDriver(); virtual void GetIntervalForIteration(GraphTime& aFrom, GraphTime& aTo) override; - virtual GraphTime GetCurrentTime() override; virtual void WaitForNextIteration() override; virtual void WakeUp() override; virtual TimeStamp GetCurrentTimeStamp() override; @@ -376,7 +371,6 @@ public: virtual void Revive() override; virtual void GetIntervalForIteration(GraphTime& aFrom, GraphTime& aTo) override; - virtual GraphTime GetCurrentTime() override; virtual void WaitForNextIteration() override; virtual void WakeUp() override; From 20bf85f5cd861ff7a31f6cadc05edea89f52ed40 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Fri, 31 Jul 2015 18:46:04 +1200 Subject: [PATCH 05/56] bug 1190285 remove unused DispatchWhenNotEnoughBuffered r=padenot --HG-- extra : rebase_source : 68f91e0b11ecd0c70d6848c7a505b0208c885d0b --- dom/media/MediaStreamGraph.cpp | 38 +--------------------------------- dom/media/MediaStreamGraph.h | 9 -------- 2 files changed, 1 insertion(+), 46 deletions(-) diff --git a/dom/media/MediaStreamGraph.cpp b/dom/media/MediaStreamGraph.cpp index 26541edca529..2641eafa31c5 100644 --- a/dom/media/MediaStreamGraph.cpp +++ b/dom/media/MediaStreamGraph.cpp @@ -265,8 +265,6 @@ void MediaStreamGraphImpl::UpdateBufferSufficiencyState(SourceMediaStream* aStream) { StreamTime desiredEnd = GetDesiredBufferEnd(aStream); - nsTArray runnables; - { MutexAutoLock lock(aStream->mMutex); for (uint32_t i = 0; i < aStream->mUpdateTracks.Length(); ++i) { @@ -279,8 +277,7 @@ MediaStreamGraphImpl::UpdateBufferSufficiencyState(SourceMediaStream* aStream) continue; } if (data->mCommands & SourceMediaStream::TRACK_END) { - // This track will end, so no point in firing not-enough-data - // callbacks. + // This track will end, so no point updating. continue; } StreamBuffer::Track* track = aStream->mBuffer.FindTrack(data->mID); @@ -288,19 +285,8 @@ MediaStreamGraphImpl::UpdateBufferSufficiencyState(SourceMediaStream* aStream) // removed the track from mUpdateTracks already. NS_ASSERTION(!track->IsEnded(), "What is this track doing here?"); data->mHaveEnough = track->GetEnd() >= desiredEnd; - if (!data->mHaveEnough) { - runnables.MoveElementsFrom(data->mDispatchWhenNotEnough); - } } } - - for (uint32_t i = 0; i < runnables.Length(); ++i) { - // This dispatch was observed to fail in test_video_dimensions.html on - // win8 64 debug when invoked from noop_resampler::fill on the cubeb audio - // thread. - nsCOMPtr r = runnables[i].mRunnable; - runnables[i].mTarget->Dispatch(r.forget(), AbstractThread::DontAssertDispatchSuccess); - } } StreamTime @@ -2669,28 +2655,6 @@ SourceMediaStream::GetEndOfAppendedData(TrackID aID) return 0; } -void -SourceMediaStream::DispatchWhenNotEnoughBuffered(TrackID aID, - TaskQueue* aSignalQueue, nsIRunnable* aSignalRunnable) -{ - MutexAutoLock lock(mMutex); - TrackData* data = FindDataForTrack(aID); - if (!data) { - nsCOMPtr r = aSignalRunnable; - aSignalQueue->Dispatch(r.forget()); - return; - } - - if (data->mHaveEnough) { - if (data->mDispatchWhenNotEnough.IsEmpty()) { - data->mDispatchWhenNotEnough.AppendElement()->Init(aSignalQueue, aSignalRunnable); - } - } else { - nsCOMPtr r = aSignalRunnable; - aSignalQueue->Dispatch(r.forget()); - } -} - void SourceMediaStream::EndTrack(TrackID aID) { diff --git a/dom/media/MediaStreamGraph.h b/dom/media/MediaStreamGraph.h index c45cee0c5a1e..5a2e07d59767 100644 --- a/dom/media/MediaStreamGraph.h +++ b/dom/media/MediaStreamGraph.h @@ -827,14 +827,6 @@ public: * that also calls AppendToTrack. */ StreamTime GetEndOfAppendedData(TrackID aID); - /** - * Ensures that aSignalRunnable will be dispatched to aSignalThread - * when we don't have enough buffered data in the track (which could be - * immediately). Will dispatch the runnable immediately if the track - * does not exist. No op if a runnable is already present for this track. - */ - void DispatchWhenNotEnoughBuffered(TrackID aID, - TaskQueue* aSignalQueue, nsIRunnable* aSignalRunnable); /** * Indicate that a track has ended. Do not do any more API calls * affecting this track. @@ -930,7 +922,6 @@ protected: // Each time the track updates are flushed to the media graph thread, // the segment buffer is emptied. nsAutoPtr mData; - nsTArray mDispatchWhenNotEnough; // Each time the track updates are flushed to the media graph thread, // this is cleared. uint32_t mCommands; From fdab75f3a4232126a165026f2ee62d88695d7609 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Fri, 31 Jul 2015 18:54:05 +1200 Subject: [PATCH 06/56] bug 1190285 remove unused HaveEnoughBuffered r=padenot --HG-- extra : rebase_source : 87bfcfb201f57e441adaefccf379c04cad0a2736 --- dom/media/GraphDriver.h | 9 ----- dom/media/MediaDecoderStateMachine.cpp | 5 +-- dom/media/MediaStreamGraph.cpp | 55 -------------------------- dom/media/MediaStreamGraph.h | 6 --- 4 files changed, 2 insertions(+), 73 deletions(-) diff --git a/dom/media/GraphDriver.h b/dom/media/GraphDriver.h index 7421f14f622c..944f3350c139 100644 --- a/dom/media/GraphDriver.h +++ b/dom/media/GraphDriver.h @@ -50,15 +50,6 @@ static const int SCHEDULE_SAFETY_MARGIN_MS = 10; static const int AUDIO_TARGET_MS = 2*MEDIA_GRAPH_TARGET_PERIOD_MS + SCHEDULE_SAFETY_MARGIN_MS; -/** - * Try have this much video buffered. Video frames are set - * near the end of the iteration of the control loop. The maximum delay - * to the setting of the next video frame is 2*MEDIA_GRAPH_TARGET_PERIOD_MS + - * SCHEDULE_SAFETY_MARGIN_MS. This is not optimal yet. - */ -static const int VIDEO_TARGET_MS = 2*MEDIA_GRAPH_TARGET_PERIOD_MS + - SCHEDULE_SAFETY_MARGIN_MS; - class MediaStreamGraphImpl; /** diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index ca29ec2af00b..cc08de004be4 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -414,9 +414,8 @@ bool MediaDecoderStateMachine::HaveEnoughDecodedAudio(int64_t aAmpleAudioUSecs) return false; } - // We don't have to check SourceMediaStream::HaveEnoughBuffered() in the - // case of stream-capture for MDSM will ensure buffering level is high enough - // for playback speed at 1x at which the DecodedStream is playing. + // MDSM will ensure buffering level is high enough for playback speed at 1x + // at which the DecodedStream is playing. return true; } diff --git a/dom/media/MediaStreamGraph.cpp b/dom/media/MediaStreamGraph.cpp index 2641eafa31c5..c126f22a254a 100644 --- a/dom/media/MediaStreamGraph.cpp +++ b/dom/media/MediaStreamGraph.cpp @@ -71,17 +71,6 @@ MediaStreamGraphImpl::~MediaStreamGraphImpl() LIFECYCLE_LOG("MediaStreamGraphImpl::~MediaStreamGraphImpl\n"); } - -StreamTime -MediaStreamGraphImpl::GetDesiredBufferEnd(MediaStream* aStream) -{ - StreamTime current = IterationEnd() - aStream->mBufferStartTime; - // When waking up media decoders, we need a longer safety margin, as it can - // take more time to get new samples. A factor of two seem to work. - return current + - 2 * MillisecondsToMediaTime(std::max(AUDIO_TARGET_MS, VIDEO_TARGET_MS)); -} - void MediaStreamGraphImpl::FinishStream(MediaStream* aStream) { @@ -261,34 +250,6 @@ MediaStreamGraphImpl::ExtractPendingInput(SourceMediaStream* aStream, } } -void -MediaStreamGraphImpl::UpdateBufferSufficiencyState(SourceMediaStream* aStream) -{ - StreamTime desiredEnd = GetDesiredBufferEnd(aStream); - { - MutexAutoLock lock(aStream->mMutex); - for (uint32_t i = 0; i < aStream->mUpdateTracks.Length(); ++i) { - SourceMediaStream::TrackData* data = &aStream->mUpdateTracks[i]; - if (data->mCommands & SourceMediaStream::TRACK_CREATE) { - // This track hasn't been created yet, so we have no sufficiency - // data. The track will be created in the next iteration of the - // control loop and then we'll fire insufficiency notifications - // if necessary. - continue; - } - if (data->mCommands & SourceMediaStream::TRACK_END) { - // This track will end, so no point updating. - continue; - } - StreamBuffer::Track* track = aStream->mBuffer.FindTrack(data->mID); - // Note that track->IsEnded() must be false, otherwise we would have - // removed the track from mUpdateTracks already. - NS_ASSERTION(!track->IsEnded(), "What is this track doing here?"); - data->mHaveEnough = track->GetEnd() >= desiredEnd; - } - } -} - StreamTime MediaStreamGraphImpl::GraphTimeToStreamTime(MediaStream* aStream, GraphTime aTime) @@ -1438,10 +1399,6 @@ MediaStreamGraphImpl::Process(GraphTime aFrom, GraphTime aTo) } PlayVideo(stream); } - SourceMediaStream* is = stream->AsSourceStream(); - if (is) { - UpdateBufferSufficiencyState(is); - } GraphTime end; if (!stream->mBlocked.GetAt(aTo, &end) || end < GRAPH_TIME_MAX) { allBlockedForever = false; @@ -2471,7 +2428,6 @@ SourceMediaStream::AddTrackInternal(TrackID aID, TrackRate aRate, StreamTime aSt data->mEndOfFlushedData = aStart; data->mCommands = TRACK_CREATE; data->mData = aSegment; - data->mHaveEnough = false; if (!(aFlags & ADDTRACK_QUEUED) && GraphImpl()) { GraphImpl()->EnsureNextIteration(); } @@ -2632,17 +2588,6 @@ SourceMediaStream::RemoveDirectListener(MediaStreamDirectListener* aListener) } } -bool -SourceMediaStream::HaveEnoughBuffered(TrackID aID) -{ - MutexAutoLock lock(mMutex); - TrackData *track = FindDataForTrack(aID); - if (track) { - return track->mHaveEnough; - } - return false; -} - StreamTime SourceMediaStream::GetEndOfAppendedData(TrackID aID) { diff --git a/dom/media/MediaStreamGraph.h b/dom/media/MediaStreamGraph.h index 5a2e07d59767..1d9a91f7a4b1 100644 --- a/dom/media/MediaStreamGraph.h +++ b/dom/media/MediaStreamGraph.h @@ -815,11 +815,6 @@ public: * or the stream was already finished. */ bool AppendToTrack(TrackID aID, MediaSegment* aSegment, MediaSegment *aRawSegment = nullptr); - /** - * Returns true if the buffer currently has enough data. - * Returns false if there isn't enough data or if no such track exists. - */ - bool HaveEnoughBuffered(TrackID aID); /** * Get the stream time of the end of the data that has been appended so far. * Can be called from any thread but won't be useful if it can race with @@ -925,7 +920,6 @@ protected: // Each time the track updates are flushed to the media graph thread, // this is cleared. uint32_t mCommands; - bool mHaveEnough; }; bool NeedsMixing(); From 0c346a395e91fb83b3d95358dc8493bbd064c6dc Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Thu, 23 Jul 2015 11:30:02 +1200 Subject: [PATCH 07/56] bug 1190285 move GetIntervalForIteration() from base class to ThreadedDriver, where it is used r=padenot --HG-- extra : rebase_source : c34ce851b40d8057ff5ca97cdd5f6f703f8a2af0 --- dom/media/GraphDriver.cpp | 6 ------ dom/media/GraphDriver.h | 10 ++++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/dom/media/GraphDriver.cpp b/dom/media/GraphDriver.cpp index 4b54bdaf27b0..86cc9599d4c8 100644 --- a/dom/media/GraphDriver.cpp +++ b/dom/media/GraphDriver.cpp @@ -692,12 +692,6 @@ AudioCallbackDriver::Revive() } } -void -AudioCallbackDriver::GetIntervalForIteration(GraphTime& aFrom, - GraphTime& aTo) -{ -} - void AudioCallbackDriver::WaitForNextIteration() { } diff --git a/dom/media/GraphDriver.h b/dom/media/GraphDriver.h index 944f3350c139..bcd585669e80 100644 --- a/dom/media/GraphDriver.h +++ b/dom/media/GraphDriver.h @@ -75,10 +75,6 @@ public: explicit GraphDriver(MediaStreamGraphImpl* aGraphImpl); NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GraphDriver); - /* When the graph wakes up to do an iteration, this returns the range of time - * that will be processed. */ - virtual void GetIntervalForIteration(GraphTime& aFrom, - GraphTime& aTo) = 0; /* For real-time graphs, this waits until it's time to process more data. For * offline graphs, this is a no-op. */ virtual void WaitForNextIteration() = 0; @@ -265,6 +261,10 @@ public: virtual bool OnThread() override { return !mThread || NS_GetCurrentThread() == mThread; } + /* When the graph wakes up to do an iteration, implementations return the + * range of time that will be processed. */ + virtual void GetIntervalForIteration(GraphTime& aFrom, + GraphTime& aTo) = 0; protected: nsCOMPtr mThread; }; @@ -360,8 +360,6 @@ public: virtual void Stop() override; virtual void Resume() override; virtual void Revive() override; - virtual void GetIntervalForIteration(GraphTime& aFrom, - GraphTime& aTo) override; virtual void WaitForNextIteration() override; virtual void WakeUp() override; From 4ca41a68412df7c78b3411f23e32fd0dcf53f47b Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Thu, 23 Jul 2015 11:48:47 +1200 Subject: [PATCH 08/56] bug 1190285 move GraphTime definition to avoid GraphDriver.h includes r=padenot --HG-- extra : rebase_source : 18cc48140505eff426483c08c1dd4c9c3c0aa909 --- dom/media/GraphDriver.h | 6 ------ dom/media/MediaSegment.h | 6 ++++++ dom/media/MediaStreamGraph.h | 2 +- dom/media/moz.build | 1 - 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/dom/media/GraphDriver.h b/dom/media/GraphDriver.h index bcd585669e80..9c13350f4e9b 100644 --- a/dom/media/GraphDriver.h +++ b/dom/media/GraphDriver.h @@ -52,12 +52,6 @@ static const int AUDIO_TARGET_MS = 2*MEDIA_GRAPH_TARGET_PERIOD_MS + class MediaStreamGraphImpl; -/** - * Microseconds relative to the start of the graph timeline. - */ -typedef int64_t GraphTime; -const GraphTime GRAPH_TIME_MAX = MEDIA_TIME_MAX; - class AudioCallbackDriver; class OfflineClockDriver; diff --git a/dom/media/MediaSegment.h b/dom/media/MediaSegment.h index 76be32869f73..82b1d150a56c 100644 --- a/dom/media/MediaSegment.h +++ b/dom/media/MediaSegment.h @@ -48,6 +48,12 @@ const int64_t MEDIA_TIME_MAX = TRACK_TICKS_MAX; typedef MediaTime StreamTime; const StreamTime STREAM_TIME_MAX = MEDIA_TIME_MAX; +/** + * Media time relative to the start of the graph timeline. + */ +typedef MediaTime GraphTime; +const GraphTime GRAPH_TIME_MAX = MEDIA_TIME_MAX; + /** * A MediaSegment is a chunk of media data sequential in time. Different * types of data have different subclasses of MediaSegment, all inheriting diff --git a/dom/media/MediaStreamGraph.h b/dom/media/MediaStreamGraph.h index 1d9a91f7a4b1..73b940e9a816 100644 --- a/dom/media/MediaStreamGraph.h +++ b/dom/media/MediaStreamGraph.h @@ -12,6 +12,7 @@ #include "mozilla/dom/AudioChannelBinding.h" +#include "AudioSegment.h" #include "AudioStream.h" #include "nsTArray.h" #include "nsIRunnable.h" @@ -21,7 +22,6 @@ #include "VideoSegment.h" #include "MainThreadUtils.h" #include "nsAutoRef.h" -#include "GraphDriver.h" #include #include "DOMMediaStream.h" #include "AudioContext.h" diff --git a/dom/media/moz.build b/dom/media/moz.build index 25d2dbb728d1..4f81f97b619f 100644 --- a/dom/media/moz.build +++ b/dom/media/moz.build @@ -110,7 +110,6 @@ EXPORTS += [ 'DOMMediaStream.h', 'EncodedBufferCache.h', 'FileBlockCache.h', - 'GraphDriver.h', 'Intervals.h', 'Latency.h', 'MediaCache.h', From db58db72fb136c08da3f7e6609f6859c78e7f67a Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Thu, 23 Jul 2015 17:15:49 +1200 Subject: [PATCH 09/56] bug 1190285 share ThreadedDriver interval update code r=padenot --HG-- extra : rebase_source : bb977d7080dbb69d2c485efdf8148f8933f84b0c --- dom/media/GraphDriver.cpp | 69 +++++++++++++++++---------------------- dom/media/GraphDriver.h | 13 ++++---- 2 files changed, 36 insertions(+), 46 deletions(-) diff --git a/dom/media/GraphDriver.cpp b/dom/media/GraphDriver.cpp index 86cc9599d4c8..7bce0a49a745 100644 --- a/dom/media/GraphDriver.cpp +++ b/dom/media/GraphDriver.cpp @@ -280,13 +280,25 @@ ThreadedDriver::RunThread() bool stillProcessing = true; while (stillProcessing) { - GraphTime prevCurrentTime, nextCurrentTime; - GetIntervalForIteration(prevCurrentTime, nextCurrentTime); + mIterationStart = IterationEnd(); + mIterationEnd += GetIntervalForIteration(); + + if (mStateComputedTime < mIterationEnd) { + STREAM_LOG(LogLevel::Warning, ("Media graph global underrun detected")); + mIterationEnd = mStateComputedTime; + } + + if (mIterationStart >= mIterationEnd) { + NS_ASSERTION(mIterationStart == mIterationEnd , + "Time can't go backwards!"); + // This could happen due to low clock resolution, maybe? + STREAM_LOG(LogLevel::Debug, ("Time did not advance")); + } mStateComputedTime = mNextStateComputedTime; mNextStateComputedTime = mGraphImpl->RoundUpToNextAudioBlock( - nextCurrentTime + mGraphImpl->MillisecondsToMediaTime(AUDIO_TARGET_MS)); + mIterationEnd + mGraphImpl->MillisecondsToMediaTime(AUDIO_TARGET_MS)); STREAM_LOG(LogLevel::Debug, ("interval[%ld; %ld] state[%ld; %ld]", (long)mIterationStart, (long)mIterationEnd, @@ -294,8 +306,8 @@ ThreadedDriver::RunThread() mGraphImpl->mFlushSourcesNow = mGraphImpl->mFlushSourcesOnNextIteration; mGraphImpl->mFlushSourcesOnNextIteration = false; - stillProcessing = mGraphImpl->OneIteration(prevCurrentTime, - nextCurrentTime, + stillProcessing = mGraphImpl->OneIteration(mIterationStart, + mIterationEnd, StateComputedTime(), mNextStateComputedTime); @@ -310,30 +322,21 @@ ThreadedDriver::RunThread() } } -void -SystemClockDriver::GetIntervalForIteration(GraphTime& aFrom, GraphTime& aTo) +MediaTime +SystemClockDriver::GetIntervalForIteration() { TimeStamp now = TimeStamp::Now(); - aFrom = mIterationStart = IterationEnd(); - aTo = mIterationEnd = mGraphImpl->SecondsToMediaTime((now - mCurrentTimeStamp).ToSeconds()) + IterationEnd(); - + MediaTime interval = + mGraphImpl->SecondsToMediaTime((now - mCurrentTimeStamp).ToSeconds()); mCurrentTimeStamp = now; - MOZ_LOG(gMediaStreamGraphLog, LogLevel::Verbose, ("Updating current time to %f (real %f, mStateComputedTime %f)", - mGraphImpl->MediaTimeToSeconds(aTo), - (now - mInitialTimeStamp).ToSeconds(), - mGraphImpl->MediaTimeToSeconds(StateComputedTime()))); + MOZ_LOG(gMediaStreamGraphLog, LogLevel::Verbose, + ("Updating current time to %f (real %f, mStateComputedTime %f)", + mGraphImpl->MediaTimeToSeconds(IterationEnd() + interval), + (now - mInitialTimeStamp).ToSeconds(), + mGraphImpl->MediaTimeToSeconds(StateComputedTime()))); - if (mStateComputedTime < aTo) { - STREAM_LOG(LogLevel::Warning, ("Media graph global underrun detected")); - aTo = mIterationEnd = mStateComputedTime; - } - - if (aFrom >= aTo) { - NS_ASSERTION(aFrom == aTo , "Time can't go backwards!"); - // This could happen due to low clock resolution, maybe? - STREAM_LOG(LogLevel::Debug, ("Time did not advance")); - } + return interval; } TimeStamp @@ -426,22 +429,10 @@ OfflineClockDriver::~OfflineClockDriver() } } -void -OfflineClockDriver::GetIntervalForIteration(GraphTime& aFrom, GraphTime& aTo) +MediaTime +OfflineClockDriver::GetIntervalForIteration() { - aFrom = mIterationStart = IterationEnd(); - aTo = mIterationEnd = IterationEnd() + mGraphImpl->MillisecondsToMediaTime(mSlice); - - if (mStateComputedTime < aTo) { - STREAM_LOG(LogLevel::Warning, ("Media graph global underrun detected")); - aTo = mIterationEnd = mStateComputedTime; - } - - if (aFrom >= aTo) { - NS_ASSERTION(aFrom == aTo , "Time can't go backwards!"); - // This could happen due to low clock resolution, maybe? - STREAM_LOG(LogLevel::Debug, ("Time did not advance")); - } + return mGraphImpl->MillisecondsToMediaTime(mSlice); } void diff --git a/dom/media/GraphDriver.h b/dom/media/GraphDriver.h index 9c13350f4e9b..f19573bfc2a2 100644 --- a/dom/media/GraphDriver.h +++ b/dom/media/GraphDriver.h @@ -256,9 +256,10 @@ public: virtual bool OnThread() override { return !mThread || NS_GetCurrentThread() == mThread; } /* When the graph wakes up to do an iteration, implementations return the - * range of time that will be processed. */ - virtual void GetIntervalForIteration(GraphTime& aFrom, - GraphTime& aTo) = 0; + * range of time that will be processed. This is called only once per + * iteration; it may determine the interval from state in a previous + * call. */ + virtual MediaTime GetIntervalForIteration() = 0; protected: nsCOMPtr mThread; }; @@ -272,8 +273,7 @@ class SystemClockDriver : public ThreadedDriver public: explicit SystemClockDriver(MediaStreamGraphImpl* aGraphImpl); virtual ~SystemClockDriver(); - virtual void GetIntervalForIteration(GraphTime& aFrom, - GraphTime& aTo) override; + virtual MediaTime GetIntervalForIteration() override; virtual void WaitForNextIteration() override; virtual void WakeUp() override; @@ -292,8 +292,7 @@ class OfflineClockDriver : public ThreadedDriver public: OfflineClockDriver(MediaStreamGraphImpl* aGraphImpl, GraphTime aSlice); virtual ~OfflineClockDriver(); - virtual void GetIntervalForIteration(GraphTime& aFrom, - GraphTime& aTo) override; + virtual MediaTime GetIntervalForIteration() override; virtual void WaitForNextIteration() override; virtual void WakeUp() override; virtual TimeStamp GetCurrentTimeStamp() override; From a6f86056b924e70172329ec883bc8fac6c9d5de1 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Wed, 29 Jul 2015 16:58:59 +1200 Subject: [PATCH 10/56] bug 1190285 only update mStateComputedTime once per iteration r=padenot UpdateStateComputedTime(GraphTime aStateComputedTime) occurs midway during the iteration, so there is no need to update at the end. --HG-- extra : rebase_source : 82a5fb08596d16ea1926725149b2688cfdf585ec --- dom/media/GraphDriver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dom/media/GraphDriver.cpp b/dom/media/GraphDriver.cpp index 7bce0a49a745..d425a404143e 100644 --- a/dom/media/GraphDriver.cpp +++ b/dom/media/GraphDriver.cpp @@ -295,7 +295,7 @@ ThreadedDriver::RunThread() STREAM_LOG(LogLevel::Debug, ("Time did not advance")); } - mStateComputedTime = mNextStateComputedTime; + MOZ_ASSERT(mStateComputedTime == mNextStateComputedTime); mNextStateComputedTime = mGraphImpl->RoundUpToNextAudioBlock( mIterationEnd + mGraphImpl->MillisecondsToMediaTime(AUDIO_TARGET_MS)); @@ -822,7 +822,7 @@ AudioCallbackDriver::DataCallback(AudioDataValue* aBuffer, long aFrames) // we don't need to run an iteration and if we do so we may overflow. if (mBuffer.Available()) { - mStateComputedTime = mNextStateComputedTime; + MOZ_ASSERT(mStateComputedTime == mNextStateComputedTime); // State computed time is decided by the audio callback's buffer length. We // compute the iteration start and end from there, trying to keep the amount From d149f45532966bb1c714904ee7eb4f163c87370c Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Fri, 31 Jul 2015 12:49:07 +1200 Subject: [PATCH 11/56] bug 1189168 avoid main thread assertion accessing mNode in SizeOfIncludingThis() r=padenot because the main thread is blocked during the call. --HG-- extra : rebase_source : 5ab42bd4d8a14e66e34781456ad11c6b48dc6227 --- dom/media/webaudio/AudioNodeEngine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/media/webaudio/AudioNodeEngine.h b/dom/media/webaudio/AudioNodeEngine.h index 617d2fcd87ce..eaa14828edde 100644 --- a/dom/media/webaudio/AudioNodeEngine.h +++ b/dom/media/webaudio/AudioNodeEngine.h @@ -380,7 +380,7 @@ public: AudioNodeSizes& aUsage) const { aUsage.mEngine = SizeOfIncludingThis(aMallocSizeOf); - if (HasNode()) { + if (mNode) { aUsage.mDomNode = mNode->SizeOfIncludingThis(aMallocSizeOf); aUsage.mNodeType = mNode->NodeType(); } From f017a69bcdd18d8f5d3dddafd735463dc0bfee4d Mon Sep 17 00:00:00 2001 From: "Byron Campen [:bwc]" Date: Wed, 29 Jul 2015 13:10:24 -0500 Subject: [PATCH 12/56] Bug 1142105 - Part 3: Extract more SDP-related functionality out of JsepSessionImpl, and some readability improvements. r=mt --HG-- extra : rebase_source : ecf05d79d34920fdf6aa773332cd53cd736cfea8 --- .../signaling/src/jsep/JsepSessionImpl.cpp | 201 +++++------------- .../signaling/src/jsep/JsepSessionImpl.h | 21 +- media/webrtc/signaling/src/sdp/SdpHelper.cpp | 93 ++++++++ media/webrtc/signaling/src/sdp/SdpHelper.h | 12 ++ 4 files changed, 174 insertions(+), 153 deletions(-) diff --git a/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp b/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp index 0936e397fc25..d9a3e1b29b7f 100644 --- a/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp +++ b/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp @@ -289,7 +289,7 @@ JsepSessionImpl::GetRemoteTracksRemoved() const } nsresult -JsepSessionImpl::AddOfferMSections(const JsepOfferOptions& options, Sdp* sdp) +JsepSessionImpl::SetupOfferMSections(const JsepOfferOptions& options, Sdp* sdp) { // First audio, then video, then datachannel, for interop // TODO(bug 1121756): We need to group these by stream-id, _then_ by media @@ -297,19 +297,19 @@ JsepSessionImpl::AddOfferMSections(const JsepOfferOptions& options, Sdp* sdp) // older versions of Firefox if a video-only stream is added before an // audio-only stream. // We should probably wait until 38 is ESR before trying to do this. - nsresult rv = AddOfferMSectionsByType( + nsresult rv = SetupOfferMSectionsByType( SdpMediaSection::kAudio, options.mOfferToReceiveAudio, sdp); NS_ENSURE_SUCCESS(rv, rv); - rv = AddOfferMSectionsByType( + rv = SetupOfferMSectionsByType( SdpMediaSection::kVideo, options.mOfferToReceiveVideo, sdp); NS_ENSURE_SUCCESS(rv, rv); if (!(options.mDontOfferDataChannel.isSome() && *options.mDontOfferDataChannel)) { - rv = AddOfferMSectionsByType( + rv = SetupOfferMSectionsByType( SdpMediaSection::kApplication, Maybe(), sdp); NS_ENSURE_SUCCESS(rv, rv); @@ -325,9 +325,9 @@ JsepSessionImpl::AddOfferMSections(const JsepOfferOptions& options, Sdp* sdp) } nsresult -JsepSessionImpl::AddOfferMSectionsByType(SdpMediaSection::MediaType mediatype, - Maybe offerToReceiveMaybe, - Sdp* sdp) +JsepSessionImpl::SetupOfferMSectionsByType(SdpMediaSection::MediaType mediatype, + Maybe offerToReceiveMaybe, + Sdp* sdp) { // Convert the Maybe into a size_t*, since that is more readable, especially // when using it as an in/out param. @@ -467,7 +467,7 @@ JsepSessionImpl::SetRecvAsNeededOrDisable(SdpMediaSection::MediaType mediatype, if (!msection.IsSending()) { // Unused m-section, and no reason to offer to recv on it - DisableMsection(sdp, &msection); + mSdpHelper.DisableMsection(sdp, &msection); } } @@ -491,15 +491,15 @@ JsepSessionImpl::AddRecvonlyMsections(SdpMediaSection::MediaType mediatype, // This function creates a skeleton SDP based on the old descriptions // (ie; all m-sections are inactive). nsresult -JsepSessionImpl::CreateReoffer(const Sdp& oldLocalSdp, - const Sdp& oldAnswer, - Sdp* newSdp) +JsepSessionImpl::AddReofferMsections(const Sdp& oldLocalSdp, + const Sdp& oldAnswer, + Sdp* newSdp) { nsresult rv; for (size_t i = 0; i < oldLocalSdp.GetMediaSectionCount(); ++i) { // We do not set the direction in this function (or disable when previously - // disabled), that happens in |AddOfferMSectionsByType| + // disabled), that happens in |SetupOfferMSectionsByType| rv = CreateOfferMSection(oldLocalSdp.GetMediaSection(i).GetMediaType(), SdpDirectionAttribute::kInactive, newSdp); @@ -513,8 +513,6 @@ JsepSessionImpl::CreateReoffer(const Sdp& oldLocalSdp, return NS_OK; } -// TODO(1142105): Do we teach SdpHelper about BundlePolicy, or are -// we getting too much JSEP in there at that point? void JsepSessionImpl::SetupBundle(Sdp* sdp) const { @@ -608,41 +606,42 @@ JsepSessionImpl::CreateOffer(const JsepOfferOptions& options, return NS_ERROR_UNEXPECTED; } + // Undo track assignments from a previous call to CreateOffer + // (ie; if the track has not been negotiated yet, it doesn't necessarily need + // to stay in the same m-section that it was in) + for (auto i = mLocalTracks.begin(); i != mLocalTracks.end(); ++i) { + if (!i->mNegotiated) { + i->mAssignedMLine.reset(); + } + } + UniquePtr sdp; // Make the basic SDP that is common to offer/answer. nsresult rv = CreateGenericSDP(&sdp); NS_ENSURE_SUCCESS(rv, rv); - ++mSessionVersion; if (mCurrentLocalDescription) { - rv = CreateReoffer(*mCurrentLocalDescription, *GetAnswer(), sdp.get()); + rv = AddReofferMsections(*mCurrentLocalDescription, + *GetAnswer(), + sdp.get()); NS_ENSURE_SUCCESS(rv, rv); } - // Get rid of all m-line assignments that have not been negotiated - if (NS_SUCCEEDED(rv)) { - for (auto i = mLocalTracks.begin(); i != mLocalTracks.end(); ++i) { - if (!i->mNegotiated) { - i->mAssignedMLine.reset(); - } - } - } - - // Now add all the m-lines that we are attempting to negotiate. - rv = AddOfferMSections(options, sdp.get()); + // Ensure that we have all the m-sections we need, and disable extras + rv = SetupOfferMSections(options, sdp.get()); NS_ENSURE_SUCCESS(rv, rv); SetupBundle(sdp.get()); - if (GetAnswer()) { - // We have an old answer from a previous negotiation - rv = SetupTransportParams(*GetAnswer(), *sdp, sdp.get()); + if (mCurrentLocalDescription) { + rv = CopyPreviousTransportParams(*GetAnswer(), *sdp, sdp.get()); NS_ENSURE_SUCCESS(rv,rv); } *offer = sdp->ToString(); mGeneratedLocalDescription = Move(sdp); + ++mSessionVersion; return NS_OK; } @@ -774,36 +773,10 @@ void JsepSessionImpl::AddCommonExtmaps(const SdpMediaSection& remoteMsection, SdpMediaSection* msection) { - if (!remoteMsection.GetAttributeList().HasAttribute( - SdpAttribute::kExtmapAttribute)) { - return; - } - auto* ourExtensions = GetRtpExtensions(remoteMsection.GetMediaType()); - if (!ourExtensions) { - return; - } - - UniquePtr ourExtmap(new SdpExtmapAttributeList); - auto& theirExtmap = remoteMsection.GetAttributeList().GetExtmap().mExtmaps; - for (auto i = theirExtmap.begin(); i != theirExtmap.end(); ++i) { - for (auto j = ourExtensions->begin(); j != ourExtensions->end(); ++j) { - if (i->extensionname == j->extensionname) { - ourExtmap->mExtmaps.push_back(*i); - - // RFC 5285 says that ids >= 4096 can be used by the offerer to - // force the answerer to pick, otherwise the value in the offer is - // used. - if (ourExtmap->mExtmaps.back().entry >= 4096) { - ourExtmap->mExtmaps.back().entry = j->entry; - } - } - } - } - - if (!ourExtmap->mExtmaps.empty()) { - msection->GetAttributeList().SetAttribute(ourExtmap.release()); + if (ourExtensions) { + mSdpHelper.AddCommonExtmaps(remoteMsection, *ourExtensions, msection); } } @@ -836,8 +809,6 @@ JsepSessionImpl::CreateAnswer(const JsepAnswerOptions& options, const Sdp& offer = *mPendingRemoteDescription; - std::vector bundleGroups; - // Copy the bundle groups into our answer UniquePtr groupAttr(new SdpGroupAttributeList); mSdpHelper.GetBundleGroups(offer, &groupAttr->mGroups); @@ -869,9 +840,8 @@ JsepSessionImpl::CreateAnswer(const JsepAnswerOptions& options, NS_ENSURE_SUCCESS(rv, rv); } - if (GetAnswer()) { - // We have an old answer from a previous negotiation - rv = SetupTransportParams(*GetAnswer(), *sdp, sdp.get()); + if (mCurrentLocalDescription) { + rv = CopyPreviousTransportParams(*GetAnswer(), *sdp, sdp.get()); NS_ENSURE_SUCCESS(rv,rv); } @@ -953,7 +923,7 @@ JsepSessionImpl::CreateAnswerMSection(const JsepAnswerOptions& options, NS_ENSURE_SUCCESS(rv, rv); if (mSdpHelper.MsectionIsDisabled(remoteMsection)) { - DisableMsection(sdp, &msection); + mSdpHelper.DisableMsection(sdp, &msection); return NS_OK; } @@ -995,13 +965,13 @@ JsepSessionImpl::CreateAnswerMSection(const JsepAnswerOptions& options, AddCommonExtmaps(remoteMsection, &msection); if (!msection.IsReceiving() && !msection.IsSending()) { - DisableMsection(sdp, &msection); + mSdpHelper.DisableMsection(sdp, &msection); return NS_OK; } if (msection.GetFormats().empty()) { // Could not negotiate anything. Disable m-section. - DisableMsection(sdp, &msection); + mSdpHelper.DisableMsection(sdp, &msection); } return NS_OK; @@ -1158,7 +1128,7 @@ JsepSessionImpl::SetLocalDescription(JsepSdpType type, const std::string& sdp) NS_ENSURE_SUCCESS(rv, rv); // Create transport objects. - mOldTransports = mTransports; + mOldTransports = mTransports; // Save in case we need to rollback for (size_t t = 0; t < parsed->GetMediaSectionCount(); ++t) { if (t >= mTransports.size()) { mTransports.push_back(RefPtr(new JsepTransport)); @@ -1385,11 +1355,9 @@ JsepSessionImpl::HandleNegotiatedSession(const UniquePtr& local, mNegotiatedTrackPairs = trackPairs; // Mark all assigned local tracks as negotiated - if (NS_SUCCEEDED(rv)) { - for (auto i = mLocalTracks.begin(); i != mLocalTracks.end(); ++i) { - if (i->mAssignedMLine.isSome()) { - i->mNegotiated = true; - } + for (auto i = mLocalTracks.begin(); i != mLocalTracks.end(); ++i) { + if (i->mAssignedMLine.isSome()) { + i->mNegotiated = true; } } @@ -1679,9 +1647,9 @@ JsepSessionImpl::AddTransportAttributes(SdpMediaSection* msection, } nsresult -JsepSessionImpl::SetupTransportParams(const Sdp& oldAnswer, - const Sdp& newOffer, - Sdp* newLocal) +JsepSessionImpl::CopyPreviousTransportParams(const Sdp& oldAnswer, + const Sdp& newOffer, + Sdp* newLocal) { for (size_t i = 0; i < oldAnswer.GetMediaSectionCount(); ++i) { if (!mSdpHelper.MsectionIsDisabled(newLocal->GetMediaSection(i)) && @@ -2368,14 +2336,6 @@ JsepSessionImpl::EndOfLocalCandidates(const std::string& defaultCandidateAddr, return NS_OK; } - SdpHelper::BundledMids bundledMids; - nsresult rv = GetNegotiatedBundledMids(&bundledMids); - if (NS_FAILED(rv)) { - MOZ_ASSERT(false); - mLastError += " (This should have been caught sooner!)"; - return NS_ERROR_FAILURE; - } - std::string defaultRtcpCandidateAddrCopy(defaultRtcpCandidateAddr); if (mState == kJsepStateStable && mTransports[level]->mComponents == 1) { // We know we're doing rtcp-mux by now. Don't create an rtcp attr. @@ -2383,56 +2343,26 @@ JsepSessionImpl::EndOfLocalCandidates(const std::string& defaultCandidateAddr, defaultRtcpCandidatePort = 0; } - SdpMediaSection& msection = sdp->GetMediaSection(level); - - // TODO(bug 1142105): Factor some of this out into a helper class + // If offer/answer isn't done, it is too early to tell whether these defaults + // need to be applied to other m-sections. + SdpHelper::BundledMids bundledMids; if (mState == kJsepStateStable) { - // offer/answer is done. Do we actually incorporate these defaults? - if (msection.GetAttributeList().HasAttribute(SdpAttribute::kMidAttribute)) { - std::string mid(msection.GetAttributeList().GetMid()); - if (bundledMids.count(mid)) { - const SdpMediaSection* masterBundleMsection(bundledMids[mid]); - if (msection.GetLevel() != masterBundleMsection->GetLevel()) { - // Slave bundle m-section. Skip. - return NS_OK; - } - - // Master bundle m-section. Set defaultCandidateAddr and - // defaultCandidatePort on all bundled m-sections. - for (auto i = bundledMids.begin(); i != bundledMids.end(); ++i) { - if (i->second != masterBundleMsection) { - continue; - } - SdpMediaSection* bundledMsection = - mSdpHelper.FindMsectionByMid(*sdp, i->first); - if (!bundledMsection) { - MOZ_ASSERT(false); - continue; - } - mSdpHelper.SetDefaultAddresses(defaultCandidateAddr, - defaultCandidatePort, - defaultRtcpCandidateAddrCopy, - defaultRtcpCandidatePort, - bundledMsection); - } - } + nsresult rv = GetNegotiatedBundledMids(&bundledMids); + if (NS_FAILED(rv)) { + MOZ_ASSERT(false); + mLastError += " (This should have been caught sooner!)"; + return NS_ERROR_FAILURE; } } - mSdpHelper.SetDefaultAddresses(defaultCandidateAddr, - defaultCandidatePort, - defaultRtcpCandidateAddrCopy, - defaultRtcpCandidatePort, - &msection); - - // TODO(bug 1095793): Will this have an mid someday? - - SdpAttributeList& attrs = msection.GetAttributeList(); - attrs.SetAttribute( - new SdpFlagAttribute(SdpAttribute::kEndOfCandidatesAttribute)); - if (!mIsOfferer) { - attrs.RemoveAttribute(SdpAttribute::kIceOptionsAttribute); - } + mSdpHelper.SetDefaultAddresses( + defaultCandidateAddr, + defaultCandidatePort, + defaultRtcpCandidateAddrCopy, + defaultRtcpCandidatePort, + sdp, + level, + bundledMids); return NS_OK; } @@ -2449,19 +2379,6 @@ JsepSessionImpl::GetNegotiatedBundledMids(SdpHelper::BundledMids* bundledMids) return mSdpHelper.GetBundledMids(*answerSdp, bundledMids); } -void -JsepSessionImpl::DisableMsection(Sdp* sdp, SdpMediaSection* msection) const -{ - mSdpHelper.DisableMsection(sdp, msection); - msection->ClearCodecs(); - - // We need to have something here to fit the grammar - // TODO(bcampen@mozilla.com): What's the accepted way of doing this? Just - // add the codecs we do support? Does it matter? Most endpoints just pick - // something that the other end supported. - msection->AddCodec("111", "NULL", 0, 0); -} - nsresult JsepSessionImpl::EnableOfferMsection(SdpMediaSection* msection) { diff --git a/media/webrtc/signaling/src/jsep/JsepSessionImpl.h b/media/webrtc/signaling/src/jsep/JsepSessionImpl.h index 080282e9c483..cd7e9f77bddd 100644 --- a/media/webrtc/signaling/src/jsep/JsepSessionImpl.h +++ b/media/webrtc/signaling/src/jsep/JsepSessionImpl.h @@ -217,14 +217,14 @@ private: const UniquePtr& remote); nsresult AddTransportAttributes(SdpMediaSection* msection, SdpSetupAttribute::Role dtlsRole); - nsresult SetupTransportParams(const Sdp& oldAnswer, - const Sdp& newOffer, - Sdp* newLocal); - nsresult AddOfferMSections(const JsepOfferOptions& options, Sdp* sdp); + nsresult CopyPreviousTransportParams(const Sdp& oldAnswer, + const Sdp& newOffer, + Sdp* newLocal); + nsresult SetupOfferMSections(const JsepOfferOptions& options, Sdp* sdp); // Non-const so it can assign m-line index to tracks - nsresult AddOfferMSectionsByType(SdpMediaSection::MediaType type, - Maybe offerToReceive, - Sdp* sdp); + nsresult SetupOfferMSectionsByType(SdpMediaSection::MediaType type, + Maybe offerToReceive, + Sdp* sdp); nsresult BindLocalTracks(SdpMediaSection::MediaType mediatype, Sdp* sdp); nsresult BindTrackToMsection(JsepSendingTrack* track, @@ -238,9 +238,9 @@ private: nsresult AddRecvonlyMsections(SdpMediaSection::MediaType mediatype, size_t count, Sdp* sdp); - nsresult CreateReoffer(const Sdp& oldLocalSdp, - const Sdp& oldAnswer, - Sdp* newSdp); + nsresult AddReofferMsections(const Sdp& oldLocalSdp, + const Sdp& oldAnswer, + Sdp* newSdp); void SetupBundle(Sdp* sdp) const; nsresult GetRemoteIds(const Sdp& sdp, const SdpMediaSection& msection, @@ -280,7 +280,6 @@ private: nsresult GetNegotiatedBundledMids(SdpHelper::BundledMids* bundledMids); - void DisableMsection(Sdp* sdp, SdpMediaSection* msection) const; nsresult EnableOfferMsection(SdpMediaSection* msection); nsresult SetUniquePayloadTypes(); diff --git a/media/webrtc/signaling/src/sdp/SdpHelper.cpp b/media/webrtc/signaling/src/sdp/SdpHelper.cpp index 87fe42bacb3e..d2b9b751c4b6 100644 --- a/media/webrtc/signaling/src/sdp/SdpHelper.cpp +++ b/media/webrtc/signaling/src/sdp/SdpHelper.cpp @@ -138,6 +138,11 @@ SdpHelper::DisableMsection(Sdp* sdp, SdpMediaSection* msection) const new SdpDirectionAttribute(SdpDirectionAttribute::kInactive); msection->GetAttributeList().SetAttribute(direction); msection->SetPort(0); + + msection->ClearCodecs(); + + // We need to have something here to fit the grammar, this seems safe. + msection->AddCodec("0", "PCMU", 8000, 1); } void @@ -266,6 +271,61 @@ SdpHelper::AddCandidateToSdp(Sdp* sdp, return NS_OK; } +void +SdpHelper::SetDefaultAddresses(const std::string& defaultCandidateAddr, + uint16_t defaultCandidatePort, + const std::string& defaultRtcpCandidateAddr, + uint16_t defaultRtcpCandidatePort, + Sdp* sdp, + uint16_t level, + BundledMids bundledMids) +{ + SdpMediaSection& msection = sdp->GetMediaSection(level); + + if (msection.GetAttributeList().HasAttribute(SdpAttribute::kMidAttribute)) { + std::string mid(msection.GetAttributeList().GetMid()); + if (bundledMids.count(mid)) { + const SdpMediaSection* masterBundleMsection(bundledMids[mid]); + if (msection.GetLevel() != masterBundleMsection->GetLevel()) { + // Slave bundle m-section. Skip. + return; + } + + // Master bundle m-section. Set defaultCandidateAddr and + // defaultCandidatePort on all bundled m-sections. + for (auto i = bundledMids.begin(); i != bundledMids.end(); ++i) { + if (i->second != masterBundleMsection) { + continue; + } + SdpMediaSection* bundledMsection = FindMsectionByMid(*sdp, i->first); + if (!bundledMsection) { + MOZ_ASSERT(false); + continue; + } + SetDefaultAddresses(defaultCandidateAddr, + defaultCandidatePort, + defaultRtcpCandidateAddr, + defaultRtcpCandidatePort, + bundledMsection); + } + } + } + + SetDefaultAddresses(defaultCandidateAddr, + defaultCandidatePort, + defaultRtcpCandidateAddr, + defaultRtcpCandidatePort, + &msection); + + // TODO(bug 1095793): Will this have an mid someday? + + SdpAttributeList& attrs = msection.GetAttributeList(); + attrs.SetAttribute( + new SdpFlagAttribute(SdpAttribute::kEndOfCandidatesAttribute)); + // Remove trickle-ice option + attrs.RemoveAttribute(SdpAttribute::kIceOptionsAttribute); +} + void SdpHelper::SetDefaultAddresses(const std::string& defaultCandidateAddr, uint16_t defaultCandidatePort, @@ -604,6 +664,39 @@ SdpHelper::GetPtAsInt(const std::string& ptString, uint16_t* ptOutparam) return true; } +void +SdpHelper::AddCommonExtmaps( + const SdpMediaSection& remoteMsection, + const std::vector& localExtensions, + SdpMediaSection* localMsection) +{ + if (!remoteMsection.GetAttributeList().HasAttribute( + SdpAttribute::kExtmapAttribute)) { + return; + } + + UniquePtr localExtmap(new SdpExtmapAttributeList); + auto& theirExtmap = remoteMsection.GetAttributeList().GetExtmap().mExtmaps; + for (auto i = theirExtmap.begin(); i != theirExtmap.end(); ++i) { + for (auto j = localExtensions.begin(); j != localExtensions.end(); ++j) { + if (i->extensionname == j->extensionname) { + localExtmap->mExtmaps.push_back(*i); + + // RFC 5285 says that ids >= 4096 can be used by the offerer to + // force the answerer to pick, otherwise the value in the offer is + // used. + if (localExtmap->mExtmaps.back().entry >= 4096) { + localExtmap->mExtmaps.back().entry = j->entry; + } + } + } + } + + if (!localExtmap->mExtmaps.empty()) { + localMsection->GetAttributeList().SetAttribute(localExtmap.release()); + } +} + } // namespace mozilla diff --git a/media/webrtc/signaling/src/sdp/SdpHelper.h b/media/webrtc/signaling/src/sdp/SdpHelper.h index 84b775a3a0cd..2bc8d84ecbef 100644 --- a/media/webrtc/signaling/src/sdp/SdpHelper.h +++ b/media/webrtc/signaling/src/sdp/SdpHelper.h @@ -62,6 +62,13 @@ class SdpHelper { const std::string& candidate, const std::string& mid, uint16_t level); + void SetDefaultAddresses(const std::string& defaultCandidateAddr, + uint16_t defaultCandidatePort, + const std::string& defaultRtcpCandidateAddr, + uint16_t defaultRtcpCandidatePort, + Sdp* sdp, + uint16_t level, + BundledMids bundledMids); void SetDefaultAddresses(const std::string& defaultCandidateAddr, uint16_t defaultCandidatePort, const std::string& defaultRtcpCandidateAddr, @@ -92,6 +99,11 @@ class SdpHelper { static bool GetPtAsInt(const std::string& ptString, uint16_t* ptOutparam); + void AddCommonExtmaps( + const SdpMediaSection& remoteMsection, + const std::vector& localExtensions, + SdpMediaSection* localMsection); + private: std::string& mLastError; From 411609d79a1e225072bce38ad5d9b0b84b2820c3 Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Mon, 3 Aug 2015 11:47:00 +0200 Subject: [PATCH 13/56] Bug 1155773 - Remove gotos from XPCConvert::NativeArray2JS(). r=bholley --HG-- extra : rebase_source : 4025b380f63bf87dae43becde7b5cf21ffc4ac0a --- js/xpconnect/src/XPCConvert.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/js/xpconnect/src/XPCConvert.cpp b/js/xpconnect/src/XPCConvert.cpp index 8beffbe3b6b1..f960b13d1349 100644 --- a/js/xpconnect/src/XPCConvert.cpp +++ b/js/xpconnect/src/XPCConvert.cpp @@ -1281,7 +1281,7 @@ XPCConvert::NativeArray2JS(MutableHandleValue d, const void** s, for (i = 0; i < count; i++) { \ if (!NativeData2JS(¤t, ((_t*)*s)+i, type, iid, pErr) || \ !JS_DefineElement(cx, array, i, current, JSPROP_ENUMERATE)) \ - goto failure; \ + return false; \ } \ PR_END_MACRO @@ -1301,17 +1301,17 @@ XPCConvert::NativeArray2JS(MutableHandleValue d, const void** s, case nsXPTType::T_BOOL : POPULATE(bool); break; case nsXPTType::T_CHAR : POPULATE(char); break; case nsXPTType::T_WCHAR : POPULATE(char16_t); break; - case nsXPTType::T_VOID : NS_ERROR("bad type"); goto failure; + case nsXPTType::T_VOID : NS_ERROR("bad type"); return false; case nsXPTType::T_IID : POPULATE(nsID*); break; - case nsXPTType::T_DOMSTRING : NS_ERROR("bad type"); goto failure; + case nsXPTType::T_DOMSTRING : NS_ERROR("bad type"); return false; case nsXPTType::T_CHAR_STR : POPULATE(char*); break; case nsXPTType::T_WCHAR_STR : POPULATE(char16_t*); break; case nsXPTType::T_INTERFACE : POPULATE(nsISupports*); break; case nsXPTType::T_INTERFACE_IS : POPULATE(nsISupports*); break; - case nsXPTType::T_UTF8STRING : NS_ERROR("bad type"); goto failure; - case nsXPTType::T_CSTRING : NS_ERROR("bad type"); goto failure; - case nsXPTType::T_ASTRING : NS_ERROR("bad type"); goto failure; - default : NS_ERROR("bad type"); goto failure; + case nsXPTType::T_UTF8STRING : NS_ERROR("bad type"); return false; + case nsXPTType::T_CSTRING : NS_ERROR("bad type"); return false; + case nsXPTType::T_ASTRING : NS_ERROR("bad type"); return false; + default : NS_ERROR("bad type"); return false; } if (pErr) @@ -1319,9 +1319,6 @@ XPCConvert::NativeArray2JS(MutableHandleValue d, const void** s, d.setObject(*array); return true; -failure: - return false; - #undef POPULATE } From 6da34481393fe74ca37fa8a65ef5fca17ae759e3 Mon Sep 17 00:00:00 2001 From: Makoto Kato Date: Tue, 4 Aug 2015 16:03:50 +0900 Subject: [PATCH 14/56] Bug 1190240 - Cannot compile WMFVideoMFTManager.cpp using Windows 10 SDK. r=cpearce --- dom/media/platforms/wmf/WMFVideoMFTManager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp index f031f9d5c99a..35709dce0439 100644 --- a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp +++ b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp @@ -30,6 +30,8 @@ using mozilla::layers::IMFYCbCrImage; using mozilla::layers::LayerManager; using mozilla::layers::LayersBackend; +#if MOZ_WINSDK_MAXVER < 0x0A000000 +// Windows 10+ SDK has VP80 and VP90 defines const GUID MFVideoFormat_VP80 = { 0x30385056, @@ -45,6 +47,7 @@ const GUID MFVideoFormat_VP90 = 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} }; +#endif const CLSID CLSID_WebmMfVp8Dec = { From 527a42ddd97d1e99dbe05e38d1931fe42d58c04f Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Tue, 4 Aug 2015 17:27:52 +1000 Subject: [PATCH 15/56] Bug 1180118 - Part 1: Add a method to match a single nsCSSSelector (without pseudo-elements) against an Element. r=bzbarsky --- layout/style/StyleRule.h | 6 ++++++ layout/style/nsCSSRuleProcessor.cpp | 30 +++++++++++++++++++++++++++++ layout/style/nsCSSRuleProcessor.h | 15 +++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/layout/style/StyleRule.h b/layout/style/StyleRule.h index 8ccc8f4efadc..dd912a173b4c 100644 --- a/layout/style/StyleRule.h +++ b/layout/style/StyleRule.h @@ -159,6 +159,12 @@ public: void ToString(nsAString& aString, mozilla::CSSStyleSheet* aSheet, bool aAppend = false) const; +#ifdef DEBUG + bool IsRestrictedSelector() const { + return PseudoType() == nsCSSPseudoElements::ePseudo_NotPseudoElement; + } +#endif + private: void AddPseudoClassInternal(nsPseudoClassList *aPseudoClass); nsCSSSelector* Clone(bool aDeepNext, bool aDeepNegations) const; diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index df015d61c7cd..6297ef7d6221 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -2293,6 +2293,36 @@ static bool SelectorMatches(Element* aElement, #undef STATE_CHECK +/* static */ bool +nsCSSRuleProcessor::RestrictedSelectorMatches( + Element* aElement, + nsCSSSelector* aSelector, + TreeMatchContext& aTreeMatchContext) +{ + MOZ_ASSERT(aSelector->IsRestrictedSelector(), + "aSelector must not have a pseudo-element"); + + // We match aSelector as if :visited and :link both match visited and + // unvisited links. + + NodeMatchContext nodeContext(EventStates(), + nsCSSRuleProcessor::IsLink(aElement)); + if (nodeContext.mIsRelevantLink) { + aTreeMatchContext.SetHaveRelevantLink(); + } + aTreeMatchContext.ResetForUnvisitedMatching(); + bool matches = SelectorMatches(aElement, aSelector, nodeContext, + aTreeMatchContext, SelectorMatchesFlags::NONE); + if (nodeContext.mIsRelevantLink) { + aTreeMatchContext.ResetForVisitedMatching(); + if (SelectorMatches(aElement, aSelector, nodeContext, aTreeMatchContext, + SelectorMatchesFlags::NONE)) { + matches = true; + } + } + return matches; +} + // Right now, there are four operators: // ' ', the descendant combinator, is greedy // '~', the indirect adjacent sibling combinator, is greedy diff --git a/layout/style/nsCSSRuleProcessor.h b/layout/style/nsCSSRuleProcessor.h index 93fa68656dbf..a60af5422801 100644 --- a/layout/style/nsCSSRuleProcessor.h +++ b/layout/style/nsCSSRuleProcessor.h @@ -112,6 +112,21 @@ public: */ static bool IsLink(mozilla::dom::Element* aElement); + /** + * Returns true if the given aElement matches aSelector. + * Like nsCSSRuleProcessor.cpp's SelectorMatches (and unlike + * SelectorMatchesTree), this does not check an entire selector list + * separated by combinators. + * + * :visited and :link will match both visited and non-visited links, + * as if aTreeMatchContext->mVisitedHandling were eLinksVisitedOrUnvisited. + * + * aSelector is restricted to not containing pseudo-elements. + */ + static bool RestrictedSelectorMatches(mozilla::dom::Element* aElement, + nsCSSSelector* aSelector, + TreeMatchContext& aTreeMatchContext); + // nsIStyleRuleProcessor virtual void RulesMatching(ElementRuleProcessorData* aData) override; From 456e7234ef6d0ae6c9d6e20c54176e6be3900316 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Tue, 4 Aug 2015 17:27:52 +1000 Subject: [PATCH 16/56] Bug 1180118 - Part 2: Add eRestyle_SomeDescendants restyle hint and pass associated restyle hint data into restyle methods. r=bzbarsky --- layout/base/RestyleManager.cpp | 75 ++++++++++++++++++++-------------- layout/base/RestyleManager.h | 32 +++++++++------ layout/base/RestyleTracker.cpp | 14 +++++-- layout/base/RestyleTracker.h | 36 +++++++++++----- layout/base/nsChangeHint.h | 42 ++++++++++++++----- 5 files changed, 133 insertions(+), 66 deletions(-) diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index 1d202aaaa30a..ec829bd83902 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -981,11 +981,12 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList) } void -RestyleManager::RestyleElement(Element* aElement, - nsIFrame* aPrimaryFrame, - nsChangeHint aMinHint, - RestyleTracker& aRestyleTracker, - nsRestyleHint aRestyleHint) +RestyleManager::RestyleElement(Element* aElement, + nsIFrame* aPrimaryFrame, + nsChangeHint aMinHint, + RestyleTracker& aRestyleTracker, + nsRestyleHint aRestyleHint, + const RestyleHintData& aRestyleHintData) { MOZ_ASSERT(mReframingStyleContexts, "should have rsc"); NS_ASSERTION(aPrimaryFrame == aElement->GetPrimaryFrame(), @@ -1022,7 +1023,7 @@ RestyleManager::RestyleElement(Element* aElement, nsCSSFrameConstructor::REMOVE_FOR_RECONSTRUCTION, nullptr); } else if (aPrimaryFrame) { ComputeAndProcessStyleChange(aPrimaryFrame, aMinHint, aRestyleTracker, - aRestyleHint); + aRestyleHint, aRestyleHintData); } else if (aRestyleHint & ~eRestyle_LaterSiblings) { // We're restyling an element with no frame, so we should try to // make one if its new style says it should have one. But in order @@ -1038,7 +1039,8 @@ RestyleManager::RestyleElement(Element* aElement, newContext->StyleDisplay()->mDisplay == NS_STYLE_DISPLAY_CONTENTS) { // Style change for a display:contents node that did not recreate frames. ComputeAndProcessStyleChange(newContext, aElement, aMinHint, - aRestyleTracker, aRestyleHint); + aRestyleTracker, aRestyleHint, + aRestyleHintData); } } } @@ -1637,7 +1639,8 @@ RestyleManager::StartRebuildAllStyleData(RestyleTracker& aRestyleTracker) // frame and not the root node's primary frame? (We could do // roughly what we do for aRestyleHint above.) ComputeAndProcessStyleChange(rootFrame, - changeHint, aRestyleTracker, restyleHint); + changeHint, aRestyleTracker, restyleHint, + RestyleHintData()); } void @@ -1819,7 +1822,8 @@ RestyleManager::UpdateOnlyAnimationStyles() void RestyleManager::PostRestyleEvent(Element* aElement, nsRestyleHint aRestyleHint, - nsChangeHint aMinChangeHint) + nsChangeHint aMinChangeHint, + const RestyleHintData* aRestyleHintData) { if (MOZ_UNLIKELY(!mPresContext) || MOZ_UNLIKELY(mPresContext->PresShell()->IsDestroying())) { @@ -1831,7 +1835,8 @@ RestyleManager::PostRestyleEvent(Element* aElement, return; } - mPendingRestyles.AddPendingRestyle(aElement, aRestyleHint, aMinChangeHint); + mPendingRestyles.AddPendingRestyle(aElement, aRestyleHint, aMinChangeHint, + aRestyleHintData); // Set mHavePendingNonAnimationRestyles for any restyle that could // possibly contain non-animation styles (i.e., those that require us @@ -2742,6 +2747,7 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint) nsTArray> descendants; nsRestyleHint hintToRestore = nsRestyleHint(0); + RestyleHintData hintDataToRestore; if (mContent && mContent->IsElement() && // If we're resolving from the root of the frame tree (which // we do when mDoRebuildAllStyleData), we need to avoid getting the @@ -2764,6 +2770,7 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint) mChangeList->AppendChange(mFrame, mContent, restyleData->mChangeHint); } hintToRestore = restyleData->mRestyleHint; + hintDataToRestore = Move(restyleData->mRestyleHintData); aRestyleHint = nsRestyleHint(aRestyleHint | restyleData->mRestyleHint); descendants.SwapElements(restyleData->mDescendants); } @@ -3586,11 +3593,12 @@ ElementRestyler::RestyleChildren(nsRestyleHint aChildRestyleHint) void ElementRestyler::RestyleChildrenOfDisplayContentsElement( - nsIFrame* aParentFrame, - nsStyleContext* aNewContext, - nsChangeHint aMinHint, - RestyleTracker& aRestyleTracker, - nsRestyleHint aRestyleHint) + nsIFrame* aParentFrame, + nsStyleContext* aNewContext, + nsChangeHint aMinHint, + RestyleTracker& aRestyleTracker, + nsRestyleHint aRestyleHint, + const RestyleHintData& aRestyleHintData) { MOZ_ASSERT(!(mHintsHandled & nsChangeHint_ReconstructFrame), "why call me?"); @@ -3619,8 +3627,8 @@ ElementRestyler::RestyleChildrenOfDisplayContentsElement( !f->GetPrevContinuation()) { if (!(f->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) { ComputeStyleChangeFor(f, mChangeList, aMinHint, aRestyleTracker, - aRestyleHint, mContextsToClear, - mSwappedStructOwners); + aRestyleHint, aRestyleHintData, + mContextsToClear, mSwappedStructOwners); } } } @@ -3637,6 +3645,7 @@ ElementRestyler::ComputeStyleChangeFor(nsIFrame* aFrame, nsChangeHint aMinChange, RestyleTracker& aRestyleTracker, nsRestyleHint aRestyleHint, + const RestyleHintData& aRestyleHintData, nsTArray& aContextsToClear, nsTArray>& @@ -4090,10 +4099,11 @@ ClearCachedInheritedStyleDataOnDescendants( } void -RestyleManager::ComputeAndProcessStyleChange(nsIFrame* aFrame, - nsChangeHint aMinChange, - RestyleTracker& aRestyleTracker, - nsRestyleHint aRestyleHint) +RestyleManager::ComputeAndProcessStyleChange(nsIFrame* aFrame, + nsChangeHint aMinChange, + RestyleTracker& aRestyleTracker, + nsRestyleHint aRestyleHint, + const RestyleHintData& aRestyleHintData) { MOZ_ASSERT(mReframingStyleContexts, "should have rsc"); nsStyleChangeList changeList; @@ -4105,17 +4115,19 @@ RestyleManager::ComputeAndProcessStyleChange(nsIFrame* aFrame, nsTArray> swappedStructOwners; ElementRestyler::ComputeStyleChangeFor(aFrame, &changeList, aMinChange, aRestyleTracker, aRestyleHint, + aRestyleHintData, contextsToClear, swappedStructOwners); ProcessRestyledFrames(changeList); ClearCachedInheritedStyleDataOnDescendants(contextsToClear); } void -RestyleManager::ComputeAndProcessStyleChange(nsStyleContext* aNewContext, - Element* aElement, - nsChangeHint aMinChange, - RestyleTracker& aRestyleTracker, - nsRestyleHint aRestyleHint) +RestyleManager::ComputeAndProcessStyleChange(nsStyleContext* aNewContext, + Element* aElement, + nsChangeHint aMinChange, + RestyleTracker& aRestyleTracker, + nsRestyleHint aRestyleHint, + const RestyleHintData& aRestyleHintData) { MOZ_ASSERT(mReframingStyleContexts, "should have rsc"); MOZ_ASSERT(aNewContext->StyleDisplay()->mDisplay == NS_STYLE_DISPLAY_CONTENTS); @@ -4142,7 +4154,8 @@ RestyleManager::ComputeAndProcessStyleChange(nsStyleContext* aNewContext, visibleKidsOfHiddenElement, contextsToClear, swappedStructOwners); r.RestyleChildrenOfDisplayContentsElement(frame, aNewContext, aMinChange, - aRestyleTracker, aRestyleHint); + aRestyleTracker, + aRestyleHint, aRestyleHintData); ProcessRestyledFrames(changeList); ClearCachedInheritedStyleDataOnDescendants(contextsToClear); } @@ -4223,9 +4236,11 @@ RestyleManager::RestyleHintToString(nsRestyleHint aHint) { nsCString result; bool any = false; - const char* names[] = { "Self", "Subtree", "LaterSiblings", "CSSTransitions", - "CSSAnimations", "SVGAttrAnimations", "StyleAttribute", - "StyleAttribute_Animations", "Force", "ForceDescendants" }; + const char* names[] = { + "Self", "SomeDescendants", "Subtree", "LaterSiblings", "CSSTransitions", + "CSSAnimations", "SVGAttrAnimations", "StyleAttribute", + "StyleAttribute_Animations", "Force", "ForceDescendants" + }; uint32_t hint = aHint & ((1 << ArrayLength(names)) - 1); uint32_t rest = aHint & ~((1 << ArrayLength(names)) - 1); for (uint32_t i = 0; i < ArrayLength(names); i++) { diff --git a/layout/base/RestyleManager.h b/layout/base/RestyleManager.h index a83e43e062ed..5008b923fd25 100644 --- a/layout/base/RestyleManager.h +++ b/layout/base/RestyleManager.h @@ -129,16 +129,18 @@ public: private: // Used when restyling an element with a frame. - void ComputeAndProcessStyleChange(nsIFrame* aFrame, - nsChangeHint aMinChange, - RestyleTracker& aRestyleTracker, - nsRestyleHint aRestyleHint); + void ComputeAndProcessStyleChange(nsIFrame* aFrame, + nsChangeHint aMinChange, + RestyleTracker& aRestyleTracker, + nsRestyleHint aRestyleHint, + const RestyleHintData& aRestyleHintData); // Used when restyling a display:contents element. - void ComputeAndProcessStyleChange(nsStyleContext* aNewContext, - Element* aElement, - nsChangeHint aMinChange, - RestyleTracker& aRestyleTracker, - nsRestyleHint aRestyleHint); + void ComputeAndProcessStyleChange(nsStyleContext* aNewContext, + Element* aElement, + nsChangeHint aMinChange, + RestyleTracker& aRestyleTracker, + nsRestyleHint aRestyleHint, + const RestyleHintData& aRestyleHintData); public: @@ -335,10 +337,12 @@ public: * on them. * @param aMinChangeHint: A minimum change hint for aContent and its * descendants. + * @param aRestyleHintData: Additional data to go with aRestyleHint. */ void PostRestyleEvent(Element* aElement, nsRestyleHint aRestyleHint, - nsChangeHint aMinChangeHint); + nsChangeHint aMinChangeHint, + const RestyleHintData* aRestyleHintData = nullptr); void PostRestyleEventForLazyConstruction() { @@ -423,7 +427,8 @@ private: nsIFrame* aPrimaryFrame, nsChangeHint aMinHint, RestyleTracker& aRestyleTracker, - nsRestyleHint aRestyleHint); + nsRestyleHint aRestyleHint, + const RestyleHintData& aRestyleHintData); void StartRebuildAllStyleData(RestyleTracker& aRestyleTracker); void FinishRebuildAllStyleData(); @@ -577,7 +582,9 @@ public: nsStyleContext* aNewContext, nsChangeHint aMinHint, RestyleTracker& aRestyleTracker, - nsRestyleHint aRestyleHint); + nsRestyleHint aRestyleHint, + const RestyleHintData& + aRestyleHintData); /** * Re-resolve the style contexts for a frame tree, building aChangeList @@ -588,6 +595,7 @@ public: nsChangeHint aMinChange, RestyleTracker& aRestyleTracker, nsRestyleHint aRestyleHint, + const RestyleHintData& aRestyleHintData, nsTArray& aContextsToClear, nsTArray>& aSwappedStructOwners); diff --git a/layout/base/RestyleTracker.cpp b/layout/base/RestyleTracker.cpp index 466dfd5f7422..537387e57a74 100644 --- a/layout/base/RestyleTracker.cpp +++ b/layout/base/RestyleTracker.cpp @@ -169,6 +169,9 @@ CollectRestyles(nsISupports* aElement, currentRestyle->mElement = element; currentRestyle->mRestyleHint = aData->mRestyleHint; currentRestyle->mChangeHint = aData->mChangeHint; + // We can move aData since we'll be clearing mPendingRestyles after + // we finish enumerating it. + currentRestyle->mRestyleHintData = Move(aData->mRestyleHintData); #if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API) currentRestyle->mBacktrace = Move(aData->mBacktrace); #endif @@ -186,7 +189,8 @@ CollectRestyles(nsISupports* aElement, inline void RestyleTracker::ProcessOneRestyle(Element* aElement, nsRestyleHint aRestyleHint, - nsChangeHint aChangeHint) + nsChangeHint aChangeHint, + const RestyleHintData& aRestyleHintData) { NS_PRECONDITION((aRestyleHint & eRestyle_LaterSiblings) == 0, "Someone should have handled this before calling us"); @@ -211,7 +215,7 @@ RestyleTracker::ProcessOneRestyle(Element* aElement, } #endif mRestyleManager->RestyleElement(aElement, primaryFrame, aChangeHint, - *this, aRestyleHint); + *this, aRestyleHint, aRestyleHintData); } else if (aChangeHint && (primaryFrame || (aChangeHint & nsChangeHint_ReconstructFrame))) { @@ -367,7 +371,8 @@ RestyleTracker::DoProcessRestyles() profilerRAII.emplace("Paint", "Styles", Move(data->mBacktrace)); } #endif - ProcessOneRestyle(element, data->mRestyleHint, data->mChangeHint); + ProcessOneRestyle(element, data->mRestyleHint, data->mChangeHint, + data->mRestyleHintData); AddRestyleRootsIfAwaitingRestyle(data->mDescendants); if (isTimelineRecording) { @@ -427,7 +432,8 @@ RestyleTracker::DoProcessRestyles() ProcessOneRestyle(currentRestyle->mElement, currentRestyle->mRestyleHint, - currentRestyle->mChangeHint); + currentRestyle->mChangeHint, + currentRestyle->mRestyleHintData); if (isTimelineRecording) { mozilla::UniquePtr marker = diff --git a/layout/base/RestyleTracker.h b/layout/base/RestyleTracker.h index 3512181dc89e..95219c92d5e8 100644 --- a/layout/base/RestyleTracker.h +++ b/layout/base/RestyleTracker.h @@ -258,7 +258,8 @@ public: * if the element already had eRestyle_LaterSiblings set on it. */ bool AddPendingRestyle(Element* aElement, nsRestyleHint aRestyleHint, - nsChangeHint aMinChangeHint); + nsChangeHint aMinChangeHint, + const RestyleHintData* aRestyleHintData = nullptr); /** * Process the restyles we've been tracking. @@ -276,8 +277,9 @@ public: } struct Hints { - nsRestyleHint mRestyleHint; // What we want to restyle - nsChangeHint mChangeHint; // The minimal change hint for "self" + nsRestyleHint mRestyleHint; // What we want to restyle + nsChangeHint mChangeHint; // The minimal change hint for "self" + RestyleHintData mRestyleHintData; // Data associated with mRestyleHint }; struct RestyleData : Hints { @@ -286,9 +288,13 @@ public: mChangeHint = NS_STYLE_HINT_NONE; } - RestyleData(nsRestyleHint aRestyleHint, nsChangeHint aChangeHint) { + RestyleData(nsRestyleHint aRestyleHint, nsChangeHint aChangeHint, + const RestyleHintData* aRestyleHintData) { mRestyleHint = aRestyleHint; mChangeHint = aChangeHint; + if (aRestyleHintData) { + mRestyleHintData = *aRestyleHintData; + } } // Descendant elements we must check that we ended up restyling, ordered @@ -341,7 +347,8 @@ public: private: bool AddPendingRestyleToTable(Element* aElement, nsRestyleHint aRestyleHint, - nsChangeHint aMinChangeHint); + nsChangeHint aMinChangeHint, + const RestyleHintData* aRestyleHintData = nullptr); /** * Handle a single mPendingRestyles entry. aRestyleHint must not @@ -350,7 +357,8 @@ private: */ inline void ProcessOneRestyle(Element* aElement, nsRestyleHint aRestyleHint, - nsChangeHint aChangeHint); + nsChangeHint aChangeHint, + const RestyleHintData& aRestyleHintData); typedef nsClassHashtable PendingRestyleTable; typedef nsAutoTArray< nsRefPtr, 32> RestyleRootArray; @@ -381,7 +389,8 @@ private: inline bool RestyleTracker::AddPendingRestyleToTable(Element* aElement, nsRestyleHint aRestyleHint, - nsChangeHint aMinChangeHint) + nsChangeHint aMinChangeHint, + const RestyleHintData* aRestyleHintData) { RestyleData* existingData; @@ -396,7 +405,8 @@ RestyleTracker::AddPendingRestyleToTable(Element* aElement, } if (!existingData) { - RestyleData* rd = new RestyleData(aRestyleHint, aMinChangeHint); + RestyleData* rd = + new RestyleData(aRestyleHint, aMinChangeHint, aRestyleHintData); #if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API) if (profiler_feature_active("restyle")) { rd->mBacktrace.reset(profiler_get_backtrace()); @@ -411,6 +421,10 @@ RestyleTracker::AddPendingRestyleToTable(Element* aElement, existingData->mRestyleHint = nsRestyleHint(existingData->mRestyleHint | aRestyleHint); NS_UpdateHint(existingData->mChangeHint, aMinChangeHint); + if (aRestyleHintData) { + existingData->mRestyleHintData.mSelectorsForDescendants + .AppendElements(aRestyleHintData->mSelectorsForDescendants); + } return hadRestyleLaterSiblings; } @@ -418,10 +432,12 @@ RestyleTracker::AddPendingRestyleToTable(Element* aElement, inline bool RestyleTracker::AddPendingRestyle(Element* aElement, nsRestyleHint aRestyleHint, - nsChangeHint aMinChangeHint) + nsChangeHint aMinChangeHint, + const RestyleHintData* aRestyleHintData) { bool hadRestyleLaterSiblings = - AddPendingRestyleToTable(aElement, aRestyleHint, aMinChangeHint); + AddPendingRestyleToTable(aElement, aRestyleHint, aMinChangeHint, + aRestyleHintData); // We can only treat this element as a restyle root if we would // actually restyle its descendants (so either call diff --git a/layout/base/nsChangeHint.h b/layout/base/nsChangeHint.h index 789dd8d403f1..55d90f2d8692 100644 --- a/layout/base/nsChangeHint.h +++ b/layout/base/nsChangeHint.h @@ -8,8 +8,11 @@ #ifndef nsChangeHint_h___ #define nsChangeHint_h___ -#include "nsDebug.h" #include "mozilla/Types.h" +#include "nsDebug.h" +#include "nsTArray.h" + +class nsCSSSelector; // Defines for various style related constants @@ -377,36 +380,40 @@ enum nsRestyleHint { // work.) eRestyle_Self = (1<<0), + // Rerun selector matching on descendants of the element that match + // a given selector. + eRestyle_SomeDescendants = (1<<1), + // Rerun selector matching on the element and all of its descendants. // (Implies eRestyle_ForceDescendants, which ensures that we continue // the restyling process for all descendants, but doesn't cause // selector matching.) - eRestyle_Subtree = (1<<1), + eRestyle_Subtree = (1<<2), // Rerun selector matching on all later siblings of the element and // all of their descendants. - eRestyle_LaterSiblings = (1<<2), + eRestyle_LaterSiblings = (1<<3), // Replace the style data coming from CSS transitions without updating // any other style data. If a new style context results, update style // contexts on the descendants. (Irrelevant if eRestyle_Self or // eRestyle_Subtree is also set, since those imply a superset of the // work.) - eRestyle_CSSTransitions = (1<<3), + eRestyle_CSSTransitions = (1<<4), // Replace the style data coming from CSS animations without updating // any other style data. If a new style context results, update style // contexts on the descendants. (Irrelevant if eRestyle_Self or // eRestyle_Subtree is also set, since those imply a superset of the // work.) - eRestyle_CSSAnimations = (1<<4), + eRestyle_CSSAnimations = (1<<5), // Replace the style data coming from SVG animations (SMIL Animations) // without updating any other style data. If a new style context // results, update style contexts on the descendants. (Irrelevant if // eRestyle_Self or eRestyle_Subtree is also set, since those imply a // superset of the work.) - eRestyle_SVGAttrAnimations = (1<<5), + eRestyle_SVGAttrAnimations = (1<<6), // Replace the style data coming from inline style without updating // any other style data. If a new style context results, update style @@ -417,22 +424,22 @@ enum nsRestyleHint { // eRestyle_Self. // If the change is for the advance of a declarative animation, use // the value below instead. - eRestyle_StyleAttribute = (1<<6), + eRestyle_StyleAttribute = (1<<7), // Same as eRestyle_StyleAttribute, but for when the change results // from the advance of a declarative animation. - eRestyle_StyleAttribute_Animations = (1<<7), + eRestyle_StyleAttribute_Animations = (1<<8), // Continue the restyling process to the current frame's children even // if this frame's restyling resulted in no style changes. - eRestyle_Force = (1<<8), + eRestyle_Force = (1<<9), // Continue the restyling process to all of the current frame's // descendants, even if any frame's restyling resulted in no style // changes. (Implies eRestyle_Force.) Note that this is weaker than // eRestyle_Subtree, which makes us rerun selector matching on all // descendants rather than just continuing the restyling process. - eRestyle_ForceDescendants = (1<<9), + eRestyle_ForceDescendants = (1<<10), // Useful unions: eRestyle_AllHintsWithAnimations = eRestyle_CSSTransitions | @@ -483,4 +490,19 @@ inline nsRestyleHint operator^=(nsRestyleHint& aLeft, nsRestyleHint aRight) return aLeft = aLeft ^ aRight; } +namespace mozilla { + +/** + * Additional data used in conjunction with an nsRestyleHint to control the + * restyle process. + */ +struct RestyleHintData +{ + // When eRestyle_SomeDescendants is used, this array contains the selectors + // that identify which descendants will be restyled. + nsTArray mSelectorsForDescendants; +}; + +} // namespace mozilla + #endif /* nsChangeHint_h___ */ From 1893e1d44dedc3826ddddf3cc8543bc91e42bf2f Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Tue, 4 Aug 2015 17:27:52 +1000 Subject: [PATCH 17/56] Bug 1180118 - Part 3: Convert eRestyle_SomeDescendants into eRestyle_Self for elements that match selectors. r=bzbarsky --- layout/base/RestyleManager.cpp | 307 ++++++++++++++++++++-------- layout/base/RestyleManager.h | 20 ++ layout/base/RestyleTracker.h | 8 + layout/style/nsCSSRuleProcessor.cpp | 27 +++ 4 files changed, 280 insertions(+), 82 deletions(-) diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index ec829bd83902..d49f997b6b80 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -41,6 +41,8 @@ #include "nsDisplayList.h" #include "RestyleTrackerInlines.h" #include "nsSMILAnimationController.h" +#include "nsCSSRuleProcessor.h" +#include "ChildIterator.h" #ifdef ACCESSIBILITY #include "nsAccessibilityService.h" @@ -1011,6 +1013,9 @@ RestyleManager::RestyleElement(Element* aElement, newContext->StyleFont()->mFont.size) { // The basis for 'rem' units has changed. mRebuildAllRestyleHint |= aRestyleHint; + if (aRestyleHint & eRestyle_SomeDescendants) { + mRebuildAllRestyleHint |= eRestyle_Subtree; + } NS_UpdateHint(mRebuildAllExtraHint, aMinHint); StartRebuildAllStyleData(aRestyleTracker); return; @@ -1558,6 +1563,9 @@ RestyleManager::RebuildAllStyleData(nsChangeHint aExtraHint, NS_ASSERTION(!(aExtraHint & nsChangeHint_ReconstructFrame), "Should not reconstruct the root of the frame tree. " "Use ReconstructDocElementHierarchy instead."); + MOZ_ASSERT(!(aRestyleHint & ~(eRestyle_Subtree | eRestyle_ForceDescendants)), + "the only bits allowed in aRestyleHint are eRestyle_Subtree and " + "eRestyle_ForceDescendants"); NS_UpdateHint(mRebuildAllExtraHint, aExtraHint); mRebuildAllRestyleHint |= aRestyleHint; @@ -1875,6 +1883,9 @@ RestyleManager::PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint, NS_ASSERTION(!(aExtraHint & nsChangeHint_ReconstructFrame), "Should not reconstruct the root of the frame tree. " "Use ReconstructDocElementHierarchy instead."); + MOZ_ASSERT(!(aRestyleHint & eRestyle_SomeDescendants), + "PostRebuildAllStyleDataEvent does not handle " + "eRestyle_SomeDescendants"); mDoRebuildAllStyleData = true; NS_UpdateHint(mRebuildAllExtraHint, aExtraHint); @@ -2472,6 +2483,8 @@ ElementRestyler::ElementRestyler(nsPresContext* aPresContext, nsStyleChangeList* aChangeList, nsChangeHint aHintsHandledByAncestors, RestyleTracker& aRestyleTracker, + nsTArray& + aSelectorsForDescendants, TreeMatchContext& aTreeMatchContext, nsTArray& aVisibleKidsOfHiddenElement, @@ -2490,6 +2503,7 @@ ElementRestyler::ElementRestyler(nsPresContext* aPresContext, , mParentFrameHintsNotHandledForDescendants(nsChangeHint(0)) , mHintsNotHandledForDescendants(nsChangeHint(0)) , mRestyleTracker(aRestyleTracker) + , mSelectorsForDescendants(aSelectorsForDescendants) , mTreeMatchContext(aTreeMatchContext) , mResolvedChild(nullptr) , mContextsToClear(aContextsToClear) @@ -2522,6 +2536,7 @@ ElementRestyler::ElementRestyler(const ElementRestyler& aParentRestyler, aParentRestyler.mHintsNotHandledForDescendants) , mHintsNotHandledForDescendants(nsChangeHint(0)) , mRestyleTracker(aParentRestyler.mRestyleTracker) + , mSelectorsForDescendants(aParentRestyler.mSelectorsForDescendants) , mTreeMatchContext(aParentRestyler.mTreeMatchContext) , mResolvedChild(nullptr) , mContextsToClear(aParentRestyler.mContextsToClear) @@ -2568,6 +2583,7 @@ ElementRestyler::ElementRestyler(ParentContextFromChildFrame, nsChangeHint_Hints_NotHandledForDescendants) , mHintsNotHandledForDescendants(nsChangeHint(0)) , mRestyleTracker(aParentRestyler.mRestyleTracker) + , mSelectorsForDescendants(aParentRestyler.mSelectorsForDescendants) , mTreeMatchContext(aParentRestyler.mTreeMatchContext) , mResolvedChild(nullptr) , mContextsToClear(aParentRestyler.mContextsToClear) @@ -2589,6 +2605,7 @@ ElementRestyler::ElementRestyler(nsPresContext* aPresContext, nsStyleChangeList* aChangeList, nsChangeHint aHintsHandledByAncestors, RestyleTracker& aRestyleTracker, + nsTArray& aSelectorsForDescendants, TreeMatchContext& aTreeMatchContext, nsTArray& aVisibleKidsOfHiddenElement, @@ -2605,6 +2622,7 @@ ElementRestyler::ElementRestyler(nsPresContext* aPresContext, , mParentFrameHintsNotHandledForDescendants(nsChangeHint(0)) , mHintsNotHandledForDescendants(nsChangeHint(0)) , mRestyleTracker(aRestyleTracker) + , mSelectorsForDescendants(aSelectorsForDescendants) , mTreeMatchContext(aTreeMatchContext) , mResolvedChild(nullptr) , mContextsToClear(aContextsToClear) @@ -2704,6 +2722,78 @@ ElementRestyler::CaptureChange(nsStyleContext* aOldContext, RestyleManager::ChangeHintToString(mHintsNotHandledForDescendants).get()); } +class MOZ_STACK_CLASS AutoSelectorArrayTruncater final +{ +public: + AutoSelectorArrayTruncater(nsTArray& aSelectorsForDescendants) + : mSelectorsForDescendants(aSelectorsForDescendants) + , mOriginalLength(aSelectorsForDescendants.Length()) + { + } + + ~AutoSelectorArrayTruncater() + { + mSelectorsForDescendants.TruncateLength(mOriginalLength); + } + +private: + nsTArray& mSelectorsForDescendants; + size_t mOriginalLength; +}; + +/** + * Called when we are stopping a restyle with eRestyle_SomeDescendants, to + * search for descendants that match any of the selectors in + * mSelectorsForDescendants. If the element does match one of the selectors, + * we cause it to be restyled with eRestyle_Self. + * + * We traverse down the flattened tree unless we find an element that + * (a) already has a pending restyle, or (b) does not have a pending restyle + * but does match one of the selectors in mSelectorsForDescendants. For (a), + * we add the current mSelectorsForDescendants into the existing restyle data, + * and for (b) we add a new pending restyle with that array. So in both + * cases, when we come to restyling this element back up in + * ProcessPendingRestyles, we will again find the eRestyle_SomeDescendants + * hint and its selectors array. + * + * This ensures that we don't visit descendant elements and check them + * against mSelectorsForDescendants more than once. + */ +void +ElementRestyler::AddPendingRestylesForDescendantsMatchingSelectors(Element* aElement) +{ + if (mRestyleTracker.HasRestyleData(aElement)) { + nsRestyleHint rshint = eRestyle_SomeDescendants; + if (SelectorMatchesForRestyle(aElement)) { + rshint |= eRestyle_Self; + } + // XXX Traversing up the tree in AddPendingRestyle can be wasteful, + // as we can do this multiple times for descendants of the element + // we stopped restyling at, up in Restyle(). We should track the + // current restyle root as we traverse down here to avoid that. + RestyleHintData data; + data.mSelectorsForDescendants = mSelectorsForDescendants; + mRestyleTracker.AddPendingRestyle(aElement, rshint, nsChangeHint(0), &data); + return; + } + + if (SelectorMatchesForRestyle(aElement)) { + RestyleHintData data; + data.mSelectorsForDescendants = mSelectorsForDescendants; + mRestyleTracker.AddPendingRestyle(aElement, + eRestyle_Self | eRestyle_SomeDescendants, + nsChangeHint(0), &data); + return; + } + + FlattenedChildIterator it(aElement); + for (nsIContent* n = it.GetNextChild(); n; n = it.GetNextChild()) { + if (n->IsElement()) { + AddPendingRestylesForDescendantsMatchingSelectors(n->AsElement()); + } + } +} + /** * Recompute style for mFrame (which should not have a prev continuation * with the same style), all of its next continuations with the same @@ -2740,6 +2830,8 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint) AutoDisplayContentsAncestorPusher adcp(mTreeMatchContext, mFrame->PresContext(), mFrame->GetContent() ? mFrame->GetContent()->GetParent() : nullptr); + AutoSelectorArrayTruncater asat(mSelectorsForDescendants); + // List of descendant elements of mContent we know we will eventually need to // restyle. Before we return from this function, we call // RestyleTracker::AddRestyleRootsIfAwaitingRestyle to ensure they get @@ -2769,6 +2861,8 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint) if (NS_UpdateHint(mHintsHandled, restyleData->mChangeHint)) { mChangeList->AppendChange(mFrame, mContent, restyleData->mChangeHint); } + mSelectorsForDescendants.AppendElements( + restyleData->mRestyleHintData.mSelectorsForDescendants); hintToRestore = restyleData->mRestyleHint; hintDataToRestore = Move(restyleData->mRestyleHintData); aRestyleHint = nsRestyleHint(aRestyleHint | restyleData->mRestyleHint); @@ -2780,7 +2874,8 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint) // we restyle children with nsRestyleHint(0). But we pass the // eRestyle_ForceDescendants flag down too. nsRestyleHint childRestyleHint = - nsRestyleHint(aRestyleHint & (eRestyle_Subtree | + nsRestyleHint(aRestyleHint & (eRestyle_SomeDescendants | + eRestyle_Subtree | eRestyle_ForceDescendants)); nsRefPtr oldContext = mFrame->StyleContext(); @@ -2883,6 +2978,18 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint) } mRestyleTracker.AddRestyleRootsIfAwaitingRestyle(descendants); + + if (mContent->IsElement()) { + if ((aRestyleHint & eRestyle_SomeDescendants) && + !mSelectorsForDescendants.IsEmpty()) { + FlattenedChildIterator it(mContent->AsElement()); + for (nsIContent* n = it.GetNextChild(); n; n = it.GetNextChild()) { + if (n->IsElement()) { + AddPendingRestylesForDescendantsMatchingSelectors(n->AsElement()); + } + } + } + } return; } @@ -3084,6 +3191,30 @@ ElementRestyler::ComputeRestyleResultFromNewContext(nsIFrame* aSelf, return eRestyleResult_Stop; } +bool +ElementRestyler::SelectorMatchesForRestyle(Element* aElement) +{ + if (!aElement) { + return false; + } + for (nsCSSSelector* selector : mSelectorsForDescendants) { + if (nsCSSRuleProcessor::RestrictedSelectorMatches(aElement, selector, + mTreeMatchContext)) { + return true; + } + } + return false; +} + +bool +ElementRestyler::MustRestyleSelf(nsRestyleHint aRestyleHint, + Element* aElement) +{ + return (aRestyleHint & (eRestyle_Self | eRestyle_Subtree)) || + ((aRestyleHint & eRestyle_SomeDescendants) && + SelectorMatchesForRestyle(aElement)); +} + ElementRestyler::RestyleResult ElementRestyler::RestyleSelf(nsIFrame* aSelf, nsRestyleHint aRestyleHint, @@ -3107,7 +3238,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, RestyleResult result; - if (aRestyleHint) { + if (aRestyleHint & ~eRestyle_SomeDescendants) { result = eRestyleResult_Continue; } else { result = ComputeRestyleResultFromFrame(aSelf); @@ -3192,89 +3323,91 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, "non pseudo-element frame without content node"); newContext = styleSet->ResolveStyleForNonElement(parentContext); } - else if (!(aRestyleHint & (eRestyle_Self | eRestyle_Subtree))) { - Element* element = ElementForStyleContext(mParentContent, aSelf, pseudoType); - if (!(aRestyleHint & ~(eRestyle_Force | eRestyle_ForceDescendants)) && - !styleSet->IsInRuleTreeReconstruct()) { - LOG_RESTYLE("reparenting style context"); - newContext = - styleSet->ReparentStyleContext(oldContext, parentContext, element); - } else { - // Use ResolveStyleWithReplacement either for actual replacements - // or, with no replacements, as a substitute for - // ReparentStyleContext that rebuilds the path in the rule tree - // rather than reusing the rule node, as we need to do during a - // rule tree reconstruct. - Element* pseudoElement = PseudoElementForStyleContext(aSelf, pseudoType); - MOZ_ASSERT(!element || element != pseudoElement, - "pseudo-element for selector matching should be " - "the anonymous content node that we create, " - "not the real element"); - LOG_RESTYLE("resolving style with replacement"); - newContext = - styleSet->ResolveStyleWithReplacement(element, pseudoElement, - parentContext, oldContext, - aRestyleHint); - } - } else if (pseudoType == nsCSSPseudoElements::ePseudo_AnonBox) { - newContext = styleSet->ResolveAnonymousBoxStyle(pseudoTag, - parentContext); - } else { Element* element = ElementForStyleContext(mParentContent, aSelf, pseudoType); - if (pseudoTag) { - if (pseudoTag == nsCSSPseudoElements::before || - pseudoTag == nsCSSPseudoElements::after) { - // XXX what other pseudos do we need to treat like this? - newContext = styleSet->ProbePseudoElementStyle(element, - pseudoType, - parentContext, - mTreeMatchContext); - if (!newContext) { - // This pseudo should no longer exist; gotta reframe - NS_UpdateHint(mHintsHandled, nsChangeHint_ReconstructFrame); - mChangeList->AppendChange(aSelf, element, - nsChangeHint_ReconstructFrame); - // We're reframing anyway; just keep the same context - newContext = oldContext; -#ifdef DEBUG - // oldContext's parent might have had its style structs swapped out - // with parentContext, so to avoid any assertions that might - // otherwise trigger in oldContext's parent's destructor, we set a - // flag on oldContext to skip it and its descendants in - // nsStyleContext::AssertStructsNotUsedElsewhere. - if (oldContext->GetParent() != parentContext) { - oldContext->AddStyleBit(NS_STYLE_IS_GOING_AWAY); - } -#endif - } + if (!MustRestyleSelf(aRestyleHint, element)) { + if (!(aRestyleHint & ~(eRestyle_Force | eRestyle_ForceDescendants)) && + !styleSet->IsInRuleTreeReconstruct()) { + LOG_RESTYLE("reparenting style context"); + newContext = + styleSet->ReparentStyleContext(oldContext, parentContext, element); } else { - // Don't expect XUL tree stuff here, since it needs a comparator and - // all. - NS_ASSERTION(pseudoType < - nsCSSPseudoElements::ePseudo_PseudoElementCount, - "Unexpected pseudo type"); - Element* pseudoElement = - PseudoElementForStyleContext(aSelf, pseudoType); - MOZ_ASSERT(element != pseudoElement, + // Use ResolveStyleWithReplacement either for actual replacements + // or, with no replacements, as a substitute for + // ReparentStyleContext that rebuilds the path in the rule tree + // rather than reusing the rule node, as we need to do during a + // rule tree reconstruct. + Element* pseudoElement = PseudoElementForStyleContext(aSelf, pseudoType); + MOZ_ASSERT(!element || element != pseudoElement, "pseudo-element for selector matching should be " "the anonymous content node that we create, " "not the real element"); - newContext = styleSet->ResolvePseudoElementStyle(element, - pseudoType, - parentContext, - pseudoElement); + LOG_RESTYLE("resolving style with replacement"); + nsRestyleHint rshint = aRestyleHint & ~eRestyle_SomeDescendants; + newContext = + styleSet->ResolveStyleWithReplacement(element, pseudoElement, + parentContext, oldContext, + rshint); } + } else if (pseudoType == nsCSSPseudoElements::ePseudo_AnonBox) { + newContext = styleSet->ResolveAnonymousBoxStyle(pseudoTag, + parentContext); } else { - NS_ASSERTION(aSelf->GetContent(), - "non pseudo-element frame without content node"); - // Skip parent display based style fixup for anonymous subtrees: - TreeMatchContext::AutoParentDisplayBasedStyleFixupSkipper - parentDisplayBasedFixupSkipper(mTreeMatchContext, - element->IsRootOfNativeAnonymousSubtree()); - newContext = styleSet->ResolveStyleFor(element, parentContext, - mTreeMatchContext); + if (pseudoTag) { + if (pseudoTag == nsCSSPseudoElements::before || + pseudoTag == nsCSSPseudoElements::after) { + // XXX what other pseudos do we need to treat like this? + newContext = styleSet->ProbePseudoElementStyle(element, + pseudoType, + parentContext, + mTreeMatchContext); + if (!newContext) { + // This pseudo should no longer exist; gotta reframe + NS_UpdateHint(mHintsHandled, nsChangeHint_ReconstructFrame); + mChangeList->AppendChange(aSelf, element, + nsChangeHint_ReconstructFrame); + // We're reframing anyway; just keep the same context + newContext = oldContext; +#ifdef DEBUG + // oldContext's parent might have had its style structs swapped out + // with parentContext, so to avoid any assertions that might + // otherwise trigger in oldContext's parent's destructor, we set a + // flag on oldContext to skip it and its descendants in + // nsStyleContext::AssertStructsNotUsedElsewhere. + if (oldContext->GetParent() != parentContext) { + oldContext->AddStyleBit(NS_STYLE_IS_GOING_AWAY); + } +#endif + } + } else { + // Don't expect XUL tree stuff here, since it needs a comparator and + // all. + NS_ASSERTION(pseudoType < + nsCSSPseudoElements::ePseudo_PseudoElementCount, + "Unexpected pseudo type"); + Element* pseudoElement = + PseudoElementForStyleContext(aSelf, pseudoType); + MOZ_ASSERT(element != pseudoElement, + "pseudo-element for selector matching should be " + "the anonymous content node that we create, " + "not the real element"); + newContext = styleSet->ResolvePseudoElementStyle(element, + pseudoType, + parentContext, + pseudoElement); + } + } + else { + NS_ASSERTION(aSelf->GetContent(), + "non pseudo-element frame without content node"); + // Skip parent display based style fixup for anonymous subtrees: + TreeMatchContext::AutoParentDisplayBasedStyleFixupSkipper + parentDisplayBasedFixupSkipper(mTreeMatchContext, + element->IsRootOfNativeAnonymousSubtree()); + newContext = styleSet->ResolveStyleFor(element, parentContext, + mTreeMatchContext); + } } } @@ -3464,9 +3597,9 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, NS_ASSERTION(extraPseudoTag && extraPseudoTag != nsCSSAnonBoxes::mozNonElement, "extra style context is not pseudo element"); - if (!(aRestyleHint & (eRestyle_Self | eRestyle_Subtree))) { - Element* element = extraPseudoType != nsCSSPseudoElements::ePseudo_AnonBox - ? mContent->AsElement() : nullptr; + Element* element = extraPseudoType != nsCSSPseudoElements::ePseudo_AnonBox + ? mContent->AsElement() : nullptr; + if (!MustRestyleSelf(aRestyleHint, element)) { if (styleSet->IsInRuleTreeReconstruct()) { // Use ResolveStyleWithReplacement as a substitute for // ReparentStyleContext that rebuilds the path in the rule tree @@ -3693,6 +3826,9 @@ ElementRestyler::ComputeStyleChangeFor(nsIFrame* aFrame, Element* parent = content ? content->GetParentElementCrossingShadowRoot() : nullptr; treeMatchContext.InitAncestors(parent); + nsTArray selectorsForDescendants; + selectorsForDescendants.AppendElements( + aRestyleHintData.mSelectorsForDescendants); nsTArray visibleKidsOfHiddenElement; for (nsIFrame* ibSibling = aFrame; ibSibling; ibSibling = GetNextBlockInInlineSibling(propTable, ibSibling)) { @@ -3707,6 +3843,7 @@ ElementRestyler::ComputeStyleChangeFor(nsIFrame* aFrame, // Inner loop over next-in-flows of the current frame ElementRestyler restyler(presContext, cont, aChangeList, aMinChange, aRestyleTracker, + selectorsForDescendants, treeMatchContext, visibleKidsOfHiddenElement, aContextsToClear, aSwappedStructOwners); @@ -3805,21 +3942,25 @@ ElementRestyler::RestyleUndisplayedNodes(nsRestyleHint aChildRestyleHint, } nsRefPtr undisplayedContext; nsStyleSet* styleSet = mPresContext->StyleSet(); - if (thisChildHint & (eRestyle_Self | eRestyle_Subtree)) { + if (MustRestyleSelf(thisChildHint, element)) { undisplayedContext = styleSet->ResolveStyleFor(element, aParentContext, mTreeMatchContext); } else if (thisChildHint || styleSet->IsInRuleTreeReconstruct()) { + // XXX Should the above condition ignore eRestyle_Force(Descendants) + // like the corresponding check in RestyleSelf? + // Use ResolveStyleWithReplacement either for actual // replacements, or as a substitute for ReparentStyleContext // that rebuilds the path in the rule tree rather than reusing // the rule node, as we need to do during a rule tree // reconstruct. + nsRestyleHint rshint = thisChildHint & ~eRestyle_SomeDescendants; undisplayedContext = styleSet->ResolveStyleWithReplacement(element, nullptr, aParentContext, undisplayed->mStyle, - thisChildHint); + rshint); } else { undisplayedContext = styleSet->ReparentStyleContext(undisplayed->mStyle, @@ -4141,6 +4282,8 @@ RestyleManager::ComputeAndProcessStyleChange(nsStyleContext* aNewContext, Element* parentElement = parent && parent->IsElement() ? parent->AsElement() : nullptr; treeMatchContext.InitAncestors(parentElement); + + nsTArray selectorsForDescendants; nsTArray visibleKidsOfHiddenElement; nsTArray contextsToClear; @@ -4150,7 +4293,7 @@ RestyleManager::ComputeAndProcessStyleChange(nsStyleContext* aNewContext, nsTArray> swappedStructOwners; nsStyleChangeList changeList; ElementRestyler r(frame->PresContext(), aElement, &changeList, aMinChange, - aRestyleTracker, treeMatchContext, + aRestyleTracker, selectorsForDescendants, treeMatchContext, visibleKidsOfHiddenElement, contextsToClear, swappedStructOwners); r.RestyleChildrenOfDisplayContentsElement(frame, aNewContext, aMinChange, diff --git a/layout/base/RestyleManager.h b/layout/base/RestyleManager.h index 5008b923fd25..13afc16188f5 100644 --- a/layout/base/RestyleManager.h +++ b/layout/base/RestyleManager.h @@ -519,6 +519,7 @@ public: nsStyleChangeList* aChangeList, nsChangeHint aHintsHandledByAncestors, RestyleTracker& aRestyleTracker, + nsTArray& aSelectorsForDescendants, TreeMatchContext& aTreeMatchContext, nsTArray& aVisibleKidsOfHiddenElement, nsTArray& aContextsToClear, @@ -549,6 +550,7 @@ public: nsStyleChangeList* aChangeList, nsChangeHint aHintsHandledByAncestors, RestyleTracker& aRestyleTracker, + nsTArray& aSelectorsForDescendants, TreeMatchContext& aTreeMatchContext, nsTArray& aVisibleKidsOfHiddenElement, nsTArray& aContextsToClear, @@ -638,6 +640,21 @@ private: */ void RestyleChildren(nsRestyleHint aChildRestyleHint); + /** + * Returns true iff a selector in mSelectorsForDescendants matches aElement. + * This is called when processing a eRestyle_SomeDescendants restyle hint. + */ + bool SelectorMatchesForRestyle(Element* aElement); + + /** + * Returns true iff aRestyleHint indicates that we should be restyling. + * Specifically, this will return true when eRestyle_Self or + * eRestyle_Subtree is present, or if eRestyle_SomeDescendants is + * present and the specified element matches one of the selectors in + * mSelectorsForDescendants. + */ + bool MustRestyleSelf(nsRestyleHint aRestyleHint, Element* aElement); + /** * Helpers for Restyle(). */ @@ -698,6 +715,8 @@ private: eNotifyHidden }; + void AddPendingRestylesForDescendantsMatchingSelectors(Element* aElement); + #ifdef RESTYLE_LOGGING int32_t& LoggingDepth() { return mLoggingDepth; } #endif @@ -725,6 +744,7 @@ private: nsChangeHint mParentFrameHintsNotHandledForDescendants; nsChangeHint mHintsNotHandledForDescendants; RestyleTracker& mRestyleTracker; + nsTArray& mSelectorsForDescendants; TreeMatchContext& mTreeMatchContext; nsIFrame* mResolvedChild; // child that provides our parent style context // Array of style context subtrees in which we need to clear out cached diff --git a/layout/base/RestyleTracker.h b/layout/base/RestyleTracker.h index 95219c92d5e8..b852f86a6841 100644 --- a/layout/base/RestyleTracker.h +++ b/layout/base/RestyleTracker.h @@ -319,6 +319,14 @@ public: */ bool GetRestyleData(Element* aElement, nsAutoPtr& aData); + /** + * Returns whether there is a RestyleData entry in mPendingRestyles + * for the given element. + */ + bool HasRestyleData(Element* aElement) { + return mPendingRestyles.Contains(aElement); + } + /** * For each element in aElements, appends it to mRestyleRoots if it * has its restyle bit set. This is used to ensure we restyle elements diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index 6297ef7d6221..ae75ffb05a0c 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -2293,6 +2293,28 @@ static bool SelectorMatches(Element* aElement, #undef STATE_CHECK +#ifdef DEBUG +static bool +HasPseudoClassSelectorArgsWithCombinators(nsCSSSelector* aSelector) +{ + for (nsPseudoClassList* p = aSelector->mPseudoClassList; p; p = p->mNext) { + if (nsCSSPseudoClasses::HasSelectorListArg(p->mType)) { + for (nsCSSSelectorList* l = p->u.mSelectors; l; l = l->mNext) { + if (l->mSelectors->mNext) { + return true; + } + } + } + } + for (nsCSSSelector* n = aSelector->mNegations; n; n = n->mNegations) { + if (n->mNext) { + return true; + } + } + return false; +} +#endif + /* static */ bool nsCSSRuleProcessor::RestrictedSelectorMatches( Element* aElement, @@ -2302,6 +2324,11 @@ nsCSSRuleProcessor::RestrictedSelectorMatches( MOZ_ASSERT(aSelector->IsRestrictedSelector(), "aSelector must not have a pseudo-element"); + NS_WARN_IF_FALSE(!HasPseudoClassSelectorArgsWithCombinators(aSelector), + "processing eRestyle_SomeDescendants can be slow if " + "pseudo-classes with selector arguments can now have " + "combinators in them"); + // We match aSelector as if :visited and :link both match visited and // unvisited links. From 1f9a11e085cf68f1f7be6ddaceb8eefe8ac88902 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Tue, 4 Aug 2015 17:27:53 +1000 Subject: [PATCH 18/56] Bug 1180118 - Part 4: Store pointer to the rightmost selector for class, ID and attribute selectors in the rule cascade. r=bzbarsky --- layout/style/nsCSSRuleProcessor.cpp | 77 +++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 15 deletions(-) diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index ae75ffb05a0c..ee631d5f4f02 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -783,12 +783,39 @@ RuleHash::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const //-------------------------------- +/** + * A struct that stores an nsCSSSelector pointer along side a pointer to + * the rightmost nsCSSSelector in the selector. For example, for + * + * .main p > span + * + * if mSelector points to the |p| nsCSSSelector, mRightmostSelector would + * point to the |span| nsCSSSelector. + * + * Both mSelector and mRightmostSelector are always top-level selectors, + * i.e. they aren't selectors within a :not() or :-moz-any(). + */ +struct SelectorPair +{ + SelectorPair(nsCSSSelector* aSelector, nsCSSSelector* aRightmostSelector) + : mSelector(aSelector), mRightmostSelector(aRightmostSelector) + { + MOZ_ASSERT(aSelector); + MOZ_ASSERT(mRightmostSelector); + } + SelectorPair(const SelectorPair& aOther) + : mSelector(aOther.mSelector) + , mRightmostSelector(aOther.mRightmostSelector) {} + nsCSSSelector* const mSelector; + nsCSSSelector* const mRightmostSelector; +}; + // A hash table mapping atoms to lists of selectors struct AtomSelectorEntry : public PLDHashEntryHdr { nsIAtom *mAtom; // Auto length 2, because a decent fraction of these arrays ends up // with 2 elements, and each entry is cheap. - nsAutoTArray mSelectors; + nsAutoTArray mSelectors; }; static void @@ -911,7 +938,7 @@ struct RuleCascadeData { // Looks up or creates the appropriate list in |mAttributeSelectors|. // Returns null only on allocation failure. - nsTArray* AttributeListFor(nsIAtom* aAttribute); + nsTArray* AttributeListFor(nsIAtom* aAttribute); nsMediaQueryResultCacheKey mCacheKey; RuleCascadeData* mNext; // for a different medium @@ -975,7 +1002,7 @@ RuleCascadeData::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const return n; } -nsTArray* +nsTArray* RuleCascadeData::AttributeListFor(nsIAtom* aAttribute) { AtomSelectorEntry *entry = @@ -2763,7 +2790,9 @@ struct AttributeEnumData { static void -AttributeEnumFunc(nsCSSSelector* aSelector, AttributeEnumData* aData) +AttributeEnumFunc(nsCSSSelector* aSelector, + nsCSSSelector* aRightmostSelector, + AttributeEnumData* aData) { AttributeRuleProcessorData *data = aData->data; @@ -2789,13 +2818,23 @@ AttributeEnumFunc(nsCSSSelector* aSelector, AttributeEnumData* aData) } } +static MOZ_ALWAYS_INLINE void +EnumerateSelectors(nsTArray& aSelectors, AttributeEnumData* aData) +{ + SelectorPair *iter = aSelectors.Elements(), + *end = iter + aSelectors.Length(); + for (; iter != end; ++iter) { + AttributeEnumFunc(iter->mSelector, iter->mRightmostSelector, aData); + } +} + static MOZ_ALWAYS_INLINE void EnumerateSelectors(nsTArray& aSelectors, AttributeEnumData* aData) { nsCSSSelector **iter = aSelectors.Elements(), **end = iter + aSelectors.Length(); for (; iter != end; ++iter) { - AttributeEnumFunc(*iter, aData); + AttributeEnumFunc(*iter, nullptr, aData); } } @@ -3127,7 +3166,9 @@ AddSelector(RuleCascadeData* aCascade, // The part between combinators at the top level of the selector nsCSSSelector* aSelectorInTopLevel, // The part we should look through (might be in :not or :-moz-any()) - nsCSSSelector* aSelectorPart) + nsCSSSelector* aSelectorPart, + // The right-most selector at the top level + nsCSSSelector* aRightmostSelector) { // It's worth noting that this loop over negations isn't quite // optimal for two reasons. One, we could add something to one of @@ -3152,12 +3193,13 @@ AddSelector(RuleCascadeData* aCascade, break; } case nsCSSPseudoClasses::ePseudoClass_mozTableBorderNonzero: { - nsTArray *array = + nsTArray *array = aCascade->AttributeListFor(nsGkAtoms::border); if (!array) { return false; } - array->AppendElement(aSelectorInTopLevel); + array->AppendElement(SelectorPair(aSelectorInTopLevel, + aRightmostSelector)); break; } default: { @@ -3181,7 +3223,8 @@ AddSelector(RuleCascadeData* aCascade, AtomSelectorEntry *entry = static_cast (PL_DHashTableAdd(&aCascade->mIdSelectors, curID->mAtom, fallible)); if (entry) { - entry->mSelectors.AppendElement(aSelectorInTopLevel); + entry->mSelectors.AppendElement(SelectorPair(aSelectorInTopLevel, + aRightmostSelector)); } } } else if (negation->mIDList) { @@ -3196,7 +3239,8 @@ AddSelector(RuleCascadeData* aCascade, (PL_DHashTableAdd(&aCascade->mClassSelectors, curClass->mAtom, fallible)); if (entry) { - entry->mSelectors.AppendElement(aSelectorInTopLevel); + entry->mSelectors.AppendElement(SelectorPair(aSelectorInTopLevel, + aRightmostSelector)); } } } else if (negation->mClassList) { @@ -3206,18 +3250,20 @@ AddSelector(RuleCascadeData* aCascade, // Build mAttributeSelectors. for (nsAttrSelector *attr = negation->mAttrList; attr; attr = attr->mNext) { - nsTArray *array = + nsTArray *array = aCascade->AttributeListFor(attr->mCasedAttr); if (!array) { return false; } - array->AppendElement(aSelectorInTopLevel); + array->AppendElement(SelectorPair(aSelectorInTopLevel, + aRightmostSelector)); if (attr->mLowercaseAttr != attr->mCasedAttr) { array = aCascade->AttributeListFor(attr->mLowercaseAttr); if (!array) { return false; } - array->AppendElement(aSelectorInTopLevel); + array->AppendElement(SelectorPair(aSelectorInTopLevel, + aRightmostSelector)); } } @@ -3227,7 +3273,8 @@ AddSelector(RuleCascadeData* aCascade, if (pseudoClass->mType == nsCSSPseudoClasses::ePseudoClass_any) { for (nsCSSSelectorList *l = pseudoClass->u.mSelectors; l; l = l->mNext) { nsCSSSelector *s = l->mSelectors; - if (!AddSelector(aCascade, aSelectorInTopLevel, s)) { + if (!AddSelector(aCascade, aSelectorInTopLevel, s, + aRightmostSelector)) { return false; } } @@ -3308,7 +3355,7 @@ AddRule(RuleSelectorPair* aRuleInfo, RuleCascadeData* aCascade) continue; } } - if (!AddSelector(cascade, selector, selector)) { + if (!AddSelector(cascade, selector, selector, aRuleInfo->mSelector)) { return false; } } From 18f6b81597cf5576cba74062dc5921e0ca2036ab Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Tue, 4 Aug 2015 17:27:53 +1000 Subject: [PATCH 19/56] Bug 1180118 - Part 5: Add a RestyleHintData outparam to HasAttributeDependentStyle for use with eRestyle_SomeDescendants. r=bzbarsky --- layout/base/RestyleManager.cpp | 13 ++++++++----- layout/style/AnimationCommon.cpp | 4 +++- layout/style/AnimationCommon.h | 3 ++- layout/style/SVGAttrAnimationRuleProcessor.cpp | 4 +++- layout/style/SVGAttrAnimationRuleProcessor.h | 3 ++- layout/style/nsCSSRuleProcessor.cpp | 4 +++- layout/style/nsCSSRuleProcessor.h | 4 +++- layout/style/nsHTMLCSSStyleSheet.cpp | 4 +++- layout/style/nsHTMLCSSStyleSheet.h | 3 ++- layout/style/nsHTMLStyleSheet.cpp | 4 +++- layout/style/nsHTMLStyleSheet.h | 3 ++- layout/style/nsIStyleRuleProcessor.h | 5 +++-- layout/style/nsStyleSet.cpp | 15 ++++++++++++--- layout/style/nsStyleSet.h | 4 +++- 14 files changed, 52 insertions(+), 21 deletions(-) diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index d49f997b6b80..c7319ddb87e9 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -1170,13 +1170,15 @@ RestyleManager::AttributeWillChange(Element* aElement, int32_t aModType, const nsAttrValue* aNewValue) { + RestyleHintData rsdata; nsRestyleHint rshint = mPresContext->StyleSet()->HasAttributeDependentStyle(aElement, aAttribute, aModType, false, - aNewValue); - PostRestyleEvent(aElement, rshint, NS_STYLE_HINT_NONE); + aNewValue, + rsdata); + PostRestyleEvent(aElement, rshint, NS_STYLE_HINT_NONE, &rsdata); } // Forwarded nsIMutationObserver method, to handle restyling (and @@ -1259,14 +1261,15 @@ RestyleManager::AttributeChanged(Element* aElement, // See if we can optimize away the style re-resolution -- must be called after // the frame's AttributeChanged() in case it does something that affects the style + RestyleHintData rsdata; nsRestyleHint rshint = mPresContext->StyleSet()->HasAttributeDependentStyle(aElement, aAttribute, aModType, true, - aOldValue); - - PostRestyleEvent(aElement, rshint, hint); + aOldValue, + rsdata); + PostRestyleEvent(aElement, rshint, hint, &rsdata); } /* static */ uint64_t diff --git a/layout/style/AnimationCommon.cpp b/layout/style/AnimationCommon.cpp index ebabe547b680..663f2b10c634 100644 --- a/layout/style/AnimationCommon.cpp +++ b/layout/style/AnimationCommon.cpp @@ -210,7 +210,9 @@ CommonAnimationManager::HasDocumentStateDependentStyle(StateRuleProcessorData* a } nsRestyleHint -CommonAnimationManager::HasAttributeDependentStyle(AttributeRuleProcessorData* aData) +CommonAnimationManager::HasAttributeDependentStyle( + AttributeRuleProcessorData* aData, + RestyleHintData& aRestyleHintDataResult) { return nsRestyleHint(0); } diff --git a/layout/style/AnimationCommon.h b/layout/style/AnimationCommon.h index 700ba4b04cb2..eae9911b76f5 100644 --- a/layout/style/AnimationCommon.h +++ b/layout/style/AnimationCommon.h @@ -52,7 +52,8 @@ public: virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override; virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override; virtual nsRestyleHint - HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override; + HasAttributeDependentStyle(AttributeRuleProcessorData* aData, + RestyleHintData& aRestyleHintDataResult) override; virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override; virtual void RulesMatching(ElementRuleProcessorData* aData) override; virtual void RulesMatching(PseudoElementRuleProcessorData* aData) override; diff --git a/layout/style/SVGAttrAnimationRuleProcessor.cpp b/layout/style/SVGAttrAnimationRuleProcessor.cpp index 3a1230f511e7..9eb31b1b2334 100644 --- a/layout/style/SVGAttrAnimationRuleProcessor.cpp +++ b/layout/style/SVGAttrAnimationRuleProcessor.cpp @@ -62,7 +62,9 @@ SVGAttrAnimationRuleProcessor::HasDocumentStateDependentStyle(StateRuleProcessor } /* virtual */ nsRestyleHint -SVGAttrAnimationRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData) +SVGAttrAnimationRuleProcessor::HasAttributeDependentStyle( + AttributeRuleProcessorData* aData, + RestyleHintData& aRestyleHintDataResult) { return nsRestyleHint(0); } diff --git a/layout/style/SVGAttrAnimationRuleProcessor.h b/layout/style/SVGAttrAnimationRuleProcessor.h index 7a3fb6514486..1750c761bdc5 100644 --- a/layout/style/SVGAttrAnimationRuleProcessor.h +++ b/layout/style/SVGAttrAnimationRuleProcessor.h @@ -44,7 +44,8 @@ public: virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override; virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override; virtual nsRestyleHint - HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override; + HasAttributeDependentStyle(AttributeRuleProcessorData* aData, + RestyleHintData& aRestyleHintDataResult) override; virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override; virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_MUST_OVERRIDE override; diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index ee631d5f4f02..7aac726bfba5 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -2839,7 +2839,9 @@ EnumerateSelectors(nsTArray& aSelectors, AttributeEnumData* aDat } nsRestyleHint -nsCSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData) +nsCSSRuleProcessor::HasAttributeDependentStyle( + AttributeRuleProcessorData* aData, + RestyleHintData& aRestyleHintDataResult) { // We could try making use of aData->mModType, but :not rules make it a bit // of a pain to do so... So just ignore it for now. diff --git a/layout/style/nsCSSRuleProcessor.h b/layout/style/nsCSSRuleProcessor.h index a60af5422801..3fc709b284d3 100644 --- a/layout/style/nsCSSRuleProcessor.h +++ b/layout/style/nsCSSRuleProcessor.h @@ -144,7 +144,9 @@ public: virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override; virtual nsRestyleHint - HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override; + HasAttributeDependentStyle(AttributeRuleProcessorData* aData, + mozilla::RestyleHintData& aRestyleHintDataResult) + override; virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override; diff --git a/layout/style/nsHTMLCSSStyleSheet.cpp b/layout/style/nsHTMLCSSStyleSheet.cpp index 215f9f0838f7..bd972db93a39 100644 --- a/layout/style/nsHTMLCSSStyleSheet.cpp +++ b/layout/style/nsHTMLCSSStyleSheet.cpp @@ -144,7 +144,9 @@ nsHTMLCSSStyleSheet::HasDocumentStateDependentStyle(StateRuleProcessorData* aDat // Test if style is dependent on attribute /* virtual */ nsRestyleHint -nsHTMLCSSStyleSheet::HasAttributeDependentStyle(AttributeRuleProcessorData* aData) +nsHTMLCSSStyleSheet::HasAttributeDependentStyle( + AttributeRuleProcessorData* aData, + RestyleHintData& aRestyleHintDataResult) { // Perhaps should check that it's XUL, SVG, (or HTML) namespace, but // it doesn't really matter. diff --git a/layout/style/nsHTMLCSSStyleSheet.h b/layout/style/nsHTMLCSSStyleSheet.h index f1ecf2fe4287..234f3e24cd85 100644 --- a/layout/style/nsHTMLCSSStyleSheet.h +++ b/layout/style/nsHTMLCSSStyleSheet.h @@ -43,7 +43,8 @@ public: virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override; virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override; virtual nsRestyleHint - HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override; + HasAttributeDependentStyle(AttributeRuleProcessorData* aData, + mozilla::RestyleHintData& aRestyleHintDataResult) override; virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override; virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_MUST_OVERRIDE override; diff --git a/layout/style/nsHTMLStyleSheet.cpp b/layout/style/nsHTMLStyleSheet.cpp index 546468c28a26..a496ec0034b0 100644 --- a/layout/style/nsHTMLStyleSheet.cpp +++ b/layout/style/nsHTMLStyleSheet.cpp @@ -335,7 +335,9 @@ nsHTMLStyleSheet::HasDocumentStateDependentStyle(StateRuleProcessorData* aData) } /* virtual */ nsRestyleHint -nsHTMLStyleSheet::HasAttributeDependentStyle(AttributeRuleProcessorData* aData) +nsHTMLStyleSheet::HasAttributeDependentStyle( + AttributeRuleProcessorData* aData, + RestyleHintData& aRestyleHintDataResult) { // Do nothing on before-change checks if (!aData->mAttrHasChanged) { diff --git a/layout/style/nsHTMLStyleSheet.h b/layout/style/nsHTMLStyleSheet.h index 95d2061355c3..50627849881b 100644 --- a/layout/style/nsHTMLStyleSheet.h +++ b/layout/style/nsHTMLStyleSheet.h @@ -45,7 +45,8 @@ public: virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override; virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override; virtual nsRestyleHint - HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override; + HasAttributeDependentStyle(AttributeRuleProcessorData* aData, + mozilla::RestyleHintData& aRestyleHintDataResult) override; virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override; virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_MUST_OVERRIDE override; diff --git a/layout/style/nsIStyleRuleProcessor.h b/layout/style/nsIStyleRuleProcessor.h index 00182dd38070..2075050d4076 100644 --- a/layout/style/nsIStyleRuleProcessor.h +++ b/layout/style/nsIStyleRuleProcessor.h @@ -115,8 +115,9 @@ public: * only, and may err on the side of reporting more dependencies than * really exist. */ - virtual nsRestyleHint - HasAttributeDependentStyle(AttributeRuleProcessorData* aData) = 0; + virtual nsRestyleHint HasAttributeDependentStyle( + AttributeRuleProcessorData* aData, + mozilla::RestyleHintData& aRestyleHintDataResult) = 0; /** * Do any processing that needs to happen as a result of a change in diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index 5ebeed36b6a4..1f6c5673b0bd 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -2377,14 +2377,16 @@ struct MOZ_STACK_CLASS AttributeData : public AttributeRuleProcessorData { aAttrHasChanged, aOtherValue, aTreeMatchContext), mHint(nsRestyleHint(0)) {} - nsRestyleHint mHint; + nsRestyleHint mHint; + RestyleHintData mHintData; }; static bool SheetHasAttributeStyle(nsIStyleRuleProcessor* aProcessor, void *aData) { AttributeData* data = (AttributeData*)aData; - nsRestyleHint hint = aProcessor->HasAttributeDependentStyle(data); + nsRestyleHint hint = + aProcessor->HasAttributeDependentStyle(data, data->mHintData); data->mHint = nsRestyleHint(data->mHint | hint); return true; // continue } @@ -2395,7 +2397,9 @@ nsStyleSet::HasAttributeDependentStyle(Element* aElement, nsIAtom* aAttribute, int32_t aModType, bool aAttrHasChanged, - const nsAttrValue* aOtherValue) + const nsAttrValue* aOtherValue, + mozilla::RestyleHintData& + aRestyleHintDataResult) { TreeMatchContext treeContext(false, nsRuleWalker::eLinksVisitedOrUnvisited, aElement->OwnerDoc()); @@ -2403,6 +2407,11 @@ nsStyleSet::HasAttributeDependentStyle(Element* aElement, AttributeData data(PresContext(), aElement, aAttribute, aModType, aAttrHasChanged, aOtherValue, treeContext); WalkRuleProcessors(SheetHasAttributeStyle, &data, false); + if (!(data.mHint & eRestyle_Subtree)) { + // No point keeping the list of selectors around if we are going to + // restyle the whole subtree unconditionally. + aRestyleHintDataResult = Move(data.mHintData); + } return data.mHint; } diff --git a/layout/style/nsStyleSet.h b/layout/style/nsStyleSet.h index e807af8e03a6..f848f5d94673 100644 --- a/layout/style/nsStyleSet.h +++ b/layout/style/nsStyleSet.h @@ -286,7 +286,9 @@ class nsStyleSet final nsIAtom* aAttribute, int32_t aModType, bool aAttrHasChanged, - const nsAttrValue* aOtherValue); + const nsAttrValue* aOtherValue, + mozilla::RestyleHintData& + aRestyleHintDataResult); /* * Do any processing that needs to happen as a result of a change in From 3a8af4dbea38fe77d40552d5da173623baa62c5c Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Tue, 4 Aug 2015 17:27:53 +1000 Subject: [PATCH 20/56] Bug 1180118 - Part 6: Return eRestyle_SomeDescendants from HasAttributeDependentStyle where appropriate. r=bzbarsky --- layout/style/StyleRule.h | 2 - layout/style/nsCSSRuleProcessor.cpp | 87 ++++++++++++++++++++++++++--- 2 files changed, 79 insertions(+), 10 deletions(-) diff --git a/layout/style/StyleRule.h b/layout/style/StyleRule.h index dd912a173b4c..a6996fc76b25 100644 --- a/layout/style/StyleRule.h +++ b/layout/style/StyleRule.h @@ -159,11 +159,9 @@ public: void ToString(nsAString& aString, mozilla::CSSStyleSheet* aSheet, bool aAppend = false) const; -#ifdef DEBUG bool IsRestrictedSelector() const { return PseudoType() == nsCSSPseudoElements::ePseudo_NotPseudoElement; } -#endif private: void AddPseudoClassInternal(nsPseudoClassList *aPseudoClass); diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index 7aac726bfba5..bf6dd8e1c52d 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -2781,14 +2781,77 @@ nsCSSRuleProcessor::HasDocumentStateDependentStyle(StateRuleProcessorData* aData } struct AttributeEnumData { - explicit AttributeEnumData(AttributeRuleProcessorData *aData) - : data(aData), change(nsRestyleHint(0)) {} + AttributeEnumData(AttributeRuleProcessorData *aData, + RestyleHintData& aRestyleHintData) + : data(aData), change(nsRestyleHint(0)), hintData(aRestyleHintData) {} AttributeRuleProcessorData *data; nsRestyleHint change; + RestyleHintData& hintData; }; +static inline nsRestyleHint +RestyleHintForSelectorWithAttributeChange(nsRestyleHint aCurrentHint, + nsCSSSelector* aSelector, + nsCSSSelector* aRightmostSelector) +{ + MOZ_ASSERT(aSelector); + + char16_t oper = aSelector->mOperator; + + if (oper == char16_t('+') || oper == char16_t('~')) { + return eRestyle_LaterSiblings; + } + + if (oper == char16_t(':')) { + return eRestyle_Subtree; + } + + if (oper != char16_t(0)) { + // Check whether the selector is in a form that supports + // eRestyle_SomeDescendants. If it isn't, return eRestyle_Subtree. + + if (aCurrentHint & eRestyle_Subtree) { + // No point checking, since we'll end up restyling the whole + // subtree anyway. + return eRestyle_Subtree; + } + + if (!aRightmostSelector) { + // aSelector wasn't a top-level selector, which means we were inside + // a :not() or :-moz-any(). We don't support that. + return eRestyle_Subtree; + } + + MOZ_ASSERT(aSelector != aRightmostSelector, + "if aSelector == aRightmostSelector then we should have " + "no operator"); + + // Check that aRightmostSelector can be passed to RestrictedSelectorMatches. + if (!aRightmostSelector->IsRestrictedSelector()) { + return eRestyle_Subtree; + } + + // We also don't support pseudo-elements on any of the selectors + // between aRightmostSelector and aSelector. + // XXX Can we lift this restriction, so that we don't have to loop + // over all the selectors? + for (nsCSSSelector* sel = aRightmostSelector->mNext; + sel != aSelector; + sel = sel->mNext) { + MOZ_ASSERT(sel, "aSelector must be reachable from aRightmostSelector"); + if (sel->PseudoType() != nsCSSPseudoElements::ePseudo_NotPseudoElement) { + return eRestyle_Subtree; + } + } + + return eRestyle_SomeDescendants; + } + + return eRestyle_Self; +} + static void AttributeEnumFunc(nsCSSSelector* aSelector, nsCSSSelector* aRightmostSelector, @@ -2803,18 +2866,26 @@ AttributeEnumFunc(nsCSSSelector* aSelector, return; } - nsRestyleHint possibleChange = RestyleHintForOp(aSelector->mOperator); + nsRestyleHint possibleChange = + RestyleHintForSelectorWithAttributeChange(aData->change, + aSelector, aRightmostSelector); - // If enumData->change already includes all the bits of possibleChange, don't - // bother calling SelectorMatches, since even if it returns false - // enumData->change won't change. + // If, ignoring eRestyle_SomeDescendants, enumData->change already includes + // all the bits of possibleChange, don't bother calling SelectorMatches, since + // even if it returns false enumData->change won't change. If possibleChange + // has eRestyle_SomeDescendants, we need to call SelectorMatches(Tree) + // regardless as it might give us new selectors to append to + // mSelectorsForDescendants. NodeMatchContext nodeContext(EventStates(), false); - if ((possibleChange & ~(aData->change)) && + if (((possibleChange & (~(aData->change) | eRestyle_SomeDescendants))) && SelectorMatches(data->mElement, aSelector, nodeContext, data->mTreeMatchContext, SelectorMatchesFlags::UNKNOWN) && SelectorMatchesTree(data->mElement, aSelector->mNext, data->mTreeMatchContext, false)) { aData->change = nsRestyleHint(aData->change | possibleChange); + if (possibleChange & eRestyle_SomeDescendants) { + aData->hintData.mSelectorsForDescendants.AppendElement(aRightmostSelector); + } } } @@ -2846,7 +2917,7 @@ nsCSSRuleProcessor::HasAttributeDependentStyle( // We could try making use of aData->mModType, but :not rules make it a bit // of a pain to do so... So just ignore it for now. - AttributeEnumData data(aData); + AttributeEnumData data(aData, aRestyleHintDataResult); // Don't do our special handling of certain attributes if the attr // hasn't changed yet. From ff6473749667d5b48c0828040537705362d59c3f Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Tue, 4 Aug 2015 17:27:53 +1000 Subject: [PATCH 21/56] Bug 1180118 - Part 7: Split out FindClosestRestyleRoot and allow passing in a pre-computed restyle root to AddPendingRestyle. r=bzbarsky --- layout/base/RestyleTracker.h | 71 +++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/layout/base/RestyleTracker.h b/layout/base/RestyleTracker.h index b852f86a6841..929802746609 100644 --- a/layout/base/RestyleTracker.h +++ b/layout/base/RestyleTracker.h @@ -17,6 +17,7 @@ #include "mozilla/SplayTree.h" #include "mozilla/RestyleLogging.h" #include "GeckoProfiler.h" +#include "mozilla/Maybe.h" #if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API) #include "ProfilerBacktrace.h" @@ -256,10 +257,19 @@ public: /** * Add a restyle for the given element to the tracker. Returns true * if the element already had eRestyle_LaterSiblings set on it. + * + * aRestyleRoot is the closest restyle root for aElement. If the caller + * does not know what the closest restyle root is, Nothing should be + * passed. A Some(nullptr) restyle root can be passed if there is no + * ancestor element that is a restyle root. */ bool AddPendingRestyle(Element* aElement, nsRestyleHint aRestyleHint, nsChangeHint aMinChangeHint, - const RestyleHintData* aRestyleHintData = nullptr); + const RestyleHintData* aRestyleHintData = nullptr, + mozilla::Maybe aRestyleRoot = + mozilla::Nothing()); + + Element* FindClosestRestyleRoot(Element* aElement); /** * Process the restyles we've been tracking. @@ -437,11 +447,40 @@ RestyleTracker::AddPendingRestyleToTable(Element* aElement, return hadRestyleLaterSiblings; } +inline mozilla::dom::Element* +RestyleTracker::FindClosestRestyleRoot(Element* aElement) +{ + Element* cur = aElement; + while (!cur->HasFlag(RootBit())) { + nsIContent* parent = cur->GetFlattenedTreeParent(); + // Stop if we have no parent or the parent is not an element or + // we're part of the viewport scrollbars (because those are not + // frametree descendants of the primary frame of the root + // element). + // XXXbz maybe the primary frame of the root should be the root scrollframe? + if (!parent || !parent->IsElement() || + // If we've hit the root via a native anonymous kid and that + // this native anonymous kid is not obviously a descendant + // of the root's primary frame, assume we're under the root + // scrollbars. Since those don't get reresolved when + // reresolving the root, we need to make sure to add the + // element to mRestyleRoots. + (cur->IsInNativeAnonymousSubtree() && !parent->GetParent() && + cur->GetPrimaryFrame() && + cur->GetPrimaryFrame()->GetParent() != parent->GetPrimaryFrame())) { + return nullptr; + } + cur = parent->AsElement(); + } + return cur; +} + inline bool RestyleTracker::AddPendingRestyle(Element* aElement, nsRestyleHint aRestyleHint, nsChangeHint aMinChangeHint, - const RestyleHintData* aRestyleHintData) + const RestyleHintData* aRestyleHintData, + mozilla::Maybe aRestyleRoot) { bool hadRestyleLaterSiblings = AddPendingRestyleToTable(aElement, aRestyleHint, aMinChangeHint, @@ -452,29 +491,11 @@ RestyleTracker::AddPendingRestyle(Element* aElement, // ReResolveStyleContext on it or just reframe it). if ((aRestyleHint & ~eRestyle_LaterSiblings) || (aMinChangeHint & nsChangeHint_ReconstructFrame)) { - Element* cur = aElement; - while (!cur->HasFlag(RootBit())) { - nsIContent* parent = cur->GetFlattenedTreeParent(); - // Stop if we have no parent or the parent is not an element or - // we're part of the viewport scrollbars (because those are not - // frametree descendants of the primary frame of the root - // element). - // XXXbz maybe the primary frame of the root should be the root scrollframe? - if (!parent || !parent->IsElement() || - // If we've hit the root via a native anonymous kid and that - // this native anonymous kid is not obviously a descendant - // of the root's primary frame, assume we're under the root - // scrollbars. Since those don't get reresolved when - // reresolving the root, we need to make sure to add the - // element to mRestyleRoots. - (cur->IsInNativeAnonymousSubtree() && !parent->GetParent() && - cur->GetPrimaryFrame() && - cur->GetPrimaryFrame()->GetParent() != parent->GetPrimaryFrame())) { - mRestyleRoots.AppendElement(aElement); - cur = aElement; - break; - } - cur = parent->AsElement(); + Element* cur = + aRestyleRoot ? *aRestyleRoot : FindClosestRestyleRoot(aElement); + if (!cur) { + mRestyleRoots.AppendElement(aElement); + cur = aElement; } // At this point some ancestor of aElement (possibly aElement // itself) is in mRestyleRoots. Set the root bit on aElement, to From e090c4f7c90abd7b23775c3348af756072815a56 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Tue, 4 Aug 2015 17:27:53 +1000 Subject: [PATCH 22/56] Bug 1180118 - Part 8: Keep track of the closest restyle root in AddPendingRestylesForDescendantsMatchingSelectors. r=bzbarsky --- layout/base/RestyleManager.cpp | 28 ++++++++++++++++++---------- layout/base/RestyleManager.h | 3 ++- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index c7319ddb87e9..53c3fb53431a 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -2763,20 +2763,23 @@ private: * against mSelectorsForDescendants more than once. */ void -ElementRestyler::AddPendingRestylesForDescendantsMatchingSelectors(Element* aElement) +ElementRestyler::AddPendingRestylesForDescendantsMatchingSelectors( + Element* aElement, + Element* aRestyleRoot) { + if (aElement->HasFlag(mRestyleTracker.RootBit())) { + aRestyleRoot = aElement; + } + if (mRestyleTracker.HasRestyleData(aElement)) { nsRestyleHint rshint = eRestyle_SomeDescendants; if (SelectorMatchesForRestyle(aElement)) { rshint |= eRestyle_Self; } - // XXX Traversing up the tree in AddPendingRestyle can be wasteful, - // as we can do this multiple times for descendants of the element - // we stopped restyling at, up in Restyle(). We should track the - // current restyle root as we traverse down here to avoid that. RestyleHintData data; data.mSelectorsForDescendants = mSelectorsForDescendants; - mRestyleTracker.AddPendingRestyle(aElement, rshint, nsChangeHint(0), &data); + mRestyleTracker.AddPendingRestyle(aElement, rshint, nsChangeHint(0), &data, + Some(aRestyleRoot)); return; } @@ -2785,14 +2788,16 @@ ElementRestyler::AddPendingRestylesForDescendantsMatchingSelectors(Element* aEle data.mSelectorsForDescendants = mSelectorsForDescendants; mRestyleTracker.AddPendingRestyle(aElement, eRestyle_Self | eRestyle_SomeDescendants, - nsChangeHint(0), &data); + nsChangeHint(0), &data, + Some(aRestyleRoot)); return; } FlattenedChildIterator it(aElement); for (nsIContent* n = it.GetNextChild(); n; n = it.GetNextChild()) { if (n->IsElement()) { - AddPendingRestylesForDescendantsMatchingSelectors(n->AsElement()); + AddPendingRestylesForDescendantsMatchingSelectors(n->AsElement(), + aRestyleRoot); } } } @@ -2985,10 +2990,13 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint) if (mContent->IsElement()) { if ((aRestyleHint & eRestyle_SomeDescendants) && !mSelectorsForDescendants.IsEmpty()) { - FlattenedChildIterator it(mContent->AsElement()); + Element* element = mContent->AsElement(); + Element* restyleRoot = mRestyleTracker.FindClosestRestyleRoot(element); + FlattenedChildIterator it(element); for (nsIContent* n = it.GetNextChild(); n; n = it.GetNextChild()) { if (n->IsElement()) { - AddPendingRestylesForDescendantsMatchingSelectors(n->AsElement()); + AddPendingRestylesForDescendantsMatchingSelectors(n->AsElement(), + restyleRoot); } } } diff --git a/layout/base/RestyleManager.h b/layout/base/RestyleManager.h index 13afc16188f5..91e6fc30485a 100644 --- a/layout/base/RestyleManager.h +++ b/layout/base/RestyleManager.h @@ -715,7 +715,8 @@ private: eNotifyHidden }; - void AddPendingRestylesForDescendantsMatchingSelectors(Element* aElement); + void AddPendingRestylesForDescendantsMatchingSelectors(Element* aElement, + Element* aRestyleRoot); #ifdef RESTYLE_LOGGING int32_t& LoggingDepth() { return mLoggingDepth; } From 96ce1278fa3541c613060e208925e1db42f80a0d Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Tue, 4 Aug 2015 17:27:53 +1000 Subject: [PATCH 23/56] Bug 1180118 - Part 9: Clear nsCSSSelector pointers in the pending restyle tracker if they might be stale. r=bzbarsky --- layout/base/RestyleManager.h | 4 ++++ layout/base/RestyleTracker.cpp | 22 ++++++++++++++++++++++ layout/base/RestyleTracker.h | 17 +++++++++++++++++ layout/style/CSSStyleSheet.cpp | 9 +++++++++ layout/style/nsStyleSet.cpp | 14 ++++++++++++++ layout/style/nsStyleSet.h | 4 ++++ 6 files changed, 70 insertions(+) diff --git a/layout/base/RestyleManager.h b/layout/base/RestyleManager.h index 91e6fc30485a..984d92dbae69 100644 --- a/layout/base/RestyleManager.h +++ b/layout/base/RestyleManager.h @@ -127,6 +127,10 @@ public: */ nsresult ReparentStyleContext(nsIFrame* aFrame); + void ClearSelectors() { + mPendingRestyles.ClearSelectors(); + } + private: // Used when restyling an element with a frame. void ComputeAndProcessStyleChange(nsIFrame* aFrame, diff --git a/layout/base/RestyleTracker.cpp b/layout/base/RestyleTracker.cpp index 537387e57a74..d6e14de28eef 100644 --- a/layout/base/RestyleTracker.cpp +++ b/layout/base/RestyleTracker.cpp @@ -447,6 +447,9 @@ RestyleTracker::DoProcessRestyles() } } + // mPendingRestyles is now empty. + mHaveSelectors = false; + mRestyleManager->EndProcessingRestyles(); } @@ -512,4 +515,23 @@ RestyleTracker::AddRestyleRootsIfAwaitingRestyle( } } +void +RestyleTracker::ClearSelectors() +{ + if (!mHaveSelectors) { + return; + } + for (auto it = mPendingRestyles.Iter(); !it.Done(); it.Next()) { + RestyleData* data = it.Data(); + if (data->mRestyleHint & eRestyle_SomeDescendants) { + data->mRestyleHint = + (data->mRestyleHint & ~eRestyle_SomeDescendants) | eRestyle_Subtree; + data->mRestyleHintData.mSelectorsForDescendants.Clear(); + } else { + MOZ_ASSERT(data->mRestyleHintData.mSelectorsForDescendants.IsEmpty()); + } + } + mHaveSelectors = false; +} + } // namespace mozilla diff --git a/layout/base/RestyleTracker.h b/layout/base/RestyleTracker.h index 929802746609..fa8805d9a011 100644 --- a/layout/base/RestyleTracker.h +++ b/layout/base/RestyleTracker.h @@ -231,6 +231,7 @@ public: explicit RestyleTracker(Element::FlagsType aRestyleBits) : mRestyleBits(aRestyleBits) , mHaveLaterSiblingRestyles(false) + , mHaveSelectors(false) { NS_PRECONDITION((mRestyleBits & ~ELEMENT_ALL_RESTYLE_FLAGS) == 0, "Why do we have these bits set?"); @@ -352,6 +353,14 @@ public: void AddRestyleRootsIfAwaitingRestyle( const nsTArray>& aElements); + /** + * Converts any eRestyle_SomeDescendants restyle hints in the pending restyle + * table into eRestyle_Subtree hints and clears out the associated arrays of + * nsCSSSelector pointers. This is called in response to a style sheet change + * that might have cause an nsCSSSelector to be destroyed. + */ + void ClearSelectors(); + /** * The document we're associated with. */ @@ -402,6 +411,9 @@ private: // flag. We need this to avoid enumerating the hashtable looking // for such entries when we can't possibly have any. bool mHaveLaterSiblingRestyles; + // True if we have some entries with selectors in the restyle hint data. + // We use this to skip iterating over mPendingRestyles in ClearSelectors. + bool mHaveSelectors; }; inline bool @@ -412,6 +424,11 @@ RestyleTracker::AddPendingRestyleToTable(Element* aElement, { RestyleData* existingData; + if (aRestyleHintData && + !aRestyleHintData->mSelectorsForDescendants.IsEmpty()) { + mHaveSelectors = true; + } + // Check the RestyleBit() flag before doing the hashtable Get, since // it's possible that the data in the hashtable isn't actually // relevant anymore (if the flag is not set). diff --git a/layout/style/CSSStyleSheet.cpp b/layout/style/CSSStyleSheet.cpp index 949823436cf4..718de62b5d01 100644 --- a/layout/style/CSSStyleSheet.cpp +++ b/layout/style/CSSStyleSheet.cpp @@ -1709,6 +1709,15 @@ CSSStyleSheet::List(FILE* out, int32_t aIndent) const void CSSStyleSheet::ClearRuleCascades() { + // We might be in ClearRuleCascades because we had a modification + // to the sheet that resulted in an nsCSSSelector being destroyed. + // Tell the RestyleManager for each document we're used in + // so that they can drop any nsCSSSelector pointers (used for + // eRestyle_SomeDescendants) in their mPendingRestyles. + for (nsStyleSet* styleSet : mStyleSets) { + styleSet->ClearSelectors(); + } + bool removedSheetFromRuleProcessorCache = false; if (mRuleProcessors) { nsCSSRuleProcessor **iter = mRuleProcessors->Elements(), diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index 1f6c5673b0bd..61e5a4781ec2 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -385,6 +385,14 @@ SortStyleSheetsByScope(nsTArray& aSheets) nsresult nsStyleSet::GatherRuleProcessors(sheetType aType) { + // We might be in GatherRuleProcessors because we are dropping a sheet, + // resulting in an nsCSSSelector being destroyed. Tell the + // RestyleManager for each document we're used in so that they can + // drop any nsCSSSelector pointers (used for eRestyle_SomeDescendants) + // in their mPendingRestyles. + if (IsCSSSheetType(aType)) { + ClearSelectors(); + } nsCOMPtr oldRuleProcessor(mRuleProcessors[aType]); nsTArray> oldScopedDocRuleProcessors; if (aType == eAgentSheet || aType == eUserSheet) { @@ -2498,3 +2506,9 @@ nsStyleSet::HasRuleProcessorUsedByMultipleStyleSets(sheetType aSheetType) static_cast(mRuleProcessors[aSheetType].get()); return rp->IsUsedByMultipleStyleSets(); } + +void +nsStyleSet::ClearSelectors() +{ + PresContext()->RestyleManager()->ClearSelectors(); +} diff --git a/layout/style/nsStyleSet.h b/layout/style/nsStyleSet.h index f848f5d94673..7d3e85a6dcd5 100644 --- a/layout/style/nsStyleSet.h +++ b/layout/style/nsStyleSet.h @@ -399,6 +399,10 @@ class nsStyleSet final bool HasRuleProcessorUsedByMultipleStyleSets(sheetType aSheetType); + // Tells the RestyleManager for the document using this style set + // to drop any nsCSSSelector pointers it has. + void ClearSelectors(); + private: nsStyleSet(const nsStyleSet& aCopy) = delete; nsStyleSet& operator=(const nsStyleSet& aCopy) = delete; From e4b325902bac691c1318d2c6633cac2b31bf2553 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Tue, 4 Aug 2015 17:27:53 +1000 Subject: [PATCH 24/56] Bug 1180118 - Part 10: Logging. r=bzbarsky --- layout/base/RestyleManager.cpp | 27 ++++++++++ layout/style/StyleRule.cpp | 95 ++++++++++++++++++++++++++++++---- layout/style/StyleRule.h | 19 ++++--- 3 files changed, 126 insertions(+), 15 deletions(-) diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index 53c3fb53431a..d020d49340ec 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -63,6 +63,15 @@ FrameTagToString(const nsIFrame* aFrame) aFrame->ListTag(result); return result; } + +static nsCString +ElementTagToString(dom::Element* aElement) +{ + nsCString result; + nsDependentAtomString buf(aElement->NodeInfo()->NameAtom()); + result.AppendPrintf("(%s@%p)", NS_ConvertUTF16toUTF8(buf).get(), aElement); + return result; +} #endif RestyleManager::RestyleManager(nsPresContext* aPresContext) @@ -2767,6 +2776,10 @@ ElementRestyler::AddPendingRestylesForDescendantsMatchingSelectors( Element* aElement, Element* aRestyleRoot) { + LOG_RESTYLE("considering element %s for eRestyle_SomeDescendants", + ElementTagToString(aElement).get()); + LOG_RESTYLE_INDENT(); + if (aElement->HasFlag(mRestyleTracker.RootBit())) { aRestyleRoot = aElement; } @@ -2774,7 +2787,10 @@ ElementRestyler::AddPendingRestylesForDescendantsMatchingSelectors( if (mRestyleTracker.HasRestyleData(aElement)) { nsRestyleHint rshint = eRestyle_SomeDescendants; if (SelectorMatchesForRestyle(aElement)) { + LOG_RESTYLE("element has existing restyle data and matches a selector"); rshint |= eRestyle_Self; + } else { + LOG_RESTYLE("element has existing restyle data but doesn't match selectors"); } RestyleHintData data; data.mSelectorsForDescendants = mSelectorsForDescendants; @@ -2784,6 +2800,7 @@ ElementRestyler::AddPendingRestylesForDescendantsMatchingSelectors( } if (SelectorMatchesForRestyle(aElement)) { + LOG_RESTYLE("element has no restyle data but matches a selector"); RestyleHintData data; data.mSelectorsForDescendants = mSelectorsForDescendants; mRestyleTracker.AddPendingRestyle(aElement, @@ -2991,6 +3008,16 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint) if ((aRestyleHint & eRestyle_SomeDescendants) && !mSelectorsForDescendants.IsEmpty()) { Element* element = mContent->AsElement(); + LOG_RESTYLE("traversing descendants of element %s to propagate " + "eRestyle_SomeDescendants for these %d selectors:", + ElementTagToString(element).get(), + int(mSelectorsForDescendants.Length())); + LOG_RESTYLE_INDENT(); +#ifdef RESTYLE_LOGGING + for (nsCSSSelector* sel : mSelectorsForDescendants) { + LOG_RESTYLE("%s", sel->RestrictedSelectorToString().get()); + } +#endif Element* restyleRoot = mRestyleTracker.FindClosestRestyleRoot(element); FlattenedChildIterator it(element); for (nsIContent* n = it.GetNextChild(); n; n = it.GetNextChild()) { diff --git a/layout/style/StyleRule.cpp b/layout/style/StyleRule.cpp index 434b389c4037..c7ae9101074b 100644 --- a/layout/style/StyleRule.cpp +++ b/layout/style/StyleRule.cpp @@ -559,7 +559,7 @@ nsCSSSelector::ToString(nsAString& aString, CSSStyleSheet* aSheet, const nsCSSSelector *s = stack.ElementAt(index); stack.RemoveElementAt(index); - s->AppendToStringWithoutCombinators(aString, aSheet); + s->AppendToStringWithoutCombinators(aString, aSheet, false); // Append the combinator, if needed. if (!stack.IsEmpty()) { @@ -583,24 +583,85 @@ nsCSSSelector::ToString(nsAString& aString, CSSStyleSheet* aSheet, } void -nsCSSSelector::AppendToStringWithoutCombinators - (nsAString& aString, CSSStyleSheet* aSheet) const +nsCSSSelector::AppendToStringWithoutCombinators( + nsAString& aString, + CSSStyleSheet* aSheet, + bool aUseStandardNamespacePrefixes) const { - AppendToStringWithoutCombinatorsOrNegations(aString, aSheet, false); + AppendToStringWithoutCombinatorsOrNegations(aString, aSheet, false, + aUseStandardNamespacePrefixes); for (const nsCSSSelector* negation = mNegations; negation; negation = negation->mNegations) { aString.AppendLiteral(":not("); - negation->AppendToStringWithoutCombinatorsOrNegations(aString, aSheet, - true); + negation->AppendToStringWithoutCombinatorsOrNegations( + aString, aSheet, true, aUseStandardNamespacePrefixes); aString.Append(char16_t(')')); } } +#ifdef DEBUG +nsCString +nsCSSSelector::RestrictedSelectorToString() const +{ + MOZ_ASSERT(IsRestrictedSelector()); + + nsString result; + AppendToStringWithoutCombinators(result, nullptr, true); + return NS_ConvertUTF16toUTF8(result); +} + +static bool +AppendStandardNamespacePrefixToString(nsAString& aString, int32_t aNameSpace) +{ + if (aNameSpace == kNameSpaceID_Unknown) { + // Wildcard namespace; no prefix to write. + return false; + } + switch (aNameSpace) { + case kNameSpaceID_None: + break; + case kNameSpaceID_XML: + aString.AppendLiteral("xml"); + break; + case kNameSpaceID_XHTML: + aString.AppendLiteral("html"); + break; + case kNameSpaceID_XLink: + aString.AppendLiteral("xlink"); + break; + case kNameSpaceID_XSLT: + aString.AppendLiteral("xsl"); + break; + case kNameSpaceID_XBL: + aString.AppendLiteral("xbl"); + break; + case kNameSpaceID_MathML: + aString.AppendLiteral("math"); + break; + case kNameSpaceID_RDF: + aString.AppendLiteral("rdf"); + break; + case kNameSpaceID_XUL: + aString.AppendLiteral("xul"); + break; + case kNameSpaceID_SVG: + aString.AppendLiteral("svg"); + break; + default: + aString.AppendLiteral("ns"); + aString.AppendInt(aNameSpace); + break; + } + return true; +} +#endif + void nsCSSSelector::AppendToStringWithoutCombinatorsOrNegations (nsAString& aString, CSSStyleSheet* aSheet, - bool aIsNegated) const + bool aIsNegated, + bool aUseStandardNamespacePrefixes) const { nsAutoString temp; bool isPseudoElement = IsPseudoElement(); @@ -616,7 +677,18 @@ nsCSSSelector::AppendToStringWithoutCombinatorsOrNegations // null, that means that the only namespaces we could have are the // wildcard namespace (which can be implicit in this case) and the "none" // namespace, which then needs to be explicitly specified. - if (!sheetNS) { + if (aUseStandardNamespacePrefixes) { +#ifdef DEBUG + // We have no sheet to look up prefix information from. This is + // only for debugging, so use some "standard" prefixes that + // are recognizable. + wroteNamespace = + AppendStandardNamespacePrefixToString(aString, mNameSpace); + if (wroteNamespace) { + aString.Append(char16_t('|')); + } +#endif + } else if (!sheetNS) { NS_ASSERTION(mNameSpace == kNameSpaceID_Unknown || mNameSpace == kNameSpaceID_None, "How did we get this namespace?"); @@ -740,7 +812,12 @@ nsCSSSelector::AppendToStringWithoutCombinatorsOrNegations aString.Append(char16_t('*')); aString.Append(char16_t('|')); } else if (list->mNameSpace != kNameSpaceID_None) { - if (aSheet) { + if (aUseStandardNamespacePrefixes) { +#ifdef DEBUG + AppendStandardNamespacePrefixToString(aString, list->mNameSpace); + aString.Append(char16_t('|')); +#endif + } else if (aSheet) { nsXMLNameSpaceMap *sheetNS = aSheet->GetNameSpaceMap(); nsIAtom *prefixAtom = sheetNS->FindPrefix(list->mNameSpace); // Default namespaces don't apply to attribute selectors, so diff --git a/layout/style/StyleRule.h b/layout/style/StyleRule.h index a6996fc76b25..057c16d661de 100644 --- a/layout/style/StyleRule.h +++ b/layout/style/StyleRule.h @@ -163,16 +163,23 @@ public: return PseudoType() == nsCSSPseudoElements::ePseudo_NotPseudoElement; } +#ifdef DEBUG + nsCString RestrictedSelectorToString() const; +#endif + private: void AddPseudoClassInternal(nsPseudoClassList *aPseudoClass); nsCSSSelector* Clone(bool aDeepNext, bool aDeepNegations) const; - void AppendToStringWithoutCombinators(nsAString& aString, - mozilla::CSSStyleSheet* aSheet) const; - void AppendToStringWithoutCombinatorsOrNegations(nsAString& aString, - mozilla::CSSStyleSheet* aSheet, - bool aIsNegated) - const; + void AppendToStringWithoutCombinators( + nsAString& aString, + mozilla::CSSStyleSheet* aSheet, + bool aUseStandardNamespacePrefixes) const; + void AppendToStringWithoutCombinatorsOrNegations( + nsAString& aString, + mozilla::CSSStyleSheet* aSheet, + bool aIsNegated, + bool aUseStandardNamespacePrefixes) const; // Returns true if this selector can have a namespace specified (which // happens if and only if the default namespace would apply to this // selector). From 6779b6d8a740c1c236a86709cb1659aab03e944c Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Tue, 4 Aug 2015 17:27:53 +1000 Subject: [PATCH 25/56] Bug 1180118 - Part 11: Use ReparentStyleContext even if eRestyle_SomeDescendants is used. r=bzbarsky --- layout/base/RestyleManager.cpp | 25 +++++++++++++++++++------ layout/base/RestyleManager.h | 10 ++++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index d020d49340ec..2bcd9872ccda 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -3253,6 +3253,20 @@ ElementRestyler::MustRestyleSelf(nsRestyleHint aRestyleHint, SelectorMatchesForRestyle(aElement)); } +bool +ElementRestyler::CanReparentStyleContext(nsRestyleHint aRestyleHint) +{ + // If we had any restyle hints other than the ones listed below, + // which don't control whether the current frame/element needs + // a new style context by looking up a new rule node, or if + // we are reconstructing the entire rule tree, then we can't + // use ReparentStyleContext. + return !(aRestyleHint & ~(eRestyle_Force | + eRestyle_ForceDescendants | + eRestyle_SomeDescendants)) && + !mPresContext->StyleSet()->IsInRuleTreeReconstruct(); +} + ElementRestyler::RestyleResult ElementRestyler::RestyleSelf(nsIFrame* aSelf, nsRestyleHint aRestyleHint, @@ -3364,8 +3378,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, else { Element* element = ElementForStyleContext(mParentContent, aSelf, pseudoType); if (!MustRestyleSelf(aRestyleHint, element)) { - if (!(aRestyleHint & ~(eRestyle_Force | eRestyle_ForceDescendants)) && - !styleSet->IsInRuleTreeReconstruct()) { + if (CanReparentStyleContext(aRestyleHint)) { LOG_RESTYLE("reparenting style context"); newContext = styleSet->ReparentStyleContext(oldContext, parentContext, element); @@ -3638,7 +3651,10 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, Element* element = extraPseudoType != nsCSSPseudoElements::ePseudo_AnonBox ? mContent->AsElement() : nullptr; if (!MustRestyleSelf(aRestyleHint, element)) { - if (styleSet->IsInRuleTreeReconstruct()) { + if (CanReparentStyleContext(aRestyleHint)) { + newExtraContext = + styleSet->ReparentStyleContext(oldExtraContext, newContext, element); + } else { // Use ResolveStyleWithReplacement as a substitute for // ReparentStyleContext that rebuilds the path in the rule tree // rather than reusing the rule node, as we need to do during a @@ -3653,9 +3669,6 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, styleSet->ResolveStyleWithReplacement(element, pseudoElement, newContext, oldExtraContext, nsRestyleHint(0)); - } else { - newExtraContext = - styleSet->ReparentStyleContext(oldExtraContext, newContext, element); } } else if (extraPseudoType == nsCSSPseudoElements::ePseudo_AnonBox) { newExtraContext = styleSet->ResolveAnonymousBoxStyle(extraPseudoTag, diff --git a/layout/base/RestyleManager.h b/layout/base/RestyleManager.h index 984d92dbae69..8bcca702b7de 100644 --- a/layout/base/RestyleManager.h +++ b/layout/base/RestyleManager.h @@ -659,6 +659,16 @@ private: */ bool MustRestyleSelf(nsRestyleHint aRestyleHint, Element* aElement); + /** + * Returns true iff aRestyleHint indicates that we can call + * ReparentStyleContext rather than any other restyling method of + * nsStyleSet that looks up a new rule node, and if we are + * not in the process of reconstructing the whole rule tree. + * This is used to check whether it is appropriate to call + * ReparentStyleContext. + */ + bool CanReparentStyleContext(nsRestyleHint aRestyleHint); + /** * Helpers for Restyle(). */ From 2811bf3638437645203006693d32bc290fb2bde2 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Tue, 4 Aug 2015 17:49:53 +1000 Subject: [PATCH 26/56] Bug 1180118 - Followup warning-as-error build fix. --- layout/base/nsChangeHint.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/base/nsChangeHint.h b/layout/base/nsChangeHint.h index 55d90f2d8692..14b7fc7a4b22 100644 --- a/layout/base/nsChangeHint.h +++ b/layout/base/nsChangeHint.h @@ -12,7 +12,7 @@ #include "nsDebug.h" #include "nsTArray.h" -class nsCSSSelector; +struct nsCSSSelector; // Defines for various style related constants From e228e20bfe5f08aa51144525e158373e2b173ddd Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Tue, 4 Aug 2015 17:50:32 +1000 Subject: [PATCH 27/56] Bug 1180118 - Second followup warning-as-error build fix. --- layout/base/RestyleManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index 2bcd9872ccda..ff891d637424 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -2737,7 +2737,7 @@ ElementRestyler::CaptureChange(nsStyleContext* aOldContext, class MOZ_STACK_CLASS AutoSelectorArrayTruncater final { public: - AutoSelectorArrayTruncater(nsTArray& aSelectorsForDescendants) + explicit AutoSelectorArrayTruncater(nsTArray& aSelectorsForDescendants) : mSelectorsForDescendants(aSelectorsForDescendants) , mOriginalLength(aSelectorsForDescendants.Length()) { From d1c5eb9e63574916b6bb43ee9bbf53179f1c4126 Mon Sep 17 00:00:00 2001 From: JW Wang Date: Tue, 4 Aug 2015 11:17:03 +0800 Subject: [PATCH 28/56] Bug 1189204 - activate autoplay when playing a media source. r=jya. --- dom/html/HTMLMediaElement.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index 2a88cc022563..d2cac6a12b3d 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -3728,12 +3728,14 @@ bool HTMLMediaElement::CanActivateAutoplay() { // For stream inputs, we activate autoplay on HAVE_NOTHING because // this element itself might be blocking the stream from making progress by - // being paused. + // being paused. We also activate autopaly when playing a media source since + // the data download is controlled by the script and there is no way to + // evaluate MediaDecoder::CanPlayThrough(). return !mPausedForInactiveDocumentOrChannel && mAutoplaying && mPaused && ((mDecoder && mReadyState >= nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA) || - mSrcStream) && + mSrcStream || mMediaSource) && HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay) && mAutoplayEnabled && !IsEditable(); From 60e71b20d85e7386b75cf3f33fa384c770a99e5b Mon Sep 17 00:00:00 2001 From: Kelly Davis Date: Tue, 4 Aug 2015 00:39:00 +0200 Subject: [PATCH 29/56] Bug 1187791 - Part 1 of 1 - SpeechRecognition::maxAlternatives can't throw; so, rm webidl throws specifier. r=smaug --HG-- extra : rebase_source : c0879a3ce21fbeb701aaa18c3ab82110cc53bce7 --- .../recognition/PocketSphinxSpeechRecognitionService.cpp | 6 ++---- dom/media/webspeech/recognition/SpeechRecognition.cpp | 4 ++-- dom/media/webspeech/recognition/SpeechRecognition.h | 4 ++-- .../recognition/test/FakeSpeechRecognitionService.cpp | 3 +-- dom/webidl/SpeechRecognition.webidl | 1 - 5 files changed, 7 insertions(+), 11 deletions(-) diff --git a/dom/media/webspeech/recognition/PocketSphinxSpeechRecognitionService.cpp b/dom/media/webspeech/recognition/PocketSphinxSpeechRecognitionService.cpp index e8d4abcb88b9..0ce52c2cca6d 100644 --- a/dom/media/webspeech/recognition/PocketSphinxSpeechRecognitionService.cpp +++ b/dom/media/webspeech/recognition/PocketSphinxSpeechRecognitionService.cpp @@ -54,8 +54,7 @@ public: SpeechRecognitionResultList* resultList = new SpeechRecognitionResultList(mRecognition); SpeechRecognitionResult* result = new SpeechRecognitionResult(mRecognition); - ErrorResult rv; - if (0 < mRecognition->GetMaxAlternatives(rv)) { // GetMaxAlternatives can't fail + if (0 < mRecognition->MaxAlternatives()) { SpeechRecognitionAlternative* alternative = new SpeechRecognitionAlternative(mRecognition); @@ -331,8 +330,7 @@ PocketSphinxSpeechRecognitionService::BuildMockResultList() SpeechRecognitionResultList* resultList = new SpeechRecognitionResultList(mRecognition); SpeechRecognitionResult* result = new SpeechRecognitionResult(mRecognition); - ErrorResult rv; - if (0 < mRecognition->GetMaxAlternatives(rv)) { // GetMaxAlternatives can't fail + if (0 < mRecognition->MaxAlternatives()) { SpeechRecognitionAlternative* alternative = new SpeechRecognitionAlternative(mRecognition); diff --git a/dom/media/webspeech/recognition/SpeechRecognition.cpp b/dom/media/webspeech/recognition/SpeechRecognition.cpp index 14e4f9833ba4..0ab8c009feb9 100644 --- a/dom/media/webspeech/recognition/SpeechRecognition.cpp +++ b/dom/media/webspeech/recognition/SpeechRecognition.cpp @@ -684,13 +684,13 @@ SpeechRecognition::SetInterimResults(bool aArg) } uint32_t -SpeechRecognition::GetMaxAlternatives(ErrorResult& aRv) const +SpeechRecognition::MaxAlternatives() const { return mMaxAlternatives; } void -SpeechRecognition::SetMaxAlternatives(uint32_t aArg, ErrorResult& aRv) +SpeechRecognition::SetMaxAlternatives(uint32_t aArg) { mMaxAlternatives = aArg; return; diff --git a/dom/media/webspeech/recognition/SpeechRecognition.h b/dom/media/webspeech/recognition/SpeechRecognition.h index 671dd023399d..2cb973d5ea06 100644 --- a/dom/media/webspeech/recognition/SpeechRecognition.h +++ b/dom/media/webspeech/recognition/SpeechRecognition.h @@ -87,9 +87,9 @@ public: void SetInterimResults(bool aArg); - uint32_t GetMaxAlternatives(ErrorResult& aRv) const; + uint32_t MaxAlternatives() const; - void SetMaxAlternatives(uint32_t aArg, ErrorResult& aRv); + void SetMaxAlternatives(uint32_t aArg); void GetServiceURI(nsString& aRetVal, ErrorResult& aRv) const; diff --git a/dom/media/webspeech/recognition/test/FakeSpeechRecognitionService.cpp b/dom/media/webspeech/recognition/test/FakeSpeechRecognitionService.cpp index 86be26ab8428..703dbad4be24 100644 --- a/dom/media/webspeech/recognition/test/FakeSpeechRecognitionService.cpp +++ b/dom/media/webspeech/recognition/test/FakeSpeechRecognitionService.cpp @@ -102,8 +102,7 @@ FakeSpeechRecognitionService::BuildMockResultList() { SpeechRecognitionResultList* resultList = new SpeechRecognitionResultList(mRecognition); SpeechRecognitionResult* result = new SpeechRecognitionResult(mRecognition); - ErrorResult rv; - if (0 < mRecognition->GetMaxAlternatives(rv)) { // GetMaxAlternatives can't fail + if (0 < mRecognition->MaxAlternatives()) { SpeechRecognitionAlternative* alternative = new SpeechRecognitionAlternative(mRecognition); alternative->mTranscript = NS_LITERAL_STRING("Mock final result"); diff --git a/dom/webidl/SpeechRecognition.webidl b/dom/webidl/SpeechRecognition.webidl index 8f7a8324074e..c7dc9422d654 100644 --- a/dom/webidl/SpeechRecognition.webidl +++ b/dom/webidl/SpeechRecognition.webidl @@ -20,7 +20,6 @@ interface SpeechRecognition : EventTarget { [Throws] attribute boolean continuous; attribute boolean interimResults; - [Throws] attribute unsigned long maxAlternatives; [Throws] attribute DOMString serviceURI; From 47ef1eb36a907e622f874cb7a30a195674874524 Mon Sep 17 00:00:00 2001 From: CJKu Date: Mon, 3 Aug 2015 22:22:00 +0200 Subject: [PATCH 30/56] Bug 1190176 - Make LayerScopeWebSocketManager thread safe. r=:djg --HG-- extra : rebase_source : 8ec753a1c645d1043cc903ef7f014ba49dcf4b4d --- gfx/layers/LayerScope.cpp | 268 +++++++++++++++++++++----------------- 1 file changed, 147 insertions(+), 121 deletions(-) diff --git a/gfx/layers/LayerScope.cpp b/gfx/layers/LayerScope.cpp index 0ec8f1da25c3..b448fb288ac5 100644 --- a/gfx/layers/LayerScope.cpp +++ b/gfx/layers/LayerScope.cpp @@ -69,61 +69,6 @@ using namespace layerscope; class DebugDataSender; class DebugGLData; -/* - * This class handle websocket protocol which included - * handshake and data frame's header - */ -class LayerScopeWebSocketHandler : public nsIInputStreamCallback { -public: - NS_DECL_THREADSAFE_ISUPPORTS - - enum SocketStateType { - NoHandshake, - HandshakeSuccess, - HandshakeFailed - }; - - LayerScopeWebSocketHandler() - : mState(NoHandshake) - , mConnected(false) - { } - - void OpenStream(nsISocketTransport* aTransport); - - bool WriteToStream(void *aPtr, uint32_t aSize); - - // nsIInputStreamCallback - NS_IMETHODIMP OnInputStreamReady(nsIAsyncInputStream *aStream) override; - -private: - virtual ~LayerScopeWebSocketHandler() { CloseConnection(); } - - void ReadInputStreamData(nsTArray& aProtocolString); - - bool WebSocketHandshake(nsTArray& aProtocolString); - - nsresult HandleSocketMessage(nsIAsyncInputStream *aStream); - - nsresult ProcessInput(uint8_t *aBuffer, uint32_t aCount); - - // Copied from WebsocketChannel, helper function to decode data frame - void ApplyMask(uint32_t aMask, uint8_t *aData, uint64_t aLen); - - bool HandleDataFrame(uint8_t *aData, uint32_t aSize); - - void CloseConnection(); - -private: - nsCOMPtr mOutputStream; - nsCOMPtr mInputStream; - nsCOMPtr mTransport; - SocketStateType mState; - bool mConnected; -}; - -NS_IMPL_ISUPPORTS(LayerScopeWebSocketHandler, nsIInputStreamCallback); - - /* * Manage Websocket connections */ @@ -132,27 +77,18 @@ public: LayerScopeWebSocketManager(); ~LayerScopeWebSocketManager(); - void AddConnection(nsISocketTransport *aTransport) - { - MOZ_ASSERT(aTransport); - nsRefPtr temp = new LayerScopeWebSocketHandler(); - temp->OpenStream(aTransport); - mHandlers.AppendElement(temp.get()); - } - - void RemoveConnection(uint32_t aIndex) - { - MOZ_ASSERT(aIndex < mHandlers.Length()); - mHandlers.RemoveElementAt(aIndex); - } - void RemoveAllConnections() { + MOZ_ASSERT(NS_IsMainThread()); + + MutexAutoLock lock(mHandlerMutex); mHandlers.Clear(); } bool WriteAll(void *ptr, uint32_t size) { + MOZ_ASSERT(NS_IsMainThread()); + for (int32_t i = mHandlers.Length() - 1; i >= 0; --i) { if (!mHandlers[i]->WriteToStream(ptr, size)) { // Send failed, remove this handler @@ -165,19 +101,116 @@ public: bool IsConnected() { + // This funtion can be called in both main thread and compositor thread. + MutexAutoLock lock(mHandlerMutex); return (mHandlers.Length() != 0) ? true : false; } void AppendDebugData(DebugGLData *aDebugData); void CleanDebugData(); void DispatchDebugData(); + private: - nsTArray > mHandlers; - nsCOMPtr mDebugSenderThread; - nsRefPtr mCurrentSender; - nsCOMPtr mServerSocket; + void AddConnection(nsISocketTransport *aTransport) + { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(aTransport); + + MutexAutoLock lock(mHandlerMutex); + + nsRefPtr temp = new SocketHandler(); + temp->OpenStream(aTransport); + mHandlers.AppendElement(temp.get()); + } + + void RemoveConnection(uint32_t aIndex) + { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(aIndex < mHandlers.Length()); + + MutexAutoLock lock(mHandlerMutex); + mHandlers.RemoveElementAt(aIndex); + } + + friend class SocketListener; + class SocketListener : public nsIServerSocketListener + { + public: + NS_DECL_THREADSAFE_ISUPPORTS + + SocketListener() { } + + /* nsIServerSocketListener */ + NS_IMETHODIMP OnSocketAccepted(nsIServerSocket *aServ, + nsISocketTransport *aTransport) override; + NS_IMETHODIMP OnStopListening(nsIServerSocket *aServ, + nsresult aStatus) override + { + return NS_OK; + } + private: + virtual ~SocketListener() { } + }; + + /* + * This class handle websocket protocol which included + * handshake and data frame's header + */ + class SocketHandler : public nsIInputStreamCallback { + public: + NS_DECL_THREADSAFE_ISUPPORTS + + SocketHandler() + : mState(NoHandshake) + , mConnected(false) + { } + + void OpenStream(nsISocketTransport* aTransport); + bool WriteToStream(void *aPtr, uint32_t aSize); + + // nsIInputStreamCallback + NS_IMETHODIMP OnInputStreamReady(nsIAsyncInputStream *aStream) override; + + private: + virtual ~SocketHandler() { CloseConnection(); } + + void ReadInputStreamData(nsTArray& aProtocolString); + bool WebSocketHandshake(nsTArray& aProtocolString); + void ApplyMask(uint32_t aMask, uint8_t *aData, uint64_t aLen); + bool HandleDataFrame(uint8_t *aData, uint32_t aSize); + void CloseConnection(); + + nsresult HandleSocketMessage(nsIAsyncInputStream *aStream); + nsresult ProcessInput(uint8_t *aBuffer, uint32_t aCount); + + private: + enum SocketStateType { + NoHandshake, + HandshakeSuccess, + HandshakeFailed + }; + SocketStateType mState; + + nsCOMPtr mOutputStream; + nsCOMPtr mInputStream; + nsCOMPtr mTransport; + bool mConnected; + }; + + nsTArray > mHandlers; + nsCOMPtr mDebugSenderThread; + nsRefPtr mCurrentSender; + nsCOMPtr mServerSocket; + + // Keep mHandlers accessing thread safe. + Mutex mHandlerMutex; }; +NS_IMPL_ISUPPORTS(LayerScopeWebSocketManager::SocketListener, + nsIServerSocketListener); +NS_IMPL_ISUPPORTS(LayerScopeWebSocketManager::SocketHandler, + nsIInputStreamCallback); + class DrawSession { public: DrawSession() @@ -236,7 +269,9 @@ private: THArray mChangedHosts; }; -// Hold all singleton objects used by LayerScope +/* + * Hold all singleton objects used by LayerScope. + */ class LayerScopeManager { public: @@ -708,40 +743,6 @@ protected: uint64_t mLayerRef; }; -class DebugListener : public nsIServerSocketListener -{ - virtual ~DebugListener() { } - -public: - - NS_DECL_THREADSAFE_ISUPPORTS - - DebugListener() { } - - /* nsIServerSocketListener */ - - NS_IMETHODIMP OnSocketAccepted(nsIServerSocket *aServ, - nsISocketTransport *aTransport) override - { - if (!gLayerScopeManager.GetSocketManager()) - return NS_OK; - - printf_stderr("*** LayerScope: Accepted connection\n"); - gLayerScopeManager.GetSocketManager()->AddConnection(aTransport); - gLayerScopeManager.GetContentMonitor()->Empty(); - return NS_OK; - } - - NS_IMETHODIMP OnStopListening(nsIServerSocket *aServ, - nsresult aStatus) override - { - return NS_OK; - } -}; - -NS_IMPL_ISUPPORTS(DebugListener, nsIServerSocketListener); - - class DebugDataSender : public nsIRunnable { virtual ~DebugDataSender() { @@ -1135,10 +1136,10 @@ LayerScope::ContentChanged(TextureHost *host) } // ---------------------------------------------- -// LayerScopeWebSocketHandler implementation +// SocketHandler implementation // ---------------------------------------------- void -LayerScopeWebSocketHandler::OpenStream(nsISocketTransport* aTransport) +LayerScopeWebSocketManager::SocketHandler::OpenStream(nsISocketTransport* aTransport) { MOZ_ASSERT(aTransport); @@ -1158,7 +1159,7 @@ LayerScopeWebSocketHandler::OpenStream(nsISocketTransport* aTransport) } bool -LayerScopeWebSocketHandler::WriteToStream(void *aPtr, +LayerScopeWebSocketManager::SocketHandler::WriteToStream(void *aPtr, uint32_t aSize) { if (mState == NoHandshake) { @@ -1214,7 +1215,7 @@ LayerScopeWebSocketHandler::WriteToStream(void *aPtr, } NS_IMETHODIMP -LayerScopeWebSocketHandler::OnInputStreamReady(nsIAsyncInputStream *aStream) +LayerScopeWebSocketManager::SocketHandler::OnInputStreamReady(nsIAsyncInputStream *aStream) { MOZ_ASSERT(mInputStream); @@ -1240,7 +1241,7 @@ LayerScopeWebSocketHandler::OnInputStreamReady(nsIAsyncInputStream *aStream) } void -LayerScopeWebSocketHandler::ReadInputStreamData(nsTArray& aProtocolString) +LayerScopeWebSocketManager::SocketHandler::ReadInputStreamData(nsTArray& aProtocolString) { nsLineBuffer lineBuffer; nsCString line; @@ -1255,7 +1256,7 @@ LayerScopeWebSocketHandler::ReadInputStreamData(nsTArray& aProtocolSt } bool -LayerScopeWebSocketHandler::WebSocketHandshake(nsTArray& aProtocolString) +LayerScopeWebSocketManager::SocketHandler::WebSocketHandshake(nsTArray& aProtocolString) { nsresult rv; bool isWebSocket = false; @@ -1343,7 +1344,7 @@ LayerScopeWebSocketHandler::WebSocketHandshake(nsTArray& aProtocolStr } nsresult -LayerScopeWebSocketHandler::HandleSocketMessage(nsIAsyncInputStream *aStream) +LayerScopeWebSocketManager::SocketHandler::HandleSocketMessage(nsIAsyncInputStream *aStream) { // The reading and parsing of this input stream is customized for layer viewer. const uint32_t cPacketSize = 1024; @@ -1377,7 +1378,7 @@ LayerScopeWebSocketHandler::HandleSocketMessage(nsIAsyncInputStream *aStream) } nsresult -LayerScopeWebSocketHandler::ProcessInput(uint8_t *aBuffer, +LayerScopeWebSocketManager::SocketHandler::ProcessInput(uint8_t *aBuffer, uint32_t aCount) { uint32_t avail = aCount; @@ -1465,7 +1466,7 @@ LayerScopeWebSocketHandler::ProcessInput(uint8_t *aBuffer, } void -LayerScopeWebSocketHandler::ApplyMask(uint32_t aMask, +LayerScopeWebSocketManager::SocketHandler::ApplyMask(uint32_t aMask, uint8_t *aData, uint64_t aLen) { @@ -1505,7 +1506,7 @@ LayerScopeWebSocketHandler::ApplyMask(uint32_t aMask, } bool -LayerScopeWebSocketHandler::HandleDataFrame(uint8_t *aData, +LayerScopeWebSocketManager::SocketHandler::HandleDataFrame(uint8_t *aData, uint32_t aSize) { // Handle payload data by protocol buffer @@ -1539,7 +1540,7 @@ LayerScopeWebSocketHandler::HandleDataFrame(uint8_t *aData, } void -LayerScopeWebSocketHandler::CloseConnection() +LayerScopeWebSocketManager::SocketHandler::CloseConnection() { gLayerScopeManager.GetSocketManager()->CleanDebugData(); if (mInputStream) { @@ -1556,18 +1557,18 @@ LayerScopeWebSocketHandler::CloseConnection() mConnected = false; } - // ---------------------------------------------- // LayerScopeWebSocketManager implementation // ---------------------------------------------- LayerScopeWebSocketManager::LayerScopeWebSocketManager() + : mHandlerMutex("LayerScopeWebSocketManager::mHandlerMutex") { NS_NewThread(getter_AddRefs(mDebugSenderThread)); mServerSocket = do_CreateInstance(NS_SERVERSOCKET_CONTRACTID); int port = gfxPrefs::LayerScopePort(); mServerSocket->Init(port, false, -1); - mServerSocket->AsyncListen(new DebugListener); + mServerSocket->AsyncListen(new SocketListener); } LayerScopeWebSocketManager::~LayerScopeWebSocketManager() @@ -1600,10 +1601,23 @@ LayerScopeWebSocketManager::DispatchDebugData() mCurrentSender = nullptr; } +NS_IMETHODIMP LayerScopeWebSocketManager::SocketListener::OnSocketAccepted( + nsIServerSocket *aServ, + nsISocketTransport *aTransport) +{ + if (!gLayerScopeManager.GetSocketManager()) + return NS_OK; + + printf_stderr("*** LayerScope: Accepted connection\n"); + gLayerScopeManager.GetSocketManager()->AddConnection(aTransport); + gLayerScopeManager.GetContentMonitor()->Empty(); + return NS_OK; +} // ---------------------------------------------- // LayerScope implementation // ---------------------------------------------- +/*static*/ void LayerScope::Init() { @@ -1614,6 +1628,7 @@ LayerScope::Init() gLayerScopeManager.CreateServerSocket(); } +/*static*/ void LayerScope::DrawBegin() { @@ -1624,6 +1639,7 @@ LayerScope::DrawBegin() gLayerScopeManager.NewDrawSession(); } +/*static*/ void LayerScope::SetRenderOffset(float aX, float aY) { @@ -1635,6 +1651,7 @@ LayerScope::SetRenderOffset(float aX, float aY) gLayerScopeManager.CurrentSession().mOffsetY = aY; } +/*static*/ void LayerScope::SetLayerTransform(const gfx::Matrix4x4& aMatrix) { @@ -1645,6 +1662,7 @@ LayerScope::SetLayerTransform(const gfx::Matrix4x4& aMatrix) gLayerScopeManager.CurrentSession().mMVMatrix = aMatrix; } +/*static*/ void LayerScope::SetDrawRects(size_t aRects, const gfx::Rect* aLayerRects, @@ -1665,6 +1683,7 @@ LayerScope::SetDrawRects(size_t aRects, } } +/*static*/ void LayerScope::DrawEnd(gl::GLContext* aGLContext, const EffectChain& aEffectChain, @@ -1692,6 +1711,7 @@ LayerScope::DrawEnd(gl::GLContext* aGLContext, } +/*static*/ void LayerScope::SendLayer(LayerComposite* aLayer, int aWidth, @@ -1704,6 +1724,7 @@ LayerScope::SendLayer(LayerComposite* aLayer, SenderHelper::SendLayer(aLayer, aWidth, aHeight); } +/*static*/ void LayerScope::SendLayerDump(UniquePtr aPacket) { @@ -1715,6 +1736,7 @@ LayerScope::SendLayerDump(UniquePtr aPacket) new DebugGLLayersData(Move(aPacket))); } +/*static*/ bool LayerScope::CheckSendable() { @@ -1734,6 +1756,7 @@ LayerScope::CheckSendable() return true; } +/*static*/ void LayerScope::CleanLayer() { @@ -1742,6 +1765,7 @@ LayerScope::CleanLayer() } } +/*static*/ void LayerScope::SetHWComposed() { @@ -1751,11 +1775,13 @@ LayerScope::SetHWComposed() } } +/*static*/ void LayerScope::SetPixelScale(double devPixelsPerCSSPixel) { gLayerScopeManager.SetPixelScale(devPixelsPerCSSPixel); } + // ---------------------------------------------- // LayerScopeAutoFrame implementation // ---------------------------------------------- From 079030035af4bf6bf48349f3e871d784cac4bdf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Pag=C3=A8s?= Date: Mon, 3 Aug 2015 06:32:00 +0200 Subject: [PATCH 31/56] Bug 1189847 - [mozversion] mozversion requires mozdevice, it shoudn't. r=dhunt This make the mozdevice dependency of mozversion optional. --HG-- extra : rebase_source : 40be17f1b8a36055b01b93c3f8087e8f9fa23fbb --- testing/mozbase/docs/mozversion.rst | 9 +++++++++ testing/mozbase/mozversion/mozversion/mozversion.py | 8 +++++++- testing/mozbase/mozversion/setup.py | 6 ++---- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/testing/mozbase/docs/mozversion.rst b/testing/mozbase/docs/mozversion.rst index a310dbc448e1..21b028d174b3 100644 --- a/testing/mozbase/docs/mozversion.rst +++ b/testing/mozbase/docs/mozversion.rst @@ -6,6 +6,15 @@ provides version information such as the application name and the changesets that it has been built from. This is commonly used in reporting or for conditional logic based on the application under test. +Note that mozversion can report the version of remote devices (e.g. Firefox OS) +but it requires the :mod:`mozdevice` dependency in that case. You can require it +along with mozversion by using the extra *device* dependency: + +.. code-block:: bash + + pip install mozversion[device] + + API Usage --------- diff --git a/testing/mozbase/mozversion/mozversion/mozversion.py b/testing/mozbase/mozversion/mozversion/mozversion.py index 7e727e3bc1ca..18b24df1cee7 100644 --- a/testing/mozbase/mozversion/mozversion/mozversion.py +++ b/testing/mozbase/mozversion/mozversion/mozversion.py @@ -12,7 +12,6 @@ import tempfile import xml.dom.minidom import zipfile -import mozdevice import mozfile import mozlog @@ -189,6 +188,13 @@ class RemoteB2GVersion(B2GVersion): **kwargs): B2GVersion.__init__(self, sources, **kwargs) + try: + import mozdevice + except ImportError: + self._logger.critical("mozdevice is required to get the version" + " of a remote device") + raise + if dm_type == 'adb': dm = mozdevice.DeviceManagerADB(deviceSerial=device_serial, serverHost=adb_host, diff --git a/testing/mozbase/mozversion/setup.py b/testing/mozbase/mozversion/setup.py index cc679661e63a..0e54cac6c230 100644 --- a/testing/mozbase/mozversion/setup.py +++ b/testing/mozbase/mozversion/setup.py @@ -6,9 +6,6 @@ from setuptools import setup PACKAGE_VERSION = '1.3' -dependencies = ['mozdevice >= 0.44', - 'mozfile >= 1.0', - 'mozlog >= 3.0'] setup(name='mozversion', version=PACKAGE_VERSION, @@ -23,7 +20,8 @@ setup(name='mozversion', packages=['mozversion'], include_package_data=True, zip_safe=False, - install_requires=dependencies, + install_requires=['mozfile >= 1.0', 'mozlog >= 3.0'], + extras_require={'device': ['mozdevice >= 0.44']}, entry_points=""" # -*- Entry points: -*- [console_scripts] From 05063f4350bdf35b95d318503dec07d93248d051 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 4 Aug 2015 17:05:25 +0900 Subject: [PATCH 32/56] Bug 1188442 IMMHandler::GetSelection() should use static Selection instance when IME doesn't have focus and return its or mSelection's reference r=emk --- widget/windows/IMMHandler.h | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/widget/windows/IMMHandler.h b/widget/windows/IMMHandler.h index c01a8a441cfd..ba6a1c3f403f 100644 --- a/widget/windows/IMMHandler.h +++ b/widget/windows/IMMHandler.h @@ -436,11 +436,29 @@ protected: bool Update(const IMENotification& aIMENotification); bool Init(nsWindow* aWindow); bool EnsureValidSelection(nsWindow* aWindow); + private: + Selection(const Selection& aOther) = delete; + void operator =(const Selection& aOther) = delete; }; + // mSelection stores the latest selection data only when sHasFocus is true. + // Don't access mSelection directly. You should use GetSelection() for + // getting proper state. Selection mSelection; - // mSelection stores the latest selection data only when sHasFocus it true. - // Therefore, if sHasFocus is false, temporary instance should be used. - Selection GetSelection() { return sHasFocus ? mSelection : Selection(); } + + Selection& GetSelection() + { + // When IME has focus, mSelection is automatically updated by + // NOTIFY_IME_OF_SELECTION_CHANGE. + if (sHasFocus) { + return mSelection; + } + // Otherwise, i.e., While IME doesn't have focus, we cannot observe + // selection changes. So, in such case, we need to query selection + // when it's necessary. + static Selection sTempSelection; + sTempSelection.Clear(); + return sTempSelection; + } bool mIsComposing; bool mIsComposingOnPlugin; From 9ac5d002ee359a8c2d98509cab240a3482113d11 Mon Sep 17 00:00:00 2001 From: "Nicolas B. Pierron" Date: Tue, 4 Aug 2015 11:03:03 +0200 Subject: [PATCH 33/56] Bug 1189750 - Fix JSScript::getPCCounts to return a reference instead of a copy. r=bhackett --- js/src/jsscript.cpp | 2 +- js/src/jsscript.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index f8a73c7a212e..c3448800a889 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -1324,7 +1324,7 @@ static inline ScriptCountsMap::Ptr GetScriptCountsMapEntry(JSScript* script) return p; } -js::PCCounts +js::PCCounts& JSScript::getPCCounts(jsbytecode* pc) { MOZ_ASSERT(containsPC(pc)); ScriptCountsMap::Ptr p = GetScriptCountsMapEntry(this); diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 12d11ea2ae78..693be2803331 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -1629,7 +1629,7 @@ class JSScript : public js::gc::TenuredCell public: bool initScriptCounts(JSContext* cx); - js::PCCounts getPCCounts(jsbytecode* pc); + js::PCCounts& getPCCounts(jsbytecode* pc); void addIonCounts(js::jit::IonScriptCounts* ionCounts); js::jit::IonScriptCounts* getIonCounts(); js::ScriptCounts releaseScriptCounts(); From 94b10d301f2bae54200dc835e0f0bce957c02a82 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Tue, 4 Aug 2015 12:20:20 +0200 Subject: [PATCH 34/56] Backed out 13 changesets (bug 1180118) for crashes on a CLOSED TREE Backed out changeset c65d298d7cfa (bug 1180118) Backed out changeset 7c5ebadc3fc9 (bug 1180118) Backed out changeset 91a3e2205388 (bug 1180118) Backed out changeset 15ad6049b940 (bug 1180118) Backed out changeset 9b41cd9f2bc5 (bug 1180118) Backed out changeset 37493f6eef20 (bug 1180118) Backed out changeset b7ec8d4d2d7e (bug 1180118) Backed out changeset cfeeae42d514 (bug 1180118) Backed out changeset 9bcc3233f3c8 (bug 1180118) Backed out changeset b99c358a6fea (bug 1180118) Backed out changeset 4a7b79980353 (bug 1180118) Backed out changeset 20984dfa4302 (bug 1180118) Backed out changeset ef165b896cf4 (bug 1180118) --- layout/base/RestyleManager.cpp | 451 +++++------------- layout/base/RestyleManager.h | 67 +-- layout/base/RestyleTracker.cpp | 36 +- layout/base/RestyleTracker.h | 128 ++--- layout/base/nsChangeHint.h | 42 +- layout/style/AnimationCommon.cpp | 4 +- layout/style/AnimationCommon.h | 3 +- layout/style/CSSStyleSheet.cpp | 9 - .../style/SVGAttrAnimationRuleProcessor.cpp | 4 +- layout/style/SVGAttrAnimationRuleProcessor.h | 3 +- layout/style/StyleRule.cpp | 95 +--- layout/style/StyleRule.h | 23 +- layout/style/nsCSSRuleProcessor.cpp | 225 +-------- layout/style/nsCSSRuleProcessor.h | 19 +- layout/style/nsHTMLCSSStyleSheet.cpp | 4 +- layout/style/nsHTMLCSSStyleSheet.h | 3 +- layout/style/nsHTMLStyleSheet.cpp | 4 +- layout/style/nsHTMLStyleSheet.h | 3 +- layout/style/nsIStyleRuleProcessor.h | 5 +- layout/style/nsStyleSet.cpp | 29 +- layout/style/nsStyleSet.h | 8 +- 21 files changed, 234 insertions(+), 931 deletions(-) diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index ff891d637424..1d202aaaa30a 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -41,8 +41,6 @@ #include "nsDisplayList.h" #include "RestyleTrackerInlines.h" #include "nsSMILAnimationController.h" -#include "nsCSSRuleProcessor.h" -#include "ChildIterator.h" #ifdef ACCESSIBILITY #include "nsAccessibilityService.h" @@ -63,15 +61,6 @@ FrameTagToString(const nsIFrame* aFrame) aFrame->ListTag(result); return result; } - -static nsCString -ElementTagToString(dom::Element* aElement) -{ - nsCString result; - nsDependentAtomString buf(aElement->NodeInfo()->NameAtom()); - result.AppendPrintf("(%s@%p)", NS_ConvertUTF16toUTF8(buf).get(), aElement); - return result; -} #endif RestyleManager::RestyleManager(nsPresContext* aPresContext) @@ -992,12 +981,11 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList) } void -RestyleManager::RestyleElement(Element* aElement, - nsIFrame* aPrimaryFrame, - nsChangeHint aMinHint, - RestyleTracker& aRestyleTracker, - nsRestyleHint aRestyleHint, - const RestyleHintData& aRestyleHintData) +RestyleManager::RestyleElement(Element* aElement, + nsIFrame* aPrimaryFrame, + nsChangeHint aMinHint, + RestyleTracker& aRestyleTracker, + nsRestyleHint aRestyleHint) { MOZ_ASSERT(mReframingStyleContexts, "should have rsc"); NS_ASSERTION(aPrimaryFrame == aElement->GetPrimaryFrame(), @@ -1022,9 +1010,6 @@ RestyleManager::RestyleElement(Element* aElement, newContext->StyleFont()->mFont.size) { // The basis for 'rem' units has changed. mRebuildAllRestyleHint |= aRestyleHint; - if (aRestyleHint & eRestyle_SomeDescendants) { - mRebuildAllRestyleHint |= eRestyle_Subtree; - } NS_UpdateHint(mRebuildAllExtraHint, aMinHint); StartRebuildAllStyleData(aRestyleTracker); return; @@ -1037,7 +1022,7 @@ RestyleManager::RestyleElement(Element* aElement, nsCSSFrameConstructor::REMOVE_FOR_RECONSTRUCTION, nullptr); } else if (aPrimaryFrame) { ComputeAndProcessStyleChange(aPrimaryFrame, aMinHint, aRestyleTracker, - aRestyleHint, aRestyleHintData); + aRestyleHint); } else if (aRestyleHint & ~eRestyle_LaterSiblings) { // We're restyling an element with no frame, so we should try to // make one if its new style says it should have one. But in order @@ -1053,8 +1038,7 @@ RestyleManager::RestyleElement(Element* aElement, newContext->StyleDisplay()->mDisplay == NS_STYLE_DISPLAY_CONTENTS) { // Style change for a display:contents node that did not recreate frames. ComputeAndProcessStyleChange(newContext, aElement, aMinHint, - aRestyleTracker, aRestyleHint, - aRestyleHintData); + aRestyleTracker, aRestyleHint); } } } @@ -1179,15 +1163,13 @@ RestyleManager::AttributeWillChange(Element* aElement, int32_t aModType, const nsAttrValue* aNewValue) { - RestyleHintData rsdata; nsRestyleHint rshint = mPresContext->StyleSet()->HasAttributeDependentStyle(aElement, aAttribute, aModType, false, - aNewValue, - rsdata); - PostRestyleEvent(aElement, rshint, NS_STYLE_HINT_NONE, &rsdata); + aNewValue); + PostRestyleEvent(aElement, rshint, NS_STYLE_HINT_NONE); } // Forwarded nsIMutationObserver method, to handle restyling (and @@ -1270,15 +1252,14 @@ RestyleManager::AttributeChanged(Element* aElement, // See if we can optimize away the style re-resolution -- must be called after // the frame's AttributeChanged() in case it does something that affects the style - RestyleHintData rsdata; nsRestyleHint rshint = mPresContext->StyleSet()->HasAttributeDependentStyle(aElement, aAttribute, aModType, true, - aOldValue, - rsdata); - PostRestyleEvent(aElement, rshint, hint, &rsdata); + aOldValue); + + PostRestyleEvent(aElement, rshint, hint); } /* static */ uint64_t @@ -1575,9 +1556,6 @@ RestyleManager::RebuildAllStyleData(nsChangeHint aExtraHint, NS_ASSERTION(!(aExtraHint & nsChangeHint_ReconstructFrame), "Should not reconstruct the root of the frame tree. " "Use ReconstructDocElementHierarchy instead."); - MOZ_ASSERT(!(aRestyleHint & ~(eRestyle_Subtree | eRestyle_ForceDescendants)), - "the only bits allowed in aRestyleHint are eRestyle_Subtree and " - "eRestyle_ForceDescendants"); NS_UpdateHint(mRebuildAllExtraHint, aExtraHint); mRebuildAllRestyleHint |= aRestyleHint; @@ -1659,8 +1637,7 @@ RestyleManager::StartRebuildAllStyleData(RestyleTracker& aRestyleTracker) // frame and not the root node's primary frame? (We could do // roughly what we do for aRestyleHint above.) ComputeAndProcessStyleChange(rootFrame, - changeHint, aRestyleTracker, restyleHint, - RestyleHintData()); + changeHint, aRestyleTracker, restyleHint); } void @@ -1842,8 +1819,7 @@ RestyleManager::UpdateOnlyAnimationStyles() void RestyleManager::PostRestyleEvent(Element* aElement, nsRestyleHint aRestyleHint, - nsChangeHint aMinChangeHint, - const RestyleHintData* aRestyleHintData) + nsChangeHint aMinChangeHint) { if (MOZ_UNLIKELY(!mPresContext) || MOZ_UNLIKELY(mPresContext->PresShell()->IsDestroying())) { @@ -1855,8 +1831,7 @@ RestyleManager::PostRestyleEvent(Element* aElement, return; } - mPendingRestyles.AddPendingRestyle(aElement, aRestyleHint, aMinChangeHint, - aRestyleHintData); + mPendingRestyles.AddPendingRestyle(aElement, aRestyleHint, aMinChangeHint); // Set mHavePendingNonAnimationRestyles for any restyle that could // possibly contain non-animation styles (i.e., those that require us @@ -1895,9 +1870,6 @@ RestyleManager::PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint, NS_ASSERTION(!(aExtraHint & nsChangeHint_ReconstructFrame), "Should not reconstruct the root of the frame tree. " "Use ReconstructDocElementHierarchy instead."); - MOZ_ASSERT(!(aRestyleHint & eRestyle_SomeDescendants), - "PostRebuildAllStyleDataEvent does not handle " - "eRestyle_SomeDescendants"); mDoRebuildAllStyleData = true; NS_UpdateHint(mRebuildAllExtraHint, aExtraHint); @@ -2495,8 +2467,6 @@ ElementRestyler::ElementRestyler(nsPresContext* aPresContext, nsStyleChangeList* aChangeList, nsChangeHint aHintsHandledByAncestors, RestyleTracker& aRestyleTracker, - nsTArray& - aSelectorsForDescendants, TreeMatchContext& aTreeMatchContext, nsTArray& aVisibleKidsOfHiddenElement, @@ -2515,7 +2485,6 @@ ElementRestyler::ElementRestyler(nsPresContext* aPresContext, , mParentFrameHintsNotHandledForDescendants(nsChangeHint(0)) , mHintsNotHandledForDescendants(nsChangeHint(0)) , mRestyleTracker(aRestyleTracker) - , mSelectorsForDescendants(aSelectorsForDescendants) , mTreeMatchContext(aTreeMatchContext) , mResolvedChild(nullptr) , mContextsToClear(aContextsToClear) @@ -2548,7 +2517,6 @@ ElementRestyler::ElementRestyler(const ElementRestyler& aParentRestyler, aParentRestyler.mHintsNotHandledForDescendants) , mHintsNotHandledForDescendants(nsChangeHint(0)) , mRestyleTracker(aParentRestyler.mRestyleTracker) - , mSelectorsForDescendants(aParentRestyler.mSelectorsForDescendants) , mTreeMatchContext(aParentRestyler.mTreeMatchContext) , mResolvedChild(nullptr) , mContextsToClear(aParentRestyler.mContextsToClear) @@ -2595,7 +2563,6 @@ ElementRestyler::ElementRestyler(ParentContextFromChildFrame, nsChangeHint_Hints_NotHandledForDescendants) , mHintsNotHandledForDescendants(nsChangeHint(0)) , mRestyleTracker(aParentRestyler.mRestyleTracker) - , mSelectorsForDescendants(aParentRestyler.mSelectorsForDescendants) , mTreeMatchContext(aParentRestyler.mTreeMatchContext) , mResolvedChild(nullptr) , mContextsToClear(aParentRestyler.mContextsToClear) @@ -2617,7 +2584,6 @@ ElementRestyler::ElementRestyler(nsPresContext* aPresContext, nsStyleChangeList* aChangeList, nsChangeHint aHintsHandledByAncestors, RestyleTracker& aRestyleTracker, - nsTArray& aSelectorsForDescendants, TreeMatchContext& aTreeMatchContext, nsTArray& aVisibleKidsOfHiddenElement, @@ -2634,7 +2600,6 @@ ElementRestyler::ElementRestyler(nsPresContext* aPresContext, , mParentFrameHintsNotHandledForDescendants(nsChangeHint(0)) , mHintsNotHandledForDescendants(nsChangeHint(0)) , mRestyleTracker(aRestyleTracker) - , mSelectorsForDescendants(aSelectorsForDescendants) , mTreeMatchContext(aTreeMatchContext) , mResolvedChild(nullptr) , mContextsToClear(aContextsToClear) @@ -2734,91 +2699,6 @@ ElementRestyler::CaptureChange(nsStyleContext* aOldContext, RestyleManager::ChangeHintToString(mHintsNotHandledForDescendants).get()); } -class MOZ_STACK_CLASS AutoSelectorArrayTruncater final -{ -public: - explicit AutoSelectorArrayTruncater(nsTArray& aSelectorsForDescendants) - : mSelectorsForDescendants(aSelectorsForDescendants) - , mOriginalLength(aSelectorsForDescendants.Length()) - { - } - - ~AutoSelectorArrayTruncater() - { - mSelectorsForDescendants.TruncateLength(mOriginalLength); - } - -private: - nsTArray& mSelectorsForDescendants; - size_t mOriginalLength; -}; - -/** - * Called when we are stopping a restyle with eRestyle_SomeDescendants, to - * search for descendants that match any of the selectors in - * mSelectorsForDescendants. If the element does match one of the selectors, - * we cause it to be restyled with eRestyle_Self. - * - * We traverse down the flattened tree unless we find an element that - * (a) already has a pending restyle, or (b) does not have a pending restyle - * but does match one of the selectors in mSelectorsForDescendants. For (a), - * we add the current mSelectorsForDescendants into the existing restyle data, - * and for (b) we add a new pending restyle with that array. So in both - * cases, when we come to restyling this element back up in - * ProcessPendingRestyles, we will again find the eRestyle_SomeDescendants - * hint and its selectors array. - * - * This ensures that we don't visit descendant elements and check them - * against mSelectorsForDescendants more than once. - */ -void -ElementRestyler::AddPendingRestylesForDescendantsMatchingSelectors( - Element* aElement, - Element* aRestyleRoot) -{ - LOG_RESTYLE("considering element %s for eRestyle_SomeDescendants", - ElementTagToString(aElement).get()); - LOG_RESTYLE_INDENT(); - - if (aElement->HasFlag(mRestyleTracker.RootBit())) { - aRestyleRoot = aElement; - } - - if (mRestyleTracker.HasRestyleData(aElement)) { - nsRestyleHint rshint = eRestyle_SomeDescendants; - if (SelectorMatchesForRestyle(aElement)) { - LOG_RESTYLE("element has existing restyle data and matches a selector"); - rshint |= eRestyle_Self; - } else { - LOG_RESTYLE("element has existing restyle data but doesn't match selectors"); - } - RestyleHintData data; - data.mSelectorsForDescendants = mSelectorsForDescendants; - mRestyleTracker.AddPendingRestyle(aElement, rshint, nsChangeHint(0), &data, - Some(aRestyleRoot)); - return; - } - - if (SelectorMatchesForRestyle(aElement)) { - LOG_RESTYLE("element has no restyle data but matches a selector"); - RestyleHintData data; - data.mSelectorsForDescendants = mSelectorsForDescendants; - mRestyleTracker.AddPendingRestyle(aElement, - eRestyle_Self | eRestyle_SomeDescendants, - nsChangeHint(0), &data, - Some(aRestyleRoot)); - return; - } - - FlattenedChildIterator it(aElement); - for (nsIContent* n = it.GetNextChild(); n; n = it.GetNextChild()) { - if (n->IsElement()) { - AddPendingRestylesForDescendantsMatchingSelectors(n->AsElement(), - aRestyleRoot); - } - } -} - /** * Recompute style for mFrame (which should not have a prev continuation * with the same style), all of its next continuations with the same @@ -2855,8 +2735,6 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint) AutoDisplayContentsAncestorPusher adcp(mTreeMatchContext, mFrame->PresContext(), mFrame->GetContent() ? mFrame->GetContent()->GetParent() : nullptr); - AutoSelectorArrayTruncater asat(mSelectorsForDescendants); - // List of descendant elements of mContent we know we will eventually need to // restyle. Before we return from this function, we call // RestyleTracker::AddRestyleRootsIfAwaitingRestyle to ensure they get @@ -2864,7 +2742,6 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint) nsTArray> descendants; nsRestyleHint hintToRestore = nsRestyleHint(0); - RestyleHintData hintDataToRestore; if (mContent && mContent->IsElement() && // If we're resolving from the root of the frame tree (which // we do when mDoRebuildAllStyleData), we need to avoid getting the @@ -2886,10 +2763,7 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint) if (NS_UpdateHint(mHintsHandled, restyleData->mChangeHint)) { mChangeList->AppendChange(mFrame, mContent, restyleData->mChangeHint); } - mSelectorsForDescendants.AppendElements( - restyleData->mRestyleHintData.mSelectorsForDescendants); hintToRestore = restyleData->mRestyleHint; - hintDataToRestore = Move(restyleData->mRestyleHintData); aRestyleHint = nsRestyleHint(aRestyleHint | restyleData->mRestyleHint); descendants.SwapElements(restyleData->mDescendants); } @@ -2899,8 +2773,7 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint) // we restyle children with nsRestyleHint(0). But we pass the // eRestyle_ForceDescendants flag down too. nsRestyleHint childRestyleHint = - nsRestyleHint(aRestyleHint & (eRestyle_SomeDescendants | - eRestyle_Subtree | + nsRestyleHint(aRestyleHint & (eRestyle_Subtree | eRestyle_ForceDescendants)); nsRefPtr oldContext = mFrame->StyleContext(); @@ -3003,31 +2876,6 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint) } mRestyleTracker.AddRestyleRootsIfAwaitingRestyle(descendants); - - if (mContent->IsElement()) { - if ((aRestyleHint & eRestyle_SomeDescendants) && - !mSelectorsForDescendants.IsEmpty()) { - Element* element = mContent->AsElement(); - LOG_RESTYLE("traversing descendants of element %s to propagate " - "eRestyle_SomeDescendants for these %d selectors:", - ElementTagToString(element).get(), - int(mSelectorsForDescendants.Length())); - LOG_RESTYLE_INDENT(); -#ifdef RESTYLE_LOGGING - for (nsCSSSelector* sel : mSelectorsForDescendants) { - LOG_RESTYLE("%s", sel->RestrictedSelectorToString().get()); - } -#endif - Element* restyleRoot = mRestyleTracker.FindClosestRestyleRoot(element); - FlattenedChildIterator it(element); - for (nsIContent* n = it.GetNextChild(); n; n = it.GetNextChild()) { - if (n->IsElement()) { - AddPendingRestylesForDescendantsMatchingSelectors(n->AsElement(), - restyleRoot); - } - } - } - } return; } @@ -3229,44 +3077,6 @@ ElementRestyler::ComputeRestyleResultFromNewContext(nsIFrame* aSelf, return eRestyleResult_Stop; } -bool -ElementRestyler::SelectorMatchesForRestyle(Element* aElement) -{ - if (!aElement) { - return false; - } - for (nsCSSSelector* selector : mSelectorsForDescendants) { - if (nsCSSRuleProcessor::RestrictedSelectorMatches(aElement, selector, - mTreeMatchContext)) { - return true; - } - } - return false; -} - -bool -ElementRestyler::MustRestyleSelf(nsRestyleHint aRestyleHint, - Element* aElement) -{ - return (aRestyleHint & (eRestyle_Self | eRestyle_Subtree)) || - ((aRestyleHint & eRestyle_SomeDescendants) && - SelectorMatchesForRestyle(aElement)); -} - -bool -ElementRestyler::CanReparentStyleContext(nsRestyleHint aRestyleHint) -{ - // If we had any restyle hints other than the ones listed below, - // which don't control whether the current frame/element needs - // a new style context by looking up a new rule node, or if - // we are reconstructing the entire rule tree, then we can't - // use ReparentStyleContext. - return !(aRestyleHint & ~(eRestyle_Force | - eRestyle_ForceDescendants | - eRestyle_SomeDescendants)) && - !mPresContext->StyleSet()->IsInRuleTreeReconstruct(); -} - ElementRestyler::RestyleResult ElementRestyler::RestyleSelf(nsIFrame* aSelf, nsRestyleHint aRestyleHint, @@ -3290,7 +3100,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, RestyleResult result; - if (aRestyleHint & ~eRestyle_SomeDescendants) { + if (aRestyleHint) { result = eRestyleResult_Continue; } else { result = ComputeRestyleResultFromFrame(aSelf); @@ -3375,91 +3185,90 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, "non pseudo-element frame without content node"); newContext = styleSet->ResolveStyleForNonElement(parentContext); } + else if (!(aRestyleHint & (eRestyle_Self | eRestyle_Subtree))) { + Element* element = ElementForStyleContext(mParentContent, aSelf, pseudoType); + if (!(aRestyleHint & ~(eRestyle_Force | eRestyle_ForceDescendants)) && + !styleSet->IsInRuleTreeReconstruct()) { + LOG_RESTYLE("reparenting style context"); + newContext = + styleSet->ReparentStyleContext(oldContext, parentContext, element); + } else { + // Use ResolveStyleWithReplacement either for actual replacements + // or, with no replacements, as a substitute for + // ReparentStyleContext that rebuilds the path in the rule tree + // rather than reusing the rule node, as we need to do during a + // rule tree reconstruct. + Element* pseudoElement = PseudoElementForStyleContext(aSelf, pseudoType); + MOZ_ASSERT(!element || element != pseudoElement, + "pseudo-element for selector matching should be " + "the anonymous content node that we create, " + "not the real element"); + LOG_RESTYLE("resolving style with replacement"); + newContext = + styleSet->ResolveStyleWithReplacement(element, pseudoElement, + parentContext, oldContext, + aRestyleHint); + } + } else if (pseudoType == nsCSSPseudoElements::ePseudo_AnonBox) { + newContext = styleSet->ResolveAnonymousBoxStyle(pseudoTag, + parentContext); + } else { Element* element = ElementForStyleContext(mParentContent, aSelf, pseudoType); - if (!MustRestyleSelf(aRestyleHint, element)) { - if (CanReparentStyleContext(aRestyleHint)) { - LOG_RESTYLE("reparenting style context"); - newContext = - styleSet->ReparentStyleContext(oldContext, parentContext, element); + if (pseudoTag) { + if (pseudoTag == nsCSSPseudoElements::before || + pseudoTag == nsCSSPseudoElements::after) { + // XXX what other pseudos do we need to treat like this? + newContext = styleSet->ProbePseudoElementStyle(element, + pseudoType, + parentContext, + mTreeMatchContext); + if (!newContext) { + // This pseudo should no longer exist; gotta reframe + NS_UpdateHint(mHintsHandled, nsChangeHint_ReconstructFrame); + mChangeList->AppendChange(aSelf, element, + nsChangeHint_ReconstructFrame); + // We're reframing anyway; just keep the same context + newContext = oldContext; +#ifdef DEBUG + // oldContext's parent might have had its style structs swapped out + // with parentContext, so to avoid any assertions that might + // otherwise trigger in oldContext's parent's destructor, we set a + // flag on oldContext to skip it and its descendants in + // nsStyleContext::AssertStructsNotUsedElsewhere. + if (oldContext->GetParent() != parentContext) { + oldContext->AddStyleBit(NS_STYLE_IS_GOING_AWAY); + } +#endif + } } else { - // Use ResolveStyleWithReplacement either for actual replacements - // or, with no replacements, as a substitute for - // ReparentStyleContext that rebuilds the path in the rule tree - // rather than reusing the rule node, as we need to do during a - // rule tree reconstruct. - Element* pseudoElement = PseudoElementForStyleContext(aSelf, pseudoType); - MOZ_ASSERT(!element || element != pseudoElement, + // Don't expect XUL tree stuff here, since it needs a comparator and + // all. + NS_ASSERTION(pseudoType < + nsCSSPseudoElements::ePseudo_PseudoElementCount, + "Unexpected pseudo type"); + Element* pseudoElement = + PseudoElementForStyleContext(aSelf, pseudoType); + MOZ_ASSERT(element != pseudoElement, "pseudo-element for selector matching should be " "the anonymous content node that we create, " "not the real element"); - LOG_RESTYLE("resolving style with replacement"); - nsRestyleHint rshint = aRestyleHint & ~eRestyle_SomeDescendants; - newContext = - styleSet->ResolveStyleWithReplacement(element, pseudoElement, - parentContext, oldContext, - rshint); - } - } else if (pseudoType == nsCSSPseudoElements::ePseudo_AnonBox) { - newContext = styleSet->ResolveAnonymousBoxStyle(pseudoTag, - parentContext); - } - else { - if (pseudoTag) { - if (pseudoTag == nsCSSPseudoElements::before || - pseudoTag == nsCSSPseudoElements::after) { - // XXX what other pseudos do we need to treat like this? - newContext = styleSet->ProbePseudoElementStyle(element, + newContext = styleSet->ResolvePseudoElementStyle(element, pseudoType, parentContext, - mTreeMatchContext); - if (!newContext) { - // This pseudo should no longer exist; gotta reframe - NS_UpdateHint(mHintsHandled, nsChangeHint_ReconstructFrame); - mChangeList->AppendChange(aSelf, element, - nsChangeHint_ReconstructFrame); - // We're reframing anyway; just keep the same context - newContext = oldContext; -#ifdef DEBUG - // oldContext's parent might have had its style structs swapped out - // with parentContext, so to avoid any assertions that might - // otherwise trigger in oldContext's parent's destructor, we set a - // flag on oldContext to skip it and its descendants in - // nsStyleContext::AssertStructsNotUsedElsewhere. - if (oldContext->GetParent() != parentContext) { - oldContext->AddStyleBit(NS_STYLE_IS_GOING_AWAY); - } -#endif - } - } else { - // Don't expect XUL tree stuff here, since it needs a comparator and - // all. - NS_ASSERTION(pseudoType < - nsCSSPseudoElements::ePseudo_PseudoElementCount, - "Unexpected pseudo type"); - Element* pseudoElement = - PseudoElementForStyleContext(aSelf, pseudoType); - MOZ_ASSERT(element != pseudoElement, - "pseudo-element for selector matching should be " - "the anonymous content node that we create, " - "not the real element"); - newContext = styleSet->ResolvePseudoElementStyle(element, - pseudoType, - parentContext, - pseudoElement); - } - } - else { - NS_ASSERTION(aSelf->GetContent(), - "non pseudo-element frame without content node"); - // Skip parent display based style fixup for anonymous subtrees: - TreeMatchContext::AutoParentDisplayBasedStyleFixupSkipper - parentDisplayBasedFixupSkipper(mTreeMatchContext, - element->IsRootOfNativeAnonymousSubtree()); - newContext = styleSet->ResolveStyleFor(element, parentContext, - mTreeMatchContext); + pseudoElement); } } + else { + NS_ASSERTION(aSelf->GetContent(), + "non pseudo-element frame without content node"); + // Skip parent display based style fixup for anonymous subtrees: + TreeMatchContext::AutoParentDisplayBasedStyleFixupSkipper + parentDisplayBasedFixupSkipper(mTreeMatchContext, + element->IsRootOfNativeAnonymousSubtree()); + newContext = styleSet->ResolveStyleFor(element, parentContext, + mTreeMatchContext); + } } MOZ_ASSERT(newContext); @@ -3648,13 +3457,10 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, NS_ASSERTION(extraPseudoTag && extraPseudoTag != nsCSSAnonBoxes::mozNonElement, "extra style context is not pseudo element"); - Element* element = extraPseudoType != nsCSSPseudoElements::ePseudo_AnonBox - ? mContent->AsElement() : nullptr; - if (!MustRestyleSelf(aRestyleHint, element)) { - if (CanReparentStyleContext(aRestyleHint)) { - newExtraContext = - styleSet->ReparentStyleContext(oldExtraContext, newContext, element); - } else { + if (!(aRestyleHint & (eRestyle_Self | eRestyle_Subtree))) { + Element* element = extraPseudoType != nsCSSPseudoElements::ePseudo_AnonBox + ? mContent->AsElement() : nullptr; + if (styleSet->IsInRuleTreeReconstruct()) { // Use ResolveStyleWithReplacement as a substitute for // ReparentStyleContext that rebuilds the path in the rule tree // rather than reusing the rule node, as we need to do during a @@ -3669,6 +3475,9 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf, styleSet->ResolveStyleWithReplacement(element, pseudoElement, newContext, oldExtraContext, nsRestyleHint(0)); + } else { + newExtraContext = + styleSet->ReparentStyleContext(oldExtraContext, newContext, element); } } else if (extraPseudoType == nsCSSPseudoElements::ePseudo_AnonBox) { newExtraContext = styleSet->ResolveAnonymousBoxStyle(extraPseudoTag, @@ -3777,12 +3586,11 @@ ElementRestyler::RestyleChildren(nsRestyleHint aChildRestyleHint) void ElementRestyler::RestyleChildrenOfDisplayContentsElement( - nsIFrame* aParentFrame, - nsStyleContext* aNewContext, - nsChangeHint aMinHint, - RestyleTracker& aRestyleTracker, - nsRestyleHint aRestyleHint, - const RestyleHintData& aRestyleHintData) + nsIFrame* aParentFrame, + nsStyleContext* aNewContext, + nsChangeHint aMinHint, + RestyleTracker& aRestyleTracker, + nsRestyleHint aRestyleHint) { MOZ_ASSERT(!(mHintsHandled & nsChangeHint_ReconstructFrame), "why call me?"); @@ -3811,8 +3619,8 @@ ElementRestyler::RestyleChildrenOfDisplayContentsElement( !f->GetPrevContinuation()) { if (!(f->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) { ComputeStyleChangeFor(f, mChangeList, aMinHint, aRestyleTracker, - aRestyleHint, aRestyleHintData, - mContextsToClear, mSwappedStructOwners); + aRestyleHint, mContextsToClear, + mSwappedStructOwners); } } } @@ -3829,7 +3637,6 @@ ElementRestyler::ComputeStyleChangeFor(nsIFrame* aFrame, nsChangeHint aMinChange, RestyleTracker& aRestyleTracker, nsRestyleHint aRestyleHint, - const RestyleHintData& aRestyleHintData, nsTArray& aContextsToClear, nsTArray>& @@ -3877,9 +3684,6 @@ ElementRestyler::ComputeStyleChangeFor(nsIFrame* aFrame, Element* parent = content ? content->GetParentElementCrossingShadowRoot() : nullptr; treeMatchContext.InitAncestors(parent); - nsTArray selectorsForDescendants; - selectorsForDescendants.AppendElements( - aRestyleHintData.mSelectorsForDescendants); nsTArray visibleKidsOfHiddenElement; for (nsIFrame* ibSibling = aFrame; ibSibling; ibSibling = GetNextBlockInInlineSibling(propTable, ibSibling)) { @@ -3894,7 +3698,6 @@ ElementRestyler::ComputeStyleChangeFor(nsIFrame* aFrame, // Inner loop over next-in-flows of the current frame ElementRestyler restyler(presContext, cont, aChangeList, aMinChange, aRestyleTracker, - selectorsForDescendants, treeMatchContext, visibleKidsOfHiddenElement, aContextsToClear, aSwappedStructOwners); @@ -3993,25 +3796,21 @@ ElementRestyler::RestyleUndisplayedNodes(nsRestyleHint aChildRestyleHint, } nsRefPtr undisplayedContext; nsStyleSet* styleSet = mPresContext->StyleSet(); - if (MustRestyleSelf(thisChildHint, element)) { + if (thisChildHint & (eRestyle_Self | eRestyle_Subtree)) { undisplayedContext = styleSet->ResolveStyleFor(element, aParentContext, mTreeMatchContext); } else if (thisChildHint || styleSet->IsInRuleTreeReconstruct()) { - // XXX Should the above condition ignore eRestyle_Force(Descendants) - // like the corresponding check in RestyleSelf? - // Use ResolveStyleWithReplacement either for actual // replacements, or as a substitute for ReparentStyleContext // that rebuilds the path in the rule tree rather than reusing // the rule node, as we need to do during a rule tree // reconstruct. - nsRestyleHint rshint = thisChildHint & ~eRestyle_SomeDescendants; undisplayedContext = styleSet->ResolveStyleWithReplacement(element, nullptr, aParentContext, undisplayed->mStyle, - rshint); + thisChildHint); } else { undisplayedContext = styleSet->ReparentStyleContext(undisplayed->mStyle, @@ -4291,11 +4090,10 @@ ClearCachedInheritedStyleDataOnDescendants( } void -RestyleManager::ComputeAndProcessStyleChange(nsIFrame* aFrame, - nsChangeHint aMinChange, - RestyleTracker& aRestyleTracker, - nsRestyleHint aRestyleHint, - const RestyleHintData& aRestyleHintData) +RestyleManager::ComputeAndProcessStyleChange(nsIFrame* aFrame, + nsChangeHint aMinChange, + RestyleTracker& aRestyleTracker, + nsRestyleHint aRestyleHint) { MOZ_ASSERT(mReframingStyleContexts, "should have rsc"); nsStyleChangeList changeList; @@ -4307,19 +4105,17 @@ RestyleManager::ComputeAndProcessStyleChange(nsIFrame* aFrame, nsTArray> swappedStructOwners; ElementRestyler::ComputeStyleChangeFor(aFrame, &changeList, aMinChange, aRestyleTracker, aRestyleHint, - aRestyleHintData, contextsToClear, swappedStructOwners); ProcessRestyledFrames(changeList); ClearCachedInheritedStyleDataOnDescendants(contextsToClear); } void -RestyleManager::ComputeAndProcessStyleChange(nsStyleContext* aNewContext, - Element* aElement, - nsChangeHint aMinChange, - RestyleTracker& aRestyleTracker, - nsRestyleHint aRestyleHint, - const RestyleHintData& aRestyleHintData) +RestyleManager::ComputeAndProcessStyleChange(nsStyleContext* aNewContext, + Element* aElement, + nsChangeHint aMinChange, + RestyleTracker& aRestyleTracker, + nsRestyleHint aRestyleHint) { MOZ_ASSERT(mReframingStyleContexts, "should have rsc"); MOZ_ASSERT(aNewContext->StyleDisplay()->mDisplay == NS_STYLE_DISPLAY_CONTENTS); @@ -4333,8 +4129,6 @@ RestyleManager::ComputeAndProcessStyleChange(nsStyleContext* aNewContext, Element* parentElement = parent && parent->IsElement() ? parent->AsElement() : nullptr; treeMatchContext.InitAncestors(parentElement); - - nsTArray selectorsForDescendants; nsTArray visibleKidsOfHiddenElement; nsTArray contextsToClear; @@ -4344,12 +4138,11 @@ RestyleManager::ComputeAndProcessStyleChange(nsStyleContext* aNewContext, nsTArray> swappedStructOwners; nsStyleChangeList changeList; ElementRestyler r(frame->PresContext(), aElement, &changeList, aMinChange, - aRestyleTracker, selectorsForDescendants, treeMatchContext, + aRestyleTracker, treeMatchContext, visibleKidsOfHiddenElement, contextsToClear, swappedStructOwners); r.RestyleChildrenOfDisplayContentsElement(frame, aNewContext, aMinChange, - aRestyleTracker, - aRestyleHint, aRestyleHintData); + aRestyleTracker, aRestyleHint); ProcessRestyledFrames(changeList); ClearCachedInheritedStyleDataOnDescendants(contextsToClear); } @@ -4430,11 +4223,9 @@ RestyleManager::RestyleHintToString(nsRestyleHint aHint) { nsCString result; bool any = false; - const char* names[] = { - "Self", "SomeDescendants", "Subtree", "LaterSiblings", "CSSTransitions", - "CSSAnimations", "SVGAttrAnimations", "StyleAttribute", - "StyleAttribute_Animations", "Force", "ForceDescendants" - }; + const char* names[] = { "Self", "Subtree", "LaterSiblings", "CSSTransitions", + "CSSAnimations", "SVGAttrAnimations", "StyleAttribute", + "StyleAttribute_Animations", "Force", "ForceDescendants" }; uint32_t hint = aHint & ((1 << ArrayLength(names)) - 1); uint32_t rest = aHint & ~((1 << ArrayLength(names)) - 1); for (uint32_t i = 0; i < ArrayLength(names); i++) { diff --git a/layout/base/RestyleManager.h b/layout/base/RestyleManager.h index 8bcca702b7de..a83e43e062ed 100644 --- a/layout/base/RestyleManager.h +++ b/layout/base/RestyleManager.h @@ -127,24 +127,18 @@ public: */ nsresult ReparentStyleContext(nsIFrame* aFrame); - void ClearSelectors() { - mPendingRestyles.ClearSelectors(); - } - private: // Used when restyling an element with a frame. - void ComputeAndProcessStyleChange(nsIFrame* aFrame, - nsChangeHint aMinChange, - RestyleTracker& aRestyleTracker, - nsRestyleHint aRestyleHint, - const RestyleHintData& aRestyleHintData); + void ComputeAndProcessStyleChange(nsIFrame* aFrame, + nsChangeHint aMinChange, + RestyleTracker& aRestyleTracker, + nsRestyleHint aRestyleHint); // Used when restyling a display:contents element. - void ComputeAndProcessStyleChange(nsStyleContext* aNewContext, - Element* aElement, - nsChangeHint aMinChange, - RestyleTracker& aRestyleTracker, - nsRestyleHint aRestyleHint, - const RestyleHintData& aRestyleHintData); + void ComputeAndProcessStyleChange(nsStyleContext* aNewContext, + Element* aElement, + nsChangeHint aMinChange, + RestyleTracker& aRestyleTracker, + nsRestyleHint aRestyleHint); public: @@ -341,12 +335,10 @@ public: * on them. * @param aMinChangeHint: A minimum change hint for aContent and its * descendants. - * @param aRestyleHintData: Additional data to go with aRestyleHint. */ void PostRestyleEvent(Element* aElement, nsRestyleHint aRestyleHint, - nsChangeHint aMinChangeHint, - const RestyleHintData* aRestyleHintData = nullptr); + nsChangeHint aMinChangeHint); void PostRestyleEventForLazyConstruction() { @@ -431,8 +423,7 @@ private: nsIFrame* aPrimaryFrame, nsChangeHint aMinHint, RestyleTracker& aRestyleTracker, - nsRestyleHint aRestyleHint, - const RestyleHintData& aRestyleHintData); + nsRestyleHint aRestyleHint); void StartRebuildAllStyleData(RestyleTracker& aRestyleTracker); void FinishRebuildAllStyleData(); @@ -523,7 +514,6 @@ public: nsStyleChangeList* aChangeList, nsChangeHint aHintsHandledByAncestors, RestyleTracker& aRestyleTracker, - nsTArray& aSelectorsForDescendants, TreeMatchContext& aTreeMatchContext, nsTArray& aVisibleKidsOfHiddenElement, nsTArray& aContextsToClear, @@ -554,7 +544,6 @@ public: nsStyleChangeList* aChangeList, nsChangeHint aHintsHandledByAncestors, RestyleTracker& aRestyleTracker, - nsTArray& aSelectorsForDescendants, TreeMatchContext& aTreeMatchContext, nsTArray& aVisibleKidsOfHiddenElement, nsTArray& aContextsToClear, @@ -588,9 +577,7 @@ public: nsStyleContext* aNewContext, nsChangeHint aMinHint, RestyleTracker& aRestyleTracker, - nsRestyleHint aRestyleHint, - const RestyleHintData& - aRestyleHintData); + nsRestyleHint aRestyleHint); /** * Re-resolve the style contexts for a frame tree, building aChangeList @@ -601,7 +588,6 @@ public: nsChangeHint aMinChange, RestyleTracker& aRestyleTracker, nsRestyleHint aRestyleHint, - const RestyleHintData& aRestyleHintData, nsTArray& aContextsToClear, nsTArray>& aSwappedStructOwners); @@ -644,31 +630,6 @@ private: */ void RestyleChildren(nsRestyleHint aChildRestyleHint); - /** - * Returns true iff a selector in mSelectorsForDescendants matches aElement. - * This is called when processing a eRestyle_SomeDescendants restyle hint. - */ - bool SelectorMatchesForRestyle(Element* aElement); - - /** - * Returns true iff aRestyleHint indicates that we should be restyling. - * Specifically, this will return true when eRestyle_Self or - * eRestyle_Subtree is present, or if eRestyle_SomeDescendants is - * present and the specified element matches one of the selectors in - * mSelectorsForDescendants. - */ - bool MustRestyleSelf(nsRestyleHint aRestyleHint, Element* aElement); - - /** - * Returns true iff aRestyleHint indicates that we can call - * ReparentStyleContext rather than any other restyling method of - * nsStyleSet that looks up a new rule node, and if we are - * not in the process of reconstructing the whole rule tree. - * This is used to check whether it is appropriate to call - * ReparentStyleContext. - */ - bool CanReparentStyleContext(nsRestyleHint aRestyleHint); - /** * Helpers for Restyle(). */ @@ -729,9 +690,6 @@ private: eNotifyHidden }; - void AddPendingRestylesForDescendantsMatchingSelectors(Element* aElement, - Element* aRestyleRoot); - #ifdef RESTYLE_LOGGING int32_t& LoggingDepth() { return mLoggingDepth; } #endif @@ -759,7 +717,6 @@ private: nsChangeHint mParentFrameHintsNotHandledForDescendants; nsChangeHint mHintsNotHandledForDescendants; RestyleTracker& mRestyleTracker; - nsTArray& mSelectorsForDescendants; TreeMatchContext& mTreeMatchContext; nsIFrame* mResolvedChild; // child that provides our parent style context // Array of style context subtrees in which we need to clear out cached diff --git a/layout/base/RestyleTracker.cpp b/layout/base/RestyleTracker.cpp index d6e14de28eef..466dfd5f7422 100644 --- a/layout/base/RestyleTracker.cpp +++ b/layout/base/RestyleTracker.cpp @@ -169,9 +169,6 @@ CollectRestyles(nsISupports* aElement, currentRestyle->mElement = element; currentRestyle->mRestyleHint = aData->mRestyleHint; currentRestyle->mChangeHint = aData->mChangeHint; - // We can move aData since we'll be clearing mPendingRestyles after - // we finish enumerating it. - currentRestyle->mRestyleHintData = Move(aData->mRestyleHintData); #if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API) currentRestyle->mBacktrace = Move(aData->mBacktrace); #endif @@ -189,8 +186,7 @@ CollectRestyles(nsISupports* aElement, inline void RestyleTracker::ProcessOneRestyle(Element* aElement, nsRestyleHint aRestyleHint, - nsChangeHint aChangeHint, - const RestyleHintData& aRestyleHintData) + nsChangeHint aChangeHint) { NS_PRECONDITION((aRestyleHint & eRestyle_LaterSiblings) == 0, "Someone should have handled this before calling us"); @@ -215,7 +211,7 @@ RestyleTracker::ProcessOneRestyle(Element* aElement, } #endif mRestyleManager->RestyleElement(aElement, primaryFrame, aChangeHint, - *this, aRestyleHint, aRestyleHintData); + *this, aRestyleHint); } else if (aChangeHint && (primaryFrame || (aChangeHint & nsChangeHint_ReconstructFrame))) { @@ -371,8 +367,7 @@ RestyleTracker::DoProcessRestyles() profilerRAII.emplace("Paint", "Styles", Move(data->mBacktrace)); } #endif - ProcessOneRestyle(element, data->mRestyleHint, data->mChangeHint, - data->mRestyleHintData); + ProcessOneRestyle(element, data->mRestyleHint, data->mChangeHint); AddRestyleRootsIfAwaitingRestyle(data->mDescendants); if (isTimelineRecording) { @@ -432,8 +427,7 @@ RestyleTracker::DoProcessRestyles() ProcessOneRestyle(currentRestyle->mElement, currentRestyle->mRestyleHint, - currentRestyle->mChangeHint, - currentRestyle->mRestyleHintData); + currentRestyle->mChangeHint); if (isTimelineRecording) { mozilla::UniquePtr marker = @@ -447,9 +441,6 @@ RestyleTracker::DoProcessRestyles() } } - // mPendingRestyles is now empty. - mHaveSelectors = false; - mRestyleManager->EndProcessingRestyles(); } @@ -515,23 +506,4 @@ RestyleTracker::AddRestyleRootsIfAwaitingRestyle( } } -void -RestyleTracker::ClearSelectors() -{ - if (!mHaveSelectors) { - return; - } - for (auto it = mPendingRestyles.Iter(); !it.Done(); it.Next()) { - RestyleData* data = it.Data(); - if (data->mRestyleHint & eRestyle_SomeDescendants) { - data->mRestyleHint = - (data->mRestyleHint & ~eRestyle_SomeDescendants) | eRestyle_Subtree; - data->mRestyleHintData.mSelectorsForDescendants.Clear(); - } else { - MOZ_ASSERT(data->mRestyleHintData.mSelectorsForDescendants.IsEmpty()); - } - } - mHaveSelectors = false; -} - } // namespace mozilla diff --git a/layout/base/RestyleTracker.h b/layout/base/RestyleTracker.h index fa8805d9a011..3512181dc89e 100644 --- a/layout/base/RestyleTracker.h +++ b/layout/base/RestyleTracker.h @@ -17,7 +17,6 @@ #include "mozilla/SplayTree.h" #include "mozilla/RestyleLogging.h" #include "GeckoProfiler.h" -#include "mozilla/Maybe.h" #if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API) #include "ProfilerBacktrace.h" @@ -231,7 +230,6 @@ public: explicit RestyleTracker(Element::FlagsType aRestyleBits) : mRestyleBits(aRestyleBits) , mHaveLaterSiblingRestyles(false) - , mHaveSelectors(false) { NS_PRECONDITION((mRestyleBits & ~ELEMENT_ALL_RESTYLE_FLAGS) == 0, "Why do we have these bits set?"); @@ -258,19 +256,9 @@ public: /** * Add a restyle for the given element to the tracker. Returns true * if the element already had eRestyle_LaterSiblings set on it. - * - * aRestyleRoot is the closest restyle root for aElement. If the caller - * does not know what the closest restyle root is, Nothing should be - * passed. A Some(nullptr) restyle root can be passed if there is no - * ancestor element that is a restyle root. */ bool AddPendingRestyle(Element* aElement, nsRestyleHint aRestyleHint, - nsChangeHint aMinChangeHint, - const RestyleHintData* aRestyleHintData = nullptr, - mozilla::Maybe aRestyleRoot = - mozilla::Nothing()); - - Element* FindClosestRestyleRoot(Element* aElement); + nsChangeHint aMinChangeHint); /** * Process the restyles we've been tracking. @@ -288,9 +276,8 @@ public: } struct Hints { - nsRestyleHint mRestyleHint; // What we want to restyle - nsChangeHint mChangeHint; // The minimal change hint for "self" - RestyleHintData mRestyleHintData; // Data associated with mRestyleHint + nsRestyleHint mRestyleHint; // What we want to restyle + nsChangeHint mChangeHint; // The minimal change hint for "self" }; struct RestyleData : Hints { @@ -299,13 +286,9 @@ public: mChangeHint = NS_STYLE_HINT_NONE; } - RestyleData(nsRestyleHint aRestyleHint, nsChangeHint aChangeHint, - const RestyleHintData* aRestyleHintData) { + RestyleData(nsRestyleHint aRestyleHint, nsChangeHint aChangeHint) { mRestyleHint = aRestyleHint; mChangeHint = aChangeHint; - if (aRestyleHintData) { - mRestyleHintData = *aRestyleHintData; - } } // Descendant elements we must check that we ended up restyling, ordered @@ -330,14 +313,6 @@ public: */ bool GetRestyleData(Element* aElement, nsAutoPtr& aData); - /** - * Returns whether there is a RestyleData entry in mPendingRestyles - * for the given element. - */ - bool HasRestyleData(Element* aElement) { - return mPendingRestyles.Contains(aElement); - } - /** * For each element in aElements, appends it to mRestyleRoots if it * has its restyle bit set. This is used to ensure we restyle elements @@ -353,14 +328,6 @@ public: void AddRestyleRootsIfAwaitingRestyle( const nsTArray>& aElements); - /** - * Converts any eRestyle_SomeDescendants restyle hints in the pending restyle - * table into eRestyle_Subtree hints and clears out the associated arrays of - * nsCSSSelector pointers. This is called in response to a style sheet change - * that might have cause an nsCSSSelector to be destroyed. - */ - void ClearSelectors(); - /** * The document we're associated with. */ @@ -374,8 +341,7 @@ public: private: bool AddPendingRestyleToTable(Element* aElement, nsRestyleHint aRestyleHint, - nsChangeHint aMinChangeHint, - const RestyleHintData* aRestyleHintData = nullptr); + nsChangeHint aMinChangeHint); /** * Handle a single mPendingRestyles entry. aRestyleHint must not @@ -384,8 +350,7 @@ private: */ inline void ProcessOneRestyle(Element* aElement, nsRestyleHint aRestyleHint, - nsChangeHint aChangeHint, - const RestyleHintData& aRestyleHintData); + nsChangeHint aChangeHint); typedef nsClassHashtable PendingRestyleTable; typedef nsAutoTArray< nsRefPtr, 32> RestyleRootArray; @@ -411,24 +376,15 @@ private: // flag. We need this to avoid enumerating the hashtable looking // for such entries when we can't possibly have any. bool mHaveLaterSiblingRestyles; - // True if we have some entries with selectors in the restyle hint data. - // We use this to skip iterating over mPendingRestyles in ClearSelectors. - bool mHaveSelectors; }; inline bool RestyleTracker::AddPendingRestyleToTable(Element* aElement, nsRestyleHint aRestyleHint, - nsChangeHint aMinChangeHint, - const RestyleHintData* aRestyleHintData) + nsChangeHint aMinChangeHint) { RestyleData* existingData; - if (aRestyleHintData && - !aRestyleHintData->mSelectorsForDescendants.IsEmpty()) { - mHaveSelectors = true; - } - // Check the RestyleBit() flag before doing the hashtable Get, since // it's possible that the data in the hashtable isn't actually // relevant anymore (if the flag is not set). @@ -440,8 +396,7 @@ RestyleTracker::AddPendingRestyleToTable(Element* aElement, } if (!existingData) { - RestyleData* rd = - new RestyleData(aRestyleHint, aMinChangeHint, aRestyleHintData); + RestyleData* rd = new RestyleData(aRestyleHint, aMinChangeHint); #if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API) if (profiler_feature_active("restyle")) { rd->mBacktrace.reset(profiler_get_backtrace()); @@ -456,63 +411,46 @@ RestyleTracker::AddPendingRestyleToTable(Element* aElement, existingData->mRestyleHint = nsRestyleHint(existingData->mRestyleHint | aRestyleHint); NS_UpdateHint(existingData->mChangeHint, aMinChangeHint); - if (aRestyleHintData) { - existingData->mRestyleHintData.mSelectorsForDescendants - .AppendElements(aRestyleHintData->mSelectorsForDescendants); - } return hadRestyleLaterSiblings; } -inline mozilla::dom::Element* -RestyleTracker::FindClosestRestyleRoot(Element* aElement) -{ - Element* cur = aElement; - while (!cur->HasFlag(RootBit())) { - nsIContent* parent = cur->GetFlattenedTreeParent(); - // Stop if we have no parent or the parent is not an element or - // we're part of the viewport scrollbars (because those are not - // frametree descendants of the primary frame of the root - // element). - // XXXbz maybe the primary frame of the root should be the root scrollframe? - if (!parent || !parent->IsElement() || - // If we've hit the root via a native anonymous kid and that - // this native anonymous kid is not obviously a descendant - // of the root's primary frame, assume we're under the root - // scrollbars. Since those don't get reresolved when - // reresolving the root, we need to make sure to add the - // element to mRestyleRoots. - (cur->IsInNativeAnonymousSubtree() && !parent->GetParent() && - cur->GetPrimaryFrame() && - cur->GetPrimaryFrame()->GetParent() != parent->GetPrimaryFrame())) { - return nullptr; - } - cur = parent->AsElement(); - } - return cur; -} - inline bool RestyleTracker::AddPendingRestyle(Element* aElement, nsRestyleHint aRestyleHint, - nsChangeHint aMinChangeHint, - const RestyleHintData* aRestyleHintData, - mozilla::Maybe aRestyleRoot) + nsChangeHint aMinChangeHint) { bool hadRestyleLaterSiblings = - AddPendingRestyleToTable(aElement, aRestyleHint, aMinChangeHint, - aRestyleHintData); + AddPendingRestyleToTable(aElement, aRestyleHint, aMinChangeHint); // We can only treat this element as a restyle root if we would // actually restyle its descendants (so either call // ReResolveStyleContext on it or just reframe it). if ((aRestyleHint & ~eRestyle_LaterSiblings) || (aMinChangeHint & nsChangeHint_ReconstructFrame)) { - Element* cur = - aRestyleRoot ? *aRestyleRoot : FindClosestRestyleRoot(aElement); - if (!cur) { - mRestyleRoots.AppendElement(aElement); - cur = aElement; + Element* cur = aElement; + while (!cur->HasFlag(RootBit())) { + nsIContent* parent = cur->GetFlattenedTreeParent(); + // Stop if we have no parent or the parent is not an element or + // we're part of the viewport scrollbars (because those are not + // frametree descendants of the primary frame of the root + // element). + // XXXbz maybe the primary frame of the root should be the root scrollframe? + if (!parent || !parent->IsElement() || + // If we've hit the root via a native anonymous kid and that + // this native anonymous kid is not obviously a descendant + // of the root's primary frame, assume we're under the root + // scrollbars. Since those don't get reresolved when + // reresolving the root, we need to make sure to add the + // element to mRestyleRoots. + (cur->IsInNativeAnonymousSubtree() && !parent->GetParent() && + cur->GetPrimaryFrame() && + cur->GetPrimaryFrame()->GetParent() != parent->GetPrimaryFrame())) { + mRestyleRoots.AppendElement(aElement); + cur = aElement; + break; + } + cur = parent->AsElement(); } // At this point some ancestor of aElement (possibly aElement // itself) is in mRestyleRoots. Set the root bit on aElement, to diff --git a/layout/base/nsChangeHint.h b/layout/base/nsChangeHint.h index 14b7fc7a4b22..789dd8d403f1 100644 --- a/layout/base/nsChangeHint.h +++ b/layout/base/nsChangeHint.h @@ -8,11 +8,8 @@ #ifndef nsChangeHint_h___ #define nsChangeHint_h___ -#include "mozilla/Types.h" #include "nsDebug.h" -#include "nsTArray.h" - -struct nsCSSSelector; +#include "mozilla/Types.h" // Defines for various style related constants @@ -380,40 +377,36 @@ enum nsRestyleHint { // work.) eRestyle_Self = (1<<0), - // Rerun selector matching on descendants of the element that match - // a given selector. - eRestyle_SomeDescendants = (1<<1), - // Rerun selector matching on the element and all of its descendants. // (Implies eRestyle_ForceDescendants, which ensures that we continue // the restyling process for all descendants, but doesn't cause // selector matching.) - eRestyle_Subtree = (1<<2), + eRestyle_Subtree = (1<<1), // Rerun selector matching on all later siblings of the element and // all of their descendants. - eRestyle_LaterSiblings = (1<<3), + eRestyle_LaterSiblings = (1<<2), // Replace the style data coming from CSS transitions without updating // any other style data. If a new style context results, update style // contexts on the descendants. (Irrelevant if eRestyle_Self or // eRestyle_Subtree is also set, since those imply a superset of the // work.) - eRestyle_CSSTransitions = (1<<4), + eRestyle_CSSTransitions = (1<<3), // Replace the style data coming from CSS animations without updating // any other style data. If a new style context results, update style // contexts on the descendants. (Irrelevant if eRestyle_Self or // eRestyle_Subtree is also set, since those imply a superset of the // work.) - eRestyle_CSSAnimations = (1<<5), + eRestyle_CSSAnimations = (1<<4), // Replace the style data coming from SVG animations (SMIL Animations) // without updating any other style data. If a new style context // results, update style contexts on the descendants. (Irrelevant if // eRestyle_Self or eRestyle_Subtree is also set, since those imply a // superset of the work.) - eRestyle_SVGAttrAnimations = (1<<6), + eRestyle_SVGAttrAnimations = (1<<5), // Replace the style data coming from inline style without updating // any other style data. If a new style context results, update style @@ -424,22 +417,22 @@ enum nsRestyleHint { // eRestyle_Self. // If the change is for the advance of a declarative animation, use // the value below instead. - eRestyle_StyleAttribute = (1<<7), + eRestyle_StyleAttribute = (1<<6), // Same as eRestyle_StyleAttribute, but for when the change results // from the advance of a declarative animation. - eRestyle_StyleAttribute_Animations = (1<<8), + eRestyle_StyleAttribute_Animations = (1<<7), // Continue the restyling process to the current frame's children even // if this frame's restyling resulted in no style changes. - eRestyle_Force = (1<<9), + eRestyle_Force = (1<<8), // Continue the restyling process to all of the current frame's // descendants, even if any frame's restyling resulted in no style // changes. (Implies eRestyle_Force.) Note that this is weaker than // eRestyle_Subtree, which makes us rerun selector matching on all // descendants rather than just continuing the restyling process. - eRestyle_ForceDescendants = (1<<10), + eRestyle_ForceDescendants = (1<<9), // Useful unions: eRestyle_AllHintsWithAnimations = eRestyle_CSSTransitions | @@ -490,19 +483,4 @@ inline nsRestyleHint operator^=(nsRestyleHint& aLeft, nsRestyleHint aRight) return aLeft = aLeft ^ aRight; } -namespace mozilla { - -/** - * Additional data used in conjunction with an nsRestyleHint to control the - * restyle process. - */ -struct RestyleHintData -{ - // When eRestyle_SomeDescendants is used, this array contains the selectors - // that identify which descendants will be restyled. - nsTArray mSelectorsForDescendants; -}; - -} // namespace mozilla - #endif /* nsChangeHint_h___ */ diff --git a/layout/style/AnimationCommon.cpp b/layout/style/AnimationCommon.cpp index 663f2b10c634..ebabe547b680 100644 --- a/layout/style/AnimationCommon.cpp +++ b/layout/style/AnimationCommon.cpp @@ -210,9 +210,7 @@ CommonAnimationManager::HasDocumentStateDependentStyle(StateRuleProcessorData* a } nsRestyleHint -CommonAnimationManager::HasAttributeDependentStyle( - AttributeRuleProcessorData* aData, - RestyleHintData& aRestyleHintDataResult) +CommonAnimationManager::HasAttributeDependentStyle(AttributeRuleProcessorData* aData) { return nsRestyleHint(0); } diff --git a/layout/style/AnimationCommon.h b/layout/style/AnimationCommon.h index eae9911b76f5..700ba4b04cb2 100644 --- a/layout/style/AnimationCommon.h +++ b/layout/style/AnimationCommon.h @@ -52,8 +52,7 @@ public: virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override; virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override; virtual nsRestyleHint - HasAttributeDependentStyle(AttributeRuleProcessorData* aData, - RestyleHintData& aRestyleHintDataResult) override; + HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override; virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override; virtual void RulesMatching(ElementRuleProcessorData* aData) override; virtual void RulesMatching(PseudoElementRuleProcessorData* aData) override; diff --git a/layout/style/CSSStyleSheet.cpp b/layout/style/CSSStyleSheet.cpp index 718de62b5d01..949823436cf4 100644 --- a/layout/style/CSSStyleSheet.cpp +++ b/layout/style/CSSStyleSheet.cpp @@ -1709,15 +1709,6 @@ CSSStyleSheet::List(FILE* out, int32_t aIndent) const void CSSStyleSheet::ClearRuleCascades() { - // We might be in ClearRuleCascades because we had a modification - // to the sheet that resulted in an nsCSSSelector being destroyed. - // Tell the RestyleManager for each document we're used in - // so that they can drop any nsCSSSelector pointers (used for - // eRestyle_SomeDescendants) in their mPendingRestyles. - for (nsStyleSet* styleSet : mStyleSets) { - styleSet->ClearSelectors(); - } - bool removedSheetFromRuleProcessorCache = false; if (mRuleProcessors) { nsCSSRuleProcessor **iter = mRuleProcessors->Elements(), diff --git a/layout/style/SVGAttrAnimationRuleProcessor.cpp b/layout/style/SVGAttrAnimationRuleProcessor.cpp index 9eb31b1b2334..3a1230f511e7 100644 --- a/layout/style/SVGAttrAnimationRuleProcessor.cpp +++ b/layout/style/SVGAttrAnimationRuleProcessor.cpp @@ -62,9 +62,7 @@ SVGAttrAnimationRuleProcessor::HasDocumentStateDependentStyle(StateRuleProcessor } /* virtual */ nsRestyleHint -SVGAttrAnimationRuleProcessor::HasAttributeDependentStyle( - AttributeRuleProcessorData* aData, - RestyleHintData& aRestyleHintDataResult) +SVGAttrAnimationRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData) { return nsRestyleHint(0); } diff --git a/layout/style/SVGAttrAnimationRuleProcessor.h b/layout/style/SVGAttrAnimationRuleProcessor.h index 1750c761bdc5..7a3fb6514486 100644 --- a/layout/style/SVGAttrAnimationRuleProcessor.h +++ b/layout/style/SVGAttrAnimationRuleProcessor.h @@ -44,8 +44,7 @@ public: virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override; virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override; virtual nsRestyleHint - HasAttributeDependentStyle(AttributeRuleProcessorData* aData, - RestyleHintData& aRestyleHintDataResult) override; + HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override; virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override; virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_MUST_OVERRIDE override; diff --git a/layout/style/StyleRule.cpp b/layout/style/StyleRule.cpp index c7ae9101074b..434b389c4037 100644 --- a/layout/style/StyleRule.cpp +++ b/layout/style/StyleRule.cpp @@ -559,7 +559,7 @@ nsCSSSelector::ToString(nsAString& aString, CSSStyleSheet* aSheet, const nsCSSSelector *s = stack.ElementAt(index); stack.RemoveElementAt(index); - s->AppendToStringWithoutCombinators(aString, aSheet, false); + s->AppendToStringWithoutCombinators(aString, aSheet); // Append the combinator, if needed. if (!stack.IsEmpty()) { @@ -583,85 +583,24 @@ nsCSSSelector::ToString(nsAString& aString, CSSStyleSheet* aSheet, } void -nsCSSSelector::AppendToStringWithoutCombinators( - nsAString& aString, - CSSStyleSheet* aSheet, - bool aUseStandardNamespacePrefixes) const +nsCSSSelector::AppendToStringWithoutCombinators + (nsAString& aString, CSSStyleSheet* aSheet) const { - AppendToStringWithoutCombinatorsOrNegations(aString, aSheet, false, - aUseStandardNamespacePrefixes); + AppendToStringWithoutCombinatorsOrNegations(aString, aSheet, false); for (const nsCSSSelector* negation = mNegations; negation; negation = negation->mNegations) { aString.AppendLiteral(":not("); - negation->AppendToStringWithoutCombinatorsOrNegations( - aString, aSheet, true, aUseStandardNamespacePrefixes); + negation->AppendToStringWithoutCombinatorsOrNegations(aString, aSheet, + true); aString.Append(char16_t(')')); } } -#ifdef DEBUG -nsCString -nsCSSSelector::RestrictedSelectorToString() const -{ - MOZ_ASSERT(IsRestrictedSelector()); - - nsString result; - AppendToStringWithoutCombinators(result, nullptr, true); - return NS_ConvertUTF16toUTF8(result); -} - -static bool -AppendStandardNamespacePrefixToString(nsAString& aString, int32_t aNameSpace) -{ - if (aNameSpace == kNameSpaceID_Unknown) { - // Wildcard namespace; no prefix to write. - return false; - } - switch (aNameSpace) { - case kNameSpaceID_None: - break; - case kNameSpaceID_XML: - aString.AppendLiteral("xml"); - break; - case kNameSpaceID_XHTML: - aString.AppendLiteral("html"); - break; - case kNameSpaceID_XLink: - aString.AppendLiteral("xlink"); - break; - case kNameSpaceID_XSLT: - aString.AppendLiteral("xsl"); - break; - case kNameSpaceID_XBL: - aString.AppendLiteral("xbl"); - break; - case kNameSpaceID_MathML: - aString.AppendLiteral("math"); - break; - case kNameSpaceID_RDF: - aString.AppendLiteral("rdf"); - break; - case kNameSpaceID_XUL: - aString.AppendLiteral("xul"); - break; - case kNameSpaceID_SVG: - aString.AppendLiteral("svg"); - break; - default: - aString.AppendLiteral("ns"); - aString.AppendInt(aNameSpace); - break; - } - return true; -} -#endif - void nsCSSSelector::AppendToStringWithoutCombinatorsOrNegations (nsAString& aString, CSSStyleSheet* aSheet, - bool aIsNegated, - bool aUseStandardNamespacePrefixes) const + bool aIsNegated) const { nsAutoString temp; bool isPseudoElement = IsPseudoElement(); @@ -677,18 +616,7 @@ nsCSSSelector::AppendToStringWithoutCombinatorsOrNegations // null, that means that the only namespaces we could have are the // wildcard namespace (which can be implicit in this case) and the "none" // namespace, which then needs to be explicitly specified. - if (aUseStandardNamespacePrefixes) { -#ifdef DEBUG - // We have no sheet to look up prefix information from. This is - // only for debugging, so use some "standard" prefixes that - // are recognizable. - wroteNamespace = - AppendStandardNamespacePrefixToString(aString, mNameSpace); - if (wroteNamespace) { - aString.Append(char16_t('|')); - } -#endif - } else if (!sheetNS) { + if (!sheetNS) { NS_ASSERTION(mNameSpace == kNameSpaceID_Unknown || mNameSpace == kNameSpaceID_None, "How did we get this namespace?"); @@ -812,12 +740,7 @@ nsCSSSelector::AppendToStringWithoutCombinatorsOrNegations aString.Append(char16_t('*')); aString.Append(char16_t('|')); } else if (list->mNameSpace != kNameSpaceID_None) { - if (aUseStandardNamespacePrefixes) { -#ifdef DEBUG - AppendStandardNamespacePrefixToString(aString, list->mNameSpace); - aString.Append(char16_t('|')); -#endif - } else if (aSheet) { + if (aSheet) { nsXMLNameSpaceMap *sheetNS = aSheet->GetNameSpaceMap(); nsIAtom *prefixAtom = sheetNS->FindPrefix(list->mNameSpace); // Default namespaces don't apply to attribute selectors, so diff --git a/layout/style/StyleRule.h b/layout/style/StyleRule.h index 057c16d661de..8ccc8f4efadc 100644 --- a/layout/style/StyleRule.h +++ b/layout/style/StyleRule.h @@ -159,27 +159,16 @@ public: void ToString(nsAString& aString, mozilla::CSSStyleSheet* aSheet, bool aAppend = false) const; - bool IsRestrictedSelector() const { - return PseudoType() == nsCSSPseudoElements::ePseudo_NotPseudoElement; - } - -#ifdef DEBUG - nsCString RestrictedSelectorToString() const; -#endif - private: void AddPseudoClassInternal(nsPseudoClassList *aPseudoClass); nsCSSSelector* Clone(bool aDeepNext, bool aDeepNegations) const; - void AppendToStringWithoutCombinators( - nsAString& aString, - mozilla::CSSStyleSheet* aSheet, - bool aUseStandardNamespacePrefixes) const; - void AppendToStringWithoutCombinatorsOrNegations( - nsAString& aString, - mozilla::CSSStyleSheet* aSheet, - bool aIsNegated, - bool aUseStandardNamespacePrefixes) const; + void AppendToStringWithoutCombinators(nsAString& aString, + mozilla::CSSStyleSheet* aSheet) const; + void AppendToStringWithoutCombinatorsOrNegations(nsAString& aString, + mozilla::CSSStyleSheet* aSheet, + bool aIsNegated) + const; // Returns true if this selector can have a namespace specified (which // happens if and only if the default namespace would apply to this // selector). diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index bf6dd8e1c52d..df015d61c7cd 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -783,39 +783,12 @@ RuleHash::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const //-------------------------------- -/** - * A struct that stores an nsCSSSelector pointer along side a pointer to - * the rightmost nsCSSSelector in the selector. For example, for - * - * .main p > span - * - * if mSelector points to the |p| nsCSSSelector, mRightmostSelector would - * point to the |span| nsCSSSelector. - * - * Both mSelector and mRightmostSelector are always top-level selectors, - * i.e. they aren't selectors within a :not() or :-moz-any(). - */ -struct SelectorPair -{ - SelectorPair(nsCSSSelector* aSelector, nsCSSSelector* aRightmostSelector) - : mSelector(aSelector), mRightmostSelector(aRightmostSelector) - { - MOZ_ASSERT(aSelector); - MOZ_ASSERT(mRightmostSelector); - } - SelectorPair(const SelectorPair& aOther) - : mSelector(aOther.mSelector) - , mRightmostSelector(aOther.mRightmostSelector) {} - nsCSSSelector* const mSelector; - nsCSSSelector* const mRightmostSelector; -}; - // A hash table mapping atoms to lists of selectors struct AtomSelectorEntry : public PLDHashEntryHdr { nsIAtom *mAtom; // Auto length 2, because a decent fraction of these arrays ends up // with 2 elements, and each entry is cheap. - nsAutoTArray mSelectors; + nsAutoTArray mSelectors; }; static void @@ -938,7 +911,7 @@ struct RuleCascadeData { // Looks up or creates the appropriate list in |mAttributeSelectors|. // Returns null only on allocation failure. - nsTArray* AttributeListFor(nsIAtom* aAttribute); + nsTArray* AttributeListFor(nsIAtom* aAttribute); nsMediaQueryResultCacheKey mCacheKey; RuleCascadeData* mNext; // for a different medium @@ -1002,7 +975,7 @@ RuleCascadeData::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const return n; } -nsTArray* +nsTArray* RuleCascadeData::AttributeListFor(nsIAtom* aAttribute) { AtomSelectorEntry *entry = @@ -2320,63 +2293,6 @@ static bool SelectorMatches(Element* aElement, #undef STATE_CHECK -#ifdef DEBUG -static bool -HasPseudoClassSelectorArgsWithCombinators(nsCSSSelector* aSelector) -{ - for (nsPseudoClassList* p = aSelector->mPseudoClassList; p; p = p->mNext) { - if (nsCSSPseudoClasses::HasSelectorListArg(p->mType)) { - for (nsCSSSelectorList* l = p->u.mSelectors; l; l = l->mNext) { - if (l->mSelectors->mNext) { - return true; - } - } - } - } - for (nsCSSSelector* n = aSelector->mNegations; n; n = n->mNegations) { - if (n->mNext) { - return true; - } - } - return false; -} -#endif - -/* static */ bool -nsCSSRuleProcessor::RestrictedSelectorMatches( - Element* aElement, - nsCSSSelector* aSelector, - TreeMatchContext& aTreeMatchContext) -{ - MOZ_ASSERT(aSelector->IsRestrictedSelector(), - "aSelector must not have a pseudo-element"); - - NS_WARN_IF_FALSE(!HasPseudoClassSelectorArgsWithCombinators(aSelector), - "processing eRestyle_SomeDescendants can be slow if " - "pseudo-classes with selector arguments can now have " - "combinators in them"); - - // We match aSelector as if :visited and :link both match visited and - // unvisited links. - - NodeMatchContext nodeContext(EventStates(), - nsCSSRuleProcessor::IsLink(aElement)); - if (nodeContext.mIsRelevantLink) { - aTreeMatchContext.SetHaveRelevantLink(); - } - aTreeMatchContext.ResetForUnvisitedMatching(); - bool matches = SelectorMatches(aElement, aSelector, nodeContext, - aTreeMatchContext, SelectorMatchesFlags::NONE); - if (nodeContext.mIsRelevantLink) { - aTreeMatchContext.ResetForVisitedMatching(); - if (SelectorMatches(aElement, aSelector, nodeContext, aTreeMatchContext, - SelectorMatchesFlags::NONE)) { - matches = true; - } - } - return matches; -} - // Right now, there are four operators: // ' ', the descendant combinator, is greedy // '~', the indirect adjacent sibling combinator, is greedy @@ -2781,81 +2697,16 @@ nsCSSRuleProcessor::HasDocumentStateDependentStyle(StateRuleProcessorData* aData } struct AttributeEnumData { - AttributeEnumData(AttributeRuleProcessorData *aData, - RestyleHintData& aRestyleHintData) - : data(aData), change(nsRestyleHint(0)), hintData(aRestyleHintData) {} + explicit AttributeEnumData(AttributeRuleProcessorData *aData) + : data(aData), change(nsRestyleHint(0)) {} AttributeRuleProcessorData *data; nsRestyleHint change; - RestyleHintData& hintData; }; -static inline nsRestyleHint -RestyleHintForSelectorWithAttributeChange(nsRestyleHint aCurrentHint, - nsCSSSelector* aSelector, - nsCSSSelector* aRightmostSelector) -{ - MOZ_ASSERT(aSelector); - - char16_t oper = aSelector->mOperator; - - if (oper == char16_t('+') || oper == char16_t('~')) { - return eRestyle_LaterSiblings; - } - - if (oper == char16_t(':')) { - return eRestyle_Subtree; - } - - if (oper != char16_t(0)) { - // Check whether the selector is in a form that supports - // eRestyle_SomeDescendants. If it isn't, return eRestyle_Subtree. - - if (aCurrentHint & eRestyle_Subtree) { - // No point checking, since we'll end up restyling the whole - // subtree anyway. - return eRestyle_Subtree; - } - - if (!aRightmostSelector) { - // aSelector wasn't a top-level selector, which means we were inside - // a :not() or :-moz-any(). We don't support that. - return eRestyle_Subtree; - } - - MOZ_ASSERT(aSelector != aRightmostSelector, - "if aSelector == aRightmostSelector then we should have " - "no operator"); - - // Check that aRightmostSelector can be passed to RestrictedSelectorMatches. - if (!aRightmostSelector->IsRestrictedSelector()) { - return eRestyle_Subtree; - } - - // We also don't support pseudo-elements on any of the selectors - // between aRightmostSelector and aSelector. - // XXX Can we lift this restriction, so that we don't have to loop - // over all the selectors? - for (nsCSSSelector* sel = aRightmostSelector->mNext; - sel != aSelector; - sel = sel->mNext) { - MOZ_ASSERT(sel, "aSelector must be reachable from aRightmostSelector"); - if (sel->PseudoType() != nsCSSPseudoElements::ePseudo_NotPseudoElement) { - return eRestyle_Subtree; - } - } - - return eRestyle_SomeDescendants; - } - - return eRestyle_Self; -} - static void -AttributeEnumFunc(nsCSSSelector* aSelector, - nsCSSSelector* aRightmostSelector, - AttributeEnumData* aData) +AttributeEnumFunc(nsCSSSelector* aSelector, AttributeEnumData* aData) { AttributeRuleProcessorData *data = aData->data; @@ -2866,36 +2717,18 @@ AttributeEnumFunc(nsCSSSelector* aSelector, return; } - nsRestyleHint possibleChange = - RestyleHintForSelectorWithAttributeChange(aData->change, - aSelector, aRightmostSelector); + nsRestyleHint possibleChange = RestyleHintForOp(aSelector->mOperator); - // If, ignoring eRestyle_SomeDescendants, enumData->change already includes - // all the bits of possibleChange, don't bother calling SelectorMatches, since - // even if it returns false enumData->change won't change. If possibleChange - // has eRestyle_SomeDescendants, we need to call SelectorMatches(Tree) - // regardless as it might give us new selectors to append to - // mSelectorsForDescendants. + // If enumData->change already includes all the bits of possibleChange, don't + // bother calling SelectorMatches, since even if it returns false + // enumData->change won't change. NodeMatchContext nodeContext(EventStates(), false); - if (((possibleChange & (~(aData->change) | eRestyle_SomeDescendants))) && + if ((possibleChange & ~(aData->change)) && SelectorMatches(data->mElement, aSelector, nodeContext, data->mTreeMatchContext, SelectorMatchesFlags::UNKNOWN) && SelectorMatchesTree(data->mElement, aSelector->mNext, data->mTreeMatchContext, false)) { aData->change = nsRestyleHint(aData->change | possibleChange); - if (possibleChange & eRestyle_SomeDescendants) { - aData->hintData.mSelectorsForDescendants.AppendElement(aRightmostSelector); - } - } -} - -static MOZ_ALWAYS_INLINE void -EnumerateSelectors(nsTArray& aSelectors, AttributeEnumData* aData) -{ - SelectorPair *iter = aSelectors.Elements(), - *end = iter + aSelectors.Length(); - for (; iter != end; ++iter) { - AttributeEnumFunc(iter->mSelector, iter->mRightmostSelector, aData); } } @@ -2905,19 +2738,17 @@ EnumerateSelectors(nsTArray& aSelectors, AttributeEnumData* aDat nsCSSSelector **iter = aSelectors.Elements(), **end = iter + aSelectors.Length(); for (; iter != end; ++iter) { - AttributeEnumFunc(*iter, nullptr, aData); + AttributeEnumFunc(*iter, aData); } } nsRestyleHint -nsCSSRuleProcessor::HasAttributeDependentStyle( - AttributeRuleProcessorData* aData, - RestyleHintData& aRestyleHintDataResult) +nsCSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData) { // We could try making use of aData->mModType, but :not rules make it a bit // of a pain to do so... So just ignore it for now. - AttributeEnumData data(aData, aRestyleHintDataResult); + AttributeEnumData data(aData); // Don't do our special handling of certain attributes if the attr // hasn't changed yet. @@ -3239,9 +3070,7 @@ AddSelector(RuleCascadeData* aCascade, // The part between combinators at the top level of the selector nsCSSSelector* aSelectorInTopLevel, // The part we should look through (might be in :not or :-moz-any()) - nsCSSSelector* aSelectorPart, - // The right-most selector at the top level - nsCSSSelector* aRightmostSelector) + nsCSSSelector* aSelectorPart) { // It's worth noting that this loop over negations isn't quite // optimal for two reasons. One, we could add something to one of @@ -3266,13 +3095,12 @@ AddSelector(RuleCascadeData* aCascade, break; } case nsCSSPseudoClasses::ePseudoClass_mozTableBorderNonzero: { - nsTArray *array = + nsTArray *array = aCascade->AttributeListFor(nsGkAtoms::border); if (!array) { return false; } - array->AppendElement(SelectorPair(aSelectorInTopLevel, - aRightmostSelector)); + array->AppendElement(aSelectorInTopLevel); break; } default: { @@ -3296,8 +3124,7 @@ AddSelector(RuleCascadeData* aCascade, AtomSelectorEntry *entry = static_cast (PL_DHashTableAdd(&aCascade->mIdSelectors, curID->mAtom, fallible)); if (entry) { - entry->mSelectors.AppendElement(SelectorPair(aSelectorInTopLevel, - aRightmostSelector)); + entry->mSelectors.AppendElement(aSelectorInTopLevel); } } } else if (negation->mIDList) { @@ -3312,8 +3139,7 @@ AddSelector(RuleCascadeData* aCascade, (PL_DHashTableAdd(&aCascade->mClassSelectors, curClass->mAtom, fallible)); if (entry) { - entry->mSelectors.AppendElement(SelectorPair(aSelectorInTopLevel, - aRightmostSelector)); + entry->mSelectors.AppendElement(aSelectorInTopLevel); } } } else if (negation->mClassList) { @@ -3323,20 +3149,18 @@ AddSelector(RuleCascadeData* aCascade, // Build mAttributeSelectors. for (nsAttrSelector *attr = negation->mAttrList; attr; attr = attr->mNext) { - nsTArray *array = + nsTArray *array = aCascade->AttributeListFor(attr->mCasedAttr); if (!array) { return false; } - array->AppendElement(SelectorPair(aSelectorInTopLevel, - aRightmostSelector)); + array->AppendElement(aSelectorInTopLevel); if (attr->mLowercaseAttr != attr->mCasedAttr) { array = aCascade->AttributeListFor(attr->mLowercaseAttr); if (!array) { return false; } - array->AppendElement(SelectorPair(aSelectorInTopLevel, - aRightmostSelector)); + array->AppendElement(aSelectorInTopLevel); } } @@ -3346,8 +3170,7 @@ AddSelector(RuleCascadeData* aCascade, if (pseudoClass->mType == nsCSSPseudoClasses::ePseudoClass_any) { for (nsCSSSelectorList *l = pseudoClass->u.mSelectors; l; l = l->mNext) { nsCSSSelector *s = l->mSelectors; - if (!AddSelector(aCascade, aSelectorInTopLevel, s, - aRightmostSelector)) { + if (!AddSelector(aCascade, aSelectorInTopLevel, s)) { return false; } } @@ -3428,7 +3251,7 @@ AddRule(RuleSelectorPair* aRuleInfo, RuleCascadeData* aCascade) continue; } } - if (!AddSelector(cascade, selector, selector, aRuleInfo->mSelector)) { + if (!AddSelector(cascade, selector, selector)) { return false; } } diff --git a/layout/style/nsCSSRuleProcessor.h b/layout/style/nsCSSRuleProcessor.h index 3fc709b284d3..93fa68656dbf 100644 --- a/layout/style/nsCSSRuleProcessor.h +++ b/layout/style/nsCSSRuleProcessor.h @@ -112,21 +112,6 @@ public: */ static bool IsLink(mozilla::dom::Element* aElement); - /** - * Returns true if the given aElement matches aSelector. - * Like nsCSSRuleProcessor.cpp's SelectorMatches (and unlike - * SelectorMatchesTree), this does not check an entire selector list - * separated by combinators. - * - * :visited and :link will match both visited and non-visited links, - * as if aTreeMatchContext->mVisitedHandling were eLinksVisitedOrUnvisited. - * - * aSelector is restricted to not containing pseudo-elements. - */ - static bool RestrictedSelectorMatches(mozilla::dom::Element* aElement, - nsCSSSelector* aSelector, - TreeMatchContext& aTreeMatchContext); - // nsIStyleRuleProcessor virtual void RulesMatching(ElementRuleProcessorData* aData) override; @@ -144,9 +129,7 @@ public: virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override; virtual nsRestyleHint - HasAttributeDependentStyle(AttributeRuleProcessorData* aData, - mozilla::RestyleHintData& aRestyleHintDataResult) - override; + HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override; virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override; diff --git a/layout/style/nsHTMLCSSStyleSheet.cpp b/layout/style/nsHTMLCSSStyleSheet.cpp index bd972db93a39..215f9f0838f7 100644 --- a/layout/style/nsHTMLCSSStyleSheet.cpp +++ b/layout/style/nsHTMLCSSStyleSheet.cpp @@ -144,9 +144,7 @@ nsHTMLCSSStyleSheet::HasDocumentStateDependentStyle(StateRuleProcessorData* aDat // Test if style is dependent on attribute /* virtual */ nsRestyleHint -nsHTMLCSSStyleSheet::HasAttributeDependentStyle( - AttributeRuleProcessorData* aData, - RestyleHintData& aRestyleHintDataResult) +nsHTMLCSSStyleSheet::HasAttributeDependentStyle(AttributeRuleProcessorData* aData) { // Perhaps should check that it's XUL, SVG, (or HTML) namespace, but // it doesn't really matter. diff --git a/layout/style/nsHTMLCSSStyleSheet.h b/layout/style/nsHTMLCSSStyleSheet.h index 234f3e24cd85..f1ecf2fe4287 100644 --- a/layout/style/nsHTMLCSSStyleSheet.h +++ b/layout/style/nsHTMLCSSStyleSheet.h @@ -43,8 +43,7 @@ public: virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override; virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override; virtual nsRestyleHint - HasAttributeDependentStyle(AttributeRuleProcessorData* aData, - mozilla::RestyleHintData& aRestyleHintDataResult) override; + HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override; virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override; virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_MUST_OVERRIDE override; diff --git a/layout/style/nsHTMLStyleSheet.cpp b/layout/style/nsHTMLStyleSheet.cpp index a496ec0034b0..546468c28a26 100644 --- a/layout/style/nsHTMLStyleSheet.cpp +++ b/layout/style/nsHTMLStyleSheet.cpp @@ -335,9 +335,7 @@ nsHTMLStyleSheet::HasDocumentStateDependentStyle(StateRuleProcessorData* aData) } /* virtual */ nsRestyleHint -nsHTMLStyleSheet::HasAttributeDependentStyle( - AttributeRuleProcessorData* aData, - RestyleHintData& aRestyleHintDataResult) +nsHTMLStyleSheet::HasAttributeDependentStyle(AttributeRuleProcessorData* aData) { // Do nothing on before-change checks if (!aData->mAttrHasChanged) { diff --git a/layout/style/nsHTMLStyleSheet.h b/layout/style/nsHTMLStyleSheet.h index 50627849881b..95d2061355c3 100644 --- a/layout/style/nsHTMLStyleSheet.h +++ b/layout/style/nsHTMLStyleSheet.h @@ -45,8 +45,7 @@ public: virtual nsRestyleHint HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) override; virtual bool HasDocumentStateDependentStyle(StateRuleProcessorData* aData) override; virtual nsRestyleHint - HasAttributeDependentStyle(AttributeRuleProcessorData* aData, - mozilla::RestyleHintData& aRestyleHintDataResult) override; + HasAttributeDependentStyle(AttributeRuleProcessorData* aData) override; virtual bool MediumFeaturesChanged(nsPresContext* aPresContext) override; virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_MUST_OVERRIDE override; diff --git a/layout/style/nsIStyleRuleProcessor.h b/layout/style/nsIStyleRuleProcessor.h index 2075050d4076..00182dd38070 100644 --- a/layout/style/nsIStyleRuleProcessor.h +++ b/layout/style/nsIStyleRuleProcessor.h @@ -115,9 +115,8 @@ public: * only, and may err on the side of reporting more dependencies than * really exist. */ - virtual nsRestyleHint HasAttributeDependentStyle( - AttributeRuleProcessorData* aData, - mozilla::RestyleHintData& aRestyleHintDataResult) = 0; + virtual nsRestyleHint + HasAttributeDependentStyle(AttributeRuleProcessorData* aData) = 0; /** * Do any processing that needs to happen as a result of a change in diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index 61e5a4781ec2..5ebeed36b6a4 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -385,14 +385,6 @@ SortStyleSheetsByScope(nsTArray& aSheets) nsresult nsStyleSet::GatherRuleProcessors(sheetType aType) { - // We might be in GatherRuleProcessors because we are dropping a sheet, - // resulting in an nsCSSSelector being destroyed. Tell the - // RestyleManager for each document we're used in so that they can - // drop any nsCSSSelector pointers (used for eRestyle_SomeDescendants) - // in their mPendingRestyles. - if (IsCSSSheetType(aType)) { - ClearSelectors(); - } nsCOMPtr oldRuleProcessor(mRuleProcessors[aType]); nsTArray> oldScopedDocRuleProcessors; if (aType == eAgentSheet || aType == eUserSheet) { @@ -2385,16 +2377,14 @@ struct MOZ_STACK_CLASS AttributeData : public AttributeRuleProcessorData { aAttrHasChanged, aOtherValue, aTreeMatchContext), mHint(nsRestyleHint(0)) {} - nsRestyleHint mHint; - RestyleHintData mHintData; + nsRestyleHint mHint; }; static bool SheetHasAttributeStyle(nsIStyleRuleProcessor* aProcessor, void *aData) { AttributeData* data = (AttributeData*)aData; - nsRestyleHint hint = - aProcessor->HasAttributeDependentStyle(data, data->mHintData); + nsRestyleHint hint = aProcessor->HasAttributeDependentStyle(data); data->mHint = nsRestyleHint(data->mHint | hint); return true; // continue } @@ -2405,9 +2395,7 @@ nsStyleSet::HasAttributeDependentStyle(Element* aElement, nsIAtom* aAttribute, int32_t aModType, bool aAttrHasChanged, - const nsAttrValue* aOtherValue, - mozilla::RestyleHintData& - aRestyleHintDataResult) + const nsAttrValue* aOtherValue) { TreeMatchContext treeContext(false, nsRuleWalker::eLinksVisitedOrUnvisited, aElement->OwnerDoc()); @@ -2415,11 +2403,6 @@ nsStyleSet::HasAttributeDependentStyle(Element* aElement, AttributeData data(PresContext(), aElement, aAttribute, aModType, aAttrHasChanged, aOtherValue, treeContext); WalkRuleProcessors(SheetHasAttributeStyle, &data, false); - if (!(data.mHint & eRestyle_Subtree)) { - // No point keeping the list of selectors around if we are going to - // restyle the whole subtree unconditionally. - aRestyleHintDataResult = Move(data.mHintData); - } return data.mHint; } @@ -2506,9 +2489,3 @@ nsStyleSet::HasRuleProcessorUsedByMultipleStyleSets(sheetType aSheetType) static_cast(mRuleProcessors[aSheetType].get()); return rp->IsUsedByMultipleStyleSets(); } - -void -nsStyleSet::ClearSelectors() -{ - PresContext()->RestyleManager()->ClearSelectors(); -} diff --git a/layout/style/nsStyleSet.h b/layout/style/nsStyleSet.h index 7d3e85a6dcd5..e807af8e03a6 100644 --- a/layout/style/nsStyleSet.h +++ b/layout/style/nsStyleSet.h @@ -286,9 +286,7 @@ class nsStyleSet final nsIAtom* aAttribute, int32_t aModType, bool aAttrHasChanged, - const nsAttrValue* aOtherValue, - mozilla::RestyleHintData& - aRestyleHintDataResult); + const nsAttrValue* aOtherValue); /* * Do any processing that needs to happen as a result of a change in @@ -399,10 +397,6 @@ class nsStyleSet final bool HasRuleProcessorUsedByMultipleStyleSets(sheetType aSheetType); - // Tells the RestyleManager for the document using this style set - // to drop any nsCSSSelector pointers it has. - void ClearSelectors(); - private: nsStyleSet(const nsStyleSet& aCopy) = delete; nsStyleSet& operator=(const nsStyleSet& aCopy) = delete; From 0a6112cf3a87ca41237d1f3aabca9490dd5734d0 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 4 Aug 2015 16:41:50 +1200 Subject: [PATCH 35/56] Bug 1190635. Don't early-return for an mHeight change, since width changes can add extra change hints. r=heycam Don't return early for an mWidth change either. --HG-- extra : commitid : 37peBegt3RL extra : rebase_source : 4b50b8cea84e13f12614c5033b4e67734c2d3755 --- layout/reftests/bugs/1190635-1-ref.html | 9 +++++++++ layout/reftests/bugs/1190635-1.html | 17 +++++++++++++++++ layout/reftests/bugs/reftest.list | 1 + layout/style/nsStyleStruct.cpp | 17 +++++++---------- 4 files changed, 34 insertions(+), 10 deletions(-) create mode 100644 layout/reftests/bugs/1190635-1-ref.html create mode 100644 layout/reftests/bugs/1190635-1.html diff --git a/layout/reftests/bugs/1190635-1-ref.html b/layout/reftests/bugs/1190635-1-ref.html new file mode 100644 index 000000000000..a42e82b0c679 --- /dev/null +++ b/layout/reftests/bugs/1190635-1-ref.html @@ -0,0 +1,9 @@ + + +
+
+ + + +
+ diff --git a/layout/reftests/bugs/1190635-1.html b/layout/reftests/bugs/1190635-1.html new file mode 100644 index 000000000000..c215543df6db --- /dev/null +++ b/layout/reftests/bugs/1190635-1.html @@ -0,0 +1,17 @@ + + + +
+
+ + + +
+ + diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 105e673931a6..939dd3949217 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1931,3 +1931,4 @@ skip-if(B2G||Mulet) == 1150021-1.xul 1150021-1-ref.xul == 1169331-1.html 1169331-1-ref.html == 1179078-1.html 1179078-1-ref.html fuzzy(1,74) fuzzy-if(gtkWidget,6,79) == 1174332-1.html 1174332-1-ref.html +== 1190635-1.html 1190635-1-ref.html diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 0c86ded5bfe7..e88fe348965e 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -1600,7 +1600,7 @@ nsChangeHint nsStylePosition::CalcDifference(const nsStylePosition& aOther) cons // elements with percentage heights in descendants which also have // percentage heights. This is handled via nsChangeHint_UpdateComputedBSize // which clears intrinsic sizes for frames that have such replaced elements. - return NS_CombineHint(hint, nsChangeHint_NeedReflow | + NS_UpdateHint(hint, nsChangeHint_NeedReflow | nsChangeHint_UpdateComputedBSize | nsChangeHint_ReflowChangesSizeOrPosition); } @@ -1610,16 +1610,13 @@ nsChangeHint nsStylePosition::CalcDifference(const nsStylePosition& aOther) cons mMaxWidth != aOther.mMaxWidth) { // None of our width differences can affect descendant intrinsic // sizes and none of them need to force children to reflow. - return - NS_CombineHint(hint, - NS_SubtractHint(nsChangeHint_AllReflowHints, - NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics, - nsChangeHint_NeedDirtyReflow))); + NS_UpdateHint(hint, NS_SubtractHint(nsChangeHint_AllReflowHints, + NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics, + nsChangeHint_NeedDirtyReflow))); } - // If width and height have not changed, but any of the offsets have changed, - // then return the respective hints so that we would hopefully be able to - // avoid reflowing. + // If any of the offsets have changed, then return the respective hints + // so that we would hopefully be able to avoid reflowing. // Note that it is possible that we'll need to reflow when processing // restyles, but we don't have enough information to make a good decision // right now. @@ -1630,7 +1627,7 @@ nsChangeHint nsStylePosition::CalcDifference(const nsStylePosition& aOther) cons NS_UpdateHint(hint, nsChangeHint(nsChangeHint_RecomputePosition | nsChangeHint_UpdateParentOverflow)); } else { - return NS_CombineHint(hint, nsChangeHint_AllReflowHints); + NS_UpdateHint(hint, nsChangeHint_AllReflowHints); } } return hint; From d4732612643ffe57174dfed02922ea665acc1d60 Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Tue, 4 Aug 2015 11:49:42 +0200 Subject: [PATCH 36/56] Bug 1190782 - about:telemetry: CSS warnings about setting height and padding-top to 'NaNem'. r=gfritzsche --- toolkit/content/aboutTelemetry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolkit/content/aboutTelemetry.js b/toolkit/content/aboutTelemetry.js index 45773663a0eb..63ed376573b0 100644 --- a/toolkit/content/aboutTelemetry.js +++ b/toolkit/content/aboutTelemetry.js @@ -1063,7 +1063,7 @@ let Histogram = { if (aHgram.values.length) { labelPadTo = String(aHgram.values[aHgram.values.length - 1][0]).length; } - let maxBarValue = aOptions.exponential ? this.getLogValue(aHgram.max_value) : aHgram.max; + let maxBarValue = aOptions.exponential ? this.getLogValue(aHgram.max) : aHgram.max; for (let [label, value] of aHgram.values) { let barValue = aOptions.exponential ? this.getLogValue(value) : value; From 05ca2b160ff8ad37f4429dbb72a09a63a5ded2c0 Mon Sep 17 00:00:00 2001 From: Paul Adenot Date: Mon, 3 Aug 2015 18:09:53 +0200 Subject: [PATCH 37/56] Bug 1189171 - Put proper id for the audio capture strings. r=florian --- .../en-US/chrome/browser/browser.properties | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties index b3c4ff659cde..0f14b29be9bd 100644 --- a/browser/locales/en-US/chrome/browser/browser.properties +++ b/browser/locales/en-US/chrome/browser/browser.properties @@ -640,7 +640,11 @@ getUserMedia.sharingMenu.accesskey = d # getUserMedia.sharingMenuMicrophoneApplication, # getUserMedia.sharingMenuMicrophoneScreen, # getUserMedia.sharingMenuMicrophoneWindow, -# getUserMedia.sharingMenuMicrophoneBrowser): +# getUserMedia.sharingMenuMicrophoneBrowser, +# getUserMedia.sharingMenuAudioCaptureApplication, +# getUserMedia.sharingMenuAudioCaptureScreen, +# getUserMedia.sharingMenuAudioCaptureWindow, +# getUserMedia.sharingMenuAudioCaptureBrowser): # %S is the website origin (e.g. www.mozilla.org) getUserMedia.sharingMenuCamera = %S (camera) getUserMedia.sharingMenuMicrophone = %S (microphone) @@ -667,10 +671,10 @@ getUserMedia.sharingMenuMicrophoneApplication = %S (microphone and application) getUserMedia.sharingMenuMicrophoneScreen = %S (microphone and screen) getUserMedia.sharingMenuMicrophoneWindow = %S (microphone and window) getUserMedia.sharingMenuMicrophoneBrowser = %S (microphone and tab) -getUserMedia.sharingMenuMicrophoneApplication = %S (tab audio and application) -getUserMedia.sharingMenuMicrophoneScreen = %S (tab audio and screen) -getUserMedia.sharingMenuMicrophoneWindow = %S (tab audio and window) -getUserMedia.sharingMenuMicrophoneBrowser = %S (tab audio and tab) +getUserMedia.sharingMenuAudioCaptureApplication = %S (tab audio and application) +getUserMedia.sharingMenuAudioCaptureScreen = %S (tab audio and screen) +getUserMedia.sharingMenuAudioCaptureWindow = %S (tab audio and window) +getUserMedia.sharingMenuAudioCaptureBrowser = %S (tab audio and tab) # LOCALIZATION NOTE(getUserMedia.sharingMenuUnknownHost): this is used for the website # origin for the sharing menu if no readable origin could be deduced from the URL. getUserMedia.sharingMenuUnknownHost = Unknown origin From ec93d8cde43b82acb351fe804614558ffba94c87 Mon Sep 17 00:00:00 2001 From: Patrick McManus Date: Fri, 31 Jul 2015 04:07:07 -0400 Subject: [PATCH 38/56] bug 1189645 - remove spdy telem r=hurley --- netwerk/protocol/http/SpdySession31.cpp | 43 ------------- netwerk/protocol/http/nsHttpConnectionMgr.cpp | 62 ------------------- netwerk/protocol/http/nsHttpConnectionMgr.h | 10 --- toolkit/components/telemetry/Histograms.json | 14 ++--- 4 files changed, 7 insertions(+), 122 deletions(-) diff --git a/netwerk/protocol/http/SpdySession31.cpp b/netwerk/protocol/http/SpdySession31.cpp index 3c99ee996903..8ba3db16d495 100644 --- a/netwerk/protocol/http/SpdySession31.cpp +++ b/netwerk/protocol/http/SpdySession31.cpp @@ -798,20 +798,6 @@ SpdySession31::GenerateSettings() numberOfEntries++; } - nsRefPtr ci; - uint32_t cwnd = 0; - GetConnectionInfo(getter_AddRefs(ci)); - if (ci) - cwnd = gHttpHandler->ConnMgr()->GetSpdyCWNDSetting(ci); - if (cwnd) { - packet[12 + 8 * numberOfEntries] = PERSISTED_VALUE; - packet[15 + 8 * numberOfEntries] = SETTINGS_TYPE_CWND; - LOG(("SpdySession31::GenerateSettings %p sending CWND %u\n", this, cwnd)); - cwnd = PR_htonl(cwnd); - memcpy(packet + 16 + 8 * numberOfEntries, &cwnd, 4); - numberOfEntries++; - } - // Advertise the Push RWIN and on each client SYN_STREAM pipeline // a window update with it in order to use larger initial windows with pulled // streams. @@ -1445,41 +1431,12 @@ SpdySession31::HandleSettings(SpdySession31 *self) switch (id) { - case SETTINGS_TYPE_UPLOAD_BW: - Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_UL_BW, value); - break; - - case SETTINGS_TYPE_DOWNLOAD_BW: - Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_DL_BW, value); - break; - - case SETTINGS_TYPE_RTT: - Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_RTT, value); - break; - case SETTINGS_TYPE_MAX_CONCURRENT: self->mMaxConcurrent = value; - Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_MAX_STREAMS, value); self->ProcessPending(); break; - case SETTINGS_TYPE_CWND: - if (flags & PERSIST_VALUE) - { - nsRefPtr ci; - self->GetConnectionInfo(getter_AddRefs(ci)); - if (ci) - gHttpHandler->ConnMgr()->ReportSpdyCWNDSetting(ci, value); - } - Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_CWND, value); - break; - - case SETTINGS_TYPE_DOWNLOAD_RETRANS_RATE: - Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_RETRANS, value); - break; - case SETTINGS_TYPE_INITIAL_WINDOW: - Telemetry::Accumulate(Telemetry::SPDY_SETTINGS_IW, value >> 10); { int32_t delta = value - self->mServerInitialStreamWindow; self->mServerInitialStreamWindow = value; diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp index 5aaf0d203f51..81a07bf45458 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -747,67 +747,6 @@ nsHttpConnectionMgr::ReportSpdyConnection(nsHttpConnection *conn, PostEvent(&nsHttpConnectionMgr::OnMsgProcessAllSpdyPendingQ); } -void -nsHttpConnectionMgr::ReportSpdyCWNDSetting(nsHttpConnectionInfo *ci, - uint32_t cwndValue) -{ - MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); - - if (!gHttpHandler->UseSpdyPersistentSettings()) - return; - - if (!ci) - return; - - nsConnectionEntry *ent = mCT.Get(ci->HashKey()); - if (!ent) - return; - - ent = GetSpdyPreferredEnt(ent); - if (!ent) // just to be thorough - but that map should always exist - return; - - cwndValue = std::max(2U, cwndValue); - cwndValue = std::min(128U, cwndValue); - - ent->mSpdyCWND = cwndValue; - ent->mSpdyCWNDTimeStamp = TimeStamp::Now(); - return; -} - -// a value of 0 means no setting is available -uint32_t -nsHttpConnectionMgr::GetSpdyCWNDSetting(nsHttpConnectionInfo *ci) -{ - MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); - - if (!gHttpHandler->UseSpdyPersistentSettings()) - return 0; - - if (!ci) - return 0; - - nsConnectionEntry *ent = mCT.Get(ci->HashKey()); - if (!ent) - return 0; - - ent = GetSpdyPreferredEnt(ent); - if (!ent) // just to be thorough - but that map should always exist - return 0; - - if (ent->mSpdyCWNDTimeStamp.IsNull()) - return 0; - - // For privacy tracking reasons, and the fact that CWND is not - // meaningful after some time, we don't honor stored CWND after 8 - // hours. - TimeDuration age = TimeStamp::Now() - ent->mSpdyCWNDTimeStamp; - if (age.ToMilliseconds() > (1000 * 60 * 60 * 8)) - return 0; - - return ent->mSpdyCWND; -} - nsHttpConnectionMgr::nsConnectionEntry * nsHttpConnectionMgr::GetSpdyPreferredEnt(nsConnectionEntry *aOriginalEntry) { @@ -3669,7 +3608,6 @@ nsConnectionEntry::nsConnectionEntry(nsHttpConnectionInfo *ci) , mYellowConnection(nullptr) , mGreenDepth(kPipelineOpen) , mPipeliningPenalty(0) - , mSpdyCWND(0) , mUsingSpdy(false) , mTestedSpdy(false) , mInPreferredHash(false) diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.h b/netwerk/protocol/http/nsHttpConnectionMgr.h index 1be39a86c0b2..6f6036b06570 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.h +++ b/netwerk/protocol/http/nsHttpConnectionMgr.h @@ -242,11 +242,6 @@ public: // bit different. void ReportSpdyConnection(nsHttpConnection *, bool usingSpdy); - // A spdy server can supply cwnd information for the session that is used - // in future sessions to speed up the opening portions of the connection. - void ReportSpdyCWNDSetting(nsHttpConnectionInfo *host, uint32_t cwndValue); - uint32_t GetSpdyCWNDSetting(nsHttpConnectionInfo *host); - bool SupportsPipelining(nsHttpConnectionInfo *); bool GetConnectionData(nsTArray *); @@ -366,11 +361,6 @@ private: // nsTArray mCoalescingKeys; - // The value of a recevied SPDY settings type 5 previously received - // for this connection entry and the time it was set. - uint32_t mSpdyCWND; - TimeStamp mSpdyCWNDTimeStamp; - // To have the UsingSpdy flag means some host with the same connection // entry has done NPN=spdy/* at some point. It does not mean every // connection is currently using spdy. diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 6b70f1a350cf..d0f80763ac96 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -1456,7 +1456,7 @@ "description": "SPDY: KB read per connection" }, "SPDY_SETTINGS_UL_BW": { - "expires_in_version": "never", + "expires_in_version": "42", "kind": "exponential", "high": "10000", "n_buckets": 100, @@ -1464,7 +1464,7 @@ "description": "SPDY: Settings Upload Bandwidth" }, "SPDY_SETTINGS_DL_BW": { - "expires_in_version": "never", + "expires_in_version": "42", "kind": "exponential", "high": "10000", "n_buckets": 100, @@ -1472,7 +1472,7 @@ "description": "SPDY: Settings Download Bandwidth" }, "SPDY_SETTINGS_RTT": { - "expires_in_version": "never", + "expires_in_version": "42", "kind": "exponential", "high": "1000", "n_buckets": 100, @@ -1485,10 +1485,10 @@ "high": "5000", "n_buckets": 100, "extended_statistics_ok": true, - "description": "SPDY: Settings Max Streams parameter" + "description": "H2: Settings Max Streams parameter" }, "SPDY_SETTINGS_CWND": { - "expires_in_version": "never", + "expires_in_version": "42", "kind": "exponential", "high": "500", "n_buckets": 50, @@ -1496,7 +1496,7 @@ "description": "SPDY: Settings CWND (packets)" }, "SPDY_SETTINGS_RETRANS": { - "expires_in_version": "never", + "expires_in_version": "42", "kind": "exponential", "high": "100", "n_buckets": 50, @@ -1509,7 +1509,7 @@ "high": "1000", "n_buckets": 50, "extended_statistics_ok": true, - "description": "SPDY: Settings IW (rounded to KB)" + "description": "H2: Settings Initial Window (rounded to KB)" }, "DISK_CACHE_CORRUPT_DETAILS": { "expires_in_version": "40", From 8f497598a6572a8207a15227fde612050cec24ba Mon Sep 17 00:00:00 2001 From: Patrick McManus Date: Fri, 31 Jul 2015 05:43:24 -0400 Subject: [PATCH 39/56] bug 1189692 - add telem for quic advertisements r=hurley --- netwerk/protocol/http/nsHttpAtomList.h | 1 + netwerk/protocol/http/nsHttpChannel.cpp | 20 ++++++++++++++------ toolkit/components/telemetry/Histograms.json | 7 ++++++- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/netwerk/protocol/http/nsHttpAtomList.h b/netwerk/protocol/http/nsHttpAtomList.h index cdbc3a300425..15f2928d1639 100644 --- a/netwerk/protocol/http/nsHttpAtomList.h +++ b/netwerk/protocol/http/nsHttpAtomList.h @@ -25,6 +25,7 @@ HTTP_ATOM(Age, "Age") HTTP_ATOM(Allow, "Allow") HTTP_ATOM(Alternate_Service, "Alt-Svc") HTTP_ATOM(Alternate_Service_Used, "Alt-Used") +HTTP_ATOM(Alternate_Protocol, "Alternate-Protocol") HTTP_ATOM(Assoc_Req, "Assoc-Req") HTTP_ATOM(Authentication, "Authentication") HTTP_ATOM(Authorization, "Authorization") diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index e14ef557e09b..d49010985667 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -1397,13 +1397,21 @@ nsHttpChannel::ProcessResponse() nsresult rv; uint32_t httpStatus = mResponseHead->Status(); - // Gather data on whether the transaction and page (if this is - // the initial page load) is being loaded with SSL. - Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_IS_SSL, - mConnectionInfo->EndToEndSSL()); - if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) { - Telemetry::Accumulate(Telemetry::HTTP_PAGELOAD_IS_SSL, + // do some telemetry + if (gHttpHandler->IsTelemetryEnabled()) { + // Gather data on whether the transaction and page (if this is + // the initial page load) is being loaded with SSL. + Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_IS_SSL, mConnectionInfo->EndToEndSSL()); + if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) { + Telemetry::Accumulate(Telemetry::HTTP_PAGELOAD_IS_SSL, + mConnectionInfo->EndToEndSSL()); + } + + // how often do we see something like Alternate-Protocol: "443:quic,p=1" + const char *alt_protocol = mResponseHead->PeekHeader(nsHttp::Alternate_Protocol); + bool saw_quic = (alt_protocol && PL_strstr(alt_protocol, "quic")) ? 1 : 0; + Telemetry::Accumulate(Telemetry::HTTP_SAW_QUIC_ALT_PROTOCOL, saw_quic); } LOG(("nsHttpChannel::ProcessResponse [this=%p httpStatus=%u]\n", diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index d0f80763ac96..046467a8a3ba 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -1657,7 +1657,12 @@ "extended_statistics_ok": true, "description": "Time from submission to dispatch of SPDY transaction (ms)" }, - "HTTP_DISK_CACHE_OVERHEAD": { + "HTTP_SAW_QUIC_ALT_PROTOCOL": { + "expires_in_version": "never", + "kind": "boolean", + "description": "Fraction of responses with a quic alt-protocol advertisement." + }, + "HTTP_DISK_CACHE_OVERHEAD": { "expires_in_version": "default", "kind": "exponential", "high": "32000000", From 9471073b8c3988273c69943dd081939f6fdf2668 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Tue, 4 Aug 2015 00:17:04 -0700 Subject: [PATCH 40/56] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/2cb6134af048 Author: Zibi Braniecki Desc: Merge pull request #31216 from zbraniecki/1190139-remove-innerHTML-from-wantToReceiveFile-entity Bug 1190139 - Remove .innerHTML from wantToReceiveFile entity. r=stas ======== https://hg.mozilla.org/integration/gaia-central/rev/7b39effadc0f Author: Zibi Braniecki Desc: Bug 1190139 - Remove .innerHTML from wantToReceiveFile entity --- b2g/config/gaia.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 065124d6f69d..26a5064729e9 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "67c38af8347f93ddc005a53f427d651b744b55c1", + "git_revision": "23e2e115d374dea7d3ebce200a06211219f551bc", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "72807eee01421a4ddf6180b2e5a66757a42a7984", + "revision": "2cb6134af0482c913865a89f38566cb644c443f9", "repo_path": "integration/gaia-central" } From 970439aa285c05c6be818b089ffb966d581a9fe2 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Tue, 4 Aug 2015 00:18:41 -0700 Subject: [PATCH 41/56] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index bee29740b04c..64251c2a5ce4 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index c4a863c20622..a2b8cb10b0b9 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index e43a0261fc8b..fee85bbee232 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 5028fd164c56..07224d6d881c 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 56c5693054ac..dc1dfd10aead 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index 54d2617edd87..bbbc24514aa6 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index e43a0261fc8b..fee85bbee232 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 3befa01db5b4..9e1bef4130b1 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 7a9e0832ed21..ab2b632ee9e2 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index ea9fdedb4203..3375e0b6b159 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + From 54ebb598c58a2bbb6cd809622b839cf4c76e42da Mon Sep 17 00:00:00 2001 From: Bevis Tseng Date: Mon, 3 Aug 2015 20:24:40 +0800 Subject: [PATCH 42/56] Bug 1189884 - Read/Update ANR of SIM Contact Properly. r=echen --- dom/icc/gonk/IccService.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dom/icc/gonk/IccService.js b/dom/icc/gonk/IccService.js index 5b0e6f40bdb1..ac33421e831a 100644 --- a/dom/icc/gonk/IccService.js +++ b/dom/icc/gonk/IccService.js @@ -96,7 +96,7 @@ function IccContact(aContact) { let anrLen = aContact.anr ? aContact.anr.length : 0; for (let i = 0; i < anrLen; i++) { - this._numbers.push(anr[i]); + this._numbers.push(aContact.anr[i]); } if (aContact.email) { @@ -717,7 +717,7 @@ Icc.prototype = { if (length > 0) { iccContact.anr = []; for (let i = 0; i < length; i++) { - iccContact.anr.push(anrArray[i].value); + iccContact.anr.push(anrArray[i]); } } } From f83576c65303a7c606adec03c788e2b8cdeeb5a9 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Tue, 4 Aug 2015 01:32:01 -0700 Subject: [PATCH 43/56] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ======== https://hg.mozilla.org/integration/gaia-central/rev/7e267d3e230b Author: Staś Małolepszy Desc: Merge pull request #31225 from stasm/1190038-sanitize-all-html Bug 1190038 - Sanitize all HTML elements. r=gandalf ======== https://hg.mozilla.org/integration/gaia-central/rev/642a780a7f1c Author: Staś Małolepszy Desc: Bug 1190038 - Sanitize all HTML elements. r=gandalf --- b2g/config/gaia.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 26a5064729e9..c825456dcf1d 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "23e2e115d374dea7d3ebce200a06211219f551bc", + "git_revision": "65c731fbe7023a5d27badb48a0f1b27f9170cfb5", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "2cb6134af0482c913865a89f38566cb644c443f9", + "revision": "7e267d3e230be824b026d709b38ef0dfb8d94fdc", "repo_path": "integration/gaia-central" } From e8e85ec34514fef7cf030f9ee20d9e4aa25b4038 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Tue, 4 Aug 2015 01:33:38 -0700 Subject: [PATCH 44/56] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index 64251c2a5ce4..ebf1907e0b98 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index a2b8cb10b0b9..42325ba71726 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index fee85bbee232..f359f6322c7a 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 07224d6d881c..ab8ea352c722 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index dc1dfd10aead..435a601f4ec7 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index bbbc24514aa6..d5d9a5fba1b3 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index fee85bbee232..f359f6322c7a 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 9e1bef4130b1..0f734b054bb5 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index ab2b632ee9e2..d88affa0ce76 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index 3375e0b6b159..99a292cc6570 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + From 0ecddb56ed39d3b24db6845e123ea3f457bc5936 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Tue, 4 Aug 2015 02:25:07 -0700 Subject: [PATCH 45/56] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ======== https://hg.mozilla.org/integration/gaia-central/rev/3c80248054fa Author: Borja Salguero Desc: Merge pull request #30985 from borjasalguero/new Bug 1183728 - [Contacts][NGA] Connect #new self-contained view to theā€¦ ======== https://hg.mozilla.org/integration/gaia-central/rev/e236e9172db1 Author: borjasalguero Desc: Bug 1183728 - [Contacts][NGA] Connect #new self-contained view to the app. r=arcturus --- b2g/config/gaia.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index c825456dcf1d..1d79a49be661 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "65c731fbe7023a5d27badb48a0f1b27f9170cfb5", + "git_revision": "db4d4b1a2f8f49347a8f3addfe02f990c73e88a3", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "7e267d3e230be824b026d709b38ef0dfb8d94fdc", + "revision": "3c80248054fa684949251358b32b9581b9c07ef8", "repo_path": "integration/gaia-central" } From 7faf13dd7a3faacbd5914da51f050eb58719b6f9 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Tue, 4 Aug 2015 02:26:44 -0700 Subject: [PATCH 46/56] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index ebf1907e0b98..619d0a3cc6f8 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 42325ba71726..a1e2f7020c65 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index f359f6322c7a..6e9e5bf09425 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index ab8ea352c722..aa005532cbd1 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 435a601f4ec7..0640a4a2fd13 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index d5d9a5fba1b3..87357974ee3b 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index f359f6322c7a..6e9e5bf09425 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 0f734b054bb5..a73bf5fe5b3b 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index d88affa0ce76..b7dbb50f0990 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index 99a292cc6570..43c72fb6e05e 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + From 7cdfd806c2436939c499ff84141535bad79602be Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Tue, 4 Aug 2015 03:10:33 -0700 Subject: [PATCH 47/56] Bumping gaia.json for 1 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/b5c119715f1a Author: Tzu-Lin Huang Desc: Revert "Bug 1186301 - [Stingray] Scanning and display BT devices in Device Deck" This reverts commit 470e3529f768d15b29ffa1be5b7058586d421c76. --- b2g/config/gaia.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 1d79a49be661..f4b772165d74 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "db4d4b1a2f8f49347a8f3addfe02f990c73e88a3", + "git_revision": "4e3dfb7242e3adccdd544572662f29713fe5f58d", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "3c80248054fa684949251358b32b9581b9c07ef8", + "revision": "b5c119715f1ad6805e645cb275751130a4599711", "repo_path": "integration/gaia-central" } From d2e64f7264056dfb3132a0731015ff4f73f692f7 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Tue, 4 Aug 2015 03:12:34 -0700 Subject: [PATCH 48/56] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index 619d0a3cc6f8..d88f26a073c7 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index a1e2f7020c65..0179ac95a7a1 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 6e9e5bf09425..cd902bbfc0f5 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index aa005532cbd1..d0c03074e211 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 0640a4a2fd13..45f620d736fa 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index 87357974ee3b..ca6c13061350 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 6e9e5bf09425..cd902bbfc0f5 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index a73bf5fe5b3b..d12c88be42b8 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index b7dbb50f0990..b061cd4ce585 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index 43c72fb6e05e..fcf09d997d9d 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + From 241d068c5eab41bfc390fc6f0278416aa2b64d25 Mon Sep 17 00:00:00 2001 From: Till Schneidereit Date: Tue, 4 Aug 2015 14:58:27 +0200 Subject: [PATCH 49/56] Bug 1190727 - Make initialization of temporary results array resilient against Array.prototype setters in self-hosted Map#next implementation. r=jandem --HG-- extra : rebase_source : a934d2238d373178e51cb5b7e254c2702909b2f2 --- js/src/builtin/Map.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/js/src/builtin/Map.js b/js/src/builtin/Map.js index 79a8605775fd..5442123cd466 100644 --- a/js/src/builtin/Map.js +++ b/js/src/builtin/Map.js @@ -47,11 +47,8 @@ function MapIteratorNext() { // Steps 8-9 (omitted). var mapIterationResultPair = iteratorTemp.mapIterationResultPair; - if (!mapIterationResultPair) { - mapIterationResultPair = iteratorTemp.mapIterationResultPair = NewDenseArray(2); - mapIterationResultPair[0] = null; - mapIterationResultPair[1] = null; - } + if (!mapIterationResultPair) + mapIterationResultPair = iteratorTemp.mapIterationResultPair = [null, null]; var retVal = {value: undefined, done: true}; From d133f06440bbdb1eb3742a455da6f7643830573d Mon Sep 17 00:00:00 2001 From: Sotaro Ikeda Date: Tue, 4 Aug 2015 06:45:44 -0700 Subject: [PATCH 50/56] Bug 1189206 - Remove worng mCurrentPosition update r=cpearce --- dom/media/MediaDecoderStateMachine.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index cc08de004be4..8ba079ae8e00 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -1274,7 +1274,6 @@ void MediaDecoderStateMachine::SetDormant(bool aDormant) } else if ((aDormant != true) && (mState == DECODER_STATE_DORMANT)) { mDecodingFrozenAtStateDecoding = true; ScheduleStateMachine(); - mCurrentPosition = 0; mDecodingFirstFrame = true; SetState(DECODER_STATE_DECODING_NONE); mDecoder->GetReentrantMonitor().NotifyAll(); From 8f6c5ee7c3abce5a8135f2b3b3f327025a9830c5 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Tue, 4 Aug 2015 09:47:06 -0700 Subject: [PATCH 51/56] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/2330e0fd58c5 Author: Fernando Campo Desc: Merge pull request #31177 from fcampo/mms-to-email-1185090 Bug 1185090 - [Contacts] Cannot send MMS to email address from details view (r=borjasalguero) ======== https://hg.mozilla.org/integration/gaia-central/rev/ad38f6fedf5c Author: Fernando Campo Desc: Bug 1185090 - [Contacts] Cannot send MMS to email address from contact page. --- b2g/config/gaia.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index f4b772165d74..f49b0d26973e 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "4e3dfb7242e3adccdd544572662f29713fe5f58d", + "git_revision": "6d91a3d13cc2a2f4a1f05e4db1076ca31517f928", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "b5c119715f1ad6805e645cb275751130a4599711", + "revision": "2330e0fd58c5637fd22379b3cde301458ebb97cc", "repo_path": "integration/gaia-central" } From 19e9bdaa3ad3c3497fe136b6fab081a7cdff091d Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Tue, 4 Aug 2015 09:48:43 -0700 Subject: [PATCH 52/56] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index d88f26a073c7..b826ed106306 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 0179ac95a7a1..d2b7fd4c5804 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index cd902bbfc0f5..d8bafb0c075b 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index d0c03074e211..93b1ec0383c1 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 45f620d736fa..dc56ed431525 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index ca6c13061350..0e939f346bcf 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index cd902bbfc0f5..d8bafb0c075b 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index d12c88be42b8..5270a4b412db 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index b061cd4ce585..fa29b02a2540 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index fcf09d997d9d..63cedee8ca66 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + From a05aa7a22563868fe4c8c9688ec5e08ebd71413e Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Tue, 4 Aug 2015 09:56:56 -0700 Subject: [PATCH 53/56] Bumping gaia.json for 1 gaia revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/68ce99a4e176 Author: Ryan VanderMeulen Desc: Bug 1110913 - Skip lockscreen_media_playback_test.js for frequent failures in automation. --- b2g/config/gaia.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index f49b0d26973e..4e8dd68a8e1c 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "6d91a3d13cc2a2f4a1f05e4db1076ca31517f928", + "git_revision": "c5425d9f1f5184731a59ed4bc99295acbde30390", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "2330e0fd58c5637fd22379b3cde301458ebb97cc", + "revision": "68ce99a4e1761c06e5f31f6674ee46fef1bbf44b", "repo_path": "integration/gaia-central" } From 005ba1de9fac63b5ac4dd7e680b28ff898cc7575 Mon Sep 17 00:00:00 2001 From: B2G Bumper Bot Date: Tue, 4 Aug 2015 09:58:33 -0700 Subject: [PATCH 54/56] Bumping manifests a=b2g-bump --- b2g/config/aries/sources.xml | 2 +- b2g/config/dolphin/sources.xml | 2 +- b2g/config/emulator-ics/sources.xml | 2 +- b2g/config/emulator-jb/sources.xml | 2 +- b2g/config/emulator-kk/sources.xml | 2 +- b2g/config/emulator-l/sources.xml | 2 +- b2g/config/emulator/sources.xml | 2 +- b2g/config/flame-kk/sources.xml | 2 +- b2g/config/nexus-4/sources.xml | 2 +- b2g/config/nexus-5-l/sources.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml index b826ed106306..7219dddb88d7 100644 --- a/b2g/config/aries/sources.xml +++ b/b2g/config/aries/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index d2b7fd4c5804..733cb2389f25 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index d8bafb0c075b..cd84559efb36 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 93b1ec0383c1..52dcb1ac36ea 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index dc56ed431525..32b71ff4d46d 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index 0e939f346bcf..ca87dbe51848 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index d8bafb0c075b..cd84559efb36 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index 5270a4b412db..08b35009290a 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index fa29b02a2540..6427f76cbee6 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index 63cedee8ca66..9b75a3adbbaa 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + From fdad9271bf2eab01ef92e344307d0e7583c236c4 Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Tue, 4 Aug 2015 13:43:17 -0400 Subject: [PATCH 55/56] Bug 1185115 - Ensure we have enough memory to allocate required capacity. r=kentuckyfriedtakahe CLOSED TREE --HG-- extra : amend_source : d3104ef74195446962f52d1328b75f62484bf3f1 --- .../av/media/libstagefright/SampleTable.cpp | 12 +++++++--- .../system/core/include/utils/Vector.h | 3 ++- .../system/core/libutils/VectorImpl.cpp | 22 ++++++++++++++----- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/media/libstagefright/frameworks/av/media/libstagefright/SampleTable.cpp b/media/libstagefright/frameworks/av/media/libstagefright/SampleTable.cpp index 3d28fc93680c..cd2f73f22104 100644 --- a/media/libstagefright/frameworks/av/media/libstagefright/SampleTable.cpp +++ b/media/libstagefright/frameworks/av/media/libstagefright/SampleTable.cpp @@ -580,7 +580,9 @@ SampleTable::setSampleAuxiliaryInformationOffsetParams( } data_offset += 4; - mCencOffsets.setCapacity(cencOffsetCount); + if (mCencOffsets.setCapacity(cencOffsetCount) < 0) { + return ERROR_MALFORMED; + } if (!version) { for (uint32_t i = 0; i < cencOffsetCount; i++) { uint32_t tmp; @@ -1104,8 +1106,12 @@ SampleTable::getSampleCencInfo( } auto& info = mCencInfo[sample_index]; - clear_sizes.setCapacity(info.mSubsampleCount); - cipher_sizes.setCapacity(info.mSubsampleCount); + if (clear_sizes.setCapacity(info.mSubsampleCount) < 0) { + return ERROR_MALFORMED; + } + if (cipher_sizes.setCapacity(info.mSubsampleCount) < 0) { + return ERROR_MALFORMED; + } for (uint32_t i = 0; i < info.mSubsampleCount; i++) { clear_sizes.push(info.mSubsamples[i].mClearBytes); diff --git a/media/libstagefright/system/core/include/utils/Vector.h b/media/libstagefright/system/core/include/utils/Vector.h index 2388d0646cc3..c08577a33e3f 100644 --- a/media/libstagefright/system/core/include/utils/Vector.h +++ b/media/libstagefright/system/core/include/utils/Vector.h @@ -18,6 +18,7 @@ #define ANDROID_VECTOR_H #include +#include #include #include @@ -191,7 +192,7 @@ public: inline iterator end() { return editArray() + size(); } inline const_iterator begin() const { return array(); } inline const_iterator end() const { return array() + size(); } - inline void reserve(size_t n) { setCapacity(n); } + inline void reserve(size_t n) { assert(setCapacity(n) >= 0); } inline bool empty() const{ return isEmpty(); } inline void push_back(const TYPE& item) { insertAt(item, size(), 1); } inline void push_front(const TYPE& item) { insertAt(item, 0, 1); } diff --git a/media/libstagefright/system/core/libutils/VectorImpl.cpp b/media/libstagefright/system/core/libutils/VectorImpl.cpp index 64d7a74d046b..b57d211d49f4 100644 --- a/media/libstagefright/system/core/libutils/VectorImpl.cpp +++ b/media/libstagefright/system/core/libutils/VectorImpl.cpp @@ -27,9 +27,8 @@ #include #include -#if !defined(SSIZE_MAX) -#define SSIZE_MAX ((ssize_t)(SIZE_MAX/2)) -#endif +static const uint32_t kMAX_ALLOCATION = + ((SIZE_MAX > INT32_MAX ? INT32_MAX : SIZE_MAX) - 1); /*****************************************************************************/ @@ -93,6 +92,7 @@ void* VectorImpl::editArrayImpl() SharedBuffer* sb = SharedBuffer::bufferFromData(mStorage)->attemptEdit(); if (sb == 0) { sb = SharedBuffer::alloc(capacity() * mItemSize); + assert(sb); if (sb) { _do_copy(sb->data(), mStorage, mCount); release_storage(); @@ -334,7 +334,7 @@ ssize_t VectorImpl::setCapacity(size_t new_capacity) // we can't reduce the capacity return capacity(); } - if (new_capacity >= (SSIZE_MAX / mItemSize)) { + if (new_capacity >= (kMAX_ALLOCATION / mItemSize)) { return NO_MEMORY; } SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); @@ -380,8 +380,11 @@ void* VectorImpl::_grow(size_t where, size_t amount) this, (int)where, (int)amount, (int)mCount); // caller already checked const size_t new_size = mCount + amount; + assert(amount < kMAX_ALLOCATION - mCount); if (capacity() < new_size) { + assert(new_size < (SIZE_MAX / 3 - 1)); const size_t new_capacity = max(kMinVectorCapacity, ((new_size*3)+1)/2); + assert(new_capacity < (kMAX_ALLOCATION / mItemSize)); // ALOGV("grow vector %p, new_capacity=%d", this, (int)new_capacity); if ((mStorage) && (mCount==where) && @@ -389,10 +392,13 @@ void* VectorImpl::_grow(size_t where, size_t amount) (mFlags & HAS_TRIVIAL_DTOR)) { const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage); + assert(cur_sb); SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize); + assert(sb); mStorage = sb->data(); } else { SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); + assert(sb); if (sb) { void* array = sb->data(); if (where != 0) { @@ -433,18 +439,23 @@ void VectorImpl::_shrink(size_t where, size_t amount) this, (int)where, (int)amount, (int)mCount); // caller already checked const size_t new_size = mCount - amount; - if (new_size*3 < capacity()) { + assert(new_size < (SIZE_MAX / 2)); + if (new_size*2 < capacity()) { const size_t new_capacity = max(kMinVectorCapacity, new_size*2); // ALOGV("shrink vector %p, new_capacity=%d", this, (int)new_capacity); + assert(new_capacity < (kMAX_ALLOCATION / mItemSize)); if ((where == new_size) && (mFlags & HAS_TRIVIAL_COPY) && (mFlags & HAS_TRIVIAL_DTOR)) { const SharedBuffer* cur_sb = SharedBuffer::bufferFromData(mStorage); + assert(cur_sb); SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize); + assert(sb); mStorage = sb->data(); } else { SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); + assert(sb); if (sb) { void* array = sb->data(); if (where != 0) { @@ -461,6 +472,7 @@ void VectorImpl::_shrink(size_t where, size_t amount) } } else { void* array = editArrayImpl(); + assert(array); void* to = reinterpret_cast(array) + where*mItemSize; _do_destroy(to, amount); if (where != new_size) { From 6937c1a640e69f74e0fdb3c4d82507e31f3a80d6 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Tue, 4 Aug 2015 15:21:57 -0400 Subject: [PATCH 56/56] Backed out changeset a9d3df6e14e0 (bug 1188780) for causing bug 1190860. a=bustage --- .../linux32/releng.manifest | 5 +-- .../tooltool-manifests/linux64/clang.manifest | 5 +-- .../linux64/releng.manifest | 5 +-- .../tooltool-manifests/linux64/tsan.manifest | 5 +-- build/unix/build-gtk3/build-gtk3.sh | 41 +------------------ build/unix/mozconfig.gtk | 34 ++++++++++++++- .../devtools/rootAnalysis/build/gcc.manifest | 5 +-- 7 files changed, 43 insertions(+), 57 deletions(-) diff --git a/browser/config/tooltool-manifests/linux32/releng.manifest b/browser/config/tooltool-manifests/linux32/releng.manifest index 9bf4aad7f53e..9bc6b0e01e29 100644 --- a/browser/config/tooltool-manifests/linux32/releng.manifest +++ b/browser/config/tooltool-manifests/linux32/releng.manifest @@ -7,11 +7,10 @@ "unpack": true }, { -"size": 11179576, -"digest": "91567ce8e2bb8ab0ebc60c31e90731d88a1ea889fb71bcf55c735746a60fa7610b7e040ea3d8f727b6f692ae3ee703d6f3b30cdbd76fdf5617f77d9c38aa20ed", +"size": 4079256, +"digest": "bb5238558bcf6db2ca395513c8dccaa15dd61b3c375598eb6a685356b0c1a2d9840e3bf81bc00242b872fd798541f53d723777c754412abf0e772b7cc284937c", "algorithm": "sha512", "filename": "gtk3.tar.xz", -"setup": "setup.sh", "unpack": true }, { diff --git a/browser/config/tooltool-manifests/linux64/clang.manifest b/browser/config/tooltool-manifests/linux64/clang.manifest index f804ab75c4cf..ba2d63fe998d 100644 --- a/browser/config/tooltool-manifests/linux64/clang.manifest +++ b/browser/config/tooltool-manifests/linux64/clang.manifest @@ -10,11 +10,10 @@ "unpack": true }, { -"size": 12057960, -"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e", +"size": 4431740, +"digest": "68fc56b0fb0cdba629b95683d6649ff76b00dccf97af90960c3d7716f6108b2162ffd5ffcd5c3a60a21b28674df688fe4dabc67345e2da35ec5abeae3d48c8e3", "algorithm": "sha512", "filename": "gtk3.tar.xz", -"setup": "setup.sh", "unpack": true } ] diff --git a/browser/config/tooltool-manifests/linux64/releng.manifest b/browser/config/tooltool-manifests/linux64/releng.manifest index 83180f42fe66..0001721cb8e5 100644 --- a/browser/config/tooltool-manifests/linux64/releng.manifest +++ b/browser/config/tooltool-manifests/linux64/releng.manifest @@ -7,11 +7,10 @@ "unpack": true }, { -"size": 12057960, -"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e", +"size": 4431740, +"digest": "68fc56b0fb0cdba629b95683d6649ff76b00dccf97af90960c3d7716f6108b2162ffd5ffcd5c3a60a21b28674df688fe4dabc67345e2da35ec5abeae3d48c8e3", "algorithm": "sha512", "filename": "gtk3.tar.xz", -"setup": "setup.sh", "unpack": true }, { diff --git a/browser/config/tooltool-manifests/linux64/tsan.manifest b/browser/config/tooltool-manifests/linux64/tsan.manifest index 1dfe9c0ba969..80609e02c1a0 100644 --- a/browser/config/tooltool-manifests/linux64/tsan.manifest +++ b/browser/config/tooltool-manifests/linux64/tsan.manifest @@ -10,11 +10,10 @@ "unpack": true }, { -"size": 12057960, -"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e", +"size": 4431740, +"digest": "68fc56b0fb0cdba629b95683d6649ff76b00dccf97af90960c3d7716f6108b2162ffd5ffcd5c3a60a21b28674df688fe4dabc67345e2da35ec5abeae3d48c8e3", "algorithm": "sha512", "filename": "gtk3.tar.xz", -"setup": "setup.sh", "unpack": true } ] diff --git a/build/unix/build-gtk3/build-gtk3.sh b/build/unix/build-gtk3/build-gtk3.sh index 9e8d5c0c8f31..24a5ae2933c3 100644 --- a/build/unix/build-gtk3/build-gtk3.sh +++ b/build/unix/build-gtk3/build-gtk3.sh @@ -57,7 +57,7 @@ build() { cd build/$name eval ../../$name-$version/configure --disable-static $* $configure_args make $make_flags - make install DESTDIR=$root_dir/gtk3 + make install-strip DESTDIR=$root_dir/gtk3 find $root_dir/gtk3 -name \*.la -delete cd ../.. } @@ -103,44 +103,5 @@ build gtk+ rm -rf $root_dir/gtk3/usr/local/share/gtk-doc rm -rf $root_dir/gtk3/usr/local/share/locale -# mock build environment doesn't have fonts in /usr/share/fonts, but -# has some in /usr/share/X11/fonts. Add this directory to the -# fontconfig configuration without changing the gtk3 tooltool package. -cat << EOF > $root_dir/gtk3/usr/local/etc/fonts/local.conf - - - - /usr/share/X11/fonts - -EOF - -cat < $root_dir/gtk3/setup.sh -#!/bin/sh - -cd \$(dirname \$0) - -# pango expects absolute paths in pango.modules, and TOOLTOOL_DIR may vary... -LD_LIBRARY_PATH=./usr/local/lib \ -PANGO_SYSCONFDIR=./usr/local/etc \ -PANGO_LIBDIR=./usr/local/lib \ -./usr/local/bin/pango-querymodules > ./usr/local/etc/pango/pango.modules - -# same with gdb-pixbuf and loaders.cache -LD_LIBRARY_PATH=./usr/local/lib \ -GDK_PIXBUF_MODULE_FILE=./usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache \ -GDK_PIXBUF_MODULEDIR=./usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders \ -./usr/local/bin/gdk-pixbuf-query-loaders > ./usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache - -# The fontconfig version in the tooltool package has known uses of -# uninitialized memory when creating its cache, and while most users -# will already have an existing cache, running Firefox on automation -# will create it. Combined with valgrind, this generates irrelevant -# errors. -# So create the fontconfig cache beforehand. -./usr/local/bin/fc-cache -EOF - -chmod +x $root_dir/gtk3/setup.sh - cd $cwd tar -C $root_dir -Jcf gtk3.tar.xz gtk3 diff --git a/build/unix/mozconfig.gtk b/build/unix/mozconfig.gtk index 5849a9c4371c..8050b05e1cbe 100644 --- a/build/unix/mozconfig.gtk +++ b/build/unix/mozconfig.gtk @@ -11,6 +11,7 @@ if [ -d "$TOOLTOOL_DIR/gtk3" ]; then export PATH="$TOOLTOOL_DIR/gtk3/usr/local/bin:${PATH}" # Ensure cairo, gdk-pixbuf, etc. are not taken from the system installed packages. LDFLAGS="-L$TOOLTOOL_DIR/gtk3/usr/local/lib ${LDFLAGS}" + mk_add_options "export LD_LIBRARY_PATH=$TOOLTOOL_DIR/gtk3/usr/local/lib" ac_add_options --enable-default-toolkit=cairo-gtk3 # Set things up to use Gtk+3 from the tooltool package @@ -21,8 +22,37 @@ if [ -d "$TOOLTOOL_DIR/gtk3" ]; then mk_add_options "export GDK_PIXBUF_MODULEDIR=$TOOLTOOL_DIR/gtk3/usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders" mk_add_options "export LD_LIBRARY_PATH=$TOOLTOOL_DIR/gtk3/usr/local/lib" - # Until a tooltool with bug 1188571 landed is available everywhere - $TOOLTOOL_DIR/gtk3/setup.sh + # pango expects absolute paths in pango.modules, and TOOLTOOL_DIR may vary... + LD_LIBRARY_PATH=$TOOLTOOL_DIR/gtk3/usr/local/lib \ + PANGO_SYSCONFDIR=$TOOLTOOL_DIR/gtk3/usr/local/etc \ + PANGO_LIBDIR=$TOOLTOOL_DIR/gtk3/usr/local/lib \ + $TOOLTOOL_DIR/gtk3/usr/local/bin/pango-querymodules > $TOOLTOOL_DIR/gtk3/usr/local/etc/pango/pango.modules + + # same with gdb-pixbuf and loaders.cache + LD_LIBRARY_PATH=$TOOLTOOL_DIR/gtk3/usr/local/lib \ + GDK_PIXBUF_MODULE_FILE=$TOOLTOOL_DIR/gtk3/usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache \ + GDK_PIXBUF_MODULEDIR=$TOOLTOOL_DIR/gtk3/usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders \ + $TOOLTOOL_DIR/gtk3/usr/local/bin/gdk-pixbuf-query-loaders > $TOOLTOOL_DIR/gtk3/usr/local/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache + + # The fontconfig version in the tooltool package has known uses of + # uninitialized memory when creating its cache, and while most users + # will already have an existing cache, running Firefox on automation + # will create it. Combined with valgrind, this generates irrelevant + # errors. + # So create the fontconfig cache beforehand. + $TOOLTOOL_DIR/gtk3/usr/local/bin/fc-cache + + # mock build environment doesn't have fonts in /usr/share/fonts, but + # has some in /usr/share/X11/fonts. Add this directory to the + # fontconfig configuration without changing the gtk3 tooltool package. + cat << EOF > $TOOLTOOL_DIR/gtk3/usr/local/etc/fonts/local.conf + + + + /usr/share/X11/fonts + +EOF + else ac_add_options --enable-default-toolkit=cairo-gtk2 fi diff --git a/js/src/devtools/rootAnalysis/build/gcc.manifest b/js/src/devtools/rootAnalysis/build/gcc.manifest index 83274df282e9..7dcd080f3092 100644 --- a/js/src/devtools/rootAnalysis/build/gcc.manifest +++ b/js/src/devtools/rootAnalysis/build/gcc.manifest @@ -10,11 +10,10 @@ "unpack": true }, { -"size": 12057960, -"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e", +"size": 4431740, +"digest": "68fc56b0fb0cdba629b95683d6649ff76b00dccf97af90960c3d7716f6108b2162ffd5ffcd5c3a60a21b28674df688fe4dabc67345e2da35ec5abeae3d48c8e3", "algorithm": "sha512", "filename": "gtk3.tar.xz", -"setup": "setup.sh", "unpack": true } ]