Index: head/www/waterfox/Makefile =================================================================== --- head/www/waterfox/Makefile (revision 471886) +++ head/www/waterfox/Makefile (revision 471887) @@ -1,78 +1,78 @@ # $FreeBSD$ PORTNAME= waterfox DISTVERSION= 56.2.0-31 DISTVERSIONSUFFIX= -gf435a827f82ac -PORTREVISION= 2 +PORTREVISION= 3 CATEGORIES= www ipv6 MAINTAINER= jbeich@FreeBSD.org COMMENT= Distilled fork of Firefox DEPRECATED= Temporary experiment EXPIRATION_DATE=2018-07-10 BUILD_DEPENDS= nspr>=4.16:devel/nspr \ nss>=3.32.1:security/nss \ icu>=59.1,1:devel/icu \ libevent>=2.1.8:devel/libevent \ harfbuzz>=1.4.7:print/harfbuzz \ graphite2>=1.3.10:graphics/graphite2 \ png>=1.6.31:graphics/png \ libvorbis>=1.3.5,3:audio/libvorbis \ libvpx>=1.5.0:multimedia/libvpx \ sqlite3>=3.19.3:databases/sqlite3 \ ${PYTHON_PKGNAMEPREFIX}sqlite3>0:databases/py-sqlite3@${PY_FLAVOR} \ v4l_compat>0:multimedia/v4l_compat \ autoconf-2.13:devel/autoconf213 \ yasm:devel/yasm \ zip:archivers/zip # soundtouch>=1.9.0:audio/soundtouch \ LIB_DEPENDS= libv4l2.so:multimedia/libv4l USE_GITHUB= yes GH_ACCOUNT= MrAlex94 GH_PROJECT= Waterfox USE_GECKO= gecko MOZ_PKGCONFIG_FILES= # empty USE_MOZILLA= -soundtouch MOZILLA_NAME= Waterfox USE_GL= gl WATERFOX_ICON= ${MOZILLA}.png WATERFOX_ICON_SRC= ${PREFIX}/lib/${MOZILLA}/browser/chrome/icons/default/default256.png WATERFOX_DESKTOP= ${MOZSRC}/taskcluster/docker/firefox-snap/firefox.desktop MOZ_OPTIONS= --enable-application=browser \ --with-app-name=${MOZILLA} \ --with-app-basename=${MOZILLA_NAME} \ --with-distribution-id=org.${MOZILLA}project OPTIONS_DEFAULT= BUNDLED_CAIRO .include "${.CURDIR}/../../www/firefox/Makefile.options" # Inconsistent fallback order (libcubeb vs. audio_device) SNDIO_PREVENTS= ${OPTIONS_MULTI_AUDIO:NSNDIO} post-patch: @${REINPLACE_CMD} -e 's/%u/%U/' -e '/X-MultipleArgs/d' \ -e 's/firefox/${MOZILLA}/' \ -e 's/Firefox/${MOZILLA_NAME}/' \ ${WATERFOX_DESKTOP} @${REINPLACE_CMD} -e 's|%%LOCALBASE%%|${LOCALBASE}|g' \ ${WRKSRC}/browser/app/nsBrowserApp.cpp pre-configure: (cd ${WRKSRC} && ${LOCALBASE}/bin/autoconf-2.13) (cd ${WRKSRC}/js/src/ && ${LOCALBASE}/bin/autoconf-2.13) post-install: ${INSTALL_DATA} ${WATERFOX_DESKTOP} \ ${STAGEDIR}${PREFIX}/share/applications/${MOZILLA}.desktop ${MKDIR} ${STAGEDIR}${PREFIX}/share/pixmaps ${LN} -sf ${WATERFOX_ICON_SRC} ${STAGEDIR}${PREFIX}/share/pixmaps/${WATERFOX_ICON} .include Index: head/www/waterfox/files/patch-bug1321069 =================================================================== --- head/www/waterfox/files/patch-bug1321069 (nonexistent) +++ head/www/waterfox/files/patch-bug1321069 (revision 471887) @@ -0,0 +1,100 @@ +commit a09c25bcc3b4 +Author: Kartikaya Gupta +Date: Wed May 30 09:49:23 2018 -0400 + + Bug 1321069 - Redirect the end event of a long-tap sequence back to the content window. r=karlt, a=RyanVM + + In the case of a long-tap touch sequence, a new popup window (the + contextmenu) is spawned while the sequence is ongoing. The touch-end of + the sequence ends up getting delivered to the popup window, instead of + the original content window, and that causes the touch-handling + machinery state in the content window to get out of sync with reality. + This patch detects this scenario and redirects the touch events on the + popup window back to the original content window. + + MozReview-Commit-ID: L2vvKLlogRA + + --HG-- + extra : source : 27a160b7025ffaadd7cc1ce326ce8729c2b180a0 +--- + widget/gtk/nsWindow.cpp | 36 +++++++++++++++++++++++++++++++++++- + widget/gtk/nsWindow.h | 3 +++ + 2 files changed, 38 insertions(+), 1 deletion(-) + +diff --git widget/gtk/nsWindow.cpp widget/gtk/nsWindow.cpp +index 54ec8615051f1..18d0ccac4dbd6 100644 +--- widget/gtk/nsWindow.cpp ++++ widget/gtk/nsWindow.cpp +@@ -3455,11 +3455,41 @@ nsWindow::OnDragDataReceivedEvent(GtkWidget *aWidget, + aSelectionData, aInfo, aTime); + } + ++nsWindow* ++nsWindow::GetTransientForWindowIfPopup() ++{ ++ if (mWindowType != eWindowType_popup) { ++ return nullptr; ++ } ++ GtkWindow* toplevel = gtk_window_get_transient_for(GTK_WINDOW(mShell)); ++ if (toplevel) { ++ return get_window_for_gtk_widget(GTK_WIDGET(toplevel)); ++ } ++ return nullptr; ++} ++ ++bool ++nsWindow::IsHandlingTouchSequence(GdkEventSequence* aSequence) ++{ ++ return mHandleTouchEvent && mTouches.Contains(aSequence); ++} ++ + #if GTK_CHECK_VERSION(3,4,0) + gboolean + nsWindow::OnTouchEvent(GdkEventTouch* aEvent) + { + if (!mHandleTouchEvent) { ++ // If a popup window was spawned (e.g. as the result of a long-press) ++ // and touch events got diverted to that window within a touch sequence, ++ // ensure the touch event gets sent to the original window instead. We ++ // keep the checks here very conservative so that we only redirect ++ // events in this specific scenario. ++ nsWindow* targetWindow = GetTransientForWindowIfPopup(); ++ if (targetWindow && ++ targetWindow->IsHandlingTouchSequence(aEvent->sequence)) { ++ return targetWindow->OnTouchEvent(aEvent); ++ } ++ + return FALSE; + } + +@@ -4780,12 +4810,16 @@ nsWindow::GrabPointer(guint32 aTime) + return; + + gint retval; ++ // Note that we need GDK_TOUCH_MASK below to work around a GDK/X11 bug that ++ // causes touch events that would normally be received by this client on ++ // other windows to be discarded during the grab. + retval = gdk_pointer_grab(mGdkWindow, TRUE, + (GdkEventMask)(GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_LEAVE_NOTIFY_MASK | +- GDK_POINTER_MOTION_MASK), ++ GDK_POINTER_MOTION_MASK | ++ GDK_TOUCH_MASK), + (GdkWindow *)nullptr, nullptr, aTime); + + if (retval == GDK_GRAB_NOT_VIEWABLE) { +diff --git widget/gtk/nsWindow.h widget/gtk/nsWindow.h +index c28c1749c76dc..33e8c4db7c1c0 100644 +--- widget/gtk/nsWindow.h ++++ widget/gtk/nsWindow.h +@@ -434,6 +434,8 @@ private: + nsIWidgetListener* GetListener(); + bool IsComposited() const; + ++ nsWindow* GetTransientForWindowIfPopup(); ++ bool IsHandlingTouchSequence(GdkEventSequence* aSequence); + + GtkWidget *mShell; + MozContainer *mContainer; Property changes on: head/www/waterfox/files/patch-bug1321069 ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/www/waterfox/files/patch-bug1346126 =================================================================== --- head/www/waterfox/files/patch-bug1346126 (nonexistent) +++ head/www/waterfox/files/patch-bug1346126 (revision 471887) @@ -0,0 +1,27 @@ +commit b46bdf1c51e0 +Author: Ryan Hunt +Date: Fri Jun 1 11:18:07 2018 -0500 + + Bug 1346126 - Use RemoveAllChildren in ~ContainerLayerComposite. r=mattwoodrow, a=RyanVM + + --HG-- + extra : source : b9814173e9a8ebbf9e6a0cb6dbf751fadead17c4 +--- + gfx/layers/composite/ContainerLayerComposite.cpp | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git gfx/layers/composite/ContainerLayerComposite.cpp gfx/layers/composite/ContainerLayerComposite.cpp +index c40b3c19f8a88..74aed9bbcc03c 100644 +--- gfx/layers/composite/ContainerLayerComposite.cpp ++++ gfx/layers/composite/ContainerLayerComposite.cpp +@@ -650,9 +650,7 @@ ContainerLayerComposite::~ContainerLayerComposite() + // LayerManagerComposite::Destroy(), a parent + // *ContainerLayerComposite::Destroy(), or Disconnect() will trigger + // cleanup of our resources. +- while (mFirstChild) { +- RemoveChild(mFirstChild); +- } ++ RemoveAllChildren(); + } + + void Property changes on: head/www/waterfox/files/patch-bug1346126 ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/www/waterfox/files/patch-bug1453127 =================================================================== --- head/www/waterfox/files/patch-bug1453127 (revision 471886) +++ head/www/waterfox/files/patch-bug1453127 (revision 471887) @@ -1,36 +1,605 @@ -commit 7f8f5d958ed6 -Author: Bryce Van Dyk -Date: Wed Apr 18 15:30:57 2018 -0400 +commit 890e77744a2a +Author: Andreas Pehrson +Date: Tue May 29 10:13:14 2018 +0200 - Bug 1453127 - Do not use iterators in MediaStreamTrack when removing listeners. r=pehrsons a=lizzard - - --HG-- - extra : source : 6b3aaee40f7507e240da08d6e073cff3c53971f4 + Bug 1453127 - Make sure decoder-captured tracks end when changing src. r=jya, a=RyanVM --- - dom/media/MediaStreamTrack.cpp | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) + dom/html/HTMLMediaElement.cpp | 18 ++++++++++++++++++ + dom/html/HTMLMediaElement.h | 5 +++++ + 2 files changed, 23 insertions(+) -diff --git dom/media/MediaStreamTrack.cpp dom/media/MediaStreamTrack.cpp -index 010373e9086d..af6c6014cf02 100644 ---- dom/media/MediaStreamTrack.cpp -+++ dom/media/MediaStreamTrack.cpp -@@ -166,11 +166,15 @@ MediaStreamTrack::Destroy() - mPrincipalHandleListener->Forget(); - mPrincipalHandleListener = nullptr; +diff --git dom/html/HTMLMediaElement.cpp dom/html/HTMLMediaElement.cpp +index b0e787fbf9278..d1502cecfb237 100644 +--- dom/html/HTMLMediaElement.cpp ++++ dom/html/HTMLMediaElement.cpp +@@ -1429,6 +1429,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTM + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mErrorSink->mError) + for (uint32_t i = 0; i < tmp->mOutputStreams.Length(); ++i) { + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOutputStreams[i].mStream); ++ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOutputStreams[i].mPreCreatedTracks) } -- for (auto l : mTrackListeners) { -- RemoveListener(l); -+ // Remove all listeners -- avoid iterating over the list we're removing from -+ const nsTArray> trackListeners(mTrackListeners); -+ for (auto listener : trackListeners) { -+ RemoveListener(listener); + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPlayed); + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTextTrackManager) +@@ -3494,6 +3495,7 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded, + RefPtr track = + out->mStream->CreateDOMTrack(audioTrackId, MediaSegment::AUDIO, + trackSource); ++ out->mPreCreatedTracks.AppendElement(track); + out->mStream->AddTrackInternal(track); + LOG(LogLevel::Debug, + ("Created audio track %d for captured decoder", audioTrackId)); +@@ -3505,6 +3507,7 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded, + RefPtr track = + out->mStream->CreateDOMTrack(videoTrackId, MediaSegment::VIDEO, + trackSource); ++ out->mPreCreatedTracks.AppendElement(track); + out->mStream->AddTrackInternal(track); + LOG(LogLevel::Debug, + ("Created video track %d for captured decoder", videoTrackId)); +@@ -7526,6 +7529,21 @@ HTMLMediaElement::RemoveMediaTracks() } -- for (auto l : mDirectTrackListeners) { -- RemoveDirectListener(l); -+ // Do the same as above for direct listeners -+ const nsTArray> directTrackListeners(mDirectTrackListeners); -+ for (auto listener : directTrackListeners) { -+ RemoveDirectListener(listener); + + mMediaTracksConstructed = false; ++ ++ for (OutputMediaStream& ms : mOutputStreams) { ++ if (!ms.mCapturingDecoder) { ++ continue; ++ } ++ for (RefPtr& t : ms.mPreCreatedTracks) { ++ if (t->Ended()) { ++ continue; ++ } ++ mAbstractMainThread->Dispatch(NewRunnableMethod( ++ "dom::HTMLMediaElement::RemoveMediaTracks", ++ t, &MediaStreamTrack::OverrideEnded)); ++ } ++ ms.mPreCreatedTracks.Clear(); ++ } + } + + class MediaElementGMPCrashHelper : public GMPCrashHelper +diff --git dom/html/HTMLMediaElement.h dom/html/HTMLMediaElement.h +index a81a2dfb22f39..126aaee2ae655 100644 +--- dom/html/HTMLMediaElement.h ++++ dom/html/HTMLMediaElement.h +@@ -843,6 +843,11 @@ protected: + bool mCapturingDecoder; + bool mCapturingMediaStream; + ++ // The following members are keeping state for a captured MediaDecoder. ++ // Tracks that were created on main thread before MediaDecoder fed them ++ // to the MediaStreamGraph. ++ nsTArray> mPreCreatedTracks; ++ + // The following members are keeping state for a captured MediaStream. + TrackID mNextAvailableTrackID; + nsTArray>> mTrackPorts; + +commit dee1e1ec98be +Author: Andreas Pehrson +Date: Tue May 29 10:21:51 2018 +0200 + + Bug 1453127 - Ensure TrackID uniqueness for captured MediaDecoder. r=jya, a=RyanVM +--- + dom/html/HTMLMediaElement.cpp | 22 +++++++--- + dom/html/HTMLMediaElement.h | 2 +- + dom/media/MediaDecoder.cpp | 13 +++++- + dom/media/MediaDecoder.h | 3 ++ + dom/media/MediaDecoderStateMachine.cpp | 10 ++++- + dom/media/MediaDecoderStateMachine.h | 5 ++- + dom/media/mediasink/DecodedStream.cpp | 11 +++-- + dom/media/mediasink/OutputStreamManager.cpp | 68 ++++++++++++++++++++++------- + dom/media/mediasink/OutputStreamManager.h | 33 ++++++++++---- + 9 files changed, 131 insertions(+), 36 deletions(-) + +diff --git dom/html/HTMLMediaElement.cpp dom/html/HTMLMediaElement.cpp +index d1502cecfb237..d11c9d03a7e52 100644 +--- dom/html/HTMLMediaElement.cpp ++++ dom/html/HTMLMediaElement.cpp +@@ -1710,6 +1710,14 @@ void HTMLMediaElement::ShutdownDecoder() + if (mMediaSource) { + mMediaSource->CompletePendingTransactions(); } ++ for (OutputMediaStream& out : mOutputStreams) { ++ if (!out.mCapturingDecoder) { ++ continue; ++ } ++ out.mNextAvailableTrackID = std::max( ++ mDecoder->NextAvailableTrackIDFor(out.mStream->GetInputStream()), ++ out.mNextAvailableTrackID); ++ } + mDecoder->Shutdown(); + mDecoder = nullptr; } +@@ -3476,6 +3484,7 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded, + if (mDecoder) { + out->mCapturingDecoder = true; + mDecoder->AddOutputStream(out->mStream->GetInputStream()->AsProcessedStream(), ++ out->mNextAvailableTrackID, + aFinishWhenEnded); + } else if (mSrcStream) { + out->mCapturingMediaStream = true; +@@ -3489,11 +3498,12 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded, + if (mDecoder) { + if (HasAudio()) { +- TrackID audioTrackId = mMediaInfo.mAudio.mTrackId; ++ TrackID audioTrackId = out->mNextAvailableTrackID++; + RefPtr trackSource = + getter->GetMediaStreamTrackSource(audioTrackId); + RefPtr track = +- out->mStream->CreateDOMTrack(audioTrackId, MediaSegment::AUDIO, ++ out->mStream->CreateDOMTrack(audioTrackId, ++ MediaSegment::AUDIO, + trackSource); + out->mPreCreatedTracks.AppendElement(track); + out->mStream->AddTrackInternal(track); +@@ -3501,7 +3511,7 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded, + ("Created audio track %d for captured decoder", audioTrackId)); + } + if (IsVideo() && HasVideo() && !out->mCapturingAudioOnly) { +- TrackID videoTrackId = mMediaInfo.mVideo.mTrackId; ++ TrackID videoTrackId = out->mNextAvailableTrackID++; + RefPtr trackSource = + getter->GetMediaStreamTrackSource(videoTrackId); + RefPtr track = +@@ -4241,11 +4251,12 @@ HTMLMediaElement::WakeLockRelease() + } + + HTMLMediaElement::OutputMediaStream::OutputMediaStream() +- : mFinishWhenEnded(false) ++ : mNextAvailableTrackID(1) ++ , mFinishWhenEnded(false) + , mCapturingAudioOnly(false) + , mCapturingDecoder(false) + , mCapturingMediaStream(false) +- , mNextAvailableTrackID(1) {} ++{} + + HTMLMediaElement::OutputMediaStream::~OutputMediaStream() + { +@@ -4844,6 +4855,7 @@ HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder) + + ms.mCapturingDecoder = true; + aDecoder->AddOutputStream(ms.mStream->GetInputStream()->AsProcessedStream(), ++ ms.mNextAvailableTrackID, + ms.mFinishWhenEnded); + } + +diff --git dom/html/HTMLMediaElement.h dom/html/HTMLMediaElement.h +index 126aaee2ae655..aeccfa5ba221d 100644 +--- dom/html/HTMLMediaElement.h ++++ dom/html/HTMLMediaElement.h +@@ -838,6 +838,7 @@ protected: + ~OutputMediaStream(); + + RefPtr mStream; ++ TrackID mNextAvailableTrackID; + bool mFinishWhenEnded; + bool mCapturingAudioOnly; + bool mCapturingDecoder; +@@ -849,7 +850,6 @@ protected: + nsTArray> mPreCreatedTracks; + + // The following members are keeping state for a captured MediaStream. +- TrackID mNextAvailableTrackID; + nsTArray>> mTrackPorts; + }; + +diff --git dom/media/MediaDecoder.cpp dom/media/MediaDecoder.cpp +index c4bf14d1206fd..11d48fb9921c1 100644 +--- dom/media/MediaDecoder.cpp ++++ dom/media/MediaDecoder.cpp +@@ -322,11 +322,13 @@ MediaDecoder::SetVolume(double aVolume) + + void + MediaDecoder::AddOutputStream(ProcessedMediaStream* aStream, ++ TrackID aNextAvailableTrackID, + bool aFinishWhenEnded) + { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(mDecoderStateMachine, "Must be called after Load()."); +- mDecoderStateMachine->AddOutputStream(aStream, aFinishWhenEnded); ++ mDecoderStateMachine->AddOutputStream( ++ aStream, aNextAvailableTrackID, aFinishWhenEnded); + } + + void +@@ -337,6 +339,14 @@ MediaDecoder::RemoveOutputStream(MediaStream* aStream) + mDecoderStateMachine->RemoveOutputStream(aStream); + } + ++TrackID ++MediaDecoder::NextAvailableTrackIDFor(MediaStream* aOutputStream) const ++{ ++ MOZ_ASSERT(NS_IsMainThread()); ++ MOZ_ASSERT(mDecoderStateMachine, "Must be called after Load()."); ++ return mDecoderStateMachine->NextAvailableTrackIDFor(aOutputStream); ++} ++ + double + MediaDecoder::GetDuration() + { +diff --git dom/media/MediaDecoder.h dom/media/MediaDecoder.h +index a8708b390433a..357f87ef8e0e8 100644 +--- dom/media/MediaDecoder.h ++++ dom/media/MediaDecoder.h +@@ -183,9 +183,12 @@ public: + // The stream is initially blocked. The decoder is responsible for unblocking + // it while it is playing back. + virtual void AddOutputStream(ProcessedMediaStream* aStream, ++ TrackID aNextAvailableTrackID, + bool aFinishWhenEnded); + // Remove an output stream added with AddOutputStream. + virtual void RemoveOutputStream(MediaStream* aStream); ++ // The next TrackID that can be used without risk of a collision. ++ virtual TrackID NextAvailableTrackIDFor(MediaStream* aOutputStream) const; + + // Return the duration of the video in seconds. + virtual double GetDuration(); +diff --git dom/media/MediaDecoderStateMachine.cpp dom/media/MediaDecoderStateMachine.cpp +index cea333f5d9a05..fef3b318b48cb 100644 +--- dom/media/MediaDecoderStateMachine.cpp ++++ dom/media/MediaDecoderStateMachine.cpp +@@ -3973,11 +3973,12 @@ MediaDecoderStateMachine::RequestDebugInfo() + } + + void MediaDecoderStateMachine::AddOutputStream(ProcessedMediaStream* aStream, ++ TrackID aNextAvailableTrackID, + bool aFinishWhenEnded) + { + MOZ_ASSERT(NS_IsMainThread()); + LOG("AddOutputStream aStream=%p!", aStream); +- mOutputStreamManager->Add(aStream, aFinishWhenEnded); ++ mOutputStreamManager->Add(aStream, aNextAvailableTrackID, aFinishWhenEnded); + nsCOMPtr r = + NewRunnableMethod("MediaDecoderStateMachine::SetAudioCaptured", + this, +@@ -4001,6 +4002,13 @@ void MediaDecoderStateMachine::RemoveOutputStream(MediaStream* aStream) + } + } + ++TrackID ++MediaDecoderStateMachine::NextAvailableTrackIDFor(MediaStream* aOutputStream) const ++{ ++ MOZ_ASSERT(NS_IsMainThread()); ++ return mOutputStreamManager->NextAvailableTrackIDFor(aOutputStream); ++} ++ + class VideoQueueMemoryFunctor : public nsDequeFunctor + { + public: +diff --git dom/media/MediaDecoderStateMachine.h dom/media/MediaDecoderStateMachine.h +index 6f7fcf825ea83..b59bcca7dc70a 100644 +--- dom/media/MediaDecoderStateMachine.h ++++ dom/media/MediaDecoderStateMachine.h +@@ -175,9 +175,12 @@ public: + + RefPtr RequestDebugInfo(); + +- void AddOutputStream(ProcessedMediaStream* aStream, bool aFinishWhenEnded); ++ void AddOutputStream(ProcessedMediaStream* aStream, ++ TrackID aNextAvailableTrackID, ++ bool aFinishWhenEnded); + // Remove an output stream added with AddOutputStream. + void RemoveOutputStream(MediaStream* aStream); ++ TrackID NextAvailableTrackIDFor(MediaStream* aOutputStream) const; + + // Seeks to the decoder to aTarget asynchronously. + RefPtr InvokeSeek(const SeekTarget& aTarget); +diff --git dom/media/mediasink/DecodedStream.cpp dom/media/mediasink/DecodedStream.cpp +index 5244a087c77e7..b5c40b9067e57 100644 +--- dom/media/mediasink/DecodedStream.cpp ++++ dom/media/mediasink/DecodedStream.cpp +@@ -193,17 +193,22 @@ DecodedStreamData::DecodedStreamData(OutputStreamManager* aOutputStreamManager, + , mAbstractMainThread(aMainThread) + { + mStream->AddListener(mListener); +- mOutputStreamManager->Connect(mStream); ++ TrackID audioTrack = TRACK_NONE; ++ TrackID videoTrack = TRACK_NONE; + + // Initialize tracks. + if (aInit.mInfo.HasAudio()) { +- mStream->AddAudioTrack(aInit.mInfo.mAudio.mTrackId, ++ audioTrack = aInit.mInfo.mAudio.mTrackId; ++ mStream->AddAudioTrack(audioTrack, + aInit.mInfo.mAudio.mRate, + 0, new AudioSegment()); + } + if (aInit.mInfo.HasVideo()) { +- mStream->AddTrack(aInit.mInfo.mVideo.mTrackId, 0, new VideoSegment()); ++ videoTrack = aInit.mInfo.mVideo.mTrackId; ++ mStream->AddTrack(videoTrack, 0, new VideoSegment()); + } ++ ++ mOutputStreamManager->Connect(mStream, audioTrack, videoTrack); + } + + DecodedStreamData::~DecodedStreamData() +diff --git dom/media/mediasink/OutputStreamManager.cpp dom/media/mediasink/OutputStreamManager.cpp +index d5685837a6783..b3ec8936d435e 100644 +--- dom/media/mediasink/OutputStreamManager.cpp ++++ dom/media/mediasink/OutputStreamManager.cpp +@@ -13,29 +13,41 @@ OutputStreamData::~OutputStreamData() + { + MOZ_ASSERT(NS_IsMainThread()); + // Break the connection to the input stream if necessary. +- if (mPort) { +- mPort->Destroy(); ++ for (RefPtr& port : mPorts) { ++ port->Destroy(); + } + } + + void +-OutputStreamData::Init(OutputStreamManager* aOwner, ProcessedMediaStream* aStream) ++OutputStreamData::Init(OutputStreamManager* aOwner, ++ ProcessedMediaStream* aStream, ++ TrackID aNextAvailableTrackID) + { + mOwner = aOwner; + mStream = aStream; ++ mNextAvailableTrackID = aNextAvailableTrackID; + } + + bool +-OutputStreamData::Connect(MediaStream* aStream) ++OutputStreamData::Connect(MediaStream* aStream, ++ TrackID aInputAudioTrackID, ++ TrackID aInputVideoTrackID) + { + MOZ_ASSERT(NS_IsMainThread()); +- MOZ_ASSERT(!mPort, "Already connected?"); ++ MOZ_ASSERT(mPorts.IsEmpty(), "Already connected?"); + + if (mStream->IsDestroyed()) { + return false; + } + +- mPort = mStream->AllocateInputPort(aStream); ++ for (TrackID tid : {aInputAudioTrackID, aInputVideoTrackID}) { ++ if (tid == TRACK_NONE) { ++ continue; ++ } ++ MOZ_ASSERT(IsTrackIDExplicit(tid)); ++ mPorts.AppendElement(mStream->AllocateInputPort( ++ aStream, tid, mNextAvailableTrackID++)); ++ } + return true; + } + +@@ -51,11 +63,11 @@ OutputStreamData::Disconnect() + return false; + } + +- // Disconnect the existing port if necessary. +- if (mPort) { +- mPort->Destroy(); +- mPort = nullptr; ++ // Disconnect any existing port. ++ for (RefPtr& port : mPorts) { ++ port->Destroy(); + } ++ mPorts.Clear(); + return true; + } + +@@ -71,8 +83,16 @@ OutputStreamData::Graph() const + return mStream->Graph(); + } + ++TrackID ++OutputStreamData::NextAvailableTrackID() const ++{ ++ return mNextAvailableTrackID; ++} ++ + void +-OutputStreamManager::Add(ProcessedMediaStream* aStream, bool aFinishWhenEnded) ++OutputStreamManager::Add(ProcessedMediaStream* aStream, ++ TrackID aNextAvailableTrackID, ++ bool aFinishWhenEnded) + { + MOZ_ASSERT(NS_IsMainThread()); + // All streams must belong to the same graph. +@@ -84,12 +104,12 @@ OutputStreamManager::Add(ProcessedMediaStream* aStream, bool aFinishWhenEnded) + } + + OutputStreamData* p = mStreams.AppendElement(); +- p->Init(this, aStream); ++ p->Init(this, aStream, aNextAvailableTrackID); + + // Connect to the input stream if we have one. Otherwise the output stream + // will be connected in Connect(). + if (mInputStream) { +- p->Connect(mInputStream); ++ p->Connect(mInputStream, mInputAudioTrackID, mInputVideoTrackID); + } + } + +@@ -105,13 +125,29 @@ OutputStreamManager::Remove(MediaStream* aStream) + } + } + ++TrackID ++OutputStreamManager::NextAvailableTrackIDFor(MediaStream* aOutputStream) const ++{ ++ MOZ_ASSERT(NS_IsMainThread()); ++ for (const OutputStreamData& out : mStreams) { ++ if (out.Equals(aOutputStream)) { ++ return out.NextAvailableTrackID(); ++ } ++ } ++ return TRACK_INVALID; ++} ++ + void +-OutputStreamManager::Connect(MediaStream* aStream) ++OutputStreamManager::Connect(MediaStream* aStream, ++ TrackID aAudioTrackID, ++ TrackID aVideoTrackID) + { + MOZ_ASSERT(NS_IsMainThread()); + mInputStream = aStream; ++ mInputAudioTrackID = aAudioTrackID; ++ mInputVideoTrackID = aVideoTrackID; + for (int32_t i = mStreams.Length() - 1; i >= 0; --i) { +- if (!mStreams[i].Connect(aStream)) { ++ if (!mStreams[i].Connect(aStream, mInputAudioTrackID, mInputVideoTrackID)) { + // Probably the DOMMediaStream was GCed. Clean up. + mStreams.RemoveElementAt(i); + } +@@ -123,6 +159,8 @@ OutputStreamManager::Disconnect() + { + MOZ_ASSERT(NS_IsMainThread()); + mInputStream = nullptr; ++ mInputAudioTrackID = TRACK_INVALID; ++ mInputVideoTrackID = TRACK_INVALID; + for (int32_t i = mStreams.Length() - 1; i >= 0; --i) { + if (!mStreams[i].Disconnect()) { + // Probably the DOMMediaStream was GCed. Clean up. +diff --git dom/media/mediasink/OutputStreamManager.h dom/media/mediasink/OutputStreamManager.h +index 7f91a60c1e9dd..8e89878e45090 100644 +--- dom/media/mediasink/OutputStreamManager.h ++++ dom/media/mediasink/OutputStreamManager.h +@@ -9,6 +9,7 @@ + + #include "mozilla/RefPtr.h" + #include "nsTArray.h" ++#include "MediaSegment.h" + + namespace mozilla { + +@@ -21,11 +22,13 @@ class ProcessedMediaStream; + class OutputStreamData { + public: + ~OutputStreamData(); +- void Init(OutputStreamManager* aOwner, ProcessedMediaStream* aStream); ++ void Init(OutputStreamManager* aOwner, ++ ProcessedMediaStream* aStream, ++ TrackID aNextAvailableTrackID); + +- // Connect mStream to the input stream. ++ // Connect the given input stream's audio and video tracks to mStream. + // Return false is mStream is already destroyed, otherwise true. +- bool Connect(MediaStream* aStream); ++ bool Connect(MediaStream* aStream, TrackID aAudioTrackID, TrackID aVideoTrackID); + // Disconnect mStream from its input stream. + // Return false is mStream is already destroyed, otherwise true. + bool Disconnect(); +@@ -34,12 +37,16 @@ public: + bool Equals(MediaStream* aStream) const; + // Return the graph mStream belongs to. + MediaStreamGraph* Graph() const; ++ // The next TrackID that will not cause a collision in mStream. ++ TrackID NextAvailableTrackID() const; + + private: + OutputStreamManager* mOwner; + RefPtr mStream; +- // mPort connects our mStream to an input stream. +- RefPtr mPort; ++ // mPort connects an input stream to our mStream. ++ nsTArray> mPorts; ++ // For guaranteeing TrackID uniqueness in our mStream. ++ TrackID mNextAvailableTrackID = TRACK_INVALID; + }; + + class OutputStreamManager { +@@ -47,18 +54,24 @@ class OutputStreamManager { + + public: + // Add the output stream to the collection. +- void Add(ProcessedMediaStream* aStream, bool aFinishWhenEnded); ++ void Add(ProcessedMediaStream* aStream, ++ TrackID aNextAvailableTrackID, ++ bool aFinishWhenEnded); + // Remove the output stream from the collection. + void Remove(MediaStream* aStream); ++ // The next TrackID that will not cause a collision in aOutputStream. ++ TrackID NextAvailableTrackIDFor(MediaStream* aOutputStream) const; + // Return true if the collection empty. + bool IsEmpty() const + { + MOZ_ASSERT(NS_IsMainThread()); + return mStreams.IsEmpty(); + } +- // Connect all output streams in the collection to the input stream. +- void Connect(MediaStream* aStream); +- // Disconnect all output streams from the input stream. ++ // Connect the given input stream's tracks to all output streams. ++ void Connect(MediaStream* aStream, ++ TrackID aAudioTrackID, ++ TrackID aVideoTrackID); ++ // Disconnect the input stream to all output streams. + void Disconnect(); + // Return the graph these streams belong to or null if empty. + MediaStreamGraph* Graph() const +@@ -72,6 +85,8 @@ private: + // Keep the input stream so we can connect the output streams that + // are added after Connect(). + RefPtr mInputStream; ++ TrackID mInputAudioTrackID = TRACK_INVALID; ++ TrackID mInputVideoTrackID = TRACK_INVALID; + nsTArray mStreams; + }; + + +commit 91317ba976c8 +Author: Andreas Pehrson +Date: Wed May 30 10:44:56 2018 +0200 + + Bug 1453127 - Clear output streams on shutdown. r=jya, a=RyanVM +--- + dom/media/MediaDecoderStateMachine.cpp | 4 ++++ + dom/media/mediasink/OutputStreamManager.cpp | 7 +++++++ + dom/media/mediasink/OutputStreamManager.h | 2 ++ + 3 files changed, 13 insertions(+) + +diff --git dom/media/MediaDecoderStateMachine.cpp dom/media/MediaDecoderStateMachine.cpp +index fef3b318b48cb..582fe7ba995fe 100644 +--- dom/media/MediaDecoderStateMachine.cpp ++++ dom/media/MediaDecoderStateMachine.cpp +@@ -3564,6 +3564,10 @@ MediaDecoderStateMachine::FinishDecodeFirstFrame() + RefPtr + MediaDecoderStateMachine::BeginShutdown() + { ++ MOZ_ASSERT(NS_IsMainThread()); ++ if (mOutputStreamManager) { ++ mOutputStreamManager->Clear(); ++ } + return InvokeAsync(OwnerThread(), this, __func__, + &MediaDecoderStateMachine::Shutdown); + } +diff --git dom/media/mediasink/OutputStreamManager.cpp dom/media/mediasink/OutputStreamManager.cpp +index b3ec8936d435e..7ecc203ed8309 100644 +--- dom/media/mediasink/OutputStreamManager.cpp ++++ dom/media/mediasink/OutputStreamManager.cpp +@@ -125,6 +125,13 @@ OutputStreamManager::Remove(MediaStream* aStream) + } + } + ++void ++OutputStreamManager::Clear() ++{ ++ MOZ_ASSERT(NS_IsMainThread()); ++ mStreams.Clear(); ++} ++ + TrackID + OutputStreamManager::NextAvailableTrackIDFor(MediaStream* aOutputStream) const + { +diff --git dom/media/mediasink/OutputStreamManager.h dom/media/mediasink/OutputStreamManager.h +index 8e89878e45090..ec5040178ee0b 100644 +--- dom/media/mediasink/OutputStreamManager.h ++++ dom/media/mediasink/OutputStreamManager.h +@@ -59,6 +59,8 @@ public: + bool aFinishWhenEnded); + // Remove the output stream from the collection. + void Remove(MediaStream* aStream); ++ // Clear all output streams from the collection. ++ void Clear(); + // The next TrackID that will not cause a collision in aOutputStream. + TrackID NextAvailableTrackIDFor(MediaStream* aOutputStream) const; + // Return true if the collection empty. Index: head/www/waterfox/files/patch-bug1461448 =================================================================== --- head/www/waterfox/files/patch-bug1461448 (nonexistent) +++ head/www/waterfox/files/patch-bug1461448 (revision 471887) @@ -0,0 +1,80 @@ +commit cd48fc1a4518 +Author: Jon Coppeard +Date: Fri May 18 10:29:00 2018 +0100 + + Bug 1461448 - Add gray marking phase to delayed marking phase. r=sfink, a=RyanVM + + --HG-- + extra : source : ff105a4cff4eb85a9e50a4ccf8144069412521e5 +--- + js/src/gc/GenerateStatsPhases.py | 6 +++-- + js/src/jit-test/tests/gc/bug-1461448.js | 40 +++++++++++++++++++++++++++++++++ + 2 files changed, 44 insertions(+), 2 deletions(-) + +diff --git js/src/gc/GenerateStatsPhases.py js/src/gc/GenerateStatsPhases.py +index ece873dc05004..2daf83555e33b 100644 +--- js/src/gc/GenerateStatsPhases.py ++++ js/src/gc/GenerateStatsPhases.py +@@ -88,12 +88,14 @@ PhaseKindGraphRoots = [ + PhaseKind("PURGE", "Purge", 5), + PhaseKind("PURGE_SHAPE_TABLES", "Purge ShapeTables", 60), + JoinParallelTasksPhaseKind +- ]), ++ ]), + PhaseKind("MARK", "Mark", 6, [ + MarkRootsPhaseKind, + UnmarkGrayPhaseKind, +- PhaseKind("MARK_DELAYED", "Mark Delayed", 8) ++ PhaseKind("MARK_DELAYED", "Mark Delayed", 8, [ ++ UnmarkGrayPhaseKind, + ]), ++ ]), + PhaseKind("SWEEP", "Sweep", 9, [ + PhaseKind("SWEEP_MARK", "Mark During Sweeping", 10, [ + UnmarkGrayPhaseKind, +diff --git js/src/jit-test/tests/gc/bug-1461448.js js/src/jit-test/tests/gc/bug-1461448.js +new file mode 100644 +index 0000000000000..3b9e69df89101 +--- /dev/null ++++ js/src/jit-test/tests/gc/bug-1461448.js +@@ -0,0 +1,40 @@ ++if (helperThreadCount() === 0) ++ quit(); ++ ++gczeal(0); ++ ++let lfPreamble = ` ++ var lfOffThreadGlobal = newGlobal(); ++ for (lfLocal in this) ++ try {} catch(lfVare5) {} ++`; ++evaluate(lfPreamble); ++evaluate(` ++ var g = newGlobal(); ++ var dbg = new Debugger; ++ var gw = dbg.addDebuggee(g); ++ for (lfLocal in this) ++ if (!(lfLocal in lfOffThreadGlobal)) ++ try { ++ lfOffThreadGlobal[lfLocal] = this[lfLocal]; ++ } catch(lfVare5) {} ++ var g = newGlobal(); ++ var gw = dbg.addDebuggee(g); ++`); ++lfOffThreadGlobal.offThreadCompileScript(` ++ gcparam("markStackLimit", 1); ++ grayRoot()[0] = "foo"; ++`); ++lfOffThreadGlobal.runOffThreadScript(); ++eval(` ++ var lfOffThreadGlobal = newGlobal(); ++ try { evaluate(\` ++ gczeal(18, 1); ++ grayRoot()[0] = "foo"; ++ let inst = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary( ++ \\\`(module ++ (memory (export "memory") 1 1) ++ )\\\` ++ ))); ++\`); } catch(exc) {} ++`); Property changes on: head/www/waterfox/files/patch-bug1461448 ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/www/waterfox/files/patch-z-bug1392739 =================================================================== --- head/www/waterfox/files/patch-z-bug1392739 (nonexistent) +++ head/www/waterfox/files/patch-z-bug1392739 (revision 471887) @@ -0,0 +1,28 @@ +commit ef5f80343490 +Author: Valentin Gosu +Date: Mon Jun 4 13:57:51 2018 +0200 + + Bug 1392739 - Use CheckedInt in nsStandardURL::Deserialize(). r=mayhemer, a=RyanVM + + --HG-- + extra : source : 5c47f8a1bad20a61a1ec699cc6508e21f39a7a98 +--- + netwerk/base/nsStandardURL.cpp | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git netwerk/base/nsStandardURL.cpp netwerk/base/nsStandardURL.cpp +index db7bf74f31812..4d3da91f88b20 100644 +--- netwerk/base/nsStandardURL.cpp ++++ netwerk/base/nsStandardURL.cpp +@@ -3552,8 +3551,10 @@ FromIPCSegment(const nsACString& aSpec, const ipc::StandardURLSegment& aSegment, + return false; + } + ++ CheckedInt segmentLen = aSegment.position(); ++ segmentLen += aSegment.length(); + // Make sure the segment does not extend beyond the spec. +- if (NS_WARN_IF(aSegment.position() + aSegment.length() > aSpec.Length())) { ++ if (NS_WARN_IF(!segmentLen.isValid() || segmentLen.value() > aSpec.Length())) { + return false; + } + Property changes on: head/www/waterfox/files/patch-z-bug1392739 ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property