From b1f8ce5e9c891f0d8ecc70d2ccb550d2300193e5 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Wed, 5 Jul 2017 15:30:28 -0400 Subject: [PATCH 01/63] Bug 1378483 - Allow TextLayers in the parent process. r=mattwoodrow. This fixes text using a painted layer in the Chrome. --- layout/generic/nsTextFrame.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 379769718860..8799141a4c36 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -5137,8 +5137,7 @@ nsDisplayText::nsDisplayText(nsDisplayListBuilder* aBuilder, nsTextFrame* aFrame Color color; if (!capture->ContainsOnlyColoredGlyphs(mFont, color, glyphs) || !mFont - || !mFont->CanSerialize() - || XRE_IsParentProcess()) { + || !mFont->CanSerialize()) { mFont = nullptr; mGlyphs.Clear(); } else { From 1eb1c9091d041e51b02a4217af807eef08146999 Mon Sep 17 00:00:00 2001 From: Bob Owen Date: Wed, 5 Jul 2017 21:00:55 +0100 Subject: [PATCH 02/63] Bug 1378061: Only set user's SID in USER_LIMITED as deny only when not using restricting SIDs. r=jimm --- .../chromium/sandbox/win/src/restricted_token_utils.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.cc b/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.cc index 416d7b551ec5..2a7b17583206 100644 --- a/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.cc +++ b/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.cc @@ -83,7 +83,11 @@ DWORD CreateRestrictedToken(TokenLevel security_level, sid_exceptions.push_back(WinWorldSid); sid_exceptions.push_back(WinInteractiveSid); privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME); - restricted_token.AddUserSidForDenyOnly(); + // This breaks web audio, so we don't want to do this in the restricting + // SIDs (normal) case. See bug 1378061. + if (!gUseRestricting) { + restricted_token.AddUserSidForDenyOnly(); + } restricted_token.AddRestrictingSid(WinBuiltinUsersSid); restricted_token.AddRestrictingSid(WinWorldSid); restricted_token.AddRestrictingSid(WinRestrictedCodeSid); From 1be37cf55cbead3243e2f653f9589e8073b31558 Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Wed, 5 Jul 2017 21:57:47 +0200 Subject: [PATCH 03/63] Bug 1364016 - Have _openURIInNewTab() provide the correct triggeringPrincipal. r=baku --- dom/base/nsOpenURIInFrameParams.cpp | 15 +++++++++++++++ dom/base/nsOpenURIInFrameParams.h | 1 + dom/interfaces/base/nsIBrowserDOMWindow.idl | 2 ++ dom/ipc/ContentChild.cpp | 21 ++++++++++++++++----- dom/ipc/ContentParent.cpp | 14 ++++++++++---- dom/ipc/ContentParent.h | 7 +++++-- dom/ipc/PContent.ipdl | 6 ++++-- 7 files changed, 53 insertions(+), 13 deletions(-) diff --git a/dom/base/nsOpenURIInFrameParams.cpp b/dom/base/nsOpenURIInFrameParams.cpp index cd4a4e78e815..0297caa4f1fa 100644 --- a/dom/base/nsOpenURIInFrameParams.cpp +++ b/dom/base/nsOpenURIInFrameParams.cpp @@ -40,6 +40,21 @@ nsOpenURIInFrameParams::GetIsPrivate(bool* aIsPrivate) return NS_OK; } +NS_IMETHODIMP +nsOpenURIInFrameParams::GetTriggeringPrincipal(nsIPrincipal** aTriggeringPrincipal) +{ + NS_ADDREF(*aTriggeringPrincipal = mTriggeringPrincipal); + return NS_OK; +} + +NS_IMETHODIMP +nsOpenURIInFrameParams::SetTriggeringPrincipal(nsIPrincipal* aTriggeringPrincipal) +{ + NS_ENSURE_TRUE(aTriggeringPrincipal, NS_ERROR_INVALID_ARG); + mTriggeringPrincipal = aTriggeringPrincipal; + return NS_OK; +} + NS_IMETHODIMP nsOpenURIInFrameParams::GetOpenerOriginAttributes(JSContext* aCx, JS::MutableHandle aValue) diff --git a/dom/base/nsOpenURIInFrameParams.h b/dom/base/nsOpenURIInFrameParams.h index 83683e41f945..f00ee3d47aa1 100644 --- a/dom/base/nsOpenURIInFrameParams.h +++ b/dom/base/nsOpenURIInFrameParams.h @@ -25,4 +25,5 @@ private: mozilla::OriginAttributes mOpenerOriginAttributes; nsString mReferrer; + nsCOMPtr mTriggeringPrincipal; }; diff --git a/dom/interfaces/base/nsIBrowserDOMWindow.idl b/dom/interfaces/base/nsIBrowserDOMWindow.idl index 509a3065ea4e..2ebad4080608 100644 --- a/dom/interfaces/base/nsIBrowserDOMWindow.idl +++ b/dom/interfaces/base/nsIBrowserDOMWindow.idl @@ -9,12 +9,14 @@ interface mozIDOMWindowProxy; interface nsIDOMWindow; interface nsIURI; interface nsIFrameLoaderOwner; +interface nsIPrincipal; [scriptable, uuid(e774db14-79ac-4156-a7a3-aa3fd0a22c10)] interface nsIOpenURIInFrameParams : nsISupports { attribute DOMString referrer; readonly attribute boolean isPrivate; + attribute nsIPrincipal triggeringPrincipal; [implicit_jscontext] readonly attribute jsval openerOriginAttributes; diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 5129e6261418..c732e9f6d47b 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -73,6 +73,7 @@ #include "mozilla/WebBrowserPersistDocumentChild.h" #include "imgLoader.h" #include "GMPServiceChild.h" +#include "NullPrincipal.h" #ifdef MOZ_GECKO_PROFILER #include "ChildProfilerController.h" @@ -691,15 +692,19 @@ ContentChild::ProvideWindow(mozIDOMWindowProxy* aParent, static nsresult GetWindowParamsFromParent(mozIDOMWindowProxy* aParent, - nsACString& aBaseURIString, float* aFullZoom) + nsACString& aBaseURIString, float* aFullZoom, + nsIPrincipal** aTriggeringPrincipal) { *aFullZoom = 1.0f; auto* opener = nsPIDOMWindowOuter::From(aParent); if (!opener) { + nsCOMPtr nullPrincipal = NullPrincipal::Create(); + NS_ADDREF(*aTriggeringPrincipal = nullPrincipal); return NS_OK; } nsCOMPtr doc = opener->GetDoc(); + NS_ADDREF(*aTriggeringPrincipal = doc->NodePrincipal()); nsCOMPtr baseURI = doc->GetDocBaseURI(); if (!baseURI) { NS_ERROR("nsIDocument didn't return a base URI"); @@ -779,7 +784,9 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener, if (loadInDifferentProcess) { nsAutoCString baseURIString; float fullZoom; - rv = GetWindowParamsFromParent(aParent, baseURIString, &fullZoom); + nsCOMPtr triggeringPrincipal; + rv = GetWindowParamsFromParent(aParent, baseURIString, &fullZoom, + getter_AddRefs(triggeringPrincipal)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -795,7 +802,8 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener, features, baseURIString, fullZoom, - name); + name, + Principal(triggeringPrincipal)); // We return NS_ERROR_ABORT, so that the caller knows that we've abandoned // the window open as far as it is concerned. @@ -891,7 +899,9 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener, } else { nsAutoCString baseURIString; float fullZoom; - rv = GetWindowParamsFromParent(aParent, baseURIString, &fullZoom); + nsCOMPtr triggeringPrincipal; + rv = GetWindowParamsFromParent(aParent, baseURIString, &fullZoom, + getter_AddRefs(triggeringPrincipal)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -902,7 +912,8 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener, aSizeSpecified, features, baseURIString, - fullZoom); + fullZoom, + Principal(triggeringPrincipal)); } // Await the promise being resolved. When the promise is resolved, we'll set diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index b622ad632281..62aacdec9fb6 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -4504,7 +4504,8 @@ ContentParent::CommonCreateWindow(PBrowserParent* aThisTab, const nsString& aName, nsresult& aResult, nsCOMPtr& aNewTabParent, - bool* aWindowIsNew) + bool* aWindowIsNew, + nsIPrincipal* aTriggeringPrincipal) { // The content process should never be in charge of computing whether or @@ -4582,6 +4583,8 @@ ContentParent::CommonCreateWindow(PBrowserParent* aThisTab, nsCOMPtr params = new nsOpenURIInFrameParams(openerOriginAttributes); params->SetReferrer(NS_ConvertUTF8toUTF16(aBaseURI)); + MOZ_ASSERT(aTriggeringPrincipal, "need a valid triggeringPrincipal"); + params->SetTriggeringPrincipal(aTriggeringPrincipal); nsCOMPtr frameLoaderOwner; aResult = browserDOMWin->OpenURIInFrame(aURIToLoad, params, openLocation, @@ -4664,6 +4667,7 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab, const nsCString& aFeatures, const nsCString& aBaseURI, const float& aFullZoom, + const IPC::Principal& aTriggeringPrincipal, CreateWindowResolver&& aResolve) { nsresult rv = NS_OK; @@ -4708,7 +4712,8 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab, aCalledFromJS, aPositionSpecified, aSizeSpecified, nullptr, aFeatures, aBaseURI, aFullZoom, nextTabParentId, NullString(), rv, - newRemoteTab, &cwi.windowOpened()); + newRemoteTab, &cwi.windowOpened(), + aTriggeringPrincipal); if (!ipcResult) { return ipcResult; } @@ -4751,7 +4756,8 @@ ContentParent::RecvCreateWindowInDifferentProcess( const nsCString& aFeatures, const nsCString& aBaseURI, const float& aFullZoom, - const nsString& aName) + const nsString& aName, + const IPC::Principal& aTriggeringPrincipal) { nsCOMPtr newRemoteTab; bool windowIsNew; @@ -4762,7 +4768,7 @@ ContentParent::RecvCreateWindowInDifferentProcess( aCalledFromJS, aPositionSpecified, aSizeSpecified, uriToLoad, aFeatures, aBaseURI, aFullZoom, /* aNextTabParentId = */ 0, aName, rv, - newRemoteTab, &windowIsNew); + newRemoteTab, &windowIsNew, aTriggeringPrincipal); if (!ipcResult) { return ipcResult; } diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index cae28e17b927..2669e7c14f64 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -536,6 +536,7 @@ public: const nsCString& aFeatures, const nsCString& aBaseURI, const float& aFullZoom, + const IPC::Principal& aTriggeringPrincipal, CreateWindowResolver&& aResolve) override; virtual mozilla::ipc::IPCResult RecvCreateWindowInDifferentProcess( @@ -548,7 +549,8 @@ public: const nsCString& aFeatures, const nsCString& aBaseURI, const float& aFullZoom, - const nsString& aName) override; + const nsString& aName, + const IPC::Principal& aTriggeringPrincipal) override; static bool AllocateLayerTreeId(TabParent* aTabParent, uint64_t* aId); @@ -709,7 +711,8 @@ private: const nsString& aName, nsresult& aResult, nsCOMPtr& aNewTabParent, - bool* aWindowIsNew); + bool* aWindowIsNew, + nsIPrincipal* aTriggeringPrincipal); FORWARD_SHMEM_ALLOCATOR_TO(PContentParent) diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 96d877a528ce..0f186505ef29 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -991,7 +991,8 @@ parent: bool aSizeSpecified, nsCString aFeatures, nsCString aBaseURI, - float aFullZoom) + float aFullZoom, + Principal aTriggeringPrincipal) returns (CreatedWindowInfo window); async CreateWindowInDifferentProcess( @@ -1004,7 +1005,8 @@ parent: nsCString aFeatures, nsCString aBaseURI, float aFullZoom, - nsString aName); + nsString aName, + Principal aTriggeringPrincipal); sync GetAndroidSystemInfo() returns (AndroidSystemInfo info); From 2ad43ee9bd1ede37aa69a8948935cdda84afe0b6 Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Wed, 5 Jul 2017 21:58:21 +0200 Subject: [PATCH 04/63] Bug 1364016 - Explicitly pass a triggeringPrincipal to openURI. r=gijs,baku --- browser/base/content/browser.js | 8 +++----- .../content/test/general/browser_bug520538.js | 3 ++- .../content/test/general/browser_bug537474.js | 3 ++- .../content/test/urlbar/browser_bug562649.js | 3 ++- browser/components/nsBrowserContentHandler.js | 17 ++++++++++------- .../client/responsive.html/browser/tunnel.js | 7 ++++++- dom/interfaces/base/nsIBrowserDOMWindow.idl | 3 ++- dom/ipc/ContentParent.cpp | 1 + dom/workers/ServiceWorkerClients.cpp | 4 ++++ toolkit/xre/nsNativeAppSupportWin.cpp | 2 ++ uriloader/exthandler/nsWebHandlerApp.js | 4 +++- xpfe/appshell/nsContentTreeOwner.cpp | 11 +++++++---- 12 files changed, 44 insertions(+), 22 deletions(-) diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 6f7525a015eb..39ba8a200703 100755 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -5122,7 +5122,7 @@ nsBrowserAccess.prototype = { return browser; }, - openURI(aURI, aOpener, aWhere, aFlags) { + openURI(aURI, aOpener, aWhere, aFlags, aTriggeringPrincipal) { // This function should only ever be called if we're opening a URI // from a non-remote browser window (via nsContentTreeOwner). if (aOpener && Cu.isCrossProcessWrapper(aOpener)) { @@ -5154,11 +5154,9 @@ nsBrowserAccess.prototype = { } let referrer = aOpener ? makeURI(aOpener.location.href) : null; - let triggeringPrincipal = null; let referrerPolicy = Ci.nsIHttpChannel.REFERRER_POLICY_UNSET; if (aOpener && aOpener.document) { referrerPolicy = aOpener.document.referrerPolicy; - triggeringPrincipal = aOpener.document.nodePrincipal; } let isPrivate = aOpener ? PrivateBrowsingUtils.isContentWindowPrivate(aOpener) @@ -5192,7 +5190,7 @@ nsBrowserAccess.prototype = { let browser = this._openURIInNewTab(aURI, referrer, referrerPolicy, isPrivate, isExternal, forceNotRemote, userContextId, - openerWindow, triggeringPrincipal); + openerWindow, aTriggeringPrincipal); if (browser) newWindow = browser.contentWindow; break; @@ -5203,7 +5201,7 @@ nsBrowserAccess.prototype = { Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL : Ci.nsIWebNavigation.LOAD_FLAGS_NONE; gBrowser.loadURIWithFlags(aURI.spec, { - triggeringPrincipal, + aTriggeringPrincipal, flags: loadflags, referrerURI: referrer, referrerPolicy, diff --git a/browser/base/content/test/general/browser_bug520538.js b/browser/base/content/test/general/browser_bug520538.js index 41350d80d4d9..90af476cb0d2 100644 --- a/browser/base/content/test/general/browser_bug520538.js +++ b/browser/base/content/test/general/browser_bug520538.js @@ -4,7 +4,8 @@ function test() { window.browserDOMWindow.openURI(makeURI("about:blank"), null, Ci.nsIBrowserDOMWindow.OPEN_NEWTAB, - Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL); + Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL, + Services.scriptSecurityManager.getSystemPrincipal()); is(gBrowser.tabs.length, tabCount + 1, "'--new-tab about:blank' opens a new tab"); is(gBrowser.selectedTab, gBrowser.tabs[tabCount], diff --git a/browser/base/content/test/general/browser_bug537474.js b/browser/base/content/test/general/browser_bug537474.js index b7354aafc07b..d07d255dabf7 100644 --- a/browser/base/content/test/general/browser_bug537474.js +++ b/browser/base/content/test/general/browser_bug537474.js @@ -1,7 +1,8 @@ add_task(async function() { let browserLoadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); window.browserDOMWindow.openURI(makeURI("about:"), null, - Ci.nsIBrowserDOMWindow.OPEN_CURRENTWINDOW, null) + Ci.nsIBrowserDOMWindow.OPEN_CURRENTWINDOW, null, + Services.scriptSecurityManager.getSystemPrincipal()) await browserLoadedPromise; is(gBrowser.currentURI.spec, "about:", "page loads in the current content window"); }); diff --git a/browser/base/content/test/urlbar/browser_bug562649.js b/browser/base/content/test/urlbar/browser_bug562649.js index f113a3344176..cbacd8338742 100644 --- a/browser/base/content/test/urlbar/browser_bug562649.js +++ b/browser/base/content/test/urlbar/browser_bug562649.js @@ -3,7 +3,8 @@ function test() { window.browserDOMWindow.openURI(makeURI(URI), null, Ci.nsIBrowserDOMWindow.OPEN_NEWTAB, - Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL); + Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL, + Services.scriptSecurityManager.getSystemPrincipal()); is(gBrowser.userTypedValue, URI, "userTypedValue matches test URI"); is(gURLBar.value, URI, "location bar value matches test URI"); diff --git a/browser/components/nsBrowserContentHandler.js b/browser/components/nsBrowserContentHandler.js index 5032919526a4..830033ccc7c3 100644 --- a/browser/components/nsBrowserContentHandler.js +++ b/browser/components/nsBrowserContentHandler.js @@ -343,7 +343,8 @@ nsBrowserContentHandler.prototype = { try { while ((uriparam = cmdLine.handleFlagWithParam("new-tab", false))) { let uri = resolveURIInternal(cmdLine, uriparam); - handURIToExistingBrowser(uri, nsIBrowserDOMWindow.OPEN_NEWTAB, cmdLine); + handURIToExistingBrowser(uri, nsIBrowserDOMWindow.OPEN_NEWTAB, cmdLine, false, + Services.scriptSecurityManager.getSystemPrincipal()); cmdLine.preventDefault = true; } } catch (e) { @@ -391,7 +392,8 @@ nsBrowserContentHandler.prototype = { var privateWindowParam = cmdLine.handleFlagWithParam("private-window", false); if (privateWindowParam) { let resolvedURI = resolveURIInternal(cmdLine, privateWindowParam); - handURIToExistingBrowser(resolvedURI, nsIBrowserDOMWindow.OPEN_NEWTAB, cmdLine, true); + handURIToExistingBrowser(resolvedURI, nsIBrowserDOMWindow.OPEN_NEWTAB, cmdLine, true, + Services.scriptSecurityManager.getSystemPrincipal()); cmdLine.preventDefault = true; } } catch (e) { @@ -607,8 +609,8 @@ nsBrowserContentHandler.prototype = { } request.QueryInterface(nsIChannel); - handURIToExistingBrowser(request.URI, - nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, null); + handURIToExistingBrowser(request.URI, nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, null, false, + request.loadInfo.triggeringPrincipal); request.cancel(NS_BINDING_ABORTED); }, @@ -642,7 +644,7 @@ nsBrowserContentHandler.prototype = { }; var gBrowserContentHandler = new nsBrowserContentHandler(); -function handURIToExistingBrowser(uri, location, cmdLine, forcePrivate) { +function handURIToExistingBrowser(uri, location, cmdLine, forcePrivate, triggeringPrincipal) { if (!shouldLoadURI(uri)) return; @@ -667,7 +669,7 @@ function handURIToExistingBrowser(uri, location, cmdLine, forcePrivate) { .getInterface(nsIDOMWindow); var bwin = rootWin.QueryInterface(nsIDOMChromeWindow).browserDOMWindow; bwin.openURI(uri, null, location, - nsIBrowserDOMWindow.OPEN_EXTERNAL); + nsIBrowserDOMWindow.OPEN_EXTERNAL, triggeringPrincipal); } function nsDefaultCommandLineHandler() { @@ -742,7 +744,8 @@ nsDefaultCommandLineHandler.prototype = { // Try to find an existing window and load our URI into the // current tab, new tab, or new window as prefs determine. try { - handURIToExistingBrowser(urilist[0], nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, cmdLine); + handURIToExistingBrowser(urilist[0], nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, cmdLine, false, + Services.scriptSecurityManager.getSystemPrincipal()); return; } catch (e) { } diff --git a/devtools/client/responsive.html/browser/tunnel.js b/devtools/client/responsive.html/browser/tunnel.js index eb1c7fd6a78e..e4e2ebb9c1a3 100644 --- a/devtools/client/responsive.html/browser/tunnel.js +++ b/devtools/client/responsive.html/browser/tunnel.js @@ -241,13 +241,18 @@ function tunnelToInnerBrowser(outer, inner) { let { detail } = event; event.preventDefault(); let uri = Services.io.newURI(detail.url); + let sourceNode = event.dataTransfer.mozSourceNode; + let triggeringPrincipal = sourceNode + ? sourceNode.nodePrincipal + : Services.scriptSecurityManager.getSystemPrincipal(); // This API is used mainly because it's near the path used for with // regular browser tabs (which calls `openURIInFrame`). The more elaborate APIs // that support openers, window features, etc. didn't seem callable from JS and / or // this event doesn't give enough info to use them. browserWindow.browserDOMWindow .openURI(uri, null, Ci.nsIBrowserDOMWindow.OPEN_NEWTAB, - Ci.nsIBrowserDOMWindow.OPEN_NEW); + Ci.nsIBrowserDOMWindow.OPEN_NEW, + triggeringPrincipal); }, stop() { diff --git a/dom/interfaces/base/nsIBrowserDOMWindow.idl b/dom/interfaces/base/nsIBrowserDOMWindow.idl index 2ebad4080608..29142f8a17d6 100644 --- a/dom/interfaces/base/nsIBrowserDOMWindow.idl +++ b/dom/interfaces/base/nsIBrowserDOMWindow.idl @@ -99,11 +99,12 @@ interface nsIBrowserDOMWindow : nsISupports * @param aFlags flags which control the behavior of the load. The * OPEN_EXTERNAL/OPEN_NEW flag is only used when * aWhere == OPEN_DEFAULTWINDOW. + * @param aTriggeringPrincipal the principal that triggered the load of aURI * @return the window into which the URI was opened. */ mozIDOMWindowProxy openURI(in nsIURI aURI, in mozIDOMWindowProxy aOpener, - in short aWhere, in long aFlags); + in short aWhere, in long aFlags, in nsIPrincipal aTriggeringPrincipal); /** * As above, but return the nsIFrameLoaderOwner for the new window. diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 62aacdec9fb6..1d496d83d522 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -4650,6 +4650,7 @@ ContentParent::CommonCreateWindow(PBrowserParent* aThisTab, aResult = newBrowserDOMWin->OpenURI(aURIToLoad, openerWindow, nsIBrowserDOMWindow::OPEN_CURRENTWINDOW, nsIBrowserDOMWindow::OPEN_NEW, + aTriggeringPrincipal, getter_AddRefs(win)); } diff --git a/dom/workers/ServiceWorkerClients.cpp b/dom/workers/ServiceWorkerClients.cpp index a9b8c6efe5e4..7ca5b59da97e 100644 --- a/dom/workers/ServiceWorkerClients.cpp +++ b/dom/workers/ServiceWorkerClients.cpp @@ -754,10 +754,14 @@ private: return NS_ERROR_FAILURE; } + nsCOMPtr triggeringPrincipal = workerPrivate->GetPrincipal(); + MOZ_DIAGNOSTIC_ASSERT(triggeringPrincipal); + nsCOMPtr win; rv = bwin->OpenURI(uri, nullptr, nsIBrowserDOMWindow::OPEN_DEFAULTWINDOW, nsIBrowserDOMWindow::OPEN_NEW, + triggeringPrincipal, getter_AddRefs(win)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; diff --git a/toolkit/xre/nsNativeAppSupportWin.cpp b/toolkit/xre/nsNativeAppSupportWin.cpp index 99aae750824f..8c97a7d02078 100644 --- a/toolkit/xre/nsNativeAppSupportWin.cpp +++ b/toolkit/xre/nsNativeAppSupportWin.cpp @@ -6,6 +6,7 @@ #include "nsNativeAppSupportBase.h" #include "nsNativeAppSupportWin.h" #include "nsAppRunner.h" +#include "nsContentUtils.h" #include "nsXULAppAPI.h" #include "nsString.h" #include "nsIBrowserDOMWindow.h" @@ -1463,6 +1464,7 @@ nsNativeAppSupportWin::OpenBrowserWindow() rv = bwin->OpenURI( uri, 0, nsIBrowserDOMWindow::OPEN_DEFAULTWINDOW, nsIBrowserDOMWindow::OPEN_EXTERNAL, + nsContentUtils::GetSystemPrincipal(), getter_AddRefs( container ) ); if ( NS_SUCCEEDED( rv ) ) return NS_OK; diff --git a/uriloader/exthandler/nsWebHandlerApp.js b/uriloader/exthandler/nsWebHandlerApp.js index ccffbb5458a6..b8e92b03774e 100644 --- a/uriloader/exthandler/nsWebHandlerApp.js +++ b/uriloader/exthandler/nsWebHandlerApp.js @@ -12,6 +12,7 @@ const Cu = Components.utils; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/NetUtil.jsm"); +Cu.import('resource://gre/modules/Services.jsm'); //////////////////////////////////////////////////////////////////////////////// //// nsWebHandler class @@ -143,7 +144,8 @@ nsWebHandlerApp.prototype = { browserDOMWin.openURI(uriToSend, null, // no window.opener Ci.nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, - Ci.nsIBrowserDOMWindow.OPEN_NEW); + Ci.nsIBrowserDOMWindow.OPEN_NEW, + Services.scriptSecurityManager.getSystemPrincipal()); return; }, diff --git a/xpfe/appshell/nsContentTreeOwner.cpp b/xpfe/appshell/nsContentTreeOwner.cpp index 1a73de11a5df..546eaa3850a8 100644 --- a/xpfe/appshell/nsContentTreeOwner.cpp +++ b/xpfe/appshell/nsContentTreeOwner.cpp @@ -35,6 +35,7 @@ #include "nsIMIMEInfo.h" #include "nsIWidget.h" #include "nsWindowWatcher.h" +#include "NullPrincipal.h" #include "mozilla/BrowserElementParent.h" #include "nsIDOMDocument.h" @@ -923,13 +924,15 @@ nsContentTreeOwner::ProvideWindow(mozIDOMWindowProxy* aParent, } // Get a new rendering area from the browserDOMWin. We don't want - // to be starting any loads here, so get it with a null URI. + // to be starting any loads here, so get it with a null URI. Since/ + // we are not loading any URI, we follow the principle of least privlege + // and use a nullPrincipal as the triggeringPrincipal. // // This method handles setting the opener for us, so we don't need to set it // ourselves. - return browserDOMWin->OpenURI(nullptr, aParent, - openLocation, - flags, aReturn); + RefPtr nullPrincipal = NullPrincipal::Create(); + return browserDOMWin->OpenURI(nullptr, aParent, openLocation, + flags, nullPrincipal, aReturn); } } From 8bd02d75b75a04ec4593e543d5549396ca39f713 Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Wed, 5 Jul 2017 21:58:41 +0200 Subject: [PATCH 05/63] Bug 1364016 - Explicitly pass a triggeringPrincipal to openURI on android. r=snorp --- mobile/android/chrome/content/browser.js | 17 +++++++++++------ widget/android/nsWindow.cpp | 2 ++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index 39e7509863ef..16fbf764b912 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -3351,7 +3351,7 @@ function nsBrowserAccess() { nsBrowserAccess.prototype = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserDOMWindow]), - _getBrowser: function _getBrowser(aURI, aOpener, aWhere, aFlags) { + _getBrowser: function _getBrowser(aURI, aOpener, aWhere, aFlags, aTriggeringPrincipal) { let isExternal = !!(aFlags & Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL); if (isExternal && aURI && aURI.schemeIs("chrome")) return null; @@ -3427,7 +3427,8 @@ nsBrowserAccess.prototype = { opener: openerWindow, selected: true, isPrivate: isPrivate, - pinned: pinned }); + pinned: pinned, + triggeringPrincipal: aTriggeringPrincipal}); return tab.browser; } @@ -3435,14 +3436,18 @@ nsBrowserAccess.prototype = { // OPEN_CURRENTWINDOW and illegal values let browser = BrowserApp.selectedBrowser; if (aURI && browser) { - browser.loadURIWithFlags(aURI.spec, loadflags, referrer, null, null); + browser.loadURIWithFlags(aURI.spec, { + flags: loadflags, + referrerURI: referrer, + triggeringPrincipal: aTriggeringPrincipal, + }); } return browser; }, - openURI: function browser_openURI(aURI, aOpener, aWhere, aFlags) { - let browser = this._getBrowser(aURI, aOpener, aWhere, aFlags); + openURI: function browser_openURI(aURI, aOpener, aWhere, aFlags, aTriggeringPrincipal) { + let browser = this._getBrowser(aURI, aOpener, aWhere, aFlags, aTriggeringPrincipal); return browser ? browser.contentWindow : null; }, @@ -3454,7 +3459,7 @@ nsBrowserAccess.prototype = { // // We also ignore aName if it is set, as it is currently only used on the // e10s codepath. - let browser = this._getBrowser(aURI, null, aWhere, aFlags); + let browser = this._getBrowser(aURI, null, aWhere, aFlags, null); if (browser) return browser.QueryInterface(Ci.nsIFrameLoaderOwner); return null; diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index e154a50806c9..dcd266acfab9 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -44,6 +44,7 @@ using mozilla::Unused; #include "nsLayoutUtils.h" #include "nsViewManager.h" +#include "nsContentUtils.h" #include "WidgetUtils.h" #include "nsIDOMSimpleGestureEvent.h" @@ -1409,6 +1410,7 @@ nsWindow::GeckoViewSupport::LoadUri(jni::String::Param aUri, int32_t aFlags) if (NS_FAILED(browserWin->OpenURI( uri, nullptr, flags, nsIBrowserDOMWindow::OPEN_EXTERNAL, + nsContentUtils::GetSystemPrincipal(), getter_AddRefs(newWin)))) { NS_WARNING("Failed to open URI"); } From 44e203215a07a09baf143195511cce4791fbb14a Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Fri, 30 Jun 2017 12:04:02 -0700 Subject: [PATCH 06/63] Bug 1374792: Modify a11y handler to only invoke IGeckoBackChannel::put_HandlerControl once; r=eeejay MozReview-Commit-ID: Bxo0IsAuhBh --- .../ipc/win/handler/AccessibleHandler.cpp | 13 ++++--------- .../win/handler/AccessibleHandlerControl.cpp | 17 ++++++++++++++++- .../ipc/win/handler/AccessibleHandlerControl.h | 3 +++ 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/accessible/ipc/win/handler/AccessibleHandler.cpp b/accessible/ipc/win/handler/AccessibleHandler.cpp index ee2e53171c51..fe4ac95d3dc0 100644 --- a/accessible/ipc/win/handler/AccessibleHandler.cpp +++ b/accessible/ipc/win/handler/AccessibleHandler.cpp @@ -222,17 +222,12 @@ AccessibleHandler::ReadHandlerPayload(IStream* aStream, REFIID aIid) return S_OK; } - long pid = static_cast(::GetCurrentProcessId()); - - RefPtr ctl; - HRESULT hr = gControlFactory.CreateInstance(nullptr, IID_IHandlerControl, - getter_AddRefs(ctl)); - if (SUCCEEDED(hr)) { - hr = mCachedData.mGeckoBackChannel->put_HandlerControl(pid, ctl); - MOZ_ASSERT(SUCCEEDED(hr)); + RefPtr ctl(gControlFactory.GetOrCreateSingleton()); + if (!ctl) { + return E_OUTOFMEMORY; } - return hr; + return ctl->Register(WrapNotNull(mCachedData.mGeckoBackChannel)); } REFIID diff --git a/accessible/ipc/win/handler/AccessibleHandlerControl.cpp b/accessible/ipc/win/handler/AccessibleHandlerControl.cpp index 278ceac7fdd4..94cd4be5e626 100644 --- a/accessible/ipc/win/handler/AccessibleHandlerControl.cpp +++ b/accessible/ipc/win/handler/AccessibleHandlerControl.cpp @@ -132,7 +132,8 @@ AccessibleHandlerControl::Create(AccessibleHandlerControl** aOutObject) } AccessibleHandlerControl::AccessibleHandlerControl() - : mCacheGen(0) + : mIsRegistered(false) + , mCacheGen(0) , mIA2Proxy(mscom::RegisterProxy(L"ia2marshal.dll")) , mHandlerProxy(mscom::RegisterProxy()) { @@ -189,5 +190,19 @@ AccessibleHandlerControl::GetHandlerTypeInfo(ITypeInfo** aOutTypeInfo) aOutTypeInfo); } +HRESULT +AccessibleHandlerControl::Register(NotNull aGecko) +{ + if (mIsRegistered) { + return S_OK; + } + + long pid = static_cast(::GetCurrentProcessId()); + HRESULT hr = aGecko->put_HandlerControl(pid, this); + mIsRegistered = SUCCEEDED(hr); + MOZ_ASSERT(mIsRegistered); + return hr; +} + } // namespace a11y } // namespace mozilla diff --git a/accessible/ipc/win/handler/AccessibleHandlerControl.h b/accessible/ipc/win/handler/AccessibleHandlerControl.h index af29c8445d6c..b44b93236a9d 100644 --- a/accessible/ipc/win/handler/AccessibleHandlerControl.h +++ b/accessible/ipc/win/handler/AccessibleHandlerControl.h @@ -71,10 +71,13 @@ public: HRESULT GetHandlerTypeInfo(ITypeInfo** aOutTypeInfo); + HRESULT Register(NotNull aGecko); + private: AccessibleHandlerControl(); ~AccessibleHandlerControl() = default; + bool mIsRegistered; uint32_t mCacheGen; detail::TextChange mTextChange; UniquePtr mIA2Proxy; From 6ac7e2f671290afa355740e7f8fff40cafc14c20 Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Tue, 4 Jul 2017 16:04:35 -0700 Subject: [PATCH 07/63] Bug 1378141: Make 32-bit a11y builds make more thorough checks to determine which manifest to load; r=eeejay MozReview-Commit-ID: 6Hx7ggqt9Ck --HG-- extra : histedit_source : 28db28e939c947361988cb8e3c8d7932787cf47e --- accessible/ipc/win/PlatformChild.cpp | 17 +- accessible/windows/msaa/Compatibility.cpp | 180 ++++++++++++++++++++++ accessible/windows/msaa/Compatibility.h | 6 + ipc/mscom/MainThreadRuntime.cpp | 29 +--- 4 files changed, 192 insertions(+), 40 deletions(-) diff --git a/accessible/ipc/win/PlatformChild.cpp b/accessible/ipc/win/PlatformChild.cpp index 29d2d6513a2c..7293455a71a1 100644 --- a/accessible/ipc/win/PlatformChild.cpp +++ b/accessible/ipc/win/PlatformChild.cpp @@ -4,10 +4,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "mozilla/a11y/Compatibility.h" #include "mozilla/a11y/PlatformChild.h" #include "mozilla/mscom/EnsureMTA.h" #include "mozilla/mscom/InterceptorLog.h" -#include "mozilla/WindowsVersion.h" #include "Accessible2.h" #include "Accessible2_2.h" @@ -49,20 +49,7 @@ PlatformChild::PlatformChild() , mMiscTypelib(mozilla::mscom::RegisterTypelib(L"Accessible.tlb")) , mSdnTypelib(mozilla::mscom::RegisterTypelib(L"AccessibleMarshal.dll")) { - // The manifest for 32-bit Windows is embedded with resource ID 32. - // The manifest for 64-bit Windows is embedded with resource ID 64. - // Beginning with Windows 10 Creators Update, 32-bit builds use the 64-bit - // manifest. - WORD actCtxResourceId; -#if defined(HAVE_64BIT_BUILD) - actCtxResourceId = 64; -#else - if (IsWin10CreatorsUpdateOrLater()) { - actCtxResourceId = 64; - } else { - actCtxResourceId = 32; - } -#endif + WORD actCtxResourceId = Compatibility::GetActCtxResourceId(); mozilla::mscom::MTADeletePtr tmpActCtxMTA; mozilla::mscom::EnsureMTA([actCtxResourceId, &tmpActCtxMTA]() -> void { diff --git a/accessible/windows/msaa/Compatibility.cpp b/accessible/windows/msaa/Compatibility.cpp index c736ae636514..94cce4cd723b 100644 --- a/accessible/windows/msaa/Compatibility.cpp +++ b/accessible/windows/msaa/Compatibility.cpp @@ -6,12 +6,17 @@ #include "Compatibility.h" +#include "mozilla/WindowsVersion.h" +#include "nsExceptionHandler.h" +#include "nsUnicharUtils.h" #include "nsWindowsDllInterceptor.h" #include "nsWinUtils.h" #include "Statistics.h" #include "mozilla/Preferences.h" +#include + using namespace mozilla; using namespace mozilla::a11y; @@ -203,3 +208,178 @@ Compatibility::Init() } } +#if !defined(HAVE_64BIT_BUILD) + +static bool +ReadCOMRegDefaultString(const nsString& aRegPath, nsAString& aOutBuf) +{ + aOutBuf.Truncate(); + + // Get the required size and type of the registry value. + // We expect either REG_SZ or REG_EXPAND_SZ. + DWORD type; + DWORD bufLen = 0; + LONG result = ::RegGetValue(HKEY_CLASSES_ROOT, aRegPath.get(), + nullptr, RRF_RT_ANY, &type, nullptr, &bufLen); + if (result != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ)) { + return false; + } + + // Now obtain the value + DWORD flags = type == REG_SZ ? RRF_RT_REG_SZ : RRF_RT_REG_EXPAND_SZ; + + aOutBuf.SetLength((bufLen + 1) / sizeof(char16_t)); + + result = ::RegGetValue(HKEY_CLASSES_ROOT, aRegPath.get(), nullptr, + flags, nullptr, aOutBuf.BeginWriting(), &bufLen); + if (result != ERROR_SUCCESS) { + aOutBuf.Truncate(); + return false; + } + + // Truncate terminator + aOutBuf.Truncate((bufLen + 1) / sizeof(char16_t) - 1); + return true; +} + +static bool +IsSystemOleAcc(nsCOMPtr& aFile) +{ + // Use FOLDERID_SystemX86 so that Windows doesn't give us a redirected + // system32 if we're a 32-bit process running on a 64-bit OS. This is + // necessary because the values that we are reading from the registry + // are not redirected; they reference SysWOW64 directly. + PWSTR systemPath = nullptr; + HRESULT hr = ::SHGetKnownFolderPath(FOLDERID_SystemX86, 0, nullptr, + &systemPath); + if (FAILED(hr)) { + return false; + } + + nsCOMPtr oleAcc; + nsresult rv = NS_NewLocalFile(nsDependentString(systemPath), false, + getter_AddRefs(oleAcc)); + + ::CoTaskMemFree(systemPath); + systemPath = nullptr; + + if (NS_FAILED(rv)) { + return false; + } + + rv = oleAcc->Append(NS_LITERAL_STRING("oleacc.dll")); + if (NS_FAILED(rv)) { + return false; + } + + bool isEqual; + rv = oleAcc->Equals(aFile, &isEqual); + return NS_SUCCEEDED(rv) && isEqual; +} + +static bool +IsTypelibPreferred() +{ + // If IAccessible's Proxy/Stub CLSID is kUniversalMarshalerClsid, then any + // external a11y clients are expecting to use a typelib. + NS_NAMED_LITERAL_STRING(kUniversalMarshalerClsid, + "{00020424-0000-0000-C000-000000000046}"); + + NS_NAMED_LITERAL_STRING(kIAccessiblePSClsidPath, + "Interface\\{618736E0-3C3D-11CF-810C-00AA00389B71}\\ProxyStubClsid32"); + + nsAutoString psClsid; + if (!ReadCOMRegDefaultString(kIAccessiblePSClsidPath, psClsid)) { + return false; + } + + return psClsid.Equals(kUniversalMarshalerClsid, + nsCaseInsensitiveStringComparator()); +} + +static bool +IsIAccessibleTypelibRegistered() +{ + // The system default IAccessible typelib is always registered with version + // 1.1, under the neutral locale (LCID 0). + NS_NAMED_LITERAL_STRING(kIAccessibleTypelibRegPath, + "TypeLib\\{1EA4DBF0-3C3B-11CF-810C-00AA00389B71}\\1.1\\0\\win32"); + + nsAutoString typelibPath; + if (!ReadCOMRegDefaultString(kIAccessibleTypelibRegPath, typelibPath)) { + return false; + } + + nsCOMPtr libTestFile; + nsresult rv = NS_NewLocalFile(typelibPath, false, getter_AddRefs(libTestFile)); + if (NS_FAILED(rv)) { + return false; + } + + return IsSystemOleAcc(libTestFile); +} + +static bool +IsIAccessiblePSRegistered() +{ + NS_NAMED_LITERAL_STRING(kIAccessiblePSRegPath, + "CLSID\\{03022430-ABC4-11D0-BDE2-00AA001A1953}\\InProcServer32"); + + nsAutoString proxyStubPath; + if (!ReadCOMRegDefaultString(kIAccessiblePSRegPath, proxyStubPath)) { + return false; + } + + nsCOMPtr libTestFile; + nsresult rv = NS_NewLocalFile(proxyStubPath, false, getter_AddRefs(libTestFile)); + if (NS_FAILED(rv)) { + return false; + } + + return IsSystemOleAcc(libTestFile); +} + +static bool +UseIAccessibleProxyStub() +{ + // If a typelib is preferred then external clients are expecting to use + // typelib marshaling, so we should use that whenever available. + if (IsTypelibPreferred() && IsIAccessibleTypelibRegistered()) { + return false; + } + + // Otherwise we try the proxy/stub + if (IsIAccessiblePSRegistered()) { + return true; + } + + // If we reach this point then something is seriously wrong with the + // IAccessible configuration in the computer's registry. Let's annotate this + // so that we can easily determine this condition during crash analysis. + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IAccessibleConfig"), + NS_LITERAL_CSTRING("NoSystemTypeLibOrPS")); + return false; +} + +#endif // !defined(HAVE_64BIT_BUILD) + +uint16_t +Compatibility::GetActCtxResourceId() +{ +#if defined(HAVE_64BIT_BUILD) + // The manifest for 64-bit Windows is embedded with resource ID 64. + return 64; +#else + // The manifest for 32-bit Windows is embedded with resource ID 32. + // Beginning with Windows 10 Creators Update, 32-bit builds always use the + // 64-bit manifest. Older builds of Windows may or may not require the 64-bit + // manifest: UseIAccessibleProxyStub() determines the course of action. + if (mozilla::IsWin10CreatorsUpdateOrLater() || + UseIAccessibleProxyStub()) { + return 64; + } + + return 32; +#endif // defined(HAVE_64BIT_BUILD) +} + diff --git a/accessible/windows/msaa/Compatibility.h b/accessible/windows/msaa/Compatibility.h index dd9a82f7cdd9..88a3085279bf 100644 --- a/accessible/windows/msaa/Compatibility.h +++ b/accessible/windows/msaa/Compatibility.h @@ -39,6 +39,12 @@ public: */ static bool IsDolphin() { return !!(sConsumers & DOLPHIN); } + /** + * @return ID of a11y manifest resource to be passed to + * mscom::ActivationContext + */ + static uint16_t GetActCtxResourceId(); + private: Compatibility(); Compatibility(const Compatibility&); diff --git a/ipc/mscom/MainThreadRuntime.cpp b/ipc/mscom/MainThreadRuntime.cpp index 8f718dc4763c..f009a836fc62 100644 --- a/ipc/mscom/MainThreadRuntime.cpp +++ b/ipc/mscom/MainThreadRuntime.cpp @@ -6,11 +6,13 @@ #include "mozilla/mscom/MainThreadRuntime.h" +#if defined(ACCESSIBILITY) +#include "mozilla/a11y/Compatibility.h" +#endif #include "mozilla/ArrayUtils.h" #include "mozilla/Assertions.h" #include "mozilla/RefPtr.h" #include "mozilla/UniquePtr.h" -#include "mozilla/WindowsVersion.h" #include "nsWindowsHelpers.h" #include "nsXULAppAPI.h" @@ -34,29 +36,6 @@ struct LocalFreeDeleter // This API from oleaut32.dll is not declared in Windows SDK headers extern "C" void __cdecl SetOaNoCache(void); -#if defined(ACCESSIBILITY) -static WORD -GetActCtxResourceId() -{ - // The manifest for 32-bit Windows is embedded with resource ID 32. - // The manifest for 64-bit Windows is embedded with resource ID 64. - // Beginning with Windows 10 Creators Update, 32-bit builds use the 64-bit - // manifest. - WORD actCtxResourceId; -#if defined(HAVE_64BIT_BUILD) - actCtxResourceId = 64; -#else - if (mozilla::IsWin10CreatorsUpdateOrLater()) { - actCtxResourceId = 64; - } else { - actCtxResourceId = 32; - } -#endif // defined(HAVE_64BIT_BUILD) - - return actCtxResourceId; -} -#endif // defined(ACCESSIBILITY) - namespace mozilla { namespace mscom { @@ -65,7 +44,7 @@ MainThreadRuntime* MainThreadRuntime::sInstance = nullptr; MainThreadRuntime::MainThreadRuntime() : mInitResult(E_UNEXPECTED) #if defined(ACCESSIBILITY) - , mActCtxRgn(::GetActCtxResourceId()) + , mActCtxRgn(a11y::Compatibility::GetActCtxResourceId()) #endif // defined(ACCESSIBILITY) { // We must be the outermost COM initialization on this thread. The COM runtime From 8382fe5f92bef4e728d5f58eb30d38cf80cdb6bf Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Wed, 5 Jul 2017 08:54:59 +0200 Subject: [PATCH 08/63] Bug 1378068 - Test calling getLcovInfo twice. r=nbp --HG-- extra : rebase_source : 59296afd2964cbdde969801b50599464509b8965 --- js/src/jit-test/tests/coverage/getLcovInfo_twice.js | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 js/src/jit-test/tests/coverage/getLcovInfo_twice.js diff --git a/js/src/jit-test/tests/coverage/getLcovInfo_twice.js b/js/src/jit-test/tests/coverage/getLcovInfo_twice.js new file mode 100644 index 000000000000..6acd603c1987 --- /dev/null +++ b/js/src/jit-test/tests/coverage/getLcovInfo_twice.js @@ -0,0 +1,2 @@ +getLcovInfo(); +getLcovInfo(); From 6c8193aed4d4fee80ded06c6f438243afa25e10d Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Wed, 5 Jul 2017 16:56:28 -0400 Subject: [PATCH 09/63] Bug 1377962 - add more override declarations for Android-only methods; r=snorp Trying to get the build running with clang again revealed a few more missing override declarations. --- dom/media/eme/mediadrm/MediaDrmCDMProxy.h | 2 +- gfx/layers/composite/LayerManagerComposite.h | 2 +- gfx/thebes/gfxFT2FontList.h | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dom/media/eme/mediadrm/MediaDrmCDMProxy.h b/dom/media/eme/mediadrm/MediaDrmCDMProxy.h index 23be97cc396f..c2652fa42f69 100644 --- a/dom/media/eme/mediadrm/MediaDrmCDMProxy.h +++ b/dom/media/eme/mediadrm/MediaDrmCDMProxy.h @@ -28,7 +28,7 @@ class MediaDrmCDMCallbackProxy; class MediaDrmCDMProxy : public CDMProxy { public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDrmCDMProxy) + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDrmCDMProxy, override) MediaDrmCDMProxy(dom::MediaKeys* aKeys, const nsAString& aKeySystem, diff --git a/gfx/layers/composite/LayerManagerComposite.h b/gfx/layers/composite/LayerManagerComposite.h index 142d36a286af..47ee2d78dcf7 100644 --- a/gfx/layers/composite/LayerManagerComposite.h +++ b/gfx/layers/composite/LayerManagerComposite.h @@ -514,7 +514,7 @@ private: #endif #if defined(MOZ_WIDGET_ANDROID) public: - virtual void RequestScreenPixels(UiCompositorControllerParent* aController) + virtual void RequestScreenPixels(UiCompositorControllerParent* aController) override { mScreenPixelsTarget = aController; } diff --git a/gfx/thebes/gfxFT2FontList.h b/gfx/thebes/gfxFT2FontList.h index 0722f2e498ee..46944c0b4b90 100644 --- a/gfx/thebes/gfxFT2FontList.h +++ b/gfx/thebes/gfxFT2FontList.h @@ -127,14 +127,14 @@ public: virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName, uint16_t aWeight, int16_t aStretch, - uint8_t aStyle); + uint8_t aStyle) override; virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName, uint16_t aWeight, int16_t aStretch, uint8_t aStyle, const uint8_t* aFontData, - uint32_t aLength); + uint32_t aLength) override; void GetSystemFontList(InfallibleTArray* retValue); @@ -142,7 +142,7 @@ public: return static_cast(gfxPlatformFontList::PlatformFontList()); } - virtual void GetFontFamilyList(nsTArray >& aFamilyArray); + virtual void GetFontFamilyList(nsTArray >& aFamilyArray) override; void WillShutdown(); From a31659e20936c22d4440b744225e553d5c982121 Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Wed, 5 Jul 2017 23:07:11 +0200 Subject: [PATCH 10/63] Bug 1377910 - Don't bother calling DisassociateRequestFromFrame if the frame doesn't have the HasImageRequest bit since it's a no-op in that case. r=dholbert MozReview-Commit-ID: 4LlIFN7tARr --- layout/generic/nsFrame.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 6a8f60ee1151..39aa31290c65 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -857,8 +857,10 @@ AddAndRemoveImageAssociations(nsFrame* aFrame, continue; } - if (imgRequestProxy* req = oldImage.GetImageData()) { - imageLoader->DisassociateRequestFromFrame(req, aFrame); + if (aFrame->HasImageRequest()) { + if (imgRequestProxy* req = oldImage.GetImageData()) { + imageLoader->DisassociateRequestFromFrame(req, aFrame); + } } } } @@ -972,7 +974,7 @@ nsFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) // they won't have the correct size for the border either. if (oldBorderImage != newBorderImage) { // stop and restart the image loading/notification - if (oldBorderImage) { + if (oldBorderImage && HasImageRequest()) { imageLoader->DisassociateRequestFromFrame(oldBorderImage, this); } if (newBorderImage) { From 489c03b415d3e888ed874aa40468d70163b99865 Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Wed, 5 Jul 2017 23:07:11 +0200 Subject: [PATCH 11/63] Bug 1378481 - Assign 'roundingError' in the default branch too, to avoid a maybe-uninitialized compiler warning. r=dholbert MozReview-Commit-ID: CQk1PBaflct --- layout/generic/nsGridContainerFrame.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index a1a1d0efb553..55a18802930e 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -4749,6 +4749,7 @@ nsGridContainerFrame::Tracks::AlignJustifyContent( default: MOZ_ASSERT_UNREACHABLE("unknown align-/justify-content value"); between = 0; // just to avoid a compiler warning + roundingError = 0; // just to avoid a compiler warning } between += mGridGap; for (TrackSize& sz : mSizes) { From bc8aad6edbc155842751071f3abaa49e76251855 Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Wed, 5 Jul 2017 23:14:48 +0200 Subject: [PATCH 12/63] Bug 1377490 - Make nsWindow 'final' to possibly devirtualize some calls. r=jimm MozReview-Commit-ID: 6woRy5Wkogy --- widget/windows/nsWidgetFactory.cpp | 2 +- widget/windows/nsWindow.cpp | 30 +++++++++--------------------- widget/windows/nsWindow.h | 19 +++++-------------- 3 files changed, 15 insertions(+), 36 deletions(-) diff --git a/widget/windows/nsWidgetFactory.cpp b/widget/windows/nsWidgetFactory.cpp index 45d484256728..6370c11c8316 100644 --- a/widget/windows/nsWidgetFactory.cpp +++ b/widget/windows/nsWidgetFactory.cpp @@ -75,7 +75,7 @@ ChildWindowConstructor(nsISupports *aOuter, REFNSIID aIID, if (aOuter != nullptr) { return NS_ERROR_NO_AGGREGATION; } - nsCOMPtr widget = new ChildWindow; + nsCOMPtr widget = new nsWindow(true); return widget->QueryInterface(aIID, aResult); } diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index a224952e1c0b..c9b1e8846a90 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -594,9 +594,10 @@ StaticAutoPtr TIPMessageHandler::sInstance; * **************************************************************/ -nsWindow::nsWindow() +nsWindow::nsWindow(bool aIsChildWindow) : nsWindowBase() , mResizeState(NOT_RESIZING) + , mIsChildWindow(aIsChildWindow) { mIconSmall = nullptr; mIconBig = nullptr; @@ -1149,6 +1150,13 @@ DWORD nsWindow::WindowStyle() } } + if (mIsChildWindow) { + style |= WS_CLIPCHILDREN; + if (!(style & WS_POPUP)) { + style |= WS_CHILD; // WS_POPUP and WS_CHILD are mutually exclusive. + } + } + VERIFY_WINDOW_STYLE(style); return style; } @@ -8344,26 +8352,6 @@ bool nsWindow::OnPointerEvents(UINT msg, WPARAM aWParam, LPARAM aLParam) return true; } -/************************************************************** - ************************************************************** - ** - ** BLOCK: ChildWindow impl. - ** - ** Child window overrides. - ** - ************************************************************** - **************************************************************/ - -// return the style for a child nsWindow -DWORD ChildWindow::WindowStyle() -{ - DWORD style = WS_CLIPCHILDREN | nsWindow::WindowStyle(); - if (!(style & WS_POPUP)) - style |= WS_CHILD; // WS_POPUP and WS_CHILD are mutually exclusive. - VERIFY_WINDOW_STYLE(style); - return style; -} - void nsWindow::GetCompositorWidgetInitData(mozilla::widget::CompositorWidgetInitData* aInitData) { diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index f2c0e131270f..41b41726d3b2 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -67,7 +67,7 @@ struct MSGResult; * Native WIN32 window wrapper. */ -class nsWindow : public nsWindowBase +class nsWindow final : public nsWindowBase { typedef mozilla::TimeStamp TimeStamp; typedef mozilla::TimeDuration TimeDuration; @@ -78,7 +78,7 @@ class nsWindow : public nsWindowBase typedef mozilla::widget::IMEContext IMEContext; public: - nsWindow(); + explicit nsWindow(bool aIsChildWindow = false); NS_DECL_ISUPPORTS_INHERITED @@ -635,6 +635,9 @@ protected: // Whether we're in the process of sending a WM_SETTEXT ourselves bool mSendingSetText; + // Whether we we're created as a NS_CHILD_CID window (aka ChildWindow) or not. + bool mIsChildWindow : 1; + // The point in time at which the last paint completed. We use this to avoid // painting too rapidly in response to frequent input events. TimeStamp mLastPaintEndTime; @@ -662,16 +665,4 @@ protected: WinPointerEvents mPointerEvents; }; -/** - * A child window is a window with different style. - */ -class ChildWindow : public nsWindow { - -public: - ChildWindow() {} - -protected: - virtual DWORD WindowStyle(); -}; - #endif // Window_h__ From 25c8269307069971ec9829a761db2dea5868b9e8 Mon Sep 17 00:00:00 2001 From: Ryan Hunt Date: Wed, 5 Jul 2017 16:20:40 -0500 Subject: [PATCH 13/63] Bug 1377814 - Don't schedule an empty transaction on an APZ focus sequence number update. r=botond MozReview-Commit-ID: 3SERspy0w9s --HG-- extra : rebase_source : c0f4e1e0c4f3db2aa827cd1dd0692461bf02d060 extra : amend_source : 46c66f36ce0865ba5d3a6c1b9f4a9764595db447 --- layout/base/PresShell.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp index 5de953e51ef0..bc1b3fbc4003 100644 --- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -7169,9 +7169,6 @@ PresShell::HandleEvent(nsIFrame* aFrame, // Update the latest focus sequence number with this new sequence number if (mAPZFocusSequenceNumber < aEvent->mFocusSequenceNumber) { mAPZFocusSequenceNumber = aEvent->mFocusSequenceNumber; - - // Schedule an empty transaction to transmit this focus update - aFrame->SchedulePaint(nsIFrame::PAINT_COMPOSITE_ONLY); } if (sPointerEventEnabled) { From 6c67bff8a5aea44a7a4251d3f6e3c474459ac53d Mon Sep 17 00:00:00 2001 From: Honza Bambas Date: Wed, 5 Jul 2017 11:24:00 -0400 Subject: [PATCH 14/63] Bug 1368110 - Create child redirect target (new) channel using parent target channel's original URI. r=jduell, r=bz --- netwerk/protocol/http/HttpChannelChild.cpp | 14 ++++++++------ netwerk/protocol/http/HttpChannelParent.cpp | 15 +++++++++++---- netwerk/protocol/http/PHttpChannel.ipdl | 2 +- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp index ef74e5b50a18..f1abce8010d3 100644 --- a/netwerk/protocol/http/HttpChannelChild.cpp +++ b/netwerk/protocol/http/HttpChannelChild.cpp @@ -1598,15 +1598,17 @@ HttpChannelChild::SetupRedirect(nsIURI* uri, void HttpChannelChild::Redirect1Begin(const uint32_t& registrarId, - const URIParams& newUri, + const URIParams& newOriginalURI, const uint32_t& redirectFlags, const nsHttpResponseHead& responseHead, const nsACString& securityInfoSerialization, const uint64_t& channelId) { + nsresult rv; + LOG(("HttpChannelChild::Redirect1Begin [this=%p]\n", this)); - nsCOMPtr uri = DeserializeURI(newUri); + nsCOMPtr uri = DeserializeURI(newOriginalURI); if (!securityInfoSerialization.IsEmpty()) { NS_DeserializeObject(securityInfoSerialization, @@ -1614,10 +1616,10 @@ HttpChannelChild::Redirect1Begin(const uint32_t& registrarId, } nsCOMPtr newChannel; - nsresult rv = SetupRedirect(uri, - &responseHead, - redirectFlags, - getter_AddRefs(newChannel)); + rv = SetupRedirect(uri, + &responseHead, + redirectFlags, + getter_AddRefs(newChannel)); if (NS_SUCCEEDED(rv)) { if (mRedirectChannelChild) { diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp index 84858280455d..f2603f371794 100644 --- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -1754,6 +1754,8 @@ HttpChannelParent::StartRedirect(uint32_t registrarId, uint32_t redirectFlags, nsIAsyncVerifyRedirectCallback* callback) { + nsresult rv; + LOG(("HttpChannelParent::StartRedirect [this=%p, registrarId=%" PRIu32 " " "newChannel=%p callback=%p]\n", this, registrarId, newChannel, callback)); @@ -1761,11 +1763,16 @@ HttpChannelParent::StartRedirect(uint32_t registrarId, if (mIPCClosed) return NS_BINDING_ABORTED; - nsCOMPtr newURI; - newChannel->GetURI(getter_AddRefs(newURI)); + // Sending down the original URI, because that is the URI we have + // to construct the channel from - this is the URI we've been actually + // redirected to. URI of the channel may be an inner channel URI. + // URI of the channel will be reconstructed by the protocol handler + // on the child process, no need to send it then. + nsCOMPtr newOriginalURI; + newChannel->GetOriginalURI(getter_AddRefs(newOriginalURI)); URIParams uriParams; - SerializeURI(newURI, uriParams); + SerializeURI(newOriginalURI, uriParams); nsCString secInfoSerialization; UpdateAndSerializeSecurityInfo(secInfoSerialization); @@ -1776,7 +1783,7 @@ HttpChannelParent::StartRedirect(uint32_t registrarId, uint64_t channelId; nsCOMPtr httpChannel = do_QueryInterface(newChannel); if (httpChannel) { - nsresult rv = httpChannel->GetChannelId(&channelId); + rv = httpChannel->GetChannelId(&channelId); NS_ENSURE_SUCCESS(rv, NS_BINDING_ABORTED); } diff --git a/netwerk/protocol/http/PHttpChannel.ipdl b/netwerk/protocol/http/PHttpChannel.ipdl index 5a9461719284..ac65821e3917 100644 --- a/netwerk/protocol/http/PHttpChannel.ipdl +++ b/netwerk/protocol/http/PHttpChannel.ipdl @@ -117,7 +117,7 @@ child: // Called to initiate content channel redirect, starts talking to sinks // on the content process and reports result via Redirect2Verify above async Redirect1Begin(uint32_t registrarId, - URIParams newUri, + URIParams newOriginalUri, uint32_t redirectFlags, nsHttpResponseHead responseHead, nsCString securityInfoSerialization, From 6b905b817a777a4052ff2dbd535ca1d87de63b9d Mon Sep 17 00:00:00 2001 From: Joanmarie Diggs Date: Tue, 4 Jul 2017 18:24:00 -0400 Subject: [PATCH 15/63] Bug 1358462 - Elements with role="region" and no accessible name should be mapped according to host language. r=MarcoZ Perform a sanity check in Accessible::ARIATransformRole() for the internal REGION role: If there is no accessible name, transform the ARIA role into the native host language role. Also perform a sanity check when getting the AXSubrole in macOS: If the roleAtom is nsGkAtoms::region, only return AXLandmarkRegion if the internal role is REGION. --- accessible/generic/Accessible.cpp | 16 ++++++++++++++++ accessible/mac/mozAccessible.mm | 2 +- accessible/tests/mochitest/role/test_aria.html | 12 ++++++++++-- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/accessible/generic/Accessible.cpp b/accessible/generic/Accessible.cpp index e8db18f38333..1cbf9460ee41 100644 --- a/accessible/generic/Accessible.cpp +++ b/accessible/generic/Accessible.cpp @@ -1414,6 +1414,22 @@ Accessible::SetCurValue(double aValue) role Accessible::ARIATransformRole(role aRole) { + // Beginning with ARIA 1.1, user agents are expected to use the native host + // language role of the element when the region role is used without a name. + // https://rawgit.com/w3c/aria/master/core-aam/core-aam.html#role-map-region + // + // XXX: While the name computation algorithm can be non-trivial in the general + // case, it should not be especially bad here: If the author hasn't used the + // region role, this calculation won't occur. And the region role's name + // calculation rule excludes name from content. That said, this use case is + // another example of why we should consider caching the accessible name. See: + // https://bugzilla.mozilla.org/show_bug.cgi?id=1378235. + if (aRole == roles::REGION) { + nsAutoString name; + Name(name); + return name.IsEmpty() ? NativeRole() : aRole; + } + // XXX: these unfortunate exceptions don't fit into the ARIA table. This is // where the accessible role depends on both the role and ARIA state. if (aRole == roles::PUSHBUTTON) { diff --git a/accessible/mac/mozAccessible.mm b/accessible/mac/mozAccessible.mm index 2db33dc45c96..a217d945466a 100644 --- a/accessible/mac/mozAccessible.mm +++ b/accessible/mac/mozAccessible.mm @@ -798,7 +798,7 @@ ConvertToNSArray(nsTArray& aArray) if (roleAtom == nsGkAtoms::note_) return @"AXDocumentNote"; if (roleAtom == nsGkAtoms::region) - return @"AXLandmarkRegion"; + return mRole == roles::REGION ? @"AXLandmarkRegion" : nil; if (roleAtom == nsGkAtoms::status) return @"AXApplicationStatus"; if (roleAtom == nsGkAtoms::tabpanel) diff --git a/accessible/tests/mochitest/role/test_aria.html b/accessible/tests/mochitest/role/test_aria.html index 31f3b169194e..9a18598af0ae 100644 --- a/accessible/tests/mochitest/role/test_aria.html +++ b/accessible/tests/mochitest/role/test_aria.html @@ -54,7 +54,11 @@ testRole("aria_progressbar", ROLE_PROGRESSBAR); testRole("aria_radio", ROLE_RADIOBUTTON); testRole("aria_radiogroup", ROLE_RADIO_GROUP); - testRole("aria_region", ROLE_REGION); + testRole("aria_region_no_name", ROLE_TEXT); + testRole("aria_region_has_label", ROLE_REGION); + testRole("aria_region_has_labelledby", ROLE_REGION); + testRole("aria_region_has_title", ROLE_REGION); + testRole("aria_region_empty_name", ROLE_TEXT); testRole("aria_row", ROLE_ROW); testRole("aria_rowheader", ROLE_ROWHEADER); testRole("aria_scrollbar", ROLE_SCROLLBAR); @@ -238,7 +242,11 @@ - + + + + + From f16762036fcb9067b8ebc3baa6a3e0dadcda6ea9 Mon Sep 17 00:00:00 2001 From: Geoff Brown Date: Wed, 5 Jul 2017 16:02:41 -0600 Subject: [PATCH 16/63] Bug 1378251 - Upload Windows TC build crash dumps as artifacts; r=ted The MINIDUMP_SAVE_PATH had been set incorrectly in these jobs. Now it is set to the taskcluster upload directory, so when a crash dump is produced, the .dmp and .extra files are uploaded and made available as artifacts. --- .../configs/builds/taskcluster_firefox_win32_clang.py | 2 +- .../configs/builds/taskcluster_firefox_win32_clang_debug.py | 2 +- .../configs/builds/taskcluster_firefox_win32_noopt_debug.py | 2 +- .../configs/builds/taskcluster_firefox_win64_asan_debug.py | 2 +- .../configs/builds/taskcluster_firefox_win64_asan_opt.py | 2 +- .../configs/builds/taskcluster_firefox_win64_clang.py | 2 +- .../configs/builds/taskcluster_firefox_win64_clang_debug.py | 2 +- .../configs/builds/taskcluster_firefox_win64_noopt_debug.py | 2 +- .../configs/builds/taskcluster_firefox_windows_32_addondevel.py | 2 +- .../configs/builds/taskcluster_firefox_windows_32_debug.py | 2 +- .../configs/builds/taskcluster_firefox_windows_32_opt.py | 2 +- .../configs/builds/taskcluster_firefox_windows_64_addondevel.py | 2 +- .../configs/builds/taskcluster_firefox_windows_64_debug.py | 2 +- .../configs/builds/taskcluster_firefox_windows_64_opt.py | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/testing/mozharness/configs/builds/taskcluster_firefox_win32_clang.py b/testing/mozharness/configs/builds/taskcluster_firefox_win32_clang.py index d6465dd23bcf..4b9a09cc4ebf 100644 --- a/testing/mozharness/configs/builds/taskcluster_firefox_win32_clang.py +++ b/testing/mozharness/configs/builds/taskcluster_firefox_win32_clang.py @@ -70,7 +70,7 @@ config = { }, "check_test_env": { 'MINIDUMP_STACKWALK': '%(abs_tools_dir)s\\breakpad\\win32\\minidump_stackwalk.exe', - 'MINIDUMP_SAVE_PATH': '%(base_work_dir)s\\minidumps', + 'MINIDUMP_SAVE_PATH': os.path.join(os.getcwd(), 'public', 'build'), }, 'src_mozconfig': 'browser\\config\\mozconfigs\\win32\\clang', 'artifact_flag_build_variant_in_try': None, diff --git a/testing/mozharness/configs/builds/taskcluster_firefox_win32_clang_debug.py b/testing/mozharness/configs/builds/taskcluster_firefox_win32_clang_debug.py index a0ad7530b9af..00465349cf4b 100644 --- a/testing/mozharness/configs/builds/taskcluster_firefox_win32_clang_debug.py +++ b/testing/mozharness/configs/builds/taskcluster_firefox_win32_clang_debug.py @@ -72,7 +72,7 @@ config = { }, "check_test_env": { 'MINIDUMP_STACKWALK': '%(abs_tools_dir)s\\breakpad\\win32\\minidump_stackwalk.exe', - 'MINIDUMP_SAVE_PATH': '%(base_work_dir)s\\minidumps', + 'MINIDUMP_SAVE_PATH': os.path.join(os.getcwd(), 'public', 'build'), }, 'src_mozconfig': 'browser\\config\\mozconfigs\\win32\\clang-debug', 'artifact_flag_build_variant_in_try': None, diff --git a/testing/mozharness/configs/builds/taskcluster_firefox_win32_noopt_debug.py b/testing/mozharness/configs/builds/taskcluster_firefox_win32_noopt_debug.py index b59d1dcc5933..41ebd8f63d29 100644 --- a/testing/mozharness/configs/builds/taskcluster_firefox_win32_noopt_debug.py +++ b/testing/mozharness/configs/builds/taskcluster_firefox_win32_noopt_debug.py @@ -74,7 +74,7 @@ config = { }, "check_test_env": { 'MINIDUMP_STACKWALK': '%(abs_tools_dir)s\\breakpad\\win32\\minidump_stackwalk.exe', - 'MINIDUMP_SAVE_PATH': '%(base_work_dir)s\\minidumps', + 'MINIDUMP_SAVE_PATH': os.path.join(os.getcwd(), 'public', 'build'), }, 'src_mozconfig': 'browser\\config\\mozconfigs\\win32\\noopt-debug', 'artifact_flag_build_variant_in_try': None, diff --git a/testing/mozharness/configs/builds/taskcluster_firefox_win64_asan_debug.py b/testing/mozharness/configs/builds/taskcluster_firefox_win64_asan_debug.py index 48b1073e8308..8e1692979610 100644 --- a/testing/mozharness/configs/builds/taskcluster_firefox_win64_asan_debug.py +++ b/testing/mozharness/configs/builds/taskcluster_firefox_win64_asan_debug.py @@ -68,7 +68,7 @@ config = { }, "check_test_env": { 'MINIDUMP_STACKWALK': '%(abs_tools_dir)s\\breakpad\\win64\\minidump_stackwalk.exe', - 'MINIDUMP_SAVE_PATH': '%(base_work_dir)s\\minidumps', + 'MINIDUMP_SAVE_PATH': os.path.join(os.getcwd(), 'public', 'build'), }, 'src_mozconfig': 'browser\\config\\mozconfigs\\win64\\debug-asan', ######################################################################### diff --git a/testing/mozharness/configs/builds/taskcluster_firefox_win64_asan_opt.py b/testing/mozharness/configs/builds/taskcluster_firefox_win64_asan_opt.py index 51953e0d10ae..4c2efb833fe0 100644 --- a/testing/mozharness/configs/builds/taskcluster_firefox_win64_asan_opt.py +++ b/testing/mozharness/configs/builds/taskcluster_firefox_win64_asan_opt.py @@ -66,7 +66,7 @@ config = { }, "check_test_env": { 'MINIDUMP_STACKWALK': '%(abs_tools_dir)s\\breakpad\\win64\\minidump_stackwalk.exe', - 'MINIDUMP_SAVE_PATH': '%(base_work_dir)s\\minidumps', + 'MINIDUMP_SAVE_PATH': os.path.join(os.getcwd(), 'public', 'build'), }, 'src_mozconfig': 'browser\\config\\mozconfigs\\win64\\nightly-asan', ######################################################################### diff --git a/testing/mozharness/configs/builds/taskcluster_firefox_win64_clang.py b/testing/mozharness/configs/builds/taskcluster_firefox_win64_clang.py index b072a27eec3d..afcdb8d3d76c 100644 --- a/testing/mozharness/configs/builds/taskcluster_firefox_win64_clang.py +++ b/testing/mozharness/configs/builds/taskcluster_firefox_win64_clang.py @@ -66,7 +66,7 @@ config = { }, "check_test_env": { 'MINIDUMP_STACKWALK': '%(abs_tools_dir)s\\breakpad\\win64\\minidump_stackwalk.exe', - 'MINIDUMP_SAVE_PATH': '%(base_work_dir)s\\minidumps', + 'MINIDUMP_SAVE_PATH': os.path.join(os.getcwd(), 'public', 'build'), }, 'src_mozconfig': 'browser\\config\\mozconfigs\\win64\\clang', 'artifact_flag_build_variant_in_try': None, diff --git a/testing/mozharness/configs/builds/taskcluster_firefox_win64_clang_debug.py b/testing/mozharness/configs/builds/taskcluster_firefox_win64_clang_debug.py index 277d931c3580..0a2dba2aa4a5 100644 --- a/testing/mozharness/configs/builds/taskcluster_firefox_win64_clang_debug.py +++ b/testing/mozharness/configs/builds/taskcluster_firefox_win64_clang_debug.py @@ -68,7 +68,7 @@ config = { }, "check_test_env": { 'MINIDUMP_STACKWALK': '%(abs_tools_dir)s\\breakpad\\win64\\minidump_stackwalk.exe', - 'MINIDUMP_SAVE_PATH': '%(base_work_dir)s\\minidumps', + 'MINIDUMP_SAVE_PATH': os.path.join(os.getcwd(), 'public', 'build'), }, 'src_mozconfig': 'browser\\config\\mozconfigs\\win64\\clang-debug', 'artifact_flag_build_variant_in_try': None, diff --git a/testing/mozharness/configs/builds/taskcluster_firefox_win64_noopt_debug.py b/testing/mozharness/configs/builds/taskcluster_firefox_win64_noopt_debug.py index 20b1f03f34b0..73ec671d167a 100644 --- a/testing/mozharness/configs/builds/taskcluster_firefox_win64_noopt_debug.py +++ b/testing/mozharness/configs/builds/taskcluster_firefox_win64_noopt_debug.py @@ -68,7 +68,7 @@ config = { }, "check_test_env": { 'MINIDUMP_STACKWALK': '%(abs_tools_dir)s\\breakpad\\win64\\minidump_stackwalk.exe', - 'MINIDUMP_SAVE_PATH': '%(base_work_dir)s\\minidumps', + 'MINIDUMP_SAVE_PATH': os.path.join(os.getcwd(), 'public', 'build'), }, 'src_mozconfig': 'browser\\config\\mozconfigs\\win64\\noopt-debug', 'artifact_flag_build_variant_in_try': None, diff --git a/testing/mozharness/configs/builds/taskcluster_firefox_windows_32_addondevel.py b/testing/mozharness/configs/builds/taskcluster_firefox_windows_32_addondevel.py index 1b6fc2bbddb7..309ad2b3a74b 100644 --- a/testing/mozharness/configs/builds/taskcluster_firefox_windows_32_addondevel.py +++ b/testing/mozharness/configs/builds/taskcluster_firefox_windows_32_addondevel.py @@ -70,7 +70,7 @@ config = { }, "check_test_env": { 'MINIDUMP_STACKWALK': '%(abs_tools_dir)s\\breakpad\\win32\\minidump_stackwalk.exe', - 'MINIDUMP_SAVE_PATH': '%(base_work_dir)s\\minidumps', + 'MINIDUMP_SAVE_PATH': os.path.join(os.getcwd(), 'public', 'build'), }, 'src_mozconfig': 'browser/config/mozconfigs/win32/add-on-devel', ######################################################################### diff --git a/testing/mozharness/configs/builds/taskcluster_firefox_windows_32_debug.py b/testing/mozharness/configs/builds/taskcluster_firefox_windows_32_debug.py index 432a7b9c92b6..9e0ba4d0fafe 100644 --- a/testing/mozharness/configs/builds/taskcluster_firefox_windows_32_debug.py +++ b/testing/mozharness/configs/builds/taskcluster_firefox_windows_32_debug.py @@ -72,7 +72,7 @@ config = { }, "check_test_env": { 'MINIDUMP_STACKWALK': '%(abs_tools_dir)s\\breakpad\\win32\\minidump_stackwalk.exe', - 'MINIDUMP_SAVE_PATH': '%(base_work_dir)s\\minidumps', + 'MINIDUMP_SAVE_PATH': os.path.join(os.getcwd(), 'public', 'build'), }, 'src_mozconfig': 'browser\\config\\mozconfigs\\win32\\debug', ######################################################################### diff --git a/testing/mozharness/configs/builds/taskcluster_firefox_windows_32_opt.py b/testing/mozharness/configs/builds/taskcluster_firefox_windows_32_opt.py index 629ef0e1d791..a89ef83d3387 100644 --- a/testing/mozharness/configs/builds/taskcluster_firefox_windows_32_opt.py +++ b/testing/mozharness/configs/builds/taskcluster_firefox_windows_32_opt.py @@ -70,7 +70,7 @@ config = { }, "check_test_env": { 'MINIDUMP_STACKWALK': '%(abs_tools_dir)s\\breakpad\\win32\\minidump_stackwalk.exe', - 'MINIDUMP_SAVE_PATH': '%(base_work_dir)s\\minidumps', + 'MINIDUMP_SAVE_PATH': os.path.join(os.getcwd(), 'public', 'build'), }, 'src_mozconfig': 'browser\\config\\mozconfigs\\win32\\nightly', ######################################################################### diff --git a/testing/mozharness/configs/builds/taskcluster_firefox_windows_64_addondevel.py b/testing/mozharness/configs/builds/taskcluster_firefox_windows_64_addondevel.py index d86bc2a86567..d937f7fa1287 100644 --- a/testing/mozharness/configs/builds/taskcluster_firefox_windows_64_addondevel.py +++ b/testing/mozharness/configs/builds/taskcluster_firefox_windows_64_addondevel.py @@ -67,7 +67,7 @@ config = { }, "check_test_env": { 'MINIDUMP_STACKWALK': '%(abs_tools_dir)s\\breakpad\\win64\\minidump_stackwalk.exe', - 'MINIDUMP_SAVE_PATH': '%(base_work_dir)s\\minidumps', + 'MINIDUMP_SAVE_PATH': os.path.join(os.getcwd(), 'public', 'build'), }, 'src_mozconfig': 'browser/config/mozconfigs/win64/add-on-devel', ######################################################################### diff --git a/testing/mozharness/configs/builds/taskcluster_firefox_windows_64_debug.py b/testing/mozharness/configs/builds/taskcluster_firefox_windows_64_debug.py index 4b7df97ee04e..b675cd325a4d 100644 --- a/testing/mozharness/configs/builds/taskcluster_firefox_windows_64_debug.py +++ b/testing/mozharness/configs/builds/taskcluster_firefox_windows_64_debug.py @@ -68,7 +68,7 @@ config = { }, "check_test_env": { 'MINIDUMP_STACKWALK': '%(abs_tools_dir)s\\breakpad\\win64\\minidump_stackwalk.exe', - 'MINIDUMP_SAVE_PATH': '%(base_work_dir)s\\minidumps', + 'MINIDUMP_SAVE_PATH': os.path.join(os.getcwd(), 'public', 'build'), }, 'src_mozconfig': 'browser\\config\\mozconfigs\\win64\\debug', ######################################################################### diff --git a/testing/mozharness/configs/builds/taskcluster_firefox_windows_64_opt.py b/testing/mozharness/configs/builds/taskcluster_firefox_windows_64_opt.py index f6478c41f745..045caa5cd5b6 100644 --- a/testing/mozharness/configs/builds/taskcluster_firefox_windows_64_opt.py +++ b/testing/mozharness/configs/builds/taskcluster_firefox_windows_64_opt.py @@ -66,7 +66,7 @@ config = { }, "check_test_env": { 'MINIDUMP_STACKWALK': '%(abs_tools_dir)s\\breakpad\\win64\\minidump_stackwalk.exe', - 'MINIDUMP_SAVE_PATH': '%(base_work_dir)s\\minidumps', + 'MINIDUMP_SAVE_PATH': os.path.join(os.getcwd(), 'public', 'build'), }, 'src_mozconfig': 'browser\\config\\mozconfigs\\win64\\nightly', ######################################################################### From e01724861969df4728944ece44846181e2961504 Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Wed, 5 Jul 2017 15:08:13 -0700 Subject: [PATCH 17/63] Backed out changeset 8eb0c588a43e (bug 1378218) for frequent win debug xpcshell failures in test_sanitizer.js a=backout MozReview-Commit-ID: EsfsviyLVbw --- dom/base/Link.cpp | 3 +-- dom/base/Link.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/dom/base/Link.cpp b/dom/base/Link.cpp index 31890d418236..e3bd3a884953 100644 --- a/dom/base/Link.cpp +++ b/dom/base/Link.cpp @@ -197,8 +197,7 @@ Link::LinkState() const // If we have not yet registered for notifications and need to, // due to our href changing, register now! - if (!mRegistered && mNeedsRegistration && element->IsInComposedDoc() && - !HasPendingLinkUpdate()) { + if (!mRegistered && mNeedsRegistration && element->IsInComposedDoc()) { // Only try and register once. self->mNeedsRegistration = false; diff --git a/dom/base/Link.h b/dom/base/Link.h index 77833e640a22..00ea087f82c2 100644 --- a/dom/base/Link.h +++ b/dom/base/Link.h @@ -126,7 +126,7 @@ public: void TryDNSPrefetchPreconnectOrPrefetchOrPrerender(); void CancelPrefetch(); - bool HasPendingLinkUpdate() const { return mHasPendingLinkUpdate; } + bool HasPendingLinkUpdate() { return mHasPendingLinkUpdate; } void SetHasPendingLinkUpdate() { mHasPendingLinkUpdate = true; } void ClearHasPendingLinkUpdate() { mHasPendingLinkUpdate = false; } From 809522fb3ac4786a0d65d6df0dfd3fa45076fbd7 Mon Sep 17 00:00:00 2001 From: Jocelyn Liu Date: Thu, 15 Jun 2017 11:11:19 -0700 Subject: [PATCH 18/63] Bug 1367694 - Set payment request's shippingOption and shippingType attributes when creating it. r=baku Per spec, given details and options parameters of PaymentRequest constructor, 1) if details.shippingOptions exists and IDs of all shipping options are unique, request's shippingOption will be set to the last selected option's ID. Otherwise, set request's shippingOption to null. 2) if options.requestShipping is ture, set request's shippingType to options.shippingType. Otherwise, set request's shippingType to null. --- dom/payments/PaymentRequest.cpp | 14 +++- dom/payments/PaymentRequest.h | 5 ++ dom/payments/PaymentRequestManager.cpp | 111 +++++++++++++++++++------ 3 files changed, 105 insertions(+), 25 deletions(-) diff --git a/dom/payments/PaymentRequest.cpp b/dom/payments/PaymentRequest.cpp index 2303482ecd61..87a49fe4e7a9 100644 --- a/dom/payments/PaymentRequest.cpp +++ b/dom/payments/PaymentRequest.cpp @@ -589,6 +589,12 @@ PaymentRequest::UpdateShippingAddress(const nsAString& aCountry, return DispatchUpdateEvent(NS_LITERAL_STRING("shippingaddresschange")); } +void +PaymentRequest::SetShippingOption(const nsAString& aShippingOption) +{ + mShippingOption = aShippingOption; +} + void PaymentRequest::GetShippingOption(nsAString& aRetVal) const { @@ -604,10 +610,16 @@ PaymentRequest::UpdateShippingOption(const nsAString& aShippingOption) return DispatchUpdateEvent(NS_LITERAL_STRING("shippingoptionchange")); } +void +PaymentRequest::SetShippingType(const Nullable& aShippingType) +{ + mShippingType = aShippingType; +} + Nullable PaymentRequest::GetShippingType() const { - return nullptr; + return mShippingType; } PaymentRequest::~PaymentRequest() diff --git a/dom/payments/PaymentRequest.h b/dom/payments/PaymentRequest.h index f2b2cecb861f..57f0b88ad257 100644 --- a/dom/payments/PaymentRequest.h +++ b/dom/payments/PaymentRequest.h @@ -106,12 +106,15 @@ public: const nsAString& aRecipient, const nsAString& aPhone); + + void SetShippingOption(const nsAString& aShippingOption); void GetShippingOption(nsAString& aRetVal) const; nsresult UpdateShippingOption(const nsAString& aShippingOption); nsresult UpdatePayment(const PaymentDetailsUpdate& aDetails); void AbortUpdate(nsresult aRv); + void SetShippingType(const Nullable& aShippingType); Nullable GetShippingType() const; IMPL_EVENT_HANDLER(shippingaddresschange); @@ -143,6 +146,8 @@ protected: // It is populated when the user chooses a shipping option. nsString mShippingOption; + Nullable mShippingType; + // "true" when there is a pending updateWith() call to update the payment request // and "false" otherwise. bool mUpdating; diff --git a/dom/payments/PaymentRequestManager.cpp b/dom/payments/PaymentRequestManager.cpp index e5f9e1bb620b..b02334ed3276 100644 --- a/dom/payments/PaymentRequestManager.cpp +++ b/dom/payments/PaymentRequestManager.cpp @@ -103,7 +103,8 @@ nsresult ConvertDetailsBase(const PaymentDetailsBase& aDetails, nsTArray& aDisplayItems, nsTArray& aShippingOptions, - nsTArray& aModifiers) + nsTArray& aModifiers, + bool aResetShippingOptions) { if (aDetails.mDisplayItems.WasPassed()) { for (const PaymentItem& item : aDetails.mDisplayItems.Value()) { @@ -112,7 +113,7 @@ ConvertDetailsBase(const PaymentDetailsBase& aDetails, aDisplayItems.AppendElement(displayItem); } } - if (aDetails.mShippingOptions.WasPassed()) { + if (aDetails.mShippingOptions.WasPassed() && !aResetShippingOptions) { for (const PaymentShippingOption& option : aDetails.mShippingOptions.Value()) { IPCPaymentShippingOption shippingOption; ConvertShippingOption(option, shippingOption); @@ -134,13 +135,14 @@ ConvertDetailsBase(const PaymentDetailsBase& aDetails, nsresult ConvertDetailsInit(const PaymentDetailsInit& aDetails, - IPCPaymentDetails& aIPCDetails) + IPCPaymentDetails& aIPCDetails, + bool aResetShippingOptions) { // Convert PaymentDetailsBase members nsTArray displayItems; nsTArray shippingOptions; nsTArray modifiers; - nsresult rv = ConvertDetailsBase(aDetails, displayItems, shippingOptions, modifiers); + nsresult rv = ConvertDetailsBase(aDetails, displayItems, shippingOptions, modifiers, aResetShippingOptions); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -175,7 +177,10 @@ ConvertDetailsUpdate(const PaymentDetailsUpdate& aDetails, nsTArray displayItems; nsTArray shippingOptions; nsTArray modifiers; - nsresult rv = ConvertDetailsBase(aDetails, displayItems, shippingOptions, modifiers); + // [TODO] Populate a boolean flag as aResetShippingOptions based on the + // result of processing details.shippingOptions in UpdatePayment method. + nsresult rv = ConvertDetailsBase( + aDetails, displayItems, shippingOptions, modifiers, false); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -352,6 +357,37 @@ PaymentRequestManager::GetPaymentRequestById(const nsAString& aRequestId) return nullptr; } +void +GetSelectedShippingOption(const PaymentDetailsInit& aDetails, + nsAString& aOption, + bool* aResetOptions) +{ + SetDOMStringToNull(aOption); + if (!aDetails.mShippingOptions.WasPassed()) { + return; + } + + nsTArray seenIDs; + const Sequence& shippingOptions = + aDetails.mShippingOptions.Value(); + for (const PaymentShippingOption& shippingOption : shippingOptions) { + // If there are duplicate IDs present in the shippingOptions, reset aOption + // to null and set resetOptions flag to reset details.shippingOptions later + // when converting to IPC structure. + if (seenIDs.Contains(shippingOption.mId)) { + SetDOMStringToNull(aOption); + *aResetOptions = true; + return; + } + seenIDs.AppendElement(shippingOption.mId); + + // set aOption to last selected option's ID + if (shippingOption.mSelected) { + aOption = shippingOption.mId; + } + } +} + nsresult PaymentRequestManager::CreatePayment(nsPIDOMWindowInner* aWindow, const Sequence& aMethodData, @@ -362,26 +398,7 @@ PaymentRequestManager::CreatePayment(nsPIDOMWindowInner* aWindow, MOZ_ASSERT(NS_IsMainThread()); NS_ENSURE_ARG_POINTER(aRequest); *aRequest = nullptr; - nsresult rv; - nsTArray methodData; - for (const PaymentMethodData& data : aMethodData) { - IPCPaymentMethodData ipcMethodData; - rv = ConvertMethodData(data, ipcMethodData); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - methodData.AppendElement(ipcMethodData); - } - - IPCPaymentDetails details; - rv = ConvertDetailsInit(aDetails, details); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - IPCPaymentOptions options; - ConvertOptions(aOptions, options); RefPtr request = PaymentRequest::CreatePaymentRequest(aWindow, rv); if (NS_WARN_IF(NS_FAILED(rv))) { @@ -400,8 +417,48 @@ PaymentRequestManager::CreatePayment(nsPIDOMWindowInner* aWindow, } request->SetId(requestId); + /* + * Set request's mShippingOption to last selected option's ID if + * details.shippingOptions exists and IDs of all options are unique. + * Otherwise, set mShippingOption to null and set the resetShippingOptions + * flag to reset details.shippingOptions to an empty array later when + * converting details to IPC structure. + */ + nsAutoString shippingOption; + bool resetShippingOptions = false; + GetSelectedShippingOption(aDetails, shippingOption, &resetShippingOptions); + request->SetShippingOption(shippingOption); + + /* + * Set request's |mShippingType| if shipping is required. + */ + if (aOptions.mRequestShipping) { + request->SetShippingType( + Nullable(aOptions.mShippingType)); + } + nsAutoString internalId; request->GetInternalId(internalId); + + nsTArray methodData; + for (const PaymentMethodData& data : aMethodData) { + IPCPaymentMethodData ipcMethodData; + rv = ConvertMethodData(data, ipcMethodData); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + methodData.AppendElement(ipcMethodData); + } + + IPCPaymentDetails details; + rv = ConvertDetailsInit(aDetails, details, resetShippingOptions); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + IPCPaymentOptions options; + ConvertOptions(aOptions, options); + IPCPaymentCreateActionRequest action(internalId, methodData, details, @@ -489,6 +546,12 @@ PaymentRequestManager::UpdatePayment(const nsAString& aRequestId, return NS_ERROR_UNEXPECTED; } + // [TODO] Process details.shippingOptions if presented. + // 1) Check if there are duplicate IDs in details.shippingOptions, + // if so, reset details.shippingOptions to an empty sequence. + // 2) Set request's selectedShippingOption to the ID of last selected + // option. + IPCPaymentDetails details; nsresult rv = ConvertDetailsUpdate(aDetails, details); if (NS_WARN_IF(NS_FAILED(rv))) { From ffb43e0fafef0fa47c8c17b204b0e14d0a8a5980 Mon Sep 17 00:00:00 2001 From: Jocelyn Liu Date: Tue, 20 Jun 2017 14:07:16 -0700 Subject: [PATCH 19/63] Bug 1367694 - Mochitest for resetting details.shippingOptions when there are duplicate option IDs. r=baku --- dom/payments/test/ConstructorChromeScript.js | 87 ++++++++++++++++++- .../test/browser_multiple_construction.js | 2 + dom/payments/test/head.js | 28 ++++++ .../test/multiple_payment_request.html | 25 ++++++ dom/payments/test/test_constructor.html | 46 ++++++++++ 5 files changed, 185 insertions(+), 3 deletions(-) diff --git a/dom/payments/test/ConstructorChromeScript.js b/dom/payments/test/ConstructorChromeScript.js index 3d70dea57a99..b3d7366f8ee8 100644 --- a/dom/payments/test/ConstructorChromeScript.js +++ b/dom/payments/test/ConstructorChromeScript.js @@ -227,6 +227,67 @@ function checkComplexRequest(payRequest) { } } +function checkDuplicateShippingOptionsRequest(payRequest) { + if (payRequest.paymentMethods.length != 1) { + emitTestFail("paymentMethods' length should be 1."); + } + + const methodData = payRequest.paymentMethods.queryElementAt(0, Ci.nsIPaymentMethodData); + if (!methodData) { + emitTestFail("Fail to get payment methodData."); + } + let supportedMethod = methodData.supportedMethods; + if (supportedMethod != "basic-card") { + emitTestFail("supported method should be 'basic-card'."); + } + // checking the passed PaymentDetails parameter + const details = payRequest.paymentDetails; + if (details.id != "duplicate shipping options details" ) { + emitTestFail("details.id should be 'duplicate shipping options details'."); + } + if (details.totalItem.label != "Total") { + emitTestFail("total item's label should be 'Total'."); + } + if (details.totalItem.amount.currency != "USD") { + emitTestFail("total item's currency should be 'USD'."); + } + if (details.totalItem.amount.value != "1.00") { + emitTestFail("total item's value should be '1.00'."); + } + + if (details.displayItems) { + emitTestFail("details.displayItems should be undefined."); + } + if (details.modifiers) { + emitTestFail("details.displayItems should be undefined."); + } + const shippingOptions = details.shippingOptions; + if (!shippingOptions) { + emitTestFail("details.shippingOptions should not be undefined."); + } + if (shippingOptions.length != 0) { + emitTestFail("shippingOptions' length should be 0."); + } + + // checking the default generated PaymentOptions parameter + const paymentOptions = payRequest.paymentOptions; + if (paymentOptions.requestPayerName) { + emitTestFail("requestPayerName option should be false."); + } + if (paymentOptions.requestPayerEmail) { + emitTestFail("requestPayerEmail option should be false."); + } + if (paymentOptions.requestPayerPhone) { + emitTestFail("requestPayerPhone option should be false."); + } + if (paymentOptions.requestShipping) { + emitTestFail("requestShipping option should be false."); + } + if (paymentOptions.shippingType != "shipping") { + emitTestFail("shippingType option should be 'shipping'.") + } +} + function checkSimplestRequestHandler() { const paymentEnum = paymentSrv.enumerate(); if (!paymentEnum.hasMoreElements()) { @@ -261,6 +322,23 @@ function checkComplexRequestHandler() { sendAsyncMessage("check-complete"); } +function checkDuplicateShippingOptionsRequestHandler() { + const paymentEnum = paymentSrv.enumerate(); + if (!paymentEnum.hasMoreElements()) { + emitTestFail("PaymentRequestService should have at least one payment request."); + } + while (paymentEnum.hasMoreElements()) { + let payRequest = paymentEnum.getNext().QueryInterface(Ci.nsIPaymentRequest); + if (!payRequest) { + emitTestFail("Fail to get existing payment request."); + break; + } + checkDuplicateShippingOptionsRequest(payRequest); + } + paymentSrv.cleanup(); + sendAsyncMessage("check-complete"); +} + function checkMultipleRequestsHandler () { const paymentEnum = paymentSrv.enumerate(); if (!paymentEnum.hasMoreElements()) { @@ -272,10 +350,12 @@ function checkMultipleRequestsHandler () { emitTestFail("Fail to get existing payment request."); break; } - if (payRequest.paymentDetails.id != "payment details") { - checkSimplestRequest(payRequest); - } else { + if (payRequest.paymentDetails.id == "payment details") { checkComplexRequest(payRequest); + } else if (payRequest.paymentDetails.id == "duplicate shipping options details") { + checkDuplicateShippingOptionsRequest(payRequest); + } else { + checkSimplestRequest(payRequest); } } paymentSrv.cleanup(); @@ -284,6 +364,7 @@ function checkMultipleRequestsHandler () { addMessageListener("check-simplest-request", checkSimplestRequestHandler); addMessageListener("check-complex-request", checkComplexRequestHandler); +addMessageListener("check-duplicate-shipping-options-request", checkDuplicateShippingOptionsRequestHandler); addMessageListener("check-multiple-requests", checkMultipleRequestsHandler); addMessageListener("teardown", function() { diff --git a/dom/payments/test/browser_multiple_construction.js b/dom/payments/test/browser_multiple_construction.js index c61a89674aaf..786e21578a77 100644 --- a/dom/payments/test/browser_multiple_construction.js +++ b/dom/payments/test/browser_multiple_construction.js @@ -22,6 +22,8 @@ add_task(async function() { checkComplexPayment(payment); } else if (payment.paymentDetails.id == "simple details") { checkSimplePayment(payment); + } else if (payment.paymentDetails.id == "duplicate shipping options details") { + checkDupShippingOptionsPayment(payment); } else { ok(false, "Unknown payment."); } diff --git a/dom/payments/test/head.js b/dom/payments/test/head.js index 7b76a18c9751..5177d776ea92 100644 --- a/dom/payments/test/head.js +++ b/dom/payments/test/head.js @@ -101,6 +101,34 @@ function checkComplexPayment(aPayment) { is(paymentOptions.shippingType, "shipping", "shippingType option should be 'shipping'"); } +function checkDupShippingOptionsPayment(aPayment) { + // checking the passed PaymentMethods parameter + is(aPayment.paymentMethods.length, 1, "paymentMethods' length should be 1."); + + const methodData = aPayment.paymentMethods.queryElementAt(0, Ci.nsIPaymentMethodData); + ok(methodData, "Fail to get payment methodData."); + is(methodData.supportedMethods, "MyPay", "modifier's supported method name should be 'MyPay'."); + is(methodData.data, "", "method data should be empty"); + + // checking the passed PaymentDetails parameter + const details = aPayment.paymentDetails; + is(details.id, "duplicate shipping options details", "details.id should be 'duplicate shipping options details'."); + is(details.totalItem.label, "Donation", "total item's label should be 'Donation'."); + is(details.totalItem.amount.currency, "USD", "total item's currency should be 'USD'."); + is(details.totalItem.amount.value, "55.00", "total item's value should be '55.00'."); + + const shippingOptions = details.shippingOptions; + is(shippingOptions.length, 0, "shippingOptions' length should be 0."); + + // checking the passed PaymentOptions parameter + const paymentOptions = aPayment.paymentOptions; + ok(paymentOptions.requestPayerName, "payerName option should be true"); + ok(paymentOptions.requestPayerEmail, "payerEmail option should be true"); + ok(paymentOptions.requestPayerPhone, "payerPhone option should be true"); + ok(paymentOptions.requestShipping, "requestShipping option should be true"); + is(paymentOptions.shippingType, "shipping", "shippingType option should be 'shipping'"); +} + function cleanup() { const paymentSrv = Cc["@mozilla.org/dom/payments/payment-request-service;1"].getService(Ci.nsIPaymentRequestService); if (paymentSrv) { diff --git a/dom/payments/test/multiple_payment_request.html b/dom/payments/test/multiple_payment_request.html index d323572f082d..dfc4311a61cf 100644 --- a/dom/payments/test/multiple_payment_request.html +++ b/dom/payments/test/multiple_payment_request.html @@ -66,6 +66,28 @@ }, }; + const dupShippingOptionsDetails = { + id: "duplicate shipping options details", + total: { + label: "Donation", + amount: { currency: "USD", value: "55.00" } + }, + shippingOptions: [ + { + id: "dupShipping", + label: "NormalShipping", + amount: { currency: "USD", value: "10.00", }, + selected: true, + }, + { + id: "dupShipping", + label: "FastShipping", + amount: { currency: "USD", value: "30.00", }, + selected: false, + }, + ], + }; + const options = { requestPayerName: true, requestPayerEmail: true, @@ -79,6 +101,9 @@ options); const paymentRequest2 = new PaymentRequest(supportedInstruments, simpleDetails); + const paymentRequest3 = new PaymentRequest(supportedInstruments, + dupShippingOptionsDetails, + options); diff --git a/dom/payments/test/test_constructor.html b/dom/payments/test/test_constructor.html index 94f42cd3a384..5ae00d972335 100644 --- a/dom/payments/test/test_constructor.html +++ b/dom/payments/test/test_constructor.html @@ -121,6 +121,37 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1345361 shippingType: "shipping" }; + const duplicateShippingOptionsDetails = { + id: "duplicate shipping options details", + total: { + label: "Total", + amount: { + currency: "USD", + value: "1.00" + } + }, + shippingOptions: [ + { + id: "dupShipping", + label: "NormalShipping", + amount: { + currency: "USD", + value: "10.00" + }, + selected: true, + }, + { + id: "dupShipping", + label: "FastShipping", + amount: { + currency: "USD", + value: "30.00" + }, + selected: false, + }, + ], + }; + function testWithSimplestParameters() { return new Promise((resolve, reject) => { @@ -146,12 +177,26 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1345361 }); } + function testWithDuplicateShippingOptionsParameters() { + return new Promise((resolve, reject) => { + const payRequest = new PaymentRequest(simplestMethods, duplicateShippingOptionsDetails); + ok(payRequest, "PaymentRequest should be created"); + gScript.addMessageListener("check-complete", function checkCompleteHandler() { + gScript.removeMessageListener("check-complete", checkCompleteHandler); + resolve(); + }); + gScript.sendAsyncMessage("check-duplicate-shipping-options-request"); + }); + } + function testMultipleRequests() { return new Promise((resolve, reject) => { const payRequest1 = new PaymentRequest(complexMethods, complexDetails, complexOptions); const payRequest2 = new PaymentRequest(simplestMethods, simplestDetails); + const payRequest3 = new PaymentRequest(simplestMethods, duplicateShippingOptionsDetails); ok(payRequest1, "PaymentRequest with complex parameters should be created"); ok(payRequest2, "PaymentRequest with simplest parameters should be created"); + ok(payRequest3, "PaymentRequest with duplicate shipping options parameters should be created"); gScript.addMessageListener("check-complete", function checkCompleteHandler() { gScript.removeMessageListener("check-complete", checkCompleteHandler); resolve(); @@ -173,6 +218,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1345361 function runTests() { testWithSimplestParameters() .then(testWithComplexParameters) + .then(testWithDuplicateShippingOptionsParameters) .then(testMultipleRequests) .then(teardown) .catch( e => { From 6cf29dbc0ed0c0dbe3a5e94a5943a5579ad57793 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 5 Jul 2017 15:19:47 -0700 Subject: [PATCH 20/63] Refactor PaintThread for async painting. (bug 1377060 part 1, r=mchang) --HG-- extra : rebase_source : 4a3601108175cc2f091800f123461187282ca31f --- gfx/layers/PaintThread.cpp | 73 +++++++++++++++++++++++++------------- gfx/layers/PaintThread.h | 18 +++++++--- xpcom/base/StaticPtr.h | 7 ++++ 3 files changed, 68 insertions(+), 30 deletions(-) diff --git a/gfx/layers/PaintThread.cpp b/gfx/layers/PaintThread.cpp index 68b86544e320..2031f222b7c3 100644 --- a/gfx/layers/PaintThread.cpp +++ b/gfx/layers/PaintThread.cpp @@ -6,6 +6,7 @@ #include "PaintThread.h" +#include "base/task.h" #include "mozilla/gfx/2D.h" #include "mozilla/SyncRunnable.h" @@ -15,6 +16,8 @@ namespace layers { using namespace gfx; StaticAutoPtr PaintThread::sSingleton; +StaticRefPtr PaintThread::sThread; +PlatformThreadId PaintThread::sThreadId; void PaintThread::Release() @@ -30,24 +33,25 @@ void PaintThread::InitOnPaintThread() { MOZ_ASSERT(!NS_IsMainThread()); - mThreadId = PlatformThread::CurrentId(); + sThreadId = PlatformThread::CurrentId(); } bool PaintThread::Init() { MOZ_ASSERT(NS_IsMainThread()); - nsresult rv = NS_NewNamedThread("PaintThread", getter_AddRefs(mThread)); + RefPtr thread; + nsresult rv = NS_NewNamedThread("PaintThread", getter_AddRefs(thread)); if (NS_FAILED(rv)) { return false; } + sThread = thread; nsCOMPtr paintInitTask = NewRunnableMethod("PaintThread::InitOnPaintThread", this, &PaintThread::InitOnPaintThread); - - SyncRunnable::DispatchToThread(PaintThread::sSingleton->mThread, paintInitTask); + SyncRunnable::DispatchToThread(sThread, paintInitTask); return true; } @@ -69,49 +73,68 @@ PaintThread::Get() return PaintThread::sSingleton.get(); } +void +DestroyPaintThread(UniquePtr&& pt) +{ + MOZ_ASSERT(PaintThread::IsOnPaintThread()); + pt->ShutdownOnPaintThread(); +} + /* static */ void PaintThread::Shutdown() { - if (!PaintThread::sSingleton) { + MOZ_ASSERT(NS_IsMainThread()); + + UniquePtr pt(sSingleton.forget()); + if (!pt) { return; } - PaintThread::sSingleton->ShutdownImpl(); - PaintThread::sSingleton = nullptr; + sThread->Dispatch(NewRunnableFunction(DestroyPaintThread, Move(pt))); + sThread->Shutdown(); + sThread = nullptr; } void -PaintThread::ShutdownImpl() +PaintThread::ShutdownOnPaintThread() { - MOZ_ASSERT(NS_IsMainThread()); - PaintThread::sSingleton->mThread->AsyncShutdown(); + MOZ_ASSERT(IsOnPaintThread()); } -bool +/* static */ bool PaintThread::IsOnPaintThread() { - MOZ_ASSERT(mThread); - return PlatformThread::CurrentId() == mThreadId; + return sThreadId == PlatformThread::CurrentId(); +} + +void +PaintThread::PaintContentsAsync(gfx::DrawTargetCapture* aCapture, + gfx::DrawTarget* aTarget) +{ + MOZ_ASSERT(IsOnPaintThread()); + + // Draw all the things into the actual dest target. + aTarget->DrawCapturedDT(aCapture, Matrix()); } void PaintThread::PaintContents(DrawTargetCapture* aCapture, DrawTarget* aTarget) { - if (!IsOnPaintThread()) { - MOZ_ASSERT(NS_IsMainThread()); - nsCOMPtr paintTask = - NewRunnableMethod("PaintThread::PaintContents", - this, - &PaintThread::PaintContents, - aCapture, aTarget); + MOZ_ASSERT(NS_IsMainThread()); - SyncRunnable::DispatchToThread(mThread, paintTask); - return; - } + RefPtr capture(aCapture); + RefPtr target(aTarget); - // Draw all the things into the actual dest target. - aTarget->DrawCapturedDT(aCapture, Matrix()); + RefPtr self = this; + RefPtr task = NS_NewRunnableFunction("PaintThread::PaintContents", + [self, capture, target]() -> void + { + self->PaintContentsAsync(capture, target); + }); + + SyncRunnable::DispatchToThread(sThread, task); + return; } } // namespace layers diff --git a/gfx/layers/PaintThread.h b/gfx/layers/PaintThread.h index 813e8a663b5d..10a3b0dd6c9f 100644 --- a/gfx/layers/PaintThread.h +++ b/gfx/layers/PaintThread.h @@ -9,6 +9,7 @@ #include "base/platform_thread.h" #include "mozilla/StaticPtr.h" +#include "mozilla/UniquePtr.h" #include "nsThreadUtils.h" namespace mozilla { @@ -21,12 +22,15 @@ namespace layers { class PaintThread final { + friend void DestroyPaintThread(UniquePtr&& aPaintThread); + public: static void Start(); static void Shutdown(); static PaintThread* Get(); void PaintContents(gfx::DrawTargetCapture* aCapture, gfx::DrawTarget* aTarget); + // Sync Runnables need threads to be ref counted, // But this thread lives through the whole process. // We're only temporarily using sync runnables so @@ -34,18 +38,22 @@ public: void Release(); void AddRef(); + // Helper for asserts. + static bool IsOnPaintThread(); + private: - bool IsOnPaintThread(); bool Init(); - void ShutdownImpl(); + void ShutdownOnPaintThread(); void InitOnPaintThread(); + void PaintContentsAsync(gfx::DrawTargetCapture* aCapture, + gfx::DrawTarget* aTarget); static StaticAutoPtr sSingleton; - RefPtr mThread; - PlatformThreadId mThreadId; + static StaticRefPtr sThread; + static PlatformThreadId sThreadId; }; } // namespace layers } // namespace mozilla -#endif \ No newline at end of file +#endif diff --git a/xpcom/base/StaticPtr.h b/xpcom/base/StaticPtr.h index f2c820a93937..e64a9413e59f 100644 --- a/xpcom/base/StaticPtr.h +++ b/xpcom/base/StaticPtr.h @@ -67,6 +67,13 @@ public: T& operator*() const { return *get(); } + T* forget() + { + T* temp = mRawPtr; + mRawPtr = nullptr; + return temp; + } + private: // Disallow copy constructor, but only in debug mode. We only define // a default constructor in debug mode (see above); if we declared From f914e078f9c7bbe1d79ddc59f3b6431a76a988b6 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 5 Jul 2017 15:19:52 -0700 Subject: [PATCH 21/63] Implement asynchronous OMTP behind a pref. (bug 1377060 part 2, r=mchang) --HG-- extra : rebase_source : b9c49b6c0e80e2bc94a94dee2ddaae4ad985f9ec --- gfx/layers/PaintThread.cpp | 29 +++++-- gfx/layers/PaintThread.h | 5 +- gfx/layers/client/ClientLayerManager.cpp | 3 + gfx/layers/ipc/CompositorBridgeChild.cpp | 102 ++++++++++++++++++++++- gfx/layers/ipc/CompositorBridgeChild.h | 38 +++++++++ gfx/layers/ipc/ShadowLayers.cpp | 4 + gfx/thebes/gfxPrefs.h | 1 + 7 files changed, 173 insertions(+), 9 deletions(-) diff --git a/gfx/layers/PaintThread.cpp b/gfx/layers/PaintThread.cpp index 2031f222b7c3..23e235ec718c 100644 --- a/gfx/layers/PaintThread.cpp +++ b/gfx/layers/PaintThread.cpp @@ -7,7 +7,10 @@ #include "PaintThread.h" #include "base/task.h" +#include "gfxPrefs.h" +#include "mozilla/layers/CompositorBridgeChild.h" #include "mozilla/gfx/2D.h" +#include "mozilla/Preferences.h" #include "mozilla/SyncRunnable.h" namespace mozilla { @@ -108,13 +111,18 @@ PaintThread::IsOnPaintThread() } void -PaintThread::PaintContentsAsync(gfx::DrawTargetCapture* aCapture, +PaintThread::PaintContentsAsync(CompositorBridgeChild* aBridge, + gfx::DrawTargetCapture* aCapture, gfx::DrawTarget* aTarget) { MOZ_ASSERT(IsOnPaintThread()); // Draw all the things into the actual dest target. aTarget->DrawCapturedDT(aCapture, Matrix()); + + if (aBridge) { + aBridge->NotifyFinishedAsyncPaint(); + } } void @@ -123,18 +131,29 @@ PaintThread::PaintContents(DrawTargetCapture* aCapture, { MOZ_ASSERT(NS_IsMainThread()); + // If painting asynchronously, we need to acquire the compositor bridge which + // owns the underlying MessageChannel. Otherwise we leave it null and use + // synchronous dispatch. + RefPtr cbc; + if (!gfxPrefs::LayersOMTPForceSync()) { + cbc = CompositorBridgeChild::Get(); + cbc->NotifyBeginAsyncPaint(); + } RefPtr capture(aCapture); RefPtr target(aTarget); RefPtr self = this; RefPtr task = NS_NewRunnableFunction("PaintThread::PaintContents", - [self, capture, target]() -> void + [self, cbc, capture, target]() -> void { - self->PaintContentsAsync(capture, target); + self->PaintContentsAsync(cbc, capture, target); }); - SyncRunnable::DispatchToThread(sThread, task); - return; + if (cbc) { + sThread->Dispatch(task.forget()); + } else { + SyncRunnable::DispatchToThread(sThread, task); + } } } // namespace layers diff --git a/gfx/layers/PaintThread.h b/gfx/layers/PaintThread.h index 10a3b0dd6c9f..4d7bc0a46284 100644 --- a/gfx/layers/PaintThread.h +++ b/gfx/layers/PaintThread.h @@ -20,6 +20,8 @@ class DrawTargetCapture; namespace layers { +class CompositorBridgeChild; + class PaintThread final { friend void DestroyPaintThread(UniquePtr&& aPaintThread); @@ -45,7 +47,8 @@ private: bool Init(); void ShutdownOnPaintThread(); void InitOnPaintThread(); - void PaintContentsAsync(gfx::DrawTargetCapture* aCapture, + void PaintContentsAsync(CompositorBridgeChild* aBridge, + gfx::DrawTargetCapture* aCapture, gfx::DrawTarget* aTarget); static StaticAutoPtr sSingleton; diff --git a/gfx/layers/client/ClientLayerManager.cpp b/gfx/layers/client/ClientLayerManager.cpp index fd50db920144..8a18e32d9dd5 100644 --- a/gfx/layers/client/ClientLayerManager.cpp +++ b/gfx/layers/client/ClientLayerManager.cpp @@ -226,6 +226,9 @@ ClientLayerManager::CreateReadbackLayer() bool ClientLayerManager::BeginTransactionWithTarget(gfxContext* aTarget) { + // Wait for any previous async paints to complete before starting to paint again. + GetCompositorBridgeChild()->FlushAsyncPaints(); + MOZ_ASSERT(mForwarder, "ClientLayerManager::BeginTransaction without forwarder"); if (!mForwarder->IPCOpen()) { gfxCriticalNote << "ClientLayerManager::BeginTransaction with IPC channel down. GPU process may have died."; diff --git a/gfx/layers/ipc/CompositorBridgeChild.cpp b/gfx/layers/ipc/CompositorBridgeChild.cpp index ab6582c1e0a4..b8c8e0efacb6 100644 --- a/gfx/layers/ipc/CompositorBridgeChild.cpp +++ b/gfx/layers/ipc/CompositorBridgeChild.cpp @@ -19,6 +19,7 @@ #include "mozilla/layers/IAPZCTreeManager.h" #include "mozilla/layers/APZCTreeManagerChild.h" #include "mozilla/layers/LayerTransactionChild.h" +#include "mozilla/layers/PaintThread.h" #include "mozilla/layers/PLayerTransactionChild.h" #include "mozilla/layers/PTextureChild.h" #include "mozilla/layers/TextureClient.h"// for TextureClient @@ -89,6 +90,9 @@ CompositorBridgeChild::CompositorBridgeChild(CompositorManagerChild *aManager) , mMessageLoop(MessageLoop::current()) , mProcessToken(0) , mSectionAllocator(nullptr) + , mPaintLock("CompositorBridgeChild.mPaintLock") + , mOutstandingAsyncPaints(0) + , mIsWaitingForPaint(false) { MOZ_ASSERT(NS_IsMainThread()); } @@ -542,8 +546,20 @@ CompositorBridgeChild::ActorDestroy(ActorDestroyReason aWhy) gfxCriticalNote << "Receive IPC close with reason=AbnormalShutdown"; } - mCanSend = false; - mActorDestroyed = true; + { + // We take the lock to update these fields, since they are read from the + // paint thread. We don't need the lock to init them, since that happens + // on the main thread before the paint thread can ever grab a reference + // to the CompositorBridge object. + // + // Note that it is useful to take this lock for one other reason: It also + // tells us whether GetIPCChannel is safe to call. If we access the IPC + // channel within this lock, when mCanSend is true, then we know it has not + // been zapped by IPDL. + MonitorAutoLock lock(mPaintLock); + mCanSend = false; + mActorDestroyed = true; + } if (mProcessToken && XRE_IsParentProcess()) { GPUProcessManager::Get()->NotifyRemoteActorDestroyed(mProcessToken); @@ -1114,6 +1130,86 @@ CompositorBridgeChild::GetNextPipelineId() return wr::AsPipelineId(GetNextResourceId()); } +void +CompositorBridgeChild::NotifyBeginAsyncPaint() +{ + MOZ_ASSERT(NS_IsMainThread()); + + MonitorAutoLock lock(mPaintLock); + + // We must not be waiting for paints to complete yet. This would imply we + // started a new paint without waiting for a previous one, which could lead to + // incorrect rendering or IPDL deadlocks. + MOZ_ASSERT(!mIsWaitingForPaint); + + mOutstandingAsyncPaints++; +} + +void +CompositorBridgeChild::NotifyFinishedAsyncPaint() +{ + MOZ_ASSERT(PaintThread::IsOnPaintThread()); + + MonitorAutoLock lock(mPaintLock); + + mOutstandingAsyncPaints--; + + // It's possible that we painted so fast that the main thread never reached + // the code that starts delaying messages. If so, mIsWaitingForPaint will be + // false, and we can safely return. + if (mIsWaitingForPaint && mOutstandingAsyncPaints == 0) { + ResumeIPCAfterAsyncPaint(); + + // Notify the main thread in case it's blocking. We do this unconditionally + // to avoid deadlocking. + lock.Notify(); + } +} + +void +CompositorBridgeChild::PostponeMessagesIfAsyncPainting() +{ + MOZ_ASSERT(NS_IsMainThread()); + + MonitorAutoLock lock(mPaintLock); + + MOZ_ASSERT(!mIsWaitingForPaint); + + if (mOutstandingAsyncPaints > 0) { + mIsWaitingForPaint = true; + GetIPCChannel()->BeginPostponingSends(); + } +} + +void +CompositorBridgeChild::ResumeIPCAfterAsyncPaint() +{ + // Note: the caller is responsible for holding the lock. + mPaintLock.AssertCurrentThreadOwns(); + MOZ_ASSERT(PaintThread::IsOnPaintThread()); + MOZ_ASSERT(mOutstandingAsyncPaints == 0); + MOZ_ASSERT(mIsWaitingForPaint); + + mIsWaitingForPaint = false; + + // It's also possible that the channel has shut down already. + if (!mCanSend || mActorDestroyed) { + return; + } + + GetIPCChannel()->StopPostponingSends(); +} + +void +CompositorBridgeChild::FlushAsyncPaints() +{ + MOZ_ASSERT(NS_IsMainThread()); + + MonitorAutoLock lock(mPaintLock); + while (mIsWaitingForPaint) { + lock.Wait(); + } +} + } // namespace layers } // namespace mozilla - diff --git a/gfx/layers/ipc/CompositorBridgeChild.h b/gfx/layers/ipc/CompositorBridgeChild.h index f5ebe2c2c4d6..be1529cbd2ac 100644 --- a/gfx/layers/ipc/CompositorBridgeChild.h +++ b/gfx/layers/ipc/CompositorBridgeChild.h @@ -10,6 +10,7 @@ #include "base/basictypes.h" // for DISALLOW_EVIL_CONSTRUCTORS #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2 #include "mozilla/Attributes.h" // for override +#include "mozilla/Monitor.h" #include "mozilla/ipc/ProtocolUtils.h" #include "mozilla/layers/PCompositorBridgeChild.h" #include "mozilla/layers/TextureForwarder.h" // for TextureForwarder @@ -220,10 +221,33 @@ public: wr::PipelineId GetNextPipelineId(); + // Must only be called from the main thread. Notifies the CompositorBridge + // that the paint thread is going to begin painting asynchronously. + void NotifyBeginAsyncPaint(); + + // Must only be called from the paint thread. Notifies the CompositorBridge + // that the paint thread has finished an asynchronous paint request. + void NotifyFinishedAsyncPaint(); + + // Must only be called from the main thread. Notifies the CompoistorBridge + // that a transaction is about to be sent, and if the paint thread is + // currently painting, to begin delaying IPC messages. + void PostponeMessagesIfAsyncPainting(); + + // Must only be called from the main thread. Ensures that any paints from + // previous frames have been flushed. The main thread blocks until the + // operation completes. + void FlushAsyncPaints(); + private: // Private destructor, to discourage deletion outside of Release(): virtual ~CompositorBridgeChild(); + // Must only be called from the paint thread. If the main thread is delaying + // IPC messages, this forwards all such delayed IPC messages to the I/O thread + // and resumes IPC. + void ResumeIPCAfterAsyncPaint(); + void AfterDestroy(); virtual PLayerTransactionChild* @@ -328,6 +352,20 @@ private: uint64_t mProcessToken; FixedSizeSmallShmemSectionAllocator* mSectionAllocator; + + // Off-Main-Thread Painting state. This covers access to the OMTP-related + // state below. + Monitor mPaintLock; + + // Contains the number of outstanding asynchronous paints tied to a + // PLayerTransaction on this bridge. This is R/W on both the main and paint + // threads, and must be accessed within the paint lock. + size_t mOutstandingAsyncPaints; + + // True if this CompositorBridge is currently delaying its messages until the + // paint thread completes. This is R/W on both the main and paint threads, and + // must be accessed within the paint lock. + bool mIsWaitingForPaint; }; } // namespace layers diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index 337aff46bab4..d587b0c2c8dc 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -764,6 +764,10 @@ ShadowLayerForwarder::EndTransaction(const nsIntRegion& aRegionToClear, } } + // We delay at the last possible minute, to give the paint thread a chance to + // finish. If it does we don't have to delay messages at all. + GetCompositorBridgeChild()->PostponeMessagesIfAsyncPainting(); + MOZ_LAYERS_LOG(("[LayersForwarder] sending transaction...")); RenderTraceScope rendertrace3("Forward Transaction", "000093"); if (!mShadowManager->SendUpdate(info)) { diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index 117d457133ad..e99d61e1b51b 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -585,6 +585,7 @@ private: DECL_GFX_PREF(Once, "layers.mlgpu.enable-container-resizing", AdvancedLayersEnableContainerResizing, bool, true); DECL_GFX_PREF(Once, "layers.offmainthreadcomposition.force-disabled", LayersOffMainThreadCompositionForceDisabled, bool, false); DECL_GFX_PREF(Live, "layers.offmainthreadcomposition.frame-rate", LayersCompositionFrameRate, int32_t,-1); + DECL_GFX_PREF(Live, "layers.omtp.force-sync", LayersOMTPForceSync, bool, true); DECL_GFX_PREF(Live, "layers.orientation.sync.timeout", OrientationSyncMillis, uint32_t, (uint32_t)0); DECL_GFX_PREF(Once, "layers.prefer-opengl", LayersPreferOpenGL, bool, false); DECL_GFX_PREF(Live, "layers.progressive-paint", ProgressivePaint, bool, false); From 2c24b3d088734c289d8e4bdeed32e026ef08162c Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 5 Jul 2017 15:39:46 -0700 Subject: [PATCH 22/63] Ignore container layer batches that don't have an intermediate surface. (bug 1377936, r=mattwoodrow) --- gfx/layers/mlgpu/RenderPassMLGPU.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gfx/layers/mlgpu/RenderPassMLGPU.cpp b/gfx/layers/mlgpu/RenderPassMLGPU.cpp index 6ab895f64ebe..d0181925c6cd 100644 --- a/gfx/layers/mlgpu/RenderPassMLGPU.cpp +++ b/gfx/layers/mlgpu/RenderPassMLGPU.cpp @@ -348,6 +348,10 @@ ShaderRenderPass::SetupPSBuffer0(float aOpacity) void ShaderRenderPass::ExecuteRendering() { + if (mVertices.IsEmpty() && mInstances.IsEmpty()) { + return; + } + mDevice->SetPSConstantBuffer(0, &mPSBuffer0); if (MaskOperation* mask = GetMask()) { mDevice->SetPSTexture(kMaskLayerTextureSlot, mask->GetTexture()); @@ -881,6 +885,10 @@ RenderViewPass::AddToPass(LayerMLGPU* aLayer, ItemInfo& aInfo) } mSource = mAssignedLayer->GetRenderTarget(); + if (!mSource) { + return false; + } + mParentView = aInfo.view; Txn txn(this); From 8f2fab9547d27fa76af9a3a03c816494053147d9 Mon Sep 17 00:00:00 2001 From: David Major Date: Wed, 5 Jul 2017 18:45:31 -0400 Subject: [PATCH 23/63] Bug 1378442 - Move Win64 profiler hooks to profiler_start. r=mstange --- mozglue/build/WindowsDllBlocklist.cpp | 40 ----------------- tools/profiler/core/platform-win32.cpp | 59 ++++++++++++++++++++++++++ tools/profiler/core/platform.cpp | 4 ++ 3 files changed, 63 insertions(+), 40 deletions(-) diff --git a/mozglue/build/WindowsDllBlocklist.cpp b/mozglue/build/WindowsDllBlocklist.cpp index ed8065d0d6e0..d65d5975b67f 100644 --- a/mozglue/build/WindowsDllBlocklist.cpp +++ b/mozglue/build/WindowsDllBlocklist.cpp @@ -779,38 +779,6 @@ continue_loading: return stub_LdrLoadDll(filePath, flags, moduleFileName, handle); } -#ifdef _M_AMD64 -typedef NTSTATUS (NTAPI *LdrUnloadDll_func)(HMODULE module); -static LdrUnloadDll_func stub_LdrUnloadDll; - -static NTSTATUS NTAPI -patched_LdrUnloadDll(HMODULE module) -{ - // Prevent the stack walker from suspending this thread when LdrUnloadDll - // holds the RtlLookupFunctionEntry lock. - AutoSuppressStackWalking suppress; - return stub_LdrUnloadDll(module); -} - -// These pointers are disguised as PVOID to avoid pulling in obscure headers -typedef PVOID (WINAPI *LdrResolveDelayLoadedAPI_func)(PVOID ParentModuleBase, - PVOID DelayloadDescriptor, PVOID FailureDllHook, PVOID FailureSystemHook, - PVOID ThunkAddress, ULONG Flags); -static LdrResolveDelayLoadedAPI_func stub_LdrResolveDelayLoadedAPI; - -static PVOID WINAPI patched_LdrResolveDelayLoadedAPI(PVOID ParentModuleBase, - PVOID DelayloadDescriptor, PVOID FailureDllHook, PVOID FailureSystemHook, - PVOID ThunkAddress, ULONG Flags) -{ - // Prevent the stack walker from suspending this thread when - // LdrResolveDelayLoadAPI holds the RtlLookupFunctionEntry lock. - AutoSuppressStackWalking suppress; - return stub_LdrResolveDelayLoadedAPI(ParentModuleBase, DelayloadDescriptor, - FailureDllHook, FailureSystemHook, - ThunkAddress, Flags); -} -#endif - #ifdef _M_IX86 static bool ShouldBlockThread(void* aStartAddress) @@ -890,14 +858,6 @@ DllBlocklist_Initialize(uint32_t aInitFlags) Kernel32Intercept.Init("kernel32.dll"); #ifdef _M_AMD64 - NtDllIntercept.AddHook("LdrUnloadDll", - reinterpret_cast(patched_LdrUnloadDll), - (void**)&stub_LdrUnloadDll); - if (IsWin8OrLater()) { // LdrResolveDelayLoadedAPI was introduced in Win8 - NtDllIntercept.AddHook("LdrResolveDelayLoadedAPI", - reinterpret_cast(patched_LdrResolveDelayLoadedAPI), - (void**)&stub_LdrResolveDelayLoadedAPI); - } if (!IsWin8OrLater()) { // The crash that this hook works around is only seen on Win7. Kernel32Intercept.AddHook("RtlInstallFunctionTableCallback", diff --git a/tools/profiler/core/platform-win32.cpp b/tools/profiler/core/platform-win32.cpp index ee7edf9eda1b..f1899944f593 100644 --- a/tools/profiler/core/platform-win32.cpp +++ b/tools/profiler/core/platform-win32.cpp @@ -32,6 +32,10 @@ #include #include +#include "nsWindowsDllInterceptor.h" +#include "mozilla/StackWalk_windows.h" +#include "mozilla/WindowsVersion.h" + /* static */ Thread::tid_t Thread::GetCurrentId() { @@ -282,3 +286,58 @@ Registers::SyncPopulate() } #endif +#if defined(GP_PLAT_amd64_windows) +static WindowsDllInterceptor NtDllIntercept; + +typedef NTSTATUS (NTAPI *LdrUnloadDll_func)(HMODULE module); +static LdrUnloadDll_func stub_LdrUnloadDll; + +static NTSTATUS NTAPI +patched_LdrUnloadDll(HMODULE module) +{ + // Prevent the stack walker from suspending this thread when LdrUnloadDll + // holds the RtlLookupFunctionEntry lock. + AutoSuppressStackWalking suppress; + return stub_LdrUnloadDll(module); +} + +// These pointers are disguised as PVOID to avoid pulling in obscure headers +typedef PVOID (WINAPI *LdrResolveDelayLoadedAPI_func)(PVOID ParentModuleBase, + PVOID DelayloadDescriptor, PVOID FailureDllHook, PVOID FailureSystemHook, + PVOID ThunkAddress, ULONG Flags); +static LdrResolveDelayLoadedAPI_func stub_LdrResolveDelayLoadedAPI; + +static PVOID WINAPI +patched_LdrResolveDelayLoadedAPI(PVOID ParentModuleBase, + PVOID DelayloadDescriptor, PVOID FailureDllHook, PVOID FailureSystemHook, + PVOID ThunkAddress, ULONG Flags) +{ + // Prevent the stack walker from suspending this thread when + // LdrResolveDelayLoadAPI holds the RtlLookupFunctionEntry lock. + AutoSuppressStackWalking suppress; + return stub_LdrResolveDelayLoadedAPI(ParentModuleBase, DelayloadDescriptor, + FailureDllHook, FailureSystemHook, + ThunkAddress, Flags); +} + +void +InitializeWin64ProfilerHooks() +{ + static bool initialized = false; + if (initialized) { + return; + } + initialized = true; + + NtDllIntercept.Init("ntdll.dll"); + NtDllIntercept.AddHook("LdrUnloadDll", + reinterpret_cast(patched_LdrUnloadDll), + (void**)&stub_LdrUnloadDll); + if (IsWin8OrLater()) { // LdrResolveDelayLoadedAPI was introduced in Win8 + NtDllIntercept.AddHook("LdrResolveDelayLoadedAPI", + reinterpret_cast(patched_LdrResolveDelayLoadedAPI), + (void**)&stub_LdrResolveDelayLoadedAPI); + } +} +#endif // defined(GP_PLAT_amd64_windows) + diff --git a/tools/profiler/core/platform.cpp b/tools/profiler/core/platform.cpp index 40233fd2d0e0..1266b93d5238 100644 --- a/tools/profiler/core/platform.cpp +++ b/tools/profiler/core/platform.cpp @@ -2423,6 +2423,10 @@ locked_profiler_start(PSLockRef aLock, int aEntries, double aInterval, MOZ_RELEASE_ASSERT(CorePS::Exists() && !ActivePS::Exists(aLock)); +#if defined(GP_PLAT_amd64_windows) + InitializeWin64ProfilerHooks(); +#endif + // Fall back to the default values if the passed-in values are unreasonable. int entries = aEntries > 0 ? aEntries : PROFILER_DEFAULT_ENTRIES; double interval = aInterval > 0 ? aInterval : PROFILER_DEFAULT_INTERVAL; From ac00d80880674e8789d436a0eedac6eb89cbbb8c Mon Sep 17 00:00:00 2001 From: Bevis Tseng Date: Wed, 5 Jul 2017 16:23:23 +0800 Subject: [PATCH 24/63] Bug 1378298 - Make TabChildGlobal override DispatcherTrait using TabChild::TabGroup(). r=billm --- dom/ipc/TabChild.cpp | 31 ++++++++++++++++++++++++++++++- dom/ipc/TabChild.h | 18 +++++++++++++++--- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index e8fd871ed8c9..e028aaac9c7a 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -3446,7 +3446,7 @@ TabChildSHistoryListener::OnRequestCrossBrowserNavigation(uint32_t aIndex) NS_OK : NS_ERROR_FAILURE; } -TabChildGlobal::TabChildGlobal(TabChildBase* aTabChild) +TabChildGlobal::TabChildGlobal(TabChild* aTabChild) : mTabChild(aTabChild) { SetIsNotDOMBinding(); @@ -3548,3 +3548,32 @@ TabChildGlobal::GetGlobalJSObject() NS_ENSURE_TRUE(mTabChild, nullptr); return mTabChild->GetGlobal(); } + +nsresult +TabChildGlobal::Dispatch(const char* aName, + TaskCategory aCategory, + already_AddRefed&& aRunnable) +{ + if (mTabChild && mTabChild->TabGroup()) { + return mTabChild->TabGroup()->Dispatch(aName, aCategory, Move(aRunnable)); + } + return DispatcherTrait::Dispatch(aName, aCategory, Move(aRunnable)); +} + +nsISerialEventTarget* +TabChildGlobal::EventTargetFor(TaskCategory aCategory) const +{ + if (mTabChild && mTabChild->TabGroup()) { + return mTabChild->TabGroup()->EventTargetFor(aCategory); + } + return DispatcherTrait::EventTargetFor(aCategory); +} + +AbstractThread* +TabChildGlobal::AbstractMainThreadFor(TaskCategory aCategory) +{ + if (mTabChild && mTabChild->TabGroup()) { + return mTabChild->TabGroup()->AbstractMainThreadFor(aCategory); + } + return DispatcherTrait::AbstractMainThreadFor(aCategory); +} diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index cdfffab99dc2..053c391518ac 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -45,8 +45,10 @@ class nsIDOMWindowUtils; class nsIHttpChannel; +class nsISerialEventTarget; namespace mozilla { +class AbstractThread; namespace layout { class RenderFrameChild; } // namespace layout @@ -69,7 +71,6 @@ class TabChild; class TabGroup; class ClonedMessageData; class CoalescedWheelData; -class TabChildBase; class TabChildGlobal : public DOMEventTargetHelper, public nsIContentFrameMessageManager, @@ -78,7 +79,7 @@ class TabChildGlobal : public DOMEventTargetHelper, public nsSupportsWeakReference { public: - explicit TabChildGlobal(TabChildBase* aTabChild); + explicit TabChildGlobal(TabChild* aTabChild); void Init(); NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TabChildGlobal, DOMEventTargetHelper) @@ -149,8 +150,19 @@ public: MOZ_CRASH("TabChildGlobal doesn't use DOM bindings!"); } + // Dispatch a runnable related to the global. + virtual nsresult Dispatch(const char* aName, + mozilla::TaskCategory aCategory, + already_AddRefed&& aRunnable) override; + + virtual nsISerialEventTarget* + EventTargetFor(mozilla::TaskCategory aCategory) const override; + + virtual AbstractThread* + AbstractMainThreadFor(mozilla::TaskCategory aCategory) override; + nsCOMPtr mMessageManager; - RefPtr mTabChild; + RefPtr mTabChild; protected: ~TabChildGlobal(); From 7b27fc5e0360bfd0551fde56fd947b05c3fc7c15 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 5 Jul 2017 15:43:58 -0700 Subject: [PATCH 25/63] Use greyscale instead of subpixel AA for complex intermediate surfaces. (bug 1366618, r=milan) --HG-- extra : rebase_source : 95cb64f3b7de631411bc16d109d4b3cade1eea33 --- gfx/layers/composite/LayerManagerComposite.h | 1 + 1 file changed, 1 insertion(+) diff --git a/gfx/layers/composite/LayerManagerComposite.h b/gfx/layers/composite/LayerManagerComposite.h index 47ee2d78dcf7..6b52bce96e09 100644 --- a/gfx/layers/composite/LayerManagerComposite.h +++ b/gfx/layers/composite/LayerManagerComposite.h @@ -313,6 +313,7 @@ public: virtual already_AddRefed CreateRefLayer() override; virtual bool AreComponentAlphaLayersEnabled() override; + virtual bool SupportsBackdropCopyForComponentAlpha() override { return false; } virtual already_AddRefed CreateOptimalMaskDrawTarget(const IntSize &aSize) override; From e399950e74048a0854cda10dda766e6ae5c01630 Mon Sep 17 00:00:00 2001 From: Robert Strong Date: Wed, 5 Jul 2017 19:03:48 -0700 Subject: [PATCH 26/63] Bug 1378033 - Don't try to register timers during shutdown in nsUpdateTimerManager.js. r=mhowell --- .../timermanager/nsUpdateTimerManager.js | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/toolkit/components/timermanager/nsUpdateTimerManager.js b/toolkit/components/timermanager/nsUpdateTimerManager.js index 92b72fc85c55..46e9aee6008e 100644 --- a/toolkit/components/timermanager/nsUpdateTimerManager.js +++ b/toolkit/components/timermanager/nsUpdateTimerManager.js @@ -2,11 +2,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -Components.utils.import("resource://gre/modules/XPCOMUtils.jsm", this); -Components.utils.import("resource://gre/modules/Services.jsm", this); +const { classes: Cc, interfaces: Ci, utils: Cu } = Components; -const Cc = Components.classes; -const Ci = Components.interfaces; +Cu.import("resource://gre/modules/XPCOMUtils.jsm", this); +Cu.import("resource://gre/modules/Services.jsm", this); const PREF_APP_UPDATE_LASTUPDATETIME_FMT = "app.update.lastUpdateTime.%ID%"; const PREF_APP_UPDATE_TIMERMINIMUMDELAY = "app.update.timerMinimumDelay"; @@ -308,6 +307,14 @@ TimerManager.prototype = { */ registerTimer: function TM_registerTimer(id, callback, interval) { LOG("TimerManager:registerTimer - id: " + id); + if (this._timers === null) { + // Use normal logging since reportError is not available while shutting + // down. + gLogEnabled = true; + LOG("TimerManager:registerTimer called after profile-before-change " + + "notification. Ignoring timer registration for id: " + id); + return; + } if (id in this._timers && callback != this._timers[id].callback) { LOG("TimerManager:registerTimer - Ignoring second registration for " + id); return; @@ -331,11 +338,12 @@ TimerManager.prototype = { }, unregisterTimer: function TM_unregisterTimer(id) { - LOG(`TimerManager:unregisterTimer - id: ${id}`); + LOG("TimerManager:unregisterTimer - id: " + id); if (id in this._timers) { delete this._timers[id]; } else { - LOG(`TimerManager:registerTimer - Ignoring unregistration request for unknown id: ${id}`); + LOG("TimerManager:unregisterTimer - Ignoring unregistration request for " + + "unknown id: " + id); } }, From e171eb9a0034ac82f0eb465b401b0736b68cb656 Mon Sep 17 00:00:00 2001 From: sotaro Date: Thu, 6 Jul 2017 12:06:41 +0900 Subject: [PATCH 27/63] Bug 1376896 - Fix AnimatedValue leak at CompositorAnimationStorage during OMTA r=kats --- gfx/layers/AnimationHelper.h | 2 +- gfx/layers/ipc/CompositorBridgeParent.cpp | 6 +-- .../CrossProcessCompositorBridgeParent.cpp | 5 +- gfx/layers/ipc/LayerTransactionParent.cpp | 49 ++++++++++++------- gfx/layers/ipc/LayerTransactionParent.h | 5 +- 5 files changed, 42 insertions(+), 25 deletions(-) diff --git a/gfx/layers/AnimationHelper.h b/gfx/layers/AnimationHelper.h index cb49cf3aa3c8..b50ddcf69d13 100644 --- a/gfx/layers/AnimationHelper.h +++ b/gfx/layers/AnimationHelper.h @@ -165,7 +165,7 @@ public: void ClearById(const uint64_t& aId); private: - ~CompositorAnimationStorage() { Clear(); }; + ~CompositorAnimationStorage() { }; private: AnimatedValueTable mAnimatedValues; diff --git a/gfx/layers/ipc/CompositorBridgeParent.cpp b/gfx/layers/ipc/CompositorBridgeParent.cpp index 2df55b1b5c5b..8e6e0460fb14 100644 --- a/gfx/layers/ipc/CompositorBridgeParent.cpp +++ b/gfx/layers/ipc/CompositorBridgeParent.cpp @@ -1515,14 +1515,14 @@ CompositorBridgeParent::AllocPLayerTransactionParent(const nsTArrayAddIPDLReference(); return p; } mCompositionManager = new AsyncCompositionManager(this, mLayerManager); - LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, 0); + LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, GetAnimationStorage(0), 0); p->AddIPDLReference(); return p; } @@ -1644,7 +1644,7 @@ CompositorBridgeParent::RecvAdoptChild(const uint64_t& child) MOZ_ASSERT(sIndirectLayerTrees[child].mParent->mOptions == mOptions); NotifyChildCreated(child); if (sIndirectLayerTrees[child].mLayerTree) { - sIndirectLayerTrees[child].mLayerTree->SetLayerManager(mLayerManager); + sIndirectLayerTrees[child].mLayerTree->SetLayerManager(mLayerManager, GetAnimationStorage(0)); // Trigger composition to handle a case that mLayerTree was not composited yet // by previous CompositorBridgeParent, since nsRefreshDriver might wait composition complete. ScheduleComposition(); diff --git a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp index 661663e38c23..c61295c64387 100644 --- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp +++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp @@ -88,14 +88,15 @@ CrossProcessCompositorBridgeParent::AllocPLayerTransactionParent( if (state && state->mLayerManager) { state->mCrossProcessParent = this; HostLayerManager* lm = state->mLayerManager; - LayerTransactionParent* p = new LayerTransactionParent(lm, this, aId); + CompositorAnimationStorage* animStorage = state->mParent ? state->mParent->GetAnimationStorage(0) : nullptr; + LayerTransactionParent* p = new LayerTransactionParent(lm, this, animStorage, aId); p->AddIPDLReference(); sIndirectLayerTrees[aId].mLayerTree = p; return p; } NS_WARNING("Created child without a matching parent?"); - LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, aId); + LayerTransactionParent* p = new LayerTransactionParent(/* aManager */ nullptr, this, /* aAnimStorage */ nullptr, aId); p->AddIPDLReference(); return p; } diff --git a/gfx/layers/ipc/LayerTransactionParent.cpp b/gfx/layers/ipc/LayerTransactionParent.cpp index f733b57bc826..0cfbb3622e5b 100644 --- a/gfx/layers/ipc/LayerTransactionParent.cpp +++ b/gfx/layers/ipc/LayerTransactionParent.cpp @@ -51,9 +51,11 @@ namespace layers { // LayerTransactionParent LayerTransactionParent::LayerTransactionParent(HostLayerManager* aManager, CompositorBridgeParentBase* aBridge, + CompositorAnimationStorage* aAnimStorage, uint64_t aId) : mLayerManager(aManager) , mCompositorBridge(aBridge) + , mAnimStorage(aAnimStorage) , mId(aId) , mChildEpoch(0) , mParentEpoch(0) @@ -68,13 +70,21 @@ LayerTransactionParent::~LayerTransactionParent() } void -LayerTransactionParent::SetLayerManager(HostLayerManager* aLayerManager) +LayerTransactionParent::SetLayerManager(HostLayerManager* aLayerManager, CompositorAnimationStorage* aAnimStorage) { + if (mDestroyed) { + return; + } mLayerManager = aLayerManager; for (auto iter = mLayerMap.Iter(); !iter.Done(); iter.Next()) { auto layer = iter.Data(); + if (mAnimStorage && + layer->GetCompositorAnimationsId()) { + mAnimStorage->ClearById(layer->GetCompositorAnimationsId()); + } layer->AsHostLayer()->SetLayerManager(aLayerManager); } + mAnimStorage = aAnimStorage; } mozilla::ipc::IPCResult @@ -101,7 +111,16 @@ LayerTransactionParent::Destroy() return; } mDestroyed = true; + if (mAnimStorage) { + for (auto iter = mLayerMap.Iter(); !iter.Done(); iter.Next()) { + auto layer = iter.Data(); + if (layer->GetCompositorAnimationsId()) { + mAnimStorage->ClearById(layer->GetCompositorAnimationsId()); + } + } + } mCompositables.clear(); + mAnimStorage = nullptr; } class MOZ_STACK_CLASS AutoLayerTransactionParentAsyncMessageSender @@ -535,14 +554,10 @@ LayerTransactionParent::SetLayerAttributes(const OpSetLayerAttributes& aOp) layer->SetCompositorAnimations(common.compositorAnimations()); // Clean up the Animations by id in the CompositorAnimationStorage // if there are no active animations on the layer - if (layer->GetCompositorAnimationsId() && + if (mAnimStorage && + layer->GetCompositorAnimationsId() && layer->GetAnimations().IsEmpty()) { - CompositorAnimationStorage* storage = - mCompositorBridge->GetAnimationStorage(GetId()); - - if (storage) { - storage->ClearById(layer->GetCompositorAnimationsId()); - } + mAnimStorage->ClearById(layer->GetCompositorAnimationsId()); } if (common.scrollMetadata() != layer->GetAllScrollMetadata()) { UpdateHitTestingTree(layer, "scroll metadata changed"); @@ -727,14 +742,11 @@ LayerTransactionParent::RecvGetAnimationOpacity(const uint64_t& aCompositorAnima mCompositorBridge->ApplyAsyncProperties(this); - CompositorAnimationStorage* storage = - mCompositorBridge->GetAnimationStorage(GetId()); - - if (!storage) { + if (!mAnimStorage) { return IPC_FAIL_NO_REASON(this); } - Maybe opacity = storage->GetAnimationOpacity(aCompositorAnimationsId); + Maybe opacity = mAnimStorage->GetAnimationOpacity(aCompositorAnimationsId); if (opacity) { *aOpacity = *opacity; *aHasAnimationOpacity = true; @@ -756,14 +768,11 @@ LayerTransactionParent::RecvGetAnimationTransform(const uint64_t& aCompositorAni // the value. mCompositorBridge->ApplyAsyncProperties(this); - CompositorAnimationStorage* storage = - mCompositorBridge->GetAnimationStorage(GetId()); - - if (!storage) { + if (!mAnimStorage) { return IPC_FAIL_NO_REASON(this); } - Maybe transform = storage->GetAnimationTransform(aCompositorAnimationsId); + Maybe transform = mAnimStorage->GetAnimationTransform(aCompositorAnimationsId); if (transform) { *aTransform = *transform; } else { @@ -1008,6 +1017,10 @@ LayerTransactionParent::RecvReleaseLayer(const LayerHandle& aHandle) if (!aHandle || !mLayerMap.Remove(aHandle.Value(), getter_AddRefs(layer))) { return IPC_FAIL_NO_REASON(this); } + if (mAnimStorage && + layer->GetCompositorAnimationsId()) { + mAnimStorage->ClearById(layer->GetCompositorAnimationsId()); + } layer->Disconnect(); return IPC_OK(); } diff --git a/gfx/layers/ipc/LayerTransactionParent.h b/gfx/layers/ipc/LayerTransactionParent.h index 212f96c9bec9..b81d7ad9e746 100644 --- a/gfx/layers/ipc/LayerTransactionParent.h +++ b/gfx/layers/ipc/LayerTransactionParent.h @@ -33,6 +33,7 @@ class Layer; class HostLayerManager; class ShadowLayerParent; class CompositableParent; +class CompositorAnimationStorage; class CompositorBridgeParentBase; class LayerTransactionParent final : public PLayerTransactionParent, @@ -48,6 +49,7 @@ class LayerTransactionParent final : public PLayerTransactionParent, public: LayerTransactionParent(HostLayerManager* aManager, CompositorBridgeParentBase* aBridge, + CompositorAnimationStorage* aAnimStorage, uint64_t aId); protected: @@ -58,7 +60,7 @@ public: HostLayerManager* layer_manager() const { return mLayerManager; } - void SetLayerManager(HostLayerManager* aLayerManager); + void SetLayerManager(HostLayerManager* aLayerManager, CompositorAnimationStorage* aAnimStorage); uint64_t GetId() const { return mId; } Layer* GetRoot() const { return mRoot; } @@ -174,6 +176,7 @@ private: private: RefPtr mLayerManager; CompositorBridgeParentBase* mCompositorBridge; + RefPtr mAnimStorage; // Hold the root because it might be grafted under various // containers in the "real" layer tree From 9b7ab955c80f8f7cd504cc95fff7f9643dc35cfa Mon Sep 17 00:00:00 2001 From: Cervantes Yu Date: Thu, 6 Jul 2017 11:19:32 +0800 Subject: [PATCH 28/63] Bug 1375281 - Part 1: Add getHeapAllocatedAsync() to nsIMemoryReporter.idl. r=erahm nsIMemoryReporter::getHeapAllocatedAsync() is added to get attribute 'heapAllocated' asynchronously. MozReview-Commit-ID: 96KyZpCeTG1 --HG-- extra : rebase_source : 5c27b26788a3a96821ce054911dda8ce2932007d extra : amend_source : fcb923dac2dfa9d7aa5bf520d38c5bb11f0d60e9 extra : histedit_source : 83ae65c153f7cef6c6529296838a9d9aa367219e --- xpcom/base/nsIMemoryReporter.idl | 12 ++++++++++++ xpcom/base/nsMemoryReporterManager.cpp | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/xpcom/base/nsIMemoryReporter.idl b/xpcom/base/nsIMemoryReporter.idl index 9617877df690..668bdd4b133a 100644 --- a/xpcom/base/nsIMemoryReporter.idl +++ b/xpcom/base/nsIMemoryReporter.idl @@ -205,6 +205,12 @@ interface nsIFinishReportingCallback : nsISupports void callback(in nsISupports data); }; +[scriptable, function, uuid(1a80cd0f-0d9e-4397-be69-68ad28fe5175)] +interface nsIHeapAllocatedCallback : nsISupports +{ + void callback(in int64_t bytesAllocated); +}; + [scriptable, builtinclass, uuid(2998574d-8993-407a-b1a5-8ad7417653e1)] interface nsIMemoryReporterManager : nsISupports { @@ -411,6 +417,12 @@ interface nsIMemoryReporterManager : nsISupports [infallible] readonly attribute boolean isDMDEnabled; [infallible] readonly attribute boolean isDMDRunning; + /* + * Asynchronously gets attribute 'heapAllocated'. The value is returned in + * the callback argument. + */ + [must_use] void getHeapAllocatedAsync(in nsIHeapAllocatedCallback callback); + /* * Run a series of GC/CC's in an attempt to minimize the application's memory * usage. When we're finished, we invoke the given runnable if it's not diff --git a/xpcom/base/nsMemoryReporterManager.cpp b/xpcom/base/nsMemoryReporterManager.cpp index f34ba97b5628..68a8c59d495a 100644 --- a/xpcom/base/nsMemoryReporterManager.cpp +++ b/xpcom/base/nsMemoryReporterManager.cpp @@ -2373,6 +2373,12 @@ nsMemoryReporterManager::GetHeapAllocated(int64_t* aAmount) #endif } +NS_IMETHODIMP +nsMemoryReporterManager::GetHeapAllocatedAsync(nsIHeapAllocatedCallback *aCallback) +{ + return NS_ERROR_NOT_AVAILABLE; +} + // This has UNITS_PERCENTAGE, so it is multiplied by 100x. NS_IMETHODIMP nsMemoryReporterManager::GetHeapOverheadFraction(int64_t* aAmount) From 3ae5186923a15608be8bc07dd2cf6318cb295a51 Mon Sep 17 00:00:00 2001 From: Cervantes Yu Date: Thu, 6 Jul 2017 11:19:40 +0800 Subject: [PATCH 29/63] Bug 1375281 - Part 2: Implementation of nsMemoryReporterManager::GetHeapAllocatedAsync(). r=erahm,froydnj Implement nsMemoryReporterManager::GetHeapAllocatedAsync() by dispatching nsMemoryReporterManager::GetHeapAllocated() to a thread pool and dispatching the result back to the main thread to run the callback with the requested attribute. MozReview-Commit-ID: 9jj1UYqu5KD --HG-- extra : rebase_source : a3620c6313b3253c41adff8d67c77a347240891b extra : amend_source : 1732a5e4390fadbc597b6a61dc7d51e892f8441e extra : histedit_source : b892d2046a07fe00368e8f1976394dc1f4c2f496 --- xpcom/base/nsMemoryReporterManager.cpp | 42 ++++++++++++++++++++++++++ xpcom/base/nsMemoryReporterManager.h | 4 +++ 2 files changed, 46 insertions(+) diff --git a/xpcom/base/nsMemoryReporterManager.cpp b/xpcom/base/nsMemoryReporterManager.cpp index 68a8c59d495a..a027f6026ff6 100644 --- a/xpcom/base/nsMemoryReporterManager.cpp +++ b/xpcom/base/nsMemoryReporterManager.cpp @@ -9,6 +9,7 @@ #include "nsCOMPtr.h" #include "nsCOMArray.h" #include "nsPrintfCString.h" +#include "nsProxyRelease.h" #include "nsServiceManagerUtils.h" #include "nsMemoryReporterManager.h" #include "nsITimer.h" @@ -21,6 +22,7 @@ #if defined(XP_UNIX) || defined(MOZ_DMD) #include "nsMemoryInfoDumper.h" #endif +#include "nsNetCID.h" #include "mozilla/Attributes.h" #include "mozilla/MemoryReportingProcess.h" #include "mozilla/PodOperations.h" @@ -1595,6 +1597,9 @@ nsMemoryReporterManager::nsMemoryReporterManager() , mNextGeneration(1) , mPendingProcessesState(nullptr) , mPendingReportersState(nullptr) +#ifdef HAVE_JEMALLOC_STATS + , mThreadPool(do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID)) +#endif { } @@ -2376,7 +2381,44 @@ nsMemoryReporterManager::GetHeapAllocated(int64_t* aAmount) NS_IMETHODIMP nsMemoryReporterManager::GetHeapAllocatedAsync(nsIHeapAllocatedCallback *aCallback) { +#ifdef HAVE_JEMALLOC_STATS + if (!mThreadPool) { + return NS_ERROR_UNEXPECTED; + } + + RefPtr self{this}; + nsMainThreadPtrHandle mainThreadCallback( + new nsMainThreadPtrHolder("HeapAllocatedCallback", + aCallback)); + + nsCOMPtr getHeapAllocatedRunnable = NS_NewRunnableFunction( + "nsMemoryReporterManager::GetHeapAllocatedAsync", + [self, mainThreadCallback]() mutable { + MOZ_ASSERT(!NS_IsMainThread()); + + int64_t heapAllocated = 0; + nsresult rv = self->GetHeapAllocated(&heapAllocated); + + nsCOMPtr resultCallbackRunnable = NS_NewRunnableFunction( + "nsMemoryReporterManager::GetHeapAllocatedAsync", + [mainThreadCallback, heapAllocated, rv]() mutable { + MOZ_ASSERT(NS_IsMainThread()); + + if (NS_FAILED(rv)) { + mainThreadCallback->Callback(0); + return; + } + + mainThreadCallback->Callback(heapAllocated); + }); // resultCallbackRunnable. + + Unused << NS_DispatchToMainThread(resultCallbackRunnable); + }); // getHeapAllocatedRunnable. + + return mThreadPool->Dispatch(getHeapAllocatedRunnable, NS_DISPATCH_NORMAL); +#else return NS_ERROR_NOT_AVAILABLE; +#endif } // This has UNITS_PERCENTAGE, so it is multiplied by 100x. diff --git a/xpcom/base/nsMemoryReporterManager.h b/xpcom/base/nsMemoryReporterManager.h index 4cf2ecaa5829..dff47aa0ca79 100644 --- a/xpcom/base/nsMemoryReporterManager.h +++ b/xpcom/base/nsMemoryReporterManager.h @@ -10,6 +10,7 @@ #include "mozilla/Mutex.h" #include "nsDataHashtable.h" #include "nsHashKeys.h" +#include "nsIEventTarget.h" #include "nsIMemoryReporter.h" #include "nsITimer.h" #include "nsServiceManagerUtils.h" @@ -276,6 +277,9 @@ private: // This is reinitialized each time a call to GetReports is initiated. PendingReportersState* mPendingReportersState; + // Used in GetHeapAllocatedAsync() to run jemalloc_stats async. + nsCOMPtr mThreadPool; + PendingProcessesState* GetStateForGeneration(uint32_t aGeneration); static MOZ_MUST_USE bool StartChildReport(mozilla::MemoryReportingProcess* aChild, From 2d976788bde9a6b015fa85fc41d370aca58585c3 Mon Sep 17 00:00:00 2001 From: Cervantes Yu Date: Thu, 6 Jul 2017 11:19:48 +0800 Subject: [PATCH 30/63] Bug 1375281 - Part 3: Get "MEMORY_HEAP_ALLOCATED" asynchronously in TelemetrySession.jsm. r=chutten TelemetrySession.jsm gets "MEMORY_HEAP_ALLOCATED" by calling nsIMemoryReporter::GetHeapAllocatedAsync() to get the attribute asynchronously using a callback. MozReview-Commit-ID: 2PjOU68FanK --HG-- extra : rebase_source : b113b7962547b8b7bb1209de57f07efb4e71b3ce extra : amend_source : e1dd39bf52960123f3e63a5e51cf5eb50a5294f5 extra : histedit_source : a778eaebe244bf3c0df62dc9a1c0fa2c1d1a30cf --- toolkit/components/telemetry/TelemetrySession.jsm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/toolkit/components/telemetry/TelemetrySession.jsm b/toolkit/components/telemetry/TelemetrySession.jsm index 67b5ba6db0dc..3fbef47fa3d9 100644 --- a/toolkit/components/telemetry/TelemetrySession.jsm +++ b/toolkit/components/telemetry/TelemetrySession.jsm @@ -1175,7 +1175,6 @@ var Impl = { b("MEMORY_VSIZE_MAX_CONTIGUOUS", "vsizeMaxContiguous"); b("MEMORY_RESIDENT_FAST", "residentFast"); b("MEMORY_UNIQUE", "residentUnique"); - b("MEMORY_HEAP_ALLOCATED", "heapAllocated"); p("MEMORY_HEAP_OVERHEAD_FRACTION", "heapOverheadFraction"); b("MEMORY_JS_GC_HEAP", "JSMainRuntimeGCHeap"); c("MEMORY_JS_COMPARTMENTS_SYSTEM", "JSMainRuntimeCompartmentsSystem"); @@ -1186,6 +1185,15 @@ var Impl = { cc("LOW_MEMORY_EVENTS_PHYSICAL", "lowMemoryEventsPhysical"); cc("PAGE_FAULTS_HARD", "pageFaultsHard"); + try { + mgr.getHeapAllocatedAsync(heapAllocated => { + boundHandleMemoryReport("MEMORY_HEAP_ALLOCATED", + Ci.nsIMemoryReporter.UNITS_BYTES, + heapAllocated); + }); + } catch (e) { + } + if (!Utils.isContentProcess && !this._totalMemoryTimeout) { // Only the chrome process should gather total memory // total = parent RSS + sum(child USS) From 93c4d245a20713a105df3b662f3601d394efb198 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Wed, 5 Jul 2017 23:23:10 -0400 Subject: [PATCH 31/63] Bug 1353312 - Don't use conditions when caching a struct with no rules. r=dbaron MozReview-Commit-ID: 2Q1xWcDY10T --- layout/style/RuleNodeCacheConditions.h | 5 ++++ layout/style/nsRuleNode.cpp | 36 ++++++++++++++++++++++++++ layout/style/nsRuleNode.h | 13 +++++++--- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/layout/style/RuleNodeCacheConditions.h b/layout/style/RuleNodeCacheConditions.h index a7f59365de43..4b1a2349a55a 100644 --- a/layout/style/RuleNodeCacheConditions.h +++ b/layout/style/RuleNodeCacheConditions.h @@ -95,6 +95,11 @@ public: mBits |= eUncacheable; } + void Clear() + { + *this = RuleNodeCacheConditions(); + } + bool Cacheable() const { return !(mBits & eUncacheable); diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 2eea495a67ec..91b59624a25e 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -2678,6 +2678,42 @@ nsRuleNode::WalkRuleTree(const nsStyleStructID aSID, "not forcing detail to eRulePartialMixed just below is no " "longer valid"); + if (detail == eRuleNone && isReset) { + // We specified absolutely no rule information for a reset struct, and we + // may or may not have found a parent rule in the tree that specified all + // the rule information. Regardless, we don't need to use any cache + // conditions if we cache this struct in the rule tree. + // + // Normally ruleData.mConditions would already indicate that the struct + // is cacheable without conditions if detail is eRuleNone, but because + // of the UnsetPropertiesWithoutFlags call above, we may have encountered + // some rules with dependencies, which we then cleared out of ruleData. + // + // ruleData.mConditions could also indicate we are not cacheable at all, + // such as when AnimValuesStyleRule prevents us from caching structs + // when attempting to apply animations to pseudos. + // + // So if we we are uncacheable, we leave it, but if we are cacheable + // with dependencies, we convert that to cacheable without dependencies. + if (ruleData.mConditions.CacheableWithDependencies()) { + MOZ_ASSERT(pseudoRestriction, + "should only be cacheable with dependencies if we had a " + "pseudo restriction"); + ruleData.mConditions.Clear(); + } else { + // XXXheycam We shouldn't have `|| GetLevel() == SheetType::Transition` + // in the assertion condition, but rule nodes created by + // ResolveStyleByAddingRules don't call SetIsAnimationRule(). + MOZ_ASSERT(ruleData.mConditions.CacheableWithoutDependencies() || + ((HasAnimationData() || + GetLevel() == SheetType::Transition) && + aContext->GetParent() && + aContext->GetParent()->HasPseudoElementData()), + "should only be uncacheable if we had an animation rule " + "and we're inside a pseudo"); + } + } + if (!ruleData.mConditions.CacheableWithoutDependencies() && aSID != eStyleStruct_Variables) { // Treat as though some data is specified to avoid the optimizations and diff --git a/layout/style/nsRuleNode.h b/layout/style/nsRuleNode.h index 1057e568e8d9..b5e9a97913ad 100644 --- a/layout/style/nsRuleNode.h +++ b/layout/style/nsRuleNode.h @@ -193,6 +193,7 @@ public: MOZ_ASSERT(!(mConditionalBits & GetBitForSID(aSID)), "rule node should not have unconditional and conditional style " "data for a given struct"); + mConditionalBits &= ~GetBitForSID(aSID); mEntries[aSID] = aStyleStruct; } @@ -200,13 +201,17 @@ public: nsPresContext* aPresContext, void* aStyleStruct, const mozilla::RuleNodeCacheConditions& aConditions) { - MOZ_ASSERT((mConditionalBits & GetBitForSID(aSID)) || - !mEntries[aSID], - "rule node should not have unconditional and conditional style " - "data for a given struct"); + if (!(mConditionalBits & GetBitForSID(aSID))) { + MOZ_ASSERT(!mEntries[aSID], + "rule node should not have unconditional and conditional " + "style data for a given struct"); + mEntries[aSID] = nullptr; + } + MOZ_ASSERT(aConditions.CacheableWithDependencies(), "don't call SetStyleData with a cache key that has no " "conditions or is uncacheable"); + #ifdef DEBUG for (Entry* e = static_cast(mEntries[aSID]); e; e = e->mNext) { NS_WARNING_ASSERTION(e->mConditions != aConditions, From e21d52047e18505062d59874b107cde7476c093b Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Fri, 30 Jun 2017 13:46:21 -0400 Subject: [PATCH 32/63] Bug 1376026 - assume DWrite is available on Windows 7 even without the platform update. r=jrmuizel --- gfx/thebes/gfxWindowsPlatform.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index 46eab05a8b39..ebac024fd6bd 100755 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -388,12 +388,6 @@ gfxWindowsPlatform::CanUseHardwareVideoDecoding() bool gfxWindowsPlatform::InitDWriteSupport() { - // DWrite is only supported on Windows 7 with the platform update and higher. - // We check this by seeing if D2D1 support is available. - if (!Factory::SupportsD2D1()) { - return false; - } - mozilla::ScopedGfxFeatureReporter reporter("DWrite"); decltype(DWriteCreateFactory)* createDWriteFactory = (decltype(DWriteCreateFactory)*) GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory"); From edc6db4195dace5c6a4cd140cb4b623a9d7af7e1 Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Fri, 30 Jun 2017 14:09:05 -0400 Subject: [PATCH 33/63] Bug 1376026 - fix plumbing of DWrite parameters for Skia fonts to not depend on gfxPlatform. r=jrmuizel --- gfx/2d/2D.h | 17 +-- gfx/2d/DrawTargetD2D1.cpp | 43 +------- gfx/2d/DrawTargetD2D1.h | 2 - gfx/2d/Factory.cpp | 100 +++++++++++------- gfx/2d/InlineTranslator.cpp | 15 --- gfx/2d/InlineTranslator.h | 2 - gfx/2d/NativeFontResourceDWrite.cpp | 5 +- gfx/2d/RecordedEvent.h | 3 +- gfx/2d/RecordedEventImpl.h | 12 ++- gfx/2d/ScaledFontDWrite.cpp | 46 ++++++-- gfx/2d/ScaledFontDWrite.h | 52 ++++++--- gfx/skia/skia/include/ports/SkTypeface_win.h | 4 +- gfx/skia/skia/src/ports/SkFontHost_win.cpp | 6 +- gfx/skia/skia/src/ports/SkTypeface_win_dw.cpp | 10 +- gfx/skia/skia/src/ports/SkTypeface_win_dw.h | 10 +- gfx/thebes/gfxDWriteCommon.cpp | 2 +- gfx/thebes/gfxDWriteCommon.h | 2 +- gfx/thebes/gfxDWriteFontList.cpp | 10 +- gfx/thebes/gfxDWriteFonts.cpp | 31 +++--- gfx/thebes/gfxDWriteFonts.h | 3 - gfx/thebes/gfxWindowsPlatform.cpp | 57 ++-------- gfx/thebes/gfxWindowsPlatform.h | 4 +- layout/printing/PrintTranslator.cpp | 15 --- layout/printing/PrintTranslator.h | 2 - 24 files changed, 209 insertions(+), 244 deletions(-) diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h index 37f08d5384f2..fb561b752c2d 100644 --- a/gfx/2d/2D.h +++ b/gfx/2d/2D.h @@ -1520,12 +1520,13 @@ public: * * @param aData Pointer to the data * @param aSize Size of the TrueType data - * @param aType Type of NativeFontResource that should be created. + * @param aBackendType Type of the reference DrawTarget the font should be created for. + * @param aFontType Type of NativeFontResource that should be created. * @param aFontContext Optional native font context to be used to create the NativeFontResource. * @return a NativeFontResource of nullptr if failed. */ static already_AddRefed - CreateNativeFontResource(uint8_t *aData, uint32_t aSize, FontType aType, void* aFontContext = nullptr); + CreateNativeFontResource(uint8_t *aData, uint32_t aSize, BackendType aBackendType, FontType aFontType, void* aFontContext = nullptr); /** * This creates an unscaled font of the given type based on font descriptor @@ -1661,16 +1662,13 @@ public: * Returns true on success, or false on failure and leaves the D2D1/Direct3D11 devices unset. */ static bool SetDirect3D11Device(ID3D11Device *aDevice); - static bool SetDWriteFactory(IDWriteFactory *aFactory); static ID3D11Device *GetDirect3D11Device(); static ID2D1Device *GetD2D1Device(); static uint32_t GetD2D1DeviceSeq(); static IDWriteFactory *GetDWriteFactory(); + static IDWriteFactory* EnsureDWriteFactory(); static bool SupportsD2D1(); - static already_AddRefed - CreateDWriteGlyphRenderingOptions(IDWriteRenderingParams *aParams); - static uint64_t GetD2DVRAMUsageDrawTarget(); static uint64_t GetD2DVRAMUsageSourceSurface(); static void D2DCleanup(); @@ -1681,7 +1679,10 @@ public: const RefPtr& aUnscaledFont, Float aSize, bool aUseEmbeddedBitmap, - bool aForceGDIMode); + bool aForceGDIMode, + IDWriteRenderingParams *aParams, + Float aGamma, + Float aContrast); static void UpdateSystemTextQuality(); @@ -1689,6 +1690,8 @@ private: static ID2D1Device *mD2D1Device; static ID3D11Device *mD3D11Device; static IDWriteFactory *mDWriteFactory; + static bool mDWriteFactoryInitialized; + static Mutex* mDWriteFactoryLock; #endif static DrawEventRecorder *mRecorder; diff --git a/gfx/2d/DrawTargetD2D1.cpp b/gfx/2d/DrawTargetD2D1.cpp index 0df50ac8cea4..d099b652f707 100644 --- a/gfx/2d/DrawTargetD2D1.cpp +++ b/gfx/2d/DrawTargetD2D1.cpp @@ -17,6 +17,8 @@ #include "Tools.h" #include "nsAppRunner.h" +#include "mozilla/Mutex.h" + using namespace std; // decltype is not usable for overloaded functions. @@ -32,7 +34,6 @@ namespace gfx { uint64_t DrawTargetD2D1::mVRAMUsageDT; uint64_t DrawTargetD2D1::mVRAMUsageSS; -IDWriteFactory *DrawTargetD2D1::mDWriteFactory; ID2D1Factory1* DrawTargetD2D1::mFactory = nullptr; ID2D1Factory1 *D2DFactory1() @@ -608,7 +609,7 @@ DrawTargetD2D1::FillGlyphs(ScaledFont *aFont, const GlyphBuffer &aBuffer, const Pattern &aPattern, const DrawOptions &aOptions, - const GlyphRenderingOptions *aRenderingOptions) + const GlyphRenderingOptions*) { if (aFont->GetType() != FontType::DWRITE) { gfxDebug() << *this << ": Ignoring drawing call for incompatible font."; @@ -617,16 +618,7 @@ DrawTargetD2D1::FillGlyphs(ScaledFont *aFont, ScaledFontDWrite *font = static_cast(aFont); - IDWriteRenderingParams *params = nullptr; - if (aRenderingOptions) { - if (aRenderingOptions->GetType() != FontType::DWRITE) { - gfxDebug() << *this << ": Ignoring incompatible GlyphRenderingOptions."; - // This should never happen. - MOZ_ASSERT(false); - } else { - params = static_cast(aRenderingOptions)->mParams; - } - } + IDWriteRenderingParams *params = font->mParams; AntialiasMode aaMode = font->GetDefaultAAMode(); @@ -1256,33 +1248,6 @@ DrawTargetD2D1::factory() return mFactory; } -IDWriteFactory* -DrawTargetD2D1::GetDWriteFactory() -{ - if (mDWriteFactory) { - return mDWriteFactory; - } - - decltype(DWriteCreateFactory)* createDWriteFactory; - HMODULE dwriteModule = LoadLibraryW(L"dwrite.dll"); - createDWriteFactory = (decltype(DWriteCreateFactory)*) - GetProcAddress(dwriteModule, "DWriteCreateFactory"); - - if (!createDWriteFactory) { - gfxWarning() << "Failed to locate DWriteCreateFactory function."; - return nullptr; - } - - HRESULT hr = createDWriteFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), - reinterpret_cast(&mDWriteFactory)); - - if (FAILED(hr)) { - gfxWarning() << "Failed to create DWrite Factory."; - } - - return mDWriteFactory; -} - void DrawTargetD2D1::CleanupD2D() { diff --git a/gfx/2d/DrawTargetD2D1.h b/gfx/2d/DrawTargetD2D1.h index 2107da2e6b0c..da6e8f28d52c 100644 --- a/gfx/2d/DrawTargetD2D1.h +++ b/gfx/2d/DrawTargetD2D1.h @@ -155,7 +155,6 @@ public: static ID2D1Factory1 *factory(); static void CleanupD2D(); - static IDWriteFactory *GetDWriteFactory(); operator std::string() const { std::stringstream stream; @@ -294,7 +293,6 @@ private: bool mDidComplexBlendWithListInList; static ID2D1Factory1 *mFactory; - static IDWriteFactory *mDWriteFactory; // This value is uesed to verify if the DrawTarget is created by a stale device. uint32_t mDeviceSeq; diff --git a/gfx/2d/Factory.cpp b/gfx/2d/Factory.cpp index bef27f1d9672..6a0941023bd4 100644 --- a/gfx/2d/Factory.cpp +++ b/gfx/2d/Factory.cpp @@ -45,6 +45,7 @@ #include #include "HelpersD2D.h" #include "HelpersWinFonts.h" +#include "mozilla/Mutex.h" #endif #include "DrawTargetDual.h" @@ -203,6 +204,8 @@ static uint32_t mDeviceSeq = 0; ID3D11Device *Factory::mD3D11Device = nullptr; ID2D1Device *Factory::mD2D1Device = nullptr; IDWriteFactory *Factory::mDWriteFactory = nullptr; +bool Factory::mDWriteFactoryInitialized = false; +Mutex* Factory::mDWriteFactoryLock = nullptr; #endif DrawEventRecorder *Factory::mRecorder; @@ -229,6 +232,10 @@ Factory::Init(const Config& aConfig) #ifdef MOZ_ENABLE_FREETYPE mFTLock = new Mutex("Factory::mFTLock"); #endif + +#ifdef WIN32 + mDWriteFactoryLock = new Mutex("Factory::mDWriteFactoryLock"); +#endif } void @@ -247,6 +254,13 @@ Factory::ShutDown() mFTLock = nullptr; } #endif + +#ifdef WIN32 + if (mDWriteFactoryLock) { + delete mDWriteFactoryLock; + mDWriteFactoryLock = nullptr; + } +#endif } bool @@ -553,38 +567,26 @@ Factory::CreateScaledFontForNativeFont(const NativeFont &aNativeFont, } already_AddRefed -Factory::CreateNativeFontResource(uint8_t *aData, uint32_t aSize, FontType aType, void* aFontContext) +Factory::CreateNativeFontResource(uint8_t *aData, uint32_t aSize, BackendType aBackendType, FontType aFontType, void* aFontContext) { - switch (aType) { + switch (aFontType) { #ifdef WIN32 case FontType::DWRITE: { - return NativeFontResourceDWrite::Create(aData, aSize, - /* aNeedsCairo = */ false); + bool needsCairo = aBackendType == BackendType::CAIRO || + aBackendType == BackendType::SKIA; + return NativeFontResourceDWrite::Create(aData, aSize, needsCairo); } -#endif - case FontType::CAIRO: -#ifdef USE_SKIA - case FontType::SKIA: -#endif - { -#ifdef WIN32 - if (GetDWriteFactory()) { - return NativeFontResourceDWrite::Create(aData, aSize, - /* aNeedsCairo = */ true); - } else { - return NativeFontResourceGDI::Create(aData, aSize); - } + case FontType::GDI: + return NativeFontResourceGDI::Create(aData, aSize); #elif defined(XP_DARWIN) - return NativeFontResourceMac::Create(aData, aSize); + case FontType::MAC: + return NativeFontResourceMac::Create(aData, aSize); #elif defined(MOZ_WIDGET_GTK) - return NativeFontResourceFontconfig::Create(aData, aSize, - static_cast(aFontContext)); -#else - gfxWarning() << "Unable to create cairo scaled font from truetype data"; - return nullptr; + case FontType::FONTCONFIG: + return NativeFontResourceFontconfig::Create(aData, aSize, + static_cast(aFontContext)); #endif - } default: gfxWarning() << "Unable to create requested font resource from truetype data"; return nullptr; @@ -756,13 +758,6 @@ Factory::CreateDrawTargetForD3D11Texture(ID3D11Texture2D *aTexture, SurfaceForma return nullptr; } -bool -Factory::SetDWriteFactory(IDWriteFactory *aFactory) -{ - mDWriteFactory = aFactory; - return true; -} - bool Factory::SetDirect3D11Device(ID3D11Device *aDevice) { @@ -818,18 +813,43 @@ Factory::GetDWriteFactory() return mDWriteFactory; } +IDWriteFactory* +Factory::EnsureDWriteFactory() +{ + MOZ_ASSERT(mDWriteFactoryLock); + MutexAutoLock lock(*mDWriteFactoryLock); + + if (mDWriteFactoryInitialized) { + return mDWriteFactory; + } + + mDWriteFactoryInitialized = true; + + HMODULE dwriteModule = LoadLibraryW(L"dwrite.dll"); + decltype(DWriteCreateFactory)* createDWriteFactory = (decltype(DWriteCreateFactory)*) + GetProcAddress(dwriteModule, "DWriteCreateFactory"); + + if (!createDWriteFactory) { + gfxWarning() << "Failed to locate DWriteCreateFactory function."; + return nullptr; + } + + HRESULT hr = createDWriteFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), + reinterpret_cast(&mDWriteFactory)); + + if (FAILED(hr)) { + gfxWarning() << "Failed to create DWrite Factory."; + } + + return mDWriteFactory; +} + bool Factory::SupportsD2D1() { return !!D2DFactory1(); } -already_AddRefed -Factory::CreateDWriteGlyphRenderingOptions(IDWriteRenderingParams *aParams) -{ - return MakeAndAddRef(aParams); -} - BYTE sSystemTextQuality = CLEARTYPE_QUALITY; void Factory::UpdateSystemTextQuality() @@ -867,10 +887,14 @@ Factory::CreateScaledFontForDWriteFont(IDWriteFontFace* aFontFace, const RefPtr& aUnscaledFont, float aSize, bool aUseEmbeddedBitmap, - bool aForceGDIMode) + bool aForceGDIMode, + IDWriteRenderingParams* aParams, + Float aGamma, + Float aContrast) { return MakeAndAddRef(aFontFace, aUnscaledFont, aSize, aUseEmbeddedBitmap, aForceGDIMode, + aParams, aGamma, aContrast, aStyle); } diff --git a/gfx/2d/InlineTranslator.cpp b/gfx/2d/InlineTranslator.cpp index ecb051883416..e3524e6b98e1 100644 --- a/gfx/2d/InlineTranslator.cpp +++ b/gfx/2d/InlineTranslator.cpp @@ -76,20 +76,5 @@ InlineTranslator::CreateDrawTarget(ReferencePtr aRefPtr, return drawTarget.forget(); } -FontType -InlineTranslator::GetDesiredFontType() -{ - switch (mBaseDT->GetBackendType()) { - case BackendType::DIRECT2D: - return FontType::DWRITE; - case BackendType::CAIRO: - return FontType::CAIRO; - case BackendType::SKIA: - return FontType::SKIA; - default: - return FontType::CAIRO; - } -} - } // namespace gfx } // namespace mozilla diff --git a/gfx/2d/InlineTranslator.h b/gfx/2d/InlineTranslator.h index b5305f703def..f218c1c7f99e 100644 --- a/gfx/2d/InlineTranslator.h +++ b/gfx/2d/InlineTranslator.h @@ -173,8 +173,6 @@ public: mozilla::gfx::DrawTarget* GetReferenceDrawTarget() final { return mBaseDT; } - mozilla::gfx::FontType GetDesiredFontType() final; - void* GetFontContext() final { return mFontContext; } private: diff --git a/gfx/2d/NativeFontResourceDWrite.cpp b/gfx/2d/NativeFontResourceDWrite.cpp index 02395601b599..4b934c23d8aa 100644 --- a/gfx/2d/NativeFontResourceDWrite.cpp +++ b/gfx/2d/NativeFontResourceDWrite.cpp @@ -9,7 +9,6 @@ #include -#include "DrawTargetD2D1.h" #include "Logging.h" #include "mozilla/RefPtr.h" @@ -70,7 +69,7 @@ public: { if (!mInstance) { mInstance = new DWriteFontFileLoader(); - DrawTargetD2D1::GetDWriteFactory()-> + Factory::GetDWriteFactory()-> RegisterFontFileLoader(mInstance); } return mInstance; @@ -222,7 +221,7 @@ already_AddRefed NativeFontResourceDWrite::Create(uint8_t *aFontData, uint32_t aDataLength, bool aNeedsCairo) { - IDWriteFactory *factory = DrawTargetD2D1::GetDWriteFactory(); + IDWriteFactory *factory = Factory::EnsureDWriteFactory(); if (!factory) { gfxWarning() << "Failed to get DWrite Factory."; return nullptr; diff --git a/gfx/2d/RecordedEvent.h b/gfx/2d/RecordedEvent.h index 97708cdc31fa..4058df57a1b7 100644 --- a/gfx/2d/RecordedEvent.h +++ b/gfx/2d/RecordedEvent.h @@ -24,7 +24,7 @@ const uint32_t kMagicInt = 0xc001feed; // loss of backwards compatibility. Old streams will not work in a player // using a newer major revision. And new streams will not work in a player // using an older major revision. -const uint16_t kMajorRevision = 9; +const uint16_t kMajorRevision = 10; // A change in minor revision means additions of new events. New streams will // not play in older players. const uint16_t kMinorRevision = 0; @@ -111,7 +111,6 @@ public: const IntSize &aSize, SurfaceFormat aFormat); virtual DrawTarget *GetReferenceDrawTarget() = 0; - virtual FontType GetDesiredFontType() = 0; virtual void* GetFontContext() { return nullptr; } }; diff --git a/gfx/2d/RecordedEventImpl.h b/gfx/2d/RecordedEventImpl.h index 2876b94cb7c4..942731b124d4 100644 --- a/gfx/2d/RecordedEventImpl.h +++ b/gfx/2d/RecordedEventImpl.h @@ -847,7 +847,9 @@ public: } explicit RecordedFontData(UnscaledFont *aUnscaledFont) - : RecordedEventDerived(FONTDATA), mData(nullptr) + : RecordedEventDerived(FONTDATA) + , mType(aUnscaledFont->GetType()) + , mData(nullptr) { mGetFontFileDataSucceeded = aUnscaledFont->GetFontFileData(&FontDataProc, this); } @@ -871,6 +873,7 @@ public: private: friend class RecordedEvent; + FontType mType; uint8_t* mData; RecordedFontDetails mFontDetails; @@ -2642,8 +2645,8 @@ RecordedFontData::PlayEvent(Translator *aTranslator) const { RefPtr fontResource = Factory::CreateNativeFontResource(mData, mFontDetails.size, - aTranslator->GetDesiredFontType(), - aTranslator->GetFontContext()); + aTranslator->GetReferenceDrawTarget()->GetBackendType(), + mType, aTranslator->GetFontContext()); if (!fontResource) { return false; } @@ -2658,6 +2661,7 @@ RecordedFontData::Record(S &aStream) const { MOZ_ASSERT(mGetFontFileDataSucceeded); + WriteElement(aStream, mType); WriteElement(aStream, mFontDetails.fontDataKey); WriteElement(aStream, mFontDetails.size); aStream.write((const char*)mData, mFontDetails.size); @@ -2696,8 +2700,10 @@ RecordedFontData::GetFontDetails(RecordedFontDetails& fontDetails) inline RecordedFontData::RecordedFontData(istream &aStream) : RecordedEventDerived(FONTDATA) + , mType(FontType::SKIA) , mData(nullptr) { + ReadElement(aStream, mType); ReadElement(aStream, mFontDetails.fontDataKey); ReadElement(aStream, mFontDetails.size); mData = new uint8_t[mFontDetails.size]; diff --git a/gfx/2d/ScaledFontDWrite.cpp b/gfx/2d/ScaledFontDWrite.cpp index 05278bd909ff..ed4b5d59dc6a 100644 --- a/gfx/2d/ScaledFontDWrite.cpp +++ b/gfx/2d/ScaledFontDWrite.cpp @@ -3,11 +3,11 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "DrawTargetD2D1.h" #include "ScaledFontDWrite.h" #include "UnscaledFontDWrite.h" #include "PathD2D.h" #include "gfxFont.h" +#include "Logging.h" using namespace std; @@ -108,16 +108,24 @@ ScaledFontDWrite::ScaledFontDWrite(IDWriteFontFace *aFontFace, Float aSize, bool aUseEmbeddedBitmap, bool aForceGDIMode, + IDWriteRenderingParams* aParams, + Float aGamma, + Float aContrast, const gfxFontStyle* aStyle) : ScaledFontBase(aUnscaledFont, aSize) , mFontFace(aFontFace) , mUseEmbeddedBitmap(aUseEmbeddedBitmap) , mForceGDIMode(aForceGDIMode) + , mParams(aParams) + , mGamma(aGamma) + , mContrast(aContrast) { - mStyle = SkFontStyle(aStyle->weight, - DWriteFontStretchFromStretch(aStyle->stretch), - aStyle->style == NS_FONT_STYLE_NORMAL ? - SkFontStyle::kUpright_Slant : SkFontStyle::kItalic_Slant); + if (aStyle) { + mStyle = SkFontStyle(aStyle->weight, + DWriteFontStretchFromStretch(aStyle->stretch), + aStyle->style == NS_FONT_STYLE_NORMAL ? + SkFontStyle::kUpright_Slant : SkFontStyle::kItalic_Slant); + } } already_AddRefed @@ -143,12 +151,12 @@ SkTypeface* ScaledFontDWrite::GetSkTypeface() { if (!mTypeface) { - IDWriteFactory *factory = DrawTargetD2D1::GetDWriteFactory(); + IDWriteFactory *factory = Factory::GetDWriteFactory(); if (!factory) { return nullptr; } - mTypeface = SkCreateTypefaceFromDWriteFont(factory, mFontFace, mStyle, mForceGDIMode); + mTypeface = SkCreateTypefaceFromDWriteFont(factory, mFontFace, mStyle, mForceGDIMode, mGamma, mContrast); } return mTypeface; } @@ -272,12 +280,34 @@ UnscaledFontDWrite::GetFontFileData(FontFileDataOutput aDataCallback, void *aBat return true; } +bool +ScaledFontDWrite::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) +{ + InstanceData instance(this); + aCb(reinterpret_cast(&instance), sizeof(instance), aBaton); + return true; +} + already_AddRefed UnscaledFontDWrite::CreateScaledFont(Float aGlyphSize, const uint8_t* aInstanceData, uint32_t aInstanceDataLength) { - RefPtr scaledFont = new ScaledFontDWrite(mFontFace, this, aGlyphSize); + if (aInstanceDataLength < sizeof(ScaledFontDWrite::InstanceData)) { + gfxWarning() << "DWrite scaled font instance data is truncated."; + return nullptr; + } + + const ScaledFontDWrite::InstanceData *instanceData = + reinterpret_cast(aInstanceData); + RefPtr scaledFont = + new ScaledFontDWrite(mFontFace, this, aGlyphSize, + instanceData->mUseEmbeddedBitmap, + instanceData->mForceGDIMode, + nullptr, + instanceData->mGamma, + instanceData->mContrast); + if (mNeedsCairo && !scaledFont->PopulateCairoScaledFont()) { gfxWarning() << "Unable to create cairo scaled font DWrite font."; return nullptr; diff --git a/gfx/2d/ScaledFontDWrite.h b/gfx/2d/ScaledFontDWrite.h index bce40f5ce77a..e7866a974fb1 100644 --- a/gfx/2d/ScaledFontDWrite.h +++ b/gfx/2d/ScaledFontDWrite.h @@ -15,6 +15,9 @@ struct gfxFontStyle; namespace mozilla { namespace gfx { +class NativeFontResourceDWrite; +class UnscaledFontDWrite; + class ScaledFontDWrite final : public ScaledFontBase { public: @@ -26,6 +29,8 @@ public: , mFontFace(aFont) , mUseEmbeddedBitmap(false) , mForceGDIMode(false) + , mGamma(2.2f) + , mContrast(1.0f) {} ScaledFontDWrite(IDWriteFontFace *aFontFace, @@ -33,7 +38,10 @@ public: Float aSize, bool aUseEmbeddedBitmap, bool aForceGDIMode, - const gfxFontStyle* aStyle); + IDWriteRenderingParams *aParams, + Float aContrast, + Float aGamma, + const gfxFontStyle* aStyle = nullptr); FontType GetType() const override { return FontType::DWRITE; } @@ -46,6 +54,8 @@ public: bool CanSerialize() override { return true; } + bool GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) override; + AntialiasMode GetDefaultAAMode() override; bool UseEmbeddedBitmaps() { return mUseEmbeddedBitmap; } @@ -59,29 +69,39 @@ public: RefPtr mFontFace; bool mUseEmbeddedBitmap; bool mForceGDIMode; + // DrawTargetD2D1 requires the IDWriteRenderingParams, + // but we also separately need to store the gamma and contrast + // since Skia needs to be able to access these without having + // to use the full set of DWrite parameters (which would be + // required to recreate an IDWriteRenderingParams) in a + // DrawTargetRecording playback. + RefPtr mParams; + Float mGamma; + Float mContrast; protected: #ifdef USE_CAIRO_SCALED_FONT cairo_font_face_t* GetCairoFontFace() override; #endif -}; - -class GlyphRenderingOptionsDWrite : public GlyphRenderingOptions -{ -public: - MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GlyphRenderingOptionsDWrite, override) - explicit GlyphRenderingOptionsDWrite(IDWriteRenderingParams *aParams) - : mParams(aParams) - { - } - - FontType GetType() const override { return FontType::DWRITE; } private: - friend class DrawTargetD2D; - friend class DrawTargetD2D1; + friend class NativeFontResourceDWrite; + friend class UnscaledFontDWrite; - RefPtr mParams; + struct InstanceData + { + InstanceData(ScaledFontDWrite* aScaledFont) + : mUseEmbeddedBitmap(aScaledFont->mUseEmbeddedBitmap) + , mForceGDIMode(aScaledFont->mForceGDIMode) + , mGamma(aScaledFont->mGamma) + , mContrast(aScaledFont->mContrast) + {} + + bool mUseEmbeddedBitmap; + bool mForceGDIMode; + Float mGamma; + Float mContrast; + }; }; } diff --git a/gfx/skia/skia/include/ports/SkTypeface_win.h b/gfx/skia/skia/include/ports/SkTypeface_win.h index cb760ae31b58..d3b5ffae4496 100644 --- a/gfx/skia/skia/include/ports/SkTypeface_win.h +++ b/gfx/skia/skia/include/ports/SkTypeface_win.h @@ -53,7 +53,9 @@ struct IDWriteFontFallback; SK_API SkTypeface* SkCreateTypefaceFromDWriteFont(IDWriteFactory* aFactory, IDWriteFontFace* aFontFace, SkFontStyle aStyle, - bool aForceGDI); + bool aForceGDI, + float aGamma, + float aContrast); SK_API sk_sp SkFontMgr_New_GDI(); SK_API sk_sp SkFontMgr_New_DirectWrite(IDWriteFactory* factory = NULL, diff --git a/gfx/skia/skia/src/ports/SkFontHost_win.cpp b/gfx/skia/skia/src/ports/SkFontHost_win.cpp index b9148027ab7f..f976e019cb38 100644 --- a/gfx/skia/skia/src/ports/SkFontHost_win.cpp +++ b/gfx/skia/skia/src/ports/SkFontHost_win.cpp @@ -341,9 +341,11 @@ SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT& origLF) { SkTypeface* SkCreateTypefaceFromDWriteFont(IDWriteFactory* aFactory, IDWriteFontFace* aFontFace, SkFontStyle aStyle, - bool aForceGDI) + bool aForceGDI, + float aGamma, + float aContrast) { - return DWriteFontTypeface::Create(aFactory, aFontFace, aStyle, aForceGDI); + return DWriteFontTypeface::Create(aFactory, aFontFace, aStyle, aForceGDI, aGamma, aContrast); } /** diff --git a/gfx/skia/skia/src/ports/SkTypeface_win_dw.cpp b/gfx/skia/skia/src/ports/SkTypeface_win_dw.cpp index 60ad429dad32..b9ea8f8834ac 100644 --- a/gfx/skia/skia/src/ports/SkTypeface_win_dw.cpp +++ b/gfx/skia/skia/src/ports/SkTypeface_win_dw.cpp @@ -251,10 +251,6 @@ SkScalerContext* DWriteFontTypeface::onCreateScalerContext(const SkScalerContext return new SkScalerContext_DW(sk_ref_sp(const_cast(this)), effects, desc); } -#ifdef MOZ_SKIA -IDWriteRenderingParams* GetDwriteRenderingParams(bool aGDI); -#endif - void DWriteFontTypeface::onFilterRec(SkScalerContext::Rec* rec) const { if (rec->fFlags & SkScalerContext::kLCD_Vertical_Flag) { rec->fMaskFormat = SkMask::kA8_Format; @@ -288,13 +284,11 @@ void DWriteFontTypeface::onFilterRec(SkScalerContext::Rec* rec) const { } } #elif defined(MOZ_SKIA) - IDWriteRenderingParams* params = GetDwriteRenderingParams(ForceGDI()); - SkASSERT(params); - rec->setContrast(params->GetEnhancedContrast()); + rec->setContrast(fContrast); // GDI gamma should be 2.3 // See the LUT gamma values comment for GDI fonts. - float gamma = ForceGDI() ? 2.3f : params->GetGamma(); + float gamma = ForceGDI() ? 2.3f : fGamma; rec->setDeviceGamma(gamma); rec->setPaintGamma(gamma); #endif diff --git a/gfx/skia/skia/src/ports/SkTypeface_win_dw.h b/gfx/skia/skia/src/ports/SkTypeface_win_dw.h index 035d133be772..831da779e382 100644 --- a/gfx/skia/skia/src/ports/SkTypeface_win_dw.h +++ b/gfx/skia/skia/src/ports/SkTypeface_win_dw.h @@ -53,6 +53,8 @@ private: , fDWriteFont(SkSafeRefComPtr(font)) , fDWriteFontFace(SkRefComPtr(fontFace)) , fForceGDI(false) + , fGamma(2.2f) + , fContrast(1.0f) { if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace1))) { // IUnknown::QueryInterface states that if it fails, punk will be set to nullptr. @@ -81,12 +83,16 @@ public: static DWriteFontTypeface* Create(IDWriteFactory* factory, IDWriteFontFace* fontFace, SkFontStyle aStyle, - bool aForceGDI) { + bool aForceGDI, + float aGamma, + float aContrast) { DWriteFontTypeface* typeface = new DWriteFontTypeface(aStyle, factory, fontFace, nullptr, nullptr, nullptr, nullptr); typeface->fForceGDI = aForceGDI; + typeface->fGamma = aGamma; + typeface->fContrast = aContrast; return typeface; } @@ -139,6 +145,8 @@ protected: private: typedef SkTypeface INHERITED; bool fForceGDI; + float fGamma; + float fContrast; }; #endif diff --git a/gfx/thebes/gfxDWriteCommon.cpp b/gfx/thebes/gfxDWriteCommon.cpp index 3047818bb6b1..7d4db7582da4 100644 --- a/gfx/thebes/gfxDWriteCommon.cpp +++ b/gfx/thebes/gfxDWriteCommon.cpp @@ -158,7 +158,7 @@ gfxDWriteFontFileLoader::CreateCustomFontFile(FallibleTArray& aFontData MOZ_ASSERT(aFontFile); MOZ_ASSERT(aFontFileStream); - IDWriteFactory *factory = gfxWindowsPlatform::GetPlatform()->GetDWriteFactory(); + IDWriteFactory *factory = mozilla::gfx::Factory::GetDWriteFactory(); if (!factory) { gfxCriticalError() << "Failed to get DWrite Factory in CreateCustomFontFile."; return E_FAIL; diff --git a/gfx/thebes/gfxDWriteCommon.h b/gfx/thebes/gfxDWriteCommon.h index a355b59c672a..65c2df7bcbe4 100644 --- a/gfx/thebes/gfxDWriteCommon.h +++ b/gfx/thebes/gfxDWriteCommon.h @@ -127,7 +127,7 @@ public: { if (!mInstance) { mInstance = new gfxDWriteFontFileLoader(); - gfxWindowsPlatform::GetPlatform()->GetDWriteFactory()-> + mozilla::gfx::Factory::GetDWriteFactory()-> RegisterFontFileLoader(mInstance); } return mInstance; diff --git a/gfx/thebes/gfxDWriteFontList.cpp b/gfx/thebes/gfxDWriteFontList.cpp index 4a5bf38c8d2d..3af5739d8cca 100644 --- a/gfx/thebes/gfxDWriteFontList.cpp +++ b/gfx/thebes/gfxDWriteFontList.cpp @@ -613,7 +613,7 @@ gfxDWriteFontEntry::CreateFontFace(IDWriteFontFace **aFontFace, hr = mFont->CreateFontFace(getter_AddRefs(mFontFace)); } else if (mFontFile) { IDWriteFontFile *fontFile = mFontFile.get(); - hr = gfxWindowsPlatform::GetPlatform()->GetDWriteFactory()-> + hr = Factory::GetDWriteFactory()-> CreateFontFace(mFaceType, 1, &fontFile, @@ -644,7 +644,7 @@ gfxDWriteFontEntry::CreateFontFace(IDWriteFontFace **aFontFace, if (FAILED(mFontFace->GetFiles(&numberOfFiles, files.Elements()))) { return NS_ERROR_FAILURE; } - HRESULT hr = gfxWindowsPlatform::GetPlatform()->GetDWriteFactory()-> + HRESULT hr = Factory::GetDWriteFactory()-> CreateFontFace(mFontFace->GetType(), numberOfFiles, files.Elements(), @@ -883,7 +883,7 @@ gfxDWriteFontList::InitFontListForPlatform() mFontSubstitutes.Clear(); mNonExistingFonts.Clear(); - hr = gfxWindowsPlatform::GetPlatform()->GetDWriteFactory()-> + hr = Factory::GetDWriteFactory()-> GetGdiInterop(getter_AddRefs(mGDIInterop)); if (FAILED(hr)) { Telemetry::Accumulate(Telemetry::DWRITEFONT_INIT_PROBLEM, @@ -894,7 +894,7 @@ gfxDWriteFontList::InitFontListForPlatform() QueryPerformanceCounter(&t2); // base-class/interop initialization RefPtr factory = - gfxWindowsPlatform::GetPlatform()->GetDWriteFactory(); + Factory::GetDWriteFactory(); hr = factory->GetSystemFontCollection(getter_AddRefs(mSystemFonts)); NS_ASSERTION(SUCCEEDED(hr), "GetSystemFontCollection failed!"); @@ -1425,7 +1425,7 @@ gfxDWriteFontList::GlobalFontFallback(const uint32_t aCh, HRESULT hr; RefPtr dwFactory = - gfxWindowsPlatform::GetPlatform()->GetDWriteFactory(); + Factory::GetDWriteFactory(); if (!dwFactory) { return nullptr; } diff --git a/gfx/thebes/gfxDWriteFonts.cpp b/gfx/thebes/gfxDWriteFonts.cpp index 4db079af6927..8a83d9fe2ab2 100644 --- a/gfx/thebes/gfxDWriteFonts.cpp +++ b/gfx/thebes/gfxDWriteFonts.cpp @@ -599,19 +599,6 @@ gfxDWriteFont::GetGlyphWidth(DrawTarget& aDrawTarget, uint16_t aGID) return width; } -already_AddRefed -gfxDWriteFont::GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams) -{ - if (mUseClearType) { - return Factory::CreateDWriteGlyphRenderingOptions( - gfxWindowsPlatform::GetPlatform()->GetRenderingParams(GetForceGDIClassic() ? - gfxWindowsPlatform::TEXT_RENDERING_GDI_CLASSIC : gfxWindowsPlatform::TEXT_RENDERING_NORMAL)); - } else { - return Factory::CreateDWriteGlyphRenderingOptions(gfxWindowsPlatform::GetPlatform()-> - GetRenderingParams(gfxWindowsPlatform::TEXT_RENDERING_NO_CLEARTYPE)); - } -} - bool gfxDWriteFont::GetForceGDIClassic() { @@ -707,10 +694,17 @@ gfxDWriteFont::GetScaledFont(mozilla::gfx::DrawTarget *aTarget) GetUnscaledFont(), GetAdjustedSize(), GetCairoScaledFont()); - } else if (aTarget->GetBackendType() == BackendType::SKIA) { + } else { gfxDWriteFontEntry *fe = static_cast(mFontEntry.get()); bool useEmbeddedBitmap = (fe->IsCJKFont() && HasBitmapStrikeForSize(NS_lround(mAdjustedSize))); + bool forceGDI = GetForceGDIClassic(); + + IDWriteRenderingParams* params = gfxWindowsPlatform::GetPlatform()->GetRenderingParams( + mUseClearType ? + (forceGDI ? + gfxWindowsPlatform::TEXT_RENDERING_GDI_CLASSIC : gfxWindowsPlatform::TEXT_RENDERING_NORMAL) : + gfxWindowsPlatform::TEXT_RENDERING_NO_CLEARTYPE); const gfxFontStyle* fontStyle = GetStyle(); mAzureScaledFont = @@ -718,11 +712,10 @@ gfxDWriteFont::GetScaledFont(mozilla::gfx::DrawTarget *aTarget) GetUnscaledFont(), GetAdjustedSize(), useEmbeddedBitmap, - GetForceGDIClassic()); - } else { - mAzureScaledFont = Factory::CreateScaledFontForNativeFont(nativeFont, - GetUnscaledFont(), - GetAdjustedSize()); + forceGDI, + params, + params->GetGamma(), + params->GetEnhancedContrast()); } mAzureScaledFontIsCairo = wantCairo; diff --git a/gfx/thebes/gfxDWriteFonts.h b/gfx/thebes/gfxDWriteFonts.h index 16d75b84fbee..76b8bba4b523 100644 --- a/gfx/thebes/gfxDWriteFonts.h +++ b/gfx/thebes/gfxDWriteFonts.h @@ -61,9 +61,6 @@ public: virtual int32_t GetGlyphWidth(DrawTarget& aDrawTarget, uint16_t aGID) override; - virtual already_AddRefed - GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams = nullptr) override; - virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf, FontCacheSizes* aSizes) const override; virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf, diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index ebac024fd6bd..4d5080f6c8b4 100755 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -80,14 +80,6 @@ using namespace mozilla::layers; using namespace mozilla::widget; using namespace mozilla::image; -IDWriteRenderingParams* GetDwriteRenderingParams(bool aGDI) -{ - gfxWindowsPlatform::TextRenderingMode mode = aGDI ? - gfxWindowsPlatform::TEXT_RENDERING_GDI_CLASSIC : - gfxWindowsPlatform::TEXT_RENDERING_NORMAL; - return gfxWindowsPlatform::GetPlatform()->GetRenderingParams(mode); -} - DCFromDrawTarget::DCFromDrawTarget(DrawTarget& aDrawTarget) { mDC = nullptr; @@ -363,7 +355,7 @@ gfxWindowsPlatform::InitAcceleration() UpdateRenderMode(); // If we have Skia and we didn't init dwrite already, do it now. - if (!mDWriteFactory && GetDefaultContentBackend() == BackendType::SKIA) { + if (!DWriteAvailable() && GetDefaultContentBackend() == BackendType::SKIA) { InitDWriteSupport(); } @@ -389,26 +381,10 @@ bool gfxWindowsPlatform::InitDWriteSupport() { mozilla::ScopedGfxFeatureReporter reporter("DWrite"); - decltype(DWriteCreateFactory)* createDWriteFactory = (decltype(DWriteCreateFactory)*) - GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory"); - if (!createDWriteFactory) { + if (!Factory::EnsureDWriteFactory()) { return false; } - // I need a direct pointer to be able to cast to IUnknown**, I also need to - // remember to release this because the nsRefPtr will AddRef it. - RefPtr factory; - HRESULT hr = createDWriteFactory( - DWRITE_FACTORY_TYPE_SHARED, - __uuidof(IDWriteFactory), - (IUnknown **)((IDWriteFactory **)getter_AddRefs(factory))); - if (FAILED(hr) || !factory) { - return false; - } - - mDWriteFactory = factory; - Factory::SetDWriteFactory(mDWriteFactory); - SetupClearTypeParams(); reporter.SetSuccessful(); return true; @@ -515,7 +491,7 @@ gfxWindowsPlatform::CreatePlatformFontList() // bug 630201 - older pre-RTM versions of Direct2D/DirectWrite cause odd // crashers so blacklist them altogether - if (IsNotWin7PreRTM() && GetDWriteFactory()) { + if (IsNotWin7PreRTM() && DWriteAvailable()) { pfl = new gfxDWriteFontList(); if (NS_SUCCEEDED(pfl->InitFontList())) { return pfl; @@ -579,22 +555,7 @@ already_AddRefed gfxWindowsPlatform::GetScaledFontForFont(DrawTarget* aTarget, gfxFont *aFont) { if (aFont->GetType() == gfxFont::FONT_TYPE_DWRITE) { - gfxDWriteFont *font = static_cast(aFont); - - NativeFont nativeFont; - nativeFont.mType = NativeFontType::DWRITE_FONT_FACE; - nativeFont.mFont = font->GetFontFace(); - - if (aTarget->GetBackendType() == BackendType::CAIRO) { - return Factory::CreateScaledFontWithCairo(nativeFont, - font->GetUnscaledFont(), - font->GetAdjustedSize(), - font->GetCairoScaledFont()); - } - - return Factory::CreateScaledFontForNativeFont(nativeFont, - font->GetUnscaledFont(), - font->GetAdjustedSize()); + return aFont->GetScaledFont(aTarget); } NS_ASSERTION(aFont->GetType() == gfxFont::FONT_TYPE_GDI, @@ -1142,7 +1103,7 @@ gfxWindowsPlatform::FontsPrefsChanged(const char *aPref) void gfxWindowsPlatform::SetupClearTypeParams() { - if (GetDWriteFactory()) { + if (DWriteAvailable()) { // any missing prefs will default to invalid (-1) and be ignored; // out-of-range values will also be ignored FLOAT gamma = -1.0; @@ -1197,7 +1158,7 @@ gfxWindowsPlatform::SetupClearTypeParams() } RefPtr defaultRenderingParams; - GetDWriteFactory()->CreateRenderingParams(getter_AddRefs(defaultRenderingParams)); + Factory::GetDWriteFactory()->CreateRenderingParams(getter_AddRefs(defaultRenderingParams)); // For EnhancedContrast, we override the default if the user has not set it // in the registry (by using the ClearType Tuner). if (contrast < 0.0 || contrast > 10.0) { @@ -1253,14 +1214,14 @@ gfxWindowsPlatform::SetupClearTypeParams() mRenderingParams[TEXT_RENDERING_NO_CLEARTYPE] = defaultRenderingParams; - HRESULT hr = GetDWriteFactory()->CreateCustomRenderingParams( + HRESULT hr = Factory::GetDWriteFactory()->CreateCustomRenderingParams( gamma, contrast, level, dwriteGeometry, renderMode, getter_AddRefs(mRenderingParams[TEXT_RENDERING_NORMAL])); if (FAILED(hr) || !mRenderingParams[TEXT_RENDERING_NORMAL]) { mRenderingParams[TEXT_RENDERING_NORMAL] = defaultRenderingParams; } - hr = GetDWriteFactory()->CreateCustomRenderingParams( + hr = Factory::GetDWriteFactory()->CreateCustomRenderingParams( gamma, contrast, level, dwriteGeometry, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC, getter_AddRefs(mRenderingParams[TEXT_RENDERING_GDI_CLASSIC])); @@ -1565,7 +1526,7 @@ gfxWindowsPlatform::InitializeD2D() } // Using Direct2D depends on DWrite support. - if (!mDWriteFactory && !InitDWriteSupport()) { + if (!DWriteAvailable() && !InitDWriteSupport()) { d2d1.SetFailed(FeatureStatus::Failed, "Failed to initialize DirectWrite support", NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_DWRITE")); return; diff --git a/gfx/thebes/gfxWindowsPlatform.h b/gfx/thebes/gfxWindowsPlatform.h index aaed607b683f..12f637842379 100644 --- a/gfx/thebes/gfxWindowsPlatform.h +++ b/gfx/thebes/gfxWindowsPlatform.h @@ -192,8 +192,7 @@ public: void SetupClearTypeParams(); - IDWriteFactory *GetDWriteFactory() { return mDWriteFactory; } - inline bool DWriteEnabled() { return !!mDWriteFactory; } + inline bool DWriteAvailable() const { return !!mozilla::gfx::Factory::GetDWriteFactory(); } inline DWRITE_MEASURING_MODE DWriteMeasuringMode() { return mMeasuringMode; } IDWriteRenderingParams *GetRenderingParams(TextRenderingMode aRenderMode) @@ -259,7 +258,6 @@ private: void InitializeD2DConfig(); void InitializeDirectDrawConfig(); - RefPtr mDWriteFactory; RefPtr mRenderingParams[TEXT_RENDERING_COUNT]; DWRITE_MEASURING_MODE mMeasuringMode; diff --git a/layout/printing/PrintTranslator.cpp b/layout/printing/PrintTranslator.cpp index 0bda505bae69..a2f1f5cbf7b5 100644 --- a/layout/printing/PrintTranslator.cpp +++ b/layout/printing/PrintTranslator.cpp @@ -83,20 +83,5 @@ PrintTranslator::CreateDrawTarget(ReferencePtr aRefPtr, return drawTarget.forget(); } -FontType -PrintTranslator::GetDesiredFontType() -{ - switch (mBaseDT->GetBackendType()) { - case BackendType::DIRECT2D: - return FontType::DWRITE; - case BackendType::CAIRO: - return FontType::CAIRO; - case BackendType::SKIA: - return FontType::SKIA; - default: - return FontType::CAIRO; - } -} - } // namespace layout } // namespace mozilla diff --git a/layout/printing/PrintTranslator.h b/layout/printing/PrintTranslator.h index 96f68b78098e..4558518ab74e 100644 --- a/layout/printing/PrintTranslator.h +++ b/layout/printing/PrintTranslator.h @@ -175,8 +175,6 @@ public: mozilla::gfx::DrawTarget* GetReferenceDrawTarget() final { return mBaseDT; } - mozilla::gfx::FontType GetDesiredFontType() final; - private: RefPtr mDeviceContext; RefPtr mBaseDT; From 068bbf5940ac9946fbc5c712f701e787d475b3b6 Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Thu, 6 Jul 2017 00:03:58 -0400 Subject: [PATCH 34/63] Bug 1376026 - fix DWriteEnabled usage. r=me --- gfx/thebes/gfxWindowsPlatform.cpp | 8 ++++---- gfx/thebes/gfxWindowsPlatform.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index 4d5080f6c8b4..88c844b99659 100755 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -355,7 +355,7 @@ gfxWindowsPlatform::InitAcceleration() UpdateRenderMode(); // If we have Skia and we didn't init dwrite already, do it now. - if (!DWriteAvailable() && GetDefaultContentBackend() == BackendType::SKIA) { + if (!DWriteEnabled() && GetDefaultContentBackend() == BackendType::SKIA) { InitDWriteSupport(); } @@ -491,7 +491,7 @@ gfxWindowsPlatform::CreatePlatformFontList() // bug 630201 - older pre-RTM versions of Direct2D/DirectWrite cause odd // crashers so blacklist them altogether - if (IsNotWin7PreRTM() && DWriteAvailable()) { + if (IsNotWin7PreRTM() && DWriteEnabled()) { pfl = new gfxDWriteFontList(); if (NS_SUCCEEDED(pfl->InitFontList())) { return pfl; @@ -1103,7 +1103,7 @@ gfxWindowsPlatform::FontsPrefsChanged(const char *aPref) void gfxWindowsPlatform::SetupClearTypeParams() { - if (DWriteAvailable()) { + if (DWriteEnabled()) { // any missing prefs will default to invalid (-1) and be ignored; // out-of-range values will also be ignored FLOAT gamma = -1.0; @@ -1526,7 +1526,7 @@ gfxWindowsPlatform::InitializeD2D() } // Using Direct2D depends on DWrite support. - if (!DWriteAvailable() && !InitDWriteSupport()) { + if (!DWriteEnabled() && !InitDWriteSupport()) { d2d1.SetFailed(FeatureStatus::Failed, "Failed to initialize DirectWrite support", NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_DWRITE")); return; diff --git a/gfx/thebes/gfxWindowsPlatform.h b/gfx/thebes/gfxWindowsPlatform.h index 12f637842379..ded5c8330aa5 100644 --- a/gfx/thebes/gfxWindowsPlatform.h +++ b/gfx/thebes/gfxWindowsPlatform.h @@ -192,7 +192,7 @@ public: void SetupClearTypeParams(); - inline bool DWriteAvailable() const { return !!mozilla::gfx::Factory::GetDWriteFactory(); } + inline bool DWriteEnabled() const { return !!mozilla::gfx::Factory::GetDWriteFactory(); } inline DWRITE_MEASURING_MODE DWriteMeasuringMode() { return mMeasuringMode; } IDWriteRenderingParams *GetRenderingParams(TextRenderingMode aRenderMode) From a68d1bbb86bf73b3bcf46f7b85892dc023c09bf6 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:43 +1000 Subject: [PATCH 35/63] Bug 1352575 (part 1) - Remove unused supportsAsyncInit arguments and fields. r=jimm. The aAllowAsyncInit argument to PluginModuleParent's constructor is unused. This patch removes it and various other things that are no longer needed once it is gone. --HG-- extra : rebase_source : a97f5b83a0f8564fd287a5e920fb24e01b45967e --- dom/plugins/ipc/PluginModuleParent.cpp | 23 +++++++++-------------- dom/plugins/ipc/PluginModuleParent.h | 7 +++---- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index 70c7665bfdbc..1557ff0818fd 100644 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -216,9 +216,8 @@ namespace { class PluginModuleMapping : public PRCList { public: - explicit PluginModuleMapping(uint32_t aPluginId, bool aAllowAsyncInit) + explicit PluginModuleMapping(uint32_t aPluginId) : mPluginId(aPluginId) - , mAllowAsyncInit(aAllowAsyncInit) , mProcessIdValid(false) , mModule(nullptr) , mChannelOpened(false) @@ -250,7 +249,7 @@ public: GetModule() { if (!mModule) { - mModule = new PluginModuleContentParent(mAllowAsyncInit); + mModule = new PluginModuleContentParent(); } return mModule; } @@ -337,7 +336,6 @@ private: } uint32_t mPluginId; - bool mAllowAsyncInit; bool mProcessIdValid; base::ProcessId mProcessId; PluginModuleContentParent* mModule; @@ -418,8 +416,7 @@ PluginModuleContentParent::LoadModule(uint32_t aPluginId, nsPluginTag* aPluginTag) { PluginModuleMapping::NotifyLoadingModule loadingModule; - nsAutoPtr mapping( - new PluginModuleMapping(aPluginId, aPluginTag->mSupportsAsyncInit)); + nsAutoPtr mapping(new PluginModuleMapping(aPluginId)); MOZ_ASSERT(XRE_IsContentProcess()); @@ -534,8 +531,7 @@ PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId, nsAutoPtr parent( new PluginModuleChromeParent(aFilePath, aPluginId, - aPluginTag->mSandboxLevel, - aPluginTag->mSupportsAsyncInit)); + aPluginTag->mSandboxLevel)); UniquePtr onLaunchedRunnable(new LaunchedTask(parent)); parent->mSubprocess->SetCallRunnableImmediately(!parent->mIsStartingAsync); TimeStamp launchStart = TimeStamp::Now(); @@ -688,7 +684,7 @@ PluginModuleChromeParent::InitCrashReporter() return true; } -PluginModuleParent::PluginModuleParent(bool aIsChrome, bool aAllowAsyncInit) +PluginModuleParent::PluginModuleParent(bool aIsChrome) : mQuirks(QUIRKS_NOT_INITIALIZED) , mIsChrome(aIsChrome) , mShutdown(false) @@ -730,8 +726,8 @@ PluginModuleParent::~PluginModuleParent() } } -PluginModuleContentParent::PluginModuleContentParent(bool aAllowAsyncInit) - : PluginModuleParent(false, aAllowAsyncInit) +PluginModuleContentParent::PluginModuleContentParent() + : PluginModuleParent(false) { Preferences::RegisterCallback(TimeoutChanged, kContentTimeoutPref, this); } @@ -745,9 +741,8 @@ bool PluginModuleChromeParent::sInstantiated = false; PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, uint32_t aPluginId, - int32_t aSandboxLevel, - bool aAllowAsyncInit) - : PluginModuleParent(true, aAllowAsyncInit) + int32_t aSandboxLevel) + : PluginModuleParent(true) , mSubprocess(new PluginProcessParent(aFilePath)) , mPluginId(aPluginId) , mChromeTaskFactory(this) diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index 3ad0a7899431..8af10e0ed334 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -94,7 +94,7 @@ protected: DeallocPPluginInstanceParent(PPluginInstanceParent* aActor) override; public: - explicit PluginModuleParent(bool aIsChrome, bool aAllowAsyncInit); + explicit PluginModuleParent(bool aIsChrome); virtual ~PluginModuleParent(); bool RemovePendingSurrogate(const RefPtr& aSurrogate); @@ -382,7 +382,7 @@ protected: class PluginModuleContentParent : public PluginModuleParent { public: - explicit PluginModuleContentParent(bool aAllowAsyncInit); + explicit PluginModuleContentParent(); static PluginLibrary* LoadModule(uint32_t aPluginId, nsPluginTag* aPluginTag); @@ -600,8 +600,7 @@ private: // aFilePath is UTF8, not native! explicit PluginModuleChromeParent(const char* aFilePath, uint32_t aPluginId, - int32_t aSandboxLevel, - bool aAllowAsyncInit); + int32_t aSandboxLevel); void CleanupFromTimeout(const bool aByHangUI); From 04ae66367ede37bdf5fb0c0b128c0e366e7110cd Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:43 +1000 Subject: [PATCH 36/63] Bug 1352575 (part 2) - Remove nsPluginTag::mSupportsAsyncInit. r=jimm. It's not used in any useful way. --HG-- extra : rebase_source : 195ae6ac95860d229cf07cb0c86351dee32bf9a1 --- dom/plugins/base/nsPluginHost.cpp | 2 -- dom/plugins/base/nsPluginTags.cpp | 12 ------------ dom/plugins/base/nsPluginTags.h | 2 -- dom/plugins/ipc/PluginTypes.ipdlh | 1 - 4 files changed, 17 deletions(-) diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp index b3c949fe5740..8dcf7c41aacf 100644 --- a/dom/plugins/base/nsPluginHost.cpp +++ b/dom/plugins/base/nsPluginHost.cpp @@ -2383,7 +2383,6 @@ nsPluginHost::SetPluginsInContent(uint32_t aPluginEpoch, nsTArray(tag.extensions()), tag.isJavaPlugin(), tag.isFlashPlugin(), - tag.supportsAsyncInit(), tag.supportsAsyncRender(), tag.lastModifiedTime(), tag.isFromExtension(), @@ -2624,7 +2623,6 @@ nsPluginHost::SendPluginsToContent() tag->Extensions(), tag->mIsJavaPlugin, tag->mIsFlashPlugin, - tag->mSupportsAsyncInit, tag->mSupportsAsyncRender, tag->FileName(), tag->Version(), diff --git a/dom/plugins/base/nsPluginTags.cpp b/dom/plugins/base/nsPluginTags.cpp index 1ee6093dc2e1..9fb2ade8ff21 100644 --- a/dom/plugins/base/nsPluginTags.cpp +++ b/dom/plugins/base/nsPluginTags.cpp @@ -233,7 +233,6 @@ nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo, mLibrary(nullptr), mIsJavaPlugin(false), mIsFlashPlugin(false), - mSupportsAsyncInit(false), mSupportsAsyncRender(false), mFullPath(aPluginInfo->fFullPath), mLastModifiedTime(aLastModifiedTime), @@ -270,7 +269,6 @@ nsPluginTag::nsPluginTag(const char* aName, mLibrary(nullptr), mIsJavaPlugin(false), mIsFlashPlugin(false), - mSupportsAsyncInit(false), mSupportsAsyncRender(false), mFullPath(aFullPath), mLastModifiedTime(aLastModifiedTime), @@ -298,7 +296,6 @@ nsPluginTag::nsPluginTag(uint32_t aId, nsTArray aExtensions, bool aIsJavaPlugin, bool aIsFlashPlugin, - bool aSupportsAsyncInit, bool aSupportsAsyncRender, int64_t aLastModifiedTime, bool aFromExtension, @@ -310,7 +307,6 @@ nsPluginTag::nsPluginTag(uint32_t aId, mLibrary(nullptr), mIsJavaPlugin(aIsJavaPlugin), mIsFlashPlugin(aIsFlashPlugin), - mSupportsAsyncInit(aSupportsAsyncInit), mSupportsAsyncRender(aSupportsAsyncRender), mLastModifiedTime(aLastModifiedTime), mSandboxLevel(aSandboxLevel), @@ -356,25 +352,17 @@ void nsPluginTag::InitMime(const char* const* aMimeTypes, switch (nsPluginHost::GetSpecialType(mimeType)) { case nsPluginHost::eSpecialType_Java: mIsJavaPlugin = true; - mSupportsAsyncInit = true; break; case nsPluginHost::eSpecialType_Flash: // VLC sometimes claims to implement the Flash MIME type, and we want // to allow users to control that separately from Adobe Flash. if (Name().EqualsLiteral("Shockwave Flash")) { mIsFlashPlugin = true; - mSupportsAsyncInit = true; } break; case nsPluginHost::eSpecialType_Test: - mSupportsAsyncInit = true; - break; case nsPluginHost::eSpecialType_None: default: -#ifndef RELEASE_OR_BETA - // Allow async init for all plugins on Nightly and Aurora - mSupportsAsyncInit = true; -#endif break; } diff --git a/dom/plugins/base/nsPluginTags.h b/dom/plugins/base/nsPluginTags.h index 3152e6c40458..3ebb879ec965 100644 --- a/dom/plugins/base/nsPluginTags.h +++ b/dom/plugins/base/nsPluginTags.h @@ -132,7 +132,6 @@ public: nsTArray aExtensions, bool aIsJavaPlugin, bool aIsFlashPlugin, - bool aSupportsAsyncInit, bool aSupportsAsyncRender, int64_t aLastModifiedTime, bool aFromExtension, @@ -169,7 +168,6 @@ public: RefPtr mPlugin; bool mIsJavaPlugin; bool mIsFlashPlugin; - bool mSupportsAsyncInit; bool mSupportsAsyncRender; nsCString mFullPath; // UTF-8 int64_t mLastModifiedTime; diff --git a/dom/plugins/ipc/PluginTypes.ipdlh b/dom/plugins/ipc/PluginTypes.ipdlh index 1fee7bf9c7bf..a18057fc6be0 100644 --- a/dom/plugins/ipc/PluginTypes.ipdlh +++ b/dom/plugins/ipc/PluginTypes.ipdlh @@ -18,7 +18,6 @@ struct PluginTag nsCString[] extensions; bool isJavaPlugin; bool isFlashPlugin; - bool supportsAsyncInit; bool supportsAsyncRender; // flash specific nsCString filename; nsCString version; From 3dbe336b5495605aa5c133f899760c825f348c41 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:43 +1000 Subject: [PATCH 37/63] Bug 1352575 (part 3) - Remove PluginModuleChromeParent::mAsyncInitError. r=jimm. It's unused. --HG-- extra : rebase_source : a52c85e601f47b132e5e4fea1d682f7ee4210bfb --- dom/plugins/ipc/PluginModuleParent.cpp | 10 +++++----- dom/plugins/ipc/PluginModuleParent.h | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index 1557ff0818fd..00f7e951754f 100644 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -612,26 +612,27 @@ PluginModuleChromeParent::OnProcessLaunched(const bool aSucceeded) if (mInitOnAsyncConnect) { mInitOnAsyncConnect = false; + NPError dummyError; #if defined(XP_WIN) mAsyncInitRv = NP_GetEntryPoints(mNPPIface, - &mAsyncInitError); + &dummyError); if (NS_SUCCEEDED(mAsyncInitRv)) #endif { #if defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(MOZ_WIDGET_GONK) mAsyncInitRv = NP_Initialize(mNPNIface, mNPPIface, - &mAsyncInitError); + &dummyError); #else mAsyncInitRv = NP_Initialize(mNPNIface, - &mAsyncInitError); + &dummyError); #endif } #if defined(XP_MACOSX) if (NS_SUCCEEDED(mAsyncInitRv)) { mAsyncInitRv = NP_GetEntryPoints(mNPPIface, - &mAsyncInitError); + &dummyError); } #endif } @@ -760,7 +761,6 @@ PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, #endif , mInitOnAsyncConnect(false) , mAsyncInitRv(NS_ERROR_NOT_INITIALIZED) - , mAsyncInitError(NPERR_NO_ERROR) , mContentParent(nullptr) { NS_ASSERTION(mSubprocess, "Out of memory!"); diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index 8af10e0ed334..2f9fc16bab06 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -697,7 +697,6 @@ private: bool mInitOnAsyncConnect; nsresult mAsyncInitRv; - NPError mAsyncInitError; // mContentParent is to be used ONLY during the IPC dance that occurs // when ContentParent::RecvLoadPlugin is called under async plugin init! // In other contexts it is *unsafe*, as there might be multiple content From 86c372f58975604769e4d980ad4f74d667aee801 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:43 +1000 Subject: [PATCH 38/63] Bug 1352575 (part 4) - Remove dom.ipc.plugins.asyncInit.enabled pref. r=jimm. The feature is in the process of being removed. --HG-- extra : rebase_source : 7540804ef15db7001dafc854fc35f7c1834d8815 --- dom/plugins/ipc/PluginModuleParent.cpp | 1 - modules/libpref/init/all.js | 3 --- toolkit/components/telemetry/TelemetryEnvironment.jsm | 1 - toolkit/components/telemetry/TelemetrySession.jsm | 2 -- 4 files changed, 7 deletions(-) diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index 00f7e951754f..23c862369ce8 100644 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -77,7 +77,6 @@ static const char kContentTimeoutPref[] = "dom.ipc.plugins.contentTimeoutSecs"; static const char kChildTimeoutPref[] = "dom.ipc.plugins.timeoutSecs"; static const char kParentTimeoutPref[] = "dom.ipc.plugins.parentTimeoutSecs"; static const char kLaunchTimeoutPref[] = "dom.ipc.plugins.processLaunchTimeoutSecs"; -static const char kAsyncInitPref[] = "dom.ipc.plugins.asyncInit.enabled"; #ifdef XP_WIN static const char kHangUITimeoutPref[] = "dom.ipc.plugins.hangUITimeoutSecs"; static const char kHangUIMinDisplayPref[] = "dom.ipc.plugins.hangUIMinDisplaySecs"; diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index d493c98d7577..a80493f7fc6e 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -3162,9 +3162,6 @@ pref("dom.ipc.plugins.reportCrashURL", true); // Defaults to 30 seconds. pref("dom.ipc.plugins.unloadTimeoutSecs", 30); -// Asynchronous plugin initialization is on hold. -pref("dom.ipc.plugins.asyncInit.enabled", false); - // Allow Flash async drawing mode in 64-bit release builds pref("dom.ipc.plugins.asyncdrawing.enabled", true); // Force the accelerated direct path for a subset of Flash wmode values diff --git a/toolkit/components/telemetry/TelemetryEnvironment.jsm b/toolkit/components/telemetry/TelemetryEnvironment.jsm index 9d1254590e37..13bdeb57f930 100644 --- a/toolkit/components/telemetry/TelemetryEnvironment.jsm +++ b/toolkit/components/telemetry/TelemetryEnvironment.jsm @@ -187,7 +187,6 @@ const DEFAULT_ENVIRONMENT_PREFS = new Map([ ["devtools.chrome.enabled", {what: RECORD_PREF_VALUE}], ["devtools.debugger.enabled", {what: RECORD_PREF_VALUE}], ["devtools.debugger.remote-enabled", {what: RECORD_PREF_VALUE}], - ["dom.ipc.plugins.asyncInit.enabled", {what: RECORD_PREF_VALUE}], ["dom.ipc.plugins.enabled", {what: RECORD_PREF_VALUE}], ["dom.ipc.processCount", {what: RECORD_PREF_VALUE}], ["dom.max_script_run_time", {what: RECORD_PREF_VALUE}], diff --git a/toolkit/components/telemetry/TelemetrySession.jsm b/toolkit/components/telemetry/TelemetrySession.jsm index 3fbef47fa3d9..688d5b7e4bd5 100644 --- a/toolkit/components/telemetry/TelemetrySession.jsm +++ b/toolkit/components/telemetry/TelemetrySession.jsm @@ -58,7 +58,6 @@ const LOGGER_PREFIX = "TelemetrySession" + (Utils.isContentProcess ? "#content:: const PREF_BRANCH = "toolkit.telemetry."; const PREF_PREVIOUS_BUILDID = PREF_BRANCH + "previousBuildID"; const PREF_FHR_UPLOAD_ENABLED = "datareporting.healthreport.uploadEnabled"; -const PREF_ASYNC_PLUGIN_INIT = "dom.ipc.plugins.asyncInit.enabled"; const PREF_UNIFIED = PREF_BRANCH + "unified"; const PREF_SHUTDOWN_PINGSENDER = PREF_BRANCH + "shutdownPingSender.enabled"; @@ -1074,7 +1073,6 @@ var Impl = { let ret = { reason, revision: AppConstants.SOURCE_REVISION_URL, - asyncPluginInit: Preferences.get(PREF_ASYNC_PLUGIN_INIT, false), // Date.getTimezoneOffset() unintuitively returns negative values if we are ahead of // UTC and vice versa (e.g. -60 for UTC+1). We invert the sign here. From c67ffb04c63bd88465f4a6eed448a56ee5755d1d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:43 +1000 Subject: [PATCH 39/63] Bug 1352575 (part 5) - Remove PluginModuleParent::mIsStartingAsync. r=jimm. This allows a bunch of other things to be removed too, including PluginModuleParent::mSurrogateInstances, PluginModuleChromeParent::sInstantiated, and NS_PLUGIN_INIT_PENDING. The patch also removes the AsyncPluginInit crash annotation. --HG-- extra : rebase_source : cadb1d215fd93051c9032ea0a1fb6f1d2fb80c6d --- dom/ipc/ContentParent.cpp | 5 +- dom/plugins/base/nsPluginHost.cpp | 4 +- dom/plugins/ipc/PluginAsyncSurrogate.cpp | 2 +- dom/plugins/ipc/PluginBridge.h | 2 +- dom/plugins/ipc/PluginInstanceParent.cpp | 22 +-- dom/plugins/ipc/PluginModuleParent.cpp | 237 ++--------------------- dom/plugins/ipc/PluginModuleParent.h | 19 -- dom/plugins/ipc/PluginProcessParent.cpp | 4 +- dom/plugins/ipc/PluginProcessParent.h | 2 +- xpcom/base/ErrorList.py | 1 - 10 files changed, 33 insertions(+), 265 deletions(-) diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 1d496d83d522..b4aac67d5828 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -1104,8 +1104,7 @@ ContentParent::RecvLoadPlugin(const uint32_t& aPluginId, Endpoint* aEndpoint) { *aRv = NS_OK; - if (!mozilla::plugins::SetupBridge(aPluginId, this, false, aRv, aRunID, - aEndpoint)) { + if (!mozilla::plugins::SetupBridge(aPluginId, this, aRv, aRunID, aEndpoint)) { return IPC_FAIL_NO_REASON(this); } return IPC_OK(); @@ -1141,7 +1140,7 @@ ContentParent::RecvConnectPluginBridge(const uint32_t& aPluginId, // in the first call to SetupBridge in RecvLoadPlugin, so we pass in a dummy // pointer and just throw it away. uint32_t dummy = 0; - if (!mozilla::plugins::SetupBridge(aPluginId, this, true, aRv, &dummy, aEndpoint)) { + if (!mozilla::plugins::SetupBridge(aPluginId, this, aRv, &dummy, aEndpoint)) { return IPC_FAIL(this, "SetupBridge failed"); } return IPC_OK(); diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp index 8dcf7c41aacf..165ccf77edd7 100644 --- a/dom/plugins/base/nsPluginHost.cpp +++ b/dom/plugins/base/nsPluginHost.cpp @@ -758,7 +758,6 @@ nsPluginHost::InstantiatePluginInstance(const nsACString& aMimeType, nsIURI* aUR instanceOwner->Destroy(); return NS_ERROR_FAILURE; } - const bool isAsyncInit = (rv == NS_PLUGIN_INIT_PENDING); RefPtr instance; rv = instanceOwner->GetInstance(getter_AddRefs(instance)); @@ -767,8 +766,7 @@ nsPluginHost::InstantiatePluginInstance(const nsACString& aMimeType, nsIURI* aUR return rv; } - // Async init plugins will initiate their own widget creation. - if (!isAsyncInit && instance) { + if (instance) { CreateWidget(instanceOwner); } diff --git a/dom/plugins/ipc/PluginAsyncSurrogate.cpp b/dom/plugins/ipc/PluginAsyncSurrogate.cpp index 6b31a837668d..a527a6d6cf12 100644 --- a/dom/plugins/ipc/PluginAsyncSurrogate.cpp +++ b/dom/plugins/ipc/PluginAsyncSurrogate.cpp @@ -509,7 +509,7 @@ PluginAsyncSurrogate::WaitForInit() if (mParent->IsChrome()) { PluginProcessParent* process = static_cast(mParent)->Process(); MOZ_ASSERT(process); - process->SetCallRunnableImmediately(true); + process->SetCallRunnableImmediately(); if (!process->WaitUntilConnected()) { return false; } diff --git a/dom/plugins/ipc/PluginBridge.h b/dom/plugins/ipc/PluginBridge.h index 232f7dc2cf61..4b3cb54105c2 100644 --- a/dom/plugins/ipc/PluginBridge.h +++ b/dom/plugins/ipc/PluginBridge.h @@ -28,7 +28,7 @@ class PPluginModuleParent; bool SetupBridge(uint32_t aPluginId, dom::ContentParent* aContentParent, - bool aForceBridgeNow, nsresult* aResult, uint32_t* aRunID, + nsresult* aResult, uint32_t* aRunID, ipc::Endpoint* aEndpoint); nsresult diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp index 461c6ef5e0f4..2d8aadcadd6d 100644 --- a/dom/plugins/ipc/PluginInstanceParent.cpp +++ b/dom/plugins/ipc/PluginInstanceParent.cpp @@ -1775,22 +1775,12 @@ PluginInstanceParent::NPP_NewStream(NPMIMEType type, NPStream* stream, timer(Module()->GetHistogramKey()); NPError err = NPERR_NO_ERROR; - if (mParent->IsStartingAsync()) { - MOZ_ASSERT(mSurrogate); - mSurrogate->AsyncCallDeparting(); - if (SendAsyncNPP_NewStream(bs, NullableString(type), seekable)) { - *stype = nsPluginStreamListenerPeer::STREAM_TYPE_UNKNOWN; - } else { - err = NPERR_GENERIC_ERROR; - } - } else { - bs->SetAlive(); - if (!CallNPP_NewStream(bs, NullableString(type), seekable, &err, stype)) { - err = NPERR_GENERIC_ERROR; - } - if (NPERR_NO_ERROR != err) { - Unused << PBrowserStreamParent::Send__delete__(bs); - } + bs->SetAlive(); + if (!CallNPP_NewStream(bs, NullableString(type), seekable, &err, stype)) { + err = NPERR_GENERIC_ERROR; + } + if (NPERR_NO_ERROR != err) { + Unused << PBrowserStreamParent::Send__delete__(bs); } return err; diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index 23c862369ce8..9414e97fd70a 100644 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -88,7 +88,6 @@ static const char kHangUIMinDisplayPref[] = "dom.ipc.plugins.hangUIMinDisplaySec bool mozilla::plugins::SetupBridge(uint32_t aPluginId, dom::ContentParent* aContentParent, - bool aForceBridgeNow, nsresult* rv, uint32_t* runID, ipc::Endpoint* aEndpoint) @@ -98,7 +97,6 @@ mozilla::plugins::SetupBridge(uint32_t aPluginId, return false; } - PluginModuleChromeParent::ClearInstantiationFlag(); RefPtr host = nsPluginHost::GetInst(); RefPtr plugin; *rv = host->GetPluginForContentProcess(aPluginId, getter_AddRefs(plugin)); @@ -115,14 +113,6 @@ mozilla::plugins::SetupBridge(uint32_t aPluginId, if (NS_FAILED(*rv)) { return true; } - if (chromeParent->IsStartingAsync()) { - chromeParent->SetContentParent(aContentParent); - } - if (!aForceBridgeNow && chromeParent->IsStartingAsync() && - PluginModuleChromeParent::DidInstantiate()) { - // We'll handle the bridging asynchronously - return true; - } ipc::Endpoint parent; ipc::Endpoint child; @@ -506,14 +496,6 @@ PluginModuleContentParent::OnLoadPluginResult(const uint32_t& aPluginId, : NPERR_GENERIC_ERROR); } -void -PluginModuleChromeParent::SetContentParent(dom::ContentParent* aContentParent) -{ - // mContentParent is to be used ONLY during async plugin init! - MOZ_ASSERT(aContentParent && mIsStartingAsync); - mContentParent = aContentParent; -} - bool PluginModuleChromeParent::SendAssociatePluginId() { @@ -532,7 +514,7 @@ PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId, new PluginModuleChromeParent(aFilePath, aPluginId, aPluginTag->mSandboxLevel)); UniquePtr onLaunchedRunnable(new LaunchedTask(parent)); - parent->mSubprocess->SetCallRunnableImmediately(!parent->mIsStartingAsync); + parent->mSubprocess->SetCallRunnableImmediately(); TimeStamp launchStart = TimeStamp::Now(); bool launched = parent->mSubprocess->Launch(Move(onLaunchedRunnable), aPluginTag->mSandboxLevel); @@ -545,12 +527,10 @@ PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId, uint32_t blocklistState; nsresult rv = aPluginTag->GetBlocklistState(&blocklistState); parent->mIsBlocklisted = NS_FAILED(rv) || blocklistState != 0; - if (!parent->mIsStartingAsync) { - int32_t launchTimeoutSecs = Preferences::GetInt(kLaunchTimeoutPref, 0); - if (!parent->mSubprocess->WaitUntilConnected(launchTimeoutSecs * 1000)) { - parent->mShutdown = true; - return nullptr; - } + int32_t launchTimeoutSecs = Preferences::GetInt(kLaunchTimeoutPref, 0); + if (!parent->mSubprocess->WaitUntilConnected(launchTimeoutSecs * 1000)) { + parent->mShutdown = true; + return nullptr; } TimeStamp launchEnd = TimeStamp::Now(); parent->mTimeBlocked = (launchEnd - launchStart); @@ -646,7 +626,7 @@ PluginModuleChromeParent::WaitForIPCConnection() { PluginProcessParent* process = Process(); MOZ_ASSERT(process); - process->SetCallRunnableImmediately(true); + process->SetCallRunnableImmediately(); if (!process->WaitUntilConnected()) { return false; } @@ -673,11 +653,6 @@ PluginModuleChromeParent::InitCrashReporter() GeckoProcessType_Plugin, shmem, threadId); - - mCrashReporter->AddNote(NS_LITERAL_CSTRING("AsyncPluginInit"), - mIsStartingAsync ? - NS_LITERAL_CSTRING("1") : - NS_LITERAL_CSTRING("0")); } #endif @@ -697,7 +672,6 @@ PluginModuleParent::PluginModuleParent(bool aIsChrome) , mTaskFactory(this) , mSandboxLevel(0) , mIsFlashPlugin(false) - , mIsStartingAsync(false) , mNPInitialized(false) , mIsNPShutdownPending(false) , mAsyncNewRv(NS_ERROR_NOT_INITIALIZED) @@ -705,12 +679,6 @@ PluginModuleParent::PluginModuleParent(bool aIsChrome) , mCrashReporterMutex("PluginModuleChromeParent::mCrashReporterMutex") #endif { -#if defined(MOZ_CRASHREPORTER) - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AsyncPluginInit"), - mIsStartingAsync ? - NS_LITERAL_CSTRING("1") : - NS_LITERAL_CSTRING("0")); -#endif } PluginModuleParent::~PluginModuleParent() @@ -737,8 +705,6 @@ PluginModuleContentParent::~PluginModuleContentParent() Preferences::UnregisterCallback(TimeoutChanged, kContentTimeoutPref, this); } -bool PluginModuleChromeParent::sInstantiated = false; - PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, uint32_t aPluginId, int32_t aSandboxLevel) @@ -763,7 +729,6 @@ PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, , mContentParent(nullptr) { NS_ASSERTION(mSubprocess, "Out of memory!"); - sInstantiated = true; mSandboxLevel = aSandboxLevel; mRunID = GeckoChildProcessHost::GetUniqueID(); @@ -2176,16 +2141,6 @@ PluginModuleParent::OnInitFailure() } mShutdown = true; - - if (mIsStartingAsync) { - /* If we've failed then we need to enumerate any pending NPP_New calls - and clean them up. */ - uint32_t len = mSurrogateInstances.Length(); - for (uint32_t i = 0; i < len; ++i) { - mSurrogateInstances[i]->NotifyAsyncInitFailed(); - } - mSurrogateInstances.Clear(); - } } class PluginOfflineObserver final : public nsIObserver @@ -2304,16 +2259,7 @@ PluginModuleParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs } *error = NPERR_NO_ERROR; - if (mIsStartingAsync) { - if (GetIPCChannel()->CanSend()) { - // We're already connected, so we may call this immediately. - RecvNP_InitializeResult(*error); - } else { - PluginAsyncSurrogate::NP_GetEntryPoints(pFuncs); - } - } else { - SetPluginFuncs(pFuncs); - } + SetPluginFuncs(pFuncs); return NS_OK; } @@ -2333,12 +2279,6 @@ PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* mNPNIface = bFuncs; mNPPIface = pFuncs; - // NB: This *MUST* be set prior to checking whether the subprocess has - // been connected! - if (mIsStartingAsync) { - PluginAsyncSurrogate::NP_GetEntryPoints(pFuncs); - } - if (!mSubprocess->IsConnected()) { // The subprocess isn't connected yet. Defer NP_Initialize until // OnProcessLaunched is invoked. @@ -2350,18 +2290,6 @@ PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* GetSettings(&settings); TimeStamp callNpInitStart = TimeStamp::Now(); - // Asynchronous case - if (mIsStartingAsync) { - if (!SendAsyncNP_Initialize(settings)) { - Close(); - return NS_ERROR_FAILURE; - } - TimeStamp callNpInitEnd = TimeStamp::Now(); - mTimeBlocked += (callNpInitEnd - callNpInitStart); - return NS_OK; - } - - // Synchronous case if (!CallNP_Initialize(settings, error)) { Close(); return NS_ERROR_FAILURE; @@ -2387,9 +2315,6 @@ PluginModuleParent::RecvNP_InitializeResult(const NPError& aError) } SetPluginFuncs(mNPPIface); - if (mIsStartingAsync) { - InitAsyncSurrogates(); - } mNPInitialized = true; return IPC_OK(); @@ -2404,9 +2329,6 @@ PluginModuleChromeParent::RecvNP_InitializeResult(const NPError& aError) bool initOk = aError == NPERR_NO_ERROR; if (initOk) { SetPluginFuncs(mNPPIface); - if (mIsStartingAsync && !SendAssociatePluginId()) { - initOk = false; - } } mNPInitialized = initOk; bool result = mContentParent->SendLoadPluginResult(mPluginId, initOk); @@ -2441,12 +2363,7 @@ nsresult PluginModuleContentParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) { PLUGIN_LOG_DEBUG_METHOD; - nsresult rv = PluginModuleParent::NP_Initialize(bFuncs, error); - if (mIsStartingAsync && GetIPCChannel()->CanSend()) { - // We're already connected, so we may call this immediately. - RecvNP_InitializeResult(*error); - } - return rv; + return PluginModuleParent::NP_Initialize(bFuncs, error); } #endif @@ -2477,15 +2394,6 @@ PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) GetSettings(&settings); TimeStamp callNpInitStart = TimeStamp::Now(); - if (mIsStartingAsync) { - if (!SendAsyncNP_Initialize(settings)) { - return NS_ERROR_FAILURE; - } - TimeStamp callNpInitEnd = TimeStamp::Now(); - mTimeBlocked += (callNpInitEnd - callNpInitStart); - return NS_OK; - } - if (!CallNP_Initialize(settings, error)) { Close(); return NS_ERROR_FAILURE; @@ -2504,11 +2412,6 @@ PluginModuleParent::RecvNP_InitializeResult(const NPError& aError) return IPC_OK(); } - if (mIsStartingAsync && mNPPIface) { - SetPluginFuncs(mNPPIface); - InitAsyncSurrogates(); - } - mNPInitialized = true; return IPC_OK(); } @@ -2526,10 +2429,6 @@ PluginModuleChromeParent::RecvNP_InitializeResult(const NPError& aError) } else if (aError == NPERR_NO_ERROR) { // Initialization steps for (e10s && !asyncInit) || !e10s #if defined XP_WIN - if (mIsStartingAsync) { - SetPluginFuncs(mNPPIface); - } - // Send the info needed to join the browser process's audio session to the // plugin process. nsID id; @@ -2555,48 +2454,12 @@ PluginModuleChromeParent::RecvNP_InitializeResult(const NPError& aError) #endif -void -PluginModuleParent::InitAsyncSurrogates() -{ - if (MaybeRunDeferredShutdown()) { - // We've shut down, so the surrogates are no longer valid. Clear - // mSurrogateInstances to ensure that these aren't used. - mSurrogateInstances.Clear(); - return; - } - - uint32_t len = mSurrogateInstances.Length(); - for (uint32_t i = 0; i < len; ++i) { - NPError err; - mAsyncNewRv = mSurrogateInstances[i]->NPP_New(&err); - if (NS_FAILED(mAsyncNewRv)) { - mSurrogateInstances[i]->NotifyAsyncInitFailed(); - continue; - } - } - mSurrogateInstances.Clear(); -} - bool PluginModuleParent::RemovePendingSurrogate( const RefPtr& aSurrogate) { - return mSurrogateInstances.RemoveElement(aSurrogate); -} - -bool -PluginModuleParent::MaybeRunDeferredShutdown() -{ - if (!mIsStartingAsync || !mIsNPShutdownPending) { - return false; - } - MOZ_ASSERT(!mShutdown); - NPError error; - if (!DoShutdown(&error)) { - return false; - } - mIsNPShutdownPending = false; - return true; + // XXX: this function will be removed soon. + MOZ_CRASH(); } nsresult @@ -2609,14 +2472,6 @@ PluginModuleParent::NP_Shutdown(NPError* error) return NS_ERROR_FAILURE; } - /* If we're still running an async NP_Initialize then we need to defer - shutdown until we've received the result of the NP_Initialize call. */ - if (mIsStartingAsync && !mNPInitialized) { - mIsNPShutdownPending = true; - *error = NPERR_NO_ERROR; - return NS_OK; - } - if (!DoShutdown(error)) { return NS_ERROR_FAILURE; } @@ -2681,21 +2536,7 @@ PluginModuleParent::NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error) NS_ASSERTION(pFuncs, "Null pointer!"); *error = NPERR_NO_ERROR; - if (mIsStartingAsync && !IsChrome()) { - mNPPIface = pFuncs; -#if defined(XP_MACOSX) - if (mNPInitialized) { - SetPluginFuncs(pFuncs); - InitAsyncSurrogates(); - } else { - PluginAsyncSurrogate::NP_GetEntryPoints(pFuncs); - } -#else - PluginAsyncSurrogate::NP_GetEntryPoints(pFuncs); -#endif - } else { - SetPluginFuncs(pFuncs); - } + SetPluginFuncs(pFuncs); return NS_OK; } @@ -2711,9 +2552,6 @@ PluginModuleChromeParent::NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* erro return NS_OK; } #else - if (mIsStartingAsync) { - PluginAsyncSurrogate::NP_GetEntryPoints(pFuncs); - } if (!mSubprocess->IsConnected()) { mNPPIface = pFuncs; mInitOnAsyncConnect = true; @@ -2752,22 +2590,6 @@ PluginModuleParent::NPP_New(NPMIMEType pluginType, NPP instance, return NS_ERROR_FAILURE; } - if (mIsStartingAsync) { - if (!PluginAsyncSurrogate::Create(this, pluginType, instance, - argc, argn, argv)) { - *error = NPERR_GENERIC_ERROR; - return NS_ERROR_FAILURE; - } - - if (!mNPInitialized) { - RefPtr surrogate = - PluginAsyncSurrogate::Cast(instance); - mSurrogateInstances.AppendElement(surrogate); - *error = NPERR_NO_ERROR; - return NS_PLUGIN_INIT_PENDING; - } - } - // create the instance on the other side InfallibleTArray names; InfallibleTArray values; @@ -2777,12 +2599,7 @@ PluginModuleParent::NPP_New(NPMIMEType pluginType, NPP instance, values.AppendElement(NullableString(argv[i])); } - nsresult rv = NPP_NewInternal(pluginType, instance, names, values, - saved, error); - if (NS_FAILED(rv) || !mIsStartingAsync) { - return rv; - } - return NS_PLUGIN_INIT_PENDING; + return NPP_NewInternal(pluginType, instance, names, values, saved, error); } class nsCaseInsensitiveUTF8StringArrayComparator @@ -2916,10 +2733,6 @@ PluginModuleParent::NPP_NewInternal(NPMIMEType pluginType, NPP instance, #endif } - // Release the surrogate reference that was in pdata - RefPtr surrogate( - dont_AddRef(PluginAsyncSurrogate::Cast(instance))); - // Now replace it with the instance instance->pdata = static_cast(parentInstance); // Any IPC messages for the PluginInstance actor should be dispatched to the @@ -2947,31 +2760,19 @@ PluginModuleParent::NPP_NewInternal(NPMIMEType pluginType, NPP instance, { // Scope for timer Telemetry::AutoTimer timer(GetHistogramKey()); - if (mIsStartingAsync) { - MOZ_ASSERT(surrogate); - surrogate->AsyncCallDeparting(); - if (!SendAsyncNPP_New(parentInstance)) { + if (!CallSyncNPP_New(parentInstance, error)) { + // if IPC is down, we'll get an immediate "failed" return, but + // without *error being set. So make sure that the error + // condition is signaled to nsNPAPIPluginInstance + if (NPERR_NO_ERROR == *error) { *error = NPERR_GENERIC_ERROR; - return NS_ERROR_FAILURE; - } - *error = NPERR_NO_ERROR; - } else { - if (!CallSyncNPP_New(parentInstance, error)) { - // if IPC is down, we'll get an immediate "failed" return, but - // without *error being set. So make sure that the error - // condition is signaled to nsNPAPIPluginInstance - if (NPERR_NO_ERROR == *error) { - *error = NPERR_GENERIC_ERROR; - } - return NS_ERROR_FAILURE; } + return NS_ERROR_FAILURE; } } if (*error != NPERR_NO_ERROR) { - if (!mIsStartingAsync) { - NPP_Destroy(instance, 0); - } + NPP_Destroy(instance, 0); return NS_ERROR_FAILURE; } diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index 2f9fc16bab06..b966f991e538 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -99,8 +99,6 @@ public: bool RemovePendingSurrogate(const RefPtr& aSurrogate); - /** @return the state of the pref that controls async plugin init */ - bool IsStartingAsync() const { return mIsStartingAsync; } /** @return whether this modules NP_Initialize has successfully completed executing */ bool IsInitialized() const { return mNPInitialized; } @@ -315,8 +313,6 @@ public: virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor) override; #endif - void InitAsyncSurrogates(); - layers::TextureClientRecycleAllocator* EnsureTextureAllocatorForDirectBitmap(); layers::TextureClientRecycleAllocator* EnsureTextureAllocatorForDXGISurface(); @@ -324,7 +320,6 @@ protected: void NotifyFlashHang(); void NotifyPluginCrashed(); void OnInitFailure(); - bool MaybeRunDeferredShutdown(); bool DoShutdown(NPError* error); bool GetSetting(NPNVariable aVariable); @@ -357,10 +352,8 @@ protected: friend class mozilla::plugins::PluginAsyncSurrogate; - bool mIsStartingAsync; bool mNPInitialized; bool mIsNPShutdownPending; - nsTArray> mSurrogateInstances; nsresult mAsyncNewRv; uint32_t mRunID; @@ -432,14 +425,6 @@ class PluginModuleChromeParent static PluginLibrary* LoadModule(const char* aFilePath, uint32_t aPluginId, nsPluginTag* aPluginTag); - /** - * The following two functions are called by SetupBridge to determine - * whether an existing plugin module was reused, or whether a new module - * was instantiated by the plugin host. - */ - static void ClearInstantiationFlag() { sInstantiated = false; } - static bool DidInstantiate() { return sInstantiated; } - virtual ~PluginModuleChromeParent(); /* @@ -540,9 +525,6 @@ class PluginModuleChromeParent virtual mozilla::ipc::IPCResult RecvNP_InitializeResult(const NPError& aError) override; - void - SetContentParent(dom::ContentParent* aContentParent); - bool SendAssociatePluginId(); @@ -704,7 +686,6 @@ private: dom::ContentParent* mContentParent; nsCOMPtr mPluginOfflineObserver; bool mIsBlocklisted; - static bool sInstantiated; #if defined(XP_WIN) && defined(MOZ_SANDBOX) mozilla::SandboxPermissions mSandboxPermissions; #endif diff --git a/dom/plugins/ipc/PluginProcessParent.cpp b/dom/plugins/ipc/PluginProcessParent.cpp index 4a24abc802f5..8460e3424fdd 100644 --- a/dom/plugins/ipc/PluginProcessParent.cpp +++ b/dom/plugins/ipc/PluginProcessParent.cpp @@ -131,9 +131,9 @@ PluginProcessParent::Delete() } void -PluginProcessParent::SetCallRunnableImmediately(bool aCallImmediately) +PluginProcessParent::SetCallRunnableImmediately() { - mRunCompleteTaskImmediately = aCallImmediately; + mRunCompleteTaskImmediately = true; } /** diff --git a/dom/plugins/ipc/PluginProcessParent.h b/dom/plugins/ipc/PluginProcessParent.h index 89f1675627b4..4f5d73b5ad36 100644 --- a/dom/plugins/ipc/PluginProcessParent.h +++ b/dom/plugins/ipc/PluginProcessParent.h @@ -68,7 +68,7 @@ public: using mozilla::ipc::GeckoChildProcessHost::GetChannel; - void SetCallRunnableImmediately(bool aCallImmediately); + void SetCallRunnableImmediately(); virtual bool WaitUntilConnected(int32_t aTimeoutMs = 0) override; virtual void OnChannelConnected(int32_t peer_pid) override; diff --git a/xpcom/base/ErrorList.py b/xpcom/base/ErrorList.py index 4764769a6f2f..669a244ec0f6 100644 --- a/xpcom/base/ErrorList.py +++ b/xpcom/base/ErrorList.py @@ -465,7 +465,6 @@ with modules["PLUGINS"]: errors["NS_ERROR_PLUGIN_BLOCKLISTED"] = FAILURE(1002) errors["NS_ERROR_PLUGIN_TIME_RANGE_NOT_SUPPORTED"] = FAILURE(1003) errors["NS_ERROR_PLUGIN_CLICKTOPLAY"] = FAILURE(1004) - errors["NS_PLUGIN_INIT_PENDING"] = SUCCESS(1005) From b3ddc9836ac5c247da0c79b6e286bc733c2c27ae Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:43 +1000 Subject: [PATCH 40/63] Bug 1352575 (part 6) - Remove AsyncNPP_New. r=jimm. And related code. --HG-- extra : rebase_source : 55e76551a0555dda6acf6b07ba792afc48a1c0aa --- dom/plugins/ipc/PPluginModule.ipdl | 3 -- dom/plugins/ipc/PluginModuleChild.cpp | 45 --------------------------- dom/plugins/ipc/PluginModuleChild.h | 1 - 3 files changed, 49 deletions(-) diff --git a/dom/plugins/ipc/PPluginModule.ipdl b/dom/plugins/ipc/PPluginModule.ipdl index 38554668c513..b39d40b46693 100644 --- a/dom/plugins/ipc/PPluginModule.ipdl +++ b/dom/plugins/ipc/PPluginModule.ipdl @@ -73,9 +73,6 @@ child: intr SyncNPP_New(PPluginInstance aActor) returns (NPError rv); - // Implements the async plugin init version of NPP_New. - async AsyncNPP_New(PPluginInstance aActor); - intr NP_Shutdown() returns (NPError rv); diff --git a/dom/plugins/ipc/PluginModuleChild.cpp b/dom/plugins/ipc/PluginModuleChild.cpp index 147c57a85eb7..83cdeee26242 100644 --- a/dom/plugins/ipc/PluginModuleChild.cpp +++ b/dom/plugins/ipc/PluginModuleChild.cpp @@ -2386,51 +2386,6 @@ PluginModuleChild::AnswerSyncNPP_New(PPluginInstanceChild* aActor, NPError* rv) return IPC_OK(); } -class AsyncNewResultSender : public ChildAsyncCall -{ -public: - AsyncNewResultSender(PluginInstanceChild* aInstance, NPError aResult) - : ChildAsyncCall(aInstance, nullptr, nullptr) - , mResult(aResult) - { - } - - NS_IMETHOD Run() override - { - RemoveFromAsyncList(); - DebugOnly sendOk = mInstance->SendAsyncNPP_NewResult(mResult); - MOZ_ASSERT(sendOk); - return NS_OK; - } - -private: - NPError mResult; -}; - -static void -RunAsyncNPP_New(void* aChildInstance) -{ - MOZ_ASSERT(aChildInstance); - PluginInstanceChild* childInstance = - static_cast(aChildInstance); - NPError rv = childInstance->DoNPP_New(); - RefPtr task = - new AsyncNewResultSender(childInstance, rv); - childInstance->PostChildAsyncCall(task.forget()); -} - -mozilla::ipc::IPCResult -PluginModuleChild::RecvAsyncNPP_New(PPluginInstanceChild* aActor) -{ - PLUGIN_LOG_DEBUG_METHOD; - PluginInstanceChild* childInstance = - reinterpret_cast(aActor); - AssertPluginThread(); - // We don't want to run NPP_New async from within nested calls - childInstance->AsyncCall(&RunAsyncNPP_New, childInstance); - return IPC_OK(); -} - bool PluginModuleChild::DeallocPPluginInstanceChild(PPluginInstanceChild* aActor) { diff --git a/dom/plugins/ipc/PluginModuleChild.h b/dom/plugins/ipc/PluginModuleChild.h index 857b5bf14eba..8959795e28e6 100644 --- a/dom/plugins/ipc/PluginModuleChild.h +++ b/dom/plugins/ipc/PluginModuleChild.h @@ -75,7 +75,6 @@ protected: virtual mozilla::ipc::IPCResult RecvAsyncNP_Initialize(const PluginSettings& aSettings) override; virtual mozilla::ipc::IPCResult AnswerSyncNPP_New(PPluginInstanceChild* aActor, NPError* rv) override; - virtual mozilla::ipc::IPCResult RecvAsyncNPP_New(PPluginInstanceChild* aActor) override; virtual mozilla::ipc::IPCResult RecvInitPluginModuleChild(Endpoint&& endpoint) override; From 19f1b19c1d92c7ad3dc26f11cef1a92e1427c834 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:43 +1000 Subject: [PATCH 41/63] Bug 1352575 (part 7) - Remove AsyncNPP_NewStream. r=jimm. --HG-- extra : rebase_source : 6b1010d7e6dd0bc75576ac21fbbc6f59848b2dcc --- dom/plugins/ipc/PPluginInstance.ipdl | 3 -- dom/plugins/ipc/PluginInstanceChild.cpp | 46 ------------------------- dom/plugins/ipc/PluginInstanceChild.h | 6 ---- 3 files changed, 55 deletions(-) diff --git a/dom/plugins/ipc/PPluginInstance.ipdl b/dom/plugins/ipc/PPluginInstance.ipdl index 18c2240ae34f..1408446bb9f9 100644 --- a/dom/plugins/ipc/PPluginInstance.ipdl +++ b/dom/plugins/ipc/PPluginInstance.ipdl @@ -293,9 +293,6 @@ child: returns (NPError rv, uint16_t stype); - // Implements the async plugin init version of NPP_NewStream. - async AsyncNPP_NewStream(PBrowserStream actor, nsCString mimeType, bool seekable); - parent: /* NPN_NewStream */ intr PPluginStream(nsCString mimeType, diff --git a/dom/plugins/ipc/PluginInstanceChild.cpp b/dom/plugins/ipc/PluginInstanceChild.cpp index 770fdd2f3e5c..8dd81ce5bfb0 100644 --- a/dom/plugins/ipc/PluginInstanceChild.cpp +++ b/dom/plugins/ipc/PluginInstanceChild.cpp @@ -2508,52 +2508,6 @@ PluginInstanceChild::AnswerNPP_NewStream(PBrowserStreamChild* actor, return IPC_OK(); } -class NewStreamAsyncCall : public ChildAsyncCall -{ -public: - NewStreamAsyncCall(PluginInstanceChild* aInstance, - BrowserStreamChild* aBrowserStreamChild, - const nsCString& aMimeType, - const bool aSeekable) - : ChildAsyncCall(aInstance, nullptr, nullptr) - , mBrowserStreamChild(aBrowserStreamChild) - , mMimeType(aMimeType) - , mSeekable(aSeekable) - { - } - - NS_IMETHOD Run() override - { - RemoveFromAsyncList(); - - uint16_t stype = NP_NORMAL; - NPError rv = mInstance->DoNPP_NewStream(mBrowserStreamChild, mMimeType, - mSeekable, &stype); - DebugOnly sendOk = - mBrowserStreamChild->SendAsyncNPP_NewStreamResult(rv, stype); - MOZ_ASSERT(sendOk); - return NS_OK; - } - -private: - BrowserStreamChild* mBrowserStreamChild; - const nsCString mMimeType; - const bool mSeekable; -}; - -mozilla::ipc::IPCResult -PluginInstanceChild::RecvAsyncNPP_NewStream(PBrowserStreamChild* actor, - const nsCString& mimeType, - const bool& seekable) -{ - // Reusing ChildAsyncCall so that the task is cancelled properly on Destroy - BrowserStreamChild* child = static_cast(actor); - RefPtr task = - new NewStreamAsyncCall(this, child, mimeType, seekable); - PostChildAsyncCall(task.forget()); - return IPC_OK(); -} - PBrowserStreamChild* PluginInstanceChild::AllocPBrowserStreamChild(const nsCString& url, const uint32_t& length, diff --git a/dom/plugins/ipc/PluginInstanceChild.h b/dom/plugins/ipc/PluginInstanceChild.h index 1836cec193a8..0257b2739849 100644 --- a/dom/plugins/ipc/PluginInstanceChild.h +++ b/dom/plugins/ipc/PluginInstanceChild.h @@ -165,12 +165,6 @@ protected: NPError* rv, uint16_t* stype) override; - virtual mozilla::ipc::IPCResult - RecvAsyncNPP_NewStream( - PBrowserStreamChild* actor, - const nsCString& mimeType, - const bool& seekable) override; - virtual PBrowserStreamChild* AllocPBrowserStreamChild(const nsCString& url, const uint32_t& length, From 2f893da4ae7459aacf767d83884b410206eb36df Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:44 +1000 Subject: [PATCH 42/63] Bug 1352575 (part 8) - Remove AsyncNPP_NewResult. r=jimm. --HG-- extra : rebase_source : 6a4fed8d2ed4c34c2a8b2ddbd3c521cb38fc6f58 --- dom/plugins/base/nsPluginInstanceOwner.cpp | 15 --------- dom/plugins/base/nsPluginInstanceOwner.h | 1 - dom/plugins/ipc/PPluginInstance.ipdl | 3 -- dom/plugins/ipc/PluginInstanceParent.cpp | 36 ---------------------- dom/plugins/ipc/PluginInstanceParent.h | 3 -- 5 files changed, 58 deletions(-) diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index 997f806b1ae3..f73a69d16d6b 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -1675,21 +1675,6 @@ nsPluginInstanceOwner::NotifyHostAsyncInitFailed() content->StopPluginInstance(); } -void -nsPluginInstanceOwner::NotifyHostCreateWidget() -{ - mPluginHost->CreateWidget(this); -#ifdef XP_MACOSX - FixUpPluginWindow(ePluginPaintEnable); -#else - if (mPluginFrame) { - mPluginFrame->InvalidateFrame(); - } else { - CallSetWindow(); - } -#endif -} - void nsPluginInstanceOwner::NotifyDestroyPending() { diff --git a/dom/plugins/base/nsPluginInstanceOwner.h b/dom/plugins/base/nsPluginInstanceOwner.h index 589bcb02c787..8cc075d398c7 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.h +++ b/dom/plugins/base/nsPluginInstanceOwner.h @@ -270,7 +270,6 @@ public: #endif void NotifyHostAsyncInitFailed(); - void NotifyHostCreateWidget(); void NotifyDestroyPending(); bool GetCompositionString(uint32_t aIndex, nsTArray* aString, diff --git a/dom/plugins/ipc/PPluginInstance.ipdl b/dom/plugins/ipc/PPluginInstance.ipdl index 1408446bb9f9..3d6c2ff98257 100644 --- a/dom/plugins/ipc/PPluginInstance.ipdl +++ b/dom/plugins/ipc/PPluginInstance.ipdl @@ -254,9 +254,6 @@ parent: async RedrawPlugin(); - // Notifies the parent of its NPP_New result code. - async AsyncNPP_NewResult(NPError aResult); - // Sends a native window to be adopted by the native window that would be // returned by NPN_GetValue_NPNVnetscapeWindow. Only used on Windows. async SetNetscapeWindowAsParent(NativeWindowHandle childWindow); diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp index 2d8aadcadd6d..749ea4fb92aa 100644 --- a/dom/plugins/ipc/PluginInstanceParent.cpp +++ b/dom/plugins/ipc/PluginInstanceParent.cpp @@ -2041,42 +2041,6 @@ PluginInstanceParent::GetOwner() return inst->GetOwner(); } -mozilla::ipc::IPCResult -PluginInstanceParent::RecvAsyncNPP_NewResult(const NPError& aResult) -{ - // NB: mUseSurrogate must be cleared before doing anything else, especially - // calling NPP_SetWindow! - mUseSurrogate = false; - - mSurrogate->AsyncCallArriving(); - if (aResult == NPERR_NO_ERROR) { - mSurrogate->SetAcceptingCalls(true); - } - - // It is possible for a plugin instance to outlive its owner (eg. When a - // PluginDestructionGuard was on the stack at the time the owner was being - // destroyed). We need to handle that case. - nsPluginInstanceOwner* owner = GetOwner(); - if (!owner) { - // We can't do anything at this point, just return. Any pending browser - // streams will be cleaned up when the plugin instance is destroyed. - return IPC_OK(); - } - - if (aResult != NPERR_NO_ERROR) { - mSurrogate->NotifyAsyncInitFailed(); - return IPC_OK(); - } - - // Now we need to do a bunch of exciting post-NPP_New housekeeping. - owner->NotifyHostCreateWidget(); - - MOZ_ASSERT(mSurrogate); - mSurrogate->OnInstanceCreated(this); - - return IPC_OK(); -} - mozilla::ipc::IPCResult PluginInstanceParent::RecvSetNetscapeWindowAsParent(const NativeWindowHandle& childWindow) { diff --git a/dom/plugins/ipc/PluginInstanceParent.h b/dom/plugins/ipc/PluginInstanceParent.h index f0646af28736..c0f09588b7ba 100644 --- a/dom/plugins/ipc/PluginInstanceParent.h +++ b/dom/plugins/ipc/PluginInstanceParent.h @@ -241,9 +241,6 @@ public: virtual mozilla::ipc::IPCResult RecvRedrawPlugin() override; - virtual mozilla::ipc::IPCResult - RecvAsyncNPP_NewResult(const NPError& aResult) override; - virtual mozilla::ipc::IPCResult RecvSetNetscapeWindowAsParent(const NativeWindowHandle& childWindow) override; From fd1653bcc9f8c2f5ab1643ab820187f9e0b66fbd Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:44 +1000 Subject: [PATCH 43/63] Bug 1352575 (part 9) - Remove AsyncNP_Initialize. r=jimm. --HG-- extra : rebase_source : c9924774a5f32291a889868d790ed46a104e88a4 --- dom/plugins/ipc/PPluginModule.ipdl | 2 -- dom/plugins/ipc/PluginModuleChild.cpp | 10 ---------- dom/plugins/ipc/PluginModuleChild.h | 1 - 3 files changed, 13 deletions(-) diff --git a/dom/plugins/ipc/PPluginModule.ipdl b/dom/plugins/ipc/PPluginModule.ipdl index b39d40b46693..fe57fb1096d1 100644 --- a/dom/plugins/ipc/PPluginModule.ipdl +++ b/dom/plugins/ipc/PPluginModule.ipdl @@ -62,8 +62,6 @@ child: intr NP_Initialize(PluginSettings settings) returns (NPError rv); - async AsyncNP_Initialize(PluginSettings settings); - async PPluginInstance(nsCString aMimeType, nsCString[] aNames, nsCString[] aValues); diff --git a/dom/plugins/ipc/PluginModuleChild.cpp b/dom/plugins/ipc/PluginModuleChild.cpp index 83cdeee26242..597c1bdc57de 100644 --- a/dom/plugins/ipc/PluginModuleChild.cpp +++ b/dom/plugins/ipc/PluginModuleChild.cpp @@ -1842,16 +1842,6 @@ PluginModuleChild::AnswerNP_Initialize(const PluginSettings& aSettings, NPError* return IPC_OK(); } -mozilla::ipc::IPCResult -PluginModuleChild::RecvAsyncNP_Initialize(const PluginSettings& aSettings) -{ - NPError error = DoNP_Initialize(aSettings); - if (!SendNP_InitializeResult(error)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); -} - NPError PluginModuleChild::DoNP_Initialize(const PluginSettings& aSettings) { diff --git a/dom/plugins/ipc/PluginModuleChild.h b/dom/plugins/ipc/PluginModuleChild.h index 8959795e28e6..e14abbb93e9c 100644 --- a/dom/plugins/ipc/PluginModuleChild.h +++ b/dom/plugins/ipc/PluginModuleChild.h @@ -72,7 +72,6 @@ protected: virtual mozilla::ipc::IPCResult RecvDisableFlashProtectedMode() override; virtual mozilla::ipc::IPCResult AnswerNP_GetEntryPoints(NPError* rv) override; virtual mozilla::ipc::IPCResult AnswerNP_Initialize(const PluginSettings& aSettings, NPError* rv) override; - virtual mozilla::ipc::IPCResult RecvAsyncNP_Initialize(const PluginSettings& aSettings) override; virtual mozilla::ipc::IPCResult AnswerSyncNPP_New(PPluginInstanceChild* aActor, NPError* rv) override; From 8990926e778fd7f117887d70c284a3a7c492f21f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:44 +1000 Subject: [PATCH 44/63] Bug 1352575 (part 10) - Remove PluginModuleChromeParent::mContentParent. r=jimm. --HG-- extra : rebase_source : 75006d9b1b70752de872ad4c5de74248d6ce9290 --- dom/plugins/ipc/PluginModuleParent.cpp | 35 +++----------------------- dom/plugins/ipc/PluginModuleParent.h | 8 ------ 2 files changed, 4 insertions(+), 39 deletions(-) diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index 9414e97fd70a..3c4cf3a48c2c 100644 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -496,13 +496,6 @@ PluginModuleContentParent::OnLoadPluginResult(const uint32_t& aPluginId, : NPERR_GENERIC_ERROR); } -bool -PluginModuleChromeParent::SendAssociatePluginId() -{ - MOZ_ASSERT(mContentParent); - return mContentParent->SendAssociatePluginId(mPluginId, OtherPid()); -} - // static PluginLibrary* PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId, @@ -726,7 +719,6 @@ PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, #endif , mInitOnAsyncConnect(false) , mAsyncInitRv(NS_ERROR_NOT_INITIALIZED) - , mContentParent(nullptr) { NS_ASSERTION(mSubprocess, "Out of memory!"); mSandboxLevel = aSandboxLevel; @@ -2323,20 +2315,7 @@ PluginModuleParent::RecvNP_InitializeResult(const NPError& aError) mozilla::ipc::IPCResult PluginModuleChromeParent::RecvNP_InitializeResult(const NPError& aError) { - if (!mContentParent) { - return PluginModuleParent::RecvNP_InitializeResult(aError); - } - bool initOk = aError == NPERR_NO_ERROR; - if (initOk) { - SetPluginFuncs(mNPPIface); - } - mNPInitialized = initOk; - bool result = mContentParent->SendLoadPluginResult(mPluginId, initOk); - mContentParent = nullptr; - if (!result) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); + return PluginModuleParent::RecvNP_InitializeResult(aError); } #else @@ -2420,17 +2399,11 @@ mozilla::ipc::IPCResult PluginModuleChromeParent::RecvNP_InitializeResult(const NPError& aError) { bool ok = true; - if (mContentParent) { - if ((ok = SendAssociatePluginId())) { - ok = mContentParent->SendLoadPluginResult(mPluginId, - aError == NPERR_NO_ERROR); - mContentParent = nullptr; - } - } else if (aError == NPERR_NO_ERROR) { + if (aError == NPERR_NO_ERROR) { // Initialization steps for (e10s && !asyncInit) || !e10s #if defined XP_WIN - // Send the info needed to join the browser process's audio session to the - // plugin process. + // Send the info needed to join the browser process's audio session to + // the plugin process. nsID id; nsString sessionName; nsString iconPath; diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index b966f991e538..b645a0b9baa4 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -525,9 +525,6 @@ class PluginModuleChromeParent virtual mozilla::ipc::IPCResult RecvNP_InitializeResult(const NPError& aError) override; - bool - SendAssociatePluginId(); - void CachedSettingChanged(); virtual mozilla::ipc::IPCResult @@ -679,11 +676,6 @@ private: bool mInitOnAsyncConnect; nsresult mAsyncInitRv; - // mContentParent is to be used ONLY during the IPC dance that occurs - // when ContentParent::RecvLoadPlugin is called under async plugin init! - // In other contexts it is *unsafe*, as there might be multiple content - // processes in existence! - dom::ContentParent* mContentParent; nsCOMPtr mPluginOfflineObserver; bool mIsBlocklisted; #if defined(XP_WIN) && defined(MOZ_SANDBOX) From 671542cfd3030e59fb6f4e0efbdcf63750bd4876 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:44 +1000 Subject: [PATCH 45/63] Bug 1352575 (part 11) - Remove LoadPluginResult and AssociatePluginId. r=jimm. --HG-- extra : rebase_source : ecc5dd47ef1177abd947f331473a7436c97dad61 --- dom/ipc/ContentChild.cpp | 23 -------------------- dom/ipc/ContentChild.h | 6 ------ dom/ipc/PContent.ipdl | 13 ------------ dom/plugins/ipc/PluginModuleParent.cpp | 29 ++------------------------ dom/plugins/ipc/PluginModuleParent.h | 6 ------ 5 files changed, 2 insertions(+), 75 deletions(-) diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index c732e9f6d47b..d13adfe64df5 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -2772,29 +2772,6 @@ ContentChild::DeallocPOfflineCacheUpdateChild(POfflineCacheUpdateChild* actor) return true; } -mozilla::ipc::IPCResult -ContentChild::RecvLoadPluginResult(const uint32_t& aPluginId, - const bool& aResult) -{ - nsresult rv; - Endpoint endpoint; - bool finalResult = aResult && - SendConnectPluginBridge(aPluginId, &rv, &endpoint) && - NS_SUCCEEDED(rv); - plugins::PluginModuleContentParent::OnLoadPluginResult(aPluginId, - finalResult, - Move(endpoint)); - return IPC_OK(); -} - -mozilla::ipc::IPCResult -ContentChild::RecvAssociatePluginId(const uint32_t& aPluginId, - const base::ProcessId& aProcessId) -{ - plugins::PluginModuleContentParent::AssociatePluginId(aPluginId, aProcessId); - return IPC_OK(); -} - mozilla::ipc::IPCResult ContentChild::RecvDomainSetChanged(const uint32_t& aSetType, const uint32_t& aChangeType, diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index 8319c2a3d860..4198cb3d19f1 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -438,12 +438,6 @@ public: const nsCString& aTopic, const nsString& aData) override; - virtual mozilla::ipc::IPCResult RecvAssociatePluginId(const uint32_t& aPluginId, - const base::ProcessId& aProcessId) override; - - virtual mozilla::ipc::IPCResult RecvLoadPluginResult(const uint32_t& aPluginId, - const bool& aResult) override; - virtual mozilla::ipc::IPCResult RecvUpdateWindow(const uintptr_t& aChildId) override; virtual mozilla::ipc::IPCResult RecvDomainSetChanged(const uint32_t& aSetType, diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 0f186505ef29..0c24668f96c8 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -489,19 +489,6 @@ child: */ async NotifyIdleObserver(uint64_t observerId, nsCString topic, nsString str); - /** - * Called during plugin initialization to map a plugin id to a child process - * id. - */ - async AssociatePluginId(uint32_t aPluginId, ProcessId aProcessId); - - /** - * This call is used by async plugin initialization to notify the - * PluginModuleContentParent that the PluginModuleChromeParent's async - * init has completed. - */ - async LoadPluginResult(uint32_t aPluginId, bool aResult); - async InvokeDragSession(IPCDataTransfer[] transfers, uint32_t action); async EndDragSession(bool aDoneDrag, bool aUserCancelled, diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index 3c4cf3a48c2c..3e21c19f91a2 100644 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -198,9 +198,8 @@ private: namespace { /** - * Objects of this class remain linked until either an error occurs in the - * plugin initialization sequence, or until - * PluginModuleContentParent::OnLoadPluginResult has completed executing. + * Objects of this class remain linked until an error occurs in the + * plugin initialization sequence. */ class PluginModuleMapping : public PRCList { @@ -445,15 +444,6 @@ PluginModuleContentParent::LoadModule(uint32_t aPluginId, return parent; } -/* static */ void -PluginModuleContentParent::AssociatePluginId(uint32_t aPluginId, - base::ProcessId aOtherPid) -{ - DebugOnly mapping = - PluginModuleMapping::AssociateWithProcessId(aPluginId, aOtherPid); - MOZ_ASSERT(mapping); -} - /* static */ void PluginModuleContentParent::Initialize(Endpoint&& aEndpoint) { @@ -481,21 +471,6 @@ PluginModuleContentParent::Initialize(Endpoint&& aEndpoint) moduleMapping.forget(); } -/* static */ void -PluginModuleContentParent::OnLoadPluginResult(const uint32_t& aPluginId, - const bool& aResult, - Endpoint&& aEndpoint) -{ - Initialize(Move(aEndpoint)); - nsAutoPtr moduleMapping( - PluginModuleMapping::FindModuleByPluginId(aPluginId)); - MOZ_ASSERT(moduleMapping); - PluginModuleContentParent* parent = moduleMapping->GetModule(); - MOZ_ASSERT(parent); - parent->RecvNP_InitializeResult(aResult ? NPERR_NO_ERROR - : NPERR_GENERIC_ERROR); -} - // static PluginLibrary* PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId, diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index b645a0b9baa4..f7dfa65130a0 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -379,12 +379,6 @@ class PluginModuleContentParent : public PluginModuleParent static PluginLibrary* LoadModule(uint32_t aPluginId, nsPluginTag* aPluginTag); - static void OnLoadPluginResult(const uint32_t& aPluginId, - const bool& aResult, - Endpoint&& aEndpoint); - - static void AssociatePluginId(uint32_t aPluginId, base::ProcessId aProcessId); - virtual ~PluginModuleContentParent(); #if defined(XP_WIN) || defined(XP_MACOSX) From e08f1ddc1fc037bc82007761afeb1acb453179a0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:44 +1000 Subject: [PATCH 46/63] Bug 1352575 (part 12) - Remove NP_InitializeResult. r=jimm. --HG-- extra : rebase_source : 9ac4be00773bbcb27834bd338c569238cd0bec7c --- dom/plugins/ipc/PPluginModule.ipdl | 2 - dom/plugins/ipc/PluginModuleParent.cpp | 51 +++++++------------------- dom/plugins/ipc/PluginModuleParent.h | 6 --- 3 files changed, 13 insertions(+), 46 deletions(-) diff --git a/dom/plugins/ipc/PPluginModule.ipdl b/dom/plugins/ipc/PPluginModule.ipdl index fe57fb1096d1..20205a685439 100644 --- a/dom/plugins/ipc/PPluginModule.ipdl +++ b/dom/plugins/ipc/PPluginModule.ipdl @@ -99,8 +99,6 @@ child: async InitPluginModuleChild(Endpoint endpoint); parent: - async NP_InitializeResult(NPError aError); - /** * This message is only used on X11 platforms. * diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index 3e21c19f91a2..cba9a1dc2203 100644 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -2268,29 +2268,15 @@ PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* TimeStamp callNpInitEnd = TimeStamp::Now(); mTimeBlocked += (callNpInitEnd - callNpInitStart); - RecvNP_InitializeResult(*error); - - return NS_OK; -} - -mozilla::ipc::IPCResult -PluginModuleParent::RecvNP_InitializeResult(const NPError& aError) -{ - if (aError != NPERR_NO_ERROR) { + if (*error != NPERR_NO_ERROR) { OnInitFailure(); - return IPC_OK(); + return NS_OK; } SetPluginFuncs(mNPPIface); mNPInitialized = true; - return IPC_OK(); -} - -mozilla::ipc::IPCResult -PluginModuleChromeParent::RecvNP_InitializeResult(const NPError& aError) -{ - return PluginModuleParent::RecvNP_InitializeResult(aError); + return NS_OK; } #else @@ -2354,27 +2340,9 @@ PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) } TimeStamp callNpInitEnd = TimeStamp::Now(); mTimeBlocked += (callNpInitEnd - callNpInitStart); - RecvNP_InitializeResult(*error); - return NS_OK; -} -mozilla::ipc::IPCResult -PluginModuleParent::RecvNP_InitializeResult(const NPError& aError) -{ - if (aError != NPERR_NO_ERROR) { - OnInitFailure(); - return IPC_OK(); - } - - mNPInitialized = true; - return IPC_OK(); -} - -mozilla::ipc::IPCResult -PluginModuleChromeParent::RecvNP_InitializeResult(const NPError& aError) -{ bool ok = true; - if (aError == NPERR_NO_ERROR) { + if (*error == NPERR_NO_ERROR) { // Initialization steps for (e10s && !asyncInit) || !e10s #if defined XP_WIN // Send the info needed to join the browser process's audio session to @@ -2395,9 +2363,16 @@ PluginModuleChromeParent::RecvNP_InitializeResult(const NPError& aError) } if (!ok) { - return IPC_FAIL_NO_REASON(this); + return NS_ERROR_FAILURE; } - return PluginModuleParent::RecvNP_InitializeResult(aError); + + if (*error != NPERR_NO_ERROR) { + OnInitFailure(); + return NS_OK; + } + + mNPInitialized = true; + return NS_OK; } #endif diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index f7dfa65130a0..666acfac9ad2 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -178,9 +178,6 @@ protected: virtual mozilla::ipc::IPCResult RecvNPN_ReloadPlugins(const bool& aReloadPages) override; - virtual mozilla::ipc::IPCResult - RecvNP_InitializeResult(const NPError& aError) override; - static BrowserStreamParent* StreamCast(NPP instance, NPStream* s, PluginAsyncSurrogate** aSurrogate = nullptr); @@ -516,9 +513,6 @@ class PluginModuleChromeParent virtual bool WaitForIPCConnection() override; - virtual mozilla::ipc::IPCResult - RecvNP_InitializeResult(const NPError& aError) override; - void CachedSettingChanged(); virtual mozilla::ipc::IPCResult From 4b13b225525cd65e1f78971e3152f16b442b5396 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 26 May 2017 15:32:30 +1000 Subject: [PATCH 47/63] Bug 1352575 (part 13) - Remove surrogate use when casting. r=jimm. --HG-- extra : rebase_source : f58166692141cce898877f48c7390587e385175d --- dom/plugins/ipc/PluginInstanceParent.cpp | 1 - dom/plugins/ipc/PluginInstanceParent.h | 7 - dom/plugins/ipc/PluginModuleParent.cpp | 168 ++++++++--------------- dom/plugins/ipc/PluginModuleParent.h | 3 +- 4 files changed, 56 insertions(+), 123 deletions(-) diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp index 749ea4fb92aa..9d55fed865d6 100644 --- a/dom/plugins/ipc/PluginInstanceParent.cpp +++ b/dom/plugins/ipc/PluginInstanceParent.cpp @@ -116,7 +116,6 @@ PluginInstanceParent::PluginInstanceParent(PluginModuleParent* parent, const NPNetscapeFuncs* npniface) : mParent(parent) , mSurrogate(PluginAsyncSurrogate::Cast(npp)) - , mUseSurrogate(true) , mNPP(npp) , mNPNIface(npniface) , mWindowType(NPWindowTypeWindow) diff --git a/dom/plugins/ipc/PluginInstanceParent.h b/dom/plugins/ipc/PluginInstanceParent.h index c0f09588b7ba..c242fafd9525 100644 --- a/dom/plugins/ipc/PluginInstanceParent.h +++ b/dom/plugins/ipc/PluginInstanceParent.h @@ -288,12 +288,6 @@ public: return mNPP; } - bool - UseSurrogate() const - { - return mUseSurrogate; - } - void GetSrcAttribute(nsACString& aOutput) const { @@ -380,7 +374,6 @@ private: private: PluginModuleParent* mParent; RefPtr mSurrogate; - bool mUseSurrogate; NPP mNPP; const NPNetscapeFuncs* mNPNIface; nsCString mSrcAttribute; diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index cba9a1dc2203..0e56af546784 100644 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -1783,19 +1783,6 @@ PluginModuleParent::SetPluginFuncs(NPPluginFuncs* aFuncs) } } -#define RESOLVE_AND_CALL(instance, func) \ -NP_BEGIN_MACRO \ - PluginAsyncSurrogate* surrogate = nullptr; \ - PluginInstanceParent* i = PluginInstanceParent::Cast(instance, &surrogate);\ - if (surrogate && (!i || i->UseSurrogate())) { \ - return surrogate->func; \ - } \ - if (!i) { \ - return NPERR_GENERIC_ERROR; \ - } \ - return i->func; \ -NP_END_MACRO - NPError PluginModuleParent::NPP_Destroy(NPP instance, NPSavedData** saved) @@ -1807,20 +1794,14 @@ PluginModuleParent::NPP_Destroy(NPP instance, // (4) free parent PLUGIN_LOG_DEBUG_FUNCTION; - PluginAsyncSurrogate* surrogate = nullptr; - PluginInstanceParent* parentInstance = - PluginInstanceParent::Cast(instance, &surrogate); - if (surrogate && (!parentInstance || parentInstance->UseSurrogate())) { - return surrogate->NPP_Destroy(saved); - } - - if (!parentInstance) + PluginInstanceParent* pip = PluginInstanceParent::Cast(instance); + if (!pip) return NPERR_NO_ERROR; - NPError retval = parentInstance->Destroy(); + NPError retval = pip->Destroy(); instance->pdata = nullptr; - Unused << PluginInstanceParent::Call__delete__(parentInstance); + Unused << PluginInstanceParent::Call__delete__(pip); return retval; } @@ -1830,13 +1811,17 @@ PluginModuleParent::NPP_NewStream(NPP instance, NPMIMEType type, uint16_t* stype) { AUTO_PROFILER_LABEL("PluginModuleParent::NPP_NewStream", OTHER); - RESOLVE_AND_CALL(instance, NPP_NewStream(type, stream, seekable, stype)); + + PluginInstanceParent* pip = PluginInstanceParent::Cast(instance); + return pip ? pip->NPP_NewStream(type, stream, seekable, stype) + : NPERR_GENERIC_ERROR; } NPError PluginModuleParent::NPP_SetWindow(NPP instance, NPWindow* window) { - RESOLVE_AND_CALL(instance, NPP_SetWindow(window)); + PluginInstanceParent* pip = PluginInstanceParent::Cast(instance); + return pip ? pip->NPP_SetWindow(window) : NPERR_GENERIC_ERROR; } NPError @@ -1844,23 +1829,16 @@ PluginModuleParent::NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason) { - RESOLVE_AND_CALL(instance, NPP_DestroyStream(stream, reason)); + PluginInstanceParent* pip = PluginInstanceParent::Cast(instance); + return pip ? pip->NPP_DestroyStream(stream, reason) : NPERR_GENERIC_ERROR; } int32_t PluginModuleParent::NPP_WriteReady(NPP instance, NPStream* stream) { - PluginAsyncSurrogate* surrogate = nullptr; - BrowserStreamParent* s = StreamCast(instance, stream, &surrogate); - if (!s) { - if (surrogate) { - return surrogate->NPP_WriteReady(stream); - } - return -1; - } - - return s->WriteReady(); + BrowserStreamParent* s = StreamCast(instance, stream); + return s ? s->WriteReady() : -1; } int32_t @@ -1893,49 +1871,39 @@ void PluginModuleParent::NPP_Print(NPP instance, NPPrint* platformPrint) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); - i->NPP_Print(platformPrint); + PluginInstanceParent* pip = PluginInstanceParent::Cast(instance); + return pip ? pip->NPP_Print(platformPrint) : (void)0; } int16_t PluginModuleParent::NPP_HandleEvent(NPP instance, void* event) { - RESOLVE_AND_CALL(instance, NPP_HandleEvent(event)); + PluginInstanceParent* pip = PluginInstanceParent::Cast(instance); + return pip ? pip->NPP_HandleEvent(event) : NPERR_GENERIC_ERROR; } void PluginModuleParent::NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); - if (!i) - return; - - i->NPP_URLNotify(url, reason, notifyData); + PluginInstanceParent* pip = PluginInstanceParent::Cast(instance); + return pip ? pip->NPP_URLNotify(url, reason, notifyData) : (void)0; } NPError PluginModuleParent::NPP_GetValue(NPP instance, NPPVariable variable, void *ret_value) { - // The rules are slightly different for this function. - // If there is a surrogate, we *always* use it. - PluginAsyncSurrogate* surrogate = nullptr; - PluginInstanceParent* i = PluginInstanceParent::Cast(instance, &surrogate); - if (surrogate) { - return surrogate->NPP_GetValue(variable, ret_value); - } - if (!i) { - return NPERR_GENERIC_ERROR; - } - return i->NPP_GetValue(variable, ret_value); + PluginInstanceParent* pip = PluginInstanceParent::Cast(instance); + return pip ? pip->NPP_GetValue(variable, ret_value) : NPERR_GENERIC_ERROR; } NPError PluginModuleParent::NPP_SetValue(NPP instance, NPNVariable variable, void *value) { - RESOLVE_AND_CALL(instance, NPP_SetValue(variable, value)); + PluginInstanceParent* pip = PluginInstanceParent::Cast(instance); + return pip ? pip->NPP_SetValue(variable, value) : NPERR_GENERIC_ERROR; } mozilla::ipc::IPCResult @@ -1978,25 +1946,21 @@ void PluginModuleParent::NPP_URLRedirectNotify(NPP instance, const char* url, int32_t status, void* notifyData) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); - if (!i) - return; - - i->NPP_URLRedirectNotify(url, status, notifyData); + PluginInstanceParent* pip = PluginInstanceParent::Cast(instance); + return pip ? pip->NPP_URLRedirectNotify(url, status, notifyData) : (void)0; } BrowserStreamParent* -PluginModuleParent::StreamCast(NPP instance, NPStream* s, - PluginAsyncSurrogate** aSurrogate) +PluginModuleParent::StreamCast(NPP instance, NPStream* s) { - PluginInstanceParent* ip = PluginInstanceParent::Cast(instance, aSurrogate); - if (!ip || (aSurrogate && *aSurrogate && ip->UseSurrogate())) { + PluginInstanceParent* pip = PluginInstanceParent::Cast(instance); + if (!pip) { return nullptr; } BrowserStreamParent* sp = static_cast(static_cast(s->pdata)); - if (sp && (sp->mNPP != ip || s != sp->mStream)) { + if (sp && (sp->mNPP != pip || s != sp->mStream)) { MOZ_CRASH("Corrupted plugin stream data."); } return sp; @@ -2011,48 +1975,38 @@ PluginModuleParent::HasRequiredFunctions() nsresult PluginModuleParent::AsyncSetWindow(NPP instance, NPWindow* window) { - PluginAsyncSurrogate* surrogate = nullptr; - PluginInstanceParent* i = PluginInstanceParent::Cast(instance, &surrogate); - if (surrogate && (!i || i->UseSurrogate())) { - return surrogate->AsyncSetWindow(window); - } else if (!i) { - return NS_ERROR_FAILURE; - } - return i->AsyncSetWindow(window); + PluginInstanceParent* pip = PluginInstanceParent::Cast(instance); + return pip ? pip->AsyncSetWindow(window) : NS_ERROR_FAILURE; } nsresult PluginModuleParent::GetImageContainer(NPP instance, mozilla::layers::ImageContainer** aContainer) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); - return !i ? NS_ERROR_FAILURE : i->GetImageContainer(aContainer); + PluginInstanceParent* pip = PluginInstanceParent::Cast(instance); + return pip ? pip->GetImageContainer(aContainer) : NS_ERROR_FAILURE; } nsresult PluginModuleParent::GetImageSize(NPP instance, nsIntSize* aSize) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); - return !i ? NS_ERROR_FAILURE : i->GetImageSize(aSize); + PluginInstanceParent* pip = PluginInstanceParent::Cast(instance); + return pip ? pip->GetImageSize(aSize) : NS_ERROR_FAILURE; } void PluginModuleParent::DidComposite(NPP aInstance) { - if (PluginInstanceParent* i = PluginInstanceParent::Cast(aInstance)) { - i->DidComposite(); - } + PluginInstanceParent* pip = PluginInstanceParent::Cast(aInstance); + return pip ? pip->DidComposite() : (void)0; } nsresult PluginModuleParent::SetBackgroundUnknown(NPP instance) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); - if (!i) - return NS_ERROR_FAILURE; - - return i->SetBackgroundUnknown(); + PluginInstanceParent* pip = PluginInstanceParent::Cast(instance); + return pip ? pip->SetBackgroundUnknown() : NS_ERROR_FAILURE; } nsresult @@ -2060,21 +2014,16 @@ PluginModuleParent::BeginUpdateBackground(NPP instance, const nsIntRect& aRect, DrawTarget** aDrawTarget) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); - if (!i) - return NS_ERROR_FAILURE; - - return i->BeginUpdateBackground(aRect, aDrawTarget); + PluginInstanceParent* pip = PluginInstanceParent::Cast(instance); + return pip ? pip->BeginUpdateBackground(aRect, aDrawTarget) + : NS_ERROR_FAILURE; } nsresult PluginModuleParent::EndUpdateBackground(NPP instance, const nsIntRect& aRect) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); - if (!i) - return NS_ERROR_FAILURE; - - return i->EndUpdateBackground(aRect); + PluginInstanceParent* pip = PluginInstanceParent::Cast(instance); + return pip ? pip->EndUpdateBackground(aRect) : NS_ERROR_FAILURE; } #if defined(XP_WIN) @@ -2082,8 +2031,8 @@ nsresult PluginModuleParent::GetScrollCaptureContainer(NPP aInstance, mozilla::layers::ImageContainer** aContainer) { - PluginInstanceParent* inst = PluginInstanceParent::Cast(aInstance); - return !inst ? NS_ERROR_FAILURE : inst->GetScrollCaptureContainer(aContainer); + PluginInstanceParent* pip = PluginInstanceParent::Cast(aInstance); + return pip ? pip->GetScrollCaptureContainer(aContainer) : NS_ERROR_FAILURE; } #endif @@ -2093,11 +2042,9 @@ PluginModuleParent::HandledWindowedPluginKeyEvent( const NativeEventData& aNativeKeyData, bool aIsConsumed) { - PluginInstanceParent* parent = PluginInstanceParent::Cast(aInstance); - if (NS_WARN_IF(!parent)) { - return NS_ERROR_FAILURE; - } - return parent->HandledWindowedPluginKeyEvent(aNativeKeyData, aIsConsumed); + PluginInstanceParent* pip = PluginInstanceParent::Cast(aInstance); + return pip ? pip->HandledWindowedPluginKeyEvent(aNativeKeyData, aIsConsumed) + : NS_ERROR_FAILURE; } void @@ -2748,22 +2695,17 @@ PluginModuleParent::NPP_GetSitesWithData(nsCOMPtr c nsresult PluginModuleParent::IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); - if (!i) - return NS_ERROR_FAILURE; - - return i->IsRemoteDrawingCoreAnimation(aDrawing); + PluginInstanceParent* pip = PluginInstanceParent::Cast(instance); + return pip ? pip->IsRemoteDrawingCoreAnimation(aDrawing) : NS_ERROR_FAILURE; } #endif #if defined(XP_MACOSX) || defined(XP_WIN) nsresult PluginModuleParent::ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); - if (!i) - return NS_ERROR_FAILURE; - - return i->ContentsScaleFactorChanged(aContentsScaleFactor); + PluginInstanceParent* pip = PluginInstanceParent::Cast(instance); + return pip ? pip->ContentsScaleFactorChanged(aContentsScaleFactor) + : NS_ERROR_FAILURE; } #endif // #if defined(XP_MACOSX) diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index 666acfac9ad2..9cd8053889b6 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -178,8 +178,7 @@ protected: virtual mozilla::ipc::IPCResult RecvNPN_ReloadPlugins(const bool& aReloadPages) override; - static BrowserStreamParent* StreamCast(NPP instance, NPStream* s, - PluginAsyncSurrogate** aSurrogate = nullptr); + static BrowserStreamParent* StreamCast(NPP instance, NPStream* s); virtual mozilla::ipc::IPCResult AnswerNPN_SetValue_NPPVpluginRequiresAudioDeviceChanges( From 1bd10a2d9edc5e26888dbc184ea25137be1f46e3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:44 +1000 Subject: [PATCH 48/63] Bug 1352575 (part 14) - Remove more surrogate use when casting. r=jimm. --HG-- extra : rebase_source : a5c0cae3b8aae57c8b440311262a8ad0c4c64492 --- dom/plugins/base/nsJSNPRuntime.cpp | 51 ++++------------------ dom/plugins/base/nsPluginInstanceOwner.cpp | 3 +- 2 files changed, 10 insertions(+), 44 deletions(-) diff --git a/dom/plugins/base/nsJSNPRuntime.cpp b/dom/plugins/base/nsJSNPRuntime.cpp index d4c8ed52c953..112e87b4b69b 100644 --- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -1,4 +1,5 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -29,10 +30,6 @@ #include "js/TracingAPI.h" #include "mozilla/HashFunctions.h" #include "mozilla/dom/ScriptSettings.h" -#include "mozilla/plugins/PluginAsyncSurrogate.h" - -using mozilla::plugins::AsyncNPObject; -using mozilla::plugins::PluginAsyncSurrogate; #define NPRUNTIME_JSCLASS_NAME "NPObject JS wrapper class" @@ -109,24 +106,10 @@ static nsTArray* sDelayedReleases; namespace { -inline void -CastNPObject(NPObject *aObj, PluginScriptableObjectParent*& aActor, - PluginAsyncSurrogate*& aSurrogate) -{ - aActor = nullptr; - aSurrogate = nullptr; - if (aObj->_class == PluginScriptableObjectParent::GetClass()) { - aActor = static_cast(aObj)->parent; - } else if (aObj->_class == PluginAsyncSurrogate::GetClass()) { - aSurrogate = static_cast(aObj)->mSurrogate; - } -} - inline bool NPObjectIsOutOfProcessProxy(NPObject *obj) { - return obj->_class == PluginScriptableObjectParent::GetClass() || - obj->_class == PluginAsyncSurrogate::GetClass(); + return obj->_class == PluginScriptableObjectParent::GetClass(); } } // namespace @@ -1097,17 +1080,6 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JS::Handle obj) return nullptr; } - // If we're running out-of-process and initializing asynchronously, and if - // the plugin has been asked to destroy itself during initialization, - // don't return any new NPObjects. - nsNPAPIPluginInstance* inst = static_cast(npp->ndata); - if (inst->GetPlugin()->GetLibrary()->IsOOP()) { - PluginAsyncSurrogate* surrogate = PluginAsyncSurrogate::Cast(npp); - if (surrogate && surrogate->IsDestroyPending()) { - return nullptr; - } - } - // No need to enter the right compartment here as we only get the // class and private from the JSObject, neither of which cares about // compartments. @@ -1404,22 +1376,15 @@ NPObjWrapper_GetProperty(JSContext *cx, JS::Handle obj, JS::Handle(npobj)->parent; - // actor and surrogate may be null if the plugin crashed. - if (!actor && !surrogate) + // actor may be null if the plugin crashed. + if (!actor) return false; - bool success = false; - if (surrogate) { - success = surrogate->GetPropertyHelper(npobj, identifier, &hasProperty, - &hasMethod, &npv); - } else if (actor) { - success = actor->GetPropertyHelper(identifier, &hasProperty, &hasMethod, - &npv); - } + bool success = actor->GetPropertyHelper(identifier, &hasProperty, + &hasMethod, &npv); if (!ReportExceptionIfPending(cx)) { if (success) diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index f73a69d16d6b..425d12949b66 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -64,6 +64,7 @@ using mozilla::DefaultXDisplay; #include "mozilla/IMEStateManager.h" #include "mozilla/TextComposition.h" #include "mozilla/AutoRestore.h" +#include "mozilla/plugins/PluginAsyncSurrogate.h" #include "nsContentCID.h" #include "nsWidgetsCID.h" @@ -1689,7 +1690,7 @@ nsPluginInstanceOwner::NotifyDestroyPending() if (NS_FAILED(mInstance->GetNPP(&npp)) || !npp) { return; } - PluginAsyncSurrogate::NotifyDestroyPending(npp); + mozilla::plugins::PluginAsyncSurrogate::NotifyDestroyPending(npp); } nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent) From 89708190f17bd9baa1b886b3d278e7d9d9d060d1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:44 +1000 Subject: [PATCH 49/63] Bug 1352575 (part 15) - Remove PluginModuleChromeParent::mInitOnAsyncConnect. r=jimm. --HG-- extra : rebase_source : 8a32d63bd15bf365ffd825248d374c21b6a885de --- dom/plugins/ipc/PluginModuleParent.cpp | 60 +------------------------- dom/plugins/ipc/PluginModuleParent.h | 1 - 2 files changed, 1 insertion(+), 60 deletions(-) diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index 0e56af546784..e621f75a1b46 100644 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -557,33 +557,6 @@ PluginModuleChromeParent::OnProcessLaunched(const bool aSucceeded) } #endif - if (mInitOnAsyncConnect) { - mInitOnAsyncConnect = false; - NPError dummyError; -#if defined(XP_WIN) - mAsyncInitRv = NP_GetEntryPoints(mNPPIface, - &dummyError); - if (NS_SUCCEEDED(mAsyncInitRv)) -#endif - { -#if defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(MOZ_WIDGET_GONK) - mAsyncInitRv = NP_Initialize(mNPNIface, - mNPPIface, - &dummyError); -#else - mAsyncInitRv = NP_Initialize(mNPNIface, - &dummyError); -#endif - } - -#if defined(XP_MACOSX) - if (NS_SUCCEEDED(mAsyncInitRv)) { - mAsyncInitRv = NP_GetEntryPoints(mNPPIface, - &dummyError); - } -#endif - } - #ifdef MOZ_GECKO_PROFILER Unused << SendInitProfiler(ProfilerParent::CreateForProcess(OtherPid())); #endif @@ -692,7 +665,6 @@ PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, , mFlashProcess2(0) , mFinishInitTask(nullptr) #endif - , mInitOnAsyncConnect(false) , mAsyncInitRv(NS_ERROR_NOT_INITIALIZED) { NS_ASSERTION(mSubprocess, "Out of memory!"); @@ -2193,13 +2165,6 @@ PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* mNPNIface = bFuncs; mNPPIface = pFuncs; - if (!mSubprocess->IsConnected()) { - // The subprocess isn't connected yet. Defer NP_Initialize until - // OnProcessLaunched is invoked. - mInitOnAsyncConnect = true; - return NS_OK; - } - PluginSettings settings; GetSettings(&settings); @@ -2262,21 +2227,6 @@ PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) if (NS_FAILED(rv)) return rv; -#if defined(XP_MACOSX) - if (!mSubprocess->IsConnected()) { - // The subprocess isn't connected yet. Defer NP_Initialize until - // OnProcessLaunched is invoked. - mInitOnAsyncConnect = true; - *error = NPERR_NO_ERROR; - return NS_OK; - } -#else - if (mInitOnAsyncConnect) { - *error = NPERR_NO_ERROR; - return NS_OK; - } -#endif - PluginSettings settings; GetSettings(&settings); @@ -2414,17 +2364,9 @@ PluginModuleParent::NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error) nsresult PluginModuleChromeParent::NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error) { -#if defined(XP_MACOSX) - if (mInitOnAsyncConnect) { - PluginAsyncSurrogate::NP_GetEntryPoints(pFuncs); - mNPPIface = pFuncs; - *error = NPERR_NO_ERROR; - return NS_OK; - } -#else +#if !defined(XP_MACOSX) if (!mSubprocess->IsConnected()) { mNPPIface = pFuncs; - mInitOnAsyncConnect = true; *error = NPERR_NO_ERROR; return NS_OK; } diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index 9cd8053889b6..8525026e230f 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -661,7 +661,6 @@ private: friend class LaunchedTask; - bool mInitOnAsyncConnect; nsresult mAsyncInitRv; nsCOMPtr mPluginOfflineObserver; bool mIsBlocklisted; From 1f21c73d8501be133cc4347760499ae90f1fd3c8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:45 +1000 Subject: [PATCH 50/63] Bug 1352575 (part 16) - Remove PluginModuleChromeParent::mAsyncInitRv. r=jimm. --HG-- extra : rebase_source : e901cb818cd3cd39560b2fd86415024bf0fd7c1d --- dom/plugins/ipc/PluginModuleParent.cpp | 3 +-- dom/plugins/ipc/PluginModuleParent.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index e621f75a1b46..940e8f82fb12 100644 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -515,7 +515,7 @@ PluginModuleChromeParent::OnProcessLaunched(const bool aSucceeded) } // We may have already been initialized by another call that was waiting // for process connect. If so, this function doesn't need to run. - if (mAsyncInitRv != NS_ERROR_NOT_INITIALIZED || mShutdown) { + if (mShutdown) { return; } @@ -665,7 +665,6 @@ PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, , mFlashProcess2(0) , mFinishInitTask(nullptr) #endif - , mAsyncInitRv(NS_ERROR_NOT_INITIALIZED) { NS_ASSERTION(mSubprocess, "Out of memory!"); mSandboxLevel = aSandboxLevel; diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index 8525026e230f..85ae29986473 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -661,7 +661,6 @@ private: friend class LaunchedTask; - nsresult mAsyncInitRv; nsCOMPtr mPluginOfflineObserver; bool mIsBlocklisted; #if defined(XP_WIN) && defined(MOZ_SANDBOX) From 7ac822f1207824804b025ec95e3b24f02e2d6eff Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 29 May 2017 12:06:55 +1000 Subject: [PATCH 51/63] Bug 1352575 (part 17) - Remove AsyncNPP_NewStreamResult. r=jimm. --HG-- extra : rebase_source : 95ceae4a862ba44122919c5ca5e4f51b1dba0644 --- dom/plugins/ipc/BrowserStreamParent.cpp | 37 ------------------------- dom/plugins/ipc/BrowserStreamParent.h | 5 ---- dom/plugins/ipc/PBrowserStream.ipdl | 1 - 3 files changed, 43 deletions(-) diff --git a/dom/plugins/ipc/BrowserStreamParent.cpp b/dom/plugins/ipc/BrowserStreamParent.cpp index ccf6a3e3f273..f5cdf2cfeacf 100644 --- a/dom/plugins/ipc/BrowserStreamParent.cpp +++ b/dom/plugins/ipc/BrowserStreamParent.cpp @@ -23,7 +23,6 @@ BrowserStreamParent::BrowserStreamParent(PluginInstanceParent* npp, NPStream* stream) : mNPP(npp) , mStream(stream) - , mDeferredDestroyReason(NPRES_DONE) , mState(INITIALIZING) { mStream->pdata = static_cast(this); @@ -45,41 +44,6 @@ BrowserStreamParent::ActorDestroy(ActorDestroyReason aWhy) // Implement me! Bug 1005159 } -mozilla::ipc::IPCResult -BrowserStreamParent::RecvAsyncNPP_NewStreamResult(const NPError& rv, - const uint16_t& stype) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - PluginAsyncSurrogate* surrogate = mNPP->GetAsyncSurrogate(); - MOZ_ASSERT(surrogate); - surrogate->AsyncCallArriving(); - if (mState == DEFERRING_DESTROY) { - // We've been asked to destroy ourselves before init was complete. - mState = DYING; - Unused << SendNPP_DestroyStream(mDeferredDestroyReason); - return IPC_OK(); - } - - NPError error = rv; - if (error == NPERR_NO_ERROR) { - if (!mStreamListener) { - return IPC_FAIL_NO_REASON(this); - } - if (mStreamListener->SetStreamType(stype)) { - mState = ALIVE; - } else { - error = NPERR_GENERIC_ERROR; - } - } - - if (error != NPERR_NO_ERROR) { - surrogate->DestroyAsyncStream(mStream); - Unused << PBrowserStreamParent::Send__delete__(this); - } - - return IPC_OK(); -} - mozilla::ipc::IPCResult BrowserStreamParent::AnswerNPN_RequestRead(const IPCByteRanges& ranges, NPError* result) @@ -149,7 +113,6 @@ BrowserStreamParent::NPP_DestroyStream(NPReason reason) bool stillInitializing = INITIALIZING == mState; if (stillInitializing) { mState = DEFERRING_DESTROY; - mDeferredDestroyReason = reason; } else { mState = DYING; Unused << SendNPP_DestroyStream(reason); diff --git a/dom/plugins/ipc/BrowserStreamParent.h b/dom/plugins/ipc/BrowserStreamParent.h index 4be9317c3254..141d8ac4dd62 100644 --- a/dom/plugins/ipc/BrowserStreamParent.h +++ b/dom/plugins/ipc/BrowserStreamParent.h @@ -30,10 +30,6 @@ public: virtual void ActorDestroy(ActorDestroyReason aWhy) override; - virtual mozilla::ipc::IPCResult RecvAsyncNPP_NewStreamResult( - const NPError& rv, - const uint16_t& stype) override; - virtual mozilla::ipc::IPCResult AnswerNPN_RequestRead(const IPCByteRanges& ranges, NPError* result) override; @@ -61,7 +57,6 @@ private: NPStream* mStream; nsCOMPtr mStreamPeer; RefPtr mStreamListener; - NPReason mDeferredDestroyReason; enum { INITIALIZING, diff --git a/dom/plugins/ipc/PBrowserStream.ipdl b/dom/plugins/ipc/PBrowserStream.ipdl index dbd238750c81..8f5beedc522f 100644 --- a/dom/plugins/ipc/PBrowserStream.ipdl +++ b/dom/plugins/ipc/PBrowserStream.ipdl @@ -36,7 +36,6 @@ child: async __delete__(); parent: - async AsyncNPP_NewStreamResult(NPError rv, uint16_t stype); intr NPN_RequestRead(IPCByteRanges ranges) returns (NPError result); async NPN_DestroyStream(NPReason reason); From 35d18050ad7021278397fe8d785331bbd17103f7 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:45 +1000 Subject: [PATCH 52/63] Bug 1352575 (part 18) - Remove PluginAsyncSurrogate. r=jimm. The patch also removes PluginDataResolver and various other things that are no longer necessary. --HG-- extra : rebase_source : 98149b5e9e41789d4b094f52eaefc84f5393a0c4 --- dom/plugins/base/nsPluginHost.cpp | 8 - dom/plugins/base/nsPluginHost.h | 13 - dom/plugins/base/nsPluginInstanceOwner.cpp | 18 - dom/plugins/base/nsPluginInstanceOwner.h | 1 - dom/plugins/ipc/BrowserStreamParent.cpp | 1 - dom/plugins/ipc/PluginAsyncSurrogate.cpp | 996 ------------------ dom/plugins/ipc/PluginAsyncSurrogate.h | 187 ---- dom/plugins/ipc/PluginDataResolver.h | 26 - dom/plugins/ipc/PluginInstanceParent.cpp | 25 +- dom/plugins/ipc/PluginInstanceParent.h | 10 +- dom/plugins/ipc/PluginModuleParent.cpp | 11 +- dom/plugins/ipc/PluginModuleParent.h | 7 - .../ipc/PluginScriptableObjectParent.cpp | 13 - dom/plugins/ipc/moz.build | 3 - 14 files changed, 7 insertions(+), 1312 deletions(-) delete mode 100644 dom/plugins/ipc/PluginAsyncSurrogate.cpp delete mode 100644 dom/plugins/ipc/PluginAsyncSurrogate.h delete mode 100644 dom/plugins/ipc/PluginDataResolver.h diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp index 165ccf77edd7..3f89be3025b8 100644 --- a/dom/plugins/base/nsPluginHost.cpp +++ b/dom/plugins/base/nsPluginHost.cpp @@ -53,7 +53,6 @@ #include "mozilla/dom/ContentParent.h" #include "mozilla/dom/FakePluginTagInitBinding.h" #include "mozilla/LoadInfo.h" -#include "mozilla/plugins/PluginAsyncSurrogate.h" #include "mozilla/plugins/PluginBridge.h" #include "mozilla/plugins/PluginTypes.h" #include "mozilla/Preferences.h" @@ -119,7 +118,6 @@ using namespace mozilla; using mozilla::TimeStamp; using mozilla::plugins::FakePluginTag; using mozilla::plugins::PluginTag; -using mozilla::plugins::PluginAsyncSurrogate; using mozilla::dom::FakePluginTagInit; using mozilla::dom::FakePluginMimeEntry; @@ -4019,12 +4017,6 @@ PluginDestructionGuard::PluginDestructionGuard(nsNPAPIPluginInstance *aInstance) Init(); } -PluginDestructionGuard::PluginDestructionGuard(PluginAsyncSurrogate *aSurrogate) - : mInstance(static_cast(aSurrogate->GetNPP()->ndata)) -{ - InitAsync(); -} - PluginDestructionGuard::PluginDestructionGuard(NPP npp) : mInstance(npp ? static_cast(npp->ndata) : nullptr) { diff --git a/dom/plugins/base/nsPluginHost.h b/dom/plugins/base/nsPluginHost.h index fdeb5f1415d0..5beaab4fdc81 100644 --- a/dom/plugins/base/nsPluginHost.h +++ b/dom/plugins/base/nsPluginHost.h @@ -35,7 +35,6 @@ namespace mozilla { namespace plugins { class FakePluginTag; -class PluginAsyncSurrogate; class PluginTag; } // namespace plugins } // namespace mozilla @@ -425,7 +424,6 @@ class PluginDestructionGuard : public mozilla::LinkedListElement mInstance; bool mDelayedDestroy; diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index 425d12949b66..5c4434d4dd67 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -64,7 +64,6 @@ using mozilla::DefaultXDisplay; #include "mozilla/IMEStateManager.h" #include "mozilla/TextComposition.h" #include "mozilla/AutoRestore.h" -#include "mozilla/plugins/PluginAsyncSurrogate.h" #include "nsContentCID.h" #include "nsWidgetsCID.h" @@ -1676,23 +1675,6 @@ nsPluginInstanceOwner::NotifyHostAsyncInitFailed() content->StopPluginInstance(); } -void -nsPluginInstanceOwner::NotifyDestroyPending() -{ - if (!mInstance) { - return; - } - bool isOOP = false; - if (NS_FAILED(mInstance->GetIsOOP(&isOOP)) || !isOOP) { - return; - } - NPP npp = nullptr; - if (NS_FAILED(mInstance->GetNPP(&npp)) || !npp) { - return; - } - mozilla::plugins::PluginAsyncSurrogate::NotifyDestroyPending(npp); -} - nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent) { #ifdef MOZ_WIDGET_ANDROID diff --git a/dom/plugins/base/nsPluginInstanceOwner.h b/dom/plugins/base/nsPluginInstanceOwner.h index 8cc075d398c7..d10c9afb73f4 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.h +++ b/dom/plugins/base/nsPluginInstanceOwner.h @@ -270,7 +270,6 @@ public: #endif void NotifyHostAsyncInitFailed(); - void NotifyDestroyPending(); bool GetCompositionString(uint32_t aIndex, nsTArray* aString, int32_t* aLength); diff --git a/dom/plugins/ipc/BrowserStreamParent.cpp b/dom/plugins/ipc/BrowserStreamParent.cpp index f5cdf2cfeacf..8f0265112487 100644 --- a/dom/plugins/ipc/BrowserStreamParent.cpp +++ b/dom/plugins/ipc/BrowserStreamParent.cpp @@ -5,7 +5,6 @@ #include "BrowserStreamParent.h" -#include "PluginAsyncSurrogate.h" #include "PluginInstanceParent.h" #include "nsNPAPIPlugin.h" diff --git a/dom/plugins/ipc/PluginAsyncSurrogate.cpp b/dom/plugins/ipc/PluginAsyncSurrogate.cpp deleted file mode 100644 index a527a6d6cf12..000000000000 --- a/dom/plugins/ipc/PluginAsyncSurrogate.cpp +++ /dev/null @@ -1,996 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "PluginAsyncSurrogate.h" - -#include "base/message_loop.h" -#include "base/message_pump_default.h" -#include "mozilla/dom/ContentChild.h" -#include "mozilla/plugins/PluginInstanceParent.h" -#include "mozilla/plugins/PluginModuleParent.h" -#include "mozilla/plugins/PluginScriptableObjectParent.h" -#include "mozilla/Telemetry.h" -#include "nsJSNPRuntime.h" -#include "nsNPAPIPlugin.h" -#include "nsNPAPIPluginInstance.h" -#include "nsNPAPIPluginStreamListener.h" -#include "nsPluginInstanceOwner.h" -#include "nsPluginStreamListenerPeer.h" -#include "npruntime.h" -#include "nsThreadUtils.h" -#include "PluginMessageUtils.h" - -namespace mozilla { -namespace plugins { - -AsyncNPObject::AsyncNPObject(PluginAsyncSurrogate* aSurrogate) - : NPObject() - , mSurrogate(aSurrogate) - , mRealObject(nullptr) -{ -} - -AsyncNPObject::~AsyncNPObject() -{ - if (mRealObject) { - --mRealObject->asyncWrapperCount; - parent::_releaseobject(mRealObject); - mRealObject = nullptr; - } -} - -NPObject* -AsyncNPObject::GetRealObject() -{ - if (mRealObject) { - return mRealObject; - } - PluginInstanceParent* instance = PluginInstanceParent::Cast(mSurrogate->GetNPP()); - if (!instance) { - return nullptr; - } - NPObject* realObject = nullptr; - NPError err = instance->NPP_GetValue(NPPVpluginScriptableNPObject, - &realObject); - if (err != NPERR_NO_ERROR) { - return nullptr; - } - if (realObject->_class != PluginScriptableObjectParent::GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - parent::_releaseobject(realObject); - return nullptr; - } - mRealObject = static_cast(realObject); - ++mRealObject->asyncWrapperCount; - return mRealObject; -} - -class MOZ_STACK_CLASS RecursionGuard -{ -public: - RecursionGuard() - : mIsRecursive(sHasEntered) - { - if (!mIsRecursive) { - sHasEntered = true; - } - } - - ~RecursionGuard() - { - if (!mIsRecursive) { - sHasEntered = false; - } - } - - inline bool - IsRecursive() - { - return mIsRecursive; - } - -private: - bool mIsRecursive; - static bool sHasEntered; -}; - -bool RecursionGuard::sHasEntered = false; - -PluginAsyncSurrogate::PluginAsyncSurrogate(PluginModuleParent* aParent) - : mParent(aParent) - , mWindow(nullptr) - , mAcceptCalls(false) - , mInstantiated(false) - , mAsyncSetWindow(false) - , mInitCancelled(false) - , mDestroyPending(false) - , mAsyncCallsInFlight(0) -{ - MOZ_ASSERT(aParent); -} - -PluginAsyncSurrogate::~PluginAsyncSurrogate() -{ -} - -bool -PluginAsyncSurrogate::Init(NPMIMEType aPluginType, NPP aInstance, - int16_t aArgc, char* aArgn[], char* aArgv[]) -{ - mMimeType = aPluginType; - nsNPAPIPluginInstance* instance = - static_cast(aInstance->ndata); - MOZ_ASSERT(instance); - mInstance = instance; - for (int i = 0; i < aArgc; ++i) { - mNames.AppendElement(NullableString(aArgn[i])); - mValues.AppendElement(NullableString(aArgv[i])); - } - return true; -} - -/* static */ bool -PluginAsyncSurrogate::Create(PluginModuleParent* aParent, NPMIMEType aPluginType, - NPP aInstance, int16_t aArgc, - char* aArgn[], char* aArgv[]) -{ - RefPtr surrogate(new PluginAsyncSurrogate(aParent)); - if (!surrogate->Init(aPluginType, aInstance, aArgc, aArgn, aArgv)) { - return false; - } - PluginAsyncSurrogate* rawSurrogate = nullptr; - surrogate.forget(&rawSurrogate); - aInstance->pdata = static_cast(rawSurrogate); - return true; -} - -/* static */ PluginAsyncSurrogate* -PluginAsyncSurrogate::Cast(NPP aInstance) -{ - MOZ_ASSERT(aInstance); - PluginDataResolver* resolver = - reinterpret_cast(aInstance->pdata); - if (!resolver) { - return nullptr; - } - return resolver->GetAsyncSurrogate(); -} - -nsresult -PluginAsyncSurrogate::NPP_New(NPError* aError) -{ - if (!mInstance) { - return NS_ERROR_NULL_POINTER; - } - - nsresult rv = mParent->NPP_NewInternal(mMimeType.BeginWriting(), GetNPP(), - mNames, mValues, nullptr, - aError); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; -} - -void -PluginAsyncSurrogate::NP_GetEntryPoints(NPPluginFuncs* aFuncs) -{ - aFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; - aFuncs->destroy = &NPP_Destroy; - aFuncs->getvalue = &NPP_GetValue; - aFuncs->setvalue = &NPP_SetValue; - aFuncs->newstream = &NPP_NewStream; - aFuncs->setwindow = &NPP_SetWindow; - aFuncs->writeready = &NPP_WriteReady; - aFuncs->event = &NPP_HandleEvent; - aFuncs->destroystream = &NPP_DestroyStream; - // We need to set these so that content code doesn't make assumptions - // about these operations not being supported - aFuncs->write = &PluginModuleParent::NPP_Write; - aFuncs->asfile = &PluginModuleParent::NPP_StreamAsFile; -} - -/* static */ void -PluginAsyncSurrogate::NotifyDestroyPending(NPP aInstance) -{ - PluginAsyncSurrogate* surrogate = Cast(aInstance); - if (!surrogate) { - return; - } - surrogate->NotifyDestroyPending(); -} - -NPP -PluginAsyncSurrogate::GetNPP() -{ - MOZ_ASSERT(mInstance); - NPP npp; - DebugOnly rv = mInstance->GetNPP(&npp); - MOZ_ASSERT(NS_SUCCEEDED(rv)); - return npp; -} - -void -PluginAsyncSurrogate::NotifyDestroyPending() -{ - mDestroyPending = true; - nsJSNPRuntime::OnPluginDestroyPending(GetNPP()); -} - -NPError -PluginAsyncSurrogate::NPP_Destroy(NPSavedData** aSave) -{ - NotifyDestroyPending(); - if (!WaitForInit()) { - return NPERR_GENERIC_ERROR; - } - return PluginModuleParent::NPP_Destroy(GetNPP(), aSave); -} - -NPError -PluginAsyncSurrogate::NPP_GetValue(NPPVariable aVariable, void* aRetval) -{ - if (aVariable != NPPVpluginScriptableNPObject) { - if (!WaitForInit()) { - return NPERR_GENERIC_ERROR; - } - - PluginInstanceParent* instance = PluginInstanceParent::Cast(GetNPP()); - MOZ_ASSERT(instance); - return instance->NPP_GetValue(aVariable, aRetval); - } - - NPObject* npobject = parent::_createobject(GetNPP(), - const_cast(GetClass())); - MOZ_ASSERT(npobject); - MOZ_ASSERT(npobject->_class == GetClass()); - MOZ_ASSERT(npobject->referenceCount == 1); - *(NPObject**)aRetval = npobject; - return npobject ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR; -} - -NPError -PluginAsyncSurrogate::NPP_SetValue(NPNVariable aVariable, void* aValue) -{ - if (!WaitForInit()) { - return NPERR_GENERIC_ERROR; - } - return PluginModuleParent::NPP_SetValue(GetNPP(), aVariable, aValue); -} - -NPError -PluginAsyncSurrogate::NPP_NewStream(NPMIMEType aType, NPStream* aStream, - NPBool aSeekable, uint16_t* aStype) -{ - mPendingNewStreamCalls.AppendElement(PendingNewStreamCall(aType, aStream, - aSeekable)); - if (aStype) { - *aStype = nsPluginStreamListenerPeer::STREAM_TYPE_UNKNOWN; - } - return NPERR_NO_ERROR; -} - -NPError -PluginAsyncSurrogate::NPP_SetWindow(NPWindow* aWindow) -{ - mWindow = aWindow; - mAsyncSetWindow = false; - return NPERR_NO_ERROR; -} - -nsresult -PluginAsyncSurrogate::AsyncSetWindow(NPWindow* aWindow) -{ - mWindow = aWindow; - mAsyncSetWindow = true; - return NS_OK; -} - -void -PluginAsyncSurrogate::NPP_Print(NPPrint* aPrintInfo) -{ - // Do nothing, we've got nothing to print right now -} - -int16_t -PluginAsyncSurrogate::NPP_HandleEvent(void* event) -{ - // Drop the event -- the plugin isn't around to handle it - return false; -} - -int32_t -PluginAsyncSurrogate::NPP_WriteReady(NPStream* aStream) -{ - // We'll tell the browser to retry in a bit. Eventually NPP_WriteReady - // will resolve to the plugin's NPP_WriteReady and this should all just work. - return 0; -} - -NPError -PluginAsyncSurrogate::NPP_DestroyStream(NPStream* aStream, NPReason aReason) -{ - for (uint32_t idx = 0, len = mPendingNewStreamCalls.Length(); idx < len; ++idx) { - PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[idx]; - if (curPendingCall.mStream == aStream) { - mPendingNewStreamCalls.RemoveElementAt(idx); - break; - } - } - return NPERR_NO_ERROR; -} - -/* static */ NPError -PluginAsyncSurrogate::NPP_Destroy(NPP aInstance, NPSavedData** aSave) -{ - PluginAsyncSurrogate* rawSurrogate = Cast(aInstance); - MOZ_ASSERT(rawSurrogate); - PluginModuleParent* module = rawSurrogate->GetParent(); - if (module && !module->IsInitialized()) { - // Take ownership of pdata's surrogate since we're going to release it - RefPtr surrogate(dont_AddRef(rawSurrogate)); - aInstance->pdata = nullptr; - // We haven't actually called NPP_New yet, so we should remove the - // surrogate for this instance. - bool removeOk = module->RemovePendingSurrogate(surrogate); - MOZ_ASSERT(removeOk); - if (!removeOk) { - return NPERR_GENERIC_ERROR; - } - surrogate->mInitCancelled = true; - return NPERR_NO_ERROR; - } - return rawSurrogate->NPP_Destroy(aSave); -} - -/* static */ NPError -PluginAsyncSurrogate::NPP_GetValue(NPP aInstance, NPPVariable aVariable, - void* aRetval) -{ - PluginAsyncSurrogate* surrogate = Cast(aInstance); - MOZ_ASSERT(surrogate); - return surrogate->NPP_GetValue(aVariable, aRetval); -} - -/* static */ NPError -PluginAsyncSurrogate::NPP_SetValue(NPP aInstance, NPNVariable aVariable, - void* aValue) -{ - PluginAsyncSurrogate* surrogate = Cast(aInstance); - MOZ_ASSERT(surrogate); - return surrogate->NPP_SetValue(aVariable, aValue); -} - -/* static */ NPError -PluginAsyncSurrogate::NPP_NewStream(NPP aInstance, NPMIMEType aType, - NPStream* aStream, NPBool aSeekable, - uint16_t* aStype) -{ - PluginAsyncSurrogate* surrogate = Cast(aInstance); - MOZ_ASSERT(surrogate); - return surrogate->NPP_NewStream(aType, aStream, aSeekable, aStype); -} - -/* static */ NPError -PluginAsyncSurrogate::NPP_SetWindow(NPP aInstance, NPWindow* aWindow) -{ - PluginAsyncSurrogate* surrogate = Cast(aInstance); - MOZ_ASSERT(surrogate); - return surrogate->NPP_SetWindow(aWindow); -} - -/* static */ void -PluginAsyncSurrogate::NPP_Print(NPP aInstance, NPPrint* aPrintInfo) -{ - PluginAsyncSurrogate* surrogate = Cast(aInstance); - MOZ_ASSERT(surrogate); - surrogate->NPP_Print(aPrintInfo); -} - -/* static */ int16_t -PluginAsyncSurrogate::NPP_HandleEvent(NPP aInstance, void* aEvent) -{ - PluginAsyncSurrogate* surrogate = Cast(aInstance); - MOZ_ASSERT(surrogate); - return surrogate->NPP_HandleEvent(aEvent); -} - -/* static */ int32_t -PluginAsyncSurrogate::NPP_WriteReady(NPP aInstance, NPStream* aStream) -{ - PluginAsyncSurrogate* surrogate = Cast(aInstance); - MOZ_ASSERT(surrogate); - return surrogate->NPP_WriteReady(aStream); -} - -/* static */ NPError -PluginAsyncSurrogate::NPP_DestroyStream(NPP aInstance, - NPStream* aStream, - NPReason aReason) -{ - PluginAsyncSurrogate* surrogate = Cast(aInstance); - MOZ_ASSERT(surrogate); - return surrogate->NPP_DestroyStream(aStream, aReason); -} - -PluginAsyncSurrogate::PendingNewStreamCall::PendingNewStreamCall( - NPMIMEType aType, NPStream* aStream, NPBool aSeekable) - : mType(NullableString(aType)) - , mStream(aStream) - , mSeekable(aSeekable) -{ -} - -/* static */ nsNPAPIPluginStreamListener* -PluginAsyncSurrogate::GetStreamListener(NPStream* aStream) -{ - nsNPAPIStreamWrapper* wrapper = - reinterpret_cast(aStream->ndata); - if (!wrapper) { - return nullptr; - } - return wrapper->GetStreamListener(); -} - -void -PluginAsyncSurrogate::DestroyAsyncStream(NPStream* aStream) -{ - MOZ_ASSERT(aStream); - nsNPAPIPluginStreamListener* streamListener = GetStreamListener(aStream); - MOZ_ASSERT(streamListener); - // streamListener was suspended during async init. We must resume the stream - // request prior to calling _destroystream for cleanup to work correctly. - streamListener->ResumeRequest(); - if (!mInstance) { - return; - } - parent::_destroystream(GetNPP(), aStream, NPRES_DONE); -} - -/* static */ bool -PluginAsyncSurrogate::SetStreamType(NPStream* aStream, uint16_t aStreamType) -{ - nsNPAPIPluginStreamListener* streamListener = GetStreamListener(aStream); - if (!streamListener) { - return false; - } - return streamListener->SetStreamType(aStreamType); -} - -void -PluginAsyncSurrogate::OnInstanceCreated(PluginInstanceParent* aInstance) -{ - if (!mDestroyPending) { - // If NPP_Destroy has already been called then these streams have already - // been cleaned up on the browser side and are no longer valid. - for (uint32_t i = 0, len = mPendingNewStreamCalls.Length(); i < len; ++i) { - PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[i]; - uint16_t streamType = NP_NORMAL; - NPError curError = aInstance->NPP_NewStream( - const_cast(NullableStringGet(curPendingCall.mType)), - curPendingCall.mStream, curPendingCall.mSeekable, - &streamType); - if (curError != NPERR_NO_ERROR) { - // If we failed here then the send failed and we need to clean up - DestroyAsyncStream(curPendingCall.mStream); - } - } - } - mPendingNewStreamCalls.Clear(); - mInstantiated = true; -} - -/** - * During asynchronous initialization it might be necessary to wait for the - * plugin to complete its initialization. This typically occurs when the result - * of a plugin call depends on the plugin being fully instantiated. For example, - * if some JS calls into the plugin, the call must be executed synchronously to - * preserve correctness. - * - * This function works by pumping the plugin's IPC channel for events until - * initialization has completed. - */ -bool -PluginAsyncSurrogate::WaitForInit() -{ - if (mInitCancelled) { - return false; - } - if (mAcceptCalls) { - return true; - } - Telemetry::AutoTimer - timer(mParent->GetHistogramKey()); - bool result = false; - MOZ_ASSERT(mParent); - if (mParent->IsChrome()) { - PluginProcessParent* process = static_cast(mParent)->Process(); - MOZ_ASSERT(process); - process->SetCallRunnableImmediately(); - if (!process->WaitUntilConnected()) { - return false; - } - } - if (!mParent->WaitForIPCConnection()) { - return false; - } - if (!mParent->IsChrome()) { - // For e10s content processes, we need to spin the content channel until the - // protocol bridging has occurred. - dom::ContentChild* cp = dom::ContentChild::GetSingleton(); - mozilla::ipc::MessageChannel* contentChannel = cp->GetIPCChannel(); - MOZ_ASSERT(contentChannel); - while (!mParent->mNPInitialized) { - if (mParent->mShutdown) { - // Since we are pumping the message channel for events, it may be - // possible for module initialization to fail during this loop. We must - // return false if this happens or else we'll be permanently stuck. - return false; - } - result = contentChannel->WaitForIncomingMessage(); - if (!result) { - return result; - } - } - } - mozilla::ipc::MessageChannel* channel = mParent->GetIPCChannel(); - MOZ_ASSERT(channel); - while (!mAcceptCalls) { - if (mInitCancelled) { - // Since we are pumping the message channel for events, it may be - // possible for plugin instantiation to fail during this loop. We must - // return false if this happens or else we'll be permanently stuck. - return false; - } - result = channel->WaitForIncomingMessage(); - if (!result) { - break; - } - } - return result; -} - -void -PluginAsyncSurrogate::AsyncCallDeparting() -{ - ++mAsyncCallsInFlight; - if (!mPluginDestructionGuard) { - mPluginDestructionGuard = MakeUnique(this); - } -} - -void -PluginAsyncSurrogate::AsyncCallArriving() -{ - MOZ_ASSERT(mAsyncCallsInFlight > 0); - if (--mAsyncCallsInFlight == 0) { - mPluginDestructionGuard.reset(nullptr); - } -} - -void -PluginAsyncSurrogate::NotifyAsyncInitFailed() -{ - if (!mDestroyPending) { - // Clean up any pending NewStream requests - for (uint32_t i = 0, len = mPendingNewStreamCalls.Length(); i < len; ++i) { - PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[i]; - DestroyAsyncStream(curPendingCall.mStream); - } - } - mPendingNewStreamCalls.Clear(); - - // Make sure that any WaitForInit calls on this surrogate will fail, or else - // we'll be perma-blocked - mInitCancelled = true; - - if (!mInstance) { - return; - } - nsPluginInstanceOwner* owner = mInstance->GetOwner(); - if (owner) { - owner->NotifyHostAsyncInitFailed(); - } -} - -// static -NPObject* -PluginAsyncSurrogate::ScriptableAllocate(NPP aInstance, NPClass* aClass) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aClass != GetClass()) { - NS_ERROR("Huh?! Wrong class!"); - return nullptr; - } - - return new AsyncNPObject(Cast(aInstance)); -} - -// static -void -PluginAsyncSurrogate::ScriptableInvalidate(NPObject* aObject) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return; - } - - AsyncNPObject* object = static_cast(aObject); - if (!object->mSurrogate->WaitForInit()) { - return; - } - NPObject* realObject = object->GetRealObject(); - if (!realObject) { - return; - } - realObject->_class->invalidate(realObject); -} - -// static -void -PluginAsyncSurrogate::ScriptableDeallocate(NPObject* aObject) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return; - } - - AsyncNPObject* object = static_cast(aObject); - delete object; -} - -// static -bool -PluginAsyncSurrogate::ScriptableHasMethod(NPObject* aObject, - NPIdentifier aName) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return false; - } - - RecursionGuard guard; - if (guard.IsRecursive()) { - return false; - } - - AsyncNPObject* object = static_cast(aObject); - MOZ_ASSERT(object); - bool checkPluginObject = !object->mSurrogate->mInstantiated && - !object->mSurrogate->mAcceptCalls; - - if (!object->mSurrogate->WaitForInit()) { - return false; - } - NPObject* realObject = object->GetRealObject(); - if (!realObject) { - return false; - } - bool result = realObject->_class->hasMethod(realObject, aName); - if (!result && checkPluginObject) { - // We may be calling into this object because properties in the WebIDL - // object hadn't been set yet. Now that we're further along in - // initialization, we should try again. - const NPNetscapeFuncs* npn = object->mSurrogate->mParent->GetNetscapeFuncs(); - NPObject* pluginObject = nullptr; - NPError nperror = npn->getvalue(object->mSurrogate->GetNPP(), - NPNVPluginElementNPObject, - (void*)&pluginObject); - if (nperror == NPERR_NO_ERROR) { - NPPAutoPusher nppPusher(object->mSurrogate->GetNPP()); - result = pluginObject->_class->hasMethod(pluginObject, aName); - npn->releaseobject(pluginObject); - NPUTF8* idstr = npn->utf8fromidentifier(aName); - npn->memfree(idstr); - } - } - return result; -} - -bool -PluginAsyncSurrogate::GetPropertyHelper(NPObject* aObject, NPIdentifier aName, - bool* aHasProperty, bool* aHasMethod, - NPVariant* aResult) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - - if (!aObject) { - return false; - } - - RecursionGuard guard; - if (guard.IsRecursive()) { - return false; - } - - if (!WaitForInit()) { - return false; - } - - AsyncNPObject* object = static_cast(aObject); - NPObject* realObject = object->GetRealObject(); - if (!realObject) { - return false; - } - if (realObject->_class != PluginScriptableObjectParent::GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return false; - } - - PluginScriptableObjectParent* actor = - static_cast(realObject)->parent; - if (!actor) { - return false; - } - bool success = actor->GetPropertyHelper(aName, aHasProperty, aHasMethod, aResult); - if (!success) { - const NPNetscapeFuncs* npn = mParent->GetNetscapeFuncs(); - NPObject* pluginObject = nullptr; - NPError nperror = npn->getvalue(GetNPP(), NPNVPluginElementNPObject, - (void*)&pluginObject); - if (nperror == NPERR_NO_ERROR) { - NPPAutoPusher nppPusher(GetNPP()); - bool hasProperty = nsJSObjWrapper::HasOwnProperty(pluginObject, aName); - NPUTF8* idstr = npn->utf8fromidentifier(aName); - npn->memfree(idstr); - bool hasMethod = false; - if (hasProperty) { - hasMethod = pluginObject->_class->hasMethod(pluginObject, aName); - success = pluginObject->_class->getProperty(pluginObject, aName, aResult); - idstr = npn->utf8fromidentifier(aName); - npn->memfree(idstr); - } - *aHasProperty = hasProperty; - *aHasMethod = hasMethod; - npn->releaseobject(pluginObject); - } - } - return success; -} - -// static -bool -PluginAsyncSurrogate::ScriptableInvoke(NPObject* aObject, - NPIdentifier aName, - const NPVariant* aArgs, - uint32_t aArgCount, - NPVariant* aResult) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return false; - } - - AsyncNPObject* object = static_cast(aObject); - if (!object->mSurrogate->WaitForInit()) { - return false; - } - NPObject* realObject = object->GetRealObject(); - if (!realObject) { - return false; - } - return realObject->_class->invoke(realObject, aName, aArgs, aArgCount, aResult); -} - -// static -bool -PluginAsyncSurrogate::ScriptableInvokeDefault(NPObject* aObject, - const NPVariant* aArgs, - uint32_t aArgCount, - NPVariant* aResult) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return false; - } - - AsyncNPObject* object = static_cast(aObject); - if (!object->mSurrogate->WaitForInit()) { - return false; - } - NPObject* realObject = object->GetRealObject(); - if (!realObject) { - return false; - } - return realObject->_class->invokeDefault(realObject, aArgs, aArgCount, aResult); -} - -// static -bool -PluginAsyncSurrogate::ScriptableHasProperty(NPObject* aObject, - NPIdentifier aName) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return false; - } - - RecursionGuard guard; - if (guard.IsRecursive()) { - return false; - } - - AsyncNPObject* object = static_cast(aObject); - MOZ_ASSERT(object); - bool checkPluginObject = !object->mSurrogate->mInstantiated && - !object->mSurrogate->mAcceptCalls; - - if (!object->mSurrogate->WaitForInit()) { - return false; - } - NPObject* realObject = object->GetRealObject(); - if (!realObject) { - return false; - } - bool result = realObject->_class->hasProperty(realObject, aName); - const NPNetscapeFuncs* npn = object->mSurrogate->mParent->GetNetscapeFuncs(); - NPUTF8* idstr = npn->utf8fromidentifier(aName); - npn->memfree(idstr); - if (!result && checkPluginObject) { - // We may be calling into this object because properties in the WebIDL - // object hadn't been set yet. Now that we're further along in - // initialization, we should try again. - NPObject* pluginObject = nullptr; - NPError nperror = npn->getvalue(object->mSurrogate->GetNPP(), - NPNVPluginElementNPObject, - (void*)&pluginObject); - if (nperror == NPERR_NO_ERROR) { - NPPAutoPusher nppPusher(object->mSurrogate->GetNPP()); - result = nsJSObjWrapper::HasOwnProperty(pluginObject, aName); - npn->releaseobject(pluginObject); - idstr = npn->utf8fromidentifier(aName); - npn->memfree(idstr); - } - } - return result; -} - -// static -bool -PluginAsyncSurrogate::ScriptableGetProperty(NPObject* aObject, - NPIdentifier aName, - NPVariant* aResult) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - // See GetPropertyHelper below. - NS_NOTREACHED("Shouldn't ever call this directly!"); - return false; -} - -// static -bool -PluginAsyncSurrogate::ScriptableSetProperty(NPObject* aObject, - NPIdentifier aName, - const NPVariant* aValue) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return false; - } - - AsyncNPObject* object = static_cast(aObject); - if (!object->mSurrogate->WaitForInit()) { - return false; - } - NPObject* realObject = object->GetRealObject(); - if (!realObject) { - return false; - } - return realObject->_class->setProperty(realObject, aName, aValue); -} - -// static -bool -PluginAsyncSurrogate::ScriptableRemoveProperty(NPObject* aObject, - NPIdentifier aName) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return false; - } - - AsyncNPObject* object = static_cast(aObject); - if (!object->mSurrogate->WaitForInit()) { - return false; - } - NPObject* realObject = object->GetRealObject(); - if (!realObject) { - return false; - } - return realObject->_class->removeProperty(realObject, aName); -} - -// static -bool -PluginAsyncSurrogate::ScriptableEnumerate(NPObject* aObject, - NPIdentifier** aIdentifiers, - uint32_t* aCount) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return false; - } - - AsyncNPObject* object = static_cast(aObject); - if (!object->mSurrogate->WaitForInit()) { - return false; - } - NPObject* realObject = object->GetRealObject(); - if (!realObject) { - return false; - } - return realObject->_class->enumerate(realObject, aIdentifiers, aCount); -} - -// static -bool -PluginAsyncSurrogate::ScriptableConstruct(NPObject* aObject, - const NPVariant* aArgs, - uint32_t aArgCount, - NPVariant* aResult) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return false; - } - - AsyncNPObject* object = static_cast(aObject); - if (!object->mSurrogate->WaitForInit()) { - return false; - } - NPObject* realObject = object->GetRealObject(); - if (!realObject) { - return false; - } - return realObject->_class->construct(realObject, aArgs, aArgCount, aResult); -} - -const NPClass PluginAsyncSurrogate::sNPClass = { - NP_CLASS_STRUCT_VERSION, - PluginAsyncSurrogate::ScriptableAllocate, - PluginAsyncSurrogate::ScriptableDeallocate, - PluginAsyncSurrogate::ScriptableInvalidate, - PluginAsyncSurrogate::ScriptableHasMethod, - PluginAsyncSurrogate::ScriptableInvoke, - PluginAsyncSurrogate::ScriptableInvokeDefault, - PluginAsyncSurrogate::ScriptableHasProperty, - PluginAsyncSurrogate::ScriptableGetProperty, - PluginAsyncSurrogate::ScriptableSetProperty, - PluginAsyncSurrogate::ScriptableRemoveProperty, - PluginAsyncSurrogate::ScriptableEnumerate, - PluginAsyncSurrogate::ScriptableConstruct -}; - -PushSurrogateAcceptCalls::PushSurrogateAcceptCalls(PluginInstanceParent* aInstance) - : mSurrogate(nullptr) - , mPrevAcceptCallsState(false) -{ - MOZ_ASSERT(aInstance); - mSurrogate = aInstance->GetAsyncSurrogate(); - if (mSurrogate) { - mPrevAcceptCallsState = mSurrogate->SetAcceptingCalls(true); - } -} - -PushSurrogateAcceptCalls::~PushSurrogateAcceptCalls() -{ - if (mSurrogate) { - mSurrogate->SetAcceptingCalls(mPrevAcceptCallsState); - } -} - -} // namespace plugins -} // namespace mozilla diff --git a/dom/plugins/ipc/PluginAsyncSurrogate.h b/dom/plugins/ipc/PluginAsyncSurrogate.h deleted file mode 100644 index ef278cdb2257..000000000000 --- a/dom/plugins/ipc/PluginAsyncSurrogate.h +++ /dev/null @@ -1,187 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef dom_plugins_ipc_PluginAsyncSurrogate_h -#define dom_plugins_ipc_PluginAsyncSurrogate_h - -#include "mozilla/UniquePtr.h" -#include "npapi.h" -#include "npfunctions.h" -#include "npruntime.h" -#include "nsISupportsImpl.h" -#include "nsPluginHost.h" -#include "nsString.h" -#include "nsTArray.h" -#include "PluginDataResolver.h" - -namespace mozilla { -namespace plugins { - -struct ParentNPObject; -class PluginInstanceParent; -class PluginModuleParent; - -class PluginAsyncSurrogate : public PluginDataResolver -{ -public: - NS_INLINE_DECL_REFCOUNTING(PluginAsyncSurrogate) - - bool Init(NPMIMEType aPluginType, NPP aInstance, - int16_t aArgc, char* aArgn[], char* aArgv[]); - nsresult NPP_New(NPError* aError); - NPError NPP_Destroy(NPSavedData** aSave); - NPError NPP_GetValue(NPPVariable aVariable, void* aRetval); - NPError NPP_SetValue(NPNVariable aVariable, void* aValue); - NPError NPP_NewStream(NPMIMEType aType, NPStream* aStream, NPBool aSeekable, - uint16_t* aStype); - NPError NPP_SetWindow(NPWindow* aWindow); - nsresult AsyncSetWindow(NPWindow* aWindow); - void NPP_Print(NPPrint* aPrintInfo); - int16_t NPP_HandleEvent(void* aEvent); - int32_t NPP_WriteReady(NPStream* aStream); - NPError NPP_DestroyStream(NPStream* aStream, NPReason aReason); - void OnInstanceCreated(PluginInstanceParent* aInstance); - static bool Create(PluginModuleParent* aParent, NPMIMEType aPluginType, - NPP aInstance, int16_t aArgc, - char* aArgn[], char* aArgv[]); - static const NPClass* GetClass() { return &sNPClass; } - static void NP_GetEntryPoints(NPPluginFuncs* aFuncs); - static PluginAsyncSurrogate* Cast(NPP aInstance); - static void NotifyDestroyPending(NPP aInstance); - void NotifyDestroyPending(); - - virtual PluginAsyncSurrogate* - GetAsyncSurrogate() { return this; } - - virtual PluginInstanceParent* - GetInstance() { return nullptr; } - - NPP GetNPP(); - - bool GetPropertyHelper(NPObject* aObject, NPIdentifier aName, - bool* aHasProperty, bool* aHasMethod, - NPVariant* aResult); - - PluginModuleParent* GetParent() { return mParent; } - - bool IsDestroyPending() const { return mDestroyPending; } - - bool SetAcceptingCalls(bool aAccept) - { - bool prevState = mAcceptCalls; - if (mInstantiated) { - aAccept = true; - } - mAcceptCalls = aAccept; - return prevState; - } - - void AsyncCallDeparting(); - void AsyncCallArriving(); - - void NotifyAsyncInitFailed(); - void DestroyAsyncStream(NPStream* aStream); - -private: - explicit PluginAsyncSurrogate(PluginModuleParent* aParent); - virtual ~PluginAsyncSurrogate(); - - bool WaitForInit(); - - static bool SetStreamType(NPStream* aStream, uint16_t aStreamType); - - static NPError NPP_Destroy(NPP aInstance, NPSavedData** aSave); - static NPError NPP_GetValue(NPP aInstance, NPPVariable aVariable, void* aRetval); - static NPError NPP_SetValue(NPP aInstance, NPNVariable aVariable, void* aValue); - static NPError NPP_NewStream(NPP aInstance, NPMIMEType aType, NPStream* aStream, - NPBool aSeekable, uint16_t* aStype); - static NPError NPP_SetWindow(NPP aInstance, NPWindow* aWindow); - static void NPP_Print(NPP aInstance, NPPrint* aPrintInfo); - static int16_t NPP_HandleEvent(NPP aInstance, void* aEvent); - static int32_t NPP_WriteReady(NPP aInstance, NPStream* aStream); - static NPError NPP_DestroyStream(NPP aInstance, NPStream* aStream, - NPReason aReason); - - static NPObject* ScriptableAllocate(NPP aInstance, NPClass* aClass); - static void ScriptableInvalidate(NPObject* aObject); - static void ScriptableDeallocate(NPObject* aObject); - static bool ScriptableHasMethod(NPObject* aObject, NPIdentifier aName); - static bool ScriptableInvoke(NPObject* aObject, NPIdentifier aName, - const NPVariant* aArgs, uint32_t aArgCount, - NPVariant* aResult); - static bool ScriptableInvokeDefault(NPObject* aObject, const NPVariant* aArgs, - uint32_t aArgCount, NPVariant* aResult); - static bool ScriptableHasProperty(NPObject* aObject, NPIdentifier aName); - static bool ScriptableGetProperty(NPObject* aObject, NPIdentifier aName, - NPVariant* aResult); - static bool ScriptableSetProperty(NPObject* aObject, NPIdentifier aName, - const NPVariant* aValue); - static bool ScriptableRemoveProperty(NPObject* aObject, NPIdentifier aName); - static bool ScriptableEnumerate(NPObject* aObject, NPIdentifier** aIdentifiers, - uint32_t* aCount); - static bool ScriptableConstruct(NPObject* aObject, const NPVariant* aArgs, - uint32_t aArgCount, NPVariant* aResult); - static nsNPAPIPluginStreamListener* GetStreamListener(NPStream* aStream); - -private: - struct PendingNewStreamCall - { - PendingNewStreamCall(NPMIMEType aType, NPStream* aStream, NPBool aSeekable); - ~PendingNewStreamCall() {} - nsCString mType; - NPStream* mStream; - NPBool mSeekable; - }; - -private: - PluginModuleParent* mParent; - // These values are used to construct the plugin instance - nsCString mMimeType; - mozilla::WeakPtr mInstance; - InfallibleTArray mNames; - InfallibleTArray mValues; - // This is safe to store as a pointer because the spec says it will remain - // valid until destruction or a subsequent NPP_SetWindow call. - NPWindow* mWindow; - nsTArray mPendingNewStreamCalls; - UniquePtr mPluginDestructionGuard; - - bool mAcceptCalls; - bool mInstantiated; - bool mAsyncSetWindow; - bool mInitCancelled; - bool mDestroyPending; - int32_t mAsyncCallsInFlight; - - static const NPClass sNPClass; -}; - -struct AsyncNPObject : NPObject -{ - explicit AsyncNPObject(PluginAsyncSurrogate* aSurrogate); - ~AsyncNPObject(); - - NPObject* GetRealObject(); - - RefPtr mSurrogate; - ParentNPObject* mRealObject; -}; - -class MOZ_STACK_CLASS PushSurrogateAcceptCalls -{ -public: - explicit PushSurrogateAcceptCalls(PluginInstanceParent* aInstance); - ~PushSurrogateAcceptCalls(); - -private: - PluginAsyncSurrogate* mSurrogate; - bool mPrevAcceptCallsState; -}; - -} // namespace plugins -} // namespace mozilla - -#endif // dom_plugins_ipc_PluginAsyncSurrogate_h diff --git a/dom/plugins/ipc/PluginDataResolver.h b/dom/plugins/ipc/PluginDataResolver.h deleted file mode 100644 index 8371c4df7456..000000000000 --- a/dom/plugins/ipc/PluginDataResolver.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef dom_plugins_ipc_PluginDataResolver_h -#define dom_plugins_ipc_PluginDataResolver_h - -namespace mozilla { -namespace plugins { - -class PluginAsyncSurrogate; -class PluginInstanceParent; - -class PluginDataResolver -{ -public: - virtual PluginAsyncSurrogate* GetAsyncSurrogate() = 0; - virtual PluginInstanceParent* GetInstance() = 0; -}; - -} // namespace plugins -} // namespace mozilla - -#endif // dom_plugins_ipc_PluginDataResolver_h diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp index 9d55fed865d6..ac1024b160d0 100644 --- a/dom/plugins/ipc/PluginInstanceParent.cpp +++ b/dom/plugins/ipc/PluginInstanceParent.cpp @@ -12,7 +12,6 @@ #include "mozilla/Telemetry.h" #include "PluginInstanceParent.h" #include "BrowserStreamParent.h" -#include "PluginAsyncSurrogate.h" #include "PluginBackgroundDestroyer.h" #include "PluginModuleParent.h" #include "PluginStreamParent.h" @@ -115,7 +114,6 @@ PluginInstanceParent::PluginInstanceParent(PluginModuleParent* parent, const nsCString& aMimeType, const NPNetscapeFuncs* npniface) : mParent(parent) - , mSurrogate(PluginAsyncSurrogate::Cast(npp)) , mNPP(npp) , mNPNIface(npniface) , mWindowType(NPWindowTypeWindow) @@ -1222,12 +1220,6 @@ PluginInstanceParent::GetScrollCaptureContainer(ImageContainer** aContainer) } #endif // XP_WIN -PluginAsyncSurrogate* -PluginInstanceParent::GetAsyncSurrogate() -{ - return mSurrogate; -} - bool PluginInstanceParent::CreateBackground(const nsIntSize& aSize) { @@ -2288,28 +2280,21 @@ PluginInstanceParent::AnswerPluginFocusChange(const bool& gotFocus) } PluginInstanceParent* -PluginInstanceParent::Cast(NPP aInstance, PluginAsyncSurrogate** aSurrogate) +PluginInstanceParent::Cast(NPP aInstance) { - PluginDataResolver* resolver = - static_cast(aInstance->pdata); + auto ip = static_cast(aInstance->pdata); // If the plugin crashed and the PluginInstanceParent was deleted, // aInstance->pdata will be nullptr. - if (!resolver) { + if (!ip) { return nullptr; } - PluginInstanceParent* instancePtr = resolver->GetInstance(); - - if (instancePtr && aInstance != instancePtr->mNPP) { + if (aInstance != ip->mNPP) { MOZ_CRASH("Corrupted plugin data."); } - if (aSurrogate) { - *aSurrogate = resolver->GetAsyncSurrogate(); - } - - return instancePtr; + return ip; } mozilla::ipc::IPCResult diff --git a/dom/plugins/ipc/PluginInstanceParent.h b/dom/plugins/ipc/PluginInstanceParent.h index c242fafd9525..db26c3bc339a 100644 --- a/dom/plugins/ipc/PluginInstanceParent.h +++ b/dom/plugins/ipc/PluginInstanceParent.h @@ -21,7 +21,6 @@ #include "nsDataHashtable.h" #include "nsHashKeys.h" #include "nsRect.h" -#include "PluginDataResolver.h" #include "mozilla/Unused.h" #include "mozilla/EventForwards.h" @@ -43,7 +42,6 @@ class PluginModuleParent; class D3D11SurfaceHolder; class PluginInstanceParent : public PPluginInstanceParent - , public PluginDataResolver { friend class PluginModuleParent; friend class BrowserStreamParent; @@ -318,12 +316,7 @@ public: bool IsUsingDirectDrawing(); - virtual PluginAsyncSurrogate* GetAsyncSurrogate() override; - - virtual PluginInstanceParent* GetInstance() override { return this; } - - static PluginInstanceParent* Cast(NPP instance, - PluginAsyncSurrogate** aSurrogate = nullptr); + static PluginInstanceParent* Cast(NPP instance); // for IME hook virtual mozilla::ipc::IPCResult @@ -373,7 +366,6 @@ private: private: PluginModuleParent* mParent; - RefPtr mSurrogate; NPP mNPP; const NPNetscapeFuncs* mNPNIface; nsCString mSrcAttribute; diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index 940e8f82fb12..de97daa75b49 100644 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -14,7 +14,6 @@ #include "mozilla/ipc/MessageChannel.h" #include "mozilla/ipc/ProtocolUtils.h" #include "mozilla/plugins/BrowserStreamParent.h" -#include "mozilla/plugins/PluginAsyncSurrogate.h" #include "mozilla/plugins/PluginBridge.h" #include "mozilla/plugins/PluginInstanceParent.h" #include "mozilla/Preferences.h" @@ -2273,14 +2272,6 @@ PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) #endif -bool -PluginModuleParent::RemovePendingSurrogate( - const RefPtr& aSurrogate) -{ - // XXX: this function will be removed soon. - MOZ_CRASH(); -} - nsresult PluginModuleParent::NP_Shutdown(NPError* error) { @@ -2544,7 +2535,7 @@ PluginModuleParent::NPP_NewInternal(NPMIMEType pluginType, NPP instance, #endif } - instance->pdata = static_cast(parentInstance); + instance->pdata = parentInstance; // Any IPC messages for the PluginInstance actor should be dispatched to the // DocGroup for the plugin's document. diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index 85ae29986473..ec593d7e705b 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -47,7 +47,6 @@ namespace plugins { //----------------------------------------------------------------------------- class BrowserStreamParent; -class PluginAsyncSurrogate; class PluginInstanceParent; #ifdef XP_WIN @@ -97,8 +96,6 @@ public: explicit PluginModuleParent(bool aIsChrome); virtual ~PluginModuleParent(); - bool RemovePendingSurrogate(const RefPtr& aSurrogate); - /** @return whether this modules NP_Initialize has successfully completed executing */ bool IsInitialized() const { return mNPInitialized; } @@ -346,8 +343,6 @@ protected: bool GetPluginDetails(); - friend class mozilla::plugins::PluginAsyncSurrogate; - bool mNPInitialized; bool mIsNPShutdownPending; nsresult mAsyncNewRv; @@ -622,8 +617,6 @@ private: FinishHangUI(); #endif - friend class mozilla::plugins::PluginAsyncSurrogate; - #ifdef MOZ_CRASHREPORTER_INJECTOR friend class mozilla::plugins::FinishInjectorInitTask; diff --git a/dom/plugins/ipc/PluginScriptableObjectParent.cpp b/dom/plugins/ipc/PluginScriptableObjectParent.cpp index c9cc0c19887d..f9b1d09673b0 100644 --- a/dom/plugins/ipc/PluginScriptableObjectParent.cpp +++ b/dom/plugins/ipc/PluginScriptableObjectParent.cpp @@ -12,7 +12,6 @@ #include "mozilla/plugins/PluginTypes.h" #include "mozilla/Unused.h" #include "nsNPAPIPlugin.h" -#include "PluginAsyncSurrogate.h" #include "PluginScriptableObjectUtils.h" using namespace mozilla; @@ -111,7 +110,6 @@ inline void ReleaseVariant(NPVariant& aVariant, PluginInstanceParent* aInstance) { - PushSurrogateAcceptCalls acceptCalls(aInstance); const NPNetscapeFuncs* npn = GetNetscapeFuncs(aInstance); if (npn) { npn->releasevariantvalue(&aVariant); @@ -654,7 +652,6 @@ PluginScriptableObjectParent::CreateProxyObject() NS_ASSERTION(mInstance, "Must have an instance!"); NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!"); - PushSurrogateAcceptCalls acceptCalls(mInstance); const NPNetscapeFuncs* npn = GetNetscapeFuncs(mInstance); NPObject* npobject = npn->createobject(mInstance->GetNPP(), @@ -773,7 +770,6 @@ PluginScriptableObjectParent::AnswerHasMethod(const PluginIdentifier& aId, return IPC_OK(); } - PushSurrogateAcceptCalls acceptCalls(instance); const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_ERROR("No netscape funcs?!"); @@ -814,7 +810,6 @@ PluginScriptableObjectParent::AnswerInvoke(const PluginIdentifier& aId, return IPC_OK(); } - PushSurrogateAcceptCalls acceptCalls(instance); const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_ERROR("No netscape funcs?!"); @@ -904,7 +899,6 @@ PluginScriptableObjectParent::AnswerInvokeDefault(InfallibleTArray&& aA return IPC_OK(); } - PushSurrogateAcceptCalls acceptCalls(instance); const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_ERROR("No netscape funcs?!"); @@ -985,7 +979,6 @@ PluginScriptableObjectParent::AnswerHasProperty(const PluginIdentifier& aId, return IPC_OK(); } - PushSurrogateAcceptCalls acceptCalls(instance); const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_ERROR("No netscape funcs?!"); @@ -1028,7 +1021,6 @@ PluginScriptableObjectParent::AnswerGetParentProperty( return IPC_OK(); } - PushSurrogateAcceptCalls acceptCalls(instance); const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_ERROR("No netscape funcs?!"); @@ -1085,7 +1077,6 @@ PluginScriptableObjectParent::AnswerSetProperty(const PluginIdentifier& aId, return IPC_OK(); } - PushSurrogateAcceptCalls acceptCalls(instance); const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_ERROR("No netscape funcs?!"); @@ -1132,7 +1123,6 @@ PluginScriptableObjectParent::AnswerRemoveProperty(const PluginIdentifier& aId, return IPC_OK(); } - PushSurrogateAcceptCalls acceptCalls(instance); const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_ERROR("No netscape funcs?!"); @@ -1171,7 +1161,6 @@ PluginScriptableObjectParent::AnswerEnumerate(InfallibleTArray return IPC_OK(); } - PushSurrogateAcceptCalls acceptCalls(instance); const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_WARNING("No netscape funcs?!"); @@ -1224,7 +1213,6 @@ PluginScriptableObjectParent::AnswerConstruct(InfallibleTArray&& aArgs, return IPC_OK(); } - PushSurrogateAcceptCalls acceptCalls(instance); const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_ERROR("No netscape funcs?!"); @@ -1317,7 +1305,6 @@ PluginScriptableObjectParent::AnswerNPN_Evaluate(const nsCString& aScript, return IPC_OK(); } - PushSurrogateAcceptCalls acceptCalls(instance); const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_ERROR("No netscape funcs?!"); diff --git a/dom/plugins/ipc/moz.build b/dom/plugins/ipc/moz.build index 5e14d185adf6..7f328fcc8aed 100644 --- a/dom/plugins/ipc/moz.build +++ b/dom/plugins/ipc/moz.build @@ -21,9 +21,7 @@ EXPORTS.mozilla.plugins += [ 'NPEventOSX.h', 'NPEventUnix.h', 'NPEventWindows.h', - 'PluginAsyncSurrogate.h', 'PluginBridge.h', - 'PluginDataResolver.h', 'PluginInstanceChild.h', 'PluginInstanceParent.h', 'PluginMessageUtils.h', @@ -70,7 +68,6 @@ UNIFIED_SOURCES += [ 'BrowserStreamParent.cpp', 'ChildAsyncCall.cpp', 'ChildTimer.cpp', - 'PluginAsyncSurrogate.cpp', 'PluginBackgroundDestroyer.cpp', 'PluginInstanceParent.cpp', 'PluginMessageUtils.cpp', From ce3d58ef651527e66a38caa016c442ba32f7ee4f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:45 +1000 Subject: [PATCH 53/63] Bug 1352575 (part 19) - Remove PluginModuleParent::mNPInitialized. r=jimm. --HG-- extra : rebase_source : 423810d76fa2ea0785daacc549d23e8ab57ab297 --- dom/plugins/ipc/PluginModuleParent.cpp | 3 --- dom/plugins/ipc/PluginModuleParent.h | 4 ---- 2 files changed, 7 deletions(-) diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index de97daa75b49..aabc4ba5fc68 100644 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -612,7 +612,6 @@ PluginModuleParent::PluginModuleParent(bool aIsChrome) , mTaskFactory(this) , mSandboxLevel(0) , mIsFlashPlugin(false) - , mNPInitialized(false) , mIsNPShutdownPending(false) , mAsyncNewRv(NS_ERROR_NOT_INITIALIZED) #ifdef MOZ_CRASHREPORTER @@ -2185,7 +2184,6 @@ PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* SetPluginFuncs(mNPPIface); - mNPInitialized = true; return NS_OK; } @@ -2266,7 +2264,6 @@ PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) return NS_OK; } - mNPInitialized = true; return NS_OK; } diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index ec593d7e705b..bb49453bd6e0 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -96,9 +96,6 @@ public: explicit PluginModuleParent(bool aIsChrome); virtual ~PluginModuleParent(); - /** @return whether this modules NP_Initialize has successfully completed - executing */ - bool IsInitialized() const { return mNPInitialized; } bool IsChrome() const { return mIsChrome; } virtual void SetPlugin(nsNPAPIPlugin* plugin) override @@ -343,7 +340,6 @@ protected: bool GetPluginDetails(); - bool mNPInitialized; bool mIsNPShutdownPending; nsresult mAsyncNewRv; uint32_t mRunID; From 7529d220e052d098bd7ed9bfd4fbb5fd5c89b958 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:45 +1000 Subject: [PATCH 54/63] Bug 1352575 (part 20) - Remove nsPluginInstanceOwner::NotifyHostAsyncInitFailed. r=jimm. --HG-- extra : rebase_source : b57662f4121c469e81318c30e27b06c51334d0b7 --- dom/plugins/base/nsPluginInstanceOwner.cpp | 7 ------- dom/plugins/base/nsPluginInstanceOwner.h | 2 -- 2 files changed, 9 deletions(-) diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index 5c4434d4dd67..f7e65d0e6e2d 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -1668,13 +1668,6 @@ void nsPluginInstanceOwner::ExitFullScreen(jobject view) { #endif -void -nsPluginInstanceOwner::NotifyHostAsyncInitFailed() -{ - nsCOMPtr content = do_QueryReferent(mContent); - content->StopPluginInstance(); -} - nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent) { #ifdef MOZ_WIDGET_ANDROID diff --git a/dom/plugins/base/nsPluginInstanceOwner.h b/dom/plugins/base/nsPluginInstanceOwner.h index d10c9afb73f4..ae26d23e8b2f 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.h +++ b/dom/plugins/base/nsPluginInstanceOwner.h @@ -269,8 +269,6 @@ public: static void ExitFullScreen(jobject view); #endif - void NotifyHostAsyncInitFailed(); - bool GetCompositionString(uint32_t aIndex, nsTArray* aString, int32_t* aLength); bool SetCandidateWindow( From 1fae3c8e42f7382f2aa6b81a6a12ed042641db01 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:45 +1000 Subject: [PATCH 55/63] Bug 1352575 (part 21) - Remove PluginModuleParent::mIsNPShutdownPending. r=jimm. --HG-- extra : rebase_source : a3b748f82f8cc813da3c2329c502619203580b12 --- dom/plugins/ipc/PluginModuleParent.cpp | 1 - dom/plugins/ipc/PluginModuleParent.h | 1 - 2 files changed, 2 deletions(-) diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index aabc4ba5fc68..c92c41046467 100644 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -612,7 +612,6 @@ PluginModuleParent::PluginModuleParent(bool aIsChrome) , mTaskFactory(this) , mSandboxLevel(0) , mIsFlashPlugin(false) - , mIsNPShutdownPending(false) , mAsyncNewRv(NS_ERROR_NOT_INITIALIZED) #ifdef MOZ_CRASHREPORTER , mCrashReporterMutex("PluginModuleChromeParent::mCrashReporterMutex") diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index bb49453bd6e0..027102519560 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -340,7 +340,6 @@ protected: bool GetPluginDetails(); - bool mIsNPShutdownPending; nsresult mAsyncNewRv; uint32_t mRunID; From 3e11c1984e67e441beadfac34242843a283a7805 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:45 +1000 Subject: [PATCH 56/63] Bug 1352575 (part 22) - PluginModuleParent::mAsyncNewRv. r=jimm. --HG-- extra : rebase_source : 54d14cb006fcb4ee559f2d78acb7eabcc3578db0 --- dom/plugins/ipc/PluginModuleParent.cpp | 1 - dom/plugins/ipc/PluginModuleParent.h | 1 - 2 files changed, 2 deletions(-) diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index c92c41046467..437c5cdea777 100644 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -612,7 +612,6 @@ PluginModuleParent::PluginModuleParent(bool aIsChrome) , mTaskFactory(this) , mSandboxLevel(0) , mIsFlashPlugin(false) - , mAsyncNewRv(NS_ERROR_NOT_INITIALIZED) #ifdef MOZ_CRASHREPORTER , mCrashReporterMutex("PluginModuleChromeParent::mCrashReporterMutex") #endif diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index 027102519560..f01362549c0a 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -340,7 +340,6 @@ protected: bool GetPluginDetails(); - nsresult mAsyncNewRv; uint32_t mRunID; RefPtr mTextureAllocatorForDirectBitmap; From 16bed6d6fd6a3c5bc658818d85576145cfebc974 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Apr 2017 16:56:45 +1000 Subject: [PATCH 57/63] Bug 1352575 (part 23) - Remove PluginProcessParent::mRunCompleteTaskImmediately. r=jimm. Because it never gets set true any more. The patch also removes PluginModuleChromeParent::WaitForIPCConnection(). --HG-- extra : rebase_source : c50d3be53e46dc8d10e0060cf6c354fc2daa1321 --- dom/plugins/ipc/PluginModuleParent.cpp | 13 ------------- dom/plugins/ipc/PluginModuleParent.h | 4 ---- dom/plugins/ipc/PluginProcessParent.cpp | 18 +----------------- dom/plugins/ipc/PluginProcessParent.h | 2 -- 4 files changed, 1 insertion(+), 36 deletions(-) diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index 437c5cdea777..7476b798fefd 100644 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -481,7 +481,6 @@ PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId, new PluginModuleChromeParent(aFilePath, aPluginId, aPluginTag->mSandboxLevel)); UniquePtr onLaunchedRunnable(new LaunchedTask(parent)); - parent->mSubprocess->SetCallRunnableImmediately(); TimeStamp launchStart = TimeStamp::Now(); bool launched = parent->mSubprocess->Launch(Move(onLaunchedRunnable), aPluginTag->mSandboxLevel); @@ -561,18 +560,6 @@ PluginModuleChromeParent::OnProcessLaunched(const bool aSucceeded) #endif } -bool -PluginModuleChromeParent::WaitForIPCConnection() -{ - PluginProcessParent* process = Process(); - MOZ_ASSERT(process); - process->SetCallRunnableImmediately(); - if (!process->WaitUntilConnected()) { - return false; - } - return true; -} - bool PluginModuleChromeParent::InitCrashReporter() { diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index f01362549c0a..dadfb8967601 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -115,8 +115,6 @@ public: void ProcessRemoteNativeEventsInInterruptCall() override; - virtual bool WaitForIPCConnection() { return true; } - nsCString GetHistogramKey() const { return mPluginName + mPluginVersion; } @@ -499,8 +497,6 @@ class PluginModuleChromeParent EvaluateHangUIState(const bool aReset); #endif // XP_WIN - virtual bool WaitForIPCConnection() override; - void CachedSettingChanged(); virtual mozilla::ipc::IPCResult diff --git a/dom/plugins/ipc/PluginProcessParent.cpp b/dom/plugins/ipc/PluginProcessParent.cpp index 8460e3424fdd..e55d5378d99c 100644 --- a/dom/plugins/ipc/PluginProcessParent.cpp +++ b/dom/plugins/ipc/PluginProcessParent.cpp @@ -32,7 +32,6 @@ PluginProcessParent::PluginProcessParent(const std::string& aPluginFilePath) : , mPluginFilePath(aPluginFilePath) , mTaskFactory(this) , mMainMsgLoop(MessageLoop::current()) - , mRunCompleteTaskImmediately(false) #ifdef XP_WIN , mChildPid(0) #endif @@ -130,12 +129,6 @@ PluginProcessParent::Delete() &PluginProcessParent::Delete)); } -void -PluginProcessParent::SetCallRunnableImmediately() -{ - mRunCompleteTaskImmediately = true; -} - /** * This function exists so that we may provide an additional level of * indirection between the task being posted to main event loop (a @@ -156,7 +149,7 @@ bool PluginProcessParent::WaitUntilConnected(int32_t aTimeoutMs) { bool result = GeckoChildProcessHost::WaitUntilConnected(aTimeoutMs); - if (mRunCompleteTaskImmediately && mLaunchCompleteTask) { + if (mLaunchCompleteTask) { if (result) { mLaunchCompleteTask->SetLaunchSucceeded(); } @@ -177,21 +170,12 @@ PluginProcessParent::OnChannelConnected(int32_t peer_pid) #endif GeckoChildProcessHost::OnChannelConnected(peer_pid); - if (mLaunchCompleteTask && !mRunCompleteTaskImmediately) { - mLaunchCompleteTask->SetLaunchSucceeded(); - mMainMsgLoop->PostTask(mTaskFactory.NewRunnableMethod( - &PluginProcessParent::RunLaunchCompleteTask)); - } } void PluginProcessParent::OnChannelError() { GeckoChildProcessHost::OnChannelError(); - if (mLaunchCompleteTask && !mRunCompleteTaskImmediately) { - mMainMsgLoop->PostTask(mTaskFactory.NewRunnableMethod( - &PluginProcessParent::RunLaunchCompleteTask)); - } } bool diff --git a/dom/plugins/ipc/PluginProcessParent.h b/dom/plugins/ipc/PluginProcessParent.h index 4f5d73b5ad36..847c856a4499 100644 --- a/dom/plugins/ipc/PluginProcessParent.h +++ b/dom/plugins/ipc/PluginProcessParent.h @@ -68,7 +68,6 @@ public: using mozilla::ipc::GeckoChildProcessHost::GetChannel; - void SetCallRunnableImmediately(); virtual bool WaitUntilConnected(int32_t aTimeoutMs = 0) override; virtual void OnChannelConnected(int32_t peer_pid) override; @@ -85,7 +84,6 @@ private: ipc::TaskFactory mTaskFactory; UniquePtr mLaunchCompleteTask; MessageLoop* mMainMsgLoop; - bool mRunCompleteTaskImmediately; #ifdef XP_WIN typedef nsTHashtable PidSet; // Set of PIDs for all plugin child processes or NULL if empty. From 4a11a3a52d4cde89dc9cf3c2cdd62b95a1aa8ae1 Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Thu, 6 Jul 2017 00:28:07 -0400 Subject: [PATCH 58/63] Bug 1376026 - fix ScaledFontDWrite::InstanceData constructor to be explicit. r=me --- gfx/2d/ScaledFontDWrite.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/2d/ScaledFontDWrite.h b/gfx/2d/ScaledFontDWrite.h index e7866a974fb1..7caffe4cb2ac 100644 --- a/gfx/2d/ScaledFontDWrite.h +++ b/gfx/2d/ScaledFontDWrite.h @@ -90,7 +90,7 @@ private: struct InstanceData { - InstanceData(ScaledFontDWrite* aScaledFont) + explicit InstanceData(ScaledFontDWrite* aScaledFont) : mUseEmbeddedBitmap(aScaledFont->mUseEmbeddedBitmap) , mForceGDIMode(aScaledFont->mForceGDIMode) , mGamma(aScaledFont->mGamma) From 6969a898fdf71a65c224ac93b546d75546e8ac30 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Thu, 6 Jul 2017 08:11:45 +0200 Subject: [PATCH 59/63] Backed out changeset af8c0e8089fc (bug 1376026) --- gfx/2d/ScaledFontDWrite.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/2d/ScaledFontDWrite.h b/gfx/2d/ScaledFontDWrite.h index 7caffe4cb2ac..e7866a974fb1 100644 --- a/gfx/2d/ScaledFontDWrite.h +++ b/gfx/2d/ScaledFontDWrite.h @@ -90,7 +90,7 @@ private: struct InstanceData { - explicit InstanceData(ScaledFontDWrite* aScaledFont) + InstanceData(ScaledFontDWrite* aScaledFont) : mUseEmbeddedBitmap(aScaledFont->mUseEmbeddedBitmap) , mForceGDIMode(aScaledFont->mForceGDIMode) , mGamma(aScaledFont->mGamma) From cd6ff28835ff9b9d8577997b1325d536fc7299f4 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Thu, 6 Jul 2017 08:11:47 +0200 Subject: [PATCH 60/63] Backed out changeset 581652145f1b (bug 1376026) --- gfx/thebes/gfxWindowsPlatform.cpp | 8 ++++---- gfx/thebes/gfxWindowsPlatform.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index 88c844b99659..4d5080f6c8b4 100755 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -355,7 +355,7 @@ gfxWindowsPlatform::InitAcceleration() UpdateRenderMode(); // If we have Skia and we didn't init dwrite already, do it now. - if (!DWriteEnabled() && GetDefaultContentBackend() == BackendType::SKIA) { + if (!DWriteAvailable() && GetDefaultContentBackend() == BackendType::SKIA) { InitDWriteSupport(); } @@ -491,7 +491,7 @@ gfxWindowsPlatform::CreatePlatformFontList() // bug 630201 - older pre-RTM versions of Direct2D/DirectWrite cause odd // crashers so blacklist them altogether - if (IsNotWin7PreRTM() && DWriteEnabled()) { + if (IsNotWin7PreRTM() && DWriteAvailable()) { pfl = new gfxDWriteFontList(); if (NS_SUCCEEDED(pfl->InitFontList())) { return pfl; @@ -1103,7 +1103,7 @@ gfxWindowsPlatform::FontsPrefsChanged(const char *aPref) void gfxWindowsPlatform::SetupClearTypeParams() { - if (DWriteEnabled()) { + if (DWriteAvailable()) { // any missing prefs will default to invalid (-1) and be ignored; // out-of-range values will also be ignored FLOAT gamma = -1.0; @@ -1526,7 +1526,7 @@ gfxWindowsPlatform::InitializeD2D() } // Using Direct2D depends on DWrite support. - if (!DWriteEnabled() && !InitDWriteSupport()) { + if (!DWriteAvailable() && !InitDWriteSupport()) { d2d1.SetFailed(FeatureStatus::Failed, "Failed to initialize DirectWrite support", NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_DWRITE")); return; diff --git a/gfx/thebes/gfxWindowsPlatform.h b/gfx/thebes/gfxWindowsPlatform.h index ded5c8330aa5..12f637842379 100644 --- a/gfx/thebes/gfxWindowsPlatform.h +++ b/gfx/thebes/gfxWindowsPlatform.h @@ -192,7 +192,7 @@ public: void SetupClearTypeParams(); - inline bool DWriteEnabled() const { return !!mozilla::gfx::Factory::GetDWriteFactory(); } + inline bool DWriteAvailable() const { return !!mozilla::gfx::Factory::GetDWriteFactory(); } inline DWRITE_MEASURING_MODE DWriteMeasuringMode() { return mMeasuringMode; } IDWriteRenderingParams *GetRenderingParams(TextRenderingMode aRenderMode) From fbc9f302f1486da758084b0e8a3e0c59fbf3d9ef Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Thu, 6 Jul 2017 08:11:48 +0200 Subject: [PATCH 61/63] Backed out changeset d09fb3a5cedf (bug 1376026) --- gfx/2d/2D.h | 17 ++- gfx/2d/DrawTargetD2D1.cpp | 43 +++++++- gfx/2d/DrawTargetD2D1.h | 2 + gfx/2d/Factory.cpp | 104 +++++++----------- gfx/2d/InlineTranslator.cpp | 15 +++ gfx/2d/InlineTranslator.h | 2 + gfx/2d/NativeFontResourceDWrite.cpp | 5 +- gfx/2d/RecordedEvent.h | 3 +- gfx/2d/RecordedEventImpl.h | 12 +- gfx/2d/ScaledFontDWrite.cpp | 46 ++------ gfx/2d/ScaledFontDWrite.h | 52 +++------ gfx/skia/skia/include/ports/SkTypeface_win.h | 4 +- gfx/skia/skia/src/ports/SkFontHost_win.cpp | 6 +- gfx/skia/skia/src/ports/SkTypeface_win_dw.cpp | 10 +- gfx/skia/skia/src/ports/SkTypeface_win_dw.h | 10 +- gfx/thebes/gfxDWriteCommon.cpp | 2 +- gfx/thebes/gfxDWriteCommon.h | 2 +- gfx/thebes/gfxDWriteFontList.cpp | 10 +- gfx/thebes/gfxDWriteFonts.cpp | 31 ++++-- gfx/thebes/gfxDWriteFonts.h | 3 + gfx/thebes/gfxWindowsPlatform.cpp | 57 ++++++++-- gfx/thebes/gfxWindowsPlatform.h | 4 +- layout/printing/PrintTranslator.cpp | 15 +++ layout/printing/PrintTranslator.h | 2 + 24 files changed, 246 insertions(+), 211 deletions(-) diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h index fb561b752c2d..37f08d5384f2 100644 --- a/gfx/2d/2D.h +++ b/gfx/2d/2D.h @@ -1520,13 +1520,12 @@ public: * * @param aData Pointer to the data * @param aSize Size of the TrueType data - * @param aBackendType Type of the reference DrawTarget the font should be created for. - * @param aFontType Type of NativeFontResource that should be created. + * @param aType Type of NativeFontResource that should be created. * @param aFontContext Optional native font context to be used to create the NativeFontResource. * @return a NativeFontResource of nullptr if failed. */ static already_AddRefed - CreateNativeFontResource(uint8_t *aData, uint32_t aSize, BackendType aBackendType, FontType aFontType, void* aFontContext = nullptr); + CreateNativeFontResource(uint8_t *aData, uint32_t aSize, FontType aType, void* aFontContext = nullptr); /** * This creates an unscaled font of the given type based on font descriptor @@ -1662,13 +1661,16 @@ public: * Returns true on success, or false on failure and leaves the D2D1/Direct3D11 devices unset. */ static bool SetDirect3D11Device(ID3D11Device *aDevice); + static bool SetDWriteFactory(IDWriteFactory *aFactory); static ID3D11Device *GetDirect3D11Device(); static ID2D1Device *GetD2D1Device(); static uint32_t GetD2D1DeviceSeq(); static IDWriteFactory *GetDWriteFactory(); - static IDWriteFactory* EnsureDWriteFactory(); static bool SupportsD2D1(); + static already_AddRefed + CreateDWriteGlyphRenderingOptions(IDWriteRenderingParams *aParams); + static uint64_t GetD2DVRAMUsageDrawTarget(); static uint64_t GetD2DVRAMUsageSourceSurface(); static void D2DCleanup(); @@ -1679,10 +1681,7 @@ public: const RefPtr& aUnscaledFont, Float aSize, bool aUseEmbeddedBitmap, - bool aForceGDIMode, - IDWriteRenderingParams *aParams, - Float aGamma, - Float aContrast); + bool aForceGDIMode); static void UpdateSystemTextQuality(); @@ -1690,8 +1689,6 @@ private: static ID2D1Device *mD2D1Device; static ID3D11Device *mD3D11Device; static IDWriteFactory *mDWriteFactory; - static bool mDWriteFactoryInitialized; - static Mutex* mDWriteFactoryLock; #endif static DrawEventRecorder *mRecorder; diff --git a/gfx/2d/DrawTargetD2D1.cpp b/gfx/2d/DrawTargetD2D1.cpp index d099b652f707..0df50ac8cea4 100644 --- a/gfx/2d/DrawTargetD2D1.cpp +++ b/gfx/2d/DrawTargetD2D1.cpp @@ -17,8 +17,6 @@ #include "Tools.h" #include "nsAppRunner.h" -#include "mozilla/Mutex.h" - using namespace std; // decltype is not usable for overloaded functions. @@ -34,6 +32,7 @@ namespace gfx { uint64_t DrawTargetD2D1::mVRAMUsageDT; uint64_t DrawTargetD2D1::mVRAMUsageSS; +IDWriteFactory *DrawTargetD2D1::mDWriteFactory; ID2D1Factory1* DrawTargetD2D1::mFactory = nullptr; ID2D1Factory1 *D2DFactory1() @@ -609,7 +608,7 @@ DrawTargetD2D1::FillGlyphs(ScaledFont *aFont, const GlyphBuffer &aBuffer, const Pattern &aPattern, const DrawOptions &aOptions, - const GlyphRenderingOptions*) + const GlyphRenderingOptions *aRenderingOptions) { if (aFont->GetType() != FontType::DWRITE) { gfxDebug() << *this << ": Ignoring drawing call for incompatible font."; @@ -618,7 +617,16 @@ DrawTargetD2D1::FillGlyphs(ScaledFont *aFont, ScaledFontDWrite *font = static_cast(aFont); - IDWriteRenderingParams *params = font->mParams; + IDWriteRenderingParams *params = nullptr; + if (aRenderingOptions) { + if (aRenderingOptions->GetType() != FontType::DWRITE) { + gfxDebug() << *this << ": Ignoring incompatible GlyphRenderingOptions."; + // This should never happen. + MOZ_ASSERT(false); + } else { + params = static_cast(aRenderingOptions)->mParams; + } + } AntialiasMode aaMode = font->GetDefaultAAMode(); @@ -1248,6 +1256,33 @@ DrawTargetD2D1::factory() return mFactory; } +IDWriteFactory* +DrawTargetD2D1::GetDWriteFactory() +{ + if (mDWriteFactory) { + return mDWriteFactory; + } + + decltype(DWriteCreateFactory)* createDWriteFactory; + HMODULE dwriteModule = LoadLibraryW(L"dwrite.dll"); + createDWriteFactory = (decltype(DWriteCreateFactory)*) + GetProcAddress(dwriteModule, "DWriteCreateFactory"); + + if (!createDWriteFactory) { + gfxWarning() << "Failed to locate DWriteCreateFactory function."; + return nullptr; + } + + HRESULT hr = createDWriteFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), + reinterpret_cast(&mDWriteFactory)); + + if (FAILED(hr)) { + gfxWarning() << "Failed to create DWrite Factory."; + } + + return mDWriteFactory; +} + void DrawTargetD2D1::CleanupD2D() { diff --git a/gfx/2d/DrawTargetD2D1.h b/gfx/2d/DrawTargetD2D1.h index da6e8f28d52c..2107da2e6b0c 100644 --- a/gfx/2d/DrawTargetD2D1.h +++ b/gfx/2d/DrawTargetD2D1.h @@ -155,6 +155,7 @@ public: static ID2D1Factory1 *factory(); static void CleanupD2D(); + static IDWriteFactory *GetDWriteFactory(); operator std::string() const { std::stringstream stream; @@ -293,6 +294,7 @@ private: bool mDidComplexBlendWithListInList; static ID2D1Factory1 *mFactory; + static IDWriteFactory *mDWriteFactory; // This value is uesed to verify if the DrawTarget is created by a stale device. uint32_t mDeviceSeq; diff --git a/gfx/2d/Factory.cpp b/gfx/2d/Factory.cpp index 6a0941023bd4..bef27f1d9672 100644 --- a/gfx/2d/Factory.cpp +++ b/gfx/2d/Factory.cpp @@ -45,7 +45,6 @@ #include #include "HelpersD2D.h" #include "HelpersWinFonts.h" -#include "mozilla/Mutex.h" #endif #include "DrawTargetDual.h" @@ -204,8 +203,6 @@ static uint32_t mDeviceSeq = 0; ID3D11Device *Factory::mD3D11Device = nullptr; ID2D1Device *Factory::mD2D1Device = nullptr; IDWriteFactory *Factory::mDWriteFactory = nullptr; -bool Factory::mDWriteFactoryInitialized = false; -Mutex* Factory::mDWriteFactoryLock = nullptr; #endif DrawEventRecorder *Factory::mRecorder; @@ -232,10 +229,6 @@ Factory::Init(const Config& aConfig) #ifdef MOZ_ENABLE_FREETYPE mFTLock = new Mutex("Factory::mFTLock"); #endif - -#ifdef WIN32 - mDWriteFactoryLock = new Mutex("Factory::mDWriteFactoryLock"); -#endif } void @@ -254,13 +247,6 @@ Factory::ShutDown() mFTLock = nullptr; } #endif - -#ifdef WIN32 - if (mDWriteFactoryLock) { - delete mDWriteFactoryLock; - mDWriteFactoryLock = nullptr; - } -#endif } bool @@ -567,26 +553,38 @@ Factory::CreateScaledFontForNativeFont(const NativeFont &aNativeFont, } already_AddRefed -Factory::CreateNativeFontResource(uint8_t *aData, uint32_t aSize, BackendType aBackendType, FontType aFontType, void* aFontContext) +Factory::CreateNativeFontResource(uint8_t *aData, uint32_t aSize, FontType aType, void* aFontContext) { - switch (aFontType) { + switch (aType) { #ifdef WIN32 case FontType::DWRITE: { - bool needsCairo = aBackendType == BackendType::CAIRO || - aBackendType == BackendType::SKIA; - return NativeFontResourceDWrite::Create(aData, aSize, needsCairo); + return NativeFontResourceDWrite::Create(aData, aSize, + /* aNeedsCairo = */ false); } - case FontType::GDI: - return NativeFontResourceGDI::Create(aData, aSize); -#elif defined(XP_DARWIN) - case FontType::MAC: - return NativeFontResourceMac::Create(aData, aSize); -#elif defined(MOZ_WIDGET_GTK) - case FontType::FONTCONFIG: - return NativeFontResourceFontconfig::Create(aData, aSize, - static_cast(aFontContext)); #endif + case FontType::CAIRO: +#ifdef USE_SKIA + case FontType::SKIA: +#endif + { +#ifdef WIN32 + if (GetDWriteFactory()) { + return NativeFontResourceDWrite::Create(aData, aSize, + /* aNeedsCairo = */ true); + } else { + return NativeFontResourceGDI::Create(aData, aSize); + } +#elif defined(XP_DARWIN) + return NativeFontResourceMac::Create(aData, aSize); +#elif defined(MOZ_WIDGET_GTK) + return NativeFontResourceFontconfig::Create(aData, aSize, + static_cast(aFontContext)); +#else + gfxWarning() << "Unable to create cairo scaled font from truetype data"; + return nullptr; +#endif + } default: gfxWarning() << "Unable to create requested font resource from truetype data"; return nullptr; @@ -758,6 +756,13 @@ Factory::CreateDrawTargetForD3D11Texture(ID3D11Texture2D *aTexture, SurfaceForma return nullptr; } +bool +Factory::SetDWriteFactory(IDWriteFactory *aFactory) +{ + mDWriteFactory = aFactory; + return true; +} + bool Factory::SetDirect3D11Device(ID3D11Device *aDevice) { @@ -813,43 +818,18 @@ Factory::GetDWriteFactory() return mDWriteFactory; } -IDWriteFactory* -Factory::EnsureDWriteFactory() -{ - MOZ_ASSERT(mDWriteFactoryLock); - MutexAutoLock lock(*mDWriteFactoryLock); - - if (mDWriteFactoryInitialized) { - return mDWriteFactory; - } - - mDWriteFactoryInitialized = true; - - HMODULE dwriteModule = LoadLibraryW(L"dwrite.dll"); - decltype(DWriteCreateFactory)* createDWriteFactory = (decltype(DWriteCreateFactory)*) - GetProcAddress(dwriteModule, "DWriteCreateFactory"); - - if (!createDWriteFactory) { - gfxWarning() << "Failed to locate DWriteCreateFactory function."; - return nullptr; - } - - HRESULT hr = createDWriteFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), - reinterpret_cast(&mDWriteFactory)); - - if (FAILED(hr)) { - gfxWarning() << "Failed to create DWrite Factory."; - } - - return mDWriteFactory; -} - bool Factory::SupportsD2D1() { return !!D2DFactory1(); } +already_AddRefed +Factory::CreateDWriteGlyphRenderingOptions(IDWriteRenderingParams *aParams) +{ + return MakeAndAddRef(aParams); +} + BYTE sSystemTextQuality = CLEARTYPE_QUALITY; void Factory::UpdateSystemTextQuality() @@ -887,14 +867,10 @@ Factory::CreateScaledFontForDWriteFont(IDWriteFontFace* aFontFace, const RefPtr& aUnscaledFont, float aSize, bool aUseEmbeddedBitmap, - bool aForceGDIMode, - IDWriteRenderingParams* aParams, - Float aGamma, - Float aContrast) + bool aForceGDIMode) { return MakeAndAddRef(aFontFace, aUnscaledFont, aSize, aUseEmbeddedBitmap, aForceGDIMode, - aParams, aGamma, aContrast, aStyle); } diff --git a/gfx/2d/InlineTranslator.cpp b/gfx/2d/InlineTranslator.cpp index e3524e6b98e1..ecb051883416 100644 --- a/gfx/2d/InlineTranslator.cpp +++ b/gfx/2d/InlineTranslator.cpp @@ -76,5 +76,20 @@ InlineTranslator::CreateDrawTarget(ReferencePtr aRefPtr, return drawTarget.forget(); } +FontType +InlineTranslator::GetDesiredFontType() +{ + switch (mBaseDT->GetBackendType()) { + case BackendType::DIRECT2D: + return FontType::DWRITE; + case BackendType::CAIRO: + return FontType::CAIRO; + case BackendType::SKIA: + return FontType::SKIA; + default: + return FontType::CAIRO; + } +} + } // namespace gfx } // namespace mozilla diff --git a/gfx/2d/InlineTranslator.h b/gfx/2d/InlineTranslator.h index f218c1c7f99e..b5305f703def 100644 --- a/gfx/2d/InlineTranslator.h +++ b/gfx/2d/InlineTranslator.h @@ -173,6 +173,8 @@ public: mozilla::gfx::DrawTarget* GetReferenceDrawTarget() final { return mBaseDT; } + mozilla::gfx::FontType GetDesiredFontType() final; + void* GetFontContext() final { return mFontContext; } private: diff --git a/gfx/2d/NativeFontResourceDWrite.cpp b/gfx/2d/NativeFontResourceDWrite.cpp index 4b934c23d8aa..02395601b599 100644 --- a/gfx/2d/NativeFontResourceDWrite.cpp +++ b/gfx/2d/NativeFontResourceDWrite.cpp @@ -9,6 +9,7 @@ #include +#include "DrawTargetD2D1.h" #include "Logging.h" #include "mozilla/RefPtr.h" @@ -69,7 +70,7 @@ public: { if (!mInstance) { mInstance = new DWriteFontFileLoader(); - Factory::GetDWriteFactory()-> + DrawTargetD2D1::GetDWriteFactory()-> RegisterFontFileLoader(mInstance); } return mInstance; @@ -221,7 +222,7 @@ already_AddRefed NativeFontResourceDWrite::Create(uint8_t *aFontData, uint32_t aDataLength, bool aNeedsCairo) { - IDWriteFactory *factory = Factory::EnsureDWriteFactory(); + IDWriteFactory *factory = DrawTargetD2D1::GetDWriteFactory(); if (!factory) { gfxWarning() << "Failed to get DWrite Factory."; return nullptr; diff --git a/gfx/2d/RecordedEvent.h b/gfx/2d/RecordedEvent.h index 4058df57a1b7..97708cdc31fa 100644 --- a/gfx/2d/RecordedEvent.h +++ b/gfx/2d/RecordedEvent.h @@ -24,7 +24,7 @@ const uint32_t kMagicInt = 0xc001feed; // loss of backwards compatibility. Old streams will not work in a player // using a newer major revision. And new streams will not work in a player // using an older major revision. -const uint16_t kMajorRevision = 10; +const uint16_t kMajorRevision = 9; // A change in minor revision means additions of new events. New streams will // not play in older players. const uint16_t kMinorRevision = 0; @@ -111,6 +111,7 @@ public: const IntSize &aSize, SurfaceFormat aFormat); virtual DrawTarget *GetReferenceDrawTarget() = 0; + virtual FontType GetDesiredFontType() = 0; virtual void* GetFontContext() { return nullptr; } }; diff --git a/gfx/2d/RecordedEventImpl.h b/gfx/2d/RecordedEventImpl.h index 942731b124d4..2876b94cb7c4 100644 --- a/gfx/2d/RecordedEventImpl.h +++ b/gfx/2d/RecordedEventImpl.h @@ -847,9 +847,7 @@ public: } explicit RecordedFontData(UnscaledFont *aUnscaledFont) - : RecordedEventDerived(FONTDATA) - , mType(aUnscaledFont->GetType()) - , mData(nullptr) + : RecordedEventDerived(FONTDATA), mData(nullptr) { mGetFontFileDataSucceeded = aUnscaledFont->GetFontFileData(&FontDataProc, this); } @@ -873,7 +871,6 @@ public: private: friend class RecordedEvent; - FontType mType; uint8_t* mData; RecordedFontDetails mFontDetails; @@ -2645,8 +2642,8 @@ RecordedFontData::PlayEvent(Translator *aTranslator) const { RefPtr fontResource = Factory::CreateNativeFontResource(mData, mFontDetails.size, - aTranslator->GetReferenceDrawTarget()->GetBackendType(), - mType, aTranslator->GetFontContext()); + aTranslator->GetDesiredFontType(), + aTranslator->GetFontContext()); if (!fontResource) { return false; } @@ -2661,7 +2658,6 @@ RecordedFontData::Record(S &aStream) const { MOZ_ASSERT(mGetFontFileDataSucceeded); - WriteElement(aStream, mType); WriteElement(aStream, mFontDetails.fontDataKey); WriteElement(aStream, mFontDetails.size); aStream.write((const char*)mData, mFontDetails.size); @@ -2700,10 +2696,8 @@ RecordedFontData::GetFontDetails(RecordedFontDetails& fontDetails) inline RecordedFontData::RecordedFontData(istream &aStream) : RecordedEventDerived(FONTDATA) - , mType(FontType::SKIA) , mData(nullptr) { - ReadElement(aStream, mType); ReadElement(aStream, mFontDetails.fontDataKey); ReadElement(aStream, mFontDetails.size); mData = new uint8_t[mFontDetails.size]; diff --git a/gfx/2d/ScaledFontDWrite.cpp b/gfx/2d/ScaledFontDWrite.cpp index ed4b5d59dc6a..05278bd909ff 100644 --- a/gfx/2d/ScaledFontDWrite.cpp +++ b/gfx/2d/ScaledFontDWrite.cpp @@ -3,11 +3,11 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "DrawTargetD2D1.h" #include "ScaledFontDWrite.h" #include "UnscaledFontDWrite.h" #include "PathD2D.h" #include "gfxFont.h" -#include "Logging.h" using namespace std; @@ -108,24 +108,16 @@ ScaledFontDWrite::ScaledFontDWrite(IDWriteFontFace *aFontFace, Float aSize, bool aUseEmbeddedBitmap, bool aForceGDIMode, - IDWriteRenderingParams* aParams, - Float aGamma, - Float aContrast, const gfxFontStyle* aStyle) : ScaledFontBase(aUnscaledFont, aSize) , mFontFace(aFontFace) , mUseEmbeddedBitmap(aUseEmbeddedBitmap) , mForceGDIMode(aForceGDIMode) - , mParams(aParams) - , mGamma(aGamma) - , mContrast(aContrast) { - if (aStyle) { - mStyle = SkFontStyle(aStyle->weight, - DWriteFontStretchFromStretch(aStyle->stretch), - aStyle->style == NS_FONT_STYLE_NORMAL ? - SkFontStyle::kUpright_Slant : SkFontStyle::kItalic_Slant); - } + mStyle = SkFontStyle(aStyle->weight, + DWriteFontStretchFromStretch(aStyle->stretch), + aStyle->style == NS_FONT_STYLE_NORMAL ? + SkFontStyle::kUpright_Slant : SkFontStyle::kItalic_Slant); } already_AddRefed @@ -151,12 +143,12 @@ SkTypeface* ScaledFontDWrite::GetSkTypeface() { if (!mTypeface) { - IDWriteFactory *factory = Factory::GetDWriteFactory(); + IDWriteFactory *factory = DrawTargetD2D1::GetDWriteFactory(); if (!factory) { return nullptr; } - mTypeface = SkCreateTypefaceFromDWriteFont(factory, mFontFace, mStyle, mForceGDIMode, mGamma, mContrast); + mTypeface = SkCreateTypefaceFromDWriteFont(factory, mFontFace, mStyle, mForceGDIMode); } return mTypeface; } @@ -280,34 +272,12 @@ UnscaledFontDWrite::GetFontFileData(FontFileDataOutput aDataCallback, void *aBat return true; } -bool -ScaledFontDWrite::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) -{ - InstanceData instance(this); - aCb(reinterpret_cast(&instance), sizeof(instance), aBaton); - return true; -} - already_AddRefed UnscaledFontDWrite::CreateScaledFont(Float aGlyphSize, const uint8_t* aInstanceData, uint32_t aInstanceDataLength) { - if (aInstanceDataLength < sizeof(ScaledFontDWrite::InstanceData)) { - gfxWarning() << "DWrite scaled font instance data is truncated."; - return nullptr; - } - - const ScaledFontDWrite::InstanceData *instanceData = - reinterpret_cast(aInstanceData); - RefPtr scaledFont = - new ScaledFontDWrite(mFontFace, this, aGlyphSize, - instanceData->mUseEmbeddedBitmap, - instanceData->mForceGDIMode, - nullptr, - instanceData->mGamma, - instanceData->mContrast); - + RefPtr scaledFont = new ScaledFontDWrite(mFontFace, this, aGlyphSize); if (mNeedsCairo && !scaledFont->PopulateCairoScaledFont()) { gfxWarning() << "Unable to create cairo scaled font DWrite font."; return nullptr; diff --git a/gfx/2d/ScaledFontDWrite.h b/gfx/2d/ScaledFontDWrite.h index e7866a974fb1..bce40f5ce77a 100644 --- a/gfx/2d/ScaledFontDWrite.h +++ b/gfx/2d/ScaledFontDWrite.h @@ -15,9 +15,6 @@ struct gfxFontStyle; namespace mozilla { namespace gfx { -class NativeFontResourceDWrite; -class UnscaledFontDWrite; - class ScaledFontDWrite final : public ScaledFontBase { public: @@ -29,8 +26,6 @@ public: , mFontFace(aFont) , mUseEmbeddedBitmap(false) , mForceGDIMode(false) - , mGamma(2.2f) - , mContrast(1.0f) {} ScaledFontDWrite(IDWriteFontFace *aFontFace, @@ -38,10 +33,7 @@ public: Float aSize, bool aUseEmbeddedBitmap, bool aForceGDIMode, - IDWriteRenderingParams *aParams, - Float aContrast, - Float aGamma, - const gfxFontStyle* aStyle = nullptr); + const gfxFontStyle* aStyle); FontType GetType() const override { return FontType::DWRITE; } @@ -54,8 +46,6 @@ public: bool CanSerialize() override { return true; } - bool GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) override; - AntialiasMode GetDefaultAAMode() override; bool UseEmbeddedBitmaps() { return mUseEmbeddedBitmap; } @@ -69,39 +59,29 @@ public: RefPtr mFontFace; bool mUseEmbeddedBitmap; bool mForceGDIMode; - // DrawTargetD2D1 requires the IDWriteRenderingParams, - // but we also separately need to store the gamma and contrast - // since Skia needs to be able to access these without having - // to use the full set of DWrite parameters (which would be - // required to recreate an IDWriteRenderingParams) in a - // DrawTargetRecording playback. - RefPtr mParams; - Float mGamma; - Float mContrast; protected: #ifdef USE_CAIRO_SCALED_FONT cairo_font_face_t* GetCairoFontFace() override; #endif +}; + +class GlyphRenderingOptionsDWrite : public GlyphRenderingOptions +{ +public: + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GlyphRenderingOptionsDWrite, override) + explicit GlyphRenderingOptionsDWrite(IDWriteRenderingParams *aParams) + : mParams(aParams) + { + } + + FontType GetType() const override { return FontType::DWRITE; } private: - friend class NativeFontResourceDWrite; - friend class UnscaledFontDWrite; + friend class DrawTargetD2D; + friend class DrawTargetD2D1; - struct InstanceData - { - InstanceData(ScaledFontDWrite* aScaledFont) - : mUseEmbeddedBitmap(aScaledFont->mUseEmbeddedBitmap) - , mForceGDIMode(aScaledFont->mForceGDIMode) - , mGamma(aScaledFont->mGamma) - , mContrast(aScaledFont->mContrast) - {} - - bool mUseEmbeddedBitmap; - bool mForceGDIMode; - Float mGamma; - Float mContrast; - }; + RefPtr mParams; }; } diff --git a/gfx/skia/skia/include/ports/SkTypeface_win.h b/gfx/skia/skia/include/ports/SkTypeface_win.h index d3b5ffae4496..cb760ae31b58 100644 --- a/gfx/skia/skia/include/ports/SkTypeface_win.h +++ b/gfx/skia/skia/include/ports/SkTypeface_win.h @@ -53,9 +53,7 @@ struct IDWriteFontFallback; SK_API SkTypeface* SkCreateTypefaceFromDWriteFont(IDWriteFactory* aFactory, IDWriteFontFace* aFontFace, SkFontStyle aStyle, - bool aForceGDI, - float aGamma, - float aContrast); + bool aForceGDI); SK_API sk_sp SkFontMgr_New_GDI(); SK_API sk_sp SkFontMgr_New_DirectWrite(IDWriteFactory* factory = NULL, diff --git a/gfx/skia/skia/src/ports/SkFontHost_win.cpp b/gfx/skia/skia/src/ports/SkFontHost_win.cpp index f976e019cb38..b9148027ab7f 100644 --- a/gfx/skia/skia/src/ports/SkFontHost_win.cpp +++ b/gfx/skia/skia/src/ports/SkFontHost_win.cpp @@ -341,11 +341,9 @@ SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT& origLF) { SkTypeface* SkCreateTypefaceFromDWriteFont(IDWriteFactory* aFactory, IDWriteFontFace* aFontFace, SkFontStyle aStyle, - bool aForceGDI, - float aGamma, - float aContrast) + bool aForceGDI) { - return DWriteFontTypeface::Create(aFactory, aFontFace, aStyle, aForceGDI, aGamma, aContrast); + return DWriteFontTypeface::Create(aFactory, aFontFace, aStyle, aForceGDI); } /** diff --git a/gfx/skia/skia/src/ports/SkTypeface_win_dw.cpp b/gfx/skia/skia/src/ports/SkTypeface_win_dw.cpp index b9ea8f8834ac..60ad429dad32 100644 --- a/gfx/skia/skia/src/ports/SkTypeface_win_dw.cpp +++ b/gfx/skia/skia/src/ports/SkTypeface_win_dw.cpp @@ -251,6 +251,10 @@ SkScalerContext* DWriteFontTypeface::onCreateScalerContext(const SkScalerContext return new SkScalerContext_DW(sk_ref_sp(const_cast(this)), effects, desc); } +#ifdef MOZ_SKIA +IDWriteRenderingParams* GetDwriteRenderingParams(bool aGDI); +#endif + void DWriteFontTypeface::onFilterRec(SkScalerContext::Rec* rec) const { if (rec->fFlags & SkScalerContext::kLCD_Vertical_Flag) { rec->fMaskFormat = SkMask::kA8_Format; @@ -284,11 +288,13 @@ void DWriteFontTypeface::onFilterRec(SkScalerContext::Rec* rec) const { } } #elif defined(MOZ_SKIA) - rec->setContrast(fContrast); + IDWriteRenderingParams* params = GetDwriteRenderingParams(ForceGDI()); + SkASSERT(params); + rec->setContrast(params->GetEnhancedContrast()); // GDI gamma should be 2.3 // See the LUT gamma values comment for GDI fonts. - float gamma = ForceGDI() ? 2.3f : fGamma; + float gamma = ForceGDI() ? 2.3f : params->GetGamma(); rec->setDeviceGamma(gamma); rec->setPaintGamma(gamma); #endif diff --git a/gfx/skia/skia/src/ports/SkTypeface_win_dw.h b/gfx/skia/skia/src/ports/SkTypeface_win_dw.h index 831da779e382..035d133be772 100644 --- a/gfx/skia/skia/src/ports/SkTypeface_win_dw.h +++ b/gfx/skia/skia/src/ports/SkTypeface_win_dw.h @@ -53,8 +53,6 @@ private: , fDWriteFont(SkSafeRefComPtr(font)) , fDWriteFontFace(SkRefComPtr(fontFace)) , fForceGDI(false) - , fGamma(2.2f) - , fContrast(1.0f) { if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace1))) { // IUnknown::QueryInterface states that if it fails, punk will be set to nullptr. @@ -83,16 +81,12 @@ public: static DWriteFontTypeface* Create(IDWriteFactory* factory, IDWriteFontFace* fontFace, SkFontStyle aStyle, - bool aForceGDI, - float aGamma, - float aContrast) { + bool aForceGDI) { DWriteFontTypeface* typeface = new DWriteFontTypeface(aStyle, factory, fontFace, nullptr, nullptr, nullptr, nullptr); typeface->fForceGDI = aForceGDI; - typeface->fGamma = aGamma; - typeface->fContrast = aContrast; return typeface; } @@ -145,8 +139,6 @@ protected: private: typedef SkTypeface INHERITED; bool fForceGDI; - float fGamma; - float fContrast; }; #endif diff --git a/gfx/thebes/gfxDWriteCommon.cpp b/gfx/thebes/gfxDWriteCommon.cpp index 7d4db7582da4..3047818bb6b1 100644 --- a/gfx/thebes/gfxDWriteCommon.cpp +++ b/gfx/thebes/gfxDWriteCommon.cpp @@ -158,7 +158,7 @@ gfxDWriteFontFileLoader::CreateCustomFontFile(FallibleTArray& aFontData MOZ_ASSERT(aFontFile); MOZ_ASSERT(aFontFileStream); - IDWriteFactory *factory = mozilla::gfx::Factory::GetDWriteFactory(); + IDWriteFactory *factory = gfxWindowsPlatform::GetPlatform()->GetDWriteFactory(); if (!factory) { gfxCriticalError() << "Failed to get DWrite Factory in CreateCustomFontFile."; return E_FAIL; diff --git a/gfx/thebes/gfxDWriteCommon.h b/gfx/thebes/gfxDWriteCommon.h index 65c2df7bcbe4..a355b59c672a 100644 --- a/gfx/thebes/gfxDWriteCommon.h +++ b/gfx/thebes/gfxDWriteCommon.h @@ -127,7 +127,7 @@ public: { if (!mInstance) { mInstance = new gfxDWriteFontFileLoader(); - mozilla::gfx::Factory::GetDWriteFactory()-> + gfxWindowsPlatform::GetPlatform()->GetDWriteFactory()-> RegisterFontFileLoader(mInstance); } return mInstance; diff --git a/gfx/thebes/gfxDWriteFontList.cpp b/gfx/thebes/gfxDWriteFontList.cpp index 3af5739d8cca..4a5bf38c8d2d 100644 --- a/gfx/thebes/gfxDWriteFontList.cpp +++ b/gfx/thebes/gfxDWriteFontList.cpp @@ -613,7 +613,7 @@ gfxDWriteFontEntry::CreateFontFace(IDWriteFontFace **aFontFace, hr = mFont->CreateFontFace(getter_AddRefs(mFontFace)); } else if (mFontFile) { IDWriteFontFile *fontFile = mFontFile.get(); - hr = Factory::GetDWriteFactory()-> + hr = gfxWindowsPlatform::GetPlatform()->GetDWriteFactory()-> CreateFontFace(mFaceType, 1, &fontFile, @@ -644,7 +644,7 @@ gfxDWriteFontEntry::CreateFontFace(IDWriteFontFace **aFontFace, if (FAILED(mFontFace->GetFiles(&numberOfFiles, files.Elements()))) { return NS_ERROR_FAILURE; } - HRESULT hr = Factory::GetDWriteFactory()-> + HRESULT hr = gfxWindowsPlatform::GetPlatform()->GetDWriteFactory()-> CreateFontFace(mFontFace->GetType(), numberOfFiles, files.Elements(), @@ -883,7 +883,7 @@ gfxDWriteFontList::InitFontListForPlatform() mFontSubstitutes.Clear(); mNonExistingFonts.Clear(); - hr = Factory::GetDWriteFactory()-> + hr = gfxWindowsPlatform::GetPlatform()->GetDWriteFactory()-> GetGdiInterop(getter_AddRefs(mGDIInterop)); if (FAILED(hr)) { Telemetry::Accumulate(Telemetry::DWRITEFONT_INIT_PROBLEM, @@ -894,7 +894,7 @@ gfxDWriteFontList::InitFontListForPlatform() QueryPerformanceCounter(&t2); // base-class/interop initialization RefPtr factory = - Factory::GetDWriteFactory(); + gfxWindowsPlatform::GetPlatform()->GetDWriteFactory(); hr = factory->GetSystemFontCollection(getter_AddRefs(mSystemFonts)); NS_ASSERTION(SUCCEEDED(hr), "GetSystemFontCollection failed!"); @@ -1425,7 +1425,7 @@ gfxDWriteFontList::GlobalFontFallback(const uint32_t aCh, HRESULT hr; RefPtr dwFactory = - Factory::GetDWriteFactory(); + gfxWindowsPlatform::GetPlatform()->GetDWriteFactory(); if (!dwFactory) { return nullptr; } diff --git a/gfx/thebes/gfxDWriteFonts.cpp b/gfx/thebes/gfxDWriteFonts.cpp index 8a83d9fe2ab2..4db079af6927 100644 --- a/gfx/thebes/gfxDWriteFonts.cpp +++ b/gfx/thebes/gfxDWriteFonts.cpp @@ -599,6 +599,19 @@ gfxDWriteFont::GetGlyphWidth(DrawTarget& aDrawTarget, uint16_t aGID) return width; } +already_AddRefed +gfxDWriteFont::GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams) +{ + if (mUseClearType) { + return Factory::CreateDWriteGlyphRenderingOptions( + gfxWindowsPlatform::GetPlatform()->GetRenderingParams(GetForceGDIClassic() ? + gfxWindowsPlatform::TEXT_RENDERING_GDI_CLASSIC : gfxWindowsPlatform::TEXT_RENDERING_NORMAL)); + } else { + return Factory::CreateDWriteGlyphRenderingOptions(gfxWindowsPlatform::GetPlatform()-> + GetRenderingParams(gfxWindowsPlatform::TEXT_RENDERING_NO_CLEARTYPE)); + } +} + bool gfxDWriteFont::GetForceGDIClassic() { @@ -694,17 +707,10 @@ gfxDWriteFont::GetScaledFont(mozilla::gfx::DrawTarget *aTarget) GetUnscaledFont(), GetAdjustedSize(), GetCairoScaledFont()); - } else { + } else if (aTarget->GetBackendType() == BackendType::SKIA) { gfxDWriteFontEntry *fe = static_cast(mFontEntry.get()); bool useEmbeddedBitmap = (fe->IsCJKFont() && HasBitmapStrikeForSize(NS_lround(mAdjustedSize))); - bool forceGDI = GetForceGDIClassic(); - - IDWriteRenderingParams* params = gfxWindowsPlatform::GetPlatform()->GetRenderingParams( - mUseClearType ? - (forceGDI ? - gfxWindowsPlatform::TEXT_RENDERING_GDI_CLASSIC : gfxWindowsPlatform::TEXT_RENDERING_NORMAL) : - gfxWindowsPlatform::TEXT_RENDERING_NO_CLEARTYPE); const gfxFontStyle* fontStyle = GetStyle(); mAzureScaledFont = @@ -712,10 +718,11 @@ gfxDWriteFont::GetScaledFont(mozilla::gfx::DrawTarget *aTarget) GetUnscaledFont(), GetAdjustedSize(), useEmbeddedBitmap, - forceGDI, - params, - params->GetGamma(), - params->GetEnhancedContrast()); + GetForceGDIClassic()); + } else { + mAzureScaledFont = Factory::CreateScaledFontForNativeFont(nativeFont, + GetUnscaledFont(), + GetAdjustedSize()); } mAzureScaledFontIsCairo = wantCairo; diff --git a/gfx/thebes/gfxDWriteFonts.h b/gfx/thebes/gfxDWriteFonts.h index 76b8bba4b523..16d75b84fbee 100644 --- a/gfx/thebes/gfxDWriteFonts.h +++ b/gfx/thebes/gfxDWriteFonts.h @@ -61,6 +61,9 @@ public: virtual int32_t GetGlyphWidth(DrawTarget& aDrawTarget, uint16_t aGID) override; + virtual already_AddRefed + GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams = nullptr) override; + virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf, FontCacheSizes* aSizes) const override; virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf, diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index 4d5080f6c8b4..ebac024fd6bd 100755 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -80,6 +80,14 @@ using namespace mozilla::layers; using namespace mozilla::widget; using namespace mozilla::image; +IDWriteRenderingParams* GetDwriteRenderingParams(bool aGDI) +{ + gfxWindowsPlatform::TextRenderingMode mode = aGDI ? + gfxWindowsPlatform::TEXT_RENDERING_GDI_CLASSIC : + gfxWindowsPlatform::TEXT_RENDERING_NORMAL; + return gfxWindowsPlatform::GetPlatform()->GetRenderingParams(mode); +} + DCFromDrawTarget::DCFromDrawTarget(DrawTarget& aDrawTarget) { mDC = nullptr; @@ -355,7 +363,7 @@ gfxWindowsPlatform::InitAcceleration() UpdateRenderMode(); // If we have Skia and we didn't init dwrite already, do it now. - if (!DWriteAvailable() && GetDefaultContentBackend() == BackendType::SKIA) { + if (!mDWriteFactory && GetDefaultContentBackend() == BackendType::SKIA) { InitDWriteSupport(); } @@ -381,10 +389,26 @@ bool gfxWindowsPlatform::InitDWriteSupport() { mozilla::ScopedGfxFeatureReporter reporter("DWrite"); - if (!Factory::EnsureDWriteFactory()) { + decltype(DWriteCreateFactory)* createDWriteFactory = (decltype(DWriteCreateFactory)*) + GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory"); + if (!createDWriteFactory) { return false; } + // I need a direct pointer to be able to cast to IUnknown**, I also need to + // remember to release this because the nsRefPtr will AddRef it. + RefPtr factory; + HRESULT hr = createDWriteFactory( + DWRITE_FACTORY_TYPE_SHARED, + __uuidof(IDWriteFactory), + (IUnknown **)((IDWriteFactory **)getter_AddRefs(factory))); + if (FAILED(hr) || !factory) { + return false; + } + + mDWriteFactory = factory; + Factory::SetDWriteFactory(mDWriteFactory); + SetupClearTypeParams(); reporter.SetSuccessful(); return true; @@ -491,7 +515,7 @@ gfxWindowsPlatform::CreatePlatformFontList() // bug 630201 - older pre-RTM versions of Direct2D/DirectWrite cause odd // crashers so blacklist them altogether - if (IsNotWin7PreRTM() && DWriteAvailable()) { + if (IsNotWin7PreRTM() && GetDWriteFactory()) { pfl = new gfxDWriteFontList(); if (NS_SUCCEEDED(pfl->InitFontList())) { return pfl; @@ -555,7 +579,22 @@ already_AddRefed gfxWindowsPlatform::GetScaledFontForFont(DrawTarget* aTarget, gfxFont *aFont) { if (aFont->GetType() == gfxFont::FONT_TYPE_DWRITE) { - return aFont->GetScaledFont(aTarget); + gfxDWriteFont *font = static_cast(aFont); + + NativeFont nativeFont; + nativeFont.mType = NativeFontType::DWRITE_FONT_FACE; + nativeFont.mFont = font->GetFontFace(); + + if (aTarget->GetBackendType() == BackendType::CAIRO) { + return Factory::CreateScaledFontWithCairo(nativeFont, + font->GetUnscaledFont(), + font->GetAdjustedSize(), + font->GetCairoScaledFont()); + } + + return Factory::CreateScaledFontForNativeFont(nativeFont, + font->GetUnscaledFont(), + font->GetAdjustedSize()); } NS_ASSERTION(aFont->GetType() == gfxFont::FONT_TYPE_GDI, @@ -1103,7 +1142,7 @@ gfxWindowsPlatform::FontsPrefsChanged(const char *aPref) void gfxWindowsPlatform::SetupClearTypeParams() { - if (DWriteAvailable()) { + if (GetDWriteFactory()) { // any missing prefs will default to invalid (-1) and be ignored; // out-of-range values will also be ignored FLOAT gamma = -1.0; @@ -1158,7 +1197,7 @@ gfxWindowsPlatform::SetupClearTypeParams() } RefPtr defaultRenderingParams; - Factory::GetDWriteFactory()->CreateRenderingParams(getter_AddRefs(defaultRenderingParams)); + GetDWriteFactory()->CreateRenderingParams(getter_AddRefs(defaultRenderingParams)); // For EnhancedContrast, we override the default if the user has not set it // in the registry (by using the ClearType Tuner). if (contrast < 0.0 || contrast > 10.0) { @@ -1214,14 +1253,14 @@ gfxWindowsPlatform::SetupClearTypeParams() mRenderingParams[TEXT_RENDERING_NO_CLEARTYPE] = defaultRenderingParams; - HRESULT hr = Factory::GetDWriteFactory()->CreateCustomRenderingParams( + HRESULT hr = GetDWriteFactory()->CreateCustomRenderingParams( gamma, contrast, level, dwriteGeometry, renderMode, getter_AddRefs(mRenderingParams[TEXT_RENDERING_NORMAL])); if (FAILED(hr) || !mRenderingParams[TEXT_RENDERING_NORMAL]) { mRenderingParams[TEXT_RENDERING_NORMAL] = defaultRenderingParams; } - hr = Factory::GetDWriteFactory()->CreateCustomRenderingParams( + hr = GetDWriteFactory()->CreateCustomRenderingParams( gamma, contrast, level, dwriteGeometry, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC, getter_AddRefs(mRenderingParams[TEXT_RENDERING_GDI_CLASSIC])); @@ -1526,7 +1565,7 @@ gfxWindowsPlatform::InitializeD2D() } // Using Direct2D depends on DWrite support. - if (!DWriteAvailable() && !InitDWriteSupport()) { + if (!mDWriteFactory && !InitDWriteSupport()) { d2d1.SetFailed(FeatureStatus::Failed, "Failed to initialize DirectWrite support", NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_DWRITE")); return; diff --git a/gfx/thebes/gfxWindowsPlatform.h b/gfx/thebes/gfxWindowsPlatform.h index 12f637842379..aaed607b683f 100644 --- a/gfx/thebes/gfxWindowsPlatform.h +++ b/gfx/thebes/gfxWindowsPlatform.h @@ -192,7 +192,8 @@ public: void SetupClearTypeParams(); - inline bool DWriteAvailable() const { return !!mozilla::gfx::Factory::GetDWriteFactory(); } + IDWriteFactory *GetDWriteFactory() { return mDWriteFactory; } + inline bool DWriteEnabled() { return !!mDWriteFactory; } inline DWRITE_MEASURING_MODE DWriteMeasuringMode() { return mMeasuringMode; } IDWriteRenderingParams *GetRenderingParams(TextRenderingMode aRenderMode) @@ -258,6 +259,7 @@ private: void InitializeD2DConfig(); void InitializeDirectDrawConfig(); + RefPtr mDWriteFactory; RefPtr mRenderingParams[TEXT_RENDERING_COUNT]; DWRITE_MEASURING_MODE mMeasuringMode; diff --git a/layout/printing/PrintTranslator.cpp b/layout/printing/PrintTranslator.cpp index a2f1f5cbf7b5..0bda505bae69 100644 --- a/layout/printing/PrintTranslator.cpp +++ b/layout/printing/PrintTranslator.cpp @@ -83,5 +83,20 @@ PrintTranslator::CreateDrawTarget(ReferencePtr aRefPtr, return drawTarget.forget(); } +FontType +PrintTranslator::GetDesiredFontType() +{ + switch (mBaseDT->GetBackendType()) { + case BackendType::DIRECT2D: + return FontType::DWRITE; + case BackendType::CAIRO: + return FontType::CAIRO; + case BackendType::SKIA: + return FontType::SKIA; + default: + return FontType::CAIRO; + } +} + } // namespace layout } // namespace mozilla diff --git a/layout/printing/PrintTranslator.h b/layout/printing/PrintTranslator.h index 4558518ab74e..96f68b78098e 100644 --- a/layout/printing/PrintTranslator.h +++ b/layout/printing/PrintTranslator.h @@ -175,6 +175,8 @@ public: mozilla::gfx::DrawTarget* GetReferenceDrawTarget() final { return mBaseDT; } + mozilla::gfx::FontType GetDesiredFontType() final; + private: RefPtr mDeviceContext; RefPtr mBaseDT; From 7986433daa5d95008473882b7713fc53df6553e2 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Thu, 6 Jul 2017 08:12:22 +0200 Subject: [PATCH 62/63] Backed out changeset a93c71a7ef8b (bug 1376026) for failures like DirectWrite not supported on Windows 2008 or older --- gfx/thebes/gfxWindowsPlatform.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index ebac024fd6bd..46eab05a8b39 100755 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -388,6 +388,12 @@ gfxWindowsPlatform::CanUseHardwareVideoDecoding() bool gfxWindowsPlatform::InitDWriteSupport() { + // DWrite is only supported on Windows 7 with the platform update and higher. + // We check this by seeing if D2D1 support is available. + if (!Factory::SupportsD2D1()) { + return false; + } + mozilla::ScopedGfxFeatureReporter reporter("DWrite"); decltype(DWriteCreateFactory)* createDWriteFactory = (decltype(DWriteCreateFactory)*) GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory"); From e2e23f6bc42848df565426a33e081bbe6d0714d8 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Thu, 6 Jul 2017 01:16:41 -0500 Subject: [PATCH 63/63] Bug 1376722. r=aosmond a=abillings --- image/imgLoader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/image/imgLoader.h b/image/imgLoader.h index cb5a24f1c21d..67e86c52d74e 100644 --- a/image/imgLoader.h +++ b/image/imgLoader.h @@ -541,7 +541,7 @@ public: void AddProxy(imgRequestProxy* aProxy); - NS_DECL_ISUPPORTS + NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER NS_DECL_NSISTREAMLISTENER NS_DECL_NSIREQUESTOBSERVER