diff --git a/accessible/base/DocManager.h b/accessible/base/DocManager.h index 626d9391d3b9..ab0944c2314a 100644 --- a/accessible/base/DocManager.h +++ b/accessible/base/DocManager.h @@ -87,6 +87,9 @@ public: */ static void RemoteDocAdded(DocAccessibleParent* aDoc); + static const nsTArray* TopLevelRemoteDocs() + { return sRemoteDocuments; } + #ifdef DEBUG bool IsProcessingRefreshDriverNotification() const; #endif diff --git a/accessible/ipc/DocAccessibleParent.h b/accessible/ipc/DocAccessibleParent.h index f905ea603a58..80402f979e84 100644 --- a/accessible/ipc/DocAccessibleParent.h +++ b/accessible/ipc/DocAccessibleParent.h @@ -123,6 +123,10 @@ public: const ProxyAccessible* GetAccessible(uintptr_t aID) const { return const_cast(this)->GetAccessible(aID); } + size_t ChildDocCount() const { return mChildDocs.Length(); } + const DocAccessibleParent* ChildDocAt(size_t aIdx) const + { return mChildDocs[aIdx]; } + private: class ProxyEntry : public PLDHashEntryHdr diff --git a/accessible/windows/msaa/AccessibleWrap.cpp b/accessible/windows/msaa/AccessibleWrap.cpp index 30d8994cfe5b..1273a783fc54 100644 --- a/accessible/windows/msaa/AccessibleWrap.cpp +++ b/accessible/windows/msaa/AccessibleWrap.cpp @@ -1412,6 +1412,27 @@ GetAccessibleInSubtree(DocAccessible* aDoc, uint32_t aID) } #endif +static AccessibleWrap* +GetProxiedAccessibleInSubtree(const DocAccessibleParent* aDoc, uint32_t aID) +{ + auto wrapper = static_cast(WrapperFor(aDoc)); + AccessibleWrap* child = wrapper->GetAccessibleByID(aID); + if (child) { + return child; + } + + size_t childDocs = aDoc->ChildDocCount(); + for (size_t i = 0; i < childDocs; i++) { + const DocAccessibleParent* childDoc = aDoc->ChildDocAt(i); + child = GetProxiedAccessibleInSubtree(childDoc, aID); + if (child) { + return child; + } + } + + return nullptr; +} + Accessible* AccessibleWrap::GetXPAccessibleFor(const VARIANT& aVarChild) { @@ -1422,33 +1443,32 @@ AccessibleWrap::GetXPAccessibleFor(const VARIANT& aVarChild) if (aVarChild.lVal == CHILDID_SELF) return this; - if (IsProxy()) { - if (Proxy()->MustPruneChildren()) - return nullptr; - - if (aVarChild.lVal > 0) - return WrapperFor(Proxy()->ChildAt(aVarChild.lVal - 1)); - - // XXX Don't implement negative child ids for now because annoying, and - // doesn't seem to be speced. + if (IsProxy() ? Proxy()->MustPruneChildren() : nsAccUtils::MustPrune(this)) { return nullptr; } - if (nsAccUtils::MustPrune(this)) - return nullptr; + if (aVarChild.lVal > 0) { + // Gecko child indices are 0-based in contrast to indices used in MSAA. + if (IsProxy()) { + return WrapperFor(Proxy()->ChildAt(aVarChild.lVal - 1)); + } else { + return GetChildAt(aVarChild.lVal - 1); + } + } // If lVal negative then it is treated as child ID and we should look for // accessible through whole accessible subtree including subdocuments. // Otherwise we treat lVal as index in parent. - - if (aVarChild.lVal < 0) { - // Convert child ID to unique ID. + // Convert child ID to unique ID. + // First handle the case that both this accessible and the id'd one are in + // this process. + if (!IsProxy()) { void* uniqueID = reinterpret_cast(-aVarChild.lVal); DocAccessible* document = Document(); Accessible* child = #ifdef _WIN64 - GetAccessibleInSubtree(document, static_cast(aVarChild.lVal)); + GetAccessibleInSubtree(document, static_cast(aVarChild.lVal)); #else document->GetAccessibleByUniqueIDInSubtree(uniqueID); #endif @@ -1466,12 +1486,65 @@ AccessibleWrap::GetXPAccessibleFor(const VARIANT& aVarChild) parent = parent->Parent(); } + } + + // Now see about the case that both this accessible and the target one are + // proxied. + uint32_t id = aVarChild.lVal; + if (IsProxy()) { + DocAccessibleParent* proxyDoc = Proxy()->Document(); + AccessibleWrap* wrapper = GetProxiedAccessibleInSubtree(proxyDoc, id); + MOZ_ASSERT(wrapper->IsProxy()); + + ProxyAccessible* parent = wrapper->Proxy(); + while (parent && parent != proxyDoc) { + if (parent == this->Proxy()) { + return wrapper; + } + + parent = parent->Parent(); + } return nullptr; } - // Gecko child indices are 0-based in contrast to indices used in MSAA. - return GetChildAt(aVarChild.lVal - 1); + // Finally we need to handle the case that this accessible is in the main + // process, but the target is proxied. This is the case when the target + // accessible is in a child document of this one. + DocAccessibleParent* proxyDoc = nullptr; + DocAccessible* doc = Document(); + const nsTArray* remoteDocs = + DocManager::TopLevelRemoteDocs(); + if (!remoteDocs) { + return nullptr; + } + + size_t docCount = remoteDocs->Length(); + for (size_t i = 0; i < docCount; i++) { + Accessible* outerDoc = remoteDocs->ElementAt(i)->OuterDocOfRemoteBrowser(); + if (!outerDoc) { + continue; + } + + if (outerDoc->Document() != doc) { + continue; + } + + Accessible* parent = outerDoc; + while (parent && parent != doc) { + if (parent == this) { + AccessibleWrap* proxyWrapper = + GetProxiedAccessibleInSubtree(remoteDocs->ElementAt(i), id); + if (proxyWrapper) { + return proxyWrapper; + } + } + + parent = parent->Parent(); + } + } + + return nullptr; } void diff --git a/accessible/windows/msaa/AccessibleWrap.h b/accessible/windows/msaa/AccessibleWrap.h index fc0b8bedab32..c35bd9eb8628 100644 --- a/accessible/windows/msaa/AccessibleWrap.h +++ b/accessible/windows/msaa/AccessibleWrap.h @@ -232,7 +232,7 @@ protected: }; static inline AccessibleWrap* -WrapperFor(ProxyAccessible* aProxy) +WrapperFor(const ProxyAccessible* aProxy) { return reinterpret_cast(aProxy->GetWrapper()); } diff --git a/devtools/shared/heapsnapshot/HeapSnapshot.cpp b/devtools/shared/heapsnapshot/HeapSnapshot.cpp index 761756b76899..a0ef56ab1ff4 100644 --- a/devtools/shared/heapsnapshot/HeapSnapshot.cpp +++ b/devtools/shared/heapsnapshot/HeapSnapshot.cpp @@ -12,7 +12,7 @@ #include "js/Debug.h" #include "js/TypeDecls.h" #include "js/UbiNodeCensus.h" -#include "js/UbiNodeTraverse.h" +#include "js/UbiNodeBreadthFirst.h" #include "mozilla/Attributes.h" #include "mozilla/devtools/AutoMemMap.h" #include "mozilla/devtools/CoreDump.pb.h" diff --git a/devtools/shared/heapsnapshot/tests/gtest/moz.build b/devtools/shared/heapsnapshot/tests/gtest/moz.build index 7909a43b0253..14f7fa6b1040 100644 --- a/devtools/shared/heapsnapshot/tests/gtest/moz.build +++ b/devtools/shared/heapsnapshot/tests/gtest/moz.build @@ -24,6 +24,6 @@ UNIFIED_SOURCES = [ # THE MOCK_METHOD2 macro from gtest triggers this clang warning and it's hard # to work around, so we just ignore it. if CONFIG['CLANG_CXX']: - CXXFLAGS += ['-Wno-error=inconsistent-missing-override'] + CXXFLAGS += ['-Wno-inconsistent-missing-override'] FINAL_LIBRARY = 'xul-gtest' diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index e83797e5181c..61bc1c1e05c6 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -1508,7 +1508,7 @@ nsDocShell::LoadURI(nsIURI* aURI, } if (!owner && !inheritOwner && !ownerIsExplicit) { // See if there's system or chrome JS code running - inheritOwner = nsContentUtils::IsCallerChrome(); + inheritOwner = nsContentUtils::LegacyIsCallerChromeOrNativeCode(); } if (aLoadFlags & LOAD_FLAGS_DISALLOW_INHERIT_OWNER) { diff --git a/dom/base/BarProps.cpp b/dom/base/BarProps.cpp index 6fb657285b04..4d0e36bfe308 100644 --- a/dom/base/BarProps.cpp +++ b/dom/base/BarProps.cpp @@ -276,7 +276,7 @@ ScrollbarsProp::GetVisible(ErrorResult& aRv) void ScrollbarsProp::SetVisible(bool aVisible, ErrorResult& aRv) { - if (!nsContentUtils::IsCallerChrome()) { + if (!nsContentUtils::LegacyIsCallerChromeOrNativeCode()) { return; } diff --git a/dom/base/File.cpp b/dom/base/File.cpp index b74485dccebd..bed909d8310e 100644 --- a/dom/base/File.cpp +++ b/dom/base/File.cpp @@ -705,7 +705,7 @@ BlobImplBase::GetMozFullPath(nsAString& aFileName, ErrorResult& aRv) const aFileName.Truncate(); if (NS_IsMainThread()) { - if (nsContentUtils::IsCallerChrome()) { + if (nsContentUtils::LegacyIsCallerChromeOrNativeCode()) { GetMozFullPathInternal(aFileName, aRv); } diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index b20ecd57c084..66e4bd13b395 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -1955,9 +1955,6 @@ nsContentUtils::CheckSameOrigin(const nsINode* aTrustedNode, { MOZ_ASSERT(aTrustedNode); MOZ_ASSERT(unTrustedNode); - if (IsCallerChrome()) { - return NS_OK; - } /* * Get hold of each node's principal @@ -2713,7 +2710,7 @@ nsContentUtils::SubjectPrincipal() MOZ_ASSERT(NS_IsMainThread()); JSContext* cx = GetCurrentJSContext(); if (!cx) { - return GetSystemPrincipal(); + MOZ_CRASH("Accessing the Subject Principal without an AutoJSAPI on the stack is forbidden"); } JSCompartment *compartment = js::GetContextCompartment(cx); diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index ad584b933bed..29fdf9c1f9d3 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -195,6 +195,47 @@ public: static bool ThreadsafeIsCallerChrome(); static bool IsCallerContentXBL(); + // In the traditional Gecko architecture, both C++ code and untrusted JS code + // needed to rely on the same XPCOM method/getter/setter to get work done. + // This required lots of security checks in the various exposed methods, which + // in turn created difficulty in determining whether the caller was script + // (whose access needed to be checked) and internal C++ platform code (whose + // access did not need to be checked). To address this problem, Gecko had a + // convention whereby the absence of script on the stack was interpretted as + // "System Caller" and always granted unfettered access. + // + // Unfortunately, this created a bunch of footguns. For example, when the + // implementation of a DOM method wanted to perform a privileged + // sub-operation, it needed to "hide" the presence of script on the stack in + // order for that sub-operation to be allowed. Additionally, if script could + // trigger an API entry point to be invoked in some asynchronous way without + // script on the stack, it could potentially perform privilege escalation. + // + // In the modern world, untrusted script should interact with the platform + // exclusively over WebIDL APIs, and platform code has a lot more flexibility + // in deciding whether or not to use XPCOM. This gives us the flexibility to + // do something better. + // + // Going forward, APIs should be designed such that any security checks that + // ask the question "is my caller allowed to do this?" should live in WebIDL + // API entry points, with a separate method provided for internal callers + // that just want to get the job done. + // + // To enforce this and catch bugs, nsContentUtils::SubjectPrincipal will crash + // if it is invoked without script on the stack. To land that transition, it + // was necessary to go through and whitelist a bunch of callers that were + // depending on the old behavior. Those callers should be fixed up, and these + // methods should not be used by new code without review from bholley or bz. + static bool LegacyIsCallerNativeCode() { return !GetCurrentJSContext(); } + static bool LegacyIsCallerChromeOrNativeCode() { return LegacyIsCallerNativeCode() || IsCallerChrome(); } + static nsIPrincipal* SubjectPrincipalOrSystemIfNativeCaller() + { + if (!GetCurrentJSContext()) { + return GetSystemPrincipal(); + } + return SubjectPrincipal(); + } + static bool IsImageSrcSetDisabled(); static bool LookupBindingMember(JSContext* aCx, nsIContent *aContent, diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 153a17bb0a20..d0bb56f8fa81 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -410,7 +410,7 @@ nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin, nsIDOMElement* aElement, uint32_t aPriority) { - MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome()); + MOZ_RELEASE_ASSERT(nsContentUtils::LegacyIsCallerChromeOrNativeCode()); nsIPresShell* presShell = GetPresShell(); if (!presShell) { @@ -481,7 +481,7 @@ nsDOMWindowUtils::SetDisplayPortBaseForElement(int32_t aX, NS_IMETHODIMP nsDOMWindowUtils::SetResolution(float aResolution) { - if (!nsContentUtils::IsCallerChrome()) { + if (!nsContentUtils::LegacyIsCallerChromeOrNativeCode()) { return NS_ERROR_DOM_SECURITY_ERR; } @@ -547,7 +547,7 @@ nsDOMWindowUtils::GetIsResolutionSet(bool* aIsResolutionSet) { NS_IMETHODIMP nsDOMWindowUtils::SetIsFirstPaint(bool aIsFirstPaint) { - if (!nsContentUtils::IsCallerChrome()) { + if (!nsContentUtils::LegacyIsCallerChromeOrNativeCode()) { return NS_ERROR_DOM_SECURITY_ERR; } @@ -562,7 +562,7 @@ nsDOMWindowUtils::SetIsFirstPaint(bool aIsFirstPaint) NS_IMETHODIMP nsDOMWindowUtils::GetIsFirstPaint(bool *aIsFirstPaint) { - if (!nsContentUtils::IsCallerChrome()) { + if (!nsContentUtils::LegacyIsCallerChromeOrNativeCode()) { return NS_ERROR_DOM_SECURITY_ERR; } @@ -577,7 +577,7 @@ nsDOMWindowUtils::GetIsFirstPaint(bool *aIsFirstPaint) NS_IMETHODIMP nsDOMWindowUtils::GetPresShellId(uint32_t *aPresShellId) { - MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome()); + MOZ_RELEASE_ASSERT(nsContentUtils::LegacyIsCallerChromeOrNativeCode()); nsIPresShell* presShell = GetPresShell(); if (presShell) { @@ -1036,7 +1036,7 @@ nsDOMWindowUtils::SendNativeKeyEvent(int32_t aNativeKeyboardLayout, const nsAString& aUnmodifiedCharacters, nsIObserver* aObserver) { - MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome()); + MOZ_RELEASE_ASSERT(nsContentUtils::LegacyIsCallerChromeOrNativeCode()); // get the widget to send the event to nsCOMPtr widget = GetWidget(); @@ -1722,7 +1722,9 @@ nsDOMWindowUtils::GetBoundsWithoutFlushing(nsIDOMElement *aElement, NS_IMETHODIMP nsDOMWindowUtils::GetRootBounds(nsIDOMClientRect** aResult) { - MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome()); + // Unfortunately, this is called from AndroidBridge.cpp and the logic here is + // nontrivial, so we need to allow non-scripted callers. + MOZ_RELEASE_ASSERT(nsContentUtils::LegacyIsCallerChromeOrNativeCode()); nsIDocument* doc = GetDocument(); NS_ENSURE_STATE(doc); @@ -3150,7 +3152,7 @@ nsDOMWindowUtils::GetPlugins(JSContext* cx, JS::MutableHandle aPlugin NS_IMETHODIMP nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aHeight) { - MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome()); + MOZ_RELEASE_ASSERT(nsContentUtils::LegacyIsCallerChromeOrNativeCode()); if (!(aWidth >= 0.0 && aHeight >= 0.0)) { return NS_ERROR_ILLEGAL_VALUE; diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp index 743abe646395..431d4da4f22a 100644 --- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -1221,7 +1221,7 @@ nsFocusManager::SetFocusInner(nsIContent* aNewContent, int32_t aFlags, } bool subsumes = false; focusedPrincipal->Subsumes(newPrincipal, &subsumes); - if (!subsumes && !nsContentUtils::IsCallerChrome()) { + if (!subsumes && !nsContentUtils::LegacyIsCallerChromeOrNativeCode()) { NS_WARNING("Not allowed to focus the new window!"); return; } @@ -1275,7 +1275,7 @@ nsFocusManager::SetFocusInner(nsIContent* aNewContent, int32_t aFlags, // * isn't called by trusted event (i.e., called by untrusted event or by js) // * the focus is moved to another document's element // we need to check the permission. - if (sendFocusEvent && mFocusedContent && + if (sendFocusEvent && mFocusedContent && !nsContentUtils::LegacyIsCallerNativeCode() && mFocusedContent->OwnerDoc() != aNewContent->OwnerDoc()) { // If the caller cannot access the current focused node, the caller should // not be able to steal focus from it. E.g., When the current focused node @@ -1453,8 +1453,10 @@ nsFocusManager::AdjustWindowFocus(nsPIDOMWindow* aWindow, // When aCheckPermission is true, we should check whether the caller can // access the window or not. If it cannot access, we should stop the // adjusting. - if (aCheckPermission && !nsContentUtils::CanCallerAccess(window)) + if (aCheckPermission && !nsContentUtils::LegacyIsCallerNativeCode() && + !nsContentUtils::CanCallerAccess(window)) { break; + } window->SetFocusedNode(frameElement); } diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index dda717cd2fdf..f2398923c51c 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -2085,7 +2085,7 @@ nsGlobalWindow::SetInitialPrincipalToSubject() MOZ_ASSERT(IsOuterWindow()); // First, grab the subject principal. - nsCOMPtr newWindowPrincipal = nsContentUtils::SubjectPrincipal(); + nsCOMPtr newWindowPrincipal = nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller(); // Now, if we're about to use the system principal or an nsExpandedPrincipal, // make sure we're not using it for a content docshell. @@ -4549,7 +4549,7 @@ nsGlobalWindow::GetOpenerWindowOuter() nsGlobalWindow* win = static_cast(opener.get()); // First, check if we were called from a privileged chrome script - if (nsContentUtils::IsCallerChrome()) { + if (nsContentUtils::LegacyIsCallerChromeOrNativeCode()) { // Catch the case where we're chrome but the opener is not... if (GetPrincipal() == nsContentUtils::GetSystemPrincipal() && win->GetPrincipal() != nsContentUtils::GetSystemPrincipal()) { @@ -6513,7 +6513,7 @@ nsGlobalWindow::SetFullscreenInternal(FullscreenReason aReason, // Only chrome can change our fullscreen mode. Otherwise, the state // can only be changed for DOM fullscreen. - if (aReason == eForFullscreenMode && !nsContentUtils::IsCallerChrome()) { + if (aReason == eForFullscreenMode && !nsContentUtils::LegacyIsCallerChromeOrNativeCode()) { return NS_OK; } @@ -8249,7 +8249,7 @@ bool nsGlobalWindow::CanSetProperty(const char *aPrefName) { // Chrome can set any property. - if (nsContentUtils::IsCallerChrome()) { + if (nsContentUtils::LegacyIsCallerChromeOrNativeCode()) { return true; } @@ -10054,6 +10054,7 @@ nsGlobalWindow::AddSystemEventListener(const nsAString& aType, "explicit by making optional_argc non-zero."); if (IsOuterWindow() && mInnerWindow && + !nsContentUtils::LegacyIsCallerNativeCode() && !nsContentUtils::CanCallerAccess(mInnerWindow)) { return NS_ERROR_DOM_SECURITY_ERR; } @@ -12181,7 +12182,7 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName, nsIPrincipal::APP_STATUS_INSTALLED; } - const bool checkForPopup = !nsContentUtils::IsCallerChrome() && + const bool checkForPopup = !nsContentUtils::LegacyIsCallerChromeOrNativeCode() && !isApp && !aDialog && !WindowExists(aName, !aCalledNoScript); // Note: it's very important that this be an nsXPIDLCString, since we want diff --git a/dom/base/nsObjectLoadingContent.cpp b/dom/base/nsObjectLoadingContent.cpp index 43feb0da6133..26737ec7551f 100644 --- a/dom/base/nsObjectLoadingContent.cpp +++ b/dom/base/nsObjectLoadingContent.cpp @@ -1156,7 +1156,7 @@ nsObjectLoadingContent::OnStopRequest(nsIRequest *aRequest, } } - NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); + NS_ENSURE_TRUE(nsContentUtils::LegacyIsCallerChromeOrNativeCode(), NS_ERROR_NOT_AVAILABLE); if (aRequest != mChannel) { return NS_BINDING_ABORTED; @@ -1183,7 +1183,7 @@ nsObjectLoadingContent::OnDataAvailable(nsIRequest *aRequest, nsIInputStream *aInputStream, uint64_t aOffset, uint32_t aCount) { - NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE); + NS_ENSURE_TRUE(nsContentUtils::LegacyIsCallerChromeOrNativeCode(), NS_ERROR_NOT_AVAILABLE); if (aRequest != mChannel) { return NS_BINDING_ABORTED; @@ -2825,7 +2825,8 @@ nsObjectLoadingContent::ScriptRequestPluginInstance(JSContext* aCx, // so the ensuing expression is short-circuited. MOZ_ASSERT_IF(nsContentUtils::GetCurrentJSContext(), aCx == nsContentUtils::GetCurrentJSContext()); - bool callerIsContentJS = (!nsContentUtils::IsCallerChrome() && + bool callerIsContentJS = (nsContentUtils::GetCurrentJSContext() && + !nsContentUtils::IsCallerChrome() && !nsContentUtils::IsCallerContentXBL() && JS_IsRunning(aCx)); diff --git a/dom/base/nsRange.cpp b/dom/base/nsRange.cpp index 44ac1bbc08ec..9f0b0376c17c 100644 --- a/dom/base/nsRange.cpp +++ b/dom/base/nsRange.cpp @@ -1138,7 +1138,8 @@ nsRange::IsValidBoundary(nsINode* aNode) void nsRange::SetStart(nsINode& aNode, uint32_t aOffset, ErrorResult& aRv) { - if (!nsContentUtils::CanCallerAccess(&aNode)) { + if (!nsContentUtils::LegacyIsCallerNativeCode() && + !nsContentUtils::CanCallerAccess(&aNode)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } @@ -1190,7 +1191,8 @@ nsRange::SetStart(nsINode* aParent, int32_t aOffset) void nsRange::SetStartBefore(nsINode& aNode, ErrorResult& aRv) { - if (!nsContentUtils::CanCallerAccess(&aNode)) { + if (!nsContentUtils::LegacyIsCallerNativeCode() && + !nsContentUtils::CanCallerAccess(&aNode)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } @@ -1215,7 +1217,8 @@ nsRange::SetStartBefore(nsIDOMNode* aSibling) void nsRange::SetStartAfter(nsINode& aNode, ErrorResult& aRv) { - if (!nsContentUtils::CanCallerAccess(&aNode)) { + if (!nsContentUtils::LegacyIsCallerNativeCode() && + !nsContentUtils::CanCallerAccess(&aNode)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } @@ -1240,7 +1243,8 @@ nsRange::SetStartAfter(nsIDOMNode* aSibling) void nsRange::SetEnd(nsINode& aNode, uint32_t aOffset, ErrorResult& aRv) { - if (!nsContentUtils::CanCallerAccess(&aNode)) { + if (!nsContentUtils::LegacyIsCallerNativeCode() && + !nsContentUtils::CanCallerAccess(&aNode)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } @@ -1291,7 +1295,8 @@ nsRange::SetEnd(nsINode* aParent, int32_t aOffset) void nsRange::SetEndBefore(nsINode& aNode, ErrorResult& aRv) { - if (!nsContentUtils::CanCallerAccess(&aNode)) { + if (!nsContentUtils::LegacyIsCallerNativeCode() && + !nsContentUtils::CanCallerAccess(&aNode)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } @@ -1316,7 +1321,8 @@ nsRange::SetEndBefore(nsIDOMNode* aSibling) void nsRange::SetEndAfter(nsINode& aNode, ErrorResult& aRv) { - if (!nsContentUtils::CanCallerAccess(&aNode)) { + if (!nsContentUtils::LegacyIsCallerNativeCode() && + !nsContentUtils::CanCallerAccess(&aNode)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } @@ -1367,7 +1373,8 @@ nsRange::SelectNode(nsIDOMNode* aN) void nsRange::SelectNode(nsINode& aNode, ErrorResult& aRv) { - if (!nsContentUtils::CanCallerAccess(&aNode)) { + if (!nsContentUtils::LegacyIsCallerNativeCode() && + !nsContentUtils::CanCallerAccess(&aNode)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } @@ -1403,7 +1410,8 @@ nsRange::SelectNodeContents(nsIDOMNode* aN) void nsRange::SelectNodeContents(nsINode& aNode, ErrorResult& aRv) { - if (!nsContentUtils::CanCallerAccess(&aNode)) { + if (!nsContentUtils::LegacyIsCallerNativeCode() && + !nsContentUtils::CanCallerAccess(&aNode)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } @@ -2451,7 +2459,8 @@ nsRange::InsertNode(nsIDOMNode* aNode) void nsRange::InsertNode(nsINode& aNode, ErrorResult& aRv) { - if (!nsContentUtils::CanCallerAccess(&aNode)) { + if (!nsContentUtils::LegacyIsCallerNativeCode() && + !nsContentUtils::CanCallerAccess(&aNode)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } @@ -2548,7 +2557,8 @@ nsRange::SurroundContents(nsIDOMNode* aNewParent) void nsRange::SurroundContents(nsINode& aNewParent, ErrorResult& aRv) { - if (!nsContentUtils::CanCallerAccess(&aNewParent)) { + if (!nsContentUtils::LegacyIsCallerNativeCode() && + !nsContentUtils::CanCallerAccess(&aNewParent)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } diff --git a/dom/base/nsXMLHttpRequest.cpp b/dom/base/nsXMLHttpRequest.cpp index ffa4b097e238..fabadd85c4b9 100644 --- a/dom/base/nsXMLHttpRequest.cpp +++ b/dom/base/nsXMLHttpRequest.cpp @@ -2700,8 +2700,7 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable& aBody) nsAutoCString contentType; if (NS_FAILED(httpChannel-> GetRequestHeader(NS_LITERAL_CSTRING("Content-Type"), - contentType)) || - contentType.IsEmpty()) { + contentType))) { contentType = defaultContentType; if (!charset.IsEmpty()) { diff --git a/dom/bindings/CallbackObject.cpp b/dom/bindings/CallbackObject.cpp index e119d99a71bc..5781419018c6 100644 --- a/dom/bindings/CallbackObject.cpp +++ b/dom/bindings/CallbackObject.cpp @@ -67,7 +67,7 @@ CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback, // do anything that might perturb the relevant state. nsIPrincipal* webIDLCallerPrincipal = nullptr; if (aIsJSImplementedWebIDL) { - webIDLCallerPrincipal = nsContentUtils::SubjectPrincipal(); + webIDLCallerPrincipal = nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller(); } // We need to produce a useful JSContext here. Ideally one that the callback diff --git a/dom/camera/CameraPreviewMediaStream.cpp b/dom/camera/CameraPreviewMediaStream.cpp index 56ff90f8dbdd..e9490d77f3fd 100644 --- a/dom/camera/CameraPreviewMediaStream.cpp +++ b/dom/camera/CameraPreviewMediaStream.cpp @@ -137,7 +137,7 @@ CameraPreviewMediaStream::RateLimit(bool aLimit) } void -CameraPreviewMediaStream::SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage) +CameraPreviewMediaStream::SetCurrentFrame(const gfx::IntSize& aIntrinsicSize, Image* aImage) { { MutexAutoLock lock(mMutex); diff --git a/dom/camera/CameraPreviewMediaStream.h b/dom/camera/CameraPreviewMediaStream.h index 50de9fef7f1a..f258c36b584e 100644 --- a/dom/camera/CameraPreviewMediaStream.h +++ b/dom/camera/CameraPreviewMediaStream.h @@ -58,7 +58,7 @@ public: void Invalidate(); // Call these on any thread. - void SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage); + void SetCurrentFrame(const gfx::IntSize& aIntrinsicSize, Image* aImage); void ClearCurrentFrame(); void RateLimit(bool aLimit); diff --git a/dom/camera/DOMCameraControlListener.cpp b/dom/camera/DOMCameraControlListener.cpp index 684b6b769650..757eff76cb0e 100644 --- a/dom/camera/DOMCameraControlListener.cpp +++ b/dom/camera/DOMCameraControlListener.cpp @@ -311,7 +311,7 @@ DOMCameraControlListener::OnNewPreviewFrame(layers::Image* aImage, uint32_t aWid { DOM_CAMERA_LOGI("OnNewPreviewFrame: got %d x %d frame\n", aWidth, aHeight); - mStream->SetCurrentFrame(gfxIntSize(aWidth, aHeight), aImage); + mStream->SetCurrentFrame(gfx::IntSize(aWidth, aHeight), aImage); return true; } diff --git a/dom/canvas/CanvasImageCache.cpp b/dom/canvas/CanvasImageCache.cpp index 79a4ee6d9045..a4f66bda1061 100644 --- a/dom/canvas/CanvasImageCache.cpp +++ b/dom/canvas/CanvasImageCache.cpp @@ -53,7 +53,7 @@ struct ImageCacheEntryData { // Value nsCOMPtr mRequest; RefPtr mSourceSurface; - gfxIntSize mSize; + IntSize mSize; nsExpirationState mState; }; @@ -237,7 +237,7 @@ CanvasImageCache::NotifyDrawImage(Element* aImage, HTMLCanvasElement* aCanvas, imgIRequest* aRequest, SourceSurface* aSource, - const gfxIntSize& aSize) + const IntSize& aSize) { if (!gImageCache) { gImageCache = new ImageCache(); diff --git a/dom/canvas/CanvasImageCache.h b/dom/canvas/CanvasImageCache.h index 6b5fb3cfaa24..836368c6c3b3 100644 --- a/dom/canvas/CanvasImageCache.h +++ b/dom/canvas/CanvasImageCache.h @@ -33,7 +33,7 @@ public: dom::HTMLCanvasElement* aCanvas, imgIRequest* aRequest, SourceSurface* aSource, - const gfxIntSize& aSize); + const gfx::IntSize& aSize); /** * Check whether aImage has recently been drawn into aCanvas. If we return diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index 1f0667527710..9f4156b6dfbf 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -4787,7 +4787,7 @@ CanvasRenderingContext2D::DrawWindow(nsGlobalWindow& window, double x, { // protect against too-large surfaces that will cause allocation // or overflow issues - if (!gfxASurface::CheckSurfaceSize(gfxIntSize(int32_t(w), int32_t(h)), + if (!gfxASurface::CheckSurfaceSize(gfx::IntSize(int32_t(w), int32_t(h)), 0xffff)) { error.Throw(NS_ERROR_FAILURE); return; @@ -4976,7 +4976,7 @@ CanvasRenderingContext2D::AsyncDrawXULElement(nsXULElement& elem, // protect against too-large surfaces that will cause allocation // or overflow issues - if (!gfxASurface::CheckSurfaceSize(gfxIntSize(w, h), 0xffff)) { + if (!gfxASurface::CheckSurfaceSize(gfx::IntSize(w, h), 0xffff)) { error.Throw(NS_ERROR_FAILURE); return; } @@ -5401,7 +5401,7 @@ CanvasRenderingContext2D::PutImageData_explicit(int32_t x, int32_t y, uint32_t w uint32_t copyWidth = dirtyRect.Width(); uint32_t copyHeight = dirtyRect.Height(); - nsRefPtr imgsurf = new gfxImageSurface(gfxIntSize(copyWidth, copyHeight), + nsRefPtr imgsurf = new gfxImageSurface(gfx::IntSize(copyWidth, copyHeight), gfxImageFormat::ARGB32, false); if (!imgsurf || imgsurf->CairoStatus()) { diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp index 984d8e4a4f95..f86094c60b20 100644 --- a/dom/canvas/WebGLContext.cpp +++ b/dom/canvas/WebGLContext.cpp @@ -217,6 +217,7 @@ WebGLContext::WebGLContext() , mBypassShaderValidation(false) , mGLMaxSamples(1) , mNeedsFakeNoAlpha(false) + , mNeedsFakeNoDepth(false) , mNeedsFakeNoStencil(false) { mGeneration = 0; @@ -253,6 +254,7 @@ WebGLContext::WebGLContext() mDitherEnabled = 1; mRasterizerDiscardEnabled = 0; // OpenGL ES 3.0 spec p244 mScissorTestEnabled = 0; + mDepthTestEnabled = 0; mStencilTestEnabled = 0; // initialize some GL values: we're going to get them from the GL and use them as the sizes of arrays, @@ -543,107 +545,9 @@ HasAcceleratedLayers(const nsCOMPtr& gfxInfo) return false; } -static already_AddRefed -CreateHeadlessNativeGL(CreateContextFlags flags, const nsCOMPtr& gfxInfo, - WebGLContext* webgl) -{ - if (!(flags & CreateContextFlags::FORCE_ENABLE_HARDWARE) && - IsFeatureInBlacklist(gfxInfo, nsIGfxInfo::FEATURE_WEBGL_OPENGL)) - { - webgl->GenerateWarning("Refused to create native OpenGL context" - " because of blacklisting."); - return nullptr; - } - - nsRefPtr gl = gl::GLContextProvider::CreateHeadless(flags); - if (!gl) { - webgl->GenerateWarning("Error during native OpenGL init."); - return nullptr; - } - MOZ_ASSERT(!gl->IsANGLE()); - - return gl.forget(); -} - -// Note that we have a separate call for ANGLE and EGL, even though -// right now, we get ANGLE implicitly by using EGL on Windows. -// Eventually, we want to be able to pick ANGLE-EGL or native EGL. -static already_AddRefed -CreateHeadlessANGLE(CreateContextFlags flags, const nsCOMPtr& gfxInfo, - WebGLContext* webgl) -{ - nsRefPtr gl; - -#ifdef XP_WIN - gl = gl::GLContextProviderEGL::CreateHeadless(flags); - if (!gl) { - webgl->GenerateWarning("Error during ANGLE OpenGL init."); - return nullptr; - } - MOZ_ASSERT(gl->IsANGLE()); -#endif - - return gl.forget(); -} - -static already_AddRefed -CreateHeadlessEGL(CreateContextFlags flags, WebGLContext* webgl) -{ - nsRefPtr gl; - -#ifdef ANDROID - gl = gl::GLContextProviderEGL::CreateHeadless(flags); - if (!gl) { - webgl->GenerateWarning("Error during EGL OpenGL init."); - return nullptr; - } - MOZ_ASSERT(!gl->IsANGLE()); -#endif - - return gl.forget(); -} - -static already_AddRefed -CreateHeadlessGL(CreateContextFlags flags, const nsCOMPtr& gfxInfo, - WebGLContext* webgl) -{ - bool preferEGL = PR_GetEnv("MOZ_WEBGL_PREFER_EGL"); - bool disableANGLE = Preferences::GetBool("webgl.disable-angle", false); - - if (PR_GetEnv("MOZ_WEBGL_FORCE_OPENGL")) - disableANGLE = true; - - if (!webgl->IsWebGL2()) { - flags |= CreateContextFlags::REQUIRE_COMPAT_PROFILE; - } - - nsRefPtr gl; - - if (preferEGL) - gl = CreateHeadlessEGL(flags, webgl); - - if (!gl && !disableANGLE) { - gl = CreateHeadlessANGLE(flags, gfxInfo, webgl); - } - - if (!gl) { - gl = CreateHeadlessNativeGL(flags, gfxInfo, webgl); - } - - return gl.forget(); -} - -// Try to create a dummy offscreen with the given caps. -static bool -CreateOffscreenWithCaps(GLContext* gl, const SurfaceCaps& caps) -{ - gfx::IntSize dummySize(16, 16); - return gl->InitOffscreen(dummySize, caps); -} - static void -PopulateCapFallbackQueue(const SurfaceCaps& baseCaps, - std::queue* out_fallbackCaps) +PopulateCapFallbackQueue(const gl::SurfaceCaps& baseCaps, + std::queue* out_fallbackCaps) { out_fallbackCaps->push(baseCaps); @@ -651,7 +555,7 @@ PopulateCapFallbackQueue(const SurfaceCaps& baseCaps, // The user basically doesn't have to handle if this fails, they // just get reduced quality. if (baseCaps.antialias) { - SurfaceCaps nextCaps(baseCaps); + gl::SurfaceCaps nextCaps(baseCaps); nextCaps.antialias = false; PopulateCapFallbackQueue(nextCaps, out_fallbackCaps); } @@ -660,25 +564,22 @@ PopulateCapFallbackQueue(const SurfaceCaps& baseCaps, // depth. However, the client app will need to handle if this // doesn't work. if (baseCaps.stencil) { - SurfaceCaps nextCaps(baseCaps); + gl::SurfaceCaps nextCaps(baseCaps); nextCaps.stencil = false; PopulateCapFallbackQueue(nextCaps, out_fallbackCaps); } if (baseCaps.depth) { - SurfaceCaps nextCaps(baseCaps); + gl::SurfaceCaps nextCaps(baseCaps); nextCaps.depth = false; PopulateCapFallbackQueue(nextCaps, out_fallbackCaps); } } -static bool -CreateOffscreen(GLContext* gl, const WebGLContextOptions& options, - const nsCOMPtr& gfxInfo, WebGLContext* webgl, - layers::LayersBackend layersBackend, - layers::ISurfaceAllocator* surfAllocator) +static gl::SurfaceCaps +BaseCaps(const WebGLContextOptions& options, WebGLContext* webgl) { - SurfaceCaps baseCaps; + gl::SurfaceCaps baseCaps; baseCaps.color = true; baseCaps.alpha = options.alpha; @@ -691,29 +592,36 @@ CreateOffscreen(GLContext* gl, const WebGLContextOptions& options, if (!baseCaps.alpha) baseCaps.premultAlpha = true; - if (gl->IsANGLE() || - (gl->GetContextType() == GLContextType::GLX && - layersBackend == LayersBackend::LAYERS_OPENGL)) - { - // We can't use no-alpha formats on ANGLE yet because of: - // https://code.google.com/p/angleproject/issues/detail?id=764 - // GLX only supports GL_RGBA pixmaps as well. Since we can't blit from - // an RGB FB to GLX's RGBA FB, force RGBA when surface sharing. - baseCaps.alpha = true; - } - // we should really have this behind a // |gfxPlatform::GetPlatform()->GetScreenDepth() == 16| check, but // for now it's just behind a pref for testing/evaluation. baseCaps.bpp16 = Preferences::GetBool("webgl.prefer-16bpp", false); #ifdef MOZ_WIDGET_GONK - baseCaps.surfaceAllocator = surfAllocator; + do { + auto canvasElement = webgl->GetCanvas(); + auto ownerDoc = canvasElement->OwnerDoc(); + nsIWidget* docWidget = nsContentUtils::WidgetForDocument(ownerDoc); + if (!docWidget) + break; + + layers::LayerManager* layerManager = docWidget->GetLayerManager(); + if (!layerManager) + break; + + // XXX we really want "AsSurfaceAllocator" here for generality + layers::ShadowLayerForwarder* forwarder = layerManager->AsShadowForwarder(); + if (!forwarder) + break; + + baseCaps.surfaceAllocator = static_cast(forwarder); + } while (false); #endif // Done with baseCaps construction. bool forceAllowAA = Preferences::GetBool("webgl.msaa-force", false); + nsCOMPtr gfxInfo = services::GetGfxInfo(); if (!forceAllowAA && IsFeatureInBlacklist(gfxInfo, nsIGfxInfo::FEATURE_WEBGL_MSAA)) { @@ -722,62 +630,149 @@ CreateOffscreen(GLContext* gl, const WebGLContextOptions& options, baseCaps.antialias = false; } - std::queue fallbackCaps; + return baseCaps; +} + +//////////////////////////////////////// + +static already_AddRefed +CreateGLWithEGL(const gl::SurfaceCaps& caps, gl::CreateContextFlags flags, + WebGLContext* webgl) +{ + RefPtr gl; +#ifndef XP_MACOSX // Mac doesn't have GLContextProviderEGL. + gfx::IntSize dummySize(16, 16); + gl = gl::GLContextProviderEGL::CreateOffscreen(dummySize, caps, + flags); + if (!gl) { + webgl->GenerateWarning("Error during EGL OpenGL init."); + return nullptr; + } + + if (gl->IsANGLE()) + return nullptr; +#endif // XP_MACOSX + return gl.forget(); +} + +static already_AddRefed +CreateGLWithANGLE(const gl::SurfaceCaps& caps, gl::CreateContextFlags flags, + WebGLContext* webgl) +{ + RefPtr gl; + +#ifdef XP_WIN + gfx::IntSize dummySize(16, 16); + gl = gl::GLContextProviderEGL::CreateOffscreen(dummySize, caps, flags); + if (!gl) { + webgl->GenerateWarning("Error during ANGLE OpenGL init."); + return nullptr; + } + + if (!gl->IsANGLE()) + return nullptr; +#endif + + return gl.forget(); +} + +static already_AddRefed +CreateGLWithDefault(const gl::SurfaceCaps& caps, gl::CreateContextFlags flags, + WebGLContext* webgl) +{ + nsCOMPtr gfxInfo = services::GetGfxInfo(); + + if (!(flags & CreateContextFlags::FORCE_ENABLE_HARDWARE) && + IsFeatureInBlacklist(gfxInfo, nsIGfxInfo::FEATURE_WEBGL_OPENGL)) + { + webgl->GenerateWarning("Refused to create native OpenGL context because of" + " blacklisting."); + return nullptr; + } + + gfx::IntSize dummySize(16, 16); + RefPtr gl = gl::GLContextProvider::CreateOffscreen(dummySize, caps, flags); + if (!gl) { + webgl->GenerateWarning("Error during native OpenGL init."); + return nullptr; + } + + if (gl->IsANGLE()) + return nullptr; + + return gl.forget(); +} + +//////////////////////////////////////// + +bool +WebGLContext::CreateAndInitGLWith(FnCreateGL_T fnCreateGL, + const gl::SurfaceCaps& baseCaps, + gl::CreateContextFlags flags) +{ + MOZ_ASSERT(!gl); + + std::queue fallbackCaps; PopulateCapFallbackQueue(baseCaps, &fallbackCaps); - bool created = false; + gl = nullptr; while (!fallbackCaps.empty()) { - SurfaceCaps& caps = fallbackCaps.front(); + gl::SurfaceCaps& caps = fallbackCaps.front(); - created = CreateOffscreenWithCaps(gl, caps); - if (created) + gl = fnCreateGL(caps, flags, this); + if (gl) break; fallbackCaps.pop(); } + if (!gl) + return false; - return created; + if (!InitAndValidateGL()) { + gl = nullptr; + return false; + } + + return true; } bool -WebGLContext::CreateOffscreenGL(bool forceEnabled) +WebGLContext::CreateAndInitGL(bool forceEnabled) { - nsCOMPtr gfxInfo = services::GetGfxInfo(); + bool preferEGL = PR_GetEnv("MOZ_WEBGL_PREFER_EGL"); + bool disableANGLE = Preferences::GetBool("webgl.disable-angle", false); - layers::ISurfaceAllocator* surfAllocator = nullptr; -#ifdef MOZ_WIDGET_GONK - nsIWidget* docWidget = nsContentUtils::WidgetForDocument(mCanvasElement->OwnerDoc()); - if (docWidget) { - layers::LayerManager* layerManager = docWidget->GetLayerManager(); - if (layerManager) { - // XXX we really want "AsSurfaceAllocator" here for generality - layers::ShadowLayerForwarder* forwarder = layerManager->AsShadowForwarder(); - if (forwarder) - surfAllocator = static_cast(forwarder); - } + if (PR_GetEnv("MOZ_WEBGL_FORCE_OPENGL")) + disableANGLE = true; + + gl::CreateContextFlags flags = gl::CreateContextFlags::NONE; + if (forceEnabled) flags |= gl::CreateContextFlags::FORCE_ENABLE_HARDWARE; + if (!IsWebGL2()) flags |= gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE; + + const gl::SurfaceCaps baseCaps = BaseCaps(mOptions, this); + + MOZ_ASSERT(!gl); + + if (preferEGL) { + if (CreateAndInitGLWith(CreateGLWithEGL, baseCaps, flags)) + return true; } -#endif - CreateContextFlags flags = forceEnabled ? CreateContextFlags::FORCE_ENABLE_HARDWARE : - CreateContextFlags::NONE; + MOZ_ASSERT(!gl); - gl = CreateHeadlessGL(flags, gfxInfo, this); + if (!disableANGLE) { + if (CreateAndInitGLWith(CreateGLWithANGLE, baseCaps, flags)) + return true; + } - do { - if (!gl) - break; - - if (!CreateOffscreen(gl, mOptions, gfxInfo, this, - GetCompositorBackendType(), surfAllocator)) - break; - - if (!InitAndValidateGL()) - break; + MOZ_ASSERT(!gl); + if (CreateAndInitGLWith(CreateGLWithDefault, baseCaps, flags)) return true; - } while (false); + MOZ_ASSERT(!gl); gl = nullptr; + return false; } @@ -941,12 +936,15 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) bool forceEnabled = Preferences::GetBool("webgl.force-enabled", false); ScopedGfxFeatureReporter reporter("WebGL", forceEnabled); - if (!CreateOffscreenGL(forceEnabled)) { + MOZ_ASSERT(!gl); + if (!CreateAndInitGL(forceEnabled)) { GenerateWarning("WebGL creation failed."); return NS_ERROR_FAILURE; } MOZ_ASSERT(gl); + MOZ_ASSERT_IF(mOptions.alpha, gl->Caps().alpha); + if (!ResizeBackbuffer(width, height)) { GenerateWarning("Initializing WebGL backbuffer failed."); return NS_ERROR_FAILURE; @@ -965,14 +963,20 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) if (!mOptions.alpha && gl->Caps().alpha) mNeedsFakeNoAlpha = true; - // ANGLE doesn't quite handle this properly. - if (gl->Caps().depth && !gl->Caps().stencil && gl->IsANGLE()) + if (!mOptions.depth && gl->Caps().depth) + mNeedsFakeNoDepth = true; + + if (!mOptions.stencil && gl->Caps().stencil) mNeedsFakeNoStencil = true; } // Update mOptions. - mOptions.depth = gl->Caps().depth; - mOptions.stencil = gl->Caps().stencil; + if (!gl->Caps().depth) + mOptions.depth = false; + + if (!gl->Caps().stencil) + mOptions.stencil = false; + mOptions.antialias = gl->Caps().antialias; MakeContextCurrent(); @@ -998,10 +1002,16 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) mShouldPresent = true; MOZ_ASSERT(gl->Caps().color); + MOZ_ASSERT_IF(!mNeedsFakeNoAlpha, gl->Caps().alpha == mOptions.alpha); MOZ_ASSERT_IF(mNeedsFakeNoAlpha, !mOptions.alpha && gl->Caps().alpha); - MOZ_ASSERT(gl->Caps().depth == mOptions.depth); - MOZ_ASSERT(gl->Caps().stencil == mOptions.stencil); + + MOZ_ASSERT_IF(!mNeedsFakeNoDepth, gl->Caps().depth == mOptions.depth); + MOZ_ASSERT_IF(mNeedsFakeNoDepth, !mOptions.depth && gl->Caps().depth); + + MOZ_ASSERT_IF(!mNeedsFakeNoStencil, gl->Caps().stencil == mOptions.stencil); + MOZ_ASSERT_IF(mNeedsFakeNoStencil, !mOptions.stencil && gl->Caps().stencil); + MOZ_ASSERT(gl->Caps().antialias == mOptions.antialias); MOZ_ASSERT(gl->Caps().preserve == mOptions.preserveDrawingBuffer); @@ -1876,6 +1886,7 @@ RoundedToNextMultipleOf(CheckedUint32 x, CheckedUint32 y) WebGLContext::ScopedMaskWorkaround::ScopedMaskWorkaround(WebGLContext& webgl) : mWebGL(webgl) , mFakeNoAlpha(ShouldFakeNoAlpha(webgl)) + , mFakeNoDepth(ShouldFakeNoDepth(webgl)) , mFakeNoStencil(ShouldFakeNoStencil(webgl)) { if (mFakeNoAlpha) { @@ -1884,6 +1895,9 @@ WebGLContext::ScopedMaskWorkaround::ScopedMaskWorkaround(WebGLContext& webgl) mWebGL.mColorWriteMask[2], false); } + if (mFakeNoDepth) { + mWebGL.gl->fDisable(LOCAL_GL_DEPTH_TEST); + } if (mFakeNoStencil) { mWebGL.gl->fDisable(LOCAL_GL_STENCIL_TEST); } @@ -1897,6 +1911,9 @@ WebGLContext::ScopedMaskWorkaround::~ScopedMaskWorkaround() mWebGL.mColorWriteMask[2], mWebGL.mColorWriteMask[3]); } + if (mFakeNoDepth) { + mWebGL.gl->fEnable(LOCAL_GL_DEPTH_TEST); + } if (mFakeNoStencil) { mWebGL.gl->fEnable(LOCAL_GL_STENCIL_TEST); } diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h index 949a39d861ee..6c1ff727e4ed 100644 --- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -8,6 +8,7 @@ #include +#include "GLContextTypes.h" #include "GLDefs.h" #include "mozilla/Attributes.h" #include "mozilla/CheckedInt.h" @@ -24,6 +25,7 @@ #include "nsLayoutUtils.h" #include "nsTArray.h" #include "nsWrapperCache.h" +#include "SurfaceTypes.h" #ifdef XP_MACOSX #include "ForceDiscreteGPUHelperCGL.h" @@ -812,6 +814,7 @@ private: realGLboolean mDitherEnabled; realGLboolean mRasterizerDiscardEnabled; realGLboolean mScissorTestEnabled; + realGLboolean mDepthTestEnabled; realGLboolean mStencilTestEnabled; bool ValidateCapabilityEnum(GLenum cap, const char* info); @@ -1153,11 +1156,19 @@ public: protected: bool InitWebGL2(); + bool CreateAndInitGL(bool forceEnabled); + bool ResizeBackbuffer(uint32_t width, uint32_t height); + + typedef already_AddRefed FnCreateGL_T(const gl::SurfaceCaps& caps, + gl::CreateContextFlags flags, + WebGLContext* webgl); + + bool CreateAndInitGLWith(FnCreateGL_T fnCreateGL, const gl::SurfaceCaps& baseCaps, + gl::CreateContextFlags flags); + // ------------------------------------------------------------------------- // Validation functions (implemented in WebGLContextValidate.cpp) - bool CreateOffscreenGL(bool forceEnabled); bool InitAndValidateGL(); - bool ResizeBackbuffer(uint32_t width, uint32_t height); bool ValidateBlendEquationEnum(GLenum cap, const char* info); bool ValidateBlendFuncDstEnum(GLenum mode, const char* info); bool ValidateBlendFuncSrcEnum(GLenum mode, const char* info); @@ -1443,11 +1454,13 @@ protected: uint64_t mLastUseIndex; bool mNeedsFakeNoAlpha; + bool mNeedsFakeNoDepth; bool mNeedsFakeNoStencil; struct ScopedMaskWorkaround { WebGLContext& mWebGL; const bool mFakeNoAlpha; + const bool mFakeNoDepth; const bool mFakeNoStencil; static bool ShouldFakeNoAlpha(WebGLContext& webgl) { @@ -1458,6 +1471,13 @@ protected: webgl.mColorWriteMask[3] != false; } + static bool ShouldFakeNoDepth(WebGLContext& webgl) { + // We should only be doing this if we're about to draw to the backbuffer. + return !webgl.mBoundDrawFramebuffer && + webgl.mNeedsFakeNoDepth && + webgl.mDepthTestEnabled; + } + static bool ShouldFakeNoStencil(WebGLContext& webgl) { // We should only be doing this if we're about to draw to the backbuffer. return !webgl.mBoundDrawFramebuffer && diff --git a/dom/canvas/WebGLContextState.cpp b/dom/canvas/WebGLContextState.cpp index 4b2c54c66d74..f2d657f6d37f 100644 --- a/dom/canvas/WebGLContextState.cpp +++ b/dom/canvas/WebGLContextState.cpp @@ -360,12 +360,18 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv) case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS: case LOCAL_GL_RED_BITS: case LOCAL_GL_GREEN_BITS: - case LOCAL_GL_BLUE_BITS: - case LOCAL_GL_DEPTH_BITS: { + case LOCAL_GL_BLUE_BITS: { GLint i = 0; gl->fGetIntegerv(pname, &i); return JS::Int32Value(i); } + case LOCAL_GL_DEPTH_BITS: { + GLint i = 0; + if (!mNeedsFakeNoDepth) { + gl->fGetIntegerv(pname, &i); + } + return JS::Int32Value(i); + } case LOCAL_GL_ALPHA_BITS: { GLint i = 0; if (!mNeedsFakeNoAlpha) { @@ -622,6 +628,8 @@ realGLboolean* WebGLContext::GetStateTrackingSlot(GLenum cap) { switch (cap) { + case LOCAL_GL_DEPTH_TEST: + return &mDepthTestEnabled; case LOCAL_GL_DITHER: return &mDitherEnabled; case LOCAL_GL_RASTERIZER_DISCARD: diff --git a/dom/canvas/WebGLContextUtils.cpp b/dom/canvas/WebGLContextUtils.cpp index cbf16e444ed1..ba8c347814e7 100644 --- a/dom/canvas/WebGLContextUtils.cpp +++ b/dom/canvas/WebGLContextUtils.cpp @@ -1175,6 +1175,7 @@ WebGLContext::AssertCachedState() } // Draw state + MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_DEPTH_TEST) == mDepthTestEnabled); MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_DITHER) == mDitherEnabled); MOZ_ASSERT_IF(IsWebGL2(), gl->fIsEnabled(LOCAL_GL_RASTERIZER_DISCARD) == mRasterizerDiscardEnabled); diff --git a/dom/events/Event.cpp b/dom/events/Event.cpp index fba31bf3edee..8b8217a5f5ad 100644 --- a/dom/events/Event.cpp +++ b/dom/events/Event.cpp @@ -904,7 +904,7 @@ Event::GetScreenCoords(nsPresContext* aPresContext, WidgetEvent* aEvent, LayoutDeviceIntPoint aPoint) { - if (!nsContentUtils::IsCallerChrome() && + if (!nsContentUtils::LegacyIsCallerChromeOrNativeCode() && nsContentUtils::ResistFingerprinting()) { // When resisting fingerprinting, return client coordinates instead. CSSIntPoint clientCoords = GetClientCoords(aPresContext, aEvent, aPoint, CSSIntPoint(0, 0)); diff --git a/dom/events/EventDispatcher.cpp b/dom/events/EventDispatcher.cpp index dc8dce02c7c4..362d2c0fe23f 100644 --- a/dom/events/EventDispatcher.cpp +++ b/dom/events/EventDispatcher.cpp @@ -36,6 +36,7 @@ #include "mozilla/dom/TouchEvent.h" #include "mozilla/dom/TransitionEvent.h" #include "mozilla/dom/WheelEvent.h" +#include "mozilla/dom/WorkerPrivate.h" #include "mozilla/dom/XULCommandEvent.h" #include "mozilla/EventDispatcher.h" #include "mozilla/EventListenerManager.h" @@ -709,7 +710,9 @@ EventDispatcher::DispatchDOMEvent(nsISupports* aTarget, if (!dontResetTrusted) { //Check security state to determine if dispatcher is trusted - aDOMEvent->SetTrusted(nsContentUtils::ThreadsafeIsCallerChrome()); + bool trusted = NS_IsMainThread() ? nsContentUtils::LegacyIsCallerChromeOrNativeCode() + : mozilla::dom::workers::IsCurrentThreadRunningChromeWorker(); + aDOMEvent->SetTrusted(trusted); } return EventDispatcher::Dispatch(aTarget, aPresContext, innerEvent, diff --git a/dom/events/Touch.cpp b/dom/events/Touch.cpp index c326a9ea7b47..b93ae71a6c5b 100644 --- a/dom/events/Touch.cpp +++ b/dom/events/Touch.cpp @@ -93,6 +93,7 @@ Touch::GetTarget() const { nsCOMPtr content = do_QueryInterface(mTarget); if (content && content->ChromeOnlyAccess() && + !nsContentUtils::LegacyIsCallerNativeCode() && !nsContentUtils::CanAccessNativeAnon()) { return content->FindFirstNonChromeOnlyAccessContent(); } diff --git a/dom/events/test/test_bug607464.html b/dom/events/test/test_bug607464.html index a1d1cf08d357..ac8076bfd9ea 100644 --- a/dom/events/test/test_bug607464.html +++ b/dom/events/test/test_bug607464.html @@ -7,6 +7,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=607464 Test for Bug 607464 + @@ -63,7 +64,9 @@ function runTest() { } }, true); - scrollDown150PxWithPixelScrolling(scrollbox); + flushApzRepaints(function() { + scrollDown150PxWithPixelScrolling(scrollbox); + }, win); }, win); } diff --git a/dom/geolocation/nsGeolocation.cpp b/dom/geolocation/nsGeolocation.cpp index af8c24c3cfdb..9c791514e6df 100644 --- a/dom/geolocation/nsGeolocation.cpp +++ b/dom/geolocation/nsGeolocation.cpp @@ -1419,7 +1419,7 @@ Geolocation::GetCurrentPosition(GeoPositionCallback& callback, return NS_OK; } - if (!mOwner && !nsContentUtils::IsCallerChrome()) { + if (!mOwner && !nsContentUtils::LegacyIsCallerChromeOrNativeCode()) { return NS_ERROR_FAILURE; } @@ -1442,7 +1442,7 @@ Geolocation::GetCurrentPositionReady(nsGeolocationRequest* aRequest) return NS_OK; } - if (!nsContentUtils::IsCallerChrome()) { + if (!nsContentUtils::LegacyIsCallerChromeOrNativeCode()) { return NS_ERROR_FAILURE; } @@ -1513,7 +1513,7 @@ Geolocation::WatchPosition(GeoPositionCallback& aCallback, return NS_OK; } - if (!mOwner && !nsContentUtils::IsCallerChrome()) { + if (!mOwner && !nsContentUtils::LegacyIsCallerChromeOrNativeCode()) { return NS_ERROR_FAILURE; } @@ -1535,7 +1535,7 @@ Geolocation::WatchPositionReady(nsGeolocationRequest* aRequest) return NS_OK; } - if (!nsContentUtils::IsCallerChrome()) { + if (!nsContentUtils::LegacyIsCallerChromeOrNativeCode()) { return NS_ERROR_FAILURE; } diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp index 2aa4b8d127ec..f4c2268fbf99 100644 --- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -1417,7 +1417,7 @@ HTMLInputElement::GetValueInternal(nsAString& aValue) const return NS_OK; case VALUE_MODE_FILENAME: - if (nsContentUtils::IsCallerChrome()) { + if (nsContentUtils::LegacyIsCallerChromeOrNativeCode()) { #ifndef MOZ_CHILD_PERMISSIONS aValue.Assign(mFirstFilePath); #else @@ -2994,7 +2994,7 @@ HTMLInputElement::DispatchSelectEvent(nsPresContext* aPresContext) // If already handling select event, don't dispatch a second. if (!mHandlingSelectEvent) { - WidgetEvent event(nsContentUtils::IsCallerChrome(), eFormSelect); + WidgetEvent event(nsContentUtils::LegacyIsCallerChromeOrNativeCode(), eFormSelect); mHandlingSelectEvent = true; EventDispatcher::Dispatch(static_cast(this), diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index b9a97606af2f..afa8a69badf3 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -1472,7 +1472,7 @@ HTMLMediaElement::Seek(double aTime, // Detect if user has interacted with element by seeking so that // play will not be blocked when initiated by a script. - if (EventStateManager::IsHandlingUserInput() || nsContentUtils::IsCallerChrome()) { + if (EventStateManager::IsHandlingUserInput() || nsContentUtils::LegacyIsCallerChromeOrNativeCode()) { mHasUserInteraction = true; } @@ -3042,7 +3042,7 @@ public: if (!mElement) { return; } - gfxIntSize size; + gfx::IntSize size; { MutexAutoLock lock(mMutex); size = mInitialSize; @@ -3056,13 +3056,13 @@ public: const MediaSegment& aQueuedMedia) override { MutexAutoLock lock(mMutex); - if (mInitialSize != gfxIntSize(0,0) || + if (mInitialSize != gfx::IntSize(0,0) || aQueuedMedia.GetType() != MediaSegment::VIDEO) { return; } const VideoSegment& video = static_cast(aQueuedMedia); for (VideoSegment::ConstChunkIterator c(video); !c.IsEnded(); c.Next()) { - if (c->mFrame.GetIntrinsicSize() != gfxIntSize(0,0)) { + if (c->mFrame.GetIntrinsicSize() != gfx::IntSize(0,0)) { mInitialSize = c->mFrame.GetIntrinsicSize(); nsCOMPtr event = NS_NewRunnableMethod(this, &StreamSizeListener::ReceivedSize); @@ -3077,7 +3077,7 @@ private: // mMutex protects the fields below; they can be accessed on any thread Mutex mMutex; - gfxIntSize mInitialSize; + gfx::IntSize mInitialSize; }; class HTMLMediaElement::MediaStreamTracksAvailableCallback: diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp index b29349a4f211..415209c0144c 100644 --- a/dom/html/nsGenericHTMLElement.cpp +++ b/dom/html/nsGenericHTMLElement.cpp @@ -2792,7 +2792,8 @@ nsGenericHTMLElement::GetEditor(nsIEditor** aEditor) { *aEditor = nullptr; - if (!nsContentUtils::IsCallerChrome()) { + // See also HTMLTextFieldAccessible::GetEditor. + if (!nsContentUtils::LegacyIsCallerChromeOrNativeCode()) { return NS_ERROR_DOM_SECURITY_ERR; } diff --git a/dom/html/nsHTMLDocument.cpp b/dom/html/nsHTMLDocument.cpp index e5936e6ebab8..c8eac93ede2e 100644 --- a/dom/html/nsHTMLDocument.cpp +++ b/dom/html/nsHTMLDocument.cpp @@ -2929,7 +2929,7 @@ nsHTMLDocument::SetDesignMode(const nsAString & aDesignMode) void nsHTMLDocument::SetDesignMode(const nsAString& aDesignMode, ErrorResult& rv) { - if (!nsContentUtils::SubjectPrincipal()->Subsumes(NodePrincipal())) { + if (!nsContentUtils::LegacyIsCallerNativeCode() && !nsContentUtils::SubjectPrincipal()->Subsumes(NodePrincipal())) { rv.Throw(NS_ERROR_DOM_PROP_ACCESS_DENIED); return; } diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 08d02cba68b9..bc63689244df 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -2177,7 +2177,7 @@ ContentChild::RecvAddPermission(const IPC::Permission& permission) } bool -ContentChild::RecvScreenSizeChanged(const gfxIntSize& size) +ContentChild::RecvScreenSizeChanged(const gfx::IntSize& size) { #ifdef ANDROID mScreenSize = size; diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index 721fd1b037c5..678f53fe5923 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -332,7 +332,7 @@ public: virtual bool RecvAddPermission(const IPC::Permission& permission) override; - virtual bool RecvScreenSizeChanged(const gfxIntSize &size) override; + virtual bool RecvScreenSizeChanged(const gfx::IntSize &size) override; virtual bool RecvFlushMemory(const nsString& reason) override; @@ -407,7 +407,7 @@ public: virtual bool RecvEndDragSession(const bool& aDoneDrag, const bool& aUserCancelled) override; #ifdef ANDROID - gfxIntSize GetScreenSize() { return mScreenSize; } + gfx::IntSize GetScreenSize() { return mScreenSize; } #endif // Get the directory for IndexedDB files. We query the parent for this and @@ -502,7 +502,7 @@ private: AppInfo mAppInfo; #ifdef ANDROID - gfxIntSize mScreenSize; + gfx::IntSize mScreenSize; #endif bool mIsForApp; diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 1c09ae2169b8..4d4926132e15 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -2727,7 +2727,7 @@ ContentParent::RecvSetClipboard(const IPCDataTransfer& aDataTransfer, item.flavor().EqualsLiteral(kPNGImageMime) || item.flavor().EqualsLiteral(kGIFImageMime)) { const IPCDataTransferImage& imageDetails = item.imageDetails(); - const gfxIntSize size(imageDetails.width(), imageDetails.height()); + const gfx::IntSize size(imageDetails.width(), imageDetails.height()); if (!size.width || !size.height) { return true; } diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 67c7a470121b..eb7ddb994e65 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -84,7 +84,7 @@ using struct mozilla::void_t from "ipc/IPCMessageUtils.h"; using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h"; using mozilla::dom::quota::PersistenceType from "mozilla/dom/quota/PersistenceType.h"; using mozilla::hal::ProcessPriority from "mozilla/HalTypes.h"; -using gfxIntSize from "nsSize.h"; +using mozilla::gfx::IntSize from "mozilla/gfx/2D.h"; using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h"; using mozilla::dom::ContentParentId from "mozilla/dom/ipc/IdType.h"; using struct LookAndFeelInt from "mozilla/widget/WidgetMessageUtils.h"; @@ -546,7 +546,7 @@ child: // nsIPermissionManager messages AddPermission(Permission permission); - ScreenSizeChanged(gfxIntSize size); + ScreenSizeChanged(IntSize size); Volumes(VolumeInfo[] volumes); diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index f43e64adcfdf..811011c6352d 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -1979,7 +1979,7 @@ TabParent::RecvSetCustomCursor(const nsCString& aCursorData, } if (mTabSetsCursor) { - const gfxIntSize size(aWidth, aHeight); + const gfx::IntSize size(aWidth, aHeight); mozilla::RefPtr customCursor = new mozilla::gfx::SourceSurfaceRawData(); mozilla::gfx::SourceSurfaceRawData* raw = static_cast(customCursor.get()); diff --git a/dom/media/VideoFrameContainer.cpp b/dom/media/VideoFrameContainer.cpp index 5cf3c868c519..2ece19ad2cbd 100644 --- a/dom/media/VideoFrameContainer.cpp +++ b/dom/media/VideoFrameContainer.cpp @@ -29,7 +29,7 @@ VideoFrameContainer::VideoFrameContainer(dom::HTMLMediaElement* aElement, VideoFrameContainer::~VideoFrameContainer() {} -void VideoFrameContainer::SetCurrentFrame(const gfxIntSize& aIntrinsicSize, +void VideoFrameContainer::SetCurrentFrame(const gfx::IntSize& aIntrinsicSize, Image* aImage, const TimeStamp& aTargetTime) { @@ -44,14 +44,14 @@ void VideoFrameContainer::SetCurrentFrame(const gfxIntSize& aIntrinsicSize, } } -void VideoFrameContainer::SetCurrentFrames(const gfxIntSize& aIntrinsicSize, +void VideoFrameContainer::SetCurrentFrames(const gfx::IntSize& aIntrinsicSize, const nsTArray& aImages) { MutexAutoLock lock(mMutex); SetCurrentFramesLocked(aIntrinsicSize, aImages); } -void VideoFrameContainer::SetCurrentFramesLocked(const gfxIntSize& aIntrinsicSize, +void VideoFrameContainer::SetCurrentFramesLocked(const gfx::IntSize& aIntrinsicSize, const nsTArray& aImages) { mMutex.AssertCurrentThreadOwns(); diff --git a/dom/media/VideoFrameContainer.h b/dom/media/VideoFrameContainer.h index 795def76c11f..8d96a7946883 100644 --- a/dom/media/VideoFrameContainer.h +++ b/dom/media/VideoFrameContainer.h @@ -42,11 +42,11 @@ public: already_AddRefed aContainer); // Call on any thread - B2G_ACL_EXPORT void SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage, + B2G_ACL_EXPORT void SetCurrentFrame(const gfx::IntSize& aIntrinsicSize, Image* aImage, const TimeStamp& aTargetTime); - void SetCurrentFrames(const gfxIntSize& aIntrinsicSize, + void SetCurrentFrames(const gfx::IntSize& aIntrinsicSize, const nsTArray& aImages); - void ClearCurrentFrame(const gfxIntSize& aIntrinsicSize) + void ClearCurrentFrame(const gfx::IntSize& aIntrinsicSize) { SetCurrentFrames(aIntrinsicSize, nsTArray()); } @@ -79,7 +79,7 @@ public: void ForgetElement() { mElement = nullptr; } protected: - void SetCurrentFramesLocked(const gfxIntSize& aIntrinsicSize, + void SetCurrentFramesLocked(const gfx::IntSize& aIntrinsicSize, const nsTArray& aImages); // Non-addreffed pointer to the element. The element calls ForgetElement @@ -94,7 +94,7 @@ protected: // This can differ from the Image's actual size when the media resource // specifies that the Image should be stretched to have the correct aspect // ratio. - gfxIntSize mIntrinsicSize; + gfx::IntSize mIntrinsicSize; // We maintain our own mFrameID which is auto-incremented at every // SetCurrentFrame() or NewFrameID() call. ImageContainer::FrameID mFrameID; diff --git a/dom/media/VideoSegment.cpp b/dom/media/VideoSegment.cpp index 41cf8ca9f0a0..c5420173cc44 100644 --- a/dom/media/VideoSegment.cpp +++ b/dom/media/VideoSegment.cpp @@ -14,7 +14,7 @@ namespace mozilla { using namespace layers; VideoFrame::VideoFrame(already_AddRefed& aImage, - const gfxIntSize& aIntrinsicSize) + const gfx::IntSize& aIntrinsicSize) : mImage(aImage), mIntrinsicSize(aIntrinsicSize), mForceBlack(false) {} @@ -28,7 +28,7 @@ VideoFrame::~VideoFrame() void VideoFrame::SetNull() { mImage = nullptr; - mIntrinsicSize = gfxIntSize(0, 0); + mIntrinsicSize = gfx::IntSize(0, 0); } void @@ -41,7 +41,7 @@ VideoFrame::TakeFrom(VideoFrame* aFrame) #if !defined(MOZILLA_XPCOMRT_API) /* static */ already_AddRefed -VideoFrame::CreateBlackImage(const gfxIntSize& aSize) +VideoFrame::CreateBlackImage(const gfx::IntSize& aSize) { nsRefPtr container; nsRefPtr image; diff --git a/dom/media/VideoSegment.h b/dom/media/VideoSegment.h index 36def06d9bf7..7a761d38287e 100644 --- a/dom/media/VideoSegment.h +++ b/dom/media/VideoSegment.h @@ -30,7 +30,7 @@ public: typedef mozilla::layers::Image Image; #endif - VideoFrame(already_AddRefed& aImage, const gfxIntSize& aIntrinsicSize); + VideoFrame(already_AddRefed& aImage, const gfx::IntSize& aIntrinsicSize); VideoFrame(); ~VideoFrame(); @@ -48,13 +48,13 @@ public: Image* GetImage() const { return mImage; } void SetForceBlack(bool aForceBlack) { mForceBlack = aForceBlack; } bool GetForceBlack() const { return mForceBlack; } - const gfxIntSize& GetIntrinsicSize() const { return mIntrinsicSize; } + const gfx::IntSize& GetIntrinsicSize() const { return mIntrinsicSize; } void SetNull(); void TakeFrom(VideoFrame* aFrame); #if !defined(MOZILLA_XPCOMRT_API) // Create a planar YCbCr black image. - static already_AddRefed CreateBlackImage(const gfxIntSize& aSize); + static already_AddRefed CreateBlackImage(const gfx::IntSize& aSize); #endif // !defined(MOZILLA_XPCOMRT_API) protected: @@ -62,7 +62,7 @@ protected: // still have an intrinsic size in this case. nsRefPtr mImage; // The desired size to render the video frame at. - gfxIntSize mIntrinsicSize; + gfx::IntSize mIntrinsicSize; bool mForceBlack; }; diff --git a/dom/media/android/AndroidMediaReader.cpp b/dom/media/android/AndroidMediaReader.cpp index 6fb3827b5a1f..715d35100236 100644 --- a/dom/media/android/AndroidMediaReader.cpp +++ b/dom/media/android/AndroidMediaReader.cpp @@ -79,7 +79,7 @@ nsresult AndroidMediaReader::ReadMetadata(MediaInfo* aInfo, mInitialFrame = frameSize; VideoFrameContainer* container = mDecoder->GetVideoFrameContainer(); if (container) { - container->ClearCurrentFrame(gfxIntSize(displaySize.width, displaySize.height)); + container->ClearCurrentFrame(IntSize(displaySize.width, displaySize.height)); } } diff --git a/dom/media/eme/MediaKeySystemAccessManager.cpp b/dom/media/eme/MediaKeySystemAccessManager.cpp index 318c6a955d98..7e247e293ada 100644 --- a/dom/media/eme/MediaKeySystemAccessManager.cpp +++ b/dom/media/eme/MediaKeySystemAccessManager.cpp @@ -78,18 +78,13 @@ MediaKeySystemAccessManager::Request(DetailedPromise* aPromise, static bool ShouldTrialCreateGMP(const nsAString& aKeySystem) { - // Trial create where the CDM has a decoder; - // * ClearKey and Primetime on Windows Vista and later. - // * Primetime on MacOSX Lion and later. - return - Preferences::GetBool("media.gmp.trial-create.enabled", false) && + // Trial create where the CDM has a Windows Media Foundation decoder. #ifdef XP_WIN - IsVistaOrLater(); -#elif defined(XP_MACOSX) - aKeySystem.EqualsLiteral("com.adobe.primetime") && - nsCocoaFeatures::OnLionOrLater(); + return Preferences::GetBool("media.gmp.trial-create.enabled", false) && + aKeySystem.EqualsLiteral("org.w3.clearkey") && + IsVistaOrLater(); #else - false; + return false; #endif } diff --git a/dom/media/eme/MediaKeys.cpp b/dom/media/eme/MediaKeys.cpp index 55303086bf40..c73659a631e1 100644 --- a/dom/media/eme/MediaKeys.cpp +++ b/dom/media/eme/MediaKeys.cpp @@ -59,42 +59,12 @@ MediaKeys::MediaKeys(nsPIDOMWindow* aParent, this, NS_ConvertUTF16toUTF8(mKeySystem).get()); } -static PLDHashOperator -RejectPromises(const uint32_t& aKey, - nsRefPtr& aPromise, - void* aClosure) -{ - aPromise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR, - NS_LITERAL_CSTRING("Promise still outstanding at MediaKeys shutdown")); - ((MediaKeys*)aClosure)->Release(); - return PL_DHASH_NEXT; -} - MediaKeys::~MediaKeys() { Shutdown(); EME_LOG("MediaKeys[%p] destroyed", this); } -static PLDHashOperator -CopySessions(const nsAString& aKey, - nsRefPtr& aSession, - void* aClosure) -{ - KeySessionHashMap* p = static_cast(aClosure); - p->Put(aSession->GetSessionId(), aSession); - return PL_DHASH_NEXT; -} - -static PLDHashOperator -CloseSessions(const nsAString& aKey, - nsRefPtr& aSession, - void* aClosure) -{ - aSession->OnClosed(); - return PL_DHASH_NEXT; -} - void MediaKeys::Terminated() { @@ -102,8 +72,14 @@ MediaKeys::Terminated() KeySessionHashMap keySessions; // Remove entries during iteration will screw it. Make a copy first. - mKeySessions.Enumerate(&CopySessions, &keySessions); - keySessions.Enumerate(&CloseSessions, nullptr); + for (auto iter = mKeySessions.Iter(); !iter.Done(); iter.Next()) { + nsRefPtr& session = iter.Data(); + keySessions.Put(session->GetSessionId(), session); + } + for (auto iter = keySessions.Iter(); !iter.Done(); iter.Next()) { + nsRefPtr& session = iter.Data(); + session->OnClosed(); + } keySessions.Clear(); MOZ_ASSERT(mKeySessions.Count() == 0); @@ -125,7 +101,12 @@ MediaKeys::Shutdown() nsRefPtr kungFuDeathGrip = this; - mPromises.Enumerate(&RejectPromises, this); + for (auto iter = mPromises.Iter(); !iter.Done(); iter.Next()) { + nsRefPtr& promise = iter.Data(); + promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR, + NS_LITERAL_CSTRING("Promise still outstanding at MediaKeys shutdown")); + Release(); + } mPromises.Clear(); } diff --git a/dom/media/encoder/TrackEncoder.cpp b/dom/media/encoder/TrackEncoder.cpp index b0cddbfef064..97353256966a 100644 --- a/dom/media/encoder/TrackEncoder.cpp +++ b/dom/media/encoder/TrackEncoder.cpp @@ -197,7 +197,7 @@ VideoTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, VideoChunk chunk = *iter; if (!chunk.IsNull()) { gfx::IntSize imgsize = chunk.mFrame.GetImage()->GetSize(); - gfxIntSize intrinsicSize = chunk.mFrame.GetIntrinsicSize(); + gfx::IntSize intrinsicSize = chunk.mFrame.GetIntrinsicSize(); nsresult rv = Init(imgsize.width, imgsize.height, intrinsicSize.width, intrinsicSize.height, aGraph->GraphRate()); diff --git a/dom/media/encoder/VP8TrackEncoder.cpp b/dom/media/encoder/VP8TrackEncoder.cpp index 75120524c5ef..b52870fdcf77 100644 --- a/dom/media/encoder/VP8TrackEncoder.cpp +++ b/dom/media/encoder/VP8TrackEncoder.cpp @@ -251,7 +251,7 @@ nsresult VP8TrackEncoder::PrepareRawFrame(VideoChunk &aChunk) nsRefPtr img; if (aChunk.mFrame.GetForceBlack() || aChunk.IsNull()) { if (!mMuteFrame) { - mMuteFrame = VideoFrame::CreateBlackImage(gfxIntSize(mFrameWidth, mFrameHeight)); + mMuteFrame = VideoFrame::CreateBlackImage(gfx::IntSize(mFrameWidth, mFrameHeight)); MOZ_ASSERT(mMuteFrame); } img = mMuteFrame; diff --git a/dom/media/gmp/GMPServiceChild.cpp b/dom/media/gmp/GMPServiceChild.cpp index 0cdc2c0b8209..005828f09c53 100644 --- a/dom/media/gmp/GMPServiceChild.cpp +++ b/dom/media/gmp/GMPServiceChild.cpp @@ -311,20 +311,16 @@ GMPServiceChild::GetBridgedGMPContentParent(ProcessId aOtherPid, mContentParents.Get(aOtherPid, aGMPContentParent); } -static PLDHashOperator -FindAndRemoveGMPContentParent(const uint64_t& aKey, - nsRefPtr& aData, - void* aUserArg) -{ - return aData == aUserArg ? - (PLDHashOperator)(PL_DHASH_STOP | PL_DHASH_REMOVE) : - PL_DHASH_NEXT; -} - void GMPServiceChild::RemoveGMPContentParent(GMPContentParent* aGMPContentParent) { - mContentParents.Enumerate(FindAndRemoveGMPContentParent, aGMPContentParent); + for (auto iter = mContentParents.Iter(); !iter.Done(); iter.Next()) { + nsRefPtr& parent = iter.Data(); + if (parent == aGMPContentParent) { + iter.Remove(); + break; + } + } } static PLDHashOperator diff --git a/dom/media/ogg/OggReader.cpp b/dom/media/ogg/OggReader.cpp index 61b908ed55d8..631257c97f97 100644 --- a/dom/media/ogg/OggReader.cpp +++ b/dom/media/ogg/OggReader.cpp @@ -240,7 +240,7 @@ void OggReader::SetupTargetTheora(TheoraState* aTheoraState) VideoFrameContainer* container = mDecoder->GetVideoFrameContainer(); if (container) { - container->ClearCurrentFrame(gfxIntSize(displaySize.width, displaySize.height)); + container->ClearCurrentFrame(IntSize(displaySize.width, displaySize.height)); } // Copy Theora info data for time computations on other threads. diff --git a/dom/media/omx/MediaCodecReader.cpp b/dom/media/omx/MediaCodecReader.cpp index 526b7fec7a2b..c9ec24b43323 100644 --- a/dom/media/omx/MediaCodecReader.cpp +++ b/dom/media/omx/MediaCodecReader.cpp @@ -744,7 +744,7 @@ MediaCodecReader::HandleResourceAllocated() VideoFrameContainer* container = mDecoder->GetVideoFrameContainer(); if (container) { container->ClearCurrentFrame( - gfxIntSize(mInfo.mVideo.mDisplay.width, mInfo.mVideo.mDisplay.height)); + gfx::IntSize(mInfo.mVideo.mDisplay.width, mInfo.mVideo.mDisplay.height)); } nsRefPtr metadata = new MetadataHolder(); @@ -847,32 +847,6 @@ MediaCodecReader::WaitFenceAndReleaseOutputBuffer() } } -PLDHashOperator -MediaCodecReader::ReleaseTextureClient(TextureClient* aClient, - size_t& aIndex, - void* aUserArg) -{ - nsRefPtr reader = static_cast(aUserArg); - MOZ_ASSERT(reader, "reader should not be nullptr in ReleaseTextureClient()"); - - return reader->ReleaseTextureClient(aClient, aIndex); -} - -PLDHashOperator -MediaCodecReader::ReleaseTextureClient(TextureClient* aClient, - size_t& aIndex) -{ - MOZ_ASSERT(aClient, "TextureClient should be a valid pointer"); - - aClient->ClearRecycleCallback(); - - if (mVideoTrack.mCodec != nullptr) { - mVideoTrack.mCodec->releaseOutputBuffer(aIndex); - } - - return PL_DHASH_REMOVE; -} - void MediaCodecReader::ReleaseAllTextureClients() { @@ -884,7 +858,17 @@ MediaCodecReader::ReleaseAllTextureClients() } printf_stderr("All TextureClients should be released already"); - mTextureClientIndexes.Enumerate(MediaCodecReader::ReleaseTextureClient, this); + for (auto iter = mTextureClientIndexes.Iter(); !iter.Done(); iter.Next()) { + TextureClient* client = iter.Key(); + size_t& index = iter.Data(); + + client->ClearRecycleCallback(); + + if (mVideoTrack.mCodec != nullptr) { + mVideoTrack.mCodec->releaseOutputBuffer(index); + } + iter.Remove(); + } mTextureClientIndexes.Clear(); } diff --git a/dom/media/omx/MediaCodecReader.h b/dom/media/omx/MediaCodecReader.h index d2c1de8f57a0..e597ca1ec12c 100644 --- a/dom/media/omx/MediaCodecReader.h +++ b/dom/media/omx/MediaCodecReader.h @@ -397,11 +397,6 @@ private: void WaitFenceAndReleaseOutputBuffer(); void ReleaseRecycledTextureClients(); - static PLDHashOperator ReleaseTextureClient(TextureClient* aClient, - size_t& aIndex, - void* aUserArg); - PLDHashOperator ReleaseTextureClient(TextureClient* aClient, - size_t& aIndex); void ReleaseAllTextureClients(); diff --git a/dom/media/omx/MediaOmxReader.cpp b/dom/media/omx/MediaOmxReader.cpp index ba4232aab0ca..2580530987aa 100644 --- a/dom/media/omx/MediaOmxReader.cpp +++ b/dom/media/omx/MediaOmxReader.cpp @@ -307,7 +307,7 @@ void MediaOmxReader::HandleResourceAllocated() mInitialFrame = frameSize; VideoFrameContainer* container = mDecoder->GetVideoFrameContainer(); if (container) { - container->ClearCurrentFrame(gfxIntSize(displaySize.width, displaySize.height)); + container->ClearCurrentFrame(IntSize(displaySize.width, displaySize.height)); } } diff --git a/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp b/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp index a903be72898f..a2fd57796f0b 100644 --- a/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp +++ b/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp @@ -19,15 +19,6 @@ namespace mozilla { typedef MozPromiseRequestHolder DecryptPromiseRequestHolder; -static PLDHashOperator -DropDecryptPromises(MediaRawData* aKey, - nsAutoPtr& aData, - void* aUserArg) -{ - aData->DisconnectIfExists(); - return PL_DHASH_REMOVE; -} - class EMEDecryptor : public MediaDataDecoder { public: @@ -107,7 +98,11 @@ public: nsresult Flush() override { MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); MOZ_ASSERT(!mIsShutdown); - mDecrypts.Enumerate(&DropDecryptPromises, nullptr); + for (auto iter = mDecrypts.Iter(); !iter.Done(); iter.Next()) { + nsAutoPtr& holder = iter.Data(); + holder->DisconnectIfExists(); + iter.Remove(); + } nsresult rv = mDecoder->Flush(); unused << NS_WARN_IF(NS_FAILED(rv)); mSamplesWaitingForKey->Flush(); @@ -117,7 +112,11 @@ public: nsresult Drain() override { MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); MOZ_ASSERT(!mIsShutdown); - mDecrypts.Enumerate(&DropDecryptPromises, nullptr); + for (auto iter = mDecrypts.Iter(); !iter.Done(); iter.Next()) { + nsAutoPtr& holder = iter.Data(); + holder->DisconnectIfExists(); + iter.Remove(); + } nsresult rv = mDecoder->Drain(); unused << NS_WARN_IF(NS_FAILED(rv)); return rv; diff --git a/dom/media/platforms/android/AndroidDecoderModule.cpp b/dom/media/platforms/android/AndroidDecoderModule.cpp index 21e0f227475c..f88e1bc7a1d9 100644 --- a/dom/media/platforms/android/AndroidDecoderModule.cpp +++ b/dom/media/platforms/android/AndroidDecoderModule.cpp @@ -100,7 +100,7 @@ public: LOCAL_EGL_NONE, LOCAL_EGL_NONE }; - EGLContext eglContext = static_cast(mGLContext.get())->GetEGLContext(); + EGLContext eglContext = static_cast(mGLContext.get())->mContext; EGLImage eglImage = sEGLLibrary.fCreateImage(EGL_DISPLAY(), eglContext, LOCAL_EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer)tex, attribs); diff --git a/dom/media/systemservices/MediaParent.cpp b/dom/media/systemservices/MediaParent.cpp index c818e32348d2..9ef143909905 100644 --- a/dom/media/systemservices/MediaParent.cpp +++ b/dom/media/systemservices/MediaParent.cpp @@ -83,26 +83,21 @@ class OriginKeyStore : public nsISupports return NS_OK; } - static PLDHashOperator - HashCleaner(const nsACString& aOrigin, nsAutoPtr& aOriginKey, - void *aUserArg) - { - OriginKey* since = static_cast(aUserArg); - - LOG((((aOriginKey->mSecondsStamp >= since->mSecondsStamp)? - "%s: REMOVE %lld >= %lld" : - "%s: KEEP %lld < %lld"), - __FUNCTION__, aOriginKey->mSecondsStamp, since->mSecondsStamp)); - - return (aOriginKey->mSecondsStamp >= since->mSecondsStamp)? - PL_DHASH_REMOVE : PL_DHASH_NEXT; - } - void Clear(int64_t aSinceWhen) { // Avoid int64_t* <-> void* casting offset OriginKey since(nsCString(), aSinceWhen / PR_USEC_PER_SEC); - mKeys.Enumerate(HashCleaner, &since); + for (auto iter = mKeys.Iter(); !iter.Done(); iter.Next()) { + nsAutoPtr& originKey = iter.Data(); + LOG((((originKey->mSecondsStamp >= since.mSecondsStamp)? + "%s: REMOVE %lld >= %lld" : + "%s: KEEP %lld < %lld"), + __FUNCTION__, originKey->mSecondsStamp, since.mSecondsStamp)); + + if (originKey->mSecondsStamp >= since.mSecondsStamp) { + iter.Remove(); + } + } mPersistCount = 0; } diff --git a/dom/media/systemservices/MediaSystemResourceService.cpp b/dom/media/systemservices/MediaSystemResourceService.cpp index 9fc5fb87ccbf..0d695e6b1eb7 100644 --- a/dom/media/systemservices/MediaSystemResourceService.cpp +++ b/dom/media/systemservices/MediaSystemResourceService.cpp @@ -141,25 +141,6 @@ MediaSystemResourceService::ReleaseResource(media::MediaSystemResourceManagerPar UpdateRequests(aResourceType); } -struct ReleaseResourceData -{ - MediaSystemResourceService* mSelf; - media::MediaSystemResourceManagerParent* mParent; -}; - -/*static*/PLDHashOperator -MediaSystemResourceService::ReleaseResourceForKey(const uint32_t& aKey, - nsAutoPtr& aData, - void* aClosure) -{ - ReleaseResourceData* closure = static_cast(aClosure); - - closure->mSelf->RemoveRequests(closure->mParent, static_cast(aKey)); - closure->mSelf->UpdateRequests(static_cast(aKey)); - - return PLDHashOperator::PL_DHASH_NEXT; -} - void MediaSystemResourceService::ReleaseResource(media::MediaSystemResourceManagerParent* aParent) { @@ -169,8 +150,11 @@ MediaSystemResourceService::ReleaseResource(media::MediaSystemResourceManagerPar return; } - ReleaseResourceData data = { this, aParent }; - mResources.Enumerate(ReleaseResourceForKey, &data); + for (auto iter = mResources.Iter(); !iter.Done(); iter.Next()) { + const uint32_t& key = iter.Key(); + RemoveRequests(aParent, static_cast(key)); + UpdateRequests(static_cast(key)); + } } void diff --git a/dom/media/systemservices/MediaSystemResourceService.h b/dom/media/systemservices/MediaSystemResourceService.h index 62e56da75b9e..06e1b537cc78 100644 --- a/dom/media/systemservices/MediaSystemResourceService.h +++ b/dom/media/systemservices/MediaSystemResourceService.h @@ -77,10 +77,6 @@ private: void UpdateRequests(MediaSystemResourceType aResourceType); - static PLDHashOperator ReleaseResourceForKey(const uint32_t& aKey, - nsAutoPtr& aData, - void* aClosure); - bool mDestroyed; nsClassHashtable mResources; diff --git a/dom/media/webspeech/synth/pico/nsPicoService.cpp b/dom/media/webspeech/synth/pico/nsPicoService.cpp index 0849745d7cb3..be3d38adf5f8 100644 --- a/dom/media/webspeech/synth/pico/nsPicoService.cpp +++ b/dom/media/webspeech/synth/pico/nsPicoService.cpp @@ -501,40 +501,8 @@ nsPicoService::GetServiceType(SpeechServiceType* aServiceType) return NS_OK; } -struct VoiceTraverserData -{ - nsPicoService* mService; - nsSynthVoiceRegistry* mRegistry; -}; - // private methods -static PLDHashOperator -PicoAddVoiceTraverser(const nsAString& aUri, - nsRefPtr& aVoice, - void* aUserArg) -{ - // If we are missing either a language or a voice resource, it is invalid. - if (aVoice->mTaFile.IsEmpty() || aVoice->mSgFile.IsEmpty()) { - return PL_DHASH_REMOVE; - } - - VoiceTraverserData* data = static_cast(aUserArg); - - nsAutoString name; - name.AssignLiteral("Pico "); - name.Append(aVoice->mLanguage); - - // This service is multi-threaded and can handle more than one utterance at a - // time before previous utterances end. So, aQueuesUtterances == false - DebugOnly rv = - data->mRegistry->AddVoice( - data->mService, aUri, name, aVoice->mLanguage, true, false); - NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to add voice"); - - return PL_DHASH_NEXT; -} - void nsPicoService::Init() { @@ -617,8 +585,28 @@ nsPicoService::Init() void nsPicoService::RegisterVoices() { - VoiceTraverserData data = { this, nsSynthVoiceRegistry::GetInstance() }; - mVoices.Enumerate(PicoAddVoiceTraverser, &data); + nsSynthVoiceRegistry* registry = nsSynthVoiceRegistry::GetInstance(); + + for (auto iter = mVoices.Iter(); !iter.Done(); iter.Next()) { + const nsAString& uri = iter.Key(); + nsRefPtr& voice = iter.Data(); + + // If we are missing either a language or a voice resource, it is invalid. + if (voice->mTaFile.IsEmpty() || voice->mSgFile.IsEmpty()) { + iter.Remove(); + continue; + } + + nsAutoString name; + name.AssignLiteral("Pico "); + name.Append(voice->mLanguage); + + // This service is multi-threaded and can handle more than one utterance at a + // time before previous utterances end. So, aQueuesUtterances == false + DebugOnly rv = + registry->AddVoice(this, uri, name, voice->mLanguage, true, false); + NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to add voice"); + } mInitialized = true; } diff --git a/dom/plugins/base/android/ANPOpenGL.cpp b/dom/plugins/base/android/ANPOpenGL.cpp index 60c532505514..80ddbd0d270e 100644 --- a/dom/plugins/base/android/ANPOpenGL.cpp +++ b/dom/plugins/base/android/ANPOpenGL.cpp @@ -28,7 +28,7 @@ static ANPEGLContext anp_opengl_acquireContext(NPP instance) { return nullptr; context->MakeCurrent(); - return GLContextEGL::Cast(context)->GetEGLContext(); + return GLContextEGL::Cast(context)->mContext; } static ANPTextureInfo anp_opengl_lockTexture(NPP instance) { diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index f95d9f5c7f38..31f3a0719be0 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -2587,7 +2587,7 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext, aFrameRect.width != pluginSurface->Width() || aFrameRect.height != pluginSurface->Height()) { - pluginSurface = new gfxImageSurface(gfxIntSize(aFrameRect.width, aFrameRect.height), + pluginSurface = new gfxImageSurface(gfx::IntSize(aFrameRect.width, aFrameRect.height), gfxImageFormat::ARGB32); if (!pluginSurface) return; diff --git a/dom/plugins/ipc/PPluginInstance.ipdl b/dom/plugins/ipc/PPluginInstance.ipdl index a162d3639e4c..3187ca5371e0 100644 --- a/dom/plugins/ipc/PPluginInstance.ipdl +++ b/dom/plugins/ipc/PPluginInstance.ipdl @@ -22,7 +22,7 @@ using NPCoordinateSpace from "npapi.h"; using NPNVariable from "npapi.h"; using mozilla::plugins::NativeWindowHandle from "mozilla/plugins/PluginMessageUtils.h"; using gfxSurfaceType from "gfxTypes.h"; -using gfxIntSize from "nsSize.h"; +using mozilla::gfx::IntSize from "mozilla/gfx/2D.h"; using struct mozilla::null_t from "ipc/IPCMessageUtils.h"; using mozilla::plugins::WindowsSharedMemoryHandle from "mozilla/plugins/PluginMessageUtils.h"; using mozilla::layers::SurfaceDescriptorX11 from "gfxipc/ShadowLayerUtils.h"; @@ -189,7 +189,7 @@ parent: returns (SurfaceDescriptor prevSurface); async PPluginSurface(WindowsSharedMemoryHandle handle, - gfxIntSize size, + IntSize size, bool transparent); intr NPN_PushPopupsEnabledState(bool aState); diff --git a/dom/plugins/ipc/PluginInstanceChild.cpp b/dom/plugins/ipc/PluginInstanceChild.cpp index a94d41a04ed5..6d970bddc644 100644 --- a/dom/plugins/ipc/PluginInstanceChild.cpp +++ b/dom/plugins/ipc/PluginInstanceChild.cpp @@ -2861,8 +2861,7 @@ PluginInstanceChild::CreateOptSurface(void) Visual* defaultVisual = DefaultVisualOfScreen(screen); mCurrentSurface = gfxXlibSurface::Create(screen, defaultVisual, - gfxIntSize(mWindow.width, - mWindow.height)); + IntSize(mWindow.width, mWindow.height)); return mCurrentSurface != nullptr; } @@ -2873,8 +2872,7 @@ PluginInstanceChild::CreateOptSurface(void) } mCurrentSurface = gfxXlibSurface::Create(screen, xfmt, - gfxIntSize(mWindow.width, - mWindow.height)); + IntSize(mWindow.width, mWindow.height)); return mCurrentSurface != nullptr; } #endif @@ -2898,7 +2896,7 @@ PluginInstanceChild::CreateOptSurface(void) // Make common shmem implementation working for any platform mCurrentSurface = - gfxSharedImageSurface::CreateUnsafe(this, gfxIntSize(mWindow.width, mWindow.height), format); + gfxSharedImageSurface::CreateUnsafe(this, IntSize(mWindow.width, mWindow.height), format); return !!mCurrentSurface; } @@ -2966,7 +2964,7 @@ PluginInstanceChild::EnsureCurrentBuffer(void) { #ifndef XP_DARWIN nsIntRect toInvalidate(0, 0, 0, 0); - gfxIntSize winSize = gfxIntSize(mWindow.width, mWindow.height); + IntSize winSize = IntSize(mWindow.width, mWindow.height); if (mBackground && mBackground->GetSize() != winSize) { // It would be nice to keep the old background here, but doing @@ -2978,7 +2976,7 @@ PluginInstanceChild::EnsureCurrentBuffer(void) } if (mCurrentSurface) { - gfxIntSize surfSize = mCurrentSurface->GetSize(); + IntSize surfSize = mCurrentSurface->GetSize(); if (winSize != surfSize || (mBackground && !CanPaintOnBackground()) || (mBackground && @@ -3309,7 +3307,7 @@ PluginInstanceChild::PaintRectWithAlphaExtraction(const nsIntRect& aRect, nsRefPtr whiteImage; nsRefPtr blackImage; gfxRect targetRect(rect.x, rect.y, rect.width, rect.height); - gfxIntSize targetSize(rect.width, rect.height); + IntSize targetSize(rect.width, rect.height); gfxPoint deviceOffset = -targetRect.TopLeft(); // We always use a temporary "white image" @@ -3487,7 +3485,7 @@ PluginInstanceChild::ShowPluginFrame() // Fix up old invalidations that might have been made when our // surface was a different size - gfxIntSize surfaceSize = mCurrentSurface->GetSize(); + IntSize surfaceSize = mCurrentSurface->GetSize(); rect.IntersectRect(rect, nsIntRect(0, 0, surfaceSize.width, surfaceSize.height)); @@ -3749,7 +3747,7 @@ PluginInstanceChild::RecvUpdateBackground(const SurfaceDescriptor& aBackground, return false; } - gfxIntSize bgSize = mBackground->GetSize(); + IntSize bgSize = mBackground->GetSize(); mAccumulatedInvalidRect.UnionRect(mAccumulatedInvalidRect, nsIntRect(0, 0, bgSize.width, bgSize.height)); AsyncShowPluginFrame(); @@ -3786,7 +3784,7 @@ PluginInstanceChild::RecvPPluginBackgroundDestroyerConstructor( // alpha values. (We should be notified of that invalidation soon // too, but we don't assume that here.) if (mBackground) { - gfxIntSize bgsize = mBackground->GetSize(); + IntSize bgsize = mBackground->GetSize(); mAccumulatedInvalidRect.UnionRect( nsIntRect(0, 0, bgsize.width, bgsize.height), mAccumulatedInvalidRect); diff --git a/dom/plugins/ipc/PluginInstanceChild.h b/dom/plugins/ipc/PluginInstanceChild.h index e7bab586f172..a3b477425cf8 100644 --- a/dom/plugins/ipc/PluginInstanceChild.h +++ b/dom/plugins/ipc/PluginInstanceChild.h @@ -113,7 +113,7 @@ protected: virtual PPluginSurfaceChild* AllocPPluginSurfaceChild(const WindowsSharedMemoryHandle&, - const gfxIntSize&, const bool&) override { + const gfx::IntSize&, const bool&) override { return new PPluginSurfaceChild(); } diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp index 5bb6a827e299..284f3cc5acd7 100644 --- a/dom/plugins/ipc/PluginInstanceParent.cpp +++ b/dom/plugins/ipc/PluginInstanceParent.cpp @@ -726,7 +726,7 @@ nsresult PluginInstanceParent::GetImageSize(nsIntSize* aSize) { if (mFrontSurface) { - gfxIntSize size = mFrontSurface->GetSize(); + mozilla::gfx::IntSize size = mFrontSurface->GetSize(); *aSize = nsIntSize(size.width, size.height); return NS_OK; } @@ -795,7 +795,7 @@ PluginInstanceParent::BeginUpdateBackground(const nsIntRect& aRect, } } - gfxIntSize sz = mBackground->GetSize(); + mozilla::gfx::IntSize sz = mBackground->GetSize(); #ifdef DEBUG MOZ_ASSERT(nsIntRect(0, 0, sz.width, sz.height).Contains(aRect), "Update outside of background area"); @@ -852,7 +852,7 @@ PluginInstanceParent::CreateBackground(const nsIntSize& aSize) Screen* screen = DefaultScreenOfDisplay(DefaultXDisplay()); Visual* visual = DefaultVisualOfScreen(screen); mBackground = gfxXlibSurface::Create(screen, visual, - gfxIntSize(aSize.width, aSize.height)); + mozilla::gfx::IntSize(aSize.width, aSize.height)); return !!mBackground; #elif defined(XP_WIN) @@ -861,7 +861,7 @@ PluginInstanceParent::CreateBackground(const nsIntSize& aSize) mBackground = gfxSharedImageSurface::CreateUnsafe( this, - gfxIntSize(aSize.width, aSize.height), + mozilla::gfx::IntSize(aSize.width, aSize.height), gfxImageFormat::RGB24); return !!mBackground; #else @@ -1600,7 +1600,7 @@ PluginInstanceParent::GetActorForNPObject(NPObject* aObject) PPluginSurfaceParent* PluginInstanceParent::AllocPPluginSurfaceParent(const WindowsSharedMemoryHandle& handle, - const gfxIntSize& size, + const mozilla::gfx::IntSize& size, const bool& transparent) { #ifdef XP_WIN diff --git a/dom/plugins/ipc/PluginInstanceParent.h b/dom/plugins/ipc/PluginInstanceParent.h index 84c467da21f6..01b9c8c2f216 100644 --- a/dom/plugins/ipc/PluginInstanceParent.h +++ b/dom/plugins/ipc/PluginInstanceParent.h @@ -169,7 +169,7 @@ public: virtual PPluginSurfaceParent* AllocPPluginSurfaceParent(const WindowsSharedMemoryHandle& handle, - const gfxIntSize& size, + const mozilla::gfx::IntSize& size, const bool& transparent) override; virtual bool diff --git a/dom/plugins/ipc/PluginSurfaceParent.cpp b/dom/plugins/ipc/PluginSurfaceParent.cpp index a9087cb1f42d..1d5e19ad6438 100644 --- a/dom/plugins/ipc/PluginSurfaceParent.cpp +++ b/dom/plugins/ipc/PluginSurfaceParent.cpp @@ -12,7 +12,7 @@ namespace mozilla { namespace plugins { PluginSurfaceParent::PluginSurfaceParent(const WindowsSharedMemoryHandle& handle, - const gfxIntSize& size, + const gfx::IntSize& size, bool transparent) { SharedDIBSurface* dibsurf = new SharedDIBSurface(); diff --git a/dom/plugins/ipc/PluginSurfaceParent.h b/dom/plugins/ipc/PluginSurfaceParent.h index 07f1423cbba1..12dab7e728e2 100644 --- a/dom/plugins/ipc/PluginSurfaceParent.h +++ b/dom/plugins/ipc/PluginSurfaceParent.h @@ -23,7 +23,7 @@ class PluginSurfaceParent : public PPluginSurfaceParent { public: PluginSurfaceParent(const WindowsSharedMemoryHandle& handle, - const gfxIntSize& size, + const gfx::IntSize& size, const bool transparent); ~PluginSurfaceParent(); diff --git a/dom/quota/QuotaManager.cpp b/dom/quota/QuotaManager.cpp index ab451bbd63ac..04b23fbf6596 100644 --- a/dom/quota/QuotaManager.cpp +++ b/dom/quota/QuotaManager.cpp @@ -3575,7 +3575,7 @@ QuotaManager::GetInfoForChrome(nsACString* aGroup, bool* aIsApp) { MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(nsContentUtils::IsCallerChrome()); + MOZ_ASSERT(nsContentUtils::LegacyIsCallerChromeOrNativeCode()); if (aGroup) { ChromeOrigin(*aGroup); diff --git a/dom/tests/mochitest/general/test_picture_pref.html b/dom/tests/mochitest/general/test_picture_pref.html index 53723d9c5fba..a020c685634b 100644 --- a/dom/tests/mochitest/general/test_picture_pref.html +++ b/dom/tests/mochitest/general/test_picture_pref.html @@ -71,6 +71,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=870022 function runTest(iframe) { var doc = iframe.contentDocument; + var win = iframe.contentWindow; var img = doc.querySelector("img"); var source = doc.querySelector("source"); @@ -78,9 +79,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=870022 is(source.sizes, undefined, "sizes should not be visible on "); is(source.srcset, undefined, "srcset should not be visible on "); - var imgSizesDesc = Object.getOwnPropertyDescriptor(HTMLImageElement.prototype, "sizes"); - var sourceSizesDesc = Object.getOwnPropertyDescriptor(HTMLSourceElement.prototype, "sizes"); - var sourceSrcsetDesc = Object.getOwnPropertyDescriptor(HTMLSourceElement.prototype, "srcset"); + var imgSizesDesc = Object.getOwnPropertyDescriptor(win.HTMLImageElement.prototype, "sizes"); + var sourceSizesDesc = Object.getOwnPropertyDescriptor(win.HTMLSourceElement.prototype, "sizes"); + var sourceSrcsetDesc = Object.getOwnPropertyDescriptor(win.HTMLSourceElement.prototype, "srcset"); is(imgSizesDesc, undefined, "HTMLImageElement should know nothing of sizes"); is(sourceSizesDesc, undefined, "HTMLSourceElement should know nothing of sizes"); is(sourceSrcsetDesc, undefined, "HTMLSourceElement should know nothing of srcset"); diff --git a/dom/tests/mochitest/general/test_srcset_pref.html b/dom/tests/mochitest/general/test_srcset_pref.html index c7458163e9b7..b658d57d1691 100644 --- a/dom/tests/mochitest/general/test_srcset_pref.html +++ b/dom/tests/mochitest/general/test_srcset_pref.html @@ -12,8 +12,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=870021 Mozilla Bug 870021
-