diff --git a/accessible/base/TreeWalker.cpp b/accessible/base/TreeWalker.cpp index 3e778a0cc81c..8e97e38c7a60 100644 --- a/accessible/base/TreeWalker.cpp +++ b/accessible/base/TreeWalker.cpp @@ -9,6 +9,7 @@ #include "nsAccessibilityService.h" #include "DocAccessible.h" +#include "mozilla/dom/ChildIterator.h" #include "mozilla/dom/Element.h" using namespace mozilla::a11y; @@ -22,13 +23,12 @@ namespace a11y { struct WalkState { - WalkState(nsIContent *aContent) : - content(aContent), childIdx(0), prevState(nullptr) {} + WalkState(nsIContent *aContent, uint32_t aFilter) : + content(aContent), prevState(nullptr), iter(aContent, aFilter) {} nsCOMPtr content; - nsCOMPtr childList; - uint32_t childIdx; WalkState *prevState; + dom::AllChildrenIterator iter; }; } // namespace a11y @@ -45,14 +45,13 @@ TreeWalker:: { NS_ASSERTION(aContent, "No node for the accessible tree walker!"); - if (aContent) - mState = new WalkState(aContent); - mChildFilter = mContext->CanHaveAnonChildren() ? nsIContent::eAllChildren : nsIContent::eAllButXBL; - mChildFilter |= nsIContent::eSkipPlaceholderContent; + if (aContent) + mState = new WalkState(aContent, mChildFilter); + MOZ_COUNT_CTOR(TreeWalker); } @@ -74,17 +73,7 @@ TreeWalker::NextChildInternal(bool aNoWalkUp) if (!mState || !mState->content) return nullptr; - if (!mState->childList) - mState->childList = mState->content->GetChildren(mChildFilter); - - uint32_t length = 0; - if (mState->childList) - mState->childList->GetLength(&length); - - while (mState->childIdx < length) { - nsIContent* childNode = mState->childList->Item(mState->childIdx); - mState->childIdx++; - + while (nsIContent* childNode = mState->iter.GetNextChild()) { bool isSubtreeHidden = false; Accessible* accessible = mFlags & eWalkCache ? mDoc->GetAccessible(childNode) : @@ -95,7 +84,7 @@ TreeWalker::NextChildInternal(bool aNoWalkUp) return accessible; // Walk down into subtree to find accessibles. - if (!isSubtreeHidden) { + if (!isSubtreeHidden && childNode->IsElement()) { PushState(childNode); accessible = NextChildInternal(true); if (accessible) @@ -123,14 +112,7 @@ TreeWalker::NextChildInternal(bool aNoWalkUp) return nullptr; PushState(parentNode->AsElement()); - mState->childList = mState->content->GetChildren(mChildFilter); - length = 0; - if (mState->childList) - mState->childList->GetLength(&length); - - while (mState->childIdx < length) { - nsIContent* childNode = mState->childList->Item(mState->childIdx); - mState->childIdx++; + while (nsIContent* childNode = mState->iter.GetNextChild()) { if (childNode == anchorNode) return NextChildInternal(false); } @@ -153,7 +135,7 @@ TreeWalker::PopState() void TreeWalker::PushState(nsIContent* aContent) { - WalkState* nextToLastState = new WalkState(aContent); + WalkState* nextToLastState = new WalkState(aContent, mChildFilter); nextToLastState->prevState = mState; mState = nextToLastState; } diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 228cb9bea14e..ca8abf8ee841 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 5c5de49e830d..edb0fa309c30 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 6e1b7effe75f..cbf1fea1d834 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/sources.xml b/b2g/config/emulator/sources.xml index 228cb9bea14e..ca8abf8ee841 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index fda8b59317fd..96ec004587c3 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + @@ -133,7 +133,7 @@ - + diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 032b9e35ceb8..9d346c0f8d0a 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "ac2ad84f3387c493bc6c2b1c0496b0fc10a49a49", + "revision": "c3b71e7993bb9ed0f45994f70552601e0466f0e3", "repo_path": "/integration/gaia-central" } diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index d9480e1fd113..fd055f5da55d 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index f57af41c3ec0..ffa01defc74c 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 0f774290d9aa..84490b006a64 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index 2af3f4aea56c..db8aae58fcef 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/content/base/public/Element.h b/content/base/public/Element.h index e09717136311..93256938b088 100644 --- a/content/base/public/Element.h +++ b/content/base/public/Element.h @@ -1488,11 +1488,8 @@ NS_IMETHOD SetAttributeNode(nsIDOMAttr* newAttr, \ if (!newAttr) { \ return NS_ERROR_INVALID_POINTER; \ } \ - mozilla::dom::Attr* attr = mozilla::dom::Attr::FromDOMAttr(newAttr); \ - if (!attr) { \ - return NS_ERROR_INVALID_POINTER; \ - } \ mozilla::ErrorResult rv; \ + mozilla::dom::Attr* attr = static_cast(newAttr); \ *_retval = Element::SetAttributeNode(*attr, rv).take(); \ return rv.ErrorCode(); \ } \ @@ -1502,11 +1499,8 @@ NS_IMETHOD RemoveAttributeNode(nsIDOMAttr* oldAttr, \ if (!oldAttr) { \ return NS_ERROR_INVALID_POINTER; \ } \ - mozilla::dom::Attr* attr = mozilla::dom::Attr::FromDOMAttr(oldAttr); \ - if (!attr) { \ - return NS_ERROR_INVALID_POINTER; \ - } \ mozilla::ErrorResult rv; \ + mozilla::dom::Attr* attr = static_cast(oldAttr); \ *_retval = Element::RemoveAttributeNode(*attr, rv).take(); \ return rv.ErrorCode(); \ } \ @@ -1521,11 +1515,8 @@ NS_IMETHOD GetAttributeNodeNS(const nsAString& namespaceURI, \ NS_IMETHOD SetAttributeNodeNS(nsIDOMAttr* newAttr, \ nsIDOMAttr** _retval) MOZ_FINAL \ { \ - mozilla::dom::Attr* attr = mozilla::dom::Attr::FromDOMAttr(newAttr); \ - if (!attr) { \ - return NS_ERROR_INVALID_POINTER; \ - } \ mozilla::ErrorResult rv; \ + mozilla::dom::Attr* attr = static_cast(newAttr); \ *_retval = Element::SetAttributeNodeNS(*attr, rv).take(); \ return rv.ErrorCode(); \ } \ diff --git a/content/base/src/Attr.h b/content/base/src/Attr.h index f5606ead6b5f..42e02b26bc1a 100644 --- a/content/base/src/Attr.h +++ b/content/base/src/Attr.h @@ -80,14 +80,6 @@ public: virtual nsIDOMNode* AsDOMNode() { return this; } - // This method should not do anything interesting, except possibly in the case of - // external binary components. - static Attr* FromDOMAttr(nsIDOMAttr* aDOMAttr) - { - nsCOMPtr iattr = do_QueryInterface(aDOMAttr); - return static_cast(iattr.get()); - } - // WebIDL virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE; diff --git a/content/base/src/ChildIterator.cpp b/content/base/src/ChildIterator.cpp index 91c47e01829f..060d5d087f01 100644 --- a/content/base/src/ChildIterator.cpp +++ b/content/base/src/ChildIterator.cpp @@ -10,6 +10,8 @@ #include "mozilla/dom/HTMLContentElement.h" #include "mozilla/dom/HTMLShadowElement.h" #include "mozilla/dom/ShadowRoot.h" +#include "nsIAnonymousContentCreator.h" +#include "nsIFrame.h" namespace mozilla { namespace dom { @@ -154,11 +156,15 @@ ExplicitChildIterator::GetNextChild() return mChild; } -FlattenedChildIterator::FlattenedChildIterator(nsIContent* aParent) - : ExplicitChildIterator(aParent), mXBLInvolved(false) +void +FlattenedChildIterator::Init(bool aIgnoreXBL) { + if (aIgnoreXBL) { + return; + } + nsXBLBinding* binding = - aParent->OwnerDoc()->BindingManager()->GetBindingWithContent(aParent); + mParent->OwnerDoc()->BindingManager()->GetBindingWithContent(mParent); if (binding) { nsIContent* anon = binding->GetAnonymousContent(); @@ -171,8 +177,8 @@ FlattenedChildIterator::FlattenedChildIterator(nsIContent* aParent) // We set mXBLInvolved to true if either: // - The node we're iterating has a binding with content attached to it. // - The node is generated XBL content and has an child. - if (!mXBLInvolved && aParent->GetBindingParent()) { - for (nsIContent* child = aParent->GetFirstChild(); + if (!mXBLInvolved && mParent->GetBindingParent()) { + for (nsIContent* child = mParent->GetFirstChild(); child; child = child->GetNextSibling()) { if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) { @@ -281,5 +287,63 @@ ExplicitChildIterator::GetPreviousChild() return mChild; } +nsIContent* +AllChildrenIterator::GetNextChild() +{ + if (mPhase == eNeedBeforeKid) { + mPhase = eNeedExplicitKids; + nsIFrame* frame = mOriginalContent->GetPrimaryFrame(); + if (frame) { + nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame); + if (beforeFrame) { + return beforeFrame->GetContent(); + } + } + } + + if (mPhase == eNeedExplicitKids) { + nsIContent* kid = ExplicitChildIterator::GetNextChild(); + if (kid) { + return kid; + } + + mPhase = eNeedAnonKids; + } + + if (mPhase == eNeedAnonKids) { + if (mAnonKids.IsEmpty()) { + nsIAnonymousContentCreator* ac = + do_QueryFrame(mOriginalContent->GetPrimaryFrame()); + if (ac) { + ac->AppendAnonymousContentTo(mAnonKids, mFlags); + } + } + + if (!mAnonKids.IsEmpty()) { + nsIContent* nextKid = mAnonKids[0]; + mAnonKids.RemoveElementAt(0); + if (mAnonKids.IsEmpty()) { + mPhase = eNeedAfterKid; + } + + return nextKid; + } + + mPhase = eNeedAfterKid; + } + + if (mPhase == eNeedAfterKid) { + mPhase = eDone; + nsIFrame* frame = mOriginalContent->GetPrimaryFrame(); + if (frame) { + nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(frame); + if (afterFrame) { + return afterFrame->GetContent(); + } + } + } + + return nullptr; +} } // namespace dom } // namespace mozilla diff --git a/content/base/src/ChildIterator.h b/content/base/src/ChildIterator.h index eb80c9eaa0ef..09a2dc3e6229 100644 --- a/content/base/src/ChildIterator.h +++ b/content/base/src/ChildIterator.h @@ -7,6 +7,8 @@ #ifndef ChildIterator_h #define ChildIterator_h +#include "nsIContent.h" + /** * Iterates over the children on a node. If a child is an insertion point, * iterates over the children inserted there instead, or the default content @@ -107,16 +109,73 @@ protected: class FlattenedChildIterator : public ExplicitChildIterator { public: - FlattenedChildIterator(nsIContent* aParent); + FlattenedChildIterator(nsIContent* aParent) + : ExplicitChildIterator(aParent), mXBLInvolved(false) + { + Init(false); + } bool XBLInvolved() { return mXBLInvolved; } -private: +protected: + /** + * This constructor is a hack to help AllChildrenIterator which sometimes + * doesn't want to consider XBL. + */ + FlattenedChildIterator(nsIContent* aParent, bool aIgnoreXBL) + : ExplicitChildIterator(aParent), mXBLInvolved(false) + { + Init(aIgnoreXBL); + } + + void Init(bool aIgnoreXBL); + // For certain optimizations, nsCSSFrameConstructor needs to know if the // child list of the element that we're iterating matches its .childNodes. bool mXBLInvolved; }; +/** + * AllChildrenIterator returns the children of a element including before / + * after content and optionally XBL children. It assumes that no mutation of + * the DOM or frame tree takes place during iteration, and will break horribly + * if that is not true. + */ +class AllChildrenIterator : private FlattenedChildIterator +{ +public: + AllChildrenIterator(nsIContent* aNode, uint32_t aFlags) : + FlattenedChildIterator(aNode, (aFlags & nsIContent::eAllButXBL)), + mOriginalContent(aNode), mFlags(aFlags), + mPhase(eNeedBeforeKid) {} + +#ifdef DEBUG + ~AllChildrenIterator() { MOZ_ASSERT(!mMutationGuard.Mutated(0)); } +#endif + + nsIContent* GetNextChild(); + +private: + enum IteratorPhase + { + eNeedBeforeKid, + eNeedExplicitKids, + eNeedAnonKids, + eNeedAfterKid, + eDone + }; + + nsIContent* mOriginalContent; + nsTArray mAnonKids; + uint32_t mFlags; + IteratorPhase mPhase; +#ifdef DEBUG + // XXX we should really assert there are no frame tree changes as well, but + // there's no easy way to do that. + nsMutationGuard mMutationGuard; +#endif +}; + } // namespace dom } // namespace mozilla diff --git a/content/base/src/FragmentOrElement.cpp b/content/base/src/FragmentOrElement.cpp index fb7f56dc2294..9176522dc9d2 100644 --- a/content/base/src/FragmentOrElement.cpp +++ b/content/base/src/FragmentOrElement.cpp @@ -661,48 +661,9 @@ already_AddRefed FragmentOrElement::GetChildren(uint32_t aFilter) { nsRefPtr list = new nsSimpleContentList(this); - if (!list) { - return nullptr; - } - - nsIFrame *frame = GetPrimaryFrame(); - - // Append :before generated content. - if (frame) { - nsIFrame *beforeFrame = nsLayoutUtils::GetBeforeFrame(frame); - if (beforeFrame) { - list->AppendElement(beforeFrame->GetContent()); - } - } - - // If XBL is bound to this node then append XBL anonymous content including - // explict content altered by insertion point if we were requested for XBL - // anonymous content, otherwise append explicit content with respect to - // insertion point if any. - if (!(aFilter & eAllButXBL)) { - FlattenedChildIterator iter(this); - for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { - list->AppendElement(child); - } - } else { - ExplicitChildIterator iter(this); - for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { - list->AppendElement(child); - } - } - - if (frame) { - // Append native anonymous content to the end. - nsIAnonymousContentCreator* creator = do_QueryFrame(frame); - if (creator) { - creator->AppendAnonymousContentTo(*list, aFilter); - } - - // Append :after generated content. - nsIFrame *afterFrame = nsLayoutUtils::GetAfterFrame(frame); - if (afterFrame) { - list->AppendElement(afterFrame->GetContent()); - } + AllChildrenIterator iter(this, aFilter); + while (nsIContent* kid = iter.GetNextChild()) { + list->AppendElement(kid); } return list.forget(); diff --git a/content/base/src/moz.build b/content/base/src/moz.build index 8ae00098f64c..a660ba44cbc5 100644 --- a/content/base/src/moz.build +++ b/content/base/src/moz.build @@ -61,6 +61,7 @@ EXPORTS.mozilla += [ EXPORTS.mozilla.dom += [ 'Attr.h', + 'ChildIterator.h', 'Comment.h', 'DocumentFragment.h', 'DocumentType.h', diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 88249a443d08..4837b9fa9345 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -1949,7 +1949,7 @@ nsContentUtils::TraceSafeJSContext(JSTracer* aTrc) } if (JSObject* global = js::DefaultObjectForContextOrNull(cx)) { JS::AssertGCThingMustBeTenured(global); - JS_CallObjectTracer(aTrc, &global, "safe context"); + JS_CallUnbarrieredObjectTracer(aTrc, &global, "safe context"); MOZ_ASSERT(global == js::DefaultObjectForContextOrNull(cx)); } } diff --git a/content/base/src/nsDOMAttributeMap.cpp b/content/base/src/nsDOMAttributeMap.cpp index 79a9997fd5d0..2bf023c056d8 100644 --- a/content/base/src/nsDOMAttributeMap.cpp +++ b/content/base/src/nsDOMAttributeMap.cpp @@ -242,9 +242,9 @@ nsDOMAttributeMap::GetNamedItem(const nsAString& aAttrName, } NS_IMETHODIMP -nsDOMAttributeMap::SetNamedItem(nsIDOMAttr* aDOMAttr, nsIDOMAttr** aReturn) +nsDOMAttributeMap::SetNamedItem(nsIDOMAttr* aAttr, nsIDOMAttr** aReturn) { - Attr* attribute = Attr::FromDOMAttr(aDOMAttr); + Attr* attribute = static_cast(aAttr); NS_ENSURE_ARG(attribute); ErrorResult rv; @@ -253,9 +253,9 @@ nsDOMAttributeMap::SetNamedItem(nsIDOMAttr* aDOMAttr, nsIDOMAttr** aReturn) } NS_IMETHODIMP -nsDOMAttributeMap::SetNamedItemNS(nsIDOMAttr* aDOMAttr, nsIDOMAttr** aReturn) +nsDOMAttributeMap::SetNamedItemNS(nsIDOMAttr* aAttr, nsIDOMAttr** aReturn) { - Attr* attribute = Attr::FromDOMAttr(aDOMAttr); + Attr* attribute = static_cast(aAttr); NS_ENSURE_ARG(attribute); ErrorResult rv; diff --git a/content/media/MediaDecoderStateMachine.cpp b/content/media/MediaDecoderStateMachine.cpp index c91512124ee6..c74b3bdd7012 100644 --- a/content/media/MediaDecoderStateMachine.cpp +++ b/content/media/MediaDecoderStateMachine.cpp @@ -586,8 +586,8 @@ MediaDecoderStateMachine::DecodeVideo() // soon anyway and we'll want to be able to display frames immediately // after buffering finishes. if (mState == DECODER_STATE_DECODING && - mIsVideoDecoding && - ((!mIsAudioPrerolling && mIsAudioDecoding && + IsVideoDecoding() && + ((!mIsAudioPrerolling && IsAudioDecoding() && GetDecodedAudioDuration() < mLowAudioThresholdUsecs * mPlaybackRate) || (!mIsVideoPrerolling && IsVideoDecoding() && // don't skip frame when |clock time| <= |mVideoFrameEndTime| for diff --git a/content/media/MediaDecoderStateMachine.h b/content/media/MediaDecoderStateMachine.h index 78b0597a6041..d2d062bba795 100644 --- a/content/media/MediaDecoderStateMachine.h +++ b/content/media/MediaDecoderStateMachine.h @@ -829,14 +829,6 @@ protected: bool mIsAudioPrerolling; bool mIsVideoPrerolling; - // True when we have an audio stream that we're decoding, and we have not - // yet decoded to end of stream. - bool mIsAudioDecoding; - - // True when we have a video stream that we're decoding, and we have not - // yet decoded to end of stream. - bool mIsVideoDecoding; - // True when we have dispatched a task to the decode task queue to request // decoded audio/video, and/or we are waiting for the requested sample to be // returned by callback from the Reader. diff --git a/content/media/MediaResource.h b/content/media/MediaResource.h index f386df90de1d..12892b25d3c5 100644 --- a/content/media/MediaResource.h +++ b/content/media/MediaResource.h @@ -17,6 +17,7 @@ #include "mozilla/Attributes.h" #include "mozilla/TimeStamp.h" #include "nsThreadUtils.h" +#include // For HTTP seeking, if number of bytes needing to be // seeked forward is less than this value then a read is @@ -151,6 +152,12 @@ public: return aByteRange.mStart >= mStart && aByteRange.mEnd <= mEnd; } + MediaByteRange Extents(const MediaByteRange& aByteRange) const + { + return MediaByteRange(std::min(mStart, aByteRange.mStart), + std::max(mEnd, aByteRange.mEnd)); + } + int64_t mStart, mEnd; }; diff --git a/content/media/fmp4/MP4Reader.cpp b/content/media/fmp4/MP4Reader.cpp index 119de3864905..f60a9983f433 100644 --- a/content/media/fmp4/MP4Reader.cpp +++ b/content/media/fmp4/MP4Reader.cpp @@ -78,7 +78,7 @@ public: uint32_t sum = 0; uint32_t bytesRead = 0; do { - uint32_t offset = aOffset + sum; + uint64_t offset = aOffset + sum; char* buffer = reinterpret_cast(aBuffer) + sum; uint32_t toRead = aCount - sum; nsresult rv = mResource->ReadAt(offset, buffer, toRead, &bytesRead); @@ -745,13 +745,27 @@ void MP4Reader::NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset) { - nsTArray ranges; - if (NS_FAILED(mDecoder->GetResource()->GetCachedRanges(ranges))) { - return; + if (NS_IsMainThread()) { + MediaTaskQueue* queue = + mAudio.mTaskQueue ? mAudio.mTaskQueue : mVideo.mTaskQueue; + queue->Dispatch(NS_NewRunnableMethod(this, &MP4Reader::UpdateIndex)); + } else { + UpdateIndex(); } +} +void +MP4Reader::UpdateIndex() +{ + nsTArray ranges; nsTArray> timeRanges; - mDemuxer->ConvertByteRangesToTime(ranges, &timeRanges); + + MediaResource* resource = mDecoder->GetResource(); + resource->Pin(); + if (NS_SUCCEEDED(resource->GetCachedRanges(ranges))) { + mDemuxer->ConvertByteRangesToTime(ranges, &timeRanges); + } + resource->Unpin(); MonitorAutoLock mon(mTimeRangesMonitor); mTimeRanges = timeRanges; diff --git a/content/media/fmp4/MP4Reader.h b/content/media/fmp4/MP4Reader.h index 4bf010c678e0..6bc00ad18b31 100644 --- a/content/media/fmp4/MP4Reader.h +++ b/content/media/fmp4/MP4Reader.h @@ -86,6 +86,7 @@ private: bool Decode(mp4_demuxer::TrackType aTrack); void Flush(mp4_demuxer::TrackType aTrack); void DrainComplete(mp4_demuxer::TrackType aTrack); + void UpdateIndex(); void NotifyResourcesStatusChanged(); bool IsWaitingOnCodecResource(); bool IsWaitingOnCDMResource(); diff --git a/content/media/fmp4/wmf/WMFAudioMFTManager.cpp b/content/media/fmp4/wmf/WMFAudioMFTManager.cpp index 098b96dedc84..3a9dbdca196d 100644 --- a/content/media/fmp4/wmf/WMFAudioMFTManager.cpp +++ b/content/media/fmp4/wmf/WMFAudioMFTManager.cpp @@ -136,16 +136,44 @@ WMFAudioMFTManager::Input(mp4_demuxer::MP4Sample* aSample) return mDecoder->Input(data, length, aSample->composition_timestamp); } +HRESULT +WMFAudioMFTManager::UpdateOutputType() +{ + HRESULT hr; + + RefPtr type; + hr = mDecoder->GetOutputMediaType(type); + NS_ENSURE_TRUE(SUCCEEDED(hr), hr); + + hr = type->GetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, &mAudioRate); + NS_ENSURE_TRUE(SUCCEEDED(hr), hr); + + hr = type->GetUINT32(MF_MT_AUDIO_NUM_CHANNELS, &mAudioChannels); + NS_ENSURE_TRUE(SUCCEEDED(hr), hr); + + return S_OK; +} + HRESULT WMFAudioMFTManager::Output(int64_t aStreamOffset, nsAutoPtr& aOutData) { aOutData = nullptr; RefPtr sample; - HRESULT hr = mDecoder->Output(&sample); - if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { - return MF_E_TRANSFORM_NEED_MORE_INPUT; + HRESULT hr; + while (true) { + hr = mDecoder->Output(&sample); + if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { + return hr; + } + if (hr == MF_E_TRANSFORM_STREAM_CHANGE) { + hr = UpdateOutputType(); + NS_ENSURE_TRUE(SUCCEEDED(hr), hr); + continue; + } + break; } + NS_ENSURE_TRUE(SUCCEEDED(hr), hr); RefPtr buffer; diff --git a/content/media/fmp4/wmf/WMFAudioMFTManager.h b/content/media/fmp4/wmf/WMFAudioMFTManager.h index 9caff24e3c30..04f041d787d4 100644 --- a/content/media/fmp4/wmf/WMFAudioMFTManager.h +++ b/content/media/fmp4/wmf/WMFAudioMFTManager.h @@ -31,12 +31,14 @@ public: nsAutoPtr& aOutput) MOZ_OVERRIDE; private: + HRESULT UpdateOutputType(); + // IMFTransform wrapper that performs the decoding. RefPtr mDecoder; - const uint32_t mAudioChannels; + uint32_t mAudioChannels; const uint32_t mAudioBytesPerSample; - const uint32_t mAudioRate; + uint32_t mAudioRate; nsTArray mUserData; // The offset, in audio frames, at which playback started since the diff --git a/content/media/gmp/GMPChild.cpp b/content/media/gmp/GMPChild.cpp index 1c5f9bb31dc9..c0ef5bede0cd 100644 --- a/content/media/gmp/GMPChild.cpp +++ b/content/media/gmp/GMPChild.cpp @@ -157,6 +157,7 @@ GMPChild::LoadPluginLibrary(const std::string& aPluginPath) #if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX) // Enable sandboxing here -- we know the plugin file's path, but // this process's execution hasn't been affected by its content yet. + MOZ_ASSERT(mozilla::CanSandboxMediaPlugin()); mozilla::SetMediaPluginSandbox(nativePath.get()); #endif diff --git a/content/media/gmp/GMPService.cpp b/content/media/gmp/GMPService.cpp index 989decc974d2..762d0d73eb6b 100644 --- a/content/media/gmp/GMPService.cpp +++ b/content/media/gmp/GMPService.cpp @@ -20,6 +20,9 @@ #include "GMPDecryptorParent.h" #include "GMPAudioDecoderParent.h" #include "runnable_utils.h" +#if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX) +#include "mozilla/Sandbox.h" +#endif namespace mozilla { @@ -453,6 +456,11 @@ NS_IMETHODIMP GeckoMediaPluginService::AddPluginDirectory(const nsAString& aDirectory) { MOZ_ASSERT(NS_IsMainThread()); +#if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX) + if (!mozilla::CanSandboxMediaPlugin()) { + return NS_ERROR_NOT_AVAILABLE; + } +#endif nsCOMPtr thread; nsresult rv = GetThread(getter_AddRefs(thread)); if (NS_FAILED(rv)) { diff --git a/content/xul/content/src/nsXULElement.h b/content/xul/content/src/nsXULElement.h index 906c3681d370..bd825757759d 100644 --- a/content/xul/content/src/nsXULElement.h +++ b/content/xul/content/src/nsXULElement.h @@ -264,7 +264,7 @@ public: void TraceScriptObject(JSTracer* aTrc) { if (mScriptObject) { - JS_CallHeapScriptTracer(aTrc, &mScriptObject, "active window XUL prototype script"); + JS_CallScriptTracer(aTrc, &mScriptObject, "active window XUL prototype script"); } } diff --git a/content/xul/document/src/nsXULPrototypeCache.cpp b/content/xul/document/src/nsXULPrototypeCache.cpp index 91331055f55b..0ef5ae1d3837 100644 --- a/content/xul/document/src/nsXULPrototypeCache.cpp +++ b/content/xul/document/src/nsXULPrototypeCache.cpp @@ -641,7 +641,7 @@ static PLDHashOperator MarkScriptsInGC(nsIURI* aKey, JS::Heap& aScript, void* aClosure) { JSTracer* trc = static_cast(aClosure); - JS_CallHeapScriptTracer(trc, &aScript, "nsXULPrototypeCache script"); + JS_CallScriptTracer(trc, &aScript, "nsXULPrototypeCache script"); return PL_DHASH_NEXT; } diff --git a/dom/animation/AnimationPlayer.h b/dom/animation/AnimationPlayer.h index 99d8f7622779..56a8ae640b77 100644 --- a/dom/animation/AnimationPlayer.h +++ b/dom/animation/AnimationPlayer.h @@ -32,7 +32,8 @@ protected: public: explicit AnimationPlayer(AnimationTimeline* aTimeline) - : mIsRunningOnCompositor(false) + : mPlayState(NS_STYLE_ANIMATION_PLAY_STATE_RUNNING) + , mIsRunningOnCompositor(false) , mTimeline(aTimeline) { SetIsDOMBinding(); diff --git a/dom/base/nsWrapperCache.h b/dom/base/nsWrapperCache.h index 2eb1e0196382..980277f3cd20 100644 --- a/dom/base/nsWrapperCache.h +++ b/dom/base/nsWrapperCache.h @@ -228,7 +228,7 @@ protected: void TraceWrapper(JSTracer* aTrc, const char* name) { if (mWrapper) { - JS_CallHeapObjectTracer(aTrc, &mWrapper, name); + JS_CallObjectTracer(aTrc, &mWrapper, name); } } diff --git a/dom/base/nsWrapperCacheInlines.h b/dom/base/nsWrapperCacheInlines.h index 0c9a6fe6c0c9..6eec9de9d975 100644 --- a/dom/base/nsWrapperCacheInlines.h +++ b/dom/base/nsWrapperCacheInlines.h @@ -55,7 +55,7 @@ nsWrapperCache::IsBlackAndDoesNotNeedTracing(nsISupports* aThis) inline void nsWrapperCache::TraceWrapperJSObject(JSTracer* aTrc, const char* aName) { - JS_CallHeapObjectTracer(aTrc, &mWrapper, aName); + JS_CallObjectTracer(aTrc, &mWrapper, aName); } #endif /* nsWrapperCache_h___ */ diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index d37b203e4d40..4ba8a0f5c19e 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -325,7 +325,7 @@ class ProtoAndIfaceCache void Trace(JSTracer* aTracer) { for (size_t i = 0; i < ArrayLength(*this); ++i) { if ((*this)[i]) { - JS_CallHeapObjectTracer(aTracer, &(*this)[i], "protoAndIfaceCache[i]"); + JS_CallObjectTracer(aTracer, &(*this)[i], "protoAndIfaceCache[i]"); } } } @@ -386,7 +386,7 @@ class ProtoAndIfaceCache if (p) { for (size_t j = 0; j < ArrayLength(*p); ++j) { if ((*p)[j]) { - JS_CallHeapObjectTracer(trc, &(*p)[j], "protoAndIfaceCache[i]"); + JS_CallObjectTracer(trc, &(*p)[j], "protoAndIfaceCache[i]"); } } } @@ -1975,7 +1975,7 @@ class SequenceTracer public: static void TraceSequence(JSTracer* trc, JSObject** objp, JSObject** end) { for (; objp != end; ++objp) { - JS_CallObjectTracer(trc, objp, "sequence"); + JS_CallUnbarrieredObjectTracer(trc, objp, "sequence"); } } }; @@ -1989,7 +1989,7 @@ class SequenceTracer public: static void TraceSequence(JSTracer* trc, JS::Value* valp, JS::Value* end) { for (; valp != end; ++valp) { - JS_CallValueTracer(trc, valp, "sequence"); + JS_CallUnbarrieredValueTracer(trc, valp, "sequence"); } } }; diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 441b5131fb45..494fad3fc3ea 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -8534,7 +8534,7 @@ class CGUnionStruct(CGThing): if t.isObject(): traceCases.append( CGCase("e" + vars["name"], - CGGeneric('JS_CallObjectTracer(trc, %s, "%s");\n' % + CGGeneric('JS_CallUnbarrieredObjectTracer(trc, %s, "%s");\n' % ("&mValue.m" + vars["name"] + ".Value()", "mValue.m" + vars["name"])))) elif t.isDictionary(): @@ -11427,12 +11427,12 @@ class CGDictionary(CGThing): memberLoc) if type.isObject(): - trace = CGGeneric('JS_CallObjectTracer(trc, %s, "%s");\n' % + trace = CGGeneric('JS_CallUnbarrieredObjectTracer(trc, %s, "%s");\n' % ("&"+memberData, memberName)) if type.nullable(): trace = CGIfWrapper(trace, memberData) elif type.isAny(): - trace = CGGeneric('JS_CallValueTracer(trc, %s, "%s");\n' % + trace = CGGeneric('JS_CallUnbarrieredValueTracer(trc, %s, "%s");\n' % ("&"+memberData, memberName)) elif (type.isSequence() or type.isDictionary() or type.isSpiderMonkeyInterface() or type.isUnion()): diff --git a/dom/bindings/TypedArray.h b/dom/bindings/TypedArray.h index ca3e19567cae..0c58a351c960 100644 --- a/dom/bindings/TypedArray.h +++ b/dom/bindings/TypedArray.h @@ -45,10 +45,10 @@ public: inline void TraceSelf(JSTracer* trc) { if (mTypedObj) { - JS_CallObjectTracer(trc, &mTypedObj, "TypedArray.mTypedObj"); + JS_CallUnbarrieredObjectTracer(trc, &mTypedObj, "TypedArray.mTypedObj"); } if (mWrappedObj) { - JS_CallObjectTracer(trc, &mTypedObj, "TypedArray.mWrappedObj"); + JS_CallUnbarrieredObjectTracer(trc, &mTypedObj, "TypedArray.mWrappedObj"); } } diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 15b4c84dad1d..0dad108d72a3 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -922,7 +922,9 @@ ContentChild::RecvSetProcessSandbox() // at some point; see bug 880808. #if defined(MOZ_CONTENT_SANDBOX) #if defined(XP_LINUX) - SetContentProcessSandbox(); + if (CanSandboxContentProcess()) { + SetContentProcessSandbox(); + } #elif defined(XP_WIN) mozilla::SandboxTarget::Instance()->StartSandbox(); #endif diff --git a/dom/nfc/gonk/Nfc.js b/dom/nfc/gonk/Nfc.js index e85d7f4c9297..a0b22b953228 100644 --- a/dom/nfc/gonk/Nfc.js +++ b/dom/nfc/gonk/Nfc.js @@ -514,7 +514,7 @@ Nfc.prototype = { delete this.sessionTokenMap[this._currentSessionId]; this._currentSessionId = null; - this.currentPeerAppId = null; + gMessageManager.currentPeerAppId = null; break; case "ConfigResponse": let target = this.targetsByRequestId[message.requestId]; diff --git a/dom/plugins/base/nsJSNPRuntime.cpp b/dom/plugins/base/nsJSNPRuntime.cpp index 5fd47c01f119..375f9364b2d8 100644 --- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -952,7 +952,7 @@ JSObjWrapperKeyMarkCallback(JSTracer *trc, JSObject *obj, void *data) { if (!p) return; - JS_CallObjectTracer(trc, &obj, "sJSObjWrappers key object"); + JS_CallUnbarrieredObjectTracer(trc, &obj, "sJSObjWrappers key object"); nsJSObjWrapperKey newKey(obj, npp); sJSObjWrappers.rekeyIfMoved(oldKey, newKey); } @@ -2122,18 +2122,18 @@ NPObjectMember_Trace(JSTracer *trc, JSObject *obj) return; // Our NPIdentifier is not always interned, so we must root it explicitly. - JS_CallHeapIdTracer(trc, &memberPrivate->methodName, "NPObjectMemberPrivate.methodName"); + JS_CallIdTracer(trc, &memberPrivate->methodName, "NPObjectMemberPrivate.methodName"); if (!memberPrivate->fieldValue.isPrimitive()) { - JS_CallHeapValueTracer(trc, &memberPrivate->fieldValue, - "NPObject Member => fieldValue"); + JS_CallValueTracer(trc, &memberPrivate->fieldValue, + "NPObject Member => fieldValue"); } // There's no strong reference from our private data to the // NPObject, so make sure to mark the NPObject wrapper to keep the // NPObject alive as long as this NPObjectMember is alive. if (memberPrivate->npobjWrapper) { - JS_CallHeapObjectTracer(trc, &memberPrivate->npobjWrapper, - "NPObject Member => npobjWrapper"); + JS_CallObjectTracer(trc, &memberPrivate->npobjWrapper, + "NPObject Member => npobjWrapper"); } } diff --git a/dom/workers/WorkerRunnable.cpp b/dom/workers/WorkerRunnable.cpp index acf87b47c7f8..4bc70194263c 100644 --- a/dom/workers/WorkerRunnable.cpp +++ b/dom/workers/WorkerRunnable.cpp @@ -262,29 +262,29 @@ WorkerRunnable::Run() return NS_OK; } + if (targetIsWorkerThread && + mWorkerPrivate->AllPendingRunnablesShouldBeCanceled() && + !IsCanceled() && !mCallingCancelWithinRun) { + + // Prevent recursion. + mCallingCancelWithinRun = true; + + Cancel(); + + MOZ_ASSERT(mCallingCancelWithinRun); + mCallingCancelWithinRun = false; + + MOZ_ASSERT(IsCanceled(), "Subclass Cancel() didn't set IsCanceled()!"); + + return NS_OK; + } + + // Track down the appropriate global to use for the AutoJSAPI/AutoEntryScript. nsCOMPtr globalObject; bool isMainThread = !targetIsWorkerThread && !mWorkerPrivate->GetParent(); MOZ_ASSERT(isMainThread == NS_IsMainThread()); nsRefPtr kungFuDeathGrip; - if (targetIsWorkerThread) { - if (mWorkerPrivate->AllPendingRunnablesShouldBeCanceled() && - !IsCanceled() && - !mCallingCancelWithinRun) { - - // Prevent recursion. - mCallingCancelWithinRun = true; - - Cancel(); - - MOZ_ASSERT(mCallingCancelWithinRun); - mCallingCancelWithinRun = false; - - MOZ_ASSERT(IsCanceled(), "Subclass Cancel() didn't set IsCanceled()!"); - - return NS_OK; - } - globalObject = mWorkerPrivate->GlobalScope(); } else { diff --git a/dom/workers/XMLHttpRequest.cpp b/dom/workers/XMLHttpRequest.cpp index 2208d7809562..e2cbbfd96824 100644 --- a/dom/workers/XMLHttpRequest.cpp +++ b/dom/workers/XMLHttpRequest.cpp @@ -447,8 +447,8 @@ public: private: virtual void trace(JSTracer* aTrc) { - JS_CallHeapValueTracer(aTrc, &mStateData->mResponse, - "XMLHttpRequest::StateData::mResponse"); + JS_CallValueTracer(aTrc, &mStateData->mResponse, + "XMLHttpRequest::StateData::mResponse"); } }; diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp index 27b527c771b8..230f81add85a 100644 --- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -63,87 +63,87 @@ uint32_t GLContext::sDebugMode = 0; // should match the order of GLExtensions, and be null-terminated. static const char *sExtensionNames[] = { "NO_EXTENSION", - "GL_EXT_framebuffer_object", - "GL_ARB_framebuffer_object", - "GL_ARB_texture_rectangle", - "GL_EXT_bgra", - "GL_EXT_texture_format_BGRA8888", - "GL_OES_depth24", - "GL_OES_depth32", - "GL_OES_stencil8", - "GL_OES_texture_npot", - "GL_IMG_texture_npot", - "GL_ARB_depth_texture", - "GL_OES_depth_texture", - "GL_OES_packed_depth_stencil", - "GL_IMG_read_format", - "GL_EXT_read_format_bgra", - "GL_APPLE_client_storage", - "GL_APPLE_texture_range", - "GL_ARB_texture_non_power_of_two", - "GL_ARB_pixel_buffer_object", - "GL_ARB_ES2_compatibility", - "GL_ARB_ES3_compatibility", - "GL_OES_texture_float", - "GL_OES_texture_float_linear", - "GL_ARB_texture_float", - "GL_OES_texture_half_float", - "GL_OES_texture_half_float_linear", - "GL_NV_half_float", - "GL_EXT_color_buffer_float", - "GL_EXT_color_buffer_half_float", - "GL_ARB_color_buffer_float", - "GL_EXT_unpack_subimage", - "GL_OES_standard_derivatives", - "GL_EXT_texture_filter_anisotropic", - "GL_EXT_texture_compression_s3tc", - "GL_EXT_texture_compression_dxt1", + "GL_AMD_compressed_ATC_texture", + "GL_ANGLE_depth_texture", + "GL_ANGLE_framebuffer_blit", + "GL_ANGLE_framebuffer_multisample", + "GL_ANGLE_instanced_arrays", "GL_ANGLE_texture_compression_dxt3", "GL_ANGLE_texture_compression_dxt5", - "GL_AMD_compressed_ATC_texture", - "GL_IMG_texture_compression_pvrtc", - "GL_EXT_framebuffer_blit", - "GL_ANGLE_framebuffer_blit", - "GL_EXT_framebuffer_multisample", - "GL_ANGLE_framebuffer_multisample", - "GL_OES_rgb8_rgba8", - "GL_ARB_robustness", - "GL_EXT_robustness", - "GL_ARB_sync", - "GL_OES_EGL_image", - "GL_OES_EGL_sync", - "GL_OES_EGL_image_external", - "GL_EXT_packed_depth_stencil", - "GL_OES_element_index_uint", - "GL_OES_vertex_array_object", - "GL_ARB_vertex_array_object", + "GL_APPLE_client_storage", + "GL_APPLE_texture_range", "GL_APPLE_vertex_array_object", + "GL_ARB_ES2_compatibility", + "GL_ARB_ES3_compatibility", + "GL_ARB_color_buffer_float", + "GL_ARB_depth_texture", "GL_ARB_draw_buffers", - "GL_EXT_draw_buffers", - "GL_EXT_gpu_shader4", - "GL_EXT_blend_minmax", "GL_ARB_draw_instanced", - "GL_EXT_draw_instanced", - "GL_NV_draw_instanced", - "GL_ARB_instanced_arrays", - "GL_NV_instanced_arrays", - "GL_ANGLE_instanced_arrays", - "GL_EXT_occlusion_query_boolean", - "GL_ARB_occlusion_query2", - "GL_EXT_transform_feedback", - "GL_NV_transform_feedback", - "GL_ANGLE_depth_texture", - "GL_EXT_sRGB", - "GL_EXT_texture_sRGB", + "GL_ARB_framebuffer_object", "GL_ARB_framebuffer_sRGB", - "GL_EXT_framebuffer_sRGB", - "GL_KHR_debug", "GL_ARB_half_float_pixel", - "GL_EXT_frag_depth", - "GL_OES_compressed_ETC1_RGB8_texture", + "GL_ARB_instanced_arrays", + "GL_ARB_occlusion_query2", + "GL_ARB_pixel_buffer_object", + "GL_ARB_robustness", + "GL_ARB_sync", + "GL_ARB_texture_float", + "GL_ARB_texture_non_power_of_two", + "GL_ARB_texture_rectangle", + "GL_ARB_vertex_array_object", + "GL_EXT_bgra", + "GL_EXT_blend_minmax", + "GL_EXT_color_buffer_float", + "GL_EXT_color_buffer_half_float", + "GL_EXT_draw_buffers", + "GL_EXT_draw_instanced", "GL_EXT_draw_range_elements", + "GL_EXT_frag_depth", + "GL_EXT_framebuffer_blit", + "GL_EXT_framebuffer_multisample", + "GL_EXT_framebuffer_object", + "GL_EXT_framebuffer_sRGB", + "GL_EXT_gpu_shader4", + "GL_EXT_occlusion_query_boolean", + "GL_EXT_packed_depth_stencil", + "GL_EXT_read_format_bgra", + "GL_EXT_robustness", + "GL_EXT_sRGB", "GL_EXT_shader_texture_lod", + "GL_EXT_texture_compression_dxt1", + "GL_EXT_texture_compression_s3tc", + "GL_EXT_texture_filter_anisotropic", + "GL_EXT_texture_format_BGRA8888", + "GL_EXT_texture_sRGB", + "GL_EXT_transform_feedback", + "GL_EXT_unpack_subimage", + "GL_IMG_read_format", + "GL_IMG_texture_compression_pvrtc", + "GL_IMG_texture_npot", + "GL_KHR_debug", + "GL_NV_draw_instanced", "GL_NV_fence", + "GL_NV_half_float", + "GL_NV_instanced_arrays", + "GL_NV_transform_feedback", + "GL_OES_EGL_image", + "GL_OES_EGL_image_external", + "GL_OES_EGL_sync", + "GL_OES_compressed_ETC1_RGB8_texture", + "GL_OES_depth24", + "GL_OES_depth32", + "GL_OES_depth_texture", + "GL_OES_element_index_uint", + "GL_OES_packed_depth_stencil", + "GL_OES_rgb8_rgba8", + "GL_OES_standard_derivatives", + "GL_OES_stencil8", + "GL_OES_texture_float", + "GL_OES_texture_float_linear", + "GL_OES_texture_half_float", + "GL_OES_texture_half_float_linear", + "GL_OES_texture_npot", + "GL_OES_vertex_array_object", nullptr }; diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index 409c0de84721..3c94439da9e5 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -332,87 +332,87 @@ public: */ enum GLExtensions { Extension_None = 0, - EXT_framebuffer_object, - ARB_framebuffer_object, - ARB_texture_rectangle, - EXT_bgra, - EXT_texture_format_BGRA8888, - OES_depth24, - OES_depth32, - OES_stencil8, - OES_texture_npot, - IMG_texture_npot, - ARB_depth_texture, - OES_depth_texture, - OES_packed_depth_stencil, - IMG_read_format, - EXT_read_format_bgra, - APPLE_client_storage, - APPLE_texture_range, - ARB_texture_non_power_of_two, - ARB_pixel_buffer_object, - ARB_ES2_compatibility, - ARB_ES3_compatibility, - OES_texture_float, - OES_texture_float_linear, - ARB_texture_float, - OES_texture_half_float, - OES_texture_half_float_linear, - NV_half_float, - EXT_color_buffer_float, - EXT_color_buffer_half_float, - ARB_color_buffer_float, - EXT_unpack_subimage, - OES_standard_derivatives, - EXT_texture_filter_anisotropic, - EXT_texture_compression_s3tc, - EXT_texture_compression_dxt1, + AMD_compressed_ATC_texture, + ANGLE_depth_texture, + ANGLE_framebuffer_blit, + ANGLE_framebuffer_multisample, + ANGLE_instanced_arrays, ANGLE_texture_compression_dxt3, ANGLE_texture_compression_dxt5, - AMD_compressed_ATC_texture, - IMG_texture_compression_pvrtc, - EXT_framebuffer_blit, - ANGLE_framebuffer_blit, - EXT_framebuffer_multisample, - ANGLE_framebuffer_multisample, - OES_rgb8_rgba8, - ARB_robustness, - EXT_robustness, - ARB_sync, - OES_EGL_image, - OES_EGL_sync, - OES_EGL_image_external, - EXT_packed_depth_stencil, - OES_element_index_uint, - OES_vertex_array_object, - ARB_vertex_array_object, + APPLE_client_storage, + APPLE_texture_range, APPLE_vertex_array_object, + ARB_ES2_compatibility, + ARB_ES3_compatibility, + ARB_color_buffer_float, + ARB_depth_texture, ARB_draw_buffers, - EXT_draw_buffers, - EXT_gpu_shader4, - EXT_blend_minmax, ARB_draw_instanced, - EXT_draw_instanced, - NV_draw_instanced, - ARB_instanced_arrays, - NV_instanced_arrays, - ANGLE_instanced_arrays, - EXT_occlusion_query_boolean, - ARB_occlusion_query2, - EXT_transform_feedback, - NV_transform_feedback, - ANGLE_depth_texture, - EXT_sRGB, - EXT_texture_sRGB, + ARB_framebuffer_object, ARB_framebuffer_sRGB, - EXT_framebuffer_sRGB, - KHR_debug, ARB_half_float_pixel, - EXT_frag_depth, - OES_compressed_ETC1_RGB8_texture, + ARB_instanced_arrays, + ARB_occlusion_query2, + ARB_pixel_buffer_object, + ARB_robustness, + ARB_sync, + ARB_texture_float, + ARB_texture_non_power_of_two, + ARB_texture_rectangle, + ARB_vertex_array_object, + EXT_bgra, + EXT_blend_minmax, + EXT_color_buffer_float, + EXT_color_buffer_half_float, + EXT_draw_buffers, + EXT_draw_instanced, EXT_draw_range_elements, + EXT_frag_depth, + EXT_framebuffer_blit, + EXT_framebuffer_multisample, + EXT_framebuffer_object, + EXT_framebuffer_sRGB, + EXT_gpu_shader4, + EXT_occlusion_query_boolean, + EXT_packed_depth_stencil, + EXT_read_format_bgra, + EXT_robustness, + EXT_sRGB, EXT_shader_texture_lod, + EXT_texture_compression_dxt1, + EXT_texture_compression_s3tc, + EXT_texture_filter_anisotropic, + EXT_texture_format_BGRA8888, + EXT_texture_sRGB, + EXT_transform_feedback, + EXT_unpack_subimage, + IMG_read_format, + IMG_texture_compression_pvrtc, + IMG_texture_npot, + KHR_debug, + NV_draw_instanced, NV_fence, + NV_half_float, + NV_instanced_arrays, + NV_transform_feedback, + OES_EGL_image, + OES_EGL_image_external, + OES_EGL_sync, + OES_compressed_ETC1_RGB8_texture, + OES_depth24, + OES_depth32, + OES_depth_texture, + OES_element_index_uint, + OES_packed_depth_stencil, + OES_rgb8_rgba8, + OES_standard_derivatives, + OES_stencil8, + OES_texture_float, + OES_texture_float_linear, + OES_texture_half_float, + OES_texture_half_float_linear, + OES_texture_npot, + OES_vertex_array_object, Extensions_Max, Extensions_End }; diff --git a/gfx/harfbuzz/src/hb-ot-shape-complex-arabic-table.hh b/gfx/harfbuzz/src/hb-ot-shape-complex-arabic-table.hh index d41d6ce598ed..17100497ecb8 100644 --- a/gfx/harfbuzz/src/hb-ot-shape-complex-arabic-table.hh +++ b/gfx/harfbuzz/src/hb-ot-shape-complex-arabic-table.hh @@ -70,7 +70,7 @@ static const uint8_t joining_table[] = /* Mandaic */ - /* 0840 */ R,D,D,D,D,D,R,D,D,R,D,D,D,D,D,R,D,D,D,D,R,D,U,U,U,X,X,X,X,X,X,X, + /* 0840 */ R,D,D,D,D,D,R,R,D,R,D,D,D,D,D,D,D,D,D,D,R,D,U,U,U,X,X,X,X,X,X,X, /* 0860 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, /* 0880 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, diff --git a/gfx/layers/FrameMetrics.h b/gfx/layers/FrameMetrics.h index f71d21d841f0..dec598332083 100644 --- a/gfx/layers/FrameMetrics.h +++ b/gfx/layers/FrameMetrics.h @@ -402,8 +402,8 @@ public: { return mScrollId; } - - void SetScrollId(ViewID scrollId) + + void SetScrollId(ViewID scrollId) { mScrollId = scrollId; } @@ -539,6 +539,14 @@ struct ScrollableLayerGuid { MOZ_COUNT_CTOR(ScrollableLayerGuid); } + ScrollableLayerGuid(const ScrollableLayerGuid& other) + : mLayersId(other.mLayersId) + , mPresShellId(other.mPresShellId) + , mScrollId(other.mScrollId) + { + MOZ_COUNT_CTOR(ScrollableLayerGuid); + } + ~ScrollableLayerGuid() { MOZ_COUNT_DTOR(ScrollableLayerGuid); @@ -587,6 +595,15 @@ struct ZoomConstraints { MOZ_COUNT_CTOR(ZoomConstraints); } + ZoomConstraints(const ZoomConstraints& other) + : mAllowZoom(other.mAllowZoom) + , mAllowDoubleTapZoom(other.mAllowDoubleTapZoom) + , mMinZoom(other.mMinZoom) + , mMaxZoom(other.mMaxZoom) + { + MOZ_COUNT_CTOR(ZoomConstraints); + } + ~ZoomConstraints() { MOZ_COUNT_DTOR(ZoomConstraints); diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp index e8d8d46b2c9d..7bd09baeaab3 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.cpp +++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp @@ -137,7 +137,7 @@ typedef mozilla::gfx::Matrix4x4 Matrix4x4; * The following prefs are used to control the behaviour of the APZC. * The default values are provided in gfxPrefs.h. * - * "apz.allow-checkerboarding" + * "apz.allow_checkerboarding" * Pref that allows or disallows checkerboarding * * "apz.asyncscroll.throttle" diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index aff372271f7d..60ea8ffbff1d 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -1059,7 +1059,12 @@ CompositorOGL::DrawQuad(const Rect& aRect, maskType = MaskType::MaskNone; } - mPixelsFilled += aRect.width * aRect.height; + { + // XXX: This doesn't handle 3D transforms. It also doesn't handled rotated + // quads. Fix me. + const Rect destRect = aTransform.TransformBounds(aRect); + mPixelsFilled += destRect.width * destRect.height; + } // Determine the color if this is a color shader and fold the opacity into // the color since color shaders don't have an opacity uniform. diff --git a/gfx/skia/generate_mozbuild.py b/gfx/skia/generate_mozbuild.py index e5d8fc01146f..7b5b44b67c67 100755 --- a/gfx/skia/generate_mozbuild.py +++ b/gfx/skia/generate_mozbuild.py @@ -142,6 +142,7 @@ if CONFIG['GNU_CXX']: CXXFLAGS += [ '-Wno-overloaded-virtual', '-Wno-unused-function', + '-fomit-frame-pointer', ] if not CONFIG['CLANG_CXX']: CXXFLAGS += ['-Wno-logical-op'] diff --git a/gfx/skia/moz.build b/gfx/skia/moz.build index 6c0c2b5be157..1606995375c7 100644 --- a/gfx/skia/moz.build +++ b/gfx/skia/moz.build @@ -970,6 +970,7 @@ if CONFIG['GNU_CXX']: CXXFLAGS += [ '-Wno-overloaded-virtual', '-Wno-unused-function', + '-fomit-frame-pointer', ] if not CONFIG['CLANG_CXX']: CXXFLAGS += ['-Wno-logical-op'] diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index 0c7f6f7b4eac..37a39c22a6ba 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -129,7 +129,7 @@ private: // a method accessing a pref already exists. Just add yours in the list. // The apz prefs are explained in AsyncPanZoomController.cpp - DECL_GFX_PREF(Live, "apz.allow-checkerboarding", APZAllowCheckerboarding, bool, true); + DECL_GFX_PREF(Live, "apz.allow_checkerboarding", APZAllowCheckerboarding, bool, true); DECL_GFX_PREF(Live, "apz.asyncscroll.throttle", APZAsyncScrollThrottleTime, int32_t, 100); DECL_GFX_PREF(Live, "apz.asyncscroll.timeout", APZAsyncScrollTimeout, int32_t, 300); DECL_GFX_PREF(Live, "apz.axis_lock_mode", APZAxisLockMode, int32_t, 0); diff --git a/image/test/reftest/downscaling/black-border-bottom.png b/image/test/reftest/downscaling/black-border-bottom.png new file mode 100644 index 000000000000..efa7ce2dce18 Binary files /dev/null and b/image/test/reftest/downscaling/black-border-bottom.png differ diff --git a/image/test/reftest/downscaling/black-border-left.png b/image/test/reftest/downscaling/black-border-left.png new file mode 100644 index 000000000000..11bc67e98342 Binary files /dev/null and b/image/test/reftest/downscaling/black-border-left.png differ diff --git a/image/test/reftest/downscaling/black-border-rect.svg b/image/test/reftest/downscaling/black-border-rect.svg new file mode 100644 index 000000000000..0fa01a0a6394 --- /dev/null +++ b/image/test/reftest/downscaling/black-border-rect.svg @@ -0,0 +1,3 @@ + + + diff --git a/image/test/reftest/downscaling/black-border-right.png b/image/test/reftest/downscaling/black-border-right.png new file mode 100644 index 000000000000..081c52d5bca7 Binary files /dev/null and b/image/test/reftest/downscaling/black-border-right.png differ diff --git a/image/test/reftest/downscaling/black-border-top.png b/image/test/reftest/downscaling/black-border-top.png new file mode 100644 index 000000000000..fc6e69e02aa1 Binary files /dev/null and b/image/test/reftest/downscaling/black-border-top.png differ diff --git a/image/test/reftest/downscaling/downscale-2a.html b/image/test/reftest/downscaling/downscale-2a.html new file mode 100644 index 000000000000..fac11ccee53a --- /dev/null +++ b/image/test/reftest/downscaling/downscale-2a.html @@ -0,0 +1,31 @@ + + + + + + + + + + + diff --git a/image/test/reftest/downscaling/downscale-2b.html b/image/test/reftest/downscaling/downscale-2b.html new file mode 100644 index 000000000000..af7ecbff3302 --- /dev/null +++ b/image/test/reftest/downscaling/downscale-2b.html @@ -0,0 +1,31 @@ + + + + + + + + + + + diff --git a/image/test/reftest/downscaling/downscale-2c.html b/image/test/reftest/downscaling/downscale-2c.html new file mode 100644 index 000000000000..18f70456b1d4 --- /dev/null +++ b/image/test/reftest/downscaling/downscale-2c.html @@ -0,0 +1,31 @@ + + + + + + + + + + + diff --git a/image/test/reftest/downscaling/downscale-2d.html b/image/test/reftest/downscaling/downscale-2d.html new file mode 100644 index 000000000000..8d9547b73eb6 --- /dev/null +++ b/image/test/reftest/downscaling/downscale-2d.html @@ -0,0 +1,31 @@ + + + + + + + + + + + diff --git a/image/test/reftest/downscaling/downscale-2e.html b/image/test/reftest/downscaling/downscale-2e.html new file mode 100644 index 000000000000..c3d0d771f3a5 --- /dev/null +++ b/image/test/reftest/downscaling/downscale-2e.html @@ -0,0 +1,31 @@ + + + + + + + + + + + diff --git a/image/test/reftest/downscaling/downscale-2f.html b/image/test/reftest/downscaling/downscale-2f.html new file mode 100644 index 000000000000..42cfad1f5752 --- /dev/null +++ b/image/test/reftest/downscaling/downscale-2f.html @@ -0,0 +1,31 @@ + + + + + + + + + + + diff --git a/image/test/reftest/downscaling/downscale-svg-1-ref.html b/image/test/reftest/downscaling/downscale-svg-1-ref.html new file mode 100644 index 000000000000..8935619ebd28 --- /dev/null +++ b/image/test/reftest/downscaling/downscale-svg-1-ref.html @@ -0,0 +1,13 @@ + + + + + + + + diff --git a/image/test/reftest/downscaling/downscale-svg-1a.html b/image/test/reftest/downscaling/downscale-svg-1a.html new file mode 100644 index 000000000000..2263cc998240 --- /dev/null +++ b/image/test/reftest/downscaling/downscale-svg-1a.html @@ -0,0 +1,8 @@ + + + + +
+ + diff --git a/image/test/reftest/downscaling/downscale-svg-1b.html b/image/test/reftest/downscaling/downscale-svg-1b.html new file mode 100644 index 000000000000..9db239c7cd7a --- /dev/null +++ b/image/test/reftest/downscaling/downscale-svg-1b.html @@ -0,0 +1,8 @@ + + + + +
+ + diff --git a/image/test/reftest/downscaling/downscale-svg-1c.html b/image/test/reftest/downscaling/downscale-svg-1c.html new file mode 100644 index 000000000000..f8babf02672b --- /dev/null +++ b/image/test/reftest/downscaling/downscale-svg-1c.html @@ -0,0 +1,8 @@ + + + + +
+ + diff --git a/image/test/reftest/downscaling/downscale-svg-1d.html b/image/test/reftest/downscaling/downscale-svg-1d.html new file mode 100644 index 000000000000..9a56a51de0ba --- /dev/null +++ b/image/test/reftest/downscaling/downscale-svg-1d.html @@ -0,0 +1,8 @@ + + + + +
+ + diff --git a/image/test/reftest/downscaling/downscale-svg-1e.html b/image/test/reftest/downscaling/downscale-svg-1e.html new file mode 100644 index 000000000000..732ac22c964d --- /dev/null +++ b/image/test/reftest/downscaling/downscale-svg-1e.html @@ -0,0 +1,8 @@ + + + + +
+ + diff --git a/image/test/reftest/downscaling/downscale-svg-1f.html b/image/test/reftest/downscaling/downscale-svg-1f.html new file mode 100644 index 000000000000..0124682c70ca --- /dev/null +++ b/image/test/reftest/downscaling/downscale-svg-1f.html @@ -0,0 +1,8 @@ + + + + +
+ + diff --git a/image/test/reftest/downscaling/reftest.list b/image/test/reftest/downscaling/reftest.list index 53f5988b0a21..c087dd520c72 100644 --- a/image/test/reftest/downscaling/reftest.list +++ b/image/test/reftest/downscaling/reftest.list @@ -4,6 +4,14 @@ # as long as it's barely noticable visually. When necessary, this can be # explicitly allowed via 'fuzzy'/'fuzzy-if' annotations. # +# Many of these tests check primarily that we don't lose rows or columns of +# pixels when downscaling by making sure that the result isn't too similar to +# about:blank. A small amount of fuzziness is used to ensure that the tests +# don't pass because of very slight deviations; passing tests should be +# substantially different from about:blank. This fuzziness should *not* be +# removed as doing so would make the tests pass in situations where they +# shouldn't. +# # IMPORTANT: For robustness, each test should be listed *twice* in this # manifest -- once with the high quality downscaling pref disabled, and once # with this pref enabled. The pref is set via "default-preferences", so @@ -13,12 +21,77 @@ # Also note that Mac OS X has its own system-level downscaling algorithm, so # tests here may need Mac-specific "fuzzy-if(cocoaWidget,...)" annotations. + +# RUN TESTS NOT AFFECTED BY HIGH QUALITY DOWNSCALING: +# =================================================== +fails == downscale-svg-1a.html downscale-svg-1-ref.html?80 +fails == downscale-svg-1b.html downscale-svg-1-ref.html?72 +fails == downscale-svg-1c.html downscale-svg-1-ref.html?64 +fails == downscale-svg-1d.html downscale-svg-1-ref.html?53 +fails == downscale-svg-1e.html downscale-svg-1-ref.html?40 +fails == downscale-svg-1f.html downscale-svg-1-ref.html?24 + # RUN TESTS WITH HIGH QUALITY DOWNSCALING DISABLED: # ================================================= default-preferences pref(image.high_quality_downscaling.enabled,false) fuzzy-if(cocoaWidget,106,31) == downscale-1.html downscale-1-ref.html +fuzzy(5,999) random != downscale-2a.html?203,52,left about:blank +fuzzy(5,999) random != downscale-2b.html?203,52,left about:blank +fuzzy(5,999) random != downscale-2c.html?203,52,left about:blank +fuzzy(5,999) random != downscale-2d.html?203,52,left about:blank +fuzzy(5,999) random != downscale-2e.html?203,52,left about:blank +fuzzy(5,999) random != downscale-2f.html?203,52,left about:blank + +fuzzy(5,999) random != downscale-2a.html?205,53,left about:blank +fuzzy(5,999) random != downscale-2b.html?205,53,left about:blank +fuzzy(5,999) random != downscale-2c.html?205,53,left about:blank +fuzzy(5,999) random != downscale-2d.html?205,53,left about:blank +fuzzy(5,999) random != downscale-2e.html?205,53,left about:blank +fuzzy(5,999) random != downscale-2f.html?205,53,left about:blank + +fuzzy(5,999) random != downscale-2a.html?203,52,right about:blank +fuzzy(5,999) random != downscale-2b.html?203,52,right about:blank +fuzzy(5,999) random != downscale-2c.html?203,52,right about:blank +fuzzy(5,999) random != downscale-2d.html?203,52,right about:blank +fuzzy(5,999) random != downscale-2e.html?203,52,right about:blank +fuzzy(5,999) random != downscale-2f.html?203,52,right about:blank + +fuzzy(5,999) random != downscale-2a.html?205,53,right about:blank +fuzzy(5,999) random != downscale-2b.html?205,53,right about:blank +fuzzy(5,999) random != downscale-2c.html?205,53,right about:blank +fuzzy(5,999) random != downscale-2d.html?205,53,right about:blank +fuzzy(5,999) random != downscale-2e.html?205,53,right about:blank +fuzzy(5,999) random != downscale-2f.html?205,53,right about:blank + +fuzzy(5,999) random != downscale-2a.html?203,52,top about:blank +fuzzy(5,999) random != downscale-2b.html?203,52,top about:blank +fuzzy(5,999) random != downscale-2c.html?203,52,top about:blank +fuzzy(5,999) random != downscale-2d.html?203,52,top about:blank +fuzzy(5,999) random != downscale-2e.html?203,52,top about:blank +fuzzy(5,999) random != downscale-2f.html?203,52,top about:blank + +fuzzy(5,999) random != downscale-2a.html?205,53,top about:blank +fuzzy(5,999) random != downscale-2b.html?205,53,top about:blank +fuzzy(5,999) random != downscale-2c.html?205,53,top about:blank +fuzzy(5,999) random != downscale-2d.html?205,53,top about:blank +fuzzy(5,999) random != downscale-2e.html?205,53,top about:blank +fuzzy(5,999) random != downscale-2f.html?205,53,top about:blank + +fuzzy(5,999) random != downscale-2a.html?203,52,bottom about:blank +fuzzy(5,999) random != downscale-2b.html?203,52,bottom about:blank +fuzzy(5,999) random != downscale-2c.html?203,52,bottom about:blank +fuzzy(5,999) random != downscale-2d.html?203,52,bottom about:blank +fuzzy(5,999) random != downscale-2e.html?203,52,bottom about:blank +fuzzy(5,999) random != downscale-2f.html?203,52,bottom about:blank + +fuzzy(5,999) random != downscale-2a.html?205,53,bottom about:blank +fuzzy(5,999) random != downscale-2b.html?205,53,bottom about:blank +fuzzy(5,999) random != downscale-2c.html?205,53,bottom about:blank +fuzzy(5,999) random != downscale-2d.html?205,53,bottom about:blank +fuzzy(5,999) random != downscale-2e.html?205,53,bottom about:blank +fuzzy(5,999) random != downscale-2f.html?205,53,bottom about:blank # RUN TESTS WITH HIGH QUALITY DOWNSCALING ENABLED: # ================================================ @@ -26,3 +99,59 @@ fuzzy-if(cocoaWidget,106,31) == downscale-1.html downscale-1-ref.html default-preferences pref(image.high_quality_downscaling.enabled,true) fuzzy(31,127) == downscale-1.html downscale-1-ref.html + +fuzzy(5,999) random != downscale-2a.html?203,52,left about:blank +fuzzy(5,999) random != downscale-2b.html?203,52,left about:blank +fuzzy(5,999) random != downscale-2c.html?203,52,left about:blank +fuzzy(5,999) random != downscale-2d.html?203,52,left about:blank +fuzzy(5,999) random != downscale-2e.html?203,52,left about:blank +fuzzy(5,999) random != downscale-2f.html?203,52,left about:blank + +fuzzy(5,999) random != downscale-2a.html?205,53,left about:blank +fuzzy(5,999) random != downscale-2b.html?205,53,left about:blank +fuzzy(5,999) random != downscale-2c.html?205,53,left about:blank +fuzzy(5,999) random != downscale-2d.html?205,53,left about:blank +fuzzy(5,999) random != downscale-2e.html?205,53,left about:blank +fuzzy(5,999) random != downscale-2f.html?205,53,left about:blank + +fuzzy(5,999) random != downscale-2a.html?203,52,right about:blank +fuzzy(5,999) random != downscale-2b.html?203,52,right about:blank +fuzzy(5,999) random != downscale-2c.html?203,52,right about:blank +fuzzy(5,999) random != downscale-2d.html?203,52,right about:blank +fuzzy(5,999) random != downscale-2e.html?203,52,right about:blank +fuzzy(5,999) random != downscale-2f.html?203,52,right about:blank + +fuzzy(5,999) random != downscale-2a.html?205,53,right about:blank +fuzzy(5,999) random != downscale-2b.html?205,53,right about:blank +fuzzy(5,999) random != downscale-2c.html?205,53,right about:blank +fuzzy(5,999) random != downscale-2d.html?205,53,right about:blank +fuzzy(5,999) random != downscale-2e.html?205,53,right about:blank +fuzzy(5,999) random != downscale-2f.html?205,53,right about:blank + +fuzzy(5,999) random != downscale-2a.html?203,52,top about:blank +fuzzy(5,999) random != downscale-2b.html?203,52,top about:blank +fuzzy(5,999) random != downscale-2c.html?203,52,top about:blank +fuzzy(5,999) random != downscale-2d.html?203,52,top about:blank +fuzzy(5,999) random != downscale-2e.html?203,52,top about:blank +fuzzy(5,999) random != downscale-2f.html?203,52,top about:blank + +fuzzy(5,999) random != downscale-2a.html?205,53,top about:blank +fuzzy(5,999) random != downscale-2b.html?205,53,top about:blank +fuzzy(5,999) random != downscale-2c.html?205,53,top about:blank +fuzzy(5,999) random != downscale-2d.html?205,53,top about:blank +fuzzy(5,999) random != downscale-2e.html?205,53,top about:blank +fuzzy(5,999) random != downscale-2f.html?205,53,top about:blank + +fuzzy(5,999) random != downscale-2a.html?203,52,bottom about:blank +fuzzy(5,999) random != downscale-2b.html?203,52,bottom about:blank +fuzzy(5,999) random != downscale-2c.html?203,52,bottom about:blank +fuzzy(5,999) random != downscale-2d.html?203,52,bottom about:blank +fuzzy(5,999) random != downscale-2e.html?203,52,bottom about:blank +fuzzy(5,999) random != downscale-2f.html?203,52,bottom about:blank + +fuzzy(5,999) random != downscale-2a.html?205,53,bottom about:blank +fuzzy(5,999) random != downscale-2b.html?205,53,bottom about:blank +fuzzy(5,999) random != downscale-2c.html?205,53,bottom about:blank +fuzzy(5,999) random != downscale-2d.html?205,53,bottom about:blank +fuzzy(5,999) random != downscale-2e.html?205,53,bottom about:blank +fuzzy(5,999) random != downscale-2f.html?205,53,bottom about:blank diff --git a/ipc/chromium/src/base/message_pump_glib.cc b/ipc/chromium/src/base/message_pump_glib.cc index 58ebe86dc860..eefa3df53283 100644 --- a/ipc/chromium/src/base/message_pump_glib.cc +++ b/ipc/chromium/src/base/message_pump_glib.cc @@ -16,9 +16,6 @@ namespace { -// We send a byte across a pipe to wakeup the event loop. -const char kWorkScheduled = '\0'; - // Return a timeout suitable for the glib loop, -1 to block forever, // 0 to return right away, or a timeout in milliseconds from now. int GetTimeIntervalMilliseconds(const base::TimeTicks& from) { diff --git a/ipc/glue/WindowsMessageLoop.cpp b/ipc/glue/WindowsMessageLoop.cpp index 3de93a765b14..fbc9c102993c 100644 --- a/ipc/glue/WindowsMessageLoop.cpp +++ b/ipc/glue/WindowsMessageLoop.cpp @@ -14,6 +14,7 @@ #include "nsServiceManagerUtils.h" #include "nsString.h" #include "nsIXULAppInfo.h" +#include "WinUtils.h" #include "mozilla/PaintTracker.h" @@ -169,10 +170,31 @@ static void DumpNeuteredMessage(HWND hwnd, UINT uMsg) { #ifdef DEBUG - nsAutoCString log("Received \"nonqueued\" message "); - log.AppendInt(uMsg); + nsAutoCString log("Received \"nonqueued\" "); + // classify messages + if (uMsg < WM_USER) { + int idx = 0; + while (mozilla::widget::gAllEvents[idx].mId != (long)uMsg && + mozilla::widget::gAllEvents[idx].mStr != nullptr) { + idx++; + } + if (mozilla::widget::gAllEvents[idx].mStr) { + log.AppendPrintf("ui message \"%s\"", mozilla::widget::gAllEvents[idx].mStr); + } else { + log.AppendPrintf("ui message (0x%X)", uMsg); + } + } else if (uMsg >= WM_USER && uMsg < WM_APP) { + log.AppendPrintf("WM_USER message (0x%X)", uMsg); + } else if (uMsg >= WM_APP && uMsg < 0xC000) { + log.AppendPrintf("WM_APP message (0x%X)", uMsg); + } else if (uMsg >= 0xC000 && uMsg < 0x10000) { + log.AppendPrintf("registered windows message (0x%X)", uMsg); + } else { + log.AppendPrintf("system message (0x%X)", uMsg); + } + log.AppendLiteral(" during a synchronous IPC message for window "); - log.AppendInt((int64_t)hwnd); + log.AppendPrintf("0x%X", hwnd); wchar_t className[256] = { 0 }; if (GetClassNameW(hwnd, className, sizeof(className) - 1) > 0) { @@ -296,7 +318,8 @@ ProcessOrDeferMessage(HWND hwnd, case WM_GETTEXT: case WM_NCHITTEST: case WM_STYLECHANGING: // Intentional fall-through. - case WM_WINDOWPOSCHANGING: { + case WM_WINDOWPOSCHANGING: + case WM_GETTEXTLENGTH: { return DefWindowProc(hwnd, uMsg, wParam, lParam); } diff --git a/js/ipc/JavaScriptShared.cpp b/js/ipc/JavaScriptShared.cpp index b048d8e3e367..2c96f3fea70c 100644 --- a/js/ipc/JavaScriptShared.cpp +++ b/js/ipc/JavaScriptShared.cpp @@ -35,7 +35,7 @@ IdToObjectMap::trace(JSTracer *trc) { for (Table::Range r(table_.all()); !r.empty(); r.popFront()) { DebugOnly prior = r.front().value().get(); - JS_CallHeapObjectTracer(trc, &r.front().value(), "ipc-object"); + JS_CallObjectTracer(trc, &r.front().value(), "ipc-object"); MOZ_ASSERT(r.front().value() == prior); } } @@ -135,7 +135,7 @@ ObjectToIdMap::keyMarkCallback(JSTracer *trc, JSObject *key, void *data) { Table *table = static_cast(data); JSObject *prior = key; - JS_CallObjectTracer(trc, &key, "ObjectIdCache::table_ key"); + JS_CallUnbarrieredObjectTracer(trc, &key, "ObjectIdCache::table_ key"); table->rekeyIfMoved(prior, key); } diff --git a/js/public/TracingAPI.h b/js/public/TracingAPI.h index 3c7fdbe1b11c..fef0e5dec7b3 100644 --- a/js/public/TracingAPI.h +++ b/js/public/TracingAPI.h @@ -155,37 +155,40 @@ class JS_PUBLIC_API(JSTracer) // and re-inserted with the correct hash. // extern JS_PUBLIC_API(void) -JS_CallValueTracer(JSTracer *trc, JS::Value *valuep, const char *name); +JS_CallValueTracer(JSTracer *trc, JS::Heap *valuep, const char *name); extern JS_PUBLIC_API(void) -JS_CallIdTracer(JSTracer *trc, jsid *idp, const char *name); +JS_CallIdTracer(JSTracer *trc, JS::Heap *idp, const char *name); extern JS_PUBLIC_API(void) -JS_CallObjectTracer(JSTracer *trc, JSObject **objp, const char *name); +JS_CallObjectTracer(JSTracer *trc, JS::Heap *objp, const char *name); extern JS_PUBLIC_API(void) -JS_CallStringTracer(JSTracer *trc, JSString **strp, const char *name); +JS_CallStringTracer(JSTracer *trc, JS::Heap *strp, const char *name); extern JS_PUBLIC_API(void) -JS_CallScriptTracer(JSTracer *trc, JSScript **scriptp, const char *name); +JS_CallScriptTracer(JSTracer *trc, JS::Heap *scriptp, const char *name); extern JS_PUBLIC_API(void) -JS_CallHeapValueTracer(JSTracer *trc, JS::Heap *valuep, const char *name); +JS_CallFunctionTracer(JSTracer *trc, JS::Heap *funp, const char *name); + +// The following JS_CallUnbarriered*Tracer functions should only be called where +// you know for sure that a heap post barrier is not required. Use with extreme +// caution! +extern JS_PUBLIC_API(void) +JS_CallUnbarrieredValueTracer(JSTracer *trc, JS::Value *valuep, const char *name); extern JS_PUBLIC_API(void) -JS_CallHeapIdTracer(JSTracer *trc, JS::Heap *idp, const char *name); +JS_CallUnbarrieredIdTracer(JSTracer *trc, jsid *idp, const char *name); extern JS_PUBLIC_API(void) -JS_CallHeapObjectTracer(JSTracer *trc, JS::Heap *objp, const char *name); +JS_CallUnbarrieredObjectTracer(JSTracer *trc, JSObject **objp, const char *name); extern JS_PUBLIC_API(void) -JS_CallHeapStringTracer(JSTracer *trc, JS::Heap *strp, const char *name); +JS_CallUnbarrieredStringTracer(JSTracer *trc, JSString **strp, const char *name); extern JS_PUBLIC_API(void) -JS_CallHeapScriptTracer(JSTracer *trc, JS::Heap *scriptp, const char *name); - -extern JS_PUBLIC_API(void) -JS_CallHeapFunctionTracer(JSTracer *trc, JS::Heap *funp, const char *name); +JS_CallUnbarrieredScriptTracer(JSTracer *trc, JSScript **scriptp, const char *name); template inline void @@ -193,7 +196,7 @@ JS_CallHashSetObjectTracer(JSTracer *trc, HashSetEnum &e, JSObject *const &key, { JSObject *updated = key; trc->setTracingLocation(reinterpret_cast(&const_cast(key))); - JS_CallObjectTracer(trc, &updated, name); + JS_CallUnbarrieredObjectTracer(trc, &updated, name); if (updated != key) e.rekeyFront(key, updated); } diff --git a/js/src/assembler/assembler/X86Assembler.h b/js/src/assembler/assembler/X86Assembler.h index d81c15674455..767bafc3d867 100644 --- a/js/src/assembler/assembler/X86Assembler.h +++ b/js/src/assembler/assembler/X86Assembler.h @@ -288,6 +288,7 @@ private: OP2_MOVPS_VpsWps = 0x10, OP2_MOVSD_WsdVsd = 0x11, OP2_MOVPS_WpsVps = 0x11, + OP2_MOVHLPS_VqUq = 0x12, OP2_UNPCKLPS_VsdWsd = 0x14, OP2_MOVAPD_VsdWsd = 0x28, OP2_MOVAPS_VsdWsd = 0x28, @@ -312,6 +313,7 @@ private: OP2_MOVD_VdEd = 0x6E, OP2_MOVDQ_VsdWsd = 0x6F, OP2_MOVDQ_VdqWdq = 0x6F, + OP2_PSHUFD_VdqWdqIb = 0x70, OP2_PSRLDQ_Vd = 0x73, OP2_PCMPEQW = 0x75, OP2_MOVD_EdVd = 0x7E, @@ -325,7 +327,8 @@ private: OP2_MOVZX_GvEb = 0xB6, OP2_MOVZX_GvEw = 0xB7, OP2_XADD_EvGv = 0xC1, - OP2_PEXTRW_GdUdIb = 0xC5 + OP2_PEXTRW_GdUdIb = 0xC5, + OP2_SHUFPS_VpsWpsIb = 0xC6 } TwoByteOpcodeID; typedef enum { @@ -2587,6 +2590,32 @@ public: m_formatter.twoByteOp(OP2_MOVD_VdEd, (RegisterID)dst, src); } + void pshufd_irr(uint32_t mask, XMMRegisterID src, XMMRegisterID dst) + { + JS_ASSERT(mask < 256); + spew("pshufd 0x%x, %s, %s", + mask, nameFPReg(src), nameFPReg(dst)); + m_formatter.prefix(PRE_SSE_66); + m_formatter.twoByteOp(OP2_PSHUFD_VdqWdqIb, (RegisterID)dst, (RegisterID)src); + m_formatter.immediate8(uint8_t(mask)); + } + + void shufps_irr(uint32_t mask, XMMRegisterID src, XMMRegisterID dst) + { + JS_ASSERT(mask < 256); + spew("shufps 0x%x, %s, %s", + mask, nameFPReg(src), nameFPReg(dst)); + m_formatter.twoByteOp(OP2_SHUFPS_VpsWpsIb, (RegisterID)dst, (RegisterID)src); + m_formatter.immediate8(uint8_t(mask)); + } + + void movhlps_rr(XMMRegisterID src, XMMRegisterID dst) + { + spew("movhlps %s, %s", + nameFPReg(src), nameFPReg(dst)); + m_formatter.twoByteOp(OP2_MOVHLPS_VqUq, (RegisterID)dst, (RegisterID)src); + } + void psrldq_ir(int shift, XMMRegisterID dest) { spew("psrldq $%d, %s", diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index c938963f1fec..1b2ee023b526 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -829,7 +829,7 @@ CountHeap(JSContext *cx, unsigned argc, jsval *vp) if (startValue.isUndefined()) { JS_TraceRuntime(&countTracer.base); } else { - JS_CallValueTracer(&countTracer.base, startValue.address(), "root"); + JS_CallUnbarrieredValueTracer(&countTracer.base, startValue.address(), "root"); } JSCountHeapNode *node; diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index 9f1189fb154e..133279a3c5d6 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -3400,10 +3400,10 @@ CType::Trace(JSTracer* trc, JSObject* obj) FieldInfoHash* fields = static_cast(slot.toPrivate()); for (FieldInfoHash::Enum e(*fields); !e.empty(); e.popFront()) { JSString *key = e.front().key(); - JS_CallStringTracer(trc, &key, "fieldName"); + JS_CallUnbarrieredStringTracer(trc, &key, "fieldName"); if (key != e.front().key()) e.rekeyFront(JS_ASSERT_STRING_IS_FLAT(key)); - JS_CallHeapObjectTracer(trc, &e.front().value().mType, "fieldType"); + JS_CallObjectTracer(trc, &e.front().value().mType, "fieldType"); } break; @@ -3418,10 +3418,10 @@ CType::Trace(JSTracer* trc, JSObject* obj) JS_ASSERT(fninfo); // Identify our objects to the tracer. - JS_CallHeapObjectTracer(trc, &fninfo->mABI, "abi"); - JS_CallHeapObjectTracer(trc, &fninfo->mReturnType, "returnType"); + JS_CallObjectTracer(trc, &fninfo->mABI, "abi"); + JS_CallObjectTracer(trc, &fninfo->mReturnType, "returnType"); for (size_t i = 0; i < fninfo->mArgTypes.length(); ++i) - JS_CallHeapObjectTracer(trc, &fninfo->mArgTypes[i], "argType"); + JS_CallObjectTracer(trc, &fninfo->mArgTypes[i], "argType"); break; } @@ -4818,7 +4818,7 @@ PostBarrierCallback(JSTracer *trc, JSString *key, void *data) UnbarrieredFieldInfoHash *table = reinterpret_cast(data); JSString *prior = key; - JS_CallStringTracer(trc, &key, "CType fieldName"); + JS_CallUnbarrieredStringTracer(trc, &key, "CType fieldName"); table->rekeyIfMoved(JS_ASSERT_STRING_IS_FLAT(prior), JS_ASSERT_STRING_IS_FLAT(key)); } @@ -6152,10 +6152,10 @@ CClosure::Trace(JSTracer* trc, JSObject* obj) // Identify our objects to the tracer. (There's no need to identify // 'closureObj', since that's us.) - JS_CallHeapObjectTracer(trc, &cinfo->typeObj, "typeObj"); - JS_CallHeapObjectTracer(trc, &cinfo->jsfnObj, "jsfnObj"); + JS_CallObjectTracer(trc, &cinfo->typeObj, "typeObj"); + JS_CallObjectTracer(trc, &cinfo->jsfnObj, "jsfnObj"); if (cinfo->thisObj) - JS_CallHeapObjectTracer(trc, &cinfo->thisObj, "thisObj"); + JS_CallObjectTracer(trc, &cinfo->thisObj, "thisObj"); } void diff --git a/js/src/gc/Tracer.cpp b/js/src/gc/Tracer.cpp index fcd0c80c47f6..f5c9d6761dad 100644 --- a/js/src/gc/Tracer.cpp +++ b/js/src/gc/Tracer.cpp @@ -28,67 +28,67 @@ using namespace js::gc; using mozilla::DebugOnly; JS_PUBLIC_API(void) -JS_CallValueTracer(JSTracer *trc, Value *valuep, const char *name) +JS_CallUnbarrieredValueTracer(JSTracer *trc, Value *valuep, const char *name) { MarkValueUnbarriered(trc, valuep, name); } JS_PUBLIC_API(void) -JS_CallIdTracer(JSTracer *trc, jsid *idp, const char *name) +JS_CallUnbarrieredIdTracer(JSTracer *trc, jsid *idp, const char *name) { MarkIdUnbarriered(trc, idp, name); } JS_PUBLIC_API(void) -JS_CallObjectTracer(JSTracer *trc, JSObject **objp, const char *name) +JS_CallUnbarrieredObjectTracer(JSTracer *trc, JSObject **objp, const char *name) { MarkObjectUnbarriered(trc, objp, name); } JS_PUBLIC_API(void) -JS_CallStringTracer(JSTracer *trc, JSString **strp, const char *name) +JS_CallUnbarrieredStringTracer(JSTracer *trc, JSString **strp, const char *name) { MarkStringUnbarriered(trc, strp, name); } JS_PUBLIC_API(void) -JS_CallScriptTracer(JSTracer *trc, JSScript **scriptp, const char *name) +JS_CallUnbarrieredScriptTracer(JSTracer *trc, JSScript **scriptp, const char *name) { MarkScriptUnbarriered(trc, scriptp, name); } JS_PUBLIC_API(void) -JS_CallHeapValueTracer(JSTracer *trc, JS::Heap *valuep, const char *name) +JS_CallValueTracer(JSTracer *trc, JS::Heap *valuep, const char *name) { MarkValueUnbarriered(trc, valuep->unsafeGet(), name); } JS_PUBLIC_API(void) -JS_CallHeapIdTracer(JSTracer *trc, JS::Heap *idp, const char *name) +JS_CallIdTracer(JSTracer *trc, JS::Heap *idp, const char *name) { MarkIdUnbarriered(trc, idp->unsafeGet(), name); } JS_PUBLIC_API(void) -JS_CallHeapObjectTracer(JSTracer *trc, JS::Heap *objp, const char *name) +JS_CallObjectTracer(JSTracer *trc, JS::Heap *objp, const char *name) { MarkObjectUnbarriered(trc, objp->unsafeGet(), name); } JS_PUBLIC_API(void) -JS_CallHeapStringTracer(JSTracer *trc, JS::Heap *strp, const char *name) +JS_CallStringTracer(JSTracer *trc, JS::Heap *strp, const char *name) { MarkStringUnbarriered(trc, strp->unsafeGet(), name); } JS_PUBLIC_API(void) -JS_CallHeapScriptTracer(JSTracer *trc, JS::Heap *scriptp, const char *name) +JS_CallScriptTracer(JSTracer *trc, JS::Heap *scriptp, const char *name) { MarkScriptUnbarriered(trc, scriptp->unsafeGet(), name); } JS_PUBLIC_API(void) -JS_CallHeapFunctionTracer(JSTracer *trc, JS::Heap *funp, const char *name) +JS_CallFunctionTracer(JSTracer *trc, JS::Heap *funp, const char *name) { MarkObjectUnbarriered(trc, funp->unsafeGet(), name); } diff --git a/js/src/jit/IonTypes.h b/js/src/jit/IonTypes.h index 78ba1c8548cd..f5aaf8c4f7ff 100644 --- a/js/src/jit/IonTypes.h +++ b/js/src/jit/IonTypes.h @@ -451,6 +451,15 @@ SimdTypeToScalarType(MIRType type) MOZ_ASSUME_UNREACHABLE("unexpected SIMD kind"); } +// Indicates a lane in a SIMD register: X for the first lane, Y for the second, +// Z for the third (if any), W for the fourth (if any). +enum SimdLane { + LaneX = 0x0, + LaneY = 0x1, + LaneZ = 0x2, + LaneW = 0x3 +}; + #ifdef DEBUG // Track the pipeline of opcodes which has produced a snapshot. diff --git a/js/src/jit/LIR-Common.h b/js/src/jit/LIR-Common.h index 987632e67189..37c7e0c3bd89 100644 --- a/js/src/jit/LIR-Common.h +++ b/js/src/jit/LIR-Common.h @@ -128,6 +128,44 @@ class LMoveGroup : public LInstructionHelper<0, 0, 0> } }; +// Extracts an element from a given SIMD int32x4 lane. +class LSimdExtractElementI : public LInstructionHelper<1, 1, 0> +{ + SimdLane lane_; + + public: + LIR_HEADER(SimdExtractElementI); + + LSimdExtractElementI(const LAllocation &base, SimdLane lane) : lane_(lane) { + setOperand(0, base); + } + const LAllocation *getBase() { + return getOperand(0); + } + SimdLane lane() const { + return lane_; + } +}; + +// Extracts an element from a given SIMD float32x4 lane. +class LSimdExtractElementF : public LInstructionHelper<1, 1, 0> +{ + SimdLane lane_; + + public: + LIR_HEADER(SimdExtractElementF); + + LSimdExtractElementF(const LAllocation &base, SimdLane lane) : lane_(lane) { + setOperand(0, base); + } + const LAllocation *getBase() { + return getOperand(0); + } + SimdLane lane() const { + return lane_; + } +}; + // Constant 32-bit integer. class LInteger : public LInstructionHelper<1, 0, 0> { diff --git a/js/src/jit/LOpcodes.h b/js/src/jit/LOpcodes.h index 1579a234ee84..f16b6126c94f 100644 --- a/js/src/jit/LOpcodes.h +++ b/js/src/jit/LOpcodes.h @@ -16,6 +16,8 @@ _(Pointer) \ _(Double) \ _(Float32) \ + _(SimdExtractElementI) \ + _(SimdExtractElementF) \ _(Value) \ _(CloneLiteral) \ _(Parameter) \ diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index fce4423b67cd..28a8563eb685 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -3638,6 +3638,28 @@ LIRGenerator::visitRecompileCheck(MRecompileCheck *ins) return assignSafepoint(lir, ins); } +bool +LIRGenerator::visitSimdExtractElement(MSimdExtractElement *ins) +{ + JS_ASSERT(IsSimdType(ins->input()->type())); + JS_ASSERT(!IsSimdType(ins->type())); + + if (ins->input()->type() == MIRType_Int32x4) { + // Note: there could be int16x8 in the future, which doesn't use the + // same instruction. We either need to pass the arity or create new LIns. + LUse use = useRegisterAtStart(ins->input()); + return define(new(alloc()) LSimdExtractElementI(use, ins->lane()), ins); + } + + if (ins->input()->type() == MIRType_Float32x4) { + LUse use = useRegisterAtStart(ins->input()); + return define(new(alloc()) LSimdExtractElementF(use, ins->lane()), ins); + } + + MOZ_ASSUME_UNREACHABLE("Unknown SIMD kind when extracting element"); + return false; +} + static void SpewResumePoint(MBasicBlock *block, MInstruction *ins, MResumePoint *resumePoint) { diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h index 786e88350ae8..4cb3ea77d46c 100644 --- a/js/src/jit/Lowering.h +++ b/js/src/jit/Lowering.h @@ -263,6 +263,7 @@ class LIRGenerator : public LIRGeneratorSpecific bool visitGetDOMProperty(MGetDOMProperty *ins); bool visitGetDOMMember(MGetDOMMember *ins); bool visitRecompileCheck(MRecompileCheck *ins); + bool visitSimdExtractElement(MSimdExtractElement *ins); }; } // namespace jit diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 55ffe11102a4..f0b95f43f06a 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -1233,6 +1233,47 @@ class MConstant : public MNullaryInstruction ALLOW_CLONE(MConstant) }; +// Extracts a lane element from a given vector type, given by its lane symbol. +class MSimdExtractElement : public MUnaryInstruction +{ + protected: + SimdLane lane_; + + MSimdExtractElement(MDefinition *obj, MIRType type, SimdLane lane) + : MUnaryInstruction(obj), lane_(lane) + { + JS_ASSERT(IsSimdType(obj->type())); + JS_ASSERT(uint32_t(lane) < SimdTypeToLength(obj->type())); + JS_ASSERT(!IsSimdType(type)); + JS_ASSERT(SimdTypeToScalarType(obj->type()) == type); + setResultType(type); + } + + public: + INSTRUCTION_HEADER(SimdExtractElement); + static MSimdExtractElement *NewAsmJS(TempAllocator &alloc, MDefinition *obj, MIRType type, + SimdLane lane) + { + return new(alloc) MSimdExtractElement(obj, type, lane); + } + + SimdLane lane() const { + return lane_; + } + + AliasSet getAliasSet() const { + return AliasSet::None(); + } + bool congruentTo(const MDefinition *ins) const { + if (!ins->isSimdExtractElement()) + return false; + const MSimdExtractElement *other = ins->toSimdExtractElement(); + if (other->lane_ != lane_) + return false; + return congruentIfOperandsEqual(other); + } +}; + // Deep clone a constant JSObject. class MCloneLiteral : public MUnaryInstruction, diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h index 4c07b46640bf..bd6a5bbc101e 100644 --- a/js/src/jit/MOpcodes.h +++ b/js/src/jit/MOpcodes.h @@ -12,6 +12,7 @@ namespace jit { #define MIR_OPCODE_LIST(_) \ _(Constant) \ + _(SimdExtractElement) \ _(CloneLiteral) \ _(Parameter) \ _(Callee) \ diff --git a/js/src/jit/ParallelSafetyAnalysis.cpp b/js/src/jit/ParallelSafetyAnalysis.cpp index 9b5291450fe4..3f0379c6b8b9 100644 --- a/js/src/jit/ParallelSafetyAnalysis.cpp +++ b/js/src/jit/ParallelSafetyAnalysis.cpp @@ -112,6 +112,7 @@ class ParallelSafetyVisitor : public MDefinitionVisitor // obviously safe for now. We can loosen as we need. SAFE_OP(Constant) + SAFE_OP(SimdExtractElement) UNSAFE_OP(CloneLiteral) SAFE_OP(Parameter) SAFE_OP(Callee) diff --git a/js/src/jit/arm/CodeGenerator-arm.h b/js/src/jit/arm/CodeGenerator-arm.h index 68c3332b13b1..ca2e3e0030a3 100644 --- a/js/src/jit/arm/CodeGenerator-arm.h +++ b/js/src/jit/arm/CodeGenerator-arm.h @@ -224,6 +224,11 @@ class CodeGeneratorARM : public CodeGeneratorShared bool visitUDiv(LUDiv *ins); bool visitUMod(LUMod *ins); bool visitSoftUDivOrMod(LSoftUDivOrMod *ins); + + public: + // Unimplemented SIMD instructions + bool visitSimdExtractElementI(LSimdExtractElementI *ins) { MOZ_ASSUME_UNREACHABLE("NYI"); } + bool visitSimdExtractElementF(LSimdExtractElementF *ins) { MOZ_ASSUME_UNREACHABLE("NYI"); } }; typedef CodeGeneratorARM CodeGeneratorSpecific; diff --git a/js/src/jit/none/Architecture-none.h b/js/src/jit/none/Architecture-none.h index 33ffec64f590..7878b3ca5cc4 100644 --- a/js/src/jit/none/Architecture-none.h +++ b/js/src/jit/none/Architecture-none.h @@ -12,6 +12,9 @@ namespace js { namespace jit { +static const bool SupportsSimd = false; +static const uint32_t SimdStackAlignment = 0; + class Registers { public: diff --git a/js/src/jit/none/Trampoline-none.cpp b/js/src/jit/none/Trampoline-none.cpp index 9022e6e273e5..f08ae3302913 100644 --- a/js/src/jit/none/Trampoline-none.cpp +++ b/js/src/jit/none/Trampoline-none.cpp @@ -35,9 +35,9 @@ uint32_t FrameSizeClass::frameSize() const { MOZ_CRASH(); } void DispatchIonCache::initializeAddCacheState(LInstruction *, AddCacheState *) { MOZ_CRASH(); } -void MacroAssembler::PushRegsInMask(RegisterSet) { MOZ_CRASH(); } +void MacroAssembler::PushRegsInMask(RegisterSet, FloatRegisterSet) { MOZ_CRASH(); } void MacroAssembler::clampDoubleToUint8(FloatRegister, Register) { MOZ_CRASH(); } -void MacroAssembler::PopRegsInMaskIgnore(RegisterSet, RegisterSet) { MOZ_CRASH(); } +void MacroAssembler::PopRegsInMaskIgnore(RegisterSet, RegisterSet, FloatRegisterSet) { MOZ_CRASH(); } void MacroAssembler::alignFrameForICArguments(AfterICSaveLive &) { MOZ_CRASH(); } void MacroAssembler::restoreFrameAlignmentForICArguments(AfterICSaveLive &) { MOZ_CRASH(); } diff --git a/js/src/jit/shared/Assembler-x86-shared.h b/js/src/jit/shared/Assembler-x86-shared.h index 152693e8ac7a..bce51a09839a 100644 --- a/js/src/jit/shared/Assembler-x86-shared.h +++ b/js/src/jit/shared/Assembler-x86-shared.h @@ -1463,6 +1463,18 @@ class AssemblerX86Shared : public AssemblerShared JS_ASSERT(HasSSE2()); masm.movd_rr(src.code(), dest.code()); } + void pshufd(uint32_t mask, FloatRegister src, FloatRegister dest) { + JS_ASSERT(HasSSE2()); + masm.pshufd_irr(mask, src.code(), dest.code()); + } + void movhlps(FloatRegister src, FloatRegister dest) { + JS_ASSERT(HasSSE2()); + masm.movhlps_rr(src.code(), dest.code()); + } + void shufps(uint32_t mask, FloatRegister src, FloatRegister dest) { + JS_ASSERT(HasSSE2()); + masm.shufps_irr(mask, src.code(), dest.code()); + } void addsd(FloatRegister src, FloatRegister dest) { JS_ASSERT(HasSSE2()); masm.addsd_rr(src.code(), dest.code()); diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.cpp b/js/src/jit/shared/CodeGenerator-x86-shared.cpp index d3ba4683b275..077ca7c61d56 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp @@ -2053,6 +2053,45 @@ CodeGeneratorX86Shared::visitNegF(LNegF *ins) return true; } +bool +CodeGeneratorX86Shared::visitSimdExtractElementI(LSimdExtractElementI *ins) +{ + FloatRegister input = ToFloatRegister(ins->input()); + Register output = ToRegister(ins->output()); + + SimdLane lane = ins->lane(); + if (lane == LaneX) { + // The value we want to extract is in the low double-word + masm.moveLowInt32(input, output); + } else { + uint32_t mask = MacroAssembler::ComputeShuffleMask(lane); + masm.shuffleInt32(mask, input, ScratchSimdReg); + masm.moveLowInt32(ScratchSimdReg, output); + } + return true; +} + +bool +CodeGeneratorX86Shared::visitSimdExtractElementF(LSimdExtractElementF *ins) +{ + FloatRegister input = ToFloatRegister(ins->input()); + FloatRegister output = ToFloatRegister(ins->output()); + + SimdLane lane = ins->lane(); + if (lane == LaneX) { + // The value we want to extract is in the low double-word + if (input != output) + masm.moveFloat32(input, output); + } else if (lane == LaneZ) { + masm.moveHighPairToLowPairFloat32(input, output); + } else { + uint32_t mask = MacroAssembler::ComputeShuffleMask(lane); + masm.shuffleFloat32(mask, input, output); + } + masm.canonicalizeFloat(output); + return true; +} + bool CodeGeneratorX86Shared::visitForkJoinGetSlice(LForkJoinGetSlice *ins) { diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.h b/js/src/jit/shared/CodeGenerator-x86-shared.h index 1278c95e6b46..6d33809f36bb 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.h +++ b/js/src/jit/shared/CodeGenerator-x86-shared.h @@ -204,6 +204,10 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared bool visitNegD(LNegD *lir); bool visitNegF(LNegF *lir); + // SIMD operators + bool visitSimdExtractElementI(LSimdExtractElementI *lir); + bool visitSimdExtractElementF(LSimdExtractElementF *lir); + // Out of line visitors. bool visitOutOfLineBailout(OutOfLineBailout *ool); bool visitOutOfLineUndoALUOperation(OutOfLineUndoALUOperation *ool); diff --git a/js/src/jit/shared/MacroAssembler-x86-shared.h b/js/src/jit/shared/MacroAssembler-x86-shared.h index 66baa19d51d0..6c49f9900162 100644 --- a/js/src/jit/shared/MacroAssembler-x86-shared.h +++ b/js/src/jit/shared/MacroAssembler-x86-shared.h @@ -499,6 +499,38 @@ class MacroAssemblerX86Shared : public Assembler movups(src, Operand(dest)); } + static uint32_t ComputeShuffleMask(SimdLane x, SimdLane y = LaneX, + SimdLane z = LaneX, SimdLane w = LaneX) + { + uint32_t r = (uint32_t(w) << 6) | + (uint32_t(z) << 4) | + (uint32_t(y) << 2) | + uint32_t(x); + JS_ASSERT(r < 256); + return r; + } + + void shuffleInt32(uint32_t mask, FloatRegister src, FloatRegister dest) { + pshufd(mask, src, dest); + } + void moveLowInt32(FloatRegister src, Register dest) { + movd(src, dest); + } + + void moveHighPairToLowPairFloat32(FloatRegister src, FloatRegister dest) { + movhlps(src, dest); + } + void shuffleFloat32(uint32_t mask, FloatRegister src, FloatRegister dest) { + // The shuffle instruction on x86 is such that it moves 2 words from + // the dest and 2 words from the src operands. To simplify things, just + // clobber the output with the input and apply the instruction + // afterwards. + // Note: this is useAtStart-safe because src isn't read afterwards. + if (src != dest) + moveAlignedFloat32x4(src, dest); + shufps(mask, dest, dest); + } + void moveFloatAsDouble(Register src, FloatRegister dest) { movd(src, dest); cvtss2sd(dest, dest); diff --git a/js/src/jsapi-tests/tests.cpp b/js/src/jsapi-tests/tests.cpp index 2f3008b4c0a8..0be730b81edf 100644 --- a/js/src/jsapi-tests/tests.cpp +++ b/js/src/jsapi-tests/tests.cpp @@ -28,6 +28,28 @@ bool JSAPITest::init() return true; } +void JSAPITest::uninit() +{ + if (oldCompartment) { + JS_LeaveCompartment(cx, oldCompartment); + oldCompartment = nullptr; + } + if (global) { + JS_LeaveCompartment(cx, nullptr); + JS::RemoveObjectRoot(cx, &global); + global = nullptr; + } + if (cx) { + JS_EndRequest(cx); + JS_DestroyContext(cx); + cx = nullptr; + } + if (rt) { + destroyRuntime(); + rt = nullptr; + } +} + bool JSAPITest::exec(const char *bytes, const char *filename, int lineno) { JS::RootedValue v(cx); @@ -64,8 +86,11 @@ JSObject * JSAPITest::createGlobal(JSPrincipals *principals) /* Populate the global object with the standard globals, like Object and Array. */ - if (!JS_InitStandardClasses(cx, globalHandle)) - return nullptr; + if (!JS_InitStandardClasses(cx, globalHandle)) { + global = nullptr; + JS::RemoveObjectRoot(cx, &global); + } + return global; } @@ -91,6 +116,7 @@ int main(int argc, char *argv[]) if (!test->init()) { printf("TEST-UNEXPECTED-FAIL | %s | Failed to initialize.\n", name); failures++; + test->uninit(); continue; } diff --git a/js/src/jsapi-tests/tests.h b/js/src/jsapi-tests/tests.h index a89b1caef7d1..dfe00235db3d 100644 --- a/js/src/jsapi-tests/tests.h +++ b/js/src/jsapi-tests/tests.h @@ -67,28 +67,14 @@ class JSAPITest list = this; } - virtual ~JSAPITest() { uninit(); } + virtual ~JSAPITest() { + JS_ASSERT(!rt); + JS_ASSERT(!cx); + JS_ASSERT(!global); + } virtual bool init(); - - virtual void uninit() { - if (oldCompartment) { - JS_LeaveCompartment(cx, oldCompartment); - oldCompartment = nullptr; - } - global = nullptr; - if (cx) { - JS::RemoveObjectRoot(cx, &global); - JS_LeaveCompartment(cx, nullptr); - JS_EndRequest(cx); - JS_DestroyContext(cx); - cx = nullptr; - } - if (rt) { - destroyRuntime(); - rt = nullptr; - } - } + virtual void uninit(); virtual const char * name() = 0; virtual bool run(JS::HandleObject global) = 0; diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 36b3dd8123f8..d46d33db6c2b 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -1022,7 +1022,7 @@ JS::ObjectPtr::isAboutToBeFinalized() void JS::ObjectPtr::trace(JSTracer *trc, const char *name) { - JS_CallHeapObjectTracer(trc, &value, name); + JS_CallObjectTracer(trc, &value, name); } JS_FRIEND_API(JSObject *) diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index a78e333f27e2..0c1c62bda238 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -3237,46 +3237,20 @@ ReallocateElements(ThreadSafeContext *cx, JSObject *obj, ObjectElements *oldHead // Having the second class means that for bigger arrays the constant factor is // higher, but we waste less space. // -// There are two exceptions to the above rules. Both exceptions optimize for -// cases where the requested capacity is near the array's length. -// -// - If |reqAllocated| would give us a capacity equal to |length|, it's -// probably due to code like this: -// -// var a = new Array(1024); -// -// 1024 is smaller than |EagerAllocationMaxLength|, so the array elements -// are allocated immediately. This is likely to be the final size of the -// array, so we just allocate the exact length immediately. In this case, the -// capacity is 1024 and |goodAllocated| is 1026. -// -// - If the |goodAllocated| value we compute gives a capacity slightly smaller -// than |length|, we nudge |goodAllocated| up so that the capacity equals the -// length. Consider the following code, which is very much like some code -// that appears in the Kraken benchmark suite: -// -// var a = new Array(8192); -// for (var i = 0; i < 8192; i++) { a[i] = i; } -// -// 8192 is larger than |EagerAllocationMaxLength|, so the elements will be -// resized up to the final size rather than allocated immediately. Without -// this exception, it would be repeatedly resized and |goodAllocated| would -// reach 8192, which gives a capacity of 8190, which isn't quite enough, so -// it would then be have to be resized one more time to 16382 elements, -// wasting time and memory. But with the exception, the final resizing is -// nudged, resulting in a capacity of 8192 and |goodAllocated| value of 8194. +// There is one exception to the above rule: for the power-of-two cases, if the +// chosen capacity would be 2/3 or more of the array's length, the chosen +// capacity is adjusted (up or down) to be equal to the array's length +// (assuming length is at least as large as the required capacity). This avoids +// the allocation of excess elements which are unlikely to be needed, either in +// this resizing or a subsequent one. The 2/3 factor is chosen so that +// exceptional resizings will at most triple the capacity, as opposed to the +// usual doubling. // /* static */ uint32_t JSObject::goodAllocated(uint32_t reqAllocated, uint32_t length = 0) { static const uint32_t Mebi = 1024 * 1024; - uint32_t reqCapacity = reqAllocated - ObjectElements::VALUES_PER_HEADER; - if (reqCapacity == length && reqAllocated >= JSObject::SLOT_CAPACITY_MIN) { - // This is the first exception mentioned above. - return length + ObjectElements::VALUES_PER_HEADER; - } - // This table was generated with this JavaScript code and a small amount // subsequent reformatting: // @@ -3303,8 +3277,16 @@ JSObject::goodAllocated(uint32_t reqAllocated, uint32_t length = 0) uint32_t goodAllocated = reqAllocated; if (goodAllocated < Mebi) { goodAllocated = RoundUpPow2(goodAllocated); + + // Look for the abovementioned exception. + uint32_t goodCapacity = goodAllocated - ObjectElements::VALUES_PER_HEADER; + uint32_t reqCapacity = reqAllocated - ObjectElements::VALUES_PER_HEADER; + if (length >= reqCapacity && goodCapacity > (length / 3) * 2) + goodAllocated = length + ObjectElements::VALUES_PER_HEADER; + if (goodAllocated < JSObject::SLOT_CAPACITY_MIN) goodAllocated = JSObject::SLOT_CAPACITY_MIN; + } else { uint32_t i = 0; while (true) { @@ -3322,12 +3304,6 @@ JSObject::goodAllocated(uint32_t reqAllocated, uint32_t length = 0) } } - uint32_t goodCapacity = goodAllocated - ObjectElements::VALUES_PER_HEADER; - if (length > goodCapacity && (length - goodCapacity) < 16) { - // This is the second exception mentioned above. - return length + ObjectElements::VALUES_PER_HEADER; - } - return goodAllocated; } diff --git a/js/src/vm/WeakMapPtr.cpp b/js/src/vm/WeakMapPtr.cpp index 99d0c19323a6..84f75767f36b 100644 --- a/js/src/vm/WeakMapPtr.cpp +++ b/js/src/vm/WeakMapPtr.cpp @@ -99,7 +99,7 @@ JS::WeakMapPtr::keyMarkCallback(JSTracer *trc, K key, void *data) { auto map = static_cast< JS::WeakMapPtr* >(data); K prior = key; - JS_CallObjectTracer(trc, &key, "WeakMapPtr key"); + JS_CallUnbarrieredObjectTracer(trc, &key, "WeakMapPtr key"); return Utils::cast(map->ptr)->rekeyIfMoved(prior, key); } diff --git a/js/xpconnect/src/XPCMaps.h b/js/xpconnect/src/XPCMaps.h index 9464d73ba12a..cf29a49ded21 100644 --- a/js/xpconnect/src/XPCMaps.h +++ b/js/xpconnect/src/XPCMaps.h @@ -88,7 +88,7 @@ private: static void KeyMarkCallback(JSTracer *trc, JSObject *key, void *data) { JSObject2WrappedJSMap* self = static_cast(data); JSObject *prior = key; - JS_CallObjectTracer(trc, &key, "XPCJSRuntime::mWrappedJSMap key"); + JS_CallUnbarrieredObjectTracer(trc, &key, "XPCJSRuntime::mWrappedJSMap key"); self->mTable.rekeyIfMoved(prior, key); } @@ -704,7 +704,7 @@ private: UnbarrieredMap &table = reinterpret_cast(self->mTable); JSObject *prior = key; - JS_CallObjectTracer(trc, &key, "XPCWrappedNativeScope::mWaiverWrapperMap key"); + JS_CallUnbarrieredObjectTracer(trc, &key, "XPCWrappedNativeScope::mWaiverWrapperMap key"); table.rekeyIfMoved(prior, key); } diff --git a/js/xpconnect/src/XPCVariant.cpp b/js/xpconnect/src/XPCVariant.cpp index 9887b2af1a70..245c56225adf 100644 --- a/js/xpconnect/src/XPCVariant.cpp +++ b/js/xpconnect/src/XPCVariant.cpp @@ -70,7 +70,7 @@ void XPCTraceableVariant::TraceJS(JSTracer* trc) { MOZ_ASSERT(mJSVal.isMarkable()); trc->setTracingDetails(GetTraceName, this, 0); - JS_CallHeapValueTracer(trc, &mJSVal, "XPCTraceableVariant::mJSVal"); + JS_CallValueTracer(trc, &mJSVal, "XPCTraceableVariant::mJSVal"); } // static diff --git a/js/xpconnect/src/XPCWrappedJS.cpp b/js/xpconnect/src/XPCWrappedJS.cpp index 35af471c36b6..20b4d7579aea 100644 --- a/js/xpconnect/src/XPCWrappedJS.cpp +++ b/js/xpconnect/src/XPCWrappedJS.cpp @@ -286,7 +286,7 @@ nsXPCWrappedJS::TraceJS(JSTracer* trc) { MOZ_ASSERT(mRefCnt >= 2 && IsValid(), "must be strongly referenced"); trc->setTracingDetails(GetTraceName, this, 0); - JS_CallHeapObjectTracer(trc, &mJSObj, "nsXPCWrappedJS::mJSObj"); + JS_CallObjectTracer(trc, &mJSObj, "nsXPCWrappedJS::mJSObj"); } // static diff --git a/js/xpconnect/src/XPCWrappedNative.cpp b/js/xpconnect/src/XPCWrappedNative.cpp index 496c4593b102..bf901b278484 100644 --- a/js/xpconnect/src/XPCWrappedNative.cpp +++ b/js/xpconnect/src/XPCWrappedNative.cpp @@ -2655,7 +2655,7 @@ void XPCJSObjectHolder::TraceJS(JSTracer *trc) { trc->setTracingDetails(GetTraceName, this, 0); - JS_CallHeapObjectTracer(trc, &mJSObj, "XPCJSObjectHolder::mJSObj"); + JS_CallObjectTracer(trc, &mJSObj, "XPCJSObjectHolder::mJSObj"); } // static diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 13df84330616..5962906ce4dd 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -179,7 +179,7 @@ #define XPC_JS_MAP_LENGTH 32 #define XPC_JS_CLASS_MAP_LENGTH 32 -#define XPC_NATIVE_MAP_LENGTH 32 +#define XPC_NATIVE_MAP_LENGTH 8 #define XPC_NATIVE_PROTO_MAP_LENGTH 8 #define XPC_DYING_NATIVE_PROTO_MAP_LENGTH 8 #define XPC_DETACHED_NATIVE_PROTO_MAP_LENGTH 16 diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index 326e5b9e0162..57b12e1440b4 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -1579,6 +1579,9 @@ ContainerState::CreateOrRecycleThebesLayer(const nsIFrame* aAnimatedGeometryRoot // Check whether the layer will be scrollable. This is used as a hint to // influence whether tiled layers are used or not. LayerManager::ThebesLayerCreationHint creationHint = LayerManager::NONE; + if (mParameters.mInLowPrecisionDisplayPort ) { + creationHint = LayerManager::SCROLLABLE; + } nsIFrame* animatedGeometryRootParent = aAnimatedGeometryRoot->GetParent(); if (animatedGeometryRootParent && animatedGeometryRootParent->GetType() == nsGkAtoms::scrollFrame) { diff --git a/layout/base/FrameLayerBuilder.h b/layout/base/FrameLayerBuilder.h index 1db33c9ed62b..b0c25a959283 100644 --- a/layout/base/FrameLayerBuilder.h +++ b/layout/base/FrameLayerBuilder.h @@ -72,6 +72,7 @@ struct ContainerLayerParameters { , mInTransformedSubtree(false) , mInActiveTransformedSubtree(false) , mDisableSubpixelAntialiasingInDescendants(false) + , mInLowPrecisionDisplayPort(false) {} ContainerLayerParameters(float aXScale, float aYScale) : mXScale(aXScale) @@ -80,6 +81,7 @@ struct ContainerLayerParameters { , mInTransformedSubtree(false) , mInActiveTransformedSubtree(false) , mDisableSubpixelAntialiasingInDescendants(false) + , mInLowPrecisionDisplayPort(false) {} ContainerLayerParameters(float aXScale, float aYScale, const nsIntPoint& aOffset, @@ -91,6 +93,7 @@ struct ContainerLayerParameters { , mInTransformedSubtree(aParent.mInTransformedSubtree) , mInActiveTransformedSubtree(aParent.mInActiveTransformedSubtree) , mDisableSubpixelAntialiasingInDescendants(aParent.mDisableSubpixelAntialiasingInDescendants) + , mInLowPrecisionDisplayPort(aParent.mInLowPrecisionDisplayPort) {} float mXScale, mYScale; /** @@ -106,6 +109,7 @@ struct ContainerLayerParameters { bool mInTransformedSubtree; bool mInActiveTransformedSubtree; bool mDisableSubpixelAntialiasingInDescendants; + bool mInLowPrecisionDisplayPort; /** * When this is false, ThebesLayer coordinates are drawn to with an integer * translation and the scale in mXScale/mYScale. diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index 4c2e5c10d219..44bb0db50f01 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -2684,6 +2684,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext, if (aBGClipRect) { clipState.mBGClipArea = *aBGClipRect; clipState.mCustomClip = true; + clipState.mHasRoundedCorners = false; SetupDirtyRects(clipState.mBGClipArea, aDirtyRect, appUnitsPerPixel, &clipState.mDirtyRect, &clipState.mDirtyRectGfx); } else { diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 6967ebee6b33..2b27ca8affbd 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -3586,8 +3586,17 @@ already_AddRefed nsDisplaySubDocument::BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, const ContainerLayerParameters& aContainerParameters) { + nsPresContext* presContext = mFrame->PresContext(); + nsIFrame* rootScrollFrame = presContext->PresShell()->GetRootScrollFrame(); + ContainerLayerParameters params = aContainerParameters; + if ((mFlags & GENERATE_SCROLLABLE_LAYER) && + rootScrollFrame->GetContent() && + nsLayoutUtils::GetCriticalDisplayPort(rootScrollFrame->GetContent(), nullptr)) { + params.mInLowPrecisionDisplayPort = true; + } + nsRefPtr layer = nsDisplayOwnLayer::BuildLayer( - aBuilder, aManager, aContainerParameters); + aBuilder, aManager, params); if (!(mFlags & GENERATE_SCROLLABLE_LAYER)) { return layer.forget(); @@ -3595,7 +3604,6 @@ nsDisplaySubDocument::BuildLayer(nsDisplayListBuilder* aBuilder, NS_ASSERTION(layer->AsContainerLayer(), "nsDisplayOwnLayer should have made a ContainerLayer"); if (ContainerLayer* container = layer->AsContainerLayer()) { - nsPresContext* presContext = mFrame->PresContext(); nsIFrame* rootScrollFrame = presContext->PresShell()->GetRootScrollFrame(); bool isRootContentDocument = presContext->IsRootContentDocument(); @@ -3606,7 +3614,7 @@ nsDisplaySubDocument::BuildLayer(nsDisplayListBuilder* aBuilder, container->SetScrollHandoffParentId(mScrollParentId); RecordFrameMetrics(mFrame, rootScrollFrame, ReferenceFrame(), container, viewport, - false, isRootContentDocument, aContainerParameters); + false, isRootContentDocument, params); } return layer.forget(); @@ -3899,9 +3907,16 @@ already_AddRefed nsDisplayScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, const ContainerLayerParameters& aContainerParameters) { + + ContainerLayerParameters params = aContainerParameters; + if (mScrolledFrame->GetContent() && + nsLayoutUtils::GetCriticalDisplayPort(mScrolledFrame->GetContent(), nullptr)) { + params.mInLowPrecisionDisplayPort = true; + } + nsRefPtr layer = aManager->GetLayerBuilder()-> BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList, - aContainerParameters, nullptr); + params, nullptr); nsRect viewport = mScrollFrame->GetRect() - mScrollFrame->GetPosition() + @@ -3909,7 +3924,7 @@ nsDisplayScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder, layer->SetScrollHandoffParentId(mScrollParentId); RecordFrameMetrics(mScrolledFrame, mScrollFrame, ReferenceFrame(), layer, - viewport, false, false, aContainerParameters); + viewport, false, false, params); if (mList.IsOpaque()) { nsRect displayport; diff --git a/layout/forms/nsColorControlFrame.cpp b/layout/forms/nsColorControlFrame.cpp index 466b8a364c6a..e5daf2243634 100644 --- a/layout/forms/nsColorControlFrame.cpp +++ b/layout/forms/nsColorControlFrame.cpp @@ -83,10 +83,12 @@ nsColorControlFrame::CreateAnonymousContent(nsTArray& aElements) } void -nsColorControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, +nsColorControlFrame::AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) { - aElements.MaybeAppendElement(mColorContent); + if (mColorContent) { + aElements.AppendElement(mColorContent); + } } nsresult diff --git a/layout/forms/nsColorControlFrame.h b/layout/forms/nsColorControlFrame.h index 9aa3865e35a9..177920dbc476 100644 --- a/layout/forms/nsColorControlFrame.h +++ b/layout/forms/nsColorControlFrame.h @@ -37,7 +37,7 @@ public: // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; - virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, + virtual void AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) MOZ_OVERRIDE; // nsIFrame diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index 9711bc5276e2..c08e9e7f340f 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -1184,11 +1184,16 @@ nsComboboxControlFrame::CreateAnonymousContent(nsTArray& aElements) } void -nsComboboxControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, +nsComboboxControlFrame::AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) { - aElements.MaybeAppendElement(mDisplayContent); - aElements.MaybeAppendElement(mButtonContent); + if (mDisplayContent) { + aElements.AppendElement(mDisplayContent); + } + + if (mButtonContent) { + aElements.AppendElement(mButtonContent); + } } // XXXbz this is a for-now hack. Now that display:inline-block works, diff --git a/layout/forms/nsComboboxControlFrame.h b/layout/forms/nsComboboxControlFrame.h index dd0654917f27..9c8c6d8beaeb 100644 --- a/layout/forms/nsComboboxControlFrame.h +++ b/layout/forms/nsComboboxControlFrame.h @@ -59,7 +59,7 @@ public: // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; - virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, + virtual void AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) MOZ_OVERRIDE; virtual nsIFrame* CreateFrameFor(nsIContent* aContent) MOZ_OVERRIDE; diff --git a/layout/forms/nsFileControlFrame.cpp b/layout/forms/nsFileControlFrame.cpp index ab65d8a9ccdf..90930897a792 100644 --- a/layout/forms/nsFileControlFrame.cpp +++ b/layout/forms/nsFileControlFrame.cpp @@ -150,11 +150,16 @@ nsFileControlFrame::CreateAnonymousContent(nsTArray& aElements) } void -nsFileControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, +nsFileControlFrame::AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) { - aElements.MaybeAppendElement(mBrowse); - aElements.MaybeAppendElement(mTextContent); + if (mBrowse) { + aElements.AppendElement(mBrowse); + } + + if (mTextContent) { + aElements.AppendElement(mTextContent); + } } NS_QUERYFRAME_HEAD(nsFileControlFrame) diff --git a/layout/forms/nsFileControlFrame.h b/layout/forms/nsFileControlFrame.h index 62b971f53730..780fdb7e366e 100644 --- a/layout/forms/nsFileControlFrame.h +++ b/layout/forms/nsFileControlFrame.h @@ -57,7 +57,7 @@ public: // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; - virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, + virtual void AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) MOZ_OVERRIDE; #ifdef ACCESSIBILITY diff --git a/layout/forms/nsGfxButtonControlFrame.cpp b/layout/forms/nsGfxButtonControlFrame.cpp index b075f71998a4..34050ff589d9 100644 --- a/layout/forms/nsGfxButtonControlFrame.cpp +++ b/layout/forms/nsGfxButtonControlFrame.cpp @@ -69,10 +69,12 @@ nsGfxButtonControlFrame::CreateAnonymousContent(nsTArray& aElements } void -nsGfxButtonControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, +nsGfxButtonControlFrame::AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) { - aElements.MaybeAppendElement(mTextContent); + if (mTextContent) { + aElements.AppendElement(mTextContent); + } } // Create the text content used as label for the button. diff --git a/layout/forms/nsGfxButtonControlFrame.h b/layout/forms/nsGfxButtonControlFrame.h index 1339ca96505f..03aa4861ca51 100644 --- a/layout/forms/nsGfxButtonControlFrame.h +++ b/layout/forms/nsGfxButtonControlFrame.h @@ -40,7 +40,7 @@ public: // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; - virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, + virtual void AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) MOZ_OVERRIDE; virtual nsIFrame* CreateFrameFor(nsIContent* aContent) MOZ_OVERRIDE; diff --git a/layout/forms/nsMeterFrame.cpp b/layout/forms/nsMeterFrame.cpp index f5bacd62fdf4..d479c5a0a436 100644 --- a/layout/forms/nsMeterFrame.cpp +++ b/layout/forms/nsMeterFrame.cpp @@ -79,10 +79,12 @@ nsMeterFrame::CreateAnonymousContent(nsTArray& aElements) } void -nsMeterFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, +nsMeterFrame::AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) { - aElements.MaybeAppendElement(mBarDiv); + if (mBarDiv) { + aElements.AppendElement(mBarDiv); + } } NS_QUERYFRAME_HEAD(nsMeterFrame) diff --git a/layout/forms/nsMeterFrame.h b/layout/forms/nsMeterFrame.h index 142ebf4dbb19..cb2d746c9924 100644 --- a/layout/forms/nsMeterFrame.h +++ b/layout/forms/nsMeterFrame.h @@ -42,7 +42,7 @@ public: // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; - virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, + virtual void AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) MOZ_OVERRIDE; virtual nsresult AttributeChanged(int32_t aNameSpaceID, diff --git a/layout/forms/nsNumberControlFrame.cpp b/layout/forms/nsNumberControlFrame.cpp index 5f988d7e5b07..20ed683466b1 100644 --- a/layout/forms/nsNumberControlFrame.cpp +++ b/layout/forms/nsNumberControlFrame.cpp @@ -676,11 +676,13 @@ nsNumberControlFrame::ShouldUseNativeStyleForSpinner() const } void -nsNumberControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, +nsNumberControlFrame::AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) { // Only one direct anonymous child: - aElements.MaybeAppendElement(mOuterWrapper); + if (mOuterWrapper) { + aElements.AppendElement(mOuterWrapper); + } } void diff --git a/layout/forms/nsNumberControlFrame.h b/layout/forms/nsNumberControlFrame.h index 30b7fcb9f806..b5eb3e92920f 100644 --- a/layout/forms/nsNumberControlFrame.h +++ b/layout/forms/nsNumberControlFrame.h @@ -68,7 +68,7 @@ public: // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; - virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, + virtual void AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) MOZ_OVERRIDE; #ifdef DEBUG_FRAME_DUMP diff --git a/layout/forms/nsProgressFrame.cpp b/layout/forms/nsProgressFrame.cpp index b69dac6c1066..f1f9caa74f29 100644 --- a/layout/forms/nsProgressFrame.cpp +++ b/layout/forms/nsProgressFrame.cpp @@ -76,10 +76,12 @@ nsProgressFrame::CreateAnonymousContent(nsTArray& aElements) } void -nsProgressFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, +nsProgressFrame::AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) { - aElements.MaybeAppendElement(mBarDiv); + if (mBarDiv) { + aElements.AppendElement(mBarDiv); + } } NS_QUERYFRAME_HEAD(nsProgressFrame) diff --git a/layout/forms/nsProgressFrame.h b/layout/forms/nsProgressFrame.h index b99c27721e32..67b4990465d4 100644 --- a/layout/forms/nsProgressFrame.h +++ b/layout/forms/nsProgressFrame.h @@ -47,7 +47,7 @@ public: // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; - virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, + virtual void AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) MOZ_OVERRIDE; virtual nsresult AttributeChanged(int32_t aNameSpaceID, diff --git a/layout/forms/nsRangeFrame.cpp b/layout/forms/nsRangeFrame.cpp index 4c87fe547f9d..ea257e59bdf5 100644 --- a/layout/forms/nsRangeFrame.cpp +++ b/layout/forms/nsRangeFrame.cpp @@ -154,12 +154,20 @@ nsRangeFrame::CreateAnonymousContent(nsTArray& aElements) } void -nsRangeFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, +nsRangeFrame::AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) { - aElements.MaybeAppendElement(mTrackDiv); - aElements.MaybeAppendElement(mProgressDiv); - aElements.MaybeAppendElement(mThumbDiv); + if (mTrackDiv) { + aElements.AppendElement(mTrackDiv); + } + + if (mProgressDiv) { + aElements.AppendElement(mProgressDiv); + } + + if (mThumbDiv) { + aElements.AppendElement(mThumbDiv); + } } class nsDisplayRangeFocusRing : public nsDisplayItem diff --git a/layout/forms/nsRangeFrame.h b/layout/forms/nsRangeFrame.h index 6fc3c54700e3..b84020f8c550 100644 --- a/layout/forms/nsRangeFrame.h +++ b/layout/forms/nsRangeFrame.h @@ -64,7 +64,7 @@ public: // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; - virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, + virtual void AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) MOZ_OVERRIDE; virtual nsresult AttributeChanged(int32_t aNameSpaceID, diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp index ca9502dfcd66..4b3dc363af44 100644 --- a/layout/forms/nsTextControlFrame.cpp +++ b/layout/forms/nsTextControlFrame.cpp @@ -394,15 +394,20 @@ nsTextControlFrame::CreateAnonymousContent(nsTArray& aElements) } void -nsTextControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, +nsTextControlFrame::AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) { nsCOMPtr txtCtrl = do_QueryInterface(GetContent()); NS_ASSERTION(txtCtrl, "Content not a text control element"); - aElements.MaybeAppendElement(txtCtrl->GetRootEditorNode()); - if (!(aFilter & nsIContent::eSkipPlaceholderContent)) - aElements.MaybeAppendElement(txtCtrl->GetPlaceholderNode()); + nsIContent* root = txtCtrl->GetRootEditorNode(); + if (root) { + aElements.AppendElement(root); + } + + nsIContent* placeholder = txtCtrl->GetPlaceholderNode(); + if (placeholder && !(aFilter & nsIContent::eSkipPlaceholderContent)) + aElements.AppendElement(placeholder); } diff --git a/layout/forms/nsTextControlFrame.h b/layout/forms/nsTextControlFrame.h index f4fc4d7602d7..d73b0f4e440b 100644 --- a/layout/forms/nsTextControlFrame.h +++ b/layout/forms/nsTextControlFrame.h @@ -82,7 +82,7 @@ public: // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; - virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, + virtual void AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) MOZ_OVERRIDE; virtual void SetInitialChildList(ChildListID aListID, diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp index 80a1edb88cca..5547312d60ac 100644 --- a/layout/generic/nsCanvasFrame.cpp +++ b/layout/generic/nsCanvasFrame.cpp @@ -114,11 +114,19 @@ nsCanvasFrame::CreateAnonymousContent(nsTArray& aElements) } void -nsCanvasFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, uint32_t aFilter) +nsCanvasFrame::AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) { - aElements.MaybeAppendElement(mTouchCaretElement); - aElements.MaybeAppendElement(mSelectionCaretsStartElement); - aElements.MaybeAppendElement(mSelectionCaretsEndElement); + if (mTouchCaretElement) { + aElements.AppendElement(mTouchCaretElement); + } + + if (mSelectionCaretsStartElement) { + aElements.AppendElement(mSelectionCaretsStartElement); + } + + if (mSelectionCaretsEndElement) { + aElements.AppendElement(mSelectionCaretsEndElement); + } } void diff --git a/layout/generic/nsCanvasFrame.h b/layout/generic/nsCanvasFrame.h index e20344fb8dea..1df0e02582b6 100644 --- a/layout/generic/nsCanvasFrame.h +++ b/layout/generic/nsCanvasFrame.h @@ -68,7 +68,7 @@ public: // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; - virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, uint32_t aFilter) MOZ_OVERRIDE; + virtual void AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) MOZ_OVERRIDE; // Touch caret handle function mozilla::dom::Element* GetTouchCaretElement() const diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 153da2929d48..dafe5ebe9b8a 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -104,7 +104,7 @@ nsHTMLScrollFrame::CreateAnonymousContent(nsTArray& aElements) } void -nsHTMLScrollFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, +nsHTMLScrollFrame::AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) { mHelper.AppendAnonymousContentTo(aElements, aFilter); @@ -1048,7 +1048,7 @@ nsXULScrollFrame::CreateAnonymousContent(nsTArray& aElements) } void -nsXULScrollFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, +nsXULScrollFrame::AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) { mHelper.AppendAnonymousContentTo(aElements, aFilter); @@ -3546,13 +3546,24 @@ ScrollFrameHelper::CreateAnonymousContent( } void -ScrollFrameHelper::AppendAnonymousContentTo(nsBaseContentList& aElements, +ScrollFrameHelper::AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) { - aElements.MaybeAppendElement(mHScrollbarContent); - aElements.MaybeAppendElement(mVScrollbarContent); - aElements.MaybeAppendElement(mScrollCornerContent); - aElements.MaybeAppendElement(mResizerContent); + if (mHScrollbarContent) { + aElements.AppendElement(mHScrollbarContent); + } + + if (mVScrollbarContent) { + aElements.AppendElement(mVScrollbarContent); + } + + if (mScrollCornerContent) { + aElements.AppendElement(mScrollCornerContent); + } + + if (mResizerContent) { + aElements.AppendElement(mResizerContent); + } } void diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h index 7a7f355244da..1f0d1aaff34e 100644 --- a/layout/generic/nsGfxScrollFrame.h +++ b/layout/generic/nsGfxScrollFrame.h @@ -58,7 +58,7 @@ public: nsresult CreateAnonymousContent( nsTArray& aElements); - void AppendAnonymousContentTo(nsBaseContentList& aElements, uint32_t aFilter); + void AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter); nsresult FireScrollPortEvent(); void PostOverflowEvent(); void Destroy(); @@ -544,7 +544,7 @@ public: // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; - virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, + virtual void AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) MOZ_OVERRIDE; // nsIScrollbarOwner @@ -833,7 +833,7 @@ public: // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; - virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, + virtual void AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) MOZ_OVERRIDE; virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE; diff --git a/layout/generic/nsIAnonymousContentCreator.h b/layout/generic/nsIAnonymousContentCreator.h index 12bb89c90e58..3343019d8186 100644 --- a/layout/generic/nsIAnonymousContentCreator.h +++ b/layout/generic/nsIAnonymousContentCreator.h @@ -69,7 +69,7 @@ public: * * @see nsIContent::GetChildren for set of values used for filter. */ - virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, + virtual void AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) = 0; /** diff --git a/layout/generic/nsVideoFrame.cpp b/layout/generic/nsVideoFrame.cpp index 60e0d92fc121..ffb77f5824ee 100644 --- a/layout/generic/nsVideoFrame.cpp +++ b/layout/generic/nsVideoFrame.cpp @@ -121,12 +121,20 @@ nsVideoFrame::CreateAnonymousContent(nsTArray& aElements) } void -nsVideoFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, +nsVideoFrame::AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFliter) { - aElements.MaybeAppendElement(mPosterImage); - aElements.MaybeAppendElement(mVideoControls); - aElements.MaybeAppendElement(mCaptionDiv); + if (mPosterImage) { + aElements.AppendElement(mPosterImage); + } + + if (mVideoControls) { + aElements.AppendElement(mVideoControls); + } + + if (mCaptionDiv) { + aElements.AppendElement(mCaptionDiv); + } } void diff --git a/layout/generic/nsVideoFrame.h b/layout/generic/nsVideoFrame.h index d044ad319d4e..9047e43fedfc 100644 --- a/layout/generic/nsVideoFrame.h +++ b/layout/generic/nsVideoFrame.h @@ -76,7 +76,7 @@ public: } virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; - virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, + virtual void AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilters) MOZ_OVERRIDE; nsIContent* GetPosterImage() { return mPosterImage; } diff --git a/layout/style/nsTransitionManager.cpp b/layout/style/nsTransitionManager.cpp index 609f5b573145..d1e7df72e36f 100644 --- a/layout/style/nsTransitionManager.cpp +++ b/layout/style/nsTransitionManager.cpp @@ -516,8 +516,6 @@ nsTransitionManager::ConsiderStartingTransition( nsRefPtr player = new dom::AnimationPlayer(timeline); player->mStartTime = timeline->GetCurrentTimeStamp(); - player->mPlayState = NS_STYLE_ANIMATION_PLAY_STATE_RUNNING; - player->mPauseStart = TimeStamp(); player->SetSource(pt); if (!aElementTransitions) { diff --git a/layout/svg/nsSVGUseFrame.cpp b/layout/svg/nsSVGUseFrame.cpp index 148f555b18bd..78c9f81c42e8 100644 --- a/layout/svg/nsSVGUseFrame.cpp +++ b/layout/svg/nsSVGUseFrame.cpp @@ -64,7 +64,7 @@ public: // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; - virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, + virtual void AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) MOZ_OVERRIDE; private: @@ -243,10 +243,12 @@ nsSVGUseFrame::CreateAnonymousContent(nsTArray& aElements) } void -nsSVGUseFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, +nsSVGUseFrame::AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) { SVGUseElement *use = static_cast(mContent); nsIContent* clone = use->GetAnonymousContent(); - aElements.MaybeAppendElement(clone); + if (clone) { + aElements.AppendElement(clone); + } } diff --git a/layout/xul/nsDocElementBoxFrame.cpp b/layout/xul/nsDocElementBoxFrame.cpp index 9140a641c878..02a1ee0cea86 100644 --- a/layout/xul/nsDocElementBoxFrame.cpp +++ b/layout/xul/nsDocElementBoxFrame.cpp @@ -43,7 +43,7 @@ public: // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray& aElements) MOZ_OVERRIDE; - virtual void AppendAnonymousContentTo(nsBaseContentList& aElements, + virtual void AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) MOZ_OVERRIDE; virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE @@ -123,11 +123,16 @@ nsDocElementBoxFrame::CreateAnonymousContent(nsTArray& aElements) } void -nsDocElementBoxFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, +nsDocElementBoxFrame::AppendAnonymousContentTo(nsTArray& aElements, uint32_t aFilter) { - aElements.MaybeAppendElement(mPopupgroupContent); - aElements.MaybeAppendElement(mTooltipContent); + if (mPopupgroupContent) { + aElements.AppendElement(mPopupgroupContent); + } + + if (mTooltipContent) { + aElements.AppendElement(mTooltipContent); + } } NS_QUERYFRAME_HEAD(nsDocElementBoxFrame) diff --git a/media/libstagefright/binding/Box.cpp b/media/libstagefright/binding/Box.cpp index d33cfcc634ac..8e28806066cc 100644 --- a/media/libstagefright/binding/Box.cpp +++ b/media/libstagefright/binding/Box.cpp @@ -58,7 +58,7 @@ Box::Box(BoxContext* aContext, uint64_t aOffset, const Box* aParent) } MediaByteRange boxRange(aOffset, aOffset + size); - if (boxRange.mEnd > mChildOffset || + if (mChildOffset >= boxRange.mEnd || (mParent && !mParent->mRange.Contains(boxRange)) || !byteRange->Contains(boxRange)) { return; diff --git a/media/libstagefright/binding/Index.cpp b/media/libstagefright/binding/Index.cpp index 75e2374dc095..eaed3b2c16f0 100644 --- a/media/libstagefright/binding/Index.cpp +++ b/media/libstagefright/binding/Index.cpp @@ -83,11 +83,16 @@ Index::Index(const stagefright::Vector& aIndex, } } +Index::~Index() {} + void Index::ConvertByteRangesToTimeRanges( const nsTArray& aByteRanges, nsTArray>* aTimeRanges) { + RangeFinder rangeFinder(aByteRanges); + nsTArray> timeRanges; + nsTArray moofIndex; nsTArray* index; if (mMoofParser) { @@ -98,16 +103,21 @@ Index::ConvertByteRangesToTimeRanges( // We take the index out of the moof parser and move it into a local // variable so we don't get concurrency issues. It gets freed when we // exit this function. - moofIndex = mMoofParser->mIndex; + for (int i = 0; i < mMoofParser->mMoofs.Length(); i++) { + Moof& moof = mMoofParser->mMoofs[i]; + if (rangeFinder.Contains(moof.mRange) && + rangeFinder.Contains(moof.mMdatRange)) { + timeRanges.AppendElements(moof.mTimeRanges); + } else { + moofIndex.AppendElements(mMoofParser->mMoofs[i].mIndex); + } + } } index = &moofIndex; } else { index = &mIndex; } - nsTArray> timeRanges; - RangeFinder rangeFinder(aByteRanges); - bool hasSync = false; for (size_t i = 0; i < index->Length(); i++) { const MediaSource::Indice& indice = (*index)[i]; diff --git a/media/libstagefright/binding/MoofParser.cpp b/media/libstagefright/binding/MoofParser.cpp index 45625bd4fb5c..89bf631b83a0 100644 --- a/media/libstagefright/binding/MoofParser.cpp +++ b/media/libstagefright/binding/MoofParser.cpp @@ -4,52 +4,26 @@ #include "mp4_demuxer/MoofParser.h" #include "mp4_demuxer/Box.h" -#include "MediaResource.h" - -using namespace stagefright; -using namespace mozilla; namespace mp4_demuxer { -class Moof -{ -public: - Moof(Box& aBox, MoofParser* aMoofParser); - void ParseTraf(Box& aBox); - void ParseTrun(Box& aBox, Tfhd& aTfhd, Tfdt& aTfdt); - -private: - MoofParser* mMoofParser; -}; +using namespace stagefright; +using namespace mozilla; void MoofParser::RebuildFragmentedIndex(const nsTArray& aByteRanges) { BoxContext context(mSource, aByteRanges); - mIndex.Clear(); - size_t moofCount = 0; - for (size_t i = 0; i + 1 < mMoofOffsets.Length(); i++) { - Box box(&context, mMoofOffsets[i]); - if (box.IsAvailable()) { - MOZ_ASSERT(box.IsType("moof")); - Moof(box, this); - } - } - for (Box box = mMoofOffsets.IsEmpty() - ? Box(&context, 0) - : Box(&context, mMoofOffsets.LastElement()); - box.IsAvailable(); box = box.Next()) { + Box box(&context, mOffset); + for (; box.IsAvailable(); box = box.Next()) { if (box.IsType("moov")) { ParseMoov(box); } else if (box.IsType("moof")) { - if (mMoofOffsets.IsEmpty() || - mMoofOffsets.LastElement() != box.Offset()) { - mMoofOffsets.AppendElement(box.Offset()); - } - Moof(box, this); + mMoofs.AppendElement(Moof(box, mTrex, mMdhd)); } + mOffset = box.NextOffset(); } } @@ -73,7 +47,9 @@ MoofParser::ParseTrak(Box& aBox) if (box.IsType("tkhd")) { tkhd = Tkhd(box); } else if (box.IsType("mdia")) { - ParseMdia(box, tkhd); + if (tkhd.mTrackId == mTrex.mTrackId) { + ParseMdia(box, tkhd); + } } } } @@ -83,9 +59,7 @@ MoofParser::ParseMdia(Box& aBox, Tkhd& aTkhd) { for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) { if (box.IsType("mdhd")) { - if (mTrackId == aTkhd.mTrackId) { - mMdhd = Mdhd(box); - } + mMdhd = Mdhd(box); } } } @@ -95,42 +69,45 @@ MoofParser::ParseMvex(Box& aBox) { for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) { if (box.IsType("trex")) { - mTrex = Trex(box); + Trex trex = Trex(box); + if (trex.mTrackId == mTrex.mTrackId) { + mTrex = trex; + } } } } -Moof::Moof(Box& aBox, MoofParser* aMoofParser) : mMoofParser(aMoofParser) +Moof::Moof(Box& aBox, Trex& aTrex, Mdhd& aMdhd) : mRange(aBox.Range()) { for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) { if (box.IsType("traf")) { - ParseTraf(box); + ParseTraf(box, aTrex, aMdhd); } } } void -Moof::ParseTraf(Box& aBox) +Moof::ParseTraf(Box& aBox, Trex& aTrex, Mdhd& aMdhd) { - Tfhd tfhd(mMoofParser->mTrex); + Tfhd tfhd(aTrex); Tfdt tfdt; for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) { if (box.IsType("tfhd")) { - tfhd = Tfhd(box, mMoofParser->mTrex); + tfhd = Tfhd(box, aTrex); } else if (box.IsType("tfdt")) { tfdt = Tfdt(box); } else if (box.IsType("trun")) { - if (mMoofParser->mTrackId == tfhd.mTrackId) { - ParseTrun(box, tfhd, tfdt); + if (tfhd.mTrackId == aTrex.mTrackId) { + ParseTrun(box, tfhd, tfdt, aMdhd); } } } } void -Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Tfdt& aTfdt) +Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Tfdt& aTfdt, Mdhd& aMdhd) { - if (!mMoofParser->mMdhd.mTimescale) { + if (!aMdhd.mTimescale) { return; } @@ -147,6 +124,7 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Tfdt& aTfdt) bool hasFirstSampleFlags = flags & 4; uint32_t firstSampleFlags = hasFirstSampleFlags ? reader->ReadU32() : 0; uint64_t decodeTime = aTfdt.mBaseMediaDecodeTime; + nsTArray> timeRanges; for (size_t i = 0; i < sampleCount; i++) { uint32_t sampleDuration = flags & 0x100 ? reader->ReadU32() : aTfhd.mDefaultSampleDuration; @@ -164,15 +142,26 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Tfdt& aTfdt) indice.end_offset = offset; indice.start_composition = - ((decodeTime + ctsOffset) * 1000000ll) / mMoofParser->mMdhd.mTimescale; + ((decodeTime + ctsOffset) * 1000000ll) / aMdhd.mTimescale; decodeTime += sampleDuration; indice.end_composition = - ((decodeTime + ctsOffset) * 1000000ll) / mMoofParser->mMdhd.mTimescale; + ((decodeTime + ctsOffset) * 1000000ll) / aMdhd.mTimescale; indice.sync = !(sampleFlags & 0x1010000); - mMoofParser->mIndex.AppendElement(indice); + mIndex.AppendElement(indice); + + MediaByteRange compositionRange(indice.start_offset, indice.end_offset); + if (mMdatRange.IsNull()) { + mMdatRange = compositionRange; + } else { + mMdatRange = mMdatRange.Extents(compositionRange); + } + Interval::SemiNormalAppend( + timeRanges, + Interval(indice.start_composition, indice.end_composition)); } + Interval::Normalize(timeRanges, &mTimeRanges); } Tkhd::Tkhd(Box& aBox) diff --git a/media/libstagefright/binding/include/mp4_demuxer/Box.h b/media/libstagefright/binding/include/mp4_demuxer/Box.h index c5dbf600bd0d..d0cb81ae5f48 100644 --- a/media/libstagefright/binding/include/mp4_demuxer/Box.h +++ b/media/libstagefright/binding/include/mp4_demuxer/Box.h @@ -39,6 +39,9 @@ public: bool IsAvailable() const { return !mRange.IsNull(); } uint64_t Offset() const { return mRange.mStart; } uint64_t Length() const { return mRange.mEnd - mRange.mStart; } + uint64_t NextOffset() const { return mRange.mEnd; } + const MediaByteRange& Range() const { return mRange; } + const Box* Parent() const { return mParent; } bool IsType(const char* aType) const diff --git a/media/libstagefright/binding/include/mp4_demuxer/Index.h b/media/libstagefright/binding/include/mp4_demuxer/Index.h index 81bb23824ade..618a905d4c75 100644 --- a/media/libstagefright/binding/include/mp4_demuxer/Index.h +++ b/media/libstagefright/binding/include/mp4_demuxer/Index.h @@ -20,6 +20,8 @@ class Index public: Index(const stagefright::Vector& aIndex, Stream* aSource, uint32_t aTrackId); + ~Index(); + void ConvertByteRangesToTimeRanges( const nsTArray& aByteRanges, nsTArray>* aTimeRanges); diff --git a/media/libstagefright/binding/include/mp4_demuxer/Interval.h b/media/libstagefright/binding/include/mp4_demuxer/Interval.h index 2e16c675b66a..61268acdb8a4 100644 --- a/media/libstagefright/binding/include/mp4_demuxer/Interval.h +++ b/media/libstagefright/binding/include/mp4_demuxer/Interval.h @@ -41,6 +41,17 @@ struct Interval T start; T end; + static void SemiNormalAppend(nsTArray>& aIntervals, + Interval aInterval) + { + if (!aIntervals.IsEmpty() && + aIntervals.LastElement().end == aInterval.start) { + aIntervals.LastElement().end = aInterval.end; + } else { + aIntervals.AppendElement(aInterval); + } + } + static void Normalize(const nsTArray>& aIntervals, nsTArray>* aNormalized) { diff --git a/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h b/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h index 25d5074cf7c5..2f0cbdef7476 100644 --- a/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h +++ b/media/libstagefright/binding/include/mp4_demuxer/MoofParser.h @@ -7,13 +7,13 @@ #include "media/stagefright/MediaSource.h" #include "mp4_demuxer/mp4_demuxer.h" - -namespace mozilla { class MediaByteRange; } +#include "MediaResource.h" namespace mp4_demuxer { class Stream; class Box; +class Moof; class Tkhd { @@ -54,9 +54,9 @@ public: class Trex { public: - Trex() + Trex(uint32_t aTrackId) : mFlags(0) - , mTrackId(0) + , mTrackId(aTrackId) , mDefaultSampleDescriptionIndex(0) , mDefaultSampleDuration(0) , mDefaultSampleSize(0) @@ -92,11 +92,24 @@ public: uint64_t mBaseMediaDecodeTime; }; +class Moof +{ +public: + Moof(Box& aBox, Trex& aTrex, Mdhd& aMdhd); + void ParseTraf(Box& aBox, Trex& aTrex, Mdhd& aMdhd); + void ParseTrun(Box& aBox, Tfhd& aTfhd, Tfdt& aTfdt, Mdhd& aMdhd); + + mozilla::MediaByteRange mRange; + mozilla::MediaByteRange mMdatRange; + nsTArray> mTimeRanges; + nsTArray mIndex; +}; + class MoofParser { public: MoofParser(Stream* aSource, uint32_t aTrackId) - : mSource(aSource), mTrackId(aTrackId) + : mSource(aSource), mOffset(0), mTrex(aTrackId) { } void RebuildFragmentedIndex( @@ -107,12 +120,12 @@ public: void ParseMvex(Box& aBox); nsRefPtr mSource; - uint32_t mTrackId; + uint64_t mOffset; nsTArray mMoofOffsets; Mdhd mMdhd; Trex mTrex; Tfdt mTfdt; - nsTArray mIndex; + nsTArray mMoofs; }; } diff --git a/media/libstagefright/binding/mp4_demuxer.cpp b/media/libstagefright/binding/mp4_demuxer.cpp index f4d9242bb129..5daf7dd75bf9 100644 --- a/media/libstagefright/binding/mp4_demuxer.cpp +++ b/media/libstagefright/binding/mp4_demuxer.cpp @@ -24,11 +24,11 @@ struct StageFrightPrivate sp mAudio; MediaSource::ReadOptions mAudioOptions; - nsAutoPtr mAudioIndex; sp mVideo; MediaSource::ReadOptions mVideoOptions; - nsAutoPtr mVideoIndex; + + nsTArray> mIndexes; }; class DataSourceAdapter : public DataSource @@ -101,14 +101,14 @@ MP4Demuxer::Init() mPrivate->mAudio = e->getTrack(i); mPrivate->mAudio->start(); mAudioConfig.Update(metaData, mimeType); - auto index = mPrivate->mAudio->exportIndex(); - mPrivate->mAudioIndex = new Index(index, mSource, mAudioConfig.mTrackId); + mPrivate->mIndexes.AppendElement(new Index( + mPrivate->mAudio->exportIndex(), mSource, mAudioConfig.mTrackId)); } else if (!mPrivate->mVideo.get() && !strncmp(mimeType, "video/", 6)) { mPrivate->mVideo = e->getTrack(i); mPrivate->mVideo->start(); mVideoConfig.Update(metaData, mimeType); - auto index = mPrivate->mVideo->exportIndex(); - mPrivate->mVideoIndex = new Index(index, mSource, mVideoConfig.mTrackId); + mPrivate->mIndexes.AppendElement(new Index( + mPrivate->mVideo->exportIndex(), mSource, mVideoConfig.mTrackId)); } } sp metaData = e->getMetaData(); @@ -199,33 +199,20 @@ MP4Demuxer::ConvertByteRangesToTime( const nsTArray& aByteRanges, nsTArray>* aIntervals) { - if (!HasValidVideo() && !HasValidAudio()) { + if (mPrivate->mIndexes.IsEmpty()) { return; } - nsTArray> video; - if (HasValidVideo()) { - nsTArray> ranges; - if (!HasValidAudio()) { - mPrivate->mVideoIndex->ConvertByteRangesToTimeRanges(aByteRanges, - aIntervals); - return; - } - mPrivate->mVideoIndex->ConvertByteRangesToTimeRanges(aByteRanges, &video); - } + mPrivate->mIndexes[0]->ConvertByteRangesToTimeRanges(aByteRanges, aIntervals); - nsTArray> audio; - if (HasValidAudio()) { + for (int i = 1; i < mPrivate->mIndexes.Length(); i++) { nsTArray> ranges; - if (!HasValidVideo()) { - mPrivate->mAudioIndex->ConvertByteRangesToTimeRanges(aByteRanges, - aIntervals); - return; - } - mPrivate->mAudioIndex->ConvertByteRangesToTimeRanges(aByteRanges, &audio); - } + mPrivate->mIndexes[i]->ConvertByteRangesToTimeRanges(aByteRanges, &ranges); - Interval::Intersection(audio, video, aIntervals); + nsTArray> intersection; + Interval::Intersection(*aIntervals, ranges, &intersection); + *aIntervals = intersection; + } } } // namespace mp4_demuxer diff --git a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp index 33a0db99deb8..93ac8e5cfe20 100644 --- a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp @@ -314,6 +314,7 @@ static const char *FourCC2MIME(uint32_t fourcc) { return MEDIA_MIMETYPE_VIDEO_H263; case FOURCC('a', 'v', 'c', '1'): + case FOURCC('a', 'v', 'c', '3'): return MEDIA_MIMETYPE_VIDEO_AVC; default: @@ -1297,6 +1298,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { case FOURCC('H', '2', '6', '3'): case FOURCC('h', '2', '6', '3'): case FOURCC('a', 'v', 'c', '1'): + case FOURCC('a', 'v', 'c', '3'): { mHasVideo = true; diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index e50e60b30cb5..fd45f7e94c52 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -403,15 +403,54 @@ pref("media.audio_data.enabled", false); // Whether to use async panning and zooming pref("layers.async-pan-zoom.enabled", false); +// APZ preferences. For documentation/details on what these prefs do, check +// gfx/layers/apz/src/AsyncPanZoomController.cpp. +pref("apz.allow_checkerboarding", true); +pref("apz.asyncscroll.throttle", 100); +pref("apz.asyncscroll.timeout", 300); + // Whether to lock touch scrolling to one axis at a time // 0 = FREE (No locking at all) // 1 = STANDARD (Once locked, remain locked until scrolling ends) // 2 = STICKY (Allow lock to be broken, with hysteresis) pref("apz.axis_lock_mode", 0); +pref("apz.content_response_timeout", 300); +pref("apz.cross_slide.enabled", false); +pref("apz.danger_zone_x", 50); +pref("apz.danger_zone_y", 100); +pref("apz.enlarge_displayport_when_clipped", false); +pref("apz.fling_accel_base_mult", "1.0"); +pref("apz.fling_accel_interval_ms", 500); +pref("apz.fling_accel_supplemental_mult", "1.0"); +pref("apz.fling_friction", "0.002"); +pref("apz.fling_stop_on_tap_threshold", "0.05"); +pref("apz.fling_stopped_threshold", "0.01"); +pref("apz.max_velocity_inches_per_ms", "-1.0"); +pref("apz.max_velocity_queue_size", 5); +pref("apz.min_skate_speed", "1.0"); +pref("apz.num_paint_duration_samples", 3); +pref("apz.overscroll.enabled", false); +pref("apz.overscroll.fling_friction", "0.02"); +pref("apz.overscroll.fling_stopped_threshold", "0.4"); +pref("apz.overscroll.clamping", "0.5"); +pref("apz.overscroll.z_effect", "0.2"); +pref("apz.overscroll.snap_back.spring_stiffness", "0.6"); +pref("apz.overscroll.snap_back.spring_friction", "0.1"); +pref("apz.overscroll.snap_back.mass", "1000.0"); + // Whether to print the APZC tree for debugging pref("apz.printtree", false); +pref("apz.test.logging_enabled", false); +pref("apz.touch_start_tolerance", "0.2222222"); // 0.2222222 came from 1.0/4.5 +pref("apz.use_paint_duration", true); +pref("apz.velocity_bias", "1.0"); +pref("apz.velocity_relevance_time_ms", 150); +pref("apz.x_stationary_size_multiplier", "3.0"); +pref("apz.y_stationary_size_multiplier", "3.5"); +pref("apz.zoom_animation_duration_ms", 250); + #ifdef XP_MACOSX // Layerize scrollable subframes to allow async panning pref("apz.subframe.enabled", true); @@ -421,6 +460,10 @@ pref("apz.apz.x_skate_size_multiplier", "2.5"); pref("apz.apz.y_skate_size_multiplier", "3.5"); #else pref("apz.subframe.enabled", false); +pref("apz.fling_repaint_interval", 75); +pref("apz.pan_repaint_interval", 250); +pref("apz.x_skate_size_multiplier", "1.5"); +pref("apz.y_skate_size_multiplier", "2.5"); #endif // APZ testing (bug 961289) diff --git a/netwerk/base/src/nsChannelClassifier.cpp b/netwerk/base/src/nsChannelClassifier.cpp index 4a3babf8d783..e0dfd4319804 100644 --- a/netwerk/base/src/nsChannelClassifier.cpp +++ b/netwerk/base/src/nsChannelClassifier.cpp @@ -9,12 +9,18 @@ #include "nsICacheEntryDescriptor.h" #include "nsICachingChannel.h" #include "nsIChannel.h" +#include "nsIDocShell.h" +#include "nsIDocument.h" #include "nsIDOMDocument.h" #include "nsIDOMWindow.h" #include "nsIIOService.h" #include "nsIPermissionManager.h" #include "nsIProtocolHandler.h" #include "nsIScriptSecurityManager.h" +#include "nsISecureBrowserUI.h" +#include "nsISecurityEventSink.h" +#include "nsIWebProgressListener.h" +#include "nsPIDOMWindow.h" #include "mozilla/Preferences.h" @@ -43,12 +49,16 @@ nsChannelClassifier::nsChannelClassifier() } nsresult -nsChannelClassifier::ShouldEnableTrackingProtection(nsIChannel* aChannel, +nsChannelClassifier::ShouldEnableTrackingProtection(nsIChannel *aChannel, bool *result) { NS_ENSURE_ARG(result); *result = false; + if (!Preferences::GetBool("privacy.trackingprotection.enabled", false)) { + return NS_OK; + } + nsresult rv; nsCOMPtr thirdPartyUtil = do_GetService(THIRDPARTYUTIL_CONTRACTID, &rv); @@ -113,6 +123,40 @@ nsChannelClassifier::ShouldEnableTrackingProtection(nsIChannel* aChannel, #endif *result = permissions != nsIPermissionManager::ALLOW_ACTION; + + // Tracking protection will be enabled so return without updating + // the security state. If any channels are subsequently cancelled + // (page elements blocked) the state will be then updated. + if (*result) { + return NS_OK; + } + + // Tracking protection will be disabled so update the security state + // of the document and fire a secure change event. + nsCOMPtr pwin = do_QueryInterface(win, &rv); + NS_ENSURE_SUCCESS(rv, NS_OK); + nsCOMPtr docShell = pwin->GetDocShell(); + if (!docShell) { + return NS_OK; + } + nsCOMPtr doc = do_GetInterface(docShell, &rv); + NS_ENSURE_SUCCESS(rv, NS_OK); + + // Notify nsIWebProgressListeners of this security event. + // Can be used to change the UI state. + nsCOMPtr eventSink = do_QueryInterface(docShell, &rv); + NS_ENSURE_SUCCESS(rv, NS_OK); + uint32_t state = 0; + nsCOMPtr securityUI; + docShell->GetSecurityUI(getter_AddRefs(securityUI)); + if (!securityUI) { + return NS_OK; + } + doc->SetHasTrackingContentLoaded(true); + securityUI->GetState(&state); + state |= nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT; + eventSink->OnSecurityChange(nullptr, state); + return NS_OK; } @@ -274,6 +318,44 @@ nsChannelClassifier::HasBeenClassified(nsIChannel *aChannel) return tag.EqualsLiteral("1"); } +nsresult +nsChannelClassifier::SetBlockedTrackingContent(nsIChannel *channel) +{ + nsresult rv; + nsCOMPtr win; + nsCOMPtr thirdPartyUtil = + do_GetService(THIRDPARTYUTIL_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, NS_OK); + rv = thirdPartyUtil->GetTopWindowForChannel( + mSuspendedChannel, getter_AddRefs(win)); + NS_ENSURE_SUCCESS(rv, NS_OK); + nsCOMPtr pwin = do_QueryInterface(win, &rv); + NS_ENSURE_SUCCESS(rv, NS_OK); + nsCOMPtr docShell = pwin->GetDocShell(); + if (!docShell) { + return NS_OK; + } + nsCOMPtr doc = do_GetInterface(docShell, &rv); + NS_ENSURE_SUCCESS(rv, NS_OK); + + // Notify nsIWebProgressListeners of this security event. + // Can be used to change the UI state. + nsCOMPtr eventSink = do_QueryInterface(docShell, &rv); + NS_ENSURE_SUCCESS(rv, NS_OK); + uint32_t state = 0; + nsCOMPtr securityUI; + docShell->GetSecurityUI(getter_AddRefs(securityUI)); + if (!securityUI) { + return NS_OK; + } + doc->SetHasTrackingContentBlocked(true); + securityUI->GetState(&state); + state |= nsIWebProgressListener::STATE_BLOCKED_TRACKING_CONTENT; + eventSink->OnSecurityChange(nullptr, state); + + return NS_OK; +} + NS_IMETHODIMP nsChannelClassifier::OnClassifyComplete(nsresult aErrorCode) { @@ -290,8 +372,16 @@ nsChannelClassifier::OnClassifyComplete(nsresult aErrorCode) "with error code: %x", this, mSuspendedChannel.get(), spec.get(), aErrorCode)); #endif + + // Channel will be cancelled (page element blocked) due to tracking. + // Do update the security state of the document and fire a security + // change event. + if (aErrorCode == NS_ERROR_TRACKING_URI) { + SetBlockedTrackingContent(mSuspendedChannel); + } + mSuspendedChannel->Cancel(aErrorCode); - } + } #ifdef DEBUG LOG(("nsChannelClassifier[%p]: resuming channel %p from " "OnClassifyComplete", this, mSuspendedChannel.get())); diff --git a/netwerk/base/src/nsChannelClassifier.h b/netwerk/base/src/nsChannelClassifier.h index 8ae252673975..02766b3a9cf9 100644 --- a/netwerk/base/src/nsChannelClassifier.h +++ b/netwerk/base/src/nsChannelClassifier.h @@ -30,6 +30,9 @@ private: bool HasBeenClassified(nsIChannel *aChannel); // Whether or not tracking protection should be enabled on this channel. nsresult ShouldEnableTrackingProtection(nsIChannel *aChannel, bool *result); + // If we are blocking tracking content, update the corresponding flag in + // the respective docshell and call nsISecurityEventSink::onSecurityChange. + nsresult SetBlockedTrackingContent(nsIChannel *channel); }; #endif diff --git a/netwerk/protocol/http/Http2Compression.cpp b/netwerk/protocol/http/Http2Compression.cpp index b3ea1c0dae7e..d768a280544a 100644 --- a/netwerk/protocol/http/Http2Compression.cpp +++ b/netwerk/protocol/http/Http2Compression.cpp @@ -1194,7 +1194,7 @@ void Http2Compressor::EncodeTableSizeChange(uint32_t newMaxSize) { uint32_t offset = mOutput->Length(); - EncodeInteger(4, newMaxSize); + EncodeInteger(5, newMaxSize); uint8_t *startByte = reinterpret_cast(mOutput->BeginWriting()) + offset; *startByte = *startByte | 0x20; } diff --git a/python/mozbuild/mozbuild/test/test_containers.py b/python/mozbuild/mozbuild/test/test_containers.py index 7e29d1c3afee..414f3eb51f1e 100644 --- a/python/mozbuild/mozbuild/test/test_containers.py +++ b/python/mozbuild/mozbuild/test/test_containers.py @@ -57,15 +57,36 @@ class TestList(unittest.TestCase): test = List([1, 2, 3]) test += [4, 5, 6] - + self.assertIsInstance(test, List) self.assertEqual(test, [1, 2, 3, 4, 5, 6]) + test = test + [7, 8] + self.assertIsInstance(test, List) + self.assertEqual(test, [1, 2, 3, 4, 5, 6, 7, 8]) + def test_add_string(self): test = List([1, 2, 3]) with self.assertRaises(ValueError): test += 'string' + def test_none(self): + """As a special exception, we allow None to be treated as an empty + list.""" + test = List([1, 2, 3]) + + test += None + self.assertEqual(test, [1, 2, 3]) + + test = test + None + self.assertIsInstance(test, List) + self.assertEqual(test, [1, 2, 3]) + + with self.assertRaises(ValueError): + test += False + + with self.assertRaises(ValueError): + test = test + False if __name__ == '__main__': main() diff --git a/python/mozbuild/mozbuild/util.py b/python/mozbuild/mozbuild/util.py index 65d4e782cf4c..f976ee55a60d 100644 --- a/python/mozbuild/mozbuild/util.py +++ b/python/mozbuild/mozbuild/util.py @@ -249,12 +249,16 @@ class List(list): return list.__setslice__(self, i, j, sequence) def __add__(self, other): + # Allow None is a special case because it makes undefined variable + # references in moz.build behave better. + other = [] if other is None else other if not isinstance(other, list): raise ValueError('Only lists can be appended to lists.') - return list.__add__(self, other) + return List(list.__add__(self, other)) def __iadd__(self, other): + other = [] if other is None else other if not isinstance(other, list): raise ValueError('Only lists can be appended to lists.') diff --git a/security/sandbox/linux/Sandbox.cpp b/security/sandbox/linux/Sandbox.cpp index 095d6a150efc..fb201cfd3bc0 100644 --- a/security/sandbox/linux/Sandbox.cpp +++ b/security/sandbox/linux/Sandbox.cpp @@ -58,6 +58,40 @@ static int gMediaPluginFileDesc = -1; static const char *gMediaPluginFilePath; #endif +struct SandboxFlags { + bool isSupported; +#ifdef MOZ_CONTENT_SANDBOX + bool isDisabledForContent; +#endif +#ifdef MOZ_GMP_SANDBOX + bool isDisabledForGMP; +#endif + + SandboxFlags() { + // Allow simulating the absence of seccomp-bpf support, for testing. + if (getenv("MOZ_FAKE_NO_SANDBOX")) { + isSupported = false; + } else { + // Determine whether seccomp-bpf is supported by trying to + // enable it with an invalid pointer for the filter. This will + // fail with EFAULT if supported and EINVAL if not, without + // changing the process's state. + if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, nullptr) != -1) { + MOZ_CRASH("prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, nullptr) didn't fail"); + } + isSupported = errno == EFAULT; + } +#ifdef MOZ_CONTENT_SANDBOX + isDisabledForContent = getenv("MOZ_DISABLE_CONTENT_SANDBOX"); +#endif +#ifdef MOZ_GMP_SANDBOX + isDisabledForGMP = getenv("MOZ_DISABLE_GMP_SANDBOX"); +#endif + } +}; + +static const SandboxFlags gSandboxFlags; + /** * Log JS stack info in the same place as the sandbox violation * message. Useful in case the responsible code is JS and all we have @@ -224,20 +258,23 @@ InstallSyscallReporter(void) * to pass a bpf program (in our case, it contains a syscall * whitelist). * - * @return 0 on success, 1 on failure. + * Reports failure by crashing. + * * @see sock_fprog (the seccomp_prog). */ -static int +static void InstallSyscallFilter(const sock_fprog *prog) { if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { - return 1; + LOG_ERROR("prctl(PR_SET_NO_NEW_PRIVS) failed: %s", strerror(errno)); + MOZ_CRASH("prctl(PR_SET_NO_NEW_PRIVS)"); } if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, (unsigned long)prog, 0, 0)) { - return 1; + LOG_ERROR("prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER) failed: %s", + strerror(errno)); + MOZ_CRASH("prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER)"); } - return 0; } // Use signals for permissions that need to be set per-thread. @@ -268,22 +305,16 @@ FindFreeSignalNumber() return 0; } +// Returns true if sandboxing was enabled, or false if sandboxing +// already was enabled. Crashes if sandboxing could not be enabled. static bool SetThreadSandbox() { - bool didAnything = false; - if (prctl(PR_GET_SECCOMP, 0, 0, 0, 0) == 0) { - if (InstallSyscallFilter(sSetSandboxFilter) == 0) { - didAnything = true; - } - /* - * Bug 880797: when all B2G devices are required to support - * seccomp-bpf, this should exit/crash if InstallSyscallFilter - * returns nonzero (ifdef MOZ_WIDGET_GONK). - */ + InstallSyscallFilter(sSetSandboxFilter); + return true; } - return didAnything; + return false; } static void @@ -435,14 +466,6 @@ BroadcastSetThreadSandbox(SandboxType aType) SetThreadSandbox(); } -// This function can overapproximate (i.e., return true even if -// sandboxing isn't supported, but not the reverse). See bug 993145. -static bool -IsSandboxingSupported(void) -{ - return prctl(PR_GET_SECCOMP) != -1; -} - // Common code for sandbox startup. static void SetCurrentProcessSandbox(SandboxType aType) @@ -451,9 +474,7 @@ SetCurrentProcessSandbox(SandboxType aType) LOG_ERROR("install_syscall_reporter() failed\n"); } - if (IsSandboxingSupported()) { - BroadcastSetThreadSandbox(aType); - } + BroadcastSetThreadSandbox(aType); } #ifdef MOZ_CONTENT_SANDBOX @@ -466,12 +487,18 @@ SetCurrentProcessSandbox(SandboxType aType) void SetContentProcessSandbox() { - if (PR_GetEnv("MOZ_DISABLE_CONTENT_SANDBOX")) { + if (gSandboxFlags.isDisabledForContent) { return; } SetCurrentProcessSandbox(kSandboxContentProcess); } + +bool +CanSandboxContentProcess() +{ + return gSandboxFlags.isSupported || gSandboxFlags.isDisabledForContent; +} #endif // MOZ_CONTENT_SANDBOX #ifdef MOZ_GMP_SANDBOX @@ -489,7 +516,7 @@ SetContentProcessSandbox() void SetMediaPluginSandbox(const char *aFilePath) { - if (PR_GetEnv("MOZ_DISABLE_GMP_SANDBOX")) { + if (gSandboxFlags.isDisabledForGMP) { return; } @@ -504,6 +531,12 @@ SetMediaPluginSandbox(const char *aFilePath) // Finally, start the sandbox. SetCurrentProcessSandbox(kSandboxMediaPlugin); } + +bool +CanSandboxMediaPlugin() +{ + return gSandboxFlags.isSupported || gSandboxFlags.isDisabledForGMP; +} #endif // MOZ_GMP_SANDBOX } // namespace mozilla diff --git a/security/sandbox/linux/Sandbox.h b/security/sandbox/linux/Sandbox.h index d8a3891ceb13..1e15fb70317e 100644 --- a/security/sandbox/linux/Sandbox.h +++ b/security/sandbox/linux/Sandbox.h @@ -9,14 +9,25 @@ namespace mozilla { +// The Set*Sandbox() functions must not be called if the corresponding +// CanSandbox*() function has returned false; if sandboxing is +// attempted, any failure to enable it is fatal. +// +// If sandboxing is disabled for a process type with the corresponding +// environment variable, Set*Sandbox() does nothing and CanSandbox*() +// returns true. + #ifdef MOZ_CONTENT_SANDBOX +// Disabled by setting env var MOZ_DISABLE_CONTENT_SANDBOX. +bool CanSandboxContentProcess(); void SetContentProcessSandbox(); #endif #ifdef MOZ_GMP_SANDBOX +// Disabled by setting env var MOZ_DISABLE_GMP_SANDBOX. +bool CanSandboxMediaPlugin(); void SetMediaPluginSandbox(const char *aFilePath); #endif } // namespace mozilla #endif // mozilla_Sandbox_h - diff --git a/testing/mochitest/mochitest_options.py b/testing/mochitest/mochitest_options.py index da1d99f7881c..64922175130e 100644 --- a/testing/mochitest/mochitest_options.py +++ b/testing/mochitest/mochitest_options.py @@ -756,7 +756,7 @@ class B2GOptions(MochitestOptions): defaults["testPath"] = "" defaults["extensionsToExclude"] = ["specialpowers"] # See dependencies of bug 1038943. - defaults["leakThreshold"] = 4727 + defaults["leakThreshold"] = 4964 self.set_defaults(**defaults) def verifyRemoteOptions(self, options): diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index a995758c5ebe..2649a391438f 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -6530,7 +6530,7 @@ "description": "Certificate pinning results by host for Mozilla operational sites" }, "CERT_PINNING_MOZ_TEST_RESULTS_BY_HOST": { - "alert_emails": ["pinning@mozilla.com"], + "alert_emails": ["pinning@mozilla.org"], "expires_in_version": "never", "kind": "enumerated", "n_values": 512, diff --git a/widget/windows/WinUtils.cpp b/widget/windows/WinUtils.cpp index 4d6ac9680d23..92f4006de812 100644 --- a/widget/windows/WinUtils.cpp +++ b/widget/windows/WinUtils.cpp @@ -59,6 +59,345 @@ using namespace mozilla::gfx; namespace mozilla { namespace widget { + +#define ENTRY(_msg) { #_msg, _msg } +EventMsgInfo gAllEvents[] = { + ENTRY(WM_NULL), + ENTRY(WM_CREATE), + ENTRY(WM_DESTROY), + ENTRY(WM_MOVE), + ENTRY(WM_SIZE), + ENTRY(WM_ACTIVATE), + ENTRY(WM_SETFOCUS), + ENTRY(WM_KILLFOCUS), + ENTRY(WM_ENABLE), + ENTRY(WM_SETREDRAW), + ENTRY(WM_SETTEXT), + ENTRY(WM_GETTEXT), + ENTRY(WM_GETTEXTLENGTH), + ENTRY(WM_PAINT), + ENTRY(WM_CLOSE), + ENTRY(WM_QUERYENDSESSION), + ENTRY(WM_QUIT), + ENTRY(WM_QUERYOPEN), + ENTRY(WM_ERASEBKGND), + ENTRY(WM_SYSCOLORCHANGE), + ENTRY(WM_ENDSESSION), + ENTRY(WM_SHOWWINDOW), + ENTRY(WM_SETTINGCHANGE), + ENTRY(WM_DEVMODECHANGE), + ENTRY(WM_ACTIVATEAPP), + ENTRY(WM_FONTCHANGE), + ENTRY(WM_TIMECHANGE), + ENTRY(WM_CANCELMODE), + ENTRY(WM_SETCURSOR), + ENTRY(WM_MOUSEACTIVATE), + ENTRY(WM_CHILDACTIVATE), + ENTRY(WM_QUEUESYNC), + ENTRY(WM_GETMINMAXINFO), + ENTRY(WM_PAINTICON), + ENTRY(WM_ICONERASEBKGND), + ENTRY(WM_NEXTDLGCTL), + ENTRY(WM_SPOOLERSTATUS), + ENTRY(WM_DRAWITEM), + ENTRY(WM_MEASUREITEM), + ENTRY(WM_DELETEITEM), + ENTRY(WM_VKEYTOITEM), + ENTRY(WM_CHARTOITEM), + ENTRY(WM_SETFONT), + ENTRY(WM_GETFONT), + ENTRY(WM_SETHOTKEY), + ENTRY(WM_GETHOTKEY), + ENTRY(WM_QUERYDRAGICON), + ENTRY(WM_COMPAREITEM), + ENTRY(WM_GETOBJECT), + ENTRY(WM_COMPACTING), + ENTRY(WM_COMMNOTIFY), + ENTRY(WM_WINDOWPOSCHANGING), + ENTRY(WM_WINDOWPOSCHANGED), + ENTRY(WM_POWER), + ENTRY(WM_COPYDATA), + ENTRY(WM_CANCELJOURNAL), + ENTRY(WM_NOTIFY), + ENTRY(WM_INPUTLANGCHANGEREQUEST), + ENTRY(WM_INPUTLANGCHANGE), + ENTRY(WM_TCARD), + ENTRY(WM_HELP), + ENTRY(WM_USERCHANGED), + ENTRY(WM_NOTIFYFORMAT), + ENTRY(WM_CONTEXTMENU), + ENTRY(WM_STYLECHANGING), + ENTRY(WM_STYLECHANGED), + ENTRY(WM_DISPLAYCHANGE), + ENTRY(WM_GETICON), + ENTRY(WM_SETICON), + ENTRY(WM_NCCREATE), + ENTRY(WM_NCDESTROY), + ENTRY(WM_NCCALCSIZE), + ENTRY(WM_NCHITTEST), + ENTRY(WM_NCPAINT), + ENTRY(WM_NCACTIVATE), + ENTRY(WM_GETDLGCODE), + ENTRY(WM_SYNCPAINT), + ENTRY(WM_NCMOUSEMOVE), + ENTRY(WM_NCLBUTTONDOWN), + ENTRY(WM_NCLBUTTONUP), + ENTRY(WM_NCLBUTTONDBLCLK), + ENTRY(WM_NCRBUTTONDOWN), + ENTRY(WM_NCRBUTTONUP), + ENTRY(WM_NCRBUTTONDBLCLK), + ENTRY(WM_NCMBUTTONDOWN), + ENTRY(WM_NCMBUTTONUP), + ENTRY(WM_NCMBUTTONDBLCLK), + ENTRY(EM_GETSEL), + ENTRY(EM_SETSEL), + ENTRY(EM_GETRECT), + ENTRY(EM_SETRECT), + ENTRY(EM_SETRECTNP), + ENTRY(EM_SCROLL), + ENTRY(EM_LINESCROLL), + ENTRY(EM_SCROLLCARET), + ENTRY(EM_GETMODIFY), + ENTRY(EM_SETMODIFY), + ENTRY(EM_GETLINECOUNT), + ENTRY(EM_LINEINDEX), + ENTRY(EM_SETHANDLE), + ENTRY(EM_GETHANDLE), + ENTRY(EM_GETTHUMB), + ENTRY(EM_LINELENGTH), + ENTRY(EM_REPLACESEL), + ENTRY(EM_GETLINE), + ENTRY(EM_LIMITTEXT), + ENTRY(EM_CANUNDO), + ENTRY(EM_UNDO), + ENTRY(EM_FMTLINES), + ENTRY(EM_LINEFROMCHAR), + ENTRY(EM_SETTABSTOPS), + ENTRY(EM_SETPASSWORDCHAR), + ENTRY(EM_EMPTYUNDOBUFFER), + ENTRY(EM_GETFIRSTVISIBLELINE), + ENTRY(EM_SETREADONLY), + ENTRY(EM_SETWORDBREAKPROC), + ENTRY(EM_GETWORDBREAKPROC), + ENTRY(EM_GETPASSWORDCHAR), + ENTRY(EM_SETMARGINS), + ENTRY(EM_GETMARGINS), + ENTRY(EM_GETLIMITTEXT), + ENTRY(EM_POSFROMCHAR), + ENTRY(EM_CHARFROMPOS), + ENTRY(EM_SETIMESTATUS), + ENTRY(EM_GETIMESTATUS), + ENTRY(SBM_SETPOS), + ENTRY(SBM_GETPOS), + ENTRY(SBM_SETRANGE), + ENTRY(SBM_SETRANGEREDRAW), + ENTRY(SBM_GETRANGE), + ENTRY(SBM_ENABLE_ARROWS), + ENTRY(SBM_SETSCROLLINFO), + ENTRY(SBM_GETSCROLLINFO), + ENTRY(WM_KEYDOWN), + ENTRY(WM_KEYUP), + ENTRY(WM_CHAR), + ENTRY(WM_DEADCHAR), + ENTRY(WM_SYSKEYDOWN), + ENTRY(WM_SYSKEYUP), + ENTRY(WM_SYSCHAR), + ENTRY(WM_SYSDEADCHAR), + ENTRY(WM_KEYLAST), + ENTRY(WM_IME_STARTCOMPOSITION), + ENTRY(WM_IME_ENDCOMPOSITION), + ENTRY(WM_IME_COMPOSITION), + ENTRY(WM_INITDIALOG), + ENTRY(WM_COMMAND), + ENTRY(WM_SYSCOMMAND), + ENTRY(WM_TIMER), + ENTRY(WM_HSCROLL), + ENTRY(WM_VSCROLL), + ENTRY(WM_INITMENU), + ENTRY(WM_INITMENUPOPUP), + ENTRY(WM_MENUSELECT), + ENTRY(WM_MENUCHAR), + ENTRY(WM_ENTERIDLE), + ENTRY(WM_MENURBUTTONUP), + ENTRY(WM_MENUDRAG), + ENTRY(WM_MENUGETOBJECT), + ENTRY(WM_UNINITMENUPOPUP), + ENTRY(WM_MENUCOMMAND), + ENTRY(WM_CHANGEUISTATE), + ENTRY(WM_UPDATEUISTATE), + ENTRY(WM_CTLCOLORMSGBOX), + ENTRY(WM_CTLCOLOREDIT), + ENTRY(WM_CTLCOLORLISTBOX), + ENTRY(WM_CTLCOLORBTN), + ENTRY(WM_CTLCOLORDLG), + ENTRY(WM_CTLCOLORSCROLLBAR), + ENTRY(WM_CTLCOLORSTATIC), + ENTRY(CB_GETEDITSEL), + ENTRY(CB_LIMITTEXT), + ENTRY(CB_SETEDITSEL), + ENTRY(CB_ADDSTRING), + ENTRY(CB_DELETESTRING), + ENTRY(CB_DIR), + ENTRY(CB_GETCOUNT), + ENTRY(CB_GETCURSEL), + ENTRY(CB_GETLBTEXT), + ENTRY(CB_GETLBTEXTLEN), + ENTRY(CB_INSERTSTRING), + ENTRY(CB_RESETCONTENT), + ENTRY(CB_FINDSTRING), + ENTRY(CB_SELECTSTRING), + ENTRY(CB_SETCURSEL), + ENTRY(CB_SHOWDROPDOWN), + ENTRY(CB_GETITEMDATA), + ENTRY(CB_SETITEMDATA), + ENTRY(CB_GETDROPPEDCONTROLRECT), + ENTRY(CB_SETITEMHEIGHT), + ENTRY(CB_GETITEMHEIGHT), + ENTRY(CB_SETEXTENDEDUI), + ENTRY(CB_GETEXTENDEDUI), + ENTRY(CB_GETDROPPEDSTATE), + ENTRY(CB_FINDSTRINGEXACT), + ENTRY(CB_SETLOCALE), + ENTRY(CB_GETLOCALE), + ENTRY(CB_GETTOPINDEX), + ENTRY(CB_SETTOPINDEX), + ENTRY(CB_GETHORIZONTALEXTENT), + ENTRY(CB_SETHORIZONTALEXTENT), + ENTRY(CB_GETDROPPEDWIDTH), + ENTRY(CB_SETDROPPEDWIDTH), + ENTRY(CB_INITSTORAGE), + ENTRY(CB_MSGMAX), + ENTRY(LB_ADDSTRING), + ENTRY(LB_INSERTSTRING), + ENTRY(LB_DELETESTRING), + ENTRY(LB_SELITEMRANGEEX), + ENTRY(LB_RESETCONTENT), + ENTRY(LB_SETSEL), + ENTRY(LB_SETCURSEL), + ENTRY(LB_GETSEL), + ENTRY(LB_GETCURSEL), + ENTRY(LB_GETTEXT), + ENTRY(LB_GETTEXTLEN), + ENTRY(LB_GETCOUNT), + ENTRY(LB_SELECTSTRING), + ENTRY(LB_DIR), + ENTRY(LB_GETTOPINDEX), + ENTRY(LB_FINDSTRING), + ENTRY(LB_GETSELCOUNT), + ENTRY(LB_GETSELITEMS), + ENTRY(LB_SETTABSTOPS), + ENTRY(LB_GETHORIZONTALEXTENT), + ENTRY(LB_SETHORIZONTALEXTENT), + ENTRY(LB_SETCOLUMNWIDTH), + ENTRY(LB_ADDFILE), + ENTRY(LB_SETTOPINDEX), + ENTRY(LB_GETITEMRECT), + ENTRY(LB_GETITEMDATA), + ENTRY(LB_SETITEMDATA), + ENTRY(LB_SELITEMRANGE), + ENTRY(LB_SETANCHORINDEX), + ENTRY(LB_GETANCHORINDEX), + ENTRY(LB_SETCARETINDEX), + ENTRY(LB_GETCARETINDEX), + ENTRY(LB_SETITEMHEIGHT), + ENTRY(LB_GETITEMHEIGHT), + ENTRY(LB_FINDSTRINGEXACT), + ENTRY(LB_SETLOCALE), + ENTRY(LB_GETLOCALE), + ENTRY(LB_SETCOUNT), + ENTRY(LB_INITSTORAGE), + ENTRY(LB_ITEMFROMPOINT), + ENTRY(LB_MSGMAX), + ENTRY(WM_MOUSEMOVE), + ENTRY(WM_LBUTTONDOWN), + ENTRY(WM_LBUTTONUP), + ENTRY(WM_LBUTTONDBLCLK), + ENTRY(WM_RBUTTONDOWN), + ENTRY(WM_RBUTTONUP), + ENTRY(WM_RBUTTONDBLCLK), + ENTRY(WM_MBUTTONDOWN), + ENTRY(WM_MBUTTONUP), + ENTRY(WM_MBUTTONDBLCLK), + ENTRY(WM_MOUSEWHEEL), + ENTRY(WM_MOUSEHWHEEL), + ENTRY(WM_PARENTNOTIFY), + ENTRY(WM_ENTERMENULOOP), + ENTRY(WM_EXITMENULOOP), + ENTRY(WM_NEXTMENU), + ENTRY(WM_SIZING), + ENTRY(WM_CAPTURECHANGED), + ENTRY(WM_MOVING), + ENTRY(WM_POWERBROADCAST), + ENTRY(WM_DEVICECHANGE), + ENTRY(WM_MDICREATE), + ENTRY(WM_MDIDESTROY), + ENTRY(WM_MDIACTIVATE), + ENTRY(WM_MDIRESTORE), + ENTRY(WM_MDINEXT), + ENTRY(WM_MDIMAXIMIZE), + ENTRY(WM_MDITILE), + ENTRY(WM_MDICASCADE), + ENTRY(WM_MDIICONARRANGE), + ENTRY(WM_MDIGETACTIVE), + ENTRY(WM_MDISETMENU), + ENTRY(WM_ENTERSIZEMOVE), + ENTRY(WM_EXITSIZEMOVE), + ENTRY(WM_DROPFILES), + ENTRY(WM_MDIREFRESHMENU), + ENTRY(WM_IME_SETCONTEXT), + ENTRY(WM_IME_NOTIFY), + ENTRY(WM_IME_CONTROL), + ENTRY(WM_IME_COMPOSITIONFULL), + ENTRY(WM_IME_SELECT), + ENTRY(WM_IME_CHAR), + ENTRY(WM_IME_REQUEST), + ENTRY(WM_IME_KEYDOWN), + ENTRY(WM_IME_KEYUP), + ENTRY(WM_NCMOUSEHOVER), + ENTRY(WM_MOUSEHOVER), + ENTRY(WM_MOUSELEAVE), + ENTRY(WM_CUT), + ENTRY(WM_COPY), + ENTRY(WM_PASTE), + ENTRY(WM_CLEAR), + ENTRY(WM_UNDO), + ENTRY(WM_RENDERFORMAT), + ENTRY(WM_RENDERALLFORMATS), + ENTRY(WM_DESTROYCLIPBOARD), + ENTRY(WM_DRAWCLIPBOARD), + ENTRY(WM_PAINTCLIPBOARD), + ENTRY(WM_VSCROLLCLIPBOARD), + ENTRY(WM_SIZECLIPBOARD), + ENTRY(WM_ASKCBFORMATNAME), + ENTRY(WM_CHANGECBCHAIN), + ENTRY(WM_HSCROLLCLIPBOARD), + ENTRY(WM_QUERYNEWPALETTE), + ENTRY(WM_PALETTEISCHANGING), + ENTRY(WM_PALETTECHANGED), + ENTRY(WM_HOTKEY), + ENTRY(WM_PRINT), + ENTRY(WM_PRINTCLIENT), + ENTRY(WM_THEMECHANGED), + ENTRY(WM_HANDHELDFIRST), + ENTRY(WM_HANDHELDLAST), + ENTRY(WM_AFXFIRST), + ENTRY(WM_AFXLAST), + ENTRY(WM_PENWINFIRST), + ENTRY(WM_PENWINLAST), + ENTRY(WM_APP), + ENTRY(WM_DWMCOMPOSITIONCHANGED), + ENTRY(WM_DWMNCRENDERINGCHANGED), + ENTRY(WM_DWMCOLORIZATIONCOLORCHANGED), + ENTRY(WM_DWMWINDOWMAXIMIZEDCHANGE), + ENTRY(WM_DWMSENDICONICTHUMBNAIL), + ENTRY(WM_DWMSENDICONICLIVEPREVIEWBITMAP), + ENTRY(WM_TABLET_QUERYSYSTEMGESTURESTATUS), + ENTRY(WM_GESTURE), + ENTRY(WM_GESTURENOTIFY), + ENTRY(WM_GETTITLEBARINFOEX), + {nullptr, 0x0} +}; +#undef ENTRY #ifdef MOZ_PLACES NS_IMPL_ISUPPORTS(myDownloadObserver, nsIDownloadObserver) diff --git a/widget/windows/WinUtils.h b/widget/windows/WinUtils.h index e00e44cd2593..2dedd9b525e0 100644 --- a/widget/windows/WinUtils.h +++ b/widget/windows/WinUtils.h @@ -72,6 +72,13 @@ struct nsIntRect; namespace mozilla { namespace widget { +// Windows message debugging data +typedef struct { + const char * mStr; + UINT mId; +} EventMsgInfo; +extern EventMsgInfo gAllEvents[]; + // More complete QS definitions for MsgWaitForMultipleObjects() and // GetQueueStatus() that include newer win8 specific defines. diff --git a/widget/windows/nsTextStore.cpp b/widget/windows/nsTextStore.cpp index 1e8bc4c86e0d..0180aaf36837 100644 --- a/widget/windows/nsTextStore.cpp +++ b/widget/windows/nsTextStore.cpp @@ -23,6 +23,7 @@ #include "mozilla/WindowsVersion.h" #define INPUTSCOPE_INIT_GUID +#define TEXTATTRS_INIT_GUID #include "nsTextStore.h" using namespace mozilla; @@ -257,6 +258,105 @@ GetGUIDNameStr(REFGUID aGUID) return NS_ConvertUTF16toUTF8(str); } +static nsCString +GetGUIDNameStrWithTable(REFGUID aGUID) +{ +#define RETURN_GUID_NAME(aNamedGUID) \ + if (IsEqualGUID(aGUID, aNamedGUID)) { \ + return NS_LITERAL_CSTRING(#aNamedGUID); \ + } + + RETURN_GUID_NAME(GUID_PROP_INPUTSCOPE) + RETURN_GUID_NAME(TSATTRID_OTHERS) + RETURN_GUID_NAME(TSATTRID_Font) + RETURN_GUID_NAME(TSATTRID_Font_FaceName) + RETURN_GUID_NAME(TSATTRID_Font_SizePts) + RETURN_GUID_NAME(TSATTRID_Font_Style) + RETURN_GUID_NAME(TSATTRID_Font_Style_Bold) + RETURN_GUID_NAME(TSATTRID_Font_Style_Italic) + RETURN_GUID_NAME(TSATTRID_Font_Style_SmallCaps) + RETURN_GUID_NAME(TSATTRID_Font_Style_Capitalize) + RETURN_GUID_NAME(TSATTRID_Font_Style_Uppercase) + RETURN_GUID_NAME(TSATTRID_Font_Style_Lowercase) + RETURN_GUID_NAME(TSATTRID_Font_Style_Animation) + RETURN_GUID_NAME(TSATTRID_Font_Style_Animation_LasVegasLights) + RETURN_GUID_NAME(TSATTRID_Font_Style_Animation_BlinkingBackground) + RETURN_GUID_NAME(TSATTRID_Font_Style_Animation_SparkleText) + RETURN_GUID_NAME(TSATTRID_Font_Style_Animation_MarchingBlackAnts) + RETURN_GUID_NAME(TSATTRID_Font_Style_Animation_MarchingRedAnts) + RETURN_GUID_NAME(TSATTRID_Font_Style_Animation_Shimmer) + RETURN_GUID_NAME(TSATTRID_Font_Style_Animation_WipeDown) + RETURN_GUID_NAME(TSATTRID_Font_Style_Animation_WipeRight) + RETURN_GUID_NAME(TSATTRID_Font_Style_Emboss) + RETURN_GUID_NAME(TSATTRID_Font_Style_Engrave) + RETURN_GUID_NAME(TSATTRID_Font_Style_Hidden) + RETURN_GUID_NAME(TSATTRID_Font_Style_Kerning) + RETURN_GUID_NAME(TSATTRID_Font_Style_Outlined) + RETURN_GUID_NAME(TSATTRID_Font_Style_Position) + RETURN_GUID_NAME(TSATTRID_Font_Style_Protected) + RETURN_GUID_NAME(TSATTRID_Font_Style_Shadow) + RETURN_GUID_NAME(TSATTRID_Font_Style_Spacing) + RETURN_GUID_NAME(TSATTRID_Font_Style_Weight) + RETURN_GUID_NAME(TSATTRID_Font_Style_Height) + RETURN_GUID_NAME(TSATTRID_Font_Style_Underline) + RETURN_GUID_NAME(TSATTRID_Font_Style_Underline_Single) + RETURN_GUID_NAME(TSATTRID_Font_Style_Underline_Double) + RETURN_GUID_NAME(TSATTRID_Font_Style_Strikethrough) + RETURN_GUID_NAME(TSATTRID_Font_Style_Strikethrough_Single) + RETURN_GUID_NAME(TSATTRID_Font_Style_Strikethrough_Double) + RETURN_GUID_NAME(TSATTRID_Font_Style_Overline) + RETURN_GUID_NAME(TSATTRID_Font_Style_Overline_Single) + RETURN_GUID_NAME(TSATTRID_Font_Style_Overline_Double) + RETURN_GUID_NAME(TSATTRID_Font_Style_Blink) + RETURN_GUID_NAME(TSATTRID_Font_Style_Subscript) + RETURN_GUID_NAME(TSATTRID_Font_Style_Superscript) + RETURN_GUID_NAME(TSATTRID_Font_Style_Color) + RETURN_GUID_NAME(TSATTRID_Font_Style_BackgroundColor) + RETURN_GUID_NAME(TSATTRID_Text) + RETURN_GUID_NAME(TSATTRID_Text_VerticalWriting) + RETURN_GUID_NAME(TSATTRID_Text_RightToLeft) + RETURN_GUID_NAME(TSATTRID_Text_Orientation) + RETURN_GUID_NAME(TSATTRID_Text_Language) + RETURN_GUID_NAME(TSATTRID_Text_ReadOnly) + RETURN_GUID_NAME(TSATTRID_Text_EmbeddedObject) + RETURN_GUID_NAME(TSATTRID_Text_Alignment) + RETURN_GUID_NAME(TSATTRID_Text_Alignment_Left) + RETURN_GUID_NAME(TSATTRID_Text_Alignment_Right) + RETURN_GUID_NAME(TSATTRID_Text_Alignment_Center) + RETURN_GUID_NAME(TSATTRID_Text_Alignment_Justify) + RETURN_GUID_NAME(TSATTRID_Text_Link) + RETURN_GUID_NAME(TSATTRID_Text_Hyphenation) + RETURN_GUID_NAME(TSATTRID_Text_Para) + RETURN_GUID_NAME(TSATTRID_Text_Para_FirstLineIndent) + RETURN_GUID_NAME(TSATTRID_Text_Para_LeftIndent) + RETURN_GUID_NAME(TSATTRID_Text_Para_RightIndent) + RETURN_GUID_NAME(TSATTRID_Text_Para_SpaceAfter) + RETURN_GUID_NAME(TSATTRID_Text_Para_SpaceBefore) + RETURN_GUID_NAME(TSATTRID_Text_Para_LineSpacing) + RETURN_GUID_NAME(TSATTRID_Text_Para_LineSpacing_Single) + RETURN_GUID_NAME(TSATTRID_Text_Para_LineSpacing_OnePtFive) + RETURN_GUID_NAME(TSATTRID_Text_Para_LineSpacing_Double) + RETURN_GUID_NAME(TSATTRID_Text_Para_LineSpacing_AtLeast) + RETURN_GUID_NAME(TSATTRID_Text_Para_LineSpacing_Exactly) + RETURN_GUID_NAME(TSATTRID_Text_Para_LineSpacing_Multiple) + RETURN_GUID_NAME(TSATTRID_List) + RETURN_GUID_NAME(TSATTRID_List_LevelIndel) + RETURN_GUID_NAME(TSATTRID_List_Type) + RETURN_GUID_NAME(TSATTRID_List_Type_Bullet) + RETURN_GUID_NAME(TSATTRID_List_Type_Arabic) + RETURN_GUID_NAME(TSATTRID_List_Type_LowerLetter) + RETURN_GUID_NAME(TSATTRID_List_Type_UpperLetter) + RETURN_GUID_NAME(TSATTRID_List_Type_LowerRoman) + RETURN_GUID_NAME(TSATTRID_List_Type_UpperRoman) + RETURN_GUID_NAME(TSATTRID_App) + RETURN_GUID_NAME(TSATTRID_App_IncorrectSpelling) + RETURN_GUID_NAME(TSATTRID_App_IncorrectGrammar) + +#undef RETURN_GUID_NAME + + GetGUIDNameStr(aGUID); +} + static nsCString GetRIIDNameStr(REFIID aRIID) { @@ -504,22 +604,25 @@ GetDisplayAttrStr(const TF_DISPLAYATTRIBUTE &aDispAttr) #endif // #ifdef PR_LOGGING nsTextStore::nsTextStore() - : mContent(mComposition, mSelection) + : mContent(mComposition, mSelection) + , mEditCookie(0) + , mIPProfileCookie(TF_INVALID_COOKIE) + , mLangProfileCookie(TF_INVALID_COOKIE) + , mSinkMask(0) + , mLock(0) + , mLockQueued(0) + , mRequestedAttrValues(false) + , mIsRecordingActionsWithoutLock(false) + , mPendingOnSelectionChange(false) + , mPendingOnLayoutChange(false) + , mNativeCaretIsCreated(false) + , mIsIMM_IME(false) + , mOnActivatedCalled(false) { - mEditCookie = 0; - mIPProfileCookie = TF_INVALID_COOKIE; - mLangProfileCookie = TF_INVALID_COOKIE; - mSinkMask = 0; - mLock = 0; - mLockQueued = 0; - mInputScopeDetected = false; - mInputScopeRequested = false; - mIsRecordingActionsWithoutLock = false; - mPendingOnSelectionChange = false; - mPendingOnLayoutChange = false; - mNativeCaretIsCreated = false; - mIsIMM_IME = false; - mOnActivatedCalled = false; + for (int32_t i = 0; i < NUM_OF_SUPPORTED_ATTRS; i++) { + mRequestedAttrs[i] = false; + } + // We hope that 5 or more actions don't occur at once. mPendingActions.SetCapacity(5); @@ -2100,15 +2203,41 @@ nsTextStore::SetInputScope(const nsString& aHTMLInputType) } } +int32_t +nsTextStore::GetRequestedAttrIndex(const TS_ATTRID& aAttrID) +{ + if (IsEqualGUID(aAttrID, GUID_PROP_INPUTSCOPE)) { + return eInputScope; + } + if (IsEqualGUID(aAttrID, TSATTRID_Text_VerticalWriting)) { + return eTextVerticalWriting; + } + return eNotSupported; +} + +TS_ATTRID +nsTextStore::GetAttrID(int32_t aIndex) +{ + switch (aIndex) { + case eInputScope: + return GUID_PROP_INPUTSCOPE; + case eTextVerticalWriting: + return TSATTRID_Text_VerticalWriting; + default: + MOZ_CRASH("Invalid index? Or not implemented yet?"); + return GUID_NULL; + } +} + HRESULT -nsTextStore::ProcessScopeRequest(DWORD dwFlags, - ULONG cFilterAttrs, - const TS_ATTRID *paFilterAttrs) +nsTextStore::HandleRequestAttrs(DWORD aFlags, + ULONG aFilterCount, + const TS_ATTRID* aFilterAttrs) { PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, - ("TSF: 0x%p nsTextStore::ProcessScopeRequest(dwFlags=%s, " - "cFilterAttrs=%ld", - this, GetFindFlagName(dwFlags).get(), cFilterAttrs)); + ("TSF: 0x%p nsTextStore::HandleRequestAttrs(aFlags=%s, " + "aFilterCount=%u)", + this, GetFindFlagName(aFlags).get(), aFilterCount)); // This is a little weird! RequestSupportedAttrs gives us advanced notice // of a support query via RetrieveRequestedAttrs for a specific attribute. @@ -2116,26 +2245,19 @@ nsTextStore::ProcessScopeRequest(DWORD dwFlags, // support, but the text service will only want the input scope object // returned in RetrieveRequestedAttrs if the dwFlags passed in here contains // TS_ATTR_FIND_WANT_VALUE. - mInputScopeDetected = mInputScopeRequested = false; + for (int32_t i = 0; i < NUM_OF_SUPPORTED_ATTRS; i++) { + mRequestedAttrs[i] = false; + } + mRequestedAttrValues = !!(aFlags & TS_ATTR_FIND_WANT_VALUE); - // Currently we only support GUID_PROP_INPUTSCOPE - for (uint32_t idx = 0; idx < cFilterAttrs; ++idx) { + for (uint32_t i = 0; i < aFilterCount; i++) { PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, - ("TSF: 0x%p nsTextStore::ProcessScopeRequest() " + ("TSF: 0x%p nsTextStore::HandleRequestAttrs(), " "requested attr=%s", - this, GetCLSIDNameStr(paFilterAttrs[idx]).get())); - if (IsEqualGUID(paFilterAttrs[idx], GUID_PROP_INPUTSCOPE)) { - PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, - ("TSF: 0x%p nsTextStore::ProcessScopeRequest() " - "GUID_PROP_INPUTSCOPE queried", this)); - mInputScopeDetected = true; - if (dwFlags & TS_ATTR_FIND_WANT_VALUE) { - PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, - ("TSF: 0x%p nsTextStore::ProcessScopeRequest() " - "TS_ATTR_FIND_WANT_VALUE specified", this)); - mInputScopeRequested = true; - } - break; + this, GetGUIDNameStrWithTable(aFilterAttrs[i]).get())); + int32_t index = GetRequestedAttrIndex(aFilterAttrs[i]); + if (index != eNotSupported) { + mRequestedAttrs[index] = true; } } return S_OK; @@ -2151,7 +2273,7 @@ nsTextStore::RequestSupportedAttrs(DWORD dwFlags, "cFilterAttrs=%lu)", this, GetFindFlagName(dwFlags).get(), cFilterAttrs)); - return ProcessScopeRequest(dwFlags, cFilterAttrs, paFilterAttrs); + return HandleRequestAttrs(dwFlags, cFilterAttrs, paFilterAttrs); } STDMETHODIMP @@ -2165,8 +2287,8 @@ nsTextStore::RequestAttrsAtPosition(LONG acpPos, "cFilterAttrs=%lu, dwFlags=%s)", this, acpPos, cFilterAttrs, GetFindFlagName(dwFlags).get())); - return ProcessScopeRequest(dwFlags | TS_ATTR_FIND_WANT_VALUE, - cFilterAttrs, paFilterAttrs); + return HandleRequestAttrs(dwFlags | TS_ATTR_FIND_WANT_VALUE, + cFilterAttrs, paFilterAttrs); } STDMETHODIMP @@ -2217,38 +2339,76 @@ nsTextStore::RetrieveRequestedAttrs(ULONG ulCount, TS_ATTRVAL *paAttrVals, ULONG *pcFetched) { - if (!pcFetched || !ulCount || !paAttrVals) { + if (!pcFetched || !paAttrVals) { PR_LOG(sTextStoreLog, PR_LOG_ERROR, ("TSF: 0x%p nsTextStore::RetrieveRequestedAttrs() FAILED due to " "null argument", this)); return E_INVALIDARG; } - PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, - ("TSF: 0x%p nsTextStore::RetrieveRequestedAttrs() called " - "ulCount=%d", this, ulCount)); - - if (mInputScopeDetected || mInputScopeRequested) { - PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, - ("TSF: 0x%p nsTextStore::RetrieveRequestedAttrs() for " - "GUID_PROP_INPUTSCOPE: " - "mInputScopeDetected=%s mInputScopeRequested=%s", - this, GetBoolName(mInputScopeDetected), - GetBoolName(mInputScopeRequested))); - - paAttrVals->idAttr = GUID_PROP_INPUTSCOPE; - paAttrVals->dwOverlapId = 0; - paAttrVals->varValue.vt = VT_EMPTY; - *pcFetched = 1; - - if (mInputScopeRequested) { - paAttrVals->varValue.vt = VT_UNKNOWN; - nsRefPtr inputScope = new InputScopeImpl(mInputScopes); - paAttrVals->varValue.punkVal = inputScope.forget().take(); + ULONG expectedCount = 0; + for (int32_t i = 0; i < NUM_OF_SUPPORTED_ATTRS; i++) { + if (mRequestedAttrs[i]) { + expectedCount++; } + } + if (ulCount < expectedCount) { + PR_LOG(sTextStoreLog, PR_LOG_ERROR, + ("TSF: 0x%p nsTextStore::RetrieveRequestedAttrs() FAILED due to " + "not enough count ulCount=%u, expectedCount=%u", + this, ulCount, expectedCount)); + return E_INVALIDARG; + } - mInputScopeDetected = mInputScopeRequested = false; - return S_OK; + PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, + ("TSF: 0x%p nsTextStore::RetrieveRequestedAttrs() called " + "ulCount=%d, mRequestedAttrValues=%s", + this, ulCount, GetBoolName(mRequestedAttrValues))); + + int32_t count = 0; + for (int32_t i = 0; i < NUM_OF_SUPPORTED_ATTRS; i++) { + if (!mRequestedAttrs[i]) { + continue; + } + mRequestedAttrs[i] = false; + + TS_ATTRID attrID = GetAttrID(i); + + PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, + ("TSF: 0x%p nsTextStore::RetrieveRequestedAttrs() for %s", + this, GetGUIDNameStrWithTable(attrID).get())); + + paAttrVals[count].idAttr = attrID; + paAttrVals[count].dwOverlapId = 0; + + if (!mRequestedAttrValues) { + paAttrVals[count].varValue.vt = VT_EMPTY; + } else { + switch (i) { + case eInputScope: { + paAttrVals[count].varValue.vt = VT_UNKNOWN; + nsRefPtr inputScope = new InputScopeImpl(mInputScopes); + paAttrVals[count].varValue.punkVal = inputScope.forget().take(); + break; + } + case eTextVerticalWriting: + // Currently, we don't support vertical writing mode. + paAttrVals[count].varValue.vt = VT_BOOL; + paAttrVals[count].varValue.boolVal = VARIANT_FALSE; + break; + default: + MOZ_CRASH("Invalid index? Or not implemented yet?"); + break; + } + } + count++; + } + + mRequestedAttrValues = false; + + if (count) { + *pcFetched = count; + return NS_OK; } PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, diff --git a/widget/windows/nsTextStore.h b/widget/windows/nsTextStore.h index 6294be96d5a6..08cc1e752a16 100644 --- a/widget/windows/nsTextStore.h +++ b/widget/windows/nsTextStore.h @@ -24,6 +24,9 @@ #ifdef INPUTSCOPE_INIT_GUID #include #endif +#ifdef TEXTATTRS_INIT_GUID +#include +#endif #include // TSF InputScope, for earlier SDK 8 @@ -284,9 +287,9 @@ protected: void FlushPendingActions(); nsresult OnLayoutChangeInternal(); - HRESULT ProcessScopeRequest(DWORD dwFlags, - ULONG cFilterAttrs, - const TS_ATTRID *paFilterAttrs); + HRESULT HandleRequestAttrs(DWORD aFlags, + ULONG aFilterCount, + const TS_ATTRID* aFilterAttrs); void SetInputScope(const nsString& aHTMLInputType); // Creates native caret over our caret. This method only works on desktop @@ -663,8 +666,28 @@ protected: // The input scopes for this context, defaults to IS_DEFAULT. nsTArray mInputScopes; - bool mInputScopeDetected; - bool mInputScopeRequested; + + // Support retrieving attributes. + // TODO: We should support RightToLeft, perhaps. + enum + { + // Used for result of GetRequestedAttrIndex() + eNotSupported = -1, + + // Supported attributes + eInputScope = 0, + eTextVerticalWriting, + + // Count of the supported attributes + NUM_OF_SUPPORTED_ATTRS + }; + bool mRequestedAttrs[NUM_OF_SUPPORTED_ATTRS]; + + int32_t GetRequestedAttrIndex(const TS_ATTRID& aAttrID); + TS_ATTRID GetAttrID(int32_t aIndex); + + bool mRequestedAttrValues; + // If edit actions are being recorded without document lock, this is true. // Otherwise, false. bool mIsRecordingActionsWithoutLock; diff --git a/widget/windows/nsWindowDbg.cpp b/widget/windows/nsWindowDbg.cpp index b1a655eac4de..2e94c3e28f41 100644 --- a/widget/windows/nsWindowDbg.cpp +++ b/widget/windows/nsWindowDbg.cpp @@ -8,18 +8,14 @@ */ #include "nsWindowDbg.h" +#include "WinUtils.h" + +using namespace mozilla::widget; #ifdef PR_LOGGING extern PRLogModuleInfo* gWindowsLog; #endif -#if defined(POPUP_ROLLUP_DEBUG_OUTPUT) || defined(EVENT_DEBUG_OUTPUT) || 1 - -typedef struct { - const char * mStr; - long mId; -} EventMsgInfo; - #if defined(POPUP_ROLLUP_DEBUG_OUTPUT) MSGFEventMsgInfo gMSGFEvents[] = { "MSGF_DIALOGBOX", 0, @@ -32,343 +28,6 @@ MSGFEventMsgInfo gMSGFEvents[] = { nullptr, 0}; #endif -EventMsgInfo gAllEvents[] = { - {"WM_NULL", 0x0000}, - {"WM_CREATE", 0x0001}, - {"WM_DESTROY", 0x0002}, - {"WM_MOVE", 0x0003}, - {"WM_SIZE", 0x0005}, - {"WM_ACTIVATE", 0x0006}, - {"WM_SETFOCUS", 0x0007}, - {"WM_KILLFOCUS", 0x0008}, - {"WM_ENABLE", 0x000A}, - {"WM_SETREDRAW", 0x000B}, - {"WM_SETTEXT", 0x000C}, - {"WM_GETTEXT", 0x000D}, - {"WM_GETTEXTLENGTH", 0x000E}, - {"WM_PAINT", 0x000F}, - {"WM_CLOSE", 0x0010}, - {"WM_QUERYENDSESSION", 0x0011}, - {"WM_QUIT", 0x0012}, - {"WM_QUERYOPEN", 0x0013}, - {"WM_ERASEBKGND", 0x0014}, - {"WM_SYSCOLORCHANGE", 0x0015}, - {"WM_ENDSESSION", 0x0016}, - {"WM_SHOWWINDOW", 0x0018}, - {"WM_SETTINGCHANGE", 0x001A}, - {"WM_DEVMODECHANGE", 0x001B}, - {"WM_ACTIVATEAPP", 0x001C}, - {"WM_FONTCHANGE", 0x001D}, - {"WM_TIMECHANGE", 0x001E}, - {"WM_CANCELMODE", 0x001F}, - {"WM_SETCURSOR", 0x0020}, - {"WM_MOUSEACTIVATE", 0x0021}, - {"WM_CHILDACTIVATE", 0x0022}, - {"WM_QUEUESYNC", 0x0023}, - {"WM_GETMINMAXINFO", 0x0024}, - {"WM_PAINTICON", 0x0026}, - {"WM_ICONERASEBKGND", 0x0027}, - {"WM_NEXTDLGCTL", 0x0028}, - {"WM_SPOOLERSTATUS", 0x002A}, - {"WM_DRAWITEM", 0x002B}, - {"WM_MEASUREITEM", 0x002C}, - {"WM_DELETEITEM", 0x002D}, - {"WM_VKEYTOITEM", 0x002E}, - {"WM_CHARTOITEM", 0x002F}, - {"WM_SETFONT", 0x0030}, - {"WM_GETFONT", 0x0031}, - {"WM_SETHOTKEY", 0x0032}, - {"WM_GETHOTKEY", 0x0033}, - {"WM_QUERYDRAGICON", 0x0037}, - {"WM_COMPAREITEM", 0x0039}, - {"WM_GETOBJECT", 0x003D}, - {"WM_COMPACTING", 0x0041}, - {"WM_COMMNOTIFY", 0x0044}, - {"WM_WINDOWPOSCHANGING", 0x0046}, - {"WM_WINDOWPOSCHANGED", 0x0047}, - {"WM_POWER", 0x0048}, - {"WM_COPYDATA", 0x004A}, - {"WM_CANCELJOURNAL", 0x004B}, - {"WM_NOTIFY", 0x004E}, - {"WM_INPUTLANGCHANGEREQUEST", 0x0050}, - {"WM_INPUTLANGCHANGE", 0x0051}, - {"WM_TCARD", 0x0052}, - {"WM_HELP", 0x0053}, - {"WM_USERCHANGED", 0x0054}, - {"WM_NOTIFYFORMAT", 0x0055}, - {"WM_CONTEXTMENU", 0x007B}, - {"WM_STYLECHANGING", 0x007C}, - {"WM_STYLECHANGED", 0x007D}, - {"WM_DISPLAYCHANGE", 0x007E}, - {"WM_GETICON", 0x007F}, - {"WM_SETICON", 0x0080}, - {"WM_NCCREATE", 0x0081}, - {"WM_NCDESTROY", 0x0082}, - {"WM_NCCALCSIZE", 0x0083}, - {"WM_NCHITTEST", 0x0084}, - {"WM_NCPAINT", 0x0085}, - {"WM_NCACTIVATE", 0x0086}, - {"WM_GETDLGCODE", 0x0087}, - {"WM_SYNCPAINT", 0x0088}, - {"WM_NCMOUSEMOVE", 0x00A0}, - {"WM_NCLBUTTONDOWN", 0x00A1}, - {"WM_NCLBUTTONUP", 0x00A2}, - {"WM_NCLBUTTONDBLCLK", 0x00A3}, - {"WM_NCRBUTTONDOWN", 0x00A4}, - {"WM_NCRBUTTONUP", 0x00A5}, - {"WM_NCRBUTTONDBLCLK", 0x00A6}, - {"WM_NCMBUTTONDOWN", 0x00A7}, - {"WM_NCMBUTTONUP", 0x00A8}, - {"WM_NCMBUTTONDBLCLK", 0x00A9}, - {"EM_GETSEL", 0x00B0}, - {"EM_SETSEL", 0x00B1}, - {"EM_GETRECT", 0x00B2}, - {"EM_SETRECT", 0x00B3}, - {"EM_SETRECTNP", 0x00B4}, - {"EM_SCROLL", 0x00B5}, - {"EM_LINESCROLL", 0x00B6}, - {"EM_SCROLLCARET", 0x00B7}, - {"EM_GETMODIFY", 0x00B8}, - {"EM_SETMODIFY", 0x00B9}, - {"EM_GETLINECOUNT", 0x00BA}, - {"EM_LINEINDEX", 0x00BB}, - {"EM_SETHANDLE", 0x00BC}, - {"EM_GETHANDLE", 0x00BD}, - {"EM_GETTHUMB", 0x00BE}, - {"EM_LINELENGTH", 0x00C1}, - {"EM_REPLACESEL", 0x00C2}, - {"EM_GETLINE", 0x00C4}, - {"EM_LIMITTEXT", 0x00C5}, - {"EM_CANUNDO", 0x00C6}, - {"EM_UNDO", 0x00C7}, - {"EM_FMTLINES", 0x00C8}, - {"EM_LINEFROMCHAR", 0x00C9}, - {"EM_SETTABSTOPS", 0x00CB}, - {"EM_SETPASSWORDCHAR", 0x00CC}, - {"EM_EMPTYUNDOBUFFER", 0x00CD}, - {"EM_GETFIRSTVISIBLELINE", 0x00CE}, - {"EM_SETREADONLY", 0x00CF}, - {"EM_SETWORDBREAKPROC", 0x00D0}, - {"EM_GETWORDBREAKPROC", 0x00D1}, - {"EM_GETPASSWORDCHAR", 0x00D2}, - {"EM_SETMARGINS", 0x00D3}, - {"EM_GETMARGINS", 0x00D4}, - {"EM_GETLIMITTEXT", 0x00D5}, - {"EM_POSFROMCHAR", 0x00D6}, - {"EM_CHARFROMPOS", 0x00D7}, - {"EM_SETIMESTATUS", 0x00D8}, - {"EM_GETIMESTATUS", 0x00D9}, - {"SBM_SETPOS", 0x00E0}, - {"SBM_GETPOS", 0x00E1}, - {"SBM_SETRANGE", 0x00E2}, - {"SBM_SETRANGEREDRAW", 0x00E6}, - {"SBM_GETRANGE", 0x00E3}, - {"SBM_ENABLE_ARROWS", 0x00E4}, - {"SBM_SETSCROLLINFO", 0x00E9}, - {"SBM_GETSCROLLINFO", 0x00EA}, - {"WM_KEYDOWN", 0x0100}, - {"WM_KEYUP", 0x0101}, - {"WM_CHAR", 0x0102}, - {"WM_DEADCHAR", 0x0103}, - {"WM_SYSKEYDOWN", 0x0104}, - {"WM_SYSKEYUP", 0x0105}, - {"WM_SYSCHAR", 0x0106}, - {"WM_SYSDEADCHAR", 0x0107}, - {"WM_KEYLAST", 0x0108}, - {"WM_IME_STARTCOMPOSITION", 0x010D}, - {"WM_IME_ENDCOMPOSITION", 0x010E}, - {"WM_IME_COMPOSITION", 0x010F}, - {"WM_INITDIALOG", 0x0110}, - {"WM_COMMAND", 0x0111}, - {"WM_SYSCOMMAND", 0x0112}, - {"WM_TIMER", 0x0113}, - {"WM_HSCROLL", 0x0114}, - {"WM_VSCROLL", 0x0115}, - {"WM_INITMENU", 0x0116}, - {"WM_INITMENUPOPUP", 0x0117}, - {"WM_MENUSELECT", 0x011F}, - {"WM_MENUCHAR", 0x0120}, - {"WM_ENTERIDLE", 0x0121}, - {"WM_MENURBUTTONUP", 0x0122}, - {"WM_MENUDRAG", 0x0123}, - {"WM_MENUGETOBJECT", 0x0124}, - {"WM_UNINITMENUPOPUP", 0x0125}, - {"WM_MENUCOMMAND", 0x0126}, - {"WM_CHANGEUISTATE", 0x0127}, - {"WM_UPDATEUISTATE", 0x0128}, - {"WM_CTLCOLORMSGBOX", 0x0132}, - {"WM_CTLCOLOREDIT", 0x0133}, - {"WM_CTLCOLORLISTBOX", 0x0134}, - {"WM_CTLCOLORBTN", 0x0135}, - {"WM_CTLCOLORDLG", 0x0136}, - {"WM_CTLCOLORSCROLLBAR", 0x0137}, - {"WM_CTLCOLORSTATIC", 0x0138}, - {"CB_GETEDITSEL", 0x0140}, - {"CB_LIMITTEXT", 0x0141}, - {"CB_SETEDITSEL", 0x0142}, - {"CB_ADDSTRING", 0x0143}, - {"CB_DELETESTRING", 0x0144}, - {"CB_DIR", 0x0145}, - {"CB_GETCOUNT", 0x0146}, - {"CB_GETCURSEL", 0x0147}, - {"CB_GETLBTEXT", 0x0148}, - {"CB_GETLBTEXTLEN", 0x0149}, - {"CB_INSERTSTRING", 0x014A}, - {"CB_RESETCONTENT", 0x014B}, - {"CB_FINDSTRING", 0x014C}, - {"CB_SELECTSTRING", 0x014D}, - {"CB_SETCURSEL", 0x014E}, - {"CB_SHOWDROPDOWN", 0x014F}, - {"CB_GETITEMDATA", 0x0150}, - {"CB_SETITEMDATA", 0x0151}, - {"CB_GETDROPPEDCONTROLRECT", 0x0152}, - {"CB_SETITEMHEIGHT", 0x0153}, - {"CB_GETITEMHEIGHT", 0x0154}, - {"CB_SETEXTENDEDUI", 0x0155}, - {"CB_GETEXTENDEDUI", 0x0156}, - {"CB_GETDROPPEDSTATE", 0x0157}, - {"CB_FINDSTRINGEXACT", 0x0158}, - {"CB_SETLOCALE", 0x0159}, - {"CB_GETLOCALE", 0x015A}, - {"CB_GETTOPINDEX", 0x015b}, - {"CB_SETTOPINDEX", 0x015c}, - {"CB_GETHORIZONTALEXTENT", 0x015d}, - {"CB_SETHORIZONTALEXTENT", 0x015e}, - {"CB_GETDROPPEDWIDTH", 0x015f}, - {"CB_SETDROPPEDWIDTH", 0x0160}, - {"CB_INITSTORAGE", 0x0161}, - {"CB_MSGMAX", 0x0162}, - {"LB_ADDSTRING", 0x0180}, - {"LB_INSERTSTRING", 0x0181}, - {"LB_DELETESTRING", 0x0182}, - {"LB_SELITEMRANGEEX", 0x0183}, - {"LB_RESETCONTENT", 0x0184}, - {"LB_SETSEL", 0x0185}, - {"LB_SETCURSEL", 0x0186}, - {"LB_GETSEL", 0x0187}, - {"LB_GETCURSEL", 0x0188}, - {"LB_GETTEXT", 0x0189}, - {"LB_GETTEXTLEN", 0x018A}, - {"LB_GETCOUNT", 0x018B}, - {"LB_SELECTSTRING", 0x018C}, - {"LB_DIR", 0x018D}, - {"LB_GETTOPINDEX", 0x018E}, - {"LB_FINDSTRING", 0x018F}, - {"LB_GETSELCOUNT", 0x0190}, - {"LB_GETSELITEMS", 0x0191}, - {"LB_SETTABSTOPS", 0x0192}, - {"LB_GETHORIZONTALEXTENT", 0x0193}, - {"LB_SETHORIZONTALEXTENT", 0x0194}, - {"LB_SETCOLUMNWIDTH", 0x0195}, - {"LB_ADDFILE", 0x0196}, - {"LB_SETTOPINDEX", 0x0197}, - {"LB_GETITEMRECT", 0x0198}, - {"LB_GETITEMDATA", 0x0199}, - {"LB_SETITEMDATA", 0x019A}, - {"LB_SELITEMRANGE", 0x019B}, - {"LB_SETANCHORINDEX", 0x019C}, - {"LB_GETANCHORINDEX", 0x019D}, - {"LB_SETCARETINDEX", 0x019E}, - {"LB_GETCARETINDEX", 0x019F}, - {"LB_SETITEMHEIGHT", 0x01A0}, - {"LB_GETITEMHEIGHT", 0x01A1}, - {"LB_FINDSTRINGEXACT", 0x01A2}, - {"LB_SETLOCALE", 0x01A5}, - {"LB_GETLOCALE", 0x01A6}, - {"LB_SETCOUNT", 0x01A7}, - {"LB_INITSTORAGE", 0x01A8}, - {"LB_ITEMFROMPOINT", 0x01A9}, - {"LB_MSGMAX", 0x01B0}, - {"WM_MOUSEMOVE", 0x0200}, - {"WM_LBUTTONDOWN", 0x0201}, - {"WM_LBUTTONUP", 0x0202}, - {"WM_LBUTTONDBLCLK", 0x0203}, - {"WM_RBUTTONDOWN", 0x0204}, - {"WM_RBUTTONUP", 0x0205}, - {"WM_RBUTTONDBLCLK", 0x0206}, - {"WM_MBUTTONDOWN", 0x0207}, - {"WM_MBUTTONUP", 0x0208}, - {"WM_MBUTTONDBLCLK", 0x0209}, - {"WM_MOUSEWHEEL", 0x020A}, - {"WM_MOUSEHWHEEL", 0x020E}, - {"WM_PARENTNOTIFY", 0x0210}, - {"WM_ENTERMENULOOP", 0x0211}, - {"WM_EXITMENULOOP", 0x0212}, - {"WM_NEXTMENU", 0x0213}, - {"WM_SIZING", 0x0214}, - {"WM_CAPTURECHANGED", 0x0215}, - {"WM_MOVING", 0x0216}, - {"WM_POWERBROADCAST", 0x0218}, - {"WM_DEVICECHANGE", 0x0219}, - {"WM_MDICREATE", 0x0220}, - {"WM_MDIDESTROY", 0x0221}, - {"WM_MDIACTIVATE", 0x0222}, - {"WM_MDIRESTORE", 0x0223}, - {"WM_MDINEXT", 0x0224}, - {"WM_MDIMAXIMIZE", 0x0225}, - {"WM_MDITILE", 0x0226}, - {"WM_MDICASCADE", 0x0227}, - {"WM_MDIICONARRANGE", 0x0228}, - {"WM_MDIGETACTIVE", 0x0229}, - {"WM_MDISETMENU", 0x0230}, - {"WM_ENTERSIZEMOVE", 0x0231}, - {"WM_EXITSIZEMOVE", 0x0232}, - {"WM_DROPFILES", 0x0233}, - {"WM_MDIREFRESHMENU", 0x0234}, - {"WM_IME_SETCONTEXT", 0x0281}, - {"WM_IME_NOTIFY", 0x0282}, - {"WM_IME_CONTROL", 0x0283}, - {"WM_IME_COMPOSITIONFULL", 0x0284}, - {"WM_IME_SELECT", 0x0285}, - {"WM_IME_CHAR", 0x0286}, - {"WM_IME_REQUEST", 0x0288}, - {"WM_IME_KEYDOWN", 0x0290}, - {"WM_IME_KEYUP", 0x0291}, - {"WM_NCMOUSEHOVER", 0x02A0}, - {"WM_MOUSEHOVER", 0x02A1}, - {"WM_MOUSELEAVE", 0x02A3}, - {"WM_CUT", 0x0300}, - {"WM_COPY", 0x0301}, - {"WM_PASTE", 0x0302}, - {"WM_CLEAR", 0x0303}, - {"WM_UNDO", 0x0304}, - {"WM_RENDERFORMAT", 0x0305}, - {"WM_RENDERALLFORMATS", 0x0306}, - {"WM_DESTROYCLIPBOARD", 0x0307}, - {"WM_DRAWCLIPBOARD", 0x0308}, - {"WM_PAINTCLIPBOARD", 0x0309}, - {"WM_VSCROLLCLIPBOARD", 0x030A}, - {"WM_SIZECLIPBOARD", 0x030B}, - {"WM_ASKCBFORMATNAME", 0x030C}, - {"WM_CHANGECBCHAIN", 0x030D}, - {"WM_HSCROLLCLIPBOARD", 0x030E}, - {"WM_QUERYNEWPALETTE", 0x030F}, - {"WM_PALETTEISCHANGING", 0x0310}, - {"WM_PALETTECHANGED", 0x0311}, - {"WM_HOTKEY", 0x0312}, - {"WM_PRINT", 0x0317}, - {"WM_PRINTCLIENT", 0x0318}, - {"WM_THEMECHANGED", 0x031A}, - {"WM_HANDHELDFIRST", 0x0358}, - {"WM_HANDHELDLAST", 0x035F}, - {"WM_AFXFIRST", 0x0360}, - {"WM_AFXLAST", 0x037F}, - {"WM_PENWINFIRST", 0x0380}, - {"WM_PENWINLAST", 0x038F}, - {"WM_APP", 0x8000}, - {"WM_DWMCOMPOSITIONCHANGED", 0x031E}, - {"WM_DWMNCRENDERINGCHANGED", 0x031F}, - {"WM_DWMCOLORIZATIONCOLORCHANGED", 0x0320}, - {"WM_DWMWINDOWMAXIMIZEDCHANGE", 0x0321}, - {"WM_DWMSENDICONICTHUMBNAIL", 0x0323}, - {"WM_DWMSENDICONICLIVEPREVIEWBITMAP", 0x0326}, - {"WM_TABLET_QUERYSYSTEMGESTURESTATUS", 0x02CC}, - {"WM_GESTURE", 0x0119}, - {"WM_GESTURENOTIFY", 0x011A}, - {"WM_GETTITLEBARINFOEX", 0x033F}, - {nullptr, 0x0} -}; - static long gEventCounter = 0; static long gLastEventMsg = 0; @@ -388,8 +47,6 @@ void PrintEvent(UINT msg, bool aShowAllEvents, bool aShowMouseMoves) } } -#endif // defined(POPUP_ROLLUP_DEBUG_OUTPUT) || defined(EVENT_DEBUG_OUTPUT) - #ifdef DEBUG void DDError(const char *msg, HRESULT hr) { diff --git a/widget/windows/nsWindowDbg.h b/widget/windows/nsWindowDbg.h index ce1f4b866687..5c1a1ef47a95 100644 --- a/widget/windows/nsWindowDbg.h +++ b/widget/windows/nsWindowDbg.h @@ -34,9 +34,7 @@ #define SHOW_MOUSEMOVE_EVENTS false #endif // defined(EVENT_DEBUG_OUTPUT) -#if defined(POPUP_ROLLUP_DEBUG_OUTPUT) || defined(EVENT_DEBUG_OUTPUT) || 1 void PrintEvent(UINT msg, bool aShowAllEvents, bool aShowMouseMoves); -#endif // defined(POPUP_ROLLUP_DEBUG_OUTPUT) || defined(EVENT_DEBUG_OUTPUT) #if defined(POPUP_ROLLUP_DEBUG_OUTPUT) typedef struct { diff --git a/widget/windows/nsWindowDefs.h b/widget/windows/nsWindowDefs.h index e8f0aa0ad63a..aebc1cd92d2f 100644 --- a/widget/windows/nsWindowDefs.h +++ b/widget/windows/nsWindowDefs.h @@ -90,6 +90,19 @@ #define MAPVK_VK_TO_VSC_EX 4 #endif +#ifndef WM_DWMCOMPOSITIONCHANGED +#define WM_DWMCOMPOSITIONCHANGED 0x031E +#endif +#ifndef WM_DWMNCRENDERINGCHANGED +#define WM_DWMNCRENDERINGCHANGED 0x031F +#endif +#ifndef WM_DWMCOLORIZATIONCOLORCHANGED +#define WM_DWMCOLORIZATIONCOLORCHANGED 0x0320 +#endif +#ifndef WM_DWMWINDOWMAXIMIZEDCHANGE +#define WM_DWMWINDOWMAXIMIZEDCHANGE 0x0321 +#endif + // ConstrainPosition window positioning slop value #define kWindowPositionSlop 20 diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp index 9c039b8ff8ea..3b205485c4f8 100644 --- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -800,17 +800,17 @@ struct JsGcTracer : public TraceCallbacks virtual void Trace(JS::Heap* aPtr, const char* aName, void* aClosure) const MOZ_OVERRIDE { - JS_CallHeapValueTracer(static_cast(aClosure), aPtr, aName); + JS_CallValueTracer(static_cast(aClosure), aPtr, aName); } virtual void Trace(JS::Heap* aPtr, const char* aName, void* aClosure) const MOZ_OVERRIDE { - JS_CallHeapIdTracer(static_cast(aClosure), aPtr, aName); + JS_CallIdTracer(static_cast(aClosure), aPtr, aName); } virtual void Trace(JS::Heap* aPtr, const char* aName, void* aClosure) const MOZ_OVERRIDE { - JS_CallHeapObjectTracer(static_cast(aClosure), aPtr, aName); + JS_CallObjectTracer(static_cast(aClosure), aPtr, aName); } virtual void Trace(JS::TenuredHeap* aPtr, const char* aName, void* aClosure) const MOZ_OVERRIDE @@ -820,17 +820,17 @@ struct JsGcTracer : public TraceCallbacks virtual void Trace(JS::Heap* aPtr, const char* aName, void* aClosure) const MOZ_OVERRIDE { - JS_CallHeapStringTracer(static_cast(aClosure), aPtr, aName); + JS_CallStringTracer(static_cast(aClosure), aPtr, aName); } virtual void Trace(JS::Heap* aPtr, const char* aName, void* aClosure) const MOZ_OVERRIDE { - JS_CallHeapScriptTracer(static_cast(aClosure), aPtr, aName); + JS_CallScriptTracer(static_cast(aClosure), aPtr, aName); } virtual void Trace(JS::Heap* aPtr, const char* aName, void* aClosure) const MOZ_OVERRIDE { - JS_CallHeapFunctionTracer(static_cast(aClosure), aPtr, aName); + JS_CallFunctionTracer(static_cast(aClosure), aPtr, aName); } }; diff --git a/xpcom/glue/BlockingResourceBase.cpp b/xpcom/glue/BlockingResourceBase.cpp index 0a5c81dd9680..428e61ccdf6f 100644 --- a/xpcom/glue/BlockingResourceBase.cpp +++ b/xpcom/glue/BlockingResourceBase.cpp @@ -7,9 +7,12 @@ #include "mozilla/BlockingResourceBase.h" #ifdef DEBUG +#include "prthread.h" + #include "nsAutoPtr.h" #include "mozilla/CondVar.h" +#include "mozilla/DeadlockDetector.h" #include "mozilla/ReentrantMonitor.h" #include "mozilla/Mutex.h" @@ -37,10 +40,54 @@ PRCallOnceType BlockingResourceBase::sCallOnce; unsigned BlockingResourceBase::sResourceAcqnChainFrontTPI = (unsigned)-1; BlockingResourceBase::DDT* BlockingResourceBase::sDeadlockDetector; + +/** + * PrintCycle + * Append to |aOut| detailed information about the circular + * dependency in |aCycle|. Returns true if it *appears* that this + * cycle may represent an imminent deadlock, but this is merely a + * heuristic; the value returned may be a false positive or false + * negative. + * + * *NOT* thread safe. Calls |Print()|. + * + * FIXME bug 456272 hack alert: because we can't write call + * contexts into strings, all info is written to stderr, but only + * some info is written into |aOut| + */ bool -BlockingResourceBase::DeadlockDetectorEntry::Print( - const DDT::ResourceAcquisition& aFirstSeen, - nsACString& aOut) const +PrintCycle(const BlockingResourceBase::DDT::ResourceAcquisitionArray* aCycle, nsACString& aOut) +{ + NS_ASSERTION(aCycle->Length() > 1, "need > 1 element for cycle!"); + + bool maybeImminent = true; + + fputs("=== Cyclical dependency starts at\n", stderr); + aOut += "Cyclical dependency starts at\n"; + + const BlockingResourceBase::DDT::ResourceAcquisitionArray::elem_type res = aCycle->ElementAt(0); + maybeImminent &= res->Print(aOut); + + BlockingResourceBase::DDT::ResourceAcquisitionArray::index_type i; + BlockingResourceBase::DDT::ResourceAcquisitionArray::size_type len = aCycle->Length(); + const BlockingResourceBase::DDT::ResourceAcquisitionArray::elem_type* it = 1 + aCycle->Elements(); + for (i = 1; i < len - 1; ++i, ++it) { + fputs("\n--- Next dependency:\n", stderr); + aOut += "\nNext dependency:\n"; + + maybeImminent &= (*it)->Print(aOut); + } + + fputs("\n=== Cycle completed at\n", stderr); + aOut += "Cycle completed at\n"; + (*it)->Print(aOut); + + return maybeImminent; +} + + +bool +BlockingResourceBase::Print(nsACString& aOut) const { fprintf(stderr, "--- %s : %s", kResourceTypeName[mType], mName); @@ -63,16 +110,19 @@ BlockingResourceBase::DeadlockDetectorEntry::Print( BlockingResourceBase::BlockingResourceBase( const char* aName, BlockingResourceBase::BlockingResourceType aType) + : mName(aName) + , mType(aType) + , mAcquired(false) { + NS_ABORT_IF_FALSE(mName, "Name must be nonnull"); // PR_CallOnce guaranatees that InitStatics is called in a // thread-safe way if (PR_SUCCESS != PR_CallOnce(&sCallOnce, InitStatics)) { NS_RUNTIMEABORT("can't initialize blocking resource static members"); } - mDDEntry = new BlockingResourceBase::DeadlockDetectorEntry(aName, aType); mChainPrev = 0; - sDeadlockDetector->Add(mDDEntry); + sDeadlockDetector->Add(this); } @@ -83,15 +133,42 @@ BlockingResourceBase::~BlockingResourceBase() // base class, or its underlying primitive, will check for such // stupid mistakes. mChainPrev = 0; // racy only for stupidly buggy client code - sDeadlockDetector->Remove(mDDEntry); - mDDEntry = 0; // owned by deadlock detector + sDeadlockDetector->Remove(this); +} + + +size_t +BlockingResourceBase::SizeOfDeadlockDetector(MallocSizeOf aMallocSizeOf) +{ + return sDeadlockDetector ? + sDeadlockDetector->SizeOfIncludingThis(aMallocSizeOf) : 0; +} + + +PRStatus +BlockingResourceBase::InitStatics() +{ + PR_NewThreadPrivateIndex(&sResourceAcqnChainFrontTPI, 0); + sDeadlockDetector = new DDT(); + if (!sDeadlockDetector) { + NS_RUNTIMEABORT("can't allocate deadlock detector"); + } + return PR_SUCCESS; +} + + +void +BlockingResourceBase::Shutdown() +{ + delete sDeadlockDetector; + sDeadlockDetector = 0; } void BlockingResourceBase::CheckAcquire() { - if (mDDEntry->mType == eCondVar) { + if (mType == eCondVar) { NS_NOTYETIMPLEMENTED( "FIXME bug 456272: annots. to allow CheckAcquire()ing condvars"); return; @@ -100,7 +177,7 @@ BlockingResourceBase::CheckAcquire() BlockingResourceBase* chainFront = ResourceChainFront(); nsAutoPtr cycle( sDeadlockDetector->CheckAcquisition( - chainFront ? chainFront->mDDEntry : 0, mDDEntry)); + chainFront ? chainFront : 0, this)); if (!cycle) { return; } @@ -129,30 +206,30 @@ BlockingResourceBase::CheckAcquire() void BlockingResourceBase::Acquire() { - if (mDDEntry->mType == eCondVar) { + if (mType == eCondVar) { NS_NOTYETIMPLEMENTED( "FIXME bug 456272: annots. to allow Acquire()ing condvars"); return; } - NS_ASSERTION(!mDDEntry->mAcquired, + NS_ASSERTION(!mAcquired, "reacquiring already acquired resource"); ResourceChainAppend(ResourceChainFront()); - mDDEntry->mAcquired = true; + mAcquired = true; } void BlockingResourceBase::Release() { - if (mDDEntry->mType == eCondVar) { + if (mType == eCondVar) { NS_NOTYETIMPLEMENTED( "FIXME bug 456272: annots. to allow Release()ing condvars"); return; } BlockingResourceBase* chainFront = ResourceChainFront(); - NS_ASSERTION(chainFront && mDDEntry->mAcquired, + NS_ASSERTION(chainFront && mAcquired, "Release()ing something that hasn't been Acquire()ed"); if (chainFront == this) { @@ -178,39 +255,7 @@ BlockingResourceBase::Release() } } - mDDEntry->mAcquired = false; -} - - -bool -BlockingResourceBase::PrintCycle(const DDT::ResourceAcquisitionArray* aCycle, - nsACString& aOut) -{ - NS_ASSERTION(aCycle->Length() > 1, "need > 1 element for cycle!"); - - bool maybeImminent = true; - - fputs("=== Cyclical dependency starts at\n", stderr); - aOut += "Cyclical dependency starts at\n"; - - const DDT::ResourceAcquisition res = aCycle->ElementAt(0); - maybeImminent &= res.mResource->Print(res, aOut); - - DDT::ResourceAcquisitionArray::index_type i; - DDT::ResourceAcquisitionArray::size_type len = aCycle->Length(); - const DDT::ResourceAcquisition* it = 1 + aCycle->Elements(); - for (i = 1; i < len - 1; ++i, ++it) { - fputs("\n--- Next dependency:\n", stderr); - aOut += "\nNext dependency:\n"; - - maybeImminent &= it->mResource->Print(*it, aOut); - } - - fputs("\n=== Cycle completed at\n", stderr); - aOut += "Cycle completed at\n"; - it->mResource->Print(*it, aOut); - - return maybeImminent; + mAcquired = false; } diff --git a/xpcom/glue/BlockingResourceBase.h b/xpcom/glue/BlockingResourceBase.h index 4217f5f984bf..adb8797fdfc3 100644 --- a/xpcom/glue/BlockingResourceBase.h +++ b/xpcom/glue/BlockingResourceBase.h @@ -17,11 +17,8 @@ #ifdef DEBUG #include "prinit.h" -#include "prthread.h" #include "nsStringGlue.h" - -#include "mozilla/DeadlockDetector.h" #include "nsXPCOM.h" #endif @@ -31,6 +28,9 @@ namespace mozilla { +#ifdef DEBUG +template class DeadlockDetector; +#endif /** * BlockingResourceBase @@ -53,87 +53,39 @@ public: #ifdef DEBUG static size_t - SizeOfDeadlockDetector(MallocSizeOf aMallocSizeOf) - { - return sDeadlockDetector ? - sDeadlockDetector->SizeOfIncludingThis(aMallocSizeOf) : 0; - } - -private: - // forward declaration for the following typedef - struct DeadlockDetectorEntry; - - // ``DDT'' = ``Deadlock Detector Type'' - typedef DeadlockDetector DDT; + SizeOfDeadlockDetector(MallocSizeOf aMallocSizeOf); /** - * DeadlockDetectorEntry - * We free BlockingResources, but we never free entries in the - * deadlock detector. This struct outlives its BlockingResource - * and preserves all the state needed to print subsequent - * error messages. + * Print + * Write a description of this blocking resource to |aOut|. If + * the resource appears to be currently acquired, the current + * acquisition context is printed and true is returned. + * Otherwise, we print the context from |aFirstSeen|, the + * first acquisition from which the code calling |Print()| + * became interested in us, and return false. * - * These objects are owned by the deadlock detector. + * *NOT* thread safe. Reads |mAcquisitionContext| without + * synchronization, but this will not cause correctness + * problems. + * + * FIXME bug 456272: hack alert: because we can't write call + * contexts into strings, all info is written to stderr, but + * only some info is written into |aOut| */ - struct DeadlockDetectorEntry + bool Print(nsACString& aOut) const; + + size_t + SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { - DeadlockDetectorEntry(const char* aName, - BlockingResourceType aType) - : mName(aName) - , mType(aType) - , mAcquired(false) - { - NS_ABORT_IF_FALSE(mName, "Name must be nonnull"); - } + // NB: |mName| is not reported as it's expected to be a static string. + // If we switch to a nsString it should be added to the tally. + // |mChainPrev| is not reported because its memory is not owned. + size_t n = aMallocSizeOf(this); + return n; + } - size_t - SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const - { - // NB: |mName| is not reported as it's expected to be a static string. - // If we switch to a nsString it should be added to the tally. - // |mAcquisitionContext| has no measurable heap allocations in it. - size_t n = aMallocSizeOf(this); - return n; - } - - /** - * Print - * Write a description of this blocking resource to |aOut|. If - * the resource appears to be currently acquired, the current - * acquisition context is printed and true is returned. - * Otherwise, we print the context from |aFirstSeen|, the - * first acquisition from which the code calling |Print()| - * became interested in us, and return false. - * - * *NOT* thread safe. Reads |mAcquisitionContext| without - * synchronization, but this will not cause correctness - * problems. - * - * FIXME bug 456272: hack alert: because we can't write call - * contexts into strings, all info is written to stderr, but - * only some info is written into |aOut| - */ - bool Print(const DDT::ResourceAcquisition& aFirstSeen, - nsACString& aOut) const; - - /** - * mName - * A descriptive name for this resource. Used in error - * messages etc. - */ - const char* mName; - /** - * mType - * The more specific type of this resource. Used to implement - * special semantics (e.g., reentrancy of monitors). - **/ - BlockingResourceType mType; - /** - * mAcquired - * Indicates if this resource is currently acquired. - */ - bool mAcquired; - }; + // ``DDT'' = ``Deadlock Detector Type'' + typedef DeadlockDetector DDT; protected: /** @@ -176,23 +128,6 @@ protected: **/ void Release(); //NS_NEEDS_RESOURCE(this) - /** - * PrintCycle - * Append to |aOut| detailed information about the circular - * dependency in |aCycle|. Returns true if it *appears* that this - * cycle may represent an imminent deadlock, but this is merely a - * heuristic; the value returned may be a false positive or false - * negative. - * - * *NOT* thread safe. Calls |Print()|. - * - * FIXME bug 456272 hack alert: because we can't write call - * contexts into strings, all info is written to stderr, but only - * some info is written into |aOut| - */ - static bool PrintCycle(const DDT::ResourceAcquisitionArray* aCycle, - nsACString& aOut); - /** * ResourceChainFront * @@ -251,7 +186,7 @@ protected: */ bool GetAcquisitionState() { - return mDDEntry->mAcquired; + return mAcquired; } /** @@ -262,7 +197,7 @@ protected: */ void SetAcquisitionState(bool aAcquisitionState) { - mDDEntry->mAcquired = aAcquisitionState; + mAcquired = aAcquisitionState; } /** @@ -275,10 +210,24 @@ protected: private: /** - * mDDEntry - * The key for this BlockingResourceBase in the deadlock detector. + * mName + * A descriptive name for this resource. Used in error + * messages etc. */ - DeadlockDetectorEntry* mDDEntry; + const char* mName; + + /** + * mType + * The more specific type of this resource. Used to implement + * special semantics (e.g., reentrancy of monitors). + **/ + BlockingResourceType mType; + + /** + * mAcquired + * Indicates if this resource is currently acquired. + */ + bool mAcquired; /** * sCallOnce @@ -307,15 +256,7 @@ private: * * *NOT* thread safe. */ - static PRStatus InitStatics() - { - PR_NewThreadPrivateIndex(&sResourceAcqnChainFrontTPI, 0); - sDeadlockDetector = new DDT(); - if (!sDeadlockDetector) { - NS_RUNTIMEABORT("can't allocate deadlock detector"); - } - return PR_SUCCESS; - } + static PRStatus InitStatics(); /** * Shutdown @@ -323,11 +264,7 @@ private: * * *NOT* thread safe. */ - static void Shutdown() - { - delete sDeadlockDetector; - sDeadlockDetector = 0; - } + static void Shutdown(); # ifdef MOZILLA_INTERNAL_API // so it can call BlockingResourceBase::Shutdown() diff --git a/xpcom/glue/DeadlockDetector.h b/xpcom/glue/DeadlockDetector.h index 355f535eff4d..3763b34a73a0 100644 --- a/xpcom/glue/DeadlockDetector.h +++ b/xpcom/glue/DeadlockDetector.h @@ -65,32 +65,7 @@ template class DeadlockDetector { public: - /** - * ResourceAcquisition - * Consists simply of a resource and the calling context from - * which it was acquired. We pack this information together so - * that it can be returned back to the caller when a potential - * deadlock has been found. - */ - struct ResourceAcquisition - { - const T* mResource; - - explicit ResourceAcquisition(const T* aResource) - : mResource(aResource) - { - } - ResourceAcquisition(const ResourceAcquisition& aFrom) - : mResource(aFrom.mResource) - { - } - ResourceAcquisition& operator=(const ResourceAcquisition& aFrom) - { - mResource = aFrom.mResource; - return *this; - } - }; - typedef nsTArray ResourceAcquisitionArray; + typedef nsTArray ResourceAcquisitionArray; private: struct OrderingEntry; @@ -124,7 +99,6 @@ private: size_t n = aMallocSizeOf(this); n += mOrderedLT.SizeOfExcludingThis(aMallocSizeOf); n += mExternalRefs.SizeOfExcludingThis(aMallocSizeOf); - n += mResource->SizeOfIncludingThis(aMallocSizeOf); return n; } @@ -202,13 +176,13 @@ public: * * @param aResource Resource to make deadlock detector aware of. */ - void Add(T* aResource) + void Add(const T* aResource) { PRAutoLock _(mLock); mOrdering.Put(aResource, new OrderingEntry(aResource)); } - void Remove(T* aResource) + void Remove(const T* aResource) { PRAutoLock _(mLock); @@ -228,7 +202,6 @@ public: // Now the entry can be safely removed. mOrdering.Remove(aResource); - delete aResource; } /** @@ -278,8 +251,8 @@ public: if (!cycle) { NS_RUNTIMEABORT("can't allocate dep. cycle array"); } - cycle->AppendElement(ResourceAcquisition(current->mResource)); - cycle->AppendElement(ResourceAcquisition(aProposed)); + cycle->AppendElement(current->mResource); + cycle->AppendElement(aProposed); return cycle; } if (InTransitiveClosure(current, proposed)) { @@ -294,7 +267,7 @@ public: // right conditions. ResourceAcquisitionArray* cycle = GetDeductionChain(proposed, current); // show how acquiring |aProposed| would complete the cycle - cycle->AppendElement(ResourceAcquisition(aProposed)); + cycle->AppendElement(aProposed); return cycle; } // |aLast|, |aProposed| are unordered according to our @@ -354,7 +327,7 @@ public: if (!chain) { NS_RUNTIMEABORT("can't allocate dep. cycle array"); } - chain->AppendElement(ResourceAcquisition(aStart->mResource)); + chain->AppendElement(aStart->mResource); NS_ASSERTION(GetDeductionChain_Helper(aStart, aTarget, chain), "GetDeductionChain called when there's no deadlock"); @@ -368,14 +341,14 @@ public: ResourceAcquisitionArray* aChain) { if (aStart->mOrderedLT.BinaryIndexOf(aTarget) != NoIndex) { - aChain->AppendElement(ResourceAcquisition(aTarget->mResource)); + aChain->AppendElement(aTarget->mResource); return true; } index_type i = 0; size_type len = aStart->mOrderedLT.Length(); for (const OrderingEntry* const* it = aStart->mOrderedLT.Elements(); i < len; ++i, ++it) { - aChain->AppendElement(ResourceAcquisition((*it)->mResource)); + aChain->AppendElement((*it)->mResource); if (GetDeductionChain_Helper(*it, aTarget, aChain)) { return true; } diff --git a/xpcom/glue/tests/gtest/TestGCPostBarriers.cpp b/xpcom/glue/tests/gtest/TestGCPostBarriers.cpp index d7a57efecc07..8599fba1ed40 100644 --- a/xpcom/glue/tests/gtest/TestGCPostBarriers.cpp +++ b/xpcom/glue/tests/gtest/TestGCPostBarriers.cpp @@ -28,7 +28,7 @@ TraceArray(JSTracer* trc, void* data) { ArrayT* array = static_cast(data); for (unsigned i = 0; i < array->Length(); ++i) - JS_CallHeapObjectTracer(trc, &array->ElementAt(i), "array-element"); + JS_CallObjectTracer(trc, &array->ElementAt(i), "array-element"); } /*