Merge inbound to mozilla-central. a=merge

This commit is contained in:
Csoregi Natalia
2018-11-07 11:52:57 +02:00
77 changed files with 1240 additions and 2374 deletions

View File

@@ -10,6 +10,7 @@ skip-if = os == "linux" # Bug 952422
[browser_iframe_gone_mid_download.js] [browser_iframe_gone_mid_download.js]
[browser_indicatorDrop.js] [browser_indicatorDrop.js]
[browser_libraryDrop.js] [browser_libraryDrop.js]
skip-if = (os == 'win' && os_version == '10.0' && ccov) # Bug 1306510
[browser_library_clearall.js] [browser_library_clearall.js]
[browser_downloads_panel_block.js] [browser_downloads_panel_block.js]
skip-if = true # Bug 1352792 skip-if = true # Bug 1352792

View File

@@ -25,8 +25,7 @@ Cu.evalInSandbox(
); );
// Windows in the middleman process are initially set up as about:blank pages. // Windows in the middleman process are initially set up as about:blank pages.
// This method fills them in with a canvas filling the tab, and an overlay that // This method fills them in with a canvas filling the tab.
// can be displayed over that canvas.
function setupContents(window) { function setupContents(window) {
// The middlemanCanvas element fills the tab's contents. // The middlemanCanvas element fills the tab's contents.
const canvas = window.middlemanCanvas = window.document.createElement("canvas"); const canvas = window.middlemanCanvas = window.document.createElement("canvas");
@@ -91,13 +90,7 @@ function UpdateCanvas(buffer, width, height, hadFailure) {
} }
} }
// Entry point for when we need to update the overlay's contents or visibility.
// eslint-disable-next-line no-unused-vars
function UpdateOverlay() {
}
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
var EXPORTED_SYMBOLS = [ var EXPORTED_SYMBOLS = [
"UpdateCanvas", "UpdateCanvas",
"UpdateOverlay",
]; ];

View File

@@ -82,7 +82,7 @@
#include "mozilla/dom/FrameLoaderBinding.h" #include "mozilla/dom/FrameLoaderBinding.h"
#include "mozilla/gfx/CrossProcessPaint.h" #include "mozilla/gfx/CrossProcessPaint.h"
#include "mozilla/jsipc/CrossProcessObjectWrappers.h" #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
#include "mozilla/layout/RenderFrameParent.h" #include "mozilla/layout/RenderFrame.h"
#include "mozilla/ServoCSSParser.h" #include "mozilla/ServoCSSParser.h"
#include "mozilla/ServoStyleSet.h" #include "mozilla/ServoStyleSet.h"
#include "nsGenericHTMLFrameElement.h" #include "nsGenericHTMLFrameElement.h"
@@ -853,12 +853,12 @@ nsFrameLoader::ShowRemoteFrame(const ScreenIntSize& size,
return false; return false;
} }
RenderFrameParent* rfp = GetCurrentRenderFrame(); RenderFrame* rf = GetCurrentRenderFrame();
if (!rfp) { if (!rf) {
return false; return false;
} }
if (!rfp->AttachLayerManager()) { if (!rf->AttachLayerManager()) {
// This is just not going to work. // This is just not going to work.
return false; return false;
} }
@@ -1806,7 +1806,7 @@ nsFrameLoader::SetOwnerContent(Element* aContent)
Unused << NS_WARN_IF(rv.Failed()); Unused << NS_WARN_IF(rv.Failed());
} }
if (RenderFrameParent* rfp = GetCurrentRenderFrame()) { if (RenderFrame* rfp = GetCurrentRenderFrame()) {
rfp->OwnerContentChanged(aContent); rfp->OwnerContentChanged(aContent);
} }
} }
@@ -2616,8 +2616,8 @@ nsFrameLoader::TryRemoteBrowser()
if (!mRemoteBrowser) { if (!mRemoteBrowser) {
return false; return false;
} }
// Now that mRemoteBrowser is set, we can initialize the RenderFrameParent // Now that mRemoteBrowser is set, we can initialize the RenderFrame
mRemoteBrowser->InitRenderFrame(); mRemoteBrowser->InitRendering();
MaybeUpdatePrimaryTabParent(eTabParentChanged); MaybeUpdatePrimaryTabParent(eTabParentChanged);
@@ -2670,7 +2670,7 @@ nsFrameLoader::GetRemoteBrowser() const
return mRemoteBrowser; return mRemoteBrowser;
} }
RenderFrameParent* RenderFrame*
nsFrameLoader::GetCurrentRenderFrame() const nsFrameLoader::GetCurrentRenderFrame() const
{ {
if (mRemoteBrowser) { if (mRemoteBrowser) {
@@ -2941,6 +2941,7 @@ nsFrameLoader::SetRemoteBrowser(nsITabParent* aTabParent)
MaybeUpdatePrimaryTabParent(eTabParentChanged); MaybeUpdatePrimaryTabParent(eTabParentChanged);
ReallyLoadFrameScripts(); ReallyLoadFrameScripts();
InitializeBrowserAPI(); InitializeBrowserAPI();
mRemoteBrowser->InitRendering();
ShowRemoteFrame(ScreenIntSize(0, 0)); ShowRemoteFrame(ScreenIntSize(0, 0));
} }

View File

@@ -65,7 +65,7 @@ class StructuredCloneData;
} // namespace dom } // namespace dom
namespace layout { namespace layout {
class RenderFrameParent; class RenderFrame;
} // namespace layout } // namespace layout
} // namespace mozilla } // namespace mozilla
@@ -86,7 +86,7 @@ class nsFrameLoader final : public nsStubMutationObserver,
friend class AutoResetInFrameSwap; friend class AutoResetInFrameSwap;
typedef mozilla::dom::PBrowserParent PBrowserParent; typedef mozilla::dom::PBrowserParent PBrowserParent;
typedef mozilla::dom::TabParent TabParent; typedef mozilla::dom::TabParent TabParent;
typedef mozilla::layout::RenderFrameParent RenderFrameParent; typedef mozilla::layout::RenderFrame RenderFrame;
public: public:
static nsFrameLoader* Create(mozilla::dom::Element* aOwner, static nsFrameLoader* Create(mozilla::dom::Element* aOwner,
@@ -296,7 +296,7 @@ public:
* returned. (In-process <browser> behaves similarly, and this * returned. (In-process <browser> behaves similarly, and this
* behavior seems desirable.) * behavior seems desirable.)
*/ */
RenderFrameParent* GetCurrentRenderFrame() const; RenderFrame* GetCurrentRenderFrame() const;
mozilla::dom::ChromeMessageSender* GetFrameMessageManager() { return mMessageManager; } mozilla::dom::ChromeMessageSender* GetFrameMessageManager() { return mMessageManager; }

View File

@@ -5478,6 +5478,14 @@ nsGlobalWindowOuter::RevisePopupAbuseLevel(PopupControlState aControl)
abuse = openOverridden; abuse = openOverridden;
} }
// If this popup is allowed, let's block any other for this event, forcing
// openBlocked state.
if ((abuse == openAllowed || abuse == openControlled) &&
StaticPrefs::dom_block_multiple_popups() &&
!PopupWhitelisted()) {
nsContentUtils::PushPopupControlState(openBlocked, true);
}
return abuse; return abuse;
} }
@@ -5514,7 +5522,7 @@ nsGlobalWindowOuter::FireAbuseEvents(const nsAString &aPopupURL,
ios->NewURI(NS_ConvertUTF16toUTF8(aPopupURL), nullptr, baseURL, ios->NewURI(NS_ConvertUTF16toUTF8(aPopupURL), nullptr, baseURL,
getter_AddRefs(popupURI)); getter_AddRefs(popupURI));
// fire an event chock full of informative URIs // fire an event block full of informative URIs
FirePopupBlockedEvent(topDoc, popupURI, aPopupWindowName, FirePopupBlockedEvent(topDoc, popupURI, aPopupWindowName,
aPopupWindowFeatures); aPopupWindowFeatures);
} }

View File

@@ -57,3 +57,5 @@ skip-if = verify
[browser_timeout_throttling_with_audio_playback.js] [browser_timeout_throttling_with_audio_playback.js]
[browser_bug1303838.js] [browser_bug1303838.js]
[browser_inputStream_structuredClone.js] [browser_inputStream_structuredClone.js]
[browser_multiple_popups.js]
support-files = browser_multiple_popups.html

View File

@@ -0,0 +1,54 @@
<!DOCTYPE html>
<html>
<body>
<button onclick="openPopups();" id="openPopups">open popups</button>
<button onclick="openNestedPopups();" id="openNestedPopups">open tested popups</button>
<button onclick="openPopupAndClick();" id="openPopupAndClick">open popups and click</button>
<button onclick="closeAllWindows();" id="closeAllWindows">close all windows</button>
<input type="text" id="input" />
<script>
let windows = [];
function openPopups() {
windows.push(window.open('empty.html', '_blank', 'width=100,height=100'));
windows.push(window.open('empty.html', '_blank', 'width=100,height=100'));
}
function openNestedPopups() {
var w = window.open('empty.html', '_blank', 'width=100,height=100');
windows.push(w);
windows.push(w.open('empty.html', '_blank', 'width=100,height=100'));
}
var recursion = false;
function openPopupAndClick() {
windows.push(window.open('empty.html', '_blank', 'width=100,height=100'));
if (!recursion) {
recursion = true;
document.getElementById("openPopupAndClick").click();
}
}
function closeAllWindows() {
windows.forEach(w => {
try {
w.close();
} catch(e) {}
});
}
if (location.search.includes("openPopups")) {
let id = setInterval(() => {
if (document.getElementById('start')) {
clearInterval(id);
openPopups();
}
}, 500);
}
document.getElementById("input").onmouseup = _ => {
openPopups();
}
</script>
</body>
</html>

View File

@@ -0,0 +1,362 @@
/**
* In this test, we check that the content can't open more than one popup at a
* time (depending on "dom.allow_mulitple_popups" preference value).
*/
const TEST_DOMAIN = "http://example.net";
const TEST_PATH = "/browser/dom/base/test/";
const CHROME_DOMAIN = "chrome://mochitests/content";
requestLongerTimeout(2);
function WindowObserver(count) {
return new Promise(resolve => {
let windowObserver = function(aSubject, aTopic, aData) {
if (aTopic != "domwindowopened") {
return;
}
if (--count == 0) {
Services.ww.unregisterNotification(windowObserver);
resolve();
}
}
Services.ww.registerNotification(windowObserver);
});
}
add_task(async _ => {
info("All opened if the pref is off");
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", false],
["dom.disable_open_during_load", true],
]});
let tab = BrowserTestUtils.addTab(gBrowser, TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html")
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
let obs = new WindowObserver(2);
await BrowserTestUtils.synthesizeMouseAtCenter("#openPopups", {}, tab.linkedBrowser);
await obs;
ok(true, "We had 2 windows.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
BrowserTestUtils.removeTab(tab);
});
add_task(async _ => {
info("2 window.open()s in a click event allowed because whitelisted domain.");
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
]});
const uri = Services.io.newURI(TEST_DOMAIN);
const principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
Services.perms.addFromPrincipal(principal, "popup", Services.perms.ALLOW_ACTION);
let tab = BrowserTestUtils.addTab(gBrowser, TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html")
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
let obs = new WindowObserver(2);
await BrowserTestUtils.synthesizeMouseAtCenter("#openPopups", {}, tab.linkedBrowser);
await obs;
ok(true, "We had 2 windows.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
BrowserTestUtils.removeTab(tab);
await new Promise(aResolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_PERMISSIONS, value => {
Assert.equal(value, 0);
aResolve();
});
});
});
add_task(async _ => {
info("2 window.open()s in a mouseup event allowed because whitelisted domain.");
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
]});
const uri = Services.io.newURI(TEST_DOMAIN);
const principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
Services.perms.addFromPrincipal(principal, "popup", Services.perms.ALLOW_ACTION);
let tab = BrowserTestUtils.addTab(gBrowser, TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html")
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
let obs = new WindowObserver(2);
await BrowserTestUtils.synthesizeMouseAtCenter("#input", { type: "mouseup" }, tab.linkedBrowser);
await obs;
ok(true, "We had 2 windows.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
BrowserTestUtils.removeTab(tab);
await new Promise(aResolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_PERMISSIONS, value => {
Assert.equal(value, 0);
aResolve();
});
});
});
add_task(async _ => {
info("2 window.open()s in a single click event: only the first one is allowed.");
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
]});
let tab = BrowserTestUtils.addTab(gBrowser, TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html")
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
let p = ContentTask.spawn(browser, null, () => {
return new content.Promise(resolve => {
content.addEventListener("DOMPopupBlocked", () => {
ok(true, "The popup has been blocked");
resolve();
}, {once:true});
});
});
let obs = new WindowObserver(1);
await BrowserTestUtils.synthesizeMouseAtCenter("#openPopups", {}, tab.linkedBrowser);
await p;
await obs;
ok(true, "We had only 1 window.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
BrowserTestUtils.removeTab(tab);
});
add_task(async _ => {
info("2 window.open()s in a single mouseup event: only the first one is allowed.");
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
]});
let tab = BrowserTestUtils.addTab(gBrowser, TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html")
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
let p = ContentTask.spawn(browser, null, () => {
return new content.Promise(resolve => {
content.addEventListener("DOMPopupBlocked", () => {
ok(true, "The popup has been blocked");
resolve();
}, {once:true});
});
});
let obs = new WindowObserver(1);
await BrowserTestUtils.synthesizeMouseAtCenter("#input", { type: "mouseup" }, tab.linkedBrowser);
await p;
await obs;
ok(true, "We had only 1 window.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
BrowserTestUtils.removeTab(tab);
});
add_task(async _ => {
info("2 window.open()s by non-event code: no windows allowed.");
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
]});
let tab = BrowserTestUtils.addTab(gBrowser, TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html?openPopups")
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
await ContentTask.spawn(browser, null, () => {
return new content.Promise(resolve => {
let count = 0;
content.addEventListener("DOMPopupBlocked", function cb() {
if (++count == 2) {
content.removeEventListener("DOMPopupBlocked", cb);
ok(true, "The popup has been blocked");
resolve();
}
});
let p = content.document.createElement("p");
p.setAttribute('id', 'start');
content.document.body.appendChild(p);
});
});
ok(true, "We had 0 windows.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
BrowserTestUtils.removeTab(tab);
});
add_task(async _ => {
info("2 window.open()s by non-event code allowed by permission");
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
]});
const uri = Services.io.newURI(TEST_DOMAIN);
const principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
Services.perms.addFromPrincipal(principal, "popup", Services.perms.ALLOW_ACTION);
let obs = new WindowObserver(2);
let tab = BrowserTestUtils.addTab(gBrowser, TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html?openPopups")
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
ok(true, "We had 2 windows.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
BrowserTestUtils.removeTab(tab);
await new Promise(aResolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_PERMISSIONS, value => {
Assert.equal(value, 0);
aResolve();
});
});
});
add_task(async _ => {
info("1 window.open() executing another window.open(): only the first one is allowed.");
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
]});
let tab = BrowserTestUtils.addTab(gBrowser, TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html")
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
// We don't receive DOMPopupBlocked for nested windows. Let's use just the observer.
let obs = new WindowObserver(1);
await BrowserTestUtils.synthesizeMouseAtCenter("#openNestedPopups", {}, tab.linkedBrowser);
await obs;
ok(true, "We had 1 window.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
BrowserTestUtils.removeTab(tab);
});
add_task(async _ => {
info("window.open() and .click() on the element opening the window.");
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
]});
let tab = BrowserTestUtils.addTab(gBrowser, TEST_DOMAIN + TEST_PATH + "browser_multiple_popups.html")
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
let p = ContentTask.spawn(browser, null, () => {
return new content.Promise(resolve => {
content.addEventListener("DOMPopupBlocked", () => {
ok(true, "The popup has been blocked");
resolve();
}, {once:true});
});
});
let obs = new WindowObserver(1);
await BrowserTestUtils.synthesizeMouseAtCenter("#openPopupAndClick", {}, tab.linkedBrowser);
await p;
await obs;
ok(true, "We had only 1 window.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
BrowserTestUtils.removeTab(tab);
});
add_task(async _ => {
info("All opened from chrome.");
await SpecialPowers.pushPrefEnv({"set": [
["dom.block_multiple_popups", true],
["dom.disable_open_during_load", true],
]});
let tab = BrowserTestUtils.addTab(gBrowser, CHROME_DOMAIN + TEST_PATH + "browser_multiple_popups.html")
gBrowser.selectedTab = tab;
let browser = gBrowser.getBrowserForTab(tab);
await BrowserTestUtils.browserLoaded(browser);
let obs = new WindowObserver(2);
await BrowserTestUtils.synthesizeMouseAtCenter("#openPopups", {}, tab.linkedBrowser);
await obs;
ok(true, "We had 2 windows.");
await BrowserTestUtils.synthesizeMouseAtCenter("#closeAllWindows", {}, tab.linkedBrowser);
BrowserTestUtils.removeTab(tab);
});

View File

@@ -22,7 +22,6 @@
#include "nsVariant.h" #include "nsVariant.h"
#include "mozilla/dom/BrowserElementDictionariesBinding.h" #include "mozilla/dom/BrowserElementDictionariesBinding.h"
#include "mozilla/dom/CustomEvent.h" #include "mozilla/dom/CustomEvent.h"
#include "mozilla/layout/RenderFrameParent.h"
using namespace mozilla; using namespace mozilla;
using namespace mozilla::dom; using namespace mozilla::dom;
@@ -177,12 +176,9 @@ BrowserElementParent::DispatchOpenWindowEvent(Element* aOpenerFrameElement,
BrowserElementParent::OpenWindowResult BrowserElementParent::OpenWindowResult
BrowserElementParent::OpenWindowOOP(TabParent* aOpenerTabParent, BrowserElementParent::OpenWindowOOP(TabParent* aOpenerTabParent,
TabParent* aPopupTabParent, TabParent* aPopupTabParent,
PRenderFrameParent* aRenderFrame,
const nsAString& aURL, const nsAString& aURL,
const nsAString& aName, const nsAString& aName,
const nsAString& aFeatures, const nsAString& aFeatures)
TextureFactoryIdentifier* aTextureFactoryIdentifier,
layers::LayersId* aLayersId)
{ {
// Create an iframe owned by the same document which owns openerFrameElement. // Create an iframe owned by the same document which owns openerFrameElement.
nsCOMPtr<Element> openerFrameElement = aOpenerTabParent->GetOwnerElement(); nsCOMPtr<Element> openerFrameElement = aOpenerTabParent->GetOwnerElement();
@@ -217,12 +213,6 @@ BrowserElementParent::OpenWindowOOP(TabParent* aOpenerTabParent,
popupFrameElement->AllowCreateFrameLoader(); popupFrameElement->AllowCreateFrameLoader();
popupFrameElement->CreateRemoteFrameLoader(aPopupTabParent); popupFrameElement->CreateRemoteFrameLoader(aPopupTabParent);
RenderFrameParent* rfp = static_cast<RenderFrameParent*>(aRenderFrame);
if (!aPopupTabParent->SetRenderFrame(rfp) ||
!aPopupTabParent->GetRenderFrameInfo(aTextureFactoryIdentifier, aLayersId)) {
return BrowserElementParent::OPEN_WINDOW_IGNORED;
}
return opened; return opened;
} }

View File

@@ -22,14 +22,6 @@ namespace dom {
class TabParent; class TabParent;
} // namespace dom } // namespace dom
namespace layers {
struct TextureFactoryIdentifier;
} // namespace layers
namespace layout {
class PRenderFrameParent;
} // namespace layout
/** /**
* BrowserElementParent implements a portion of the parent-process side of * BrowserElementParent implements a portion of the parent-process side of
* <iframe mozbrowser>. * <iframe mozbrowser>.
@@ -95,12 +87,9 @@ public:
static OpenWindowResult static OpenWindowResult
OpenWindowOOP(dom::TabParent* aOpenerTabParent, OpenWindowOOP(dom::TabParent* aOpenerTabParent,
dom::TabParent* aPopupTabParent, dom::TabParent* aPopupTabParent,
layout::PRenderFrameParent* aRenderFrame,
const nsAString& aURL, const nsAString& aURL,
const nsAString& aName, const nsAString& aName,
const nsAString& aFeatures, const nsAString& aFeatures);
layers::TextureFactoryIdentifier* aTextureFactoryIdentifier,
layers::LayersId* aLayersId);
/** /**
* Handle a window.open call from an in-process <iframe mozbrowser>. * Handle a window.open call from an in-process <iframe mozbrowser>.

View File

@@ -1079,6 +1079,7 @@ CanvasRenderingContext2D::CanvasRenderingContext2D(layers::LayersBackend aCompos
, mIsCapturedFrameInvalid(false) , mIsCapturedFrameInvalid(false)
, mPathTransformWillUpdate(false) , mPathTransformWillUpdate(false)
, mInvalidateCount(0) , mInvalidateCount(0)
, mWriteOnly(false)
{ {
if (!sMaxContextsInitialized) { if (!sMaxContextsInitialized) {
sMaxContexts = gfxPrefs::CanvasAzureAcceleratedLimit(); sMaxContexts = gfxPrefs::CanvasAzureAcceleratedLimit();
@@ -2565,7 +2566,8 @@ CanvasRenderingContext2D::CreatePattern(const CanvasImageSource& aSource,
// nullptr and set CORSUsed to true for passing the security check in // nullptr and set CORSUsed to true for passing the security check in
// CanvasUtils::DoDrawImageSecurityCheck(). // CanvasUtils::DoDrawImageSecurityCheck().
RefPtr<CanvasPattern> pat = RefPtr<CanvasPattern> pat =
new CanvasPattern(this, srcSurf, repeatMode, nullptr, false, true); new CanvasPattern(this, srcSurf, repeatMode, nullptr,
imgBitmap.IsWriteOnly(), true);
return pat.forget(); return pat.forget();
} }
@@ -4920,6 +4922,10 @@ CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return; return;
} }
if (canvas->IsWriteOnly()) {
SetWriteOnly();
}
} else if (aImage.IsImageBitmap()) { } else if (aImage.IsImageBitmap()) {
ImageBitmap& imageBitmap = aImage.GetAsImageBitmap(); ImageBitmap& imageBitmap = aImage.GetAsImageBitmap();
srcSurf = imageBitmap.PrepareForDrawTarget(mTarget); srcSurf = imageBitmap.PrepareForDrawTarget(mTarget);
@@ -4928,6 +4934,10 @@ CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
return; return;
} }
if (imageBitmap.IsWriteOnly()) {
SetWriteOnly();
}
imgSize = gfx::IntSize(imageBitmap.Width(), imageBitmap.Height()); imgSize = gfx::IntSize(imageBitmap.Width(), imageBitmap.Height());
} }
else { else {
@@ -5448,7 +5458,8 @@ CanvasRenderingContext2D::GetImageData(JSContext* aCx, double aSx,
// Check only if we have a canvas element; if we were created with a docshell, // Check only if we have a canvas element; if we were created with a docshell,
// then it's special internal use. // then it's special internal use.
if (mCanvasElement && !mCanvasElement->CallerCanRead(aCx)) { if (IsWriteOnly() ||
(mCanvasElement && !mCanvasElement->CallerCanRead(aCx))) {
// XXX ERRMSG we need to report an error to developers here! (bug 329026) // XXX ERRMSG we need to report an error to developers here! (bug 329026)
aError.Throw(NS_ERROR_DOM_SECURITY_ERR); aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr; return nullptr;

View File

@@ -41,6 +41,7 @@ class SourceSurface;
namespace dom { namespace dom {
class HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap; class HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap;
typedef HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap CanvasImageSource; typedef HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap CanvasImageSource;
class ImageBitmap;
class ImageData; class ImageData;
class StringOrCanvasGradientOrCanvasPattern; class StringOrCanvasGradientOrCanvasPattern;
class OwningStringOrCanvasGradientOrCanvasPattern; class OwningStringOrCanvasGradientOrCanvasPattern;
@@ -1192,6 +1193,19 @@ protected:
friend struct CanvasBidiProcessor; friend struct CanvasBidiProcessor;
friend class CanvasDrawObserver; friend class CanvasDrawObserver;
friend class ImageBitmap;
void SetWriteOnly()
{
mWriteOnly = true;
}
bool IsWriteOnly() const
{
return mWriteOnly;
}
bool mWriteOnly;
}; };
size_t BindingJSObjectMallocBytes(CanvasRenderingContext2D* aContext); size_t BindingJSObjectMallocBytes(CanvasRenderingContext2D* aContext);

View File

@@ -471,7 +471,8 @@ CheckSecurityForElements(const nsLayoutUtils::SurfaceFromElementResult& aRes)
*/ */
template<class ElementType> template<class ElementType>
static already_AddRefed<SourceSurface> static already_AddRefed<SourceSurface>
GetSurfaceFromElement(nsIGlobalObject* aGlobal, ElementType& aElement, ErrorResult& aRv) GetSurfaceFromElement(nsIGlobalObject* aGlobal, ElementType& aElement,
bool* aWriteOnly, ErrorResult& aRv)
{ {
nsLayoutUtils::SurfaceFromElementResult res = nsLayoutUtils::SurfaceFromElementResult res =
nsLayoutUtils::SurfaceFromElement(&aElement, nsLayoutUtils::SFE_WANT_FIRST_FRAME_IF_IMAGE); nsLayoutUtils::SurfaceFromElement(&aElement, nsLayoutUtils::SFE_WANT_FIRST_FRAME_IF_IMAGE);
@@ -483,17 +484,14 @@ GetSurfaceFromElement(nsIGlobalObject* aGlobal, ElementType& aElement, ErrorResu
} }
// check origin-clean // check write-only mode
if (!CheckSecurityForElements(res)) { *aWriteOnly = !CheckSecurityForElements(res);
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
}
return surface.forget(); return surface.forget();
} }
ImageBitmap::ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData, ImageBitmap::ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
gfxAlphaType aAlphaType) bool aWriteOnly, gfxAlphaType aAlphaType)
: mParent(aGlobal) : mParent(aGlobal)
, mData(aData) , mData(aData)
, mSurface(nullptr) , mSurface(nullptr)
@@ -501,6 +499,7 @@ ImageBitmap::ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
, mPictureRect(0, 0, aData->GetSize().width, aData->GetSize().height) , mPictureRect(0, 0, aData->GetSize().width, aData->GetSize().height)
, mAlphaType(aAlphaType) , mAlphaType(aAlphaType)
, mAllocatedImageData(false) , mAllocatedImageData(false)
, mWriteOnly(aWriteOnly)
{ {
MOZ_ASSERT(aData, "aData is null in ImageBitmap constructor."); MOZ_ASSERT(aData, "aData is null in ImageBitmap constructor.");
@@ -763,6 +762,7 @@ ImageBitmap::ToCloneData() const
RefPtr<SourceSurface> surface = mData->GetAsSourceSurface(); RefPtr<SourceSurface> surface = mData->GetAsSourceSurface();
result->mSurface = surface->GetDataSurface(); result->mSurface = surface->GetDataSurface();
MOZ_ASSERT(result->mSurface); MOZ_ASSERT(result->mSurface);
result->mWriteOnly = mWriteOnly;
return result; return result;
} }
@@ -773,7 +773,8 @@ ImageBitmap::CreateFromSourceSurface(nsIGlobalObject* aGlobal,
ErrorResult& aRv) ErrorResult& aRv)
{ {
RefPtr<layers::Image> data = CreateImageFromSurface(aSource); RefPtr<layers::Image> data = CreateImageFromSurface(aSource);
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data); RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data,
false /* writeOnly */);
ret->mAllocatedImageData = true; ret->mAllocatedImageData = true;
return ret.forget(); return ret.forget();
} }
@@ -784,7 +785,8 @@ ImageBitmap::CreateFromCloneData(nsIGlobalObject* aGlobal,
{ {
RefPtr<layers::Image> data = CreateImageFromSurface(aData->mSurface); RefPtr<layers::Image> data = CreateImageFromSurface(aData->mSurface);
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, aData->mAlphaType); RefPtr<ImageBitmap> ret =
new ImageBitmap(aGlobal, data, aData->mWriteOnly, aData->mAlphaType);
ret->mAllocatedImageData = true; ret->mAllocatedImageData = true;
@@ -798,11 +800,8 @@ ImageBitmap::CreateFromOffscreenCanvas(nsIGlobalObject* aGlobal,
OffscreenCanvas& aOffscreenCanvas, OffscreenCanvas& aOffscreenCanvas,
ErrorResult& aRv) ErrorResult& aRv)
{ {
// Check origin-clean. // Check write-only mode.
if (aOffscreenCanvas.IsWriteOnly()) { bool writeOnly = aOffscreenCanvas.IsWriteOnly();
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
}
nsLayoutUtils::SurfaceFromElementResult res = nsLayoutUtils::SurfaceFromElementResult res =
nsLayoutUtils::SurfaceFromOffscreenCanvas(&aOffscreenCanvas, nsLayoutUtils::SurfaceFromOffscreenCanvas(&aOffscreenCanvas,
@@ -818,7 +817,7 @@ ImageBitmap::CreateFromOffscreenCanvas(nsIGlobalObject* aGlobal,
RefPtr<layers::Image> data = RefPtr<layers::Image> data =
CreateImageFromSurface(surface); CreateImageFromSurface(surface);
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data); RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
ret->mAllocatedImageData = true; ret->mAllocatedImageData = true;
@@ -835,9 +834,12 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl
return nullptr; return nullptr;
} }
bool writeOnly = true;
// Get the SourceSurface out from the image element and then do security // Get the SourceSurface out from the image element and then do security
// checking. // checking.
RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aImageEl, aRv); RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aImageEl,
&writeOnly, aRv);
if (NS_WARN_IF(aRv.Failed())) { if (NS_WARN_IF(aRv.Failed())) {
return nullptr; return nullptr;
@@ -851,7 +853,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl
return nullptr; return nullptr;
} }
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data); RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
// Set the picture rectangle. // Set the picture rectangle.
if (ret && aCropRect.isSome()) { if (ret && aCropRect.isSome()) {
@@ -865,9 +867,12 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl
ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, SVGImageElement& aImageEl, ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, SVGImageElement& aImageEl,
const Maybe<IntRect>& aCropRect, ErrorResult& aRv) const Maybe<IntRect>& aCropRect, ErrorResult& aRv)
{ {
bool writeOnly = true;
// Get the SourceSurface out from the image element and then do security // Get the SourceSurface out from the image element and then do security
// checking. // checking.
RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aImageEl, aRv); RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aImageEl,
&writeOnly, aRv);
if (NS_WARN_IF(aRv.Failed())) { if (NS_WARN_IF(aRv.Failed())) {
return nullptr; return nullptr;
@@ -881,7 +886,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, SVGImageElement& aImageEl,
return nullptr; return nullptr;
} }
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data); RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
// Set the picture rectangle. // Set the picture rectangle.
if (ret && aCropRect.isSome()) { if (ret && aCropRect.isSome()) {
@@ -913,10 +918,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl
// Check security. // Check security.
nsCOMPtr<nsIPrincipal> principal = aVideoEl.GetCurrentVideoPrincipal(); nsCOMPtr<nsIPrincipal> principal = aVideoEl.GetCurrentVideoPrincipal();
bool CORSUsed = aVideoEl.GetCORSMode() != CORS_NONE; bool CORSUsed = aVideoEl.GetCORSMode() != CORS_NONE;
if (!CheckSecurityForElements(false, CORSUsed, principal)) { bool writeOnly = !CheckSecurityForElements(false, CORSUsed, principal);
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
}
// Create ImageBitmap. // Create ImageBitmap.
RefPtr<layers::Image> data = aVideoEl.GetCurrentImage(); RefPtr<layers::Image> data = aVideoEl.GetCurrentImage();
@@ -924,7 +926,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl
aRv.Throw(NS_ERROR_NOT_AVAILABLE); aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return nullptr; return nullptr;
} }
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data); RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
// Set the picture rectangle. // Set the picture rectangle.
if (ret && aCropRect.isSome()) { if (ret && aCropRect.isSome()) {
@@ -943,12 +945,18 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvas
return nullptr; return nullptr;
} }
RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aCanvasEl, aRv); bool writeOnly = true;
RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aCanvasEl,
&writeOnly, aRv);
if (NS_WARN_IF(aRv.Failed())) { if (NS_WARN_IF(aRv.Failed())) {
return nullptr; return nullptr;
} }
if (!writeOnly) {
writeOnly = aCanvasEl.IsWriteOnly();
}
// Crop the source surface if needed. // Crop the source surface if needed.
RefPtr<SourceSurface> croppedSurface; RefPtr<SourceSurface> croppedSurface;
IntRect cropRect = aCropRect.valueOr(IntRect()); IntRect cropRect = aCropRect.valueOr(IntRect());
@@ -982,7 +990,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvas
return nullptr; return nullptr;
} }
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data); RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
if (needToReportMemoryAllocation) { if (needToReportMemoryAllocation) {
ret->mAllocatedImageData = true; ret->mAllocatedImageData = true;
@@ -1047,7 +1055,8 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageData& aImageData,
} }
// Create an ImageBimtap. // Create an ImageBimtap.
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, alphaType); RefPtr<ImageBitmap> ret =
new ImageBitmap(aGlobal, data, false /* write-only */, alphaType);
ret->mAllocatedImageData = true; ret->mAllocatedImageData = true;
@@ -1070,11 +1079,8 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, CanvasRenderingContext2D&
window->GetExtantDoc()->WarnOnceAbout(nsIDocument::eCreateImageBitmapCanvasRenderingContext2D); window->GetExtantDoc()->WarnOnceAbout(nsIDocument::eCreateImageBitmapCanvasRenderingContext2D);
// Check origin-clean. // Check write-only mode.
if (aCanvasCtx.GetCanvas()->IsWriteOnly()) { bool writeOnly = aCanvasCtx.GetCanvas()->IsWriteOnly() || aCanvasCtx.IsWriteOnly();
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
}
RefPtr<SourceSurface> surface = aCanvasCtx.GetSurfaceSnapshot(); RefPtr<SourceSurface> surface = aCanvasCtx.GetSurfaceSnapshot();
@@ -1096,7 +1102,8 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, CanvasRenderingContext2D&
return nullptr; return nullptr;
} }
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data); RefPtr<ImageBitmap> ret =
new ImageBitmap(aGlobal, data, writeOnly);
ret->mAllocatedImageData = true; ret->mAllocatedImageData = true;
@@ -1118,7 +1125,9 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageBitmap& aImageBitmap,
} }
RefPtr<layers::Image> data = aImageBitmap.mData; RefPtr<layers::Image> data = aImageBitmap.mData;
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, aImageBitmap.mAlphaType); RefPtr<ImageBitmap> ret =
new ImageBitmap(aGlobal, data, aImageBitmap.mWriteOnly,
aImageBitmap.mAlphaType);
// Set the picture rectangle. // Set the picture rectangle.
if (ret && aCropRect.isSome()) { if (ret && aCropRect.isSome()) {
@@ -1432,16 +1441,14 @@ ImageBitmap::ReadStructuredClone(JSContext* aCx,
uint32_t picRectWidth_; uint32_t picRectWidth_;
uint32_t picRectHeight_; uint32_t picRectHeight_;
uint32_t alphaType_; uint32_t alphaType_;
uint32_t dummy; uint32_t writeOnly;
if (!JS_ReadUint32Pair(aReader, &picRectX_, &picRectY_) || if (!JS_ReadUint32Pair(aReader, &picRectX_, &picRectY_) ||
!JS_ReadUint32Pair(aReader, &picRectWidth_, &picRectHeight_) || !JS_ReadUint32Pair(aReader, &picRectWidth_, &picRectHeight_) ||
!JS_ReadUint32Pair(aReader, &alphaType_, &dummy)) { !JS_ReadUint32Pair(aReader, &alphaType_, &writeOnly)) {
return nullptr; return nullptr;
} }
MOZ_ASSERT(dummy == 0);
int32_t picRectX = BitwiseCast<int32_t>(picRectX_); int32_t picRectX = BitwiseCast<int32_t>(picRectX_);
int32_t picRectY = BitwiseCast<int32_t>(picRectY_); int32_t picRectY = BitwiseCast<int32_t>(picRectY_);
int32_t picRectWidth = BitwiseCast<int32_t>(picRectWidth_); int32_t picRectWidth = BitwiseCast<int32_t>(picRectWidth_);
@@ -1465,7 +1472,8 @@ ImageBitmap::ReadStructuredClone(JSContext* aCx,
} }
#endif #endif
RefPtr<layers::Image> img = CreateImageFromSurface(aClonedSurfaces[aIndex]); RefPtr<layers::Image> img = CreateImageFromSurface(aClonedSurfaces[aIndex]);
RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(aParent, img, alphaType); RefPtr<ImageBitmap> imageBitmap =
new ImageBitmap(aParent, img, !!writeOnly, alphaType);
ErrorResult error; ErrorResult error;
imageBitmap->SetPictureRect(IntRect(picRectX, picRectY, imageBitmap->SetPictureRect(IntRect(picRectX, picRectY,
@@ -1505,7 +1513,7 @@ ImageBitmap::WriteStructuredClone(JSStructuredCloneWriter* aWriter,
if (NS_WARN_IF(!JS_WriteUint32Pair(aWriter, SCTAG_DOM_IMAGEBITMAP, index)) || if (NS_WARN_IF(!JS_WriteUint32Pair(aWriter, SCTAG_DOM_IMAGEBITMAP, index)) ||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectX, picRectY)) || NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectX, picRectY)) ||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectWidth, picRectHeight)) || NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectWidth, picRectHeight)) ||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, alphaType, 0))) { NS_WARN_IF(!JS_WriteUint32Pair(aWriter, alphaType, aImageBitmap->mWriteOnly))) {
return false; return false;
} }
@@ -1839,7 +1847,8 @@ CreateImageBitmapFromBlob::MimeTypeAndDecodeAndCropBlobCompletedOwningThread(lay
} }
// Create ImageBitmap object. // Create ImageBitmap object.
RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(mGlobalObject, aImage); RefPtr<ImageBitmap> imageBitmap =
new ImageBitmap(mGlobalObject, aImage, false /* write-only */);
if (mCropRect.isSome()) { if (mCropRect.isSome()) {
ErrorResult rv; ErrorResult rv;

View File

@@ -60,6 +60,7 @@ struct ImageBitmapCloneData final
RefPtr<gfx::DataSourceSurface> mSurface; RefPtr<gfx::DataSourceSurface> mSurface;
gfx::IntRect mPictureRect; gfx::IntRect mPictureRect;
gfxAlphaType mAlphaType; gfxAlphaType mAlphaType;
bool mWriteOnly;
}; };
/* /*
@@ -152,6 +153,11 @@ public:
void OnShutdown(); void OnShutdown();
bool IsWriteOnly() const
{
return mWriteOnly;
}
protected: protected:
/* /*
@@ -174,6 +180,7 @@ protected:
* CreateInternal(from ImageData) method. * CreateInternal(from ImageData) method.
*/ */
ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData, ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
bool aWriteOnly,
gfxAlphaType aAlphaType = gfxAlphaType::Premult); gfxAlphaType aAlphaType = gfxAlphaType::Premult);
virtual ~ImageBitmap(); virtual ~ImageBitmap();
@@ -255,6 +262,13 @@ protected:
* Whether this object allocated allocated and owns the image data. * Whether this object allocated allocated and owns the image data.
*/ */
bool mAllocatedImageData; bool mAllocatedImageData;
/*
* Write-Only flag is set to true if this image has been generated from a
* cross-origin source. This is the opposite of what is called 'origin-clean'
* in the spec.
*/
bool mWriteOnly;
}; };
} // namespace dom } // namespace dom

View File

@@ -245,8 +245,11 @@ struct TexImageSourceAdapter final : public TexImageSource
mPboOffset = pboOffset; mPboOffset = pboOffset;
} }
TexImageSourceAdapter(const dom::ImageBitmap* imageBitmap, ErrorResult*) { TexImageSourceAdapter(const dom::ImageBitmap* imageBitmap,
ErrorResult* out_error)
{
mImageBitmap = imageBitmap; mImageBitmap = imageBitmap;
mOut_error = out_error;
} }
TexImageSourceAdapter(const dom::ImageData* imageData, ErrorResult*) { TexImageSourceAdapter(const dom::ImageData* imageData, ErrorResult*) {

View File

@@ -12,6 +12,7 @@
#include "GLBlitHelper.h" #include "GLBlitHelper.h"
#include "GLContext.h" #include "GLContext.h"
#include "mozilla/gfx/2D.h" #include "mozilla/gfx/2D.h"
#include "mozilla/dom/HTMLCanvasElement.h"
#include "mozilla/dom/HTMLVideoElement.h" #include "mozilla/dom/HTMLVideoElement.h"
#include "mozilla/dom/ImageBitmap.h" #include "mozilla/dom/ImageBitmap.h"
#include "mozilla/dom/ImageData.h" #include "mozilla/dom/ImageData.h"
@@ -222,8 +223,13 @@ FromPboOffset(WebGLContext* webgl, TexImageTarget target,
static UniquePtr<webgl::TexUnpackBlob> static UniquePtr<webgl::TexUnpackBlob>
FromImageBitmap(WebGLContext* webgl, TexImageTarget target, FromImageBitmap(WebGLContext* webgl, TexImageTarget target,
uint32_t width, uint32_t height, uint32_t depth, uint32_t width, uint32_t height, uint32_t depth,
const dom::ImageBitmap& imageBitmap) const dom::ImageBitmap& imageBitmap, ErrorResult* aRv)
{ {
if (imageBitmap.IsWriteOnly()) {
aRv->Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
}
UniquePtr<dom::ImageBitmapCloneData> cloneData = imageBitmap.ToCloneData(); UniquePtr<dom::ImageBitmapCloneData> cloneData = imageBitmap.ToCloneData();
if (!cloneData) { if (!cloneData) {
return nullptr; return nullptr;
@@ -300,6 +306,14 @@ WebGLContext::FromDomElem(TexImageTarget target, uint32_t width,
uint32_t height, uint32_t depth, const dom::Element& elem, uint32_t height, uint32_t depth, const dom::Element& elem,
ErrorResult* const out_error) ErrorResult* const out_error)
{ {
if (elem.IsHTMLElement(nsGkAtoms::canvas)) {
const dom::HTMLCanvasElement* canvas = static_cast<const dom::HTMLCanvasElement*>(&elem);
if (canvas->IsWriteOnly()) {
out_error->Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
}
}
// The canvas spec says that drawImage should draw the first frame of // The canvas spec says that drawImage should draw the first frame of
// animated images. The webgl spec doesn't mention the issue, so we do the // animated images. The webgl spec doesn't mention the issue, so we do the
// same as drawImage. // same as drawImage.
@@ -421,7 +435,7 @@ WebGLContext::From(TexImageTarget target, GLsizei rawWidth,
if (src.mImageBitmap) { if (src.mImageBitmap) {
return FromImageBitmap(this, target, width, height, depth, return FromImageBitmap(this, target, width, height, depth,
*(src.mImageBitmap)); *(src.mImageBitmap), src.mOut_error);
} }
if (src.mImageData) { if (src.mImageData) {

View File

@@ -270,13 +270,22 @@ function testSecurityErrors() {
} }
function checkPromiseFailedWithSecurityError(p) { function checkPromiseFailedWithSecurityError(p) {
return p.then( function(reason) { ok(false, "Did not get SecurityError with unclean source. ImageBitmap was created successfully."); }, return p.then(imageBitmap => {
function(reason) { if (reason == "SecurityError: The operation is insecure.") { ok(!!imageBitmap, "ImageBitmaps are always created");
ok(true, reason); const context = document.createElement("canvas").getContext("2d");
context.drawImage(imageBitmap, 0, 0);
try {
context.getImageData(0, 0, 1, 1);
ok(false, "Did not get SecurityError with unclean source. ImageBitmap was created successfully.");
} catch (ex) {
if (ex == "SecurityError: The operation is insecure.") {
ok(true, ex);
} }
else { else {
ok(false, "Did not get SecurityError with unclean source. Error Message: " + reason); ok(false, "Did not get SecurityError with unclean source. Error Message: " + ex);
}}); }
}
});
} }
return Promise.all([ return Promise.all([

View File

@@ -1083,7 +1083,7 @@ HTMLCanvasElement::GetSize()
} }
bool bool
HTMLCanvasElement::IsWriteOnly() HTMLCanvasElement::IsWriteOnly() const
{ {
return mWriteOnly; return mWriteOnly;
} }

View File

@@ -223,7 +223,7 @@ public:
/** /**
* Determine whether the canvas is write-only. * Determine whether the canvas is write-only.
*/ */
bool IsWriteOnly(); bool IsWriteOnly() const;
/** /**
* Force the canvas to be write-only. * Force the canvas to be write-only.

View File

@@ -68,7 +68,6 @@
#include "mozilla/layers/CompositorManagerChild.h" #include "mozilla/layers/CompositorManagerChild.h"
#include "mozilla/layers/ContentProcessController.h" #include "mozilla/layers/ContentProcessController.h"
#include "mozilla/layers/ImageBridgeChild.h" #include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/layout/RenderFrameChild.h"
#include "mozilla/loader/ScriptCacheActors.h" #include "mozilla/loader/ScriptCacheActors.h"
#include "mozilla/net/NeckoChild.h" #include "mozilla/net/NeckoChild.h"
#include "mozilla/net/CookieServiceChild.h" #include "mozilla/net/CookieServiceChild.h"
@@ -972,9 +971,6 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
tabId, TabId(0), *ipcContext, aChromeFlags, tabId, TabId(0), *ipcContext, aChromeFlags,
GetID(), IsForBrowser()); GetID(), IsForBrowser());
PRenderFrameChild* renderFrame = newChild->SendPRenderFrameConstructor();
nsCOMPtr<nsPIDOMWindowInner> parentTopInnerWindow; nsCOMPtr<nsPIDOMWindowInner> parentTopInnerWindow;
if (aParent) { if (aParent) {
nsCOMPtr<nsPIDOMWindowOuter> parentTopWindow = nsCOMPtr<nsPIDOMWindowOuter> parentTopWindow =
@@ -995,9 +991,6 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
*aWindowIsNew = info.windowOpened(); *aWindowIsNew = info.windowOpened();
nsTArray<FrameScriptInfo> frameScripts(info.frameScripts()); nsTArray<FrameScriptInfo> frameScripts(info.frameScripts());
nsCString urlToLoad = info.urlToLoad(); nsCString urlToLoad = info.urlToLoad();
TextureFactoryIdentifier textureFactoryIdentifier = info.textureFactoryIdentifier();
layers::LayersId layersId = info.layersId();
CompositorOptions compositorOptions = info.compositorOptions();
uint32_t maxTouchPoints = info.maxTouchPoints(); uint32_t maxTouchPoints = info.maxTouchPoints();
DimensionInfo dimensionInfo = info.dimensions(); DimensionInfo dimensionInfo = info.dimensions();
bool hasSiblings = info.hasSiblings(); bool hasSiblings = info.hasSiblings();
@@ -1026,10 +1019,6 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
return; return;
} }
if (!layersId.IsValid()) { // if renderFrame is invalid.
renderFrame = nullptr;
}
ShowInfo showInfo(EmptyString(), false, false, true, false, 0, 0, 0); ShowInfo showInfo(EmptyString(), false, false, true, false, 0, 0, 0);
auto* opener = nsPIDOMWindowOuter::From(aParent); auto* opener = nsPIDOMWindowOuter::From(aParent);
nsIDocShell* openerShell; nsIDocShell* openerShell;
@@ -1058,8 +1047,7 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
// Unfortunately we don't get a window unless we've shown the frame. That's // Unfortunately we don't get a window unless we've shown the frame. That's
// pretty bogus; see bug 763602. // pretty bogus; see bug 763602.
newChild->DoFakeShow(textureFactoryIdentifier, layersId, compositorOptions, newChild->DoFakeShow(showInfo);
renderFrame, showInfo);
newChild->RecvUpdateDimensions(dimensionInfo); newChild->RecvUpdateDimensions(dimensionInfo);
@@ -1102,7 +1090,7 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
// NOTE: BrowserFrameOpenWindowPromise is the same type as // NOTE: BrowserFrameOpenWindowPromise is the same type as
// CreateWindowPromise, and this code depends on that fact. // CreateWindowPromise, and this code depends on that fact.
newChild->SendBrowserFrameOpenWindow(aTabOpener, renderFrame, newChild->SendBrowserFrameOpenWindow(aTabOpener,
NS_ConvertUTF8toUTF16(url), NS_ConvertUTF8toUTF16(url),
name, NS_ConvertUTF8toUTF16(features), name, NS_ConvertUTF8toUTF16(features),
std::move(resolve), std::move(reject)); std::move(resolve), std::move(reject));
@@ -1125,7 +1113,7 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
uriToLoad = mozilla::void_t(); uriToLoad = mozilla::void_t();
} }
SendCreateWindow(aTabOpener, newChild, renderFrame, SendCreateWindow(aTabOpener, newChild,
aChromeFlags, aCalledFromJS, aPositionSpecified, aChromeFlags, aCalledFromJS, aPositionSpecified,
aSizeSpecified, uriToLoad, features, baseURIString, aSizeSpecified, uriToLoad, features, baseURIString,
fullZoom, Principal(triggeringPrincipal), referrerPolicy, fullZoom, Principal(triggeringPrincipal), referrerPolicy,

View File

@@ -83,7 +83,6 @@
#include "mozilla/layers/CompositorThread.h" #include "mozilla/layers/CompositorThread.h"
#include "mozilla/layers/ImageBridgeParent.h" #include "mozilla/layers/ImageBridgeParent.h"
#include "mozilla/layers/LayerTreeOwnerTracker.h" #include "mozilla/layers/LayerTreeOwnerTracker.h"
#include "mozilla/layout/RenderFrameParent.h"
#include "mozilla/loader/ScriptCacheActors.h" #include "mozilla/loader/ScriptCacheActors.h"
#include "mozilla/LoginReputationIPC.h" #include "mozilla/LoginReputationIPC.h"
#include "mozilla/LookAndFeel.h" #include "mozilla/LookAndFeel.h"
@@ -1261,7 +1260,6 @@ ContentParent::CreateBrowser(const TabContext& aContext,
} }
RefPtr<TabParent> tp(new TabParent(constructorSender, tabId, RefPtr<TabParent> tp(new TabParent(constructorSender, tabId,
aContext, chromeFlags)); aContext, chromeFlags));
tp->SetInitedByParent();
PBrowserParent* browser = PBrowserParent* browser =
constructorSender->SendPBrowserConstructor( constructorSender->SendPBrowserConstructor(
@@ -1657,81 +1655,6 @@ ContentParent::ProcessingError(Result aCode, const char* aReason)
#endif #endif
} }
/* static */
bool
ContentParent::AllocateLayerTreeId(TabParent* aTabParent, layers::LayersId* aId)
{
return AllocateLayerTreeId(aTabParent->Manager()->AsContentParent(),
aTabParent, aTabParent->GetTabId(), aId);
}
/* static */
bool
ContentParent::AllocateLayerTreeId(ContentParent* aContent,
TabParent* aTopLevel, const TabId& aTabId,
layers::LayersId* aId)
{
GPUProcessManager* gpu = GPUProcessManager::Get();
*aId = gpu->AllocateLayerTreeId();
if (!aContent || !aTopLevel) {
return false;
}
gpu->MapLayerTreeId(*aId, aContent->OtherPid());
return true;
}
mozilla::ipc::IPCResult
ContentParent::RecvAllocateLayerTreeId(const ContentParentId& aCpId,
const TabId& aTabId, layers::LayersId* aId)
{
// Protect against spoofing by a compromised child. aCpId must either
// correspond to the process that this ContentParent represents or be a
// child of it.
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
RefPtr<ContentParent> contentParent = cpm->GetContentProcessById(aCpId);
if (!contentParent ||
(ChildID() != aCpId && !contentParent->CanCommunicateWith(ChildID()))) {
return IPC_FAIL_NO_REASON(this);
}
// GetTopLevelTabParentByProcessAndTabId will make sure that aTabId
// lives in the process for aCpId.
RefPtr<TabParent> browserParent =
cpm->GetTopLevelTabParentByProcessAndTabId(aCpId, aTabId);
MOZ_ASSERT(contentParent && browserParent);
if (!AllocateLayerTreeId(contentParent, browserParent, aTabId, aId)) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentParent::RecvDeallocateLayerTreeId(const ContentParentId& aCpId,
const layers::LayersId& aId)
{
GPUProcessManager* gpu = GPUProcessManager::Get();
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
RefPtr<ContentParent> contentParent = cpm->GetContentProcessById(aCpId);
if (!contentParent || !contentParent->CanCommunicateWith(ChildID())) {
return IPC_FAIL(this, "Spoofed DeallocateLayerTreeId call");
}
if (!gpu->IsLayerTreeIdMapped(aId, contentParent->OtherPid())) {
// You can't deallocate layer tree ids that you didn't allocate
KillHard("DeallocateLayerTreeId");
}
gpu->UnmapLayerTreeId(aId, contentParent->OtherPid());
return IPC_OK();
}
namespace { namespace {
void void
@@ -5161,7 +5084,6 @@ ContentParent::CommonCreateWindow(PBrowserParent* aThisTab,
mozilla::ipc::IPCResult mozilla::ipc::IPCResult
ContentParent::RecvCreateWindow(PBrowserParent* aThisTab, ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
PBrowserParent* aNewTab, PBrowserParent* aNewTab,
PRenderFrameParent* aRenderFrame,
const uint32_t& aChromeFlags, const uint32_t& aChromeFlags,
const bool& aCalledFromJS, const bool& aCalledFromJS,
const bool& aPositionSpecified, const bool& aPositionSpecified,
@@ -5179,7 +5101,6 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
// We always expect to open a new window here. If we don't, it's an error. // We always expect to open a new window here. If we don't, it's an error.
cwi.windowOpened() = true; cwi.windowOpened() = true;
cwi.layersId() = LayersId{0};
cwi.maxTouchPoints() = 0; cwi.maxTouchPoints() = 0;
cwi.hasSiblings() = false; cwi.hasSiblings() = false;
@@ -5237,13 +5158,7 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
MOZ_ASSERT(TabParent::GetFrom(newRemoteTab) == newTab); MOZ_ASSERT(TabParent::GetFrom(newRemoteTab) == newTab);
newTab->SwapFrameScriptsFrom(cwi.frameScripts()); newTab->SwapFrameScriptsFrom(cwi.frameScripts());
newTab->MaybeShowFrame();
RenderFrameParent* rfp = static_cast<RenderFrameParent*>(aRenderFrame);
if (!newTab->SetRenderFrame(rfp) ||
!newTab->GetRenderFrameInfo(&cwi.textureFactoryIdentifier(), &cwi.layersId())) {
rv = NS_ERROR_FAILURE;
}
cwi.compositorOptions() = rfp->GetCompositorOptions();
nsCOMPtr<nsIWidget> widget = newTab->GetWidget(); nsCOMPtr<nsIWidget> widget = newTab->GetWidget();
if (widget) { if (widget) {

View File

@@ -92,10 +92,6 @@ namespace layers {
struct TextureFactoryIdentifier; struct TextureFactoryIdentifier;
} // namespace layers } // namespace layers
namespace layout {
class PRenderFrameParent;
} // namespace layout
namespace dom { namespace dom {
class Element; class Element;
@@ -543,7 +539,6 @@ public:
virtual mozilla::ipc::IPCResult virtual mozilla::ipc::IPCResult
RecvCreateWindow(PBrowserParent* aThisTabParent, RecvCreateWindow(PBrowserParent* aThisTabParent,
PBrowserParent* aNewTab, PBrowserParent* aNewTab,
layout::PRenderFrameParent* aRenderFrame,
const uint32_t& aChromeFlags, const uint32_t& aChromeFlags,
const bool& aCalledFromJS, const bool& aCalledFromJS,
const bool& aPositionSpecified, const bool& aPositionSpecified,
@@ -570,8 +565,6 @@ public:
const IPC::Principal& aTriggeringPrincipal, const IPC::Principal& aTriggeringPrincipal,
const uint32_t& aReferrerPolicy) override; const uint32_t& aReferrerPolicy) override;
static bool AllocateLayerTreeId(TabParent* aTabParent, layers::LayersId* aId);
static void static void
BroadcastBlobURLRegistration(const nsACString& aURI, BroadcastBlobURLRegistration(const nsACString& aURI,
BlobImpl* aBlobImpl, BlobImpl* aBlobImpl,
@@ -870,10 +863,6 @@ private:
static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure); static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure);
static bool AllocateLayerTreeId(ContentParent* aContent,
TabParent* aTopLevel, const TabId& aTabId,
layers::LayersId* aId);
/** /**
* Get or create the corresponding content parent array to |aContentProcessType|. * Get or create the corresponding content parent array to |aContentProcessType|.
*/ */
@@ -1140,13 +1129,6 @@ public:
virtual void ProcessingError(Result aCode, const char* aMsgName) override; virtual void ProcessingError(Result aCode, const char* aMsgName) override;
virtual mozilla::ipc::IPCResult RecvAllocateLayerTreeId(const ContentParentId& aCpId,
const TabId& aTabId,
layers::LayersId* aId) override;
virtual mozilla::ipc::IPCResult RecvDeallocateLayerTreeId(const ContentParentId& aCpId,
const layers::LayersId& aId) override;
virtual mozilla::ipc::IPCResult RecvGraphicsError(const nsCString& aError) override; virtual mozilla::ipc::IPCResult RecvGraphicsError(const nsCString& aError) override;
virtual mozilla::ipc::IPCResult virtual mozilla::ipc::IPCResult

View File

@@ -25,9 +25,6 @@ using CSSRect from "Units.h";
using CSSSize from "Units.h"; using CSSSize from "Units.h";
using mozilla::LayoutDeviceIntPoint from "Units.h"; using mozilla::LayoutDeviceIntPoint from "Units.h";
using hal::ScreenOrientation from "mozilla/HalScreenConfiguration.h"; using hal::ScreenOrientation from "mozilla/HalScreenConfiguration.h";
using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
using mozilla::layers::CompositorOptions from "mozilla/layers/CompositorOptions.h";
using mozilla::layers::LayersId from "mozilla/layers/LayersTypes.h";
using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h"; using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h";
@@ -120,9 +117,6 @@ struct CreatedWindowInfo
bool windowOpened; bool windowOpened;
FrameScriptInfo[] frameScripts; FrameScriptInfo[] frameScripts;
nsCString urlToLoad; nsCString urlToLoad;
TextureFactoryIdentifier textureFactoryIdentifier;
LayersId layersId;
CompositorOptions compositorOptions;
uint32_t maxTouchPoints; uint32_t maxTouchPoints;
DimensionInfo dimensions; DimensionInfo dimensions;
bool hasSiblings; bool hasSiblings;

View File

@@ -11,7 +11,6 @@ include protocol PContentBridge;
include protocol PDocAccessible; include protocol PDocAccessible;
include protocol PFilePicker; include protocol PFilePicker;
include protocol PIndexedDBPermissionRequest; include protocol PIndexedDBPermissionRequest;
include protocol PRenderFrame;
include protocol PPluginWidget; include protocol PPluginWidget;
include protocol PRemotePrintJob; include protocol PRemotePrintJob;
include protocol PChildToParentStream; include protocol PChildToParentStream;
@@ -117,7 +116,6 @@ nested(upto inside_cpow) sync protocol PBrowser
manages PDocAccessible; manages PDocAccessible;
manages PFilePicker; manages PFilePicker;
manages PIndexedDBPermissionRequest; manages PIndexedDBPermissionRequest;
manages PRenderFrame;
manages PPluginWidget; manages PPluginWidget;
manages PPaymentRequest; manages PPaymentRequest;
@@ -125,12 +123,6 @@ both:
async AsyncMessage(nsString aMessage, CpowEntry[] aCpows, async AsyncMessage(nsString aMessage, CpowEntry[] aCpows,
Principal aPrincipal, ClonedMessageData aData); Principal aPrincipal, ClonedMessageData aData);
/**
* Create a layout frame (encapsulating a remote layer tree) for
* the page that is currently loaded in the <browser>.
*/
async PRenderFrame();
parent: parent:
/** /**
* Tell the parent process a new accessible document has been created. * Tell the parent process a new accessible document has been created.
@@ -439,7 +431,7 @@ parent:
* *
* @param opener the PBrowser whose content called window.open. * @param opener the PBrowser whose content called window.open.
*/ */
async BrowserFrameOpenWindow(PBrowser opener, PRenderFrame renderFrame, async BrowserFrameOpenWindow(PBrowser opener,
nsString aURL, nsString aName, nsString aFeatures) nsString aURL, nsString aName, nsString aFeatures)
returns (CreatedWindowInfo window); returns (CreatedWindowInfo window);
@@ -534,6 +526,11 @@ parent:
*/ */
async RemotePaintIsReady(); async RemotePaintIsReady();
/**
* Child informs the parent that a compositor transaction has ocurred.
*/
async NotifyCompositorTransaction();
/** /**
* Child informs the parent that the content is ready to handle input * Child informs the parent that the content is ready to handle input
* events. This is sent when the TabChild is created. * events. This is sent when the TabChild is created.
@@ -600,8 +597,7 @@ child:
async InitRendering(TextureFactoryIdentifier textureFactoryIdentifier, async InitRendering(TextureFactoryIdentifier textureFactoryIdentifier,
LayersId layersId, LayersId layersId,
CompositorOptions compositorOptions, CompositorOptions compositorOptions,
bool layersConnected, bool layersConnected);
nullable PRenderFrame renderFrame);
async LoadURL(nsCString uri, ShowInfo info); async LoadURL(nsCString uri, ShowInfo info);

View File

@@ -32,7 +32,6 @@ include protocol PPrinting;
include protocol PChildToParentStream; include protocol PChildToParentStream;
include protocol PParentToChildStream; include protocol PParentToChildStream;
include protocol POfflineCacheUpdate; include protocol POfflineCacheUpdate;
include protocol PRenderFrame;
include protocol PSpeechSynthesis; include protocol PSpeechSynthesis;
include protocol PTestShell; include protocol PTestShell;
include protocol PJavaScript; include protocol PJavaScript;
@@ -913,11 +912,6 @@ parent:
async CopyFavicon(URIParams oldURI, URIParams newURI, Principal aLoadingPrincipal, bool isPrivate); async CopyFavicon(URIParams oldURI, URIParams newURI, Principal aLoadingPrincipal, bool isPrivate);
// Tell the compositor to allocate a layer tree id for nested remote mozbrowsers.
sync AllocateLayerTreeId(ContentParentId cpId, TabId tabId)
returns (LayersId id);
async DeallocateLayerTreeId(ContentParentId cpId, LayersId id);
/** /**
* Notifies the parent about a recording device is starting or shutdown. * Notifies the parent about a recording device is starting or shutdown.
* @param recordingStatus starting or shutdown * @param recordingStatus starting or shutdown
@@ -1054,7 +1048,6 @@ parent:
async CreateWindow(nullable PBrowser aThisTab, async CreateWindow(nullable PBrowser aThisTab,
PBrowser aNewTab, PBrowser aNewTab,
PRenderFrame aRenderFrame,
uint32_t aChromeFlags, uint32_t aChromeFlags,
bool aCalledFromJS, bool aCalledFromJS,
bool aPositionSpecified, bool aPositionSpecified,

View File

@@ -42,8 +42,6 @@
#include "mozilla/layers/LayerTransactionChild.h" #include "mozilla/layers/LayerTransactionChild.h"
#include "mozilla/layers/ShadowLayers.h" #include "mozilla/layers/ShadowLayers.h"
#include "mozilla/layers/WebRenderLayerManager.h" #include "mozilla/layers/WebRenderLayerManager.h"
#include "mozilla/layout/RenderFrameChild.h"
#include "mozilla/layout/RenderFrameParent.h"
#include "mozilla/plugins/PPluginWidgetChild.h" #include "mozilla/plugins/PPluginWidgetChild.h"
#include "mozilla/recordreplay/ParentIPC.h" #include "mozilla/recordreplay/ParentIPC.h"
#include "mozilla/LookAndFeel.h" #include "mozilla/LookAndFeel.h"
@@ -397,7 +395,6 @@ TabChild::TabChild(nsIContentChild* aManager,
uint32_t aChromeFlags) uint32_t aChromeFlags)
: TabContext(aContext) : TabContext(aContext)
, mTabGroup(aTabGroup) , mTabGroup(aTabGroup)
, mRemoteFrame(nullptr)
, mManager(aManager) , mManager(aManager)
, mChromeFlags(aChromeFlags) , mChromeFlags(aChromeFlags)
, mMaxTouchPoints(0) , mMaxTouchPoints(0)
@@ -808,10 +805,10 @@ TabChild::SetStatusWithContext(uint32_t aStatusType,
const nsAString& aStatusText, const nsAString& aStatusText,
nsISupports* aStatusContext) nsISupports* aStatusContext)
{ {
// We can only send the status after the ipc machinery is set up, // We can only send the status after the ipc machinery is set up
// mRemoteFrame is a good indicator. if (IPCOpen()) {
if (mRemoteFrame)
SendSetStatus(aStatusType, nsString(aStatusText)); SendSetStatus(aStatusType, nsString(aStatusText));
}
return NS_OK; return NS_OK;
} }
@@ -1026,18 +1023,11 @@ TabChild::DestroyWindow()
if (baseWindow) if (baseWindow)
baseWindow->Destroy(); baseWindow->Destroy();
// NB: the order of mPuppetWidget->Destroy() and mRemoteFrame->Destroy()
// is important: we want to kill off remote layers before their
// frames
if (mPuppetWidget) { if (mPuppetWidget) {
mPuppetWidget->Destroy(); mPuppetWidget->Destroy();
} }
if (mRemoteFrame) { mLayersConnected = Nothing();
mRemoteFrame->Destroy();
mRemoteFrame = nullptr;
}
if (mLayersId.IsValid()) { if (mLayersId.IsValid()) {
StaticMutexAutoLock lock(sTabChildrenMutex); StaticMutexAutoLock lock(sTabChildrenMutex);
@@ -1129,13 +1119,8 @@ TabChild::RecvLoadURL(const nsCString& aURI,
} }
void void
TabChild::DoFakeShow(const TextureFactoryIdentifier& aTextureFactoryIdentifier, TabChild::DoFakeShow(const ShowInfo& aShowInfo)
const layers::LayersId& aLayersId,
const CompositorOptions& aCompositorOptions,
PRenderFrameChild* aRenderFrame, const ShowInfo& aShowInfo)
{ {
mLayersConnected = aRenderFrame ? Some(true) : Some(false);
InitRenderingState(aTextureFactoryIdentifier, aLayersId, aCompositorOptions, aRenderFrame);
RecvShow(ScreenIntSize(0, 0), aShowInfo, mParentIsActive, nsSizeMode_Normal); RecvShow(ScreenIntSize(0, 0), aShowInfo, mParentIsActive, nsSizeMode_Normal);
mDidFakeShow = true; mDidFakeShow = true;
} }
@@ -1236,13 +1221,10 @@ mozilla::ipc::IPCResult
TabChild::RecvInitRendering(const TextureFactoryIdentifier& aTextureFactoryIdentifier, TabChild::RecvInitRendering(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
const layers::LayersId& aLayersId, const layers::LayersId& aLayersId,
const CompositorOptions& aCompositorOptions, const CompositorOptions& aCompositorOptions,
const bool& aLayersConnected, const bool& aLayersConnected)
PRenderFrameChild* aRenderFrame)
{ {
MOZ_ASSERT((!mDidFakeShow && aRenderFrame) || (mDidFakeShow && !aRenderFrame));
mLayersConnected = Some(aLayersConnected); mLayersConnected = Some(aLayersConnected);
InitRenderingState(aTextureFactoryIdentifier, aLayersId, aCompositorOptions, aRenderFrame); InitRenderingState(aTextureFactoryIdentifier, aLayersId, aCompositorOptions);
return IPC_OK(); return IPC_OK();
} }
@@ -1251,7 +1233,7 @@ TabChild::RecvUpdateDimensions(const DimensionInfo& aDimensionInfo)
{ {
// When recording/replaying we need to make sure the dimensions are up to // When recording/replaying we need to make sure the dimensions are up to
// date on the compositor used in this process. // date on the compositor used in this process.
if (!mRemoteFrame && !recordreplay::IsRecordingOrReplaying()) { if (mLayersConnected.isNothing() && !recordreplay::IsRecordingOrReplaying()) {
return IPC_OK(); return IPC_OK();
} }
@@ -2731,19 +2713,6 @@ TabChild::RecvHandledWindowedPluginKeyEvent(
return IPC_OK(); return IPC_OK();
} }
PRenderFrameChild*
TabChild::AllocPRenderFrameChild()
{
return new RenderFrameChild();
}
bool
TabChild::DeallocPRenderFrameChild(PRenderFrameChild* aFrame)
{
delete aFrame;
return true;
}
bool bool
TabChild::InitTabChildMessageManager() TabChild::InitTabChildMessageManager()
{ {
@@ -2780,17 +2749,10 @@ TabChild::InitTabChildMessageManager()
void void
TabChild::InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIdentifier, TabChild::InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
const layers::LayersId& aLayersId, const layers::LayersId& aLayersId,
const CompositorOptions& aCompositorOptions, const CompositorOptions& aCompositorOptions)
PRenderFrameChild* aRenderFrame)
{ {
mPuppetWidget->InitIMEState(); mPuppetWidget->InitIMEState();
if (!aRenderFrame) {
mLayersConnected = Some(false);
NS_WARNING("failed to construct RenderFrame");
return;
}
MOZ_ASSERT(aLayersId.IsValid()); MOZ_ASSERT(aLayersId.IsValid());
mTextureFactoryIdentifier = aTextureFactoryIdentifier; mTextureFactoryIdentifier = aTextureFactoryIdentifier;
@@ -2805,7 +2767,6 @@ TabChild::InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIden
mCompositorOptions = Some(aCompositorOptions); mCompositorOptions = Some(aCompositorOptions);
mRemoteFrame = static_cast<RenderFrameChild*>(aRenderFrame);
if (aLayersId.IsValid()) { if (aLayersId.IsValid()) {
StaticMutexAutoLock lock(sTabChildrenMutex); StaticMutexAutoLock lock(sTabChildrenMutex);
@@ -2923,7 +2884,7 @@ TabChild::NotifyPainted()
if (!mNotified) { if (!mNotified) {
// Recording/replaying processes have a compositor but not a remote frame. // Recording/replaying processes have a compositor but not a remote frame.
if (!recordreplay::IsRecordingOrReplaying()) { if (!recordreplay::IsRecordingOrReplaying()) {
mRemoteFrame->SendNotifyCompositorTransaction(); SendNotifyCompositorTransaction();
} }
mNotified = true; mNotified = true;
} }
@@ -3302,7 +3263,7 @@ TabChild::RecvRequestNotifyAfterRemotePaint()
// Tell the CompositorBridgeChild that, when it gets a RemotePaintIsReady // Tell the CompositorBridgeChild that, when it gets a RemotePaintIsReady
// message that it should forward it us so that we can bounce it to our // message that it should forward it us so that we can bounce it to our
// RenderFrameParent. // TabParent.
compositor->RequestNotifyAfterRemotePaint(this); compositor->RequestNotifyAfterRemotePaint(this);
return IPC_OK(); return IPC_OK();
} }

View File

@@ -54,9 +54,6 @@ template<typename T> class nsPtrHashKey;
namespace mozilla { namespace mozilla {
class AbstractThread; class AbstractThread;
namespace layout {
class RenderFrameChild;
} // namespace layout
namespace layers { namespace layers {
class APZChild; class APZChild;
@@ -211,7 +208,6 @@ class TabChild final : public TabChildBase,
typedef mozilla::dom::ClonedMessageData ClonedMessageData; typedef mozilla::dom::ClonedMessageData ClonedMessageData;
typedef mozilla::dom::CoalescedMouseData CoalescedMouseData; typedef mozilla::dom::CoalescedMouseData CoalescedMouseData;
typedef mozilla::dom::CoalescedWheelData CoalescedWheelData; typedef mozilla::dom::CoalescedWheelData CoalescedWheelData;
typedef mozilla::layout::RenderFrameChild RenderFrameChild;
typedef mozilla::layers::APZEventState APZEventState; typedef mozilla::layers::APZEventState APZEventState;
typedef mozilla::layers::SetAllowedTouchBehaviorCallback SetAllowedTouchBehaviorCallback; typedef mozilla::layers::SetAllowedTouchBehaviorCallback SetAllowedTouchBehaviorCallback;
typedef mozilla::layers::TouchBehaviorFlags TouchBehaviorFlags; typedef mozilla::layers::TouchBehaviorFlags TouchBehaviorFlags;
@@ -307,8 +303,7 @@ public:
RecvInitRendering(const TextureFactoryIdentifier& aTextureFactoryIdentifier, RecvInitRendering(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
const layers::LayersId& aLayersId, const layers::LayersId& aLayersId,
const mozilla::layers::CompositorOptions& aCompositorOptions, const mozilla::layers::CompositorOptions& aCompositorOptions,
const bool& aLayersConnected, const bool& aLayersConnected) override;
PRenderFrameChild* aRenderFrame) override;
virtual mozilla::ipc::IPCResult virtual mozilla::ipc::IPCResult
RecvUpdateDimensions(const mozilla::dom::DimensionInfo& aDimensionInfo) override; RecvUpdateDimensions(const mozilla::dom::DimensionInfo& aDimensionInfo) override;
@@ -606,11 +601,7 @@ public:
virtual ScreenIntSize GetInnerSize() override; virtual ScreenIntSize GetInnerSize() override;
// Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow(). // Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow().
void DoFakeShow(const TextureFactoryIdentifier& aTextureFactoryIdentifier, void DoFakeShow(const ShowInfo& aShowInfo);
const layers::LayersId& aLayersId,
const mozilla::layers::CompositorOptions& aCompositorOptions,
PRenderFrameChild* aRenderFrame,
const ShowInfo& aShowInfo);
void ContentReceivedInputBlock(const ScrollableLayerGuid& aGuid, void ContentReceivedInputBlock(const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId, uint64_t aInputBlockId,
@@ -714,10 +705,6 @@ public:
protected: protected:
virtual ~TabChild(); virtual ~TabChild();
virtual PRenderFrameChild* AllocPRenderFrameChild() override;
virtual bool DeallocPRenderFrameChild(PRenderFrameChild* aFrame) override;
virtual mozilla::ipc::IPCResult RecvDestroy() override; virtual mozilla::ipc::IPCResult RecvDestroy() override;
virtual mozilla::ipc::IPCResult RecvSetDocShellIsActive(const bool& aIsActive) override; virtual mozilla::ipc::IPCResult RecvSetDocShellIsActive(const bool& aIsActive) override;
@@ -775,8 +762,7 @@ private:
void InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIdentifier, void InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
const layers::LayersId& aLayersId, const layers::LayersId& aLayersId,
const mozilla::layers::CompositorOptions& aCompositorOptions, const mozilla::layers::CompositorOptions& aCompositorOptions);
PRenderFrameChild* aRenderFrame);
void InitAPZState(); void InitAPZState();
void DestroyWindow(); void DestroyWindow();
@@ -826,7 +812,6 @@ private:
RefPtr<mozilla::dom::TabGroup> mTabGroup; RefPtr<mozilla::dom::TabGroup> mTabGroup;
RefPtr<PuppetWidget> mPuppetWidget; RefPtr<PuppetWidget> mPuppetWidget;
nsCOMPtr<nsIURI> mLastURI; nsCOMPtr<nsIURI> mLastURI;
RenderFrameChild* mRemoteFrame;
RefPtr<nsIContentChild> mManager; RefPtr<nsIContentChild> mManager;
uint32_t mChromeFlags; uint32_t mChromeFlags;
uint32_t mMaxTouchPoints; uint32_t mMaxTouchPoints;

View File

@@ -31,7 +31,7 @@
#include "mozilla/jsipc/CrossProcessObjectWrappers.h" #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
#include "mozilla/layers/AsyncDragMetrics.h" #include "mozilla/layers/AsyncDragMetrics.h"
#include "mozilla/layers/InputAPZContext.h" #include "mozilla/layers/InputAPZContext.h"
#include "mozilla/layout/RenderFrameParent.h" #include "mozilla/layout/RenderFrame.h"
#include "mozilla/plugins/PPluginWidgetParent.h" #include "mozilla/plugins/PPluginWidgetParent.h"
#include "mozilla/LookAndFeel.h" #include "mozilla/LookAndFeel.h"
#include "mozilla/MouseEvents.h" #include "mozilla/MouseEvents.h"
@@ -156,7 +156,6 @@ TabParent::TabParent(nsIContentParent* aManager,
, mIsDestroyed(false) , mIsDestroyed(false)
, mChromeFlags(aChromeFlags) , mChromeFlags(aChromeFlags)
, mDragValid(false) , mDragValid(false)
, mInitedByParent(false)
, mTabId(aTabId) , mTabId(aTabId)
, mCreatingWindow(false) , mCreatingWindow(false)
, mCursor(eCursorInvalid) , mCursor(eCursorInvalid)
@@ -359,11 +358,6 @@ TabParent::DestroyInternal()
// destroy itself and send back __delete__(). // destroy itself and send back __delete__().
Unused << SendDestroy(); Unused << SendDestroy();
if (RenderFrameParent* frame = GetRenderFrame()) {
RemoveTabParentFromTable(frame->GetLayersId());
frame->Destroy();
}
#ifdef XP_WIN #ifdef XP_WIN
// Let all PluginWidgets know we are tearing down. Prevents // Let all PluginWidgets know we are tearing down. Prevents
// these objects from sending async events after the child side // these objects from sending async events after the child side
@@ -406,8 +400,8 @@ TabParent::Destroy()
mozilla::ipc::IPCResult mozilla::ipc::IPCResult
TabParent::RecvEnsureLayersConnected(CompositorOptions* aCompositorOptions) TabParent::RecvEnsureLayersConnected(CompositorOptions* aCompositorOptions)
{ {
if (RenderFrameParent* frame = GetRenderFrame()) { if (mRenderFrame.IsInitialized()) {
frame->EnsureLayersConnected(aCompositorOptions); mRenderFrame.EnsureLayersConnected(aCompositorOptions);
} }
return IPC_OK(); return IPC_OK();
} }
@@ -433,6 +427,14 @@ TabParent::Recv__delete__()
void void
TabParent::ActorDestroy(ActorDestroyReason why) TabParent::ActorDestroy(ActorDestroyReason why)
{ {
if (mRenderFrame.IsInitialized()) {
// It's important to unmap layers after the remote browser has been destroyed,
// otherwise it may still send messages to the compositor which will reject them,
// causing assertions.
RemoveTabParentFromTable(mRenderFrame.GetLayersId());
mRenderFrame.Destroy();
}
// Even though TabParent::Destroy calls this, we need to do it here too in // Even though TabParent::Destroy calls this, we need to do it here too in
// case of a crash. // case of a crash.
IMEStateManager::OnTabParentDestroying(this); IMEStateManager::OnTabParentDestroying(this);
@@ -630,35 +632,38 @@ TabParent::LoadURL(nsIURI* aURI)
} }
void void
TabParent::InitRenderFrame() TabParent::InitRendering()
{ {
if (IsInitedByParent()) {
// If TabParent is initialized by parent side then the RenderFrame must also
// be created here. If TabParent is initialized by child side,
// child side will create RenderFrame.
MOZ_ASSERT(!GetRenderFrame());
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader(); RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
MOZ_ASSERT(!mRenderFrame.IsInitialized());
MOZ_ASSERT(frameLoader); MOZ_ASSERT(frameLoader);
if (frameLoader) {
RenderFrameParent* renderFrame = new RenderFrameParent(frameLoader); if (!frameLoader) {
MOZ_ASSERT(renderFrame->IsInitted());
layers::LayersId layersId = renderFrame->GetLayersId();
AddTabParentToTable(layersId, this);
if (!SendPRenderFrameConstructor(renderFrame)) {
return; return;
} }
mRenderFrame.Initialize(frameLoader);
MOZ_ASSERT(mRenderFrame.IsInitialized());
layers::LayersId layersId = mRenderFrame.GetLayersId();
AddTabParentToTable(layersId, this);
TextureFactoryIdentifier textureFactoryIdentifier; TextureFactoryIdentifier textureFactoryIdentifier;
renderFrame->GetTextureFactoryIdentifier(&textureFactoryIdentifier); mRenderFrame.GetTextureFactoryIdentifier(&textureFactoryIdentifier);
Unused << SendInitRendering(textureFactoryIdentifier, layersId, Unused << SendInitRendering(textureFactoryIdentifier, layersId,
renderFrame->GetCompositorOptions(), mRenderFrame.GetCompositorOptions(),
renderFrame->IsLayersConnected(), renderFrame); mRenderFrame.IsLayersConnected());
} }
} else {
// Otherwise, the child should have constructed the RenderFrame, void
// and we should already know about it. TabParent::MaybeShowFrame()
MOZ_ASSERT(GetRenderFrame()); {
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
if (!frameLoader) {
return;
} }
frameLoader->MaybeShowFrame();
} }
void void
@@ -669,7 +674,7 @@ TabParent::Show(const ScreenIntSize& size, bool aParentIsActive)
return; return;
} }
MOZ_ASSERT(GetRenderFrame()); MOZ_ASSERT(mRenderFrame.IsInitialized());
nsCOMPtr<nsISupports> container = mFrameElement->OwnerDoc()->GetContainer(); nsCOMPtr<nsISupports> container = mFrameElement->OwnerDoc()->GetContainer();
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(container); nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(container);
@@ -1654,9 +1659,19 @@ TabParent::SendHandleTap(TapType aType,
if (mIsDestroyed || !mIsReadyToHandleInputEvents) { if (mIsDestroyed || !mIsReadyToHandleInputEvents) {
return false; return false;
} }
if ((aType == TapType::eSingleTap || aType == TapType::eSecondTap) && if ((aType == TapType::eSingleTap || aType == TapType::eSecondTap)) {
GetRenderFrame()) { nsIFocusManager* fm = nsFocusManager::GetFocusManager();
GetRenderFrame()->TakeFocusForClickFromTap(); if (fm) {
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
if (frameLoader) {
RefPtr<Element> element = frameLoader->GetOwnerContent();
if (element) {
fm->SetFocus(element, nsIFocusManager::FLAG_BYMOUSE |
nsIFocusManager::FLAG_BYTOUCH |
nsIFocusManager::FLAG_NOSCROLL);
}
}
}
} }
LayoutDeviceIntPoint offset = GetChildProcessOffset(); LayoutDeviceIntPoint offset = GetChildProcessOffset();
return Manager()->AsContentParent()->IsInputPriorityEventEnabled() return Manager()->AsContentParent()->IsInputPriorityEventEnabled()
@@ -2368,13 +2383,13 @@ TabParent::GetTabIdFrom(nsIDocShell *docShell)
return TabId(0); return TabId(0);
} }
RenderFrameParent* RenderFrame*
TabParent::GetRenderFrame() TabParent::GetRenderFrame()
{ {
PRenderFrameParent* p = LoneManagedOrNullAsserts(ManagedPRenderFrameParent()); if (!mRenderFrame.IsInitialized()) {
RenderFrameParent* frame = static_cast<RenderFrameParent*>(p); return nullptr;
}
return frame; return &mRenderFrame;
} }
mozilla::ipc::IPCResult mozilla::ipc::IPCResult
@@ -2597,68 +2612,6 @@ TabParent::DeallocPColorPickerParent(PColorPickerParent* actor)
return true; return true;
} }
PRenderFrameParent*
TabParent::AllocPRenderFrameParent()
{
MOZ_ASSERT(ManagedPRenderFrameParent().IsEmpty());
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
RenderFrameParent* rfp = new RenderFrameParent(frameLoader);
if (rfp->IsInitted()) {
layers::LayersId layersId = rfp->GetLayersId();
AddTabParentToTable(layersId, this);
}
return rfp;
}
bool
TabParent::DeallocPRenderFrameParent(PRenderFrameParent* aFrame)
{
delete aFrame;
return true;
}
bool
TabParent::SetRenderFrame(PRenderFrameParent* aRFParent)
{
if (IsInitedByParent()) {
return false;
}
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
if (!frameLoader) {
return false;
}
RenderFrameParent* renderFrame = static_cast<RenderFrameParent*>(aRFParent);
bool success = renderFrame->Init(frameLoader);
if (!success) {
return false;
}
frameLoader->MaybeShowFrame();
layers::LayersId layersId = renderFrame->GetLayersId();
AddTabParentToTable(layersId, this);
return true;
}
bool
TabParent::GetRenderFrameInfo(TextureFactoryIdentifier* aTextureFactoryIdentifier,
layers::LayersId* aLayersId)
{
RenderFrameParent* rfp = GetRenderFrame();
if (!rfp) {
return false;
}
*aLayersId = rfp->GetLayersId();
rfp->GetTextureFactoryIdentifier(aTextureFactoryIdentifier);
return true;
}
already_AddRefed<nsFrameLoader> already_AddRefed<nsFrameLoader>
TabParent::GetFrameLoader(bool aUseCachedFrameLoaderAfterDestroy) const TabParent::GetFrameLoader(bool aUseCachedFrameLoaderAfterDestroy) const
{ {
@@ -2732,9 +2685,9 @@ TabParent::ApzAwareEventRoutingToChild(ScrollableLayerGuid* aOutTargetGuid,
// is destined. In such cases the layersId of the APZ result may not match // is destined. In such cases the layersId of the APZ result may not match
// the layersId of this renderframe. In such cases the main-thread hit- // the layersId of this renderframe. In such cases the main-thread hit-
// testing code "wins" so we need to update the guid to reflect this. // testing code "wins" so we need to update the guid to reflect this.
if (RenderFrameParent* rfp = GetRenderFrame()) { if (mRenderFrame.IsInitialized()) {
if (aOutTargetGuid->mLayersId != rfp->GetLayersId()) { if (aOutTargetGuid->mLayersId != mRenderFrame.GetLayersId()) {
*aOutTargetGuid = ScrollableLayerGuid(rfp->GetLayersId(), 0, ScrollableLayerGuid::NULL_SCROLL_ID); *aOutTargetGuid = ScrollableLayerGuid(mRenderFrame.GetLayersId(), 0, ScrollableLayerGuid::NULL_SCROLL_ID);
} }
} }
} }
@@ -2756,7 +2709,6 @@ TabParent::ApzAwareEventRoutingToChild(ScrollableLayerGuid* aOutTargetGuid,
mozilla::ipc::IPCResult mozilla::ipc::IPCResult
TabParent::RecvBrowserFrameOpenWindow(PBrowserParent* aOpener, TabParent::RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
PRenderFrameParent* aRenderFrame,
const nsString& aURL, const nsString& aURL,
const nsString& aName, const nsString& aName,
const nsString& aFeatures, const nsString& aFeatures,
@@ -2764,16 +2716,11 @@ TabParent::RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
{ {
CreatedWindowInfo cwi; CreatedWindowInfo cwi;
cwi.rv() = NS_OK; cwi.rv() = NS_OK;
cwi.layersId() = LayersId{0};
cwi.maxTouchPoints() = 0; cwi.maxTouchPoints() = 0;
BrowserElementParent::OpenWindowResult opened = BrowserElementParent::OpenWindowResult opened =
BrowserElementParent::OpenWindowOOP(TabParent::GetFrom(aOpener), BrowserElementParent::OpenWindowOOP(TabParent::GetFrom(aOpener),
this, aRenderFrame, aURL, aName, aFeatures, this, aURL, aName, aFeatures);
&cwi.textureFactoryIdentifier(),
&cwi.layersId());
cwi.compositorOptions() =
static_cast<RenderFrameParent*>(aRenderFrame)->GetCompositorOptions();
cwi.windowOpened() = (opened == BrowserElementParent::OPEN_WINDOW_ADDED); cwi.windowOpened() = (opened == BrowserElementParent::OPEN_WINDOW_ADDED);
nsCOMPtr<nsIWidget> widget = GetWidget(); nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) { if (widget) {
@@ -3184,6 +3131,30 @@ TabParent::RecvRemotePaintIsReady()
return IPC_OK(); return IPC_OK();
} }
mozilla::ipc::IPCResult
TabParent::RecvNotifyCompositorTransaction()
{
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
if (!frameLoader) {
return IPC_OK();
}
nsIFrame* docFrame = frameLoader->GetPrimaryFrameOfOwningContent();
if (!docFrame) {
// Bad, but nothing we can do about it (XXX/cjones: or is there?
// maybe bug 589337?). When the new frame is created, we'll
// probably still be the current render frame and will get to draw
// our content then. Or, we're shutting down and this update goes
// to /dev/null.
return IPC_OK();
}
docFrame->InvalidateLayer(DisplayItemType::TYPE_REMOTE);
return IPC_OK();
}
mozilla::ipc::IPCResult mozilla::ipc::IPCResult
TabParent::RecvRemoteIsReadyToHandleInputEvents() TabParent::RecvRemoteIsReadyToHandleInputEvents()
{ {
@@ -3555,8 +3526,8 @@ TabParent::StartApzAutoscroll(float aAnchorX, float aAnchorY,
} }
bool success = false; bool success = false;
if (RenderFrameParent* renderFrame = GetRenderFrame()) { if (mRenderFrame.IsInitialized()) {
layers::LayersId layersId = renderFrame->GetLayersId(); layers::LayersId layersId = mRenderFrame.GetLayersId();
if (nsCOMPtr<nsIWidget> widget = GetWidget()) { if (nsCOMPtr<nsIWidget> widget = GetWidget()) {
ScrollableLayerGuid guid{layersId, aPresShellId, aScrollId}; ScrollableLayerGuid guid{layersId, aPresShellId, aScrollId};
@@ -3583,8 +3554,8 @@ TabParent::StopApzAutoscroll(nsViewID aScrollId, uint32_t aPresShellId)
return NS_OK; return NS_OK;
} }
if (RenderFrameParent* renderFrame = GetRenderFrame()) { if (mRenderFrame.IsInitialized()) {
layers::LayersId layersId = renderFrame->GetLayersId(); layers::LayersId layersId = mRenderFrame.GetLayersId();
if (nsCOMPtr<nsIWidget> widget = GetWidget()) { if (nsCOMPtr<nsIWidget> widget = GetWidget()) {
ScrollableLayerGuid guid{layersId, aPresShellId, aScrollId}; ScrollableLayerGuid guid{layersId, aPresShellId, aScrollId};
widget->StopAsyncAutoscroll(guid); widget->StopAsyncAutoscroll(guid);

View File

@@ -19,6 +19,7 @@
#include "mozilla/dom/File.h" #include "mozilla/dom/File.h"
#include "mozilla/gfx/CrossProcessPaint.h" #include "mozilla/gfx/CrossProcessPaint.h"
#include "mozilla/layers/CompositorBridgeParent.h" #include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layout/RenderFrame.h"
#include "mozilla/RefPtr.h" #include "mozilla/RefPtr.h"
#include "mozilla/Move.h" #include "mozilla/Move.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
@@ -55,10 +56,6 @@ namespace layers {
struct TextureFactoryIdentifier; struct TextureFactoryIdentifier;
} // namespace layers } // namespace layers
namespace layout {
class RenderFrameParent;
} // namespace layout
namespace widget { namespace widget {
struct IMENotification; struct IMENotification;
} // namespace widget } // namespace widget
@@ -162,7 +159,6 @@ public:
virtual mozilla::ipc::IPCResult virtual mozilla::ipc::IPCResult
RecvBrowserFrameOpenWindow(PBrowserParent* aOpener, RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
PRenderFrameParent* aRenderFrame,
const nsString& aURL, const nsString& aURL,
const nsString& aName, const nsString& aName,
const nsString& aFeatures, const nsString& aFeatures,
@@ -333,7 +329,8 @@ public:
void LoadURL(nsIURI* aURI); void LoadURL(nsIURI* aURI);
void InitRenderFrame(); void InitRendering();
void MaybeShowFrame();
// XXX/cjones: it's not clear what we gain by hiding these // XXX/cjones: it's not clear what we gain by hiding these
// message-sending functions under a layer of indirection and // message-sending functions under a layer of indirection and
@@ -554,10 +551,6 @@ public:
virtual bool virtual bool
DeallocPPaymentRequestParent(PPaymentRequestParent* aActor) override; DeallocPPaymentRequestParent(PPaymentRequestParent* aActor) override;
void SetInitedByParent() { mInitedByParent = true; }
bool IsInitedByParent() const { return mInitedByParent; }
bool SendLoadRemoteScript(const nsString& aURL, bool SendLoadRemoteScript(const nsString& aURL,
const bool& aRunInGlobalScope); const bool& aRunInGlobalScope);
@@ -580,11 +573,7 @@ public:
bool TakeDragVisualization(RefPtr<mozilla::gfx::SourceSurface>& aSurface, bool TakeDragVisualization(RefPtr<mozilla::gfx::SourceSurface>& aSurface,
LayoutDeviceIntRect* aDragRect); LayoutDeviceIntRect* aDragRect);
layout::RenderFrameParent* GetRenderFrame(); layout::RenderFrame* GetRenderFrame();
bool SetRenderFrame(PRenderFrameParent* aRFParent);
bool GetRenderFrameInfo(TextureFactoryIdentifier* aTextureFactoryIdentifier,
layers::LayersId* aLayersId);
mozilla::ipc::IPCResult RecvEnsureLayersConnected(CompositorOptions* aCompositorOptions) override; mozilla::ipc::IPCResult RecvEnsureLayersConnected(CompositorOptions* aCompositorOptions) override;
@@ -620,12 +609,10 @@ protected:
Element* mFrameElement; Element* mFrameElement;
nsCOMPtr<nsIBrowserDOMWindow> mBrowserDOMWindow; nsCOMPtr<nsIBrowserDOMWindow> mBrowserDOMWindow;
virtual PRenderFrameParent* AllocPRenderFrameParent() override;
virtual bool DeallocPRenderFrameParent(PRenderFrameParent* aFrame) override;
virtual mozilla::ipc::IPCResult RecvRemotePaintIsReady() override; virtual mozilla::ipc::IPCResult RecvRemotePaintIsReady() override;
virtual mozilla::ipc::IPCResult RecvNotifyCompositorTransaction() override;
virtual mozilla::ipc::IPCResult RecvRemoteIsReadyToHandleInputEvents() override; virtual mozilla::ipc::IPCResult RecvRemoteIsReadyToHandleInputEvents() override;
virtual mozilla::ipc::IPCResult RecvPaintWhileInterruptingJSNoOp(const LayersObserverEpoch& aEpoch) override; virtual mozilla::ipc::IPCResult RecvPaintWhileInterruptingJSNoOp(const LayersObserverEpoch& aEpoch) override;
@@ -697,10 +684,6 @@ private:
LayoutDeviceIntRect mDragRect; LayoutDeviceIntRect mDragRect;
nsCString mDragPrincipalURISpec; nsCString mDragPrincipalURISpec;
// When true, the TabParent is initialized without child side's request.
// When false, the TabParent is initialized by window.open() from child side.
bool mInitedByParent;
nsCOMPtr<nsILoadContext> mLoadContext; nsCOMPtr<nsILoadContext> mLoadContext;
// We keep a strong reference to the frameloader after we've sent the // We keep a strong reference to the frameloader after we've sent the
@@ -772,6 +755,7 @@ private:
static void RemoveTabParentFromTable(layers::LayersId aLayersId); static void RemoveTabParentFromTable(layers::LayersId aLayersId);
layout::RenderFrame mRenderFrame;
LayersObserverEpoch mLayerTreeEpoch; LayersObserverEpoch mLayerTreeEpoch;
// If this flag is set, then the tab's layers will be preserved even when // If this flag is set, then the tab's layers will be preserved even when

View File

@@ -63,6 +63,7 @@ struct ID2D1Device;
struct IDWriteFactory; struct IDWriteFactory;
struct IDWriteRenderingParams; struct IDWriteRenderingParams;
struct IDWriteFontFace; struct IDWriteFontFace;
struct IDWriteFontCollection;
class GrContext; class GrContext;
class SkCanvas; class SkCanvas;
@@ -1860,9 +1861,9 @@ public:
static RefPtr<ID2D1Device> GetD2D1Device(uint32_t* aOutSeqNo = nullptr); static RefPtr<ID2D1Device> GetD2D1Device(uint32_t* aOutSeqNo = nullptr);
static bool HasD2D1Device(); static bool HasD2D1Device();
static RefPtr<IDWriteFactory> GetDWriteFactory(); static RefPtr<IDWriteFactory> GetDWriteFactory();
static bool SetDWriteFactory(IDWriteFactory *aFactory);
static RefPtr<IDWriteFactory> EnsureDWriteFactory(); static RefPtr<IDWriteFactory> EnsureDWriteFactory();
static bool SupportsD2D1(); static bool SupportsD2D1();
static RefPtr<IDWriteFontCollection> GetDWriteSystemFonts(bool aUpdate = false);
static uint64_t GetD2DVRAMUsageDrawTarget(); static uint64_t GetD2DVRAMUsageDrawTarget();
static uint64_t GetD2DVRAMUsageSourceSurface(); static uint64_t GetD2DVRAMUsageSourceSurface();
@@ -1886,6 +1887,7 @@ private:
static StaticRefPtr<ID3D11Device> mD3D11Device; static StaticRefPtr<ID3D11Device> mD3D11Device;
static StaticRefPtr<IDWriteFactory> mDWriteFactory; static StaticRefPtr<IDWriteFactory> mDWriteFactory;
static bool mDWriteFactoryInitialized; static bool mDWriteFactoryInitialized;
static StaticRefPtr<IDWriteFontCollection> mDWriteSystemFonts;
protected: protected:
// This guards access to the singleton devices above, as well as the // This guards access to the singleton devices above, as well as the

View File

@@ -229,6 +229,7 @@ StaticRefPtr<ID3D11Device> Factory::mD3D11Device;
StaticRefPtr<ID2D1Device> Factory::mD2D1Device; StaticRefPtr<ID2D1Device> Factory::mD2D1Device;
StaticRefPtr<IDWriteFactory> Factory::mDWriteFactory; StaticRefPtr<IDWriteFactory> Factory::mDWriteFactory;
bool Factory::mDWriteFactoryInitialized = false; bool Factory::mDWriteFactoryInitialized = false;
StaticRefPtr<IDWriteFontCollection> Factory::mDWriteSystemFonts;
StaticMutex Factory::mDeviceLock; StaticMutex Factory::mDeviceLock;
StaticMutex Factory::mDTDependencyLock; StaticMutex Factory::mDTDependencyLock;
#endif #endif
@@ -951,6 +952,30 @@ Factory::EnsureDWriteFactory()
return mDWriteFactory; return mDWriteFactory;
} }
RefPtr<IDWriteFontCollection>
Factory::GetDWriteSystemFonts(bool aUpdate)
{
StaticMutexAutoLock lock(mDeviceLock);
if (mDWriteSystemFonts && !aUpdate) {
return mDWriteSystemFonts;
}
if (!mDWriteFactory) {
return nullptr;
}
RefPtr<IDWriteFontCollection> systemFonts;
HRESULT hr = mDWriteFactory->GetSystemFontCollection(getter_AddRefs(systemFonts));
if (FAILED(hr)) {
gfxWarning() << "Failed to create DWrite system font collection";
return nullptr;
}
mDWriteSystemFonts = systemFonts;
return mDWriteSystemFonts;
}
bool bool
Factory::SupportsD2D1() Factory::SupportsD2D1()
{ {

View File

@@ -385,6 +385,18 @@ UnscaledFontDWrite::GetWRFontDescriptor(WRFontDescriptorOutput aCb, void* aBaton
return false; return false;
} }
RefPtr<IDWriteFontCollection> systemFonts = Factory::GetDWriteSystemFonts();
if (!systemFonts) {
return false;
}
UINT32 idx;
BOOL exists;
hr = systemFonts->FindFamilyName(familyName.data(), &idx, &exists);
if (FAILED(hr) || !exists) {
return false;
}
// The style information that identifies the font can be encoded easily in // The style information that identifies the font can be encoded easily in
// less than 32 bits. Since the index is needed for font descriptors, only // less than 32 bits. Since the index is needed for font descriptors, only
// the family name and style information, pass along the style in the index // the family name and style information, pass along the style in the index

View File

@@ -612,10 +612,10 @@ GPUProcessManager::HandleProcessLost()
// (b) [CONTENT] TabChild::ReinitRendering // (b) [CONTENT] TabChild::ReinitRendering
// (c) [CONTENT] TabChild::SendEnsureLayersConnected // (c) [CONTENT] TabChild::SendEnsureLayersConnected
// (d) [UI] TabParent::RecvEnsureLayersConnected // (d) [UI] TabParent::RecvEnsureLayersConnected
// (e) [UI] RenderFrameParent::EnsureLayersConnected // (e) [UI] RenderFrame::EnsureLayersConnected
// (f) [UI] CompositorBridgeChild::SendNotifyChildRecreated // (f) [UI] CompositorBridgeChild::SendNotifyChildRecreated
// //
// Note that at step (e), RenderFrameParent will call GetLayerManager // Note that at step (e), RenderFrame will call GetLayerManager
// on the nsIWidget owning the tab. This step ensures that a compositor // on the nsIWidget owning the tab. This step ensures that a compositor
// exists for the window. If we decided to launch a new GPU Process, // exists for the window. If we decided to launch a new GPU Process,
// at this point we block until the process has launched and we're // at this point we block until the process has launched and we're

View File

@@ -9,7 +9,7 @@
#include "mozilla/dom/EventTarget.h" // for EventTarget #include "mozilla/dom/EventTarget.h" // for EventTarget
#include "mozilla/dom/TabParent.h" // for TabParent #include "mozilla/dom/TabParent.h" // for TabParent
#include "mozilla/EventDispatcher.h" // for EventDispatcher #include "mozilla/EventDispatcher.h" // for EventDispatcher
#include "mozilla/layout/RenderFrameParent.h" // For RenderFrameParent #include "mozilla/layout/RenderFrame.h" // For RenderFrame
#include "nsIContentInlines.h" // for nsINode::IsEditable() #include "nsIContentInlines.h" // for nsINode::IsEditable()
#include "nsIPresShell.h" // for nsIPresShell #include "nsIPresShell.h" // for nsIPresShell
#include "nsLayoutUtils.h" // for nsLayoutUtils #include "nsLayoutUtils.h" // for nsLayoutUtils
@@ -166,16 +166,16 @@ FocusTarget::FocusTarget(nsIPresShell* aRootPresShell,
// Check if the key event target is a remote browser // Check if the key event target is a remote browser
if (TabParent* browserParent = TabParent::GetFrom(keyEventTarget)) { if (TabParent* browserParent = TabParent::GetFrom(keyEventTarget)) {
RenderFrameParent* rfp = browserParent->GetRenderFrame(); RenderFrame* rf = browserParent->GetRenderFrame();
// The globally focused element for scrolling is in a remote layer tree // The globally focused element for scrolling is in a remote layer tree
if (rfp) { if (rf) {
FT_LOG("Creating reflayer target with seq=%" PRIu64 ", kl=%d, lt=%" PRIu64 "\n", FT_LOG("Creating reflayer target with seq=%" PRIu64 ", kl=%d, lt=%" PRIu64 "\n",
aFocusSequenceNumber, aFocusSequenceNumber,
mFocusHasKeyEventListeners, mFocusHasKeyEventListeners,
rfp->GetLayersId()); rf->GetLayersId());
mData = AsVariant<LayersId>(rfp->GetLayersId()); mData = AsVariant<LayersId>(rf->GetLayersId());
return; return;
} }

View File

@@ -63,7 +63,6 @@
#include "mozilla/layers/RemoteContentController.h" #include "mozilla/layers/RemoteContentController.h"
#include "mozilla/layers/WebRenderBridgeParent.h" #include "mozilla/layers/WebRenderBridgeParent.h"
#include "mozilla/layers/AsyncImagePipelineManager.h" #include "mozilla/layers/AsyncImagePipelineManager.h"
#include "mozilla/layout/RenderFrameParent.h"
#include "mozilla/webrender/WebRenderAPI.h" #include "mozilla/webrender/WebRenderAPI.h"
#include "mozilla/media/MediaSystemResourceService.h" // for MediaSystemResourceService #include "mozilla/media/MediaSystemResourceService.h" // for MediaSystemResourceService
#include "mozilla/mozalloc.h" // for operator new, etc #include "mozilla/mozalloc.h" // for operator new, etc

View File

@@ -15,10 +15,6 @@
namespace mozilla { namespace mozilla {
namespace layout {
class RenderFrameChild;
} // namespace layout
namespace layers { namespace layers {
class ShadowLayerForwarder; class ShadowLayerForwarder;
@@ -73,7 +69,6 @@ protected:
Release(); Release();
} }
friend class CompositorBridgeChild; friend class CompositorBridgeChild;
friend class layout::RenderFrameChild;
ShadowLayerForwarder* mForwarder; ShadowLayerForwarder* mForwarder;
bool mIPCOpen; bool mIPCOpen;

View File

@@ -39,8 +39,6 @@
#include "mozilla/layers/TextureHost.h" #include "mozilla/layers/TextureHost.h"
#include "mozilla/layers/AsyncCompositionManager.h" #include "mozilla/layers/AsyncCompositionManager.h"
using mozilla::layout::RenderFrameParent;
namespace mozilla { namespace mozilla {
namespace layers { namespace layers {

View File

@@ -22,10 +22,6 @@ namespace ipc {
class Shmem; class Shmem;
} // namespace ipc } // namespace ipc
namespace layout {
class RenderFrameParent;
} // namespace layout
namespace layers { namespace layers {
class Layer; class Layer;
@@ -39,7 +35,6 @@ class LayerTransactionParent final : public PLayerTransactionParent,
public CompositableParentManager, public CompositableParentManager,
public ShmemAllocator public ShmemAllocator
{ {
typedef mozilla::layout::RenderFrameParent RenderFrameParent;
typedef InfallibleTArray<Edit> EditArray; typedef InfallibleTArray<Edit> EditArray;
typedef InfallibleTArray<OpDestroy> OpDestroyArray; typedef InfallibleTArray<OpDestroy> OpDestroyArray;
typedef InfallibleTArray<PluginWindowData> PluginsArray; typedef InfallibleTArray<PluginWindowData> PluginsArray;
@@ -168,7 +163,6 @@ protected:
} }
friend class CompositorBridgeParent; friend class CompositorBridgeParent;
friend class CrossProcessCompositorBridgeParent; friend class CrossProcessCompositorBridgeParent;
friend class layout::RenderFrameParent;
private: private:
// This is a function so we can log or breakpoint on why hit // This is a function so we can log or breakpoint on why hit

View File

@@ -7,7 +7,6 @@
include LayersSurfaces; include LayersSurfaces;
include protocol PCompositorBridge; include protocol PCompositorBridge;
include protocol PRenderFrame;
include protocol PTexture; include protocol PTexture;
include "gfxipc/ShadowLayerUtils.h"; include "gfxipc/ShadowLayerUtils.h";

View File

@@ -8,7 +8,6 @@
include LayersSurfaces; include LayersSurfaces;
include LayersMessages; include LayersMessages;
include protocol PCompositorBridge; include protocol PCompositorBridge;
include protocol PRenderFrame;
include protocol PTexture; include protocol PTexture;
include "mozilla/GfxMessageUtils.h"; include "mozilla/GfxMessageUtils.h";

View File

@@ -14,7 +14,6 @@
#include "mozilla/layers/APZCCallbackHelper.h" #include "mozilla/layers/APZCCallbackHelper.h"
#include "mozilla/layers/APZCTreeManagerParent.h" // for APZCTreeManagerParent #include "mozilla/layers/APZCTreeManagerParent.h" // for APZCTreeManagerParent
#include "mozilla/layers/APZThreadUtils.h" #include "mozilla/layers/APZThreadUtils.h"
#include "mozilla/layout/RenderFrameParent.h"
#include "mozilla/gfx/GPUProcessManager.h" #include "mozilla/gfx/GPUProcessManager.h"
#include "mozilla/Unused.h" #include "mozilla/Unused.h"
#include "Units.h" #include "Units.h"

View File

@@ -9,7 +9,6 @@
#include "Layers.h" #include "Layers.h"
#include "LayersLogging.h" #include "LayersLogging.h"
#include "mozilla/layers/WebRenderLayerManager.h" #include "mozilla/layers/WebRenderLayerManager.h"
#include "mozilla/layout/RenderFrameParent.h"
#include "mozilla/Unused.h" #include "mozilla/Unused.h"
#include "nsDisplayList.h" #include "nsDisplayList.h"
#include "nsTArray.h" #include "nsTArray.h"

View File

@@ -1057,8 +1057,10 @@ gfxDWriteFontList::InitFontListForPlatform()
mFontSubstitutes.Clear(); mFontSubstitutes.Clear();
mNonExistingFonts.Clear(); mNonExistingFonts.Clear();
hr = Factory::GetDWriteFactory()-> RefPtr<IDWriteFactory> factory =
GetGdiInterop(getter_AddRefs(mGDIInterop)); Factory::GetDWriteFactory();
hr = factory->GetGdiInterop(getter_AddRefs(mGDIInterop));
if (FAILED(hr)) { if (FAILED(hr)) {
Telemetry::Accumulate(Telemetry::DWRITEFONT_INIT_PROBLEM, Telemetry::Accumulate(Telemetry::DWRITEFONT_INIT_PROBLEM,
uint32_t(errGDIInterop)); uint32_t(errGDIInterop));
@@ -1067,11 +1069,8 @@ gfxDWriteFontList::InitFontListForPlatform()
QueryPerformanceCounter(&t2); // base-class/interop initialization QueryPerformanceCounter(&t2); // base-class/interop initialization
RefPtr<IDWriteFactory> factory = mSystemFonts = Factory::GetDWriteSystemFonts(true);
Factory::GetDWriteFactory(); NS_ASSERTION(mSystemFonts != nullptr, "GetSystemFontCollection failed!");
hr = factory->GetSystemFontCollection(getter_AddRefs(mSystemFonts));
NS_ASSERTION(SUCCEEDED(hr), "GetSystemFontCollection failed!");
if (FAILED(hr)) { if (FAILED(hr)) {
Telemetry::Accumulate(Telemetry::DWRITEFONT_INIT_PROBLEM, Telemetry::Accumulate(Telemetry::DWRITEFONT_INIT_PROBLEM,

View File

@@ -882,8 +882,6 @@ description =
description = description =
[PContent::NotifyKeywordSearchLoading] [PContent::NotifyKeywordSearchLoading]
description = description =
[PContent::AllocateLayerTreeId]
description =
[PContent::BeginDriverCrashGuard] [PContent::BeginDriverCrashGuard]
description = description =
[PContent::EndDriverCrashGuard] [PContent::EndDriverCrashGuard]

File diff suppressed because it is too large Load Diff

View File

@@ -93,19 +93,10 @@ JS::Result<Ok> parseAssertedMaybePositionalParameterName(
AssertedScopeKind scopeKind, AssertedScopeKind scopeKind,
MutableHandle<GCVector<JSAtom*>> positionalParams); MutableHandle<GCVector<JSAtom*>> positionalParams);
JS::Result<ParseNode*> parseAssignmentTarget(); JS::Result<ParseNode*> parseAssignmentTarget();
JS::Result<ParseNode*> parseAssignmentTargetOrAssignmentTargetWithInitializer();
JS::Result<ParseNode*> parseAssignmentTargetProperty();
JS::Result<ParseNode*> parseBinding(); JS::Result<ParseNode*> parseBinding();
JS::Result<ParseNode*> parseBindingOrBindingWithInitializer();
JS::Result<ParseNode*> parseBindingProperty();
JS::Result<ParseNode*> parseExpression(); JS::Result<ParseNode*> parseExpression();
JS::Result<ParseNode*> parseExpressionOrSuper(); JS::Result<ParseNode*> parseExpressionOrSuper();
JS::Result<ParseNode*> parseExpressionOrTemplateElement();
JS::Result<ParseNode*> parseForInOfBindingOrAssignmentTarget(); JS::Result<ParseNode*> parseForInOfBindingOrAssignmentTarget();
JS::Result<ParseNode*> parseFunctionDeclarationOrClassDeclarationOrExpression();
JS::Result<ParseNode*> parseFunctionDeclarationOrClassDeclarationOrVariableDeclaration();
JS::Result<ParseNode*> parseImportDeclarationOrExportDeclarationOrStatement();
JS::Result<ParseNode*> parseMethodDefinition();
JS::Result<ParseNode*> parseObjectProperty(); JS::Result<ParseNode*> parseObjectProperty();
JS::Result<ParseNode*> parseParameter(); JS::Result<ParseNode*> parseParameter();
JS::Result<ParseNode*> parseProgram(); JS::Result<ParseNode*> parseProgram();
@@ -117,19 +108,10 @@ JS::Result<Ok> parseSumAssertedMaybePositionalParameterName(const size_t start,
AssertedScopeKind scopeKind, AssertedScopeKind scopeKind,
MutableHandle<GCVector<JSAtom*>> positionalParams); MutableHandle<GCVector<JSAtom*>> positionalParams);
JS::Result<ParseNode*> parseSumAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseSumAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumAssignmentTargetOrAssignmentTargetWithInitializer(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumAssignmentTargetProperty(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumBinding(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseSumBinding(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumBindingOrBindingWithInitializer(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumBindingProperty(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumExpression(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseSumExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumExpressionOrSuper(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseSumExpressionOrSuper(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumExpressionOrTemplateElement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumForInOfBindingOrAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseSumForInOfBindingOrAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumFunctionDeclarationOrClassDeclarationOrExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumFunctionDeclarationOrClassDeclarationOrVariableDeclaration(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumImportDeclarationOrExportDeclarationOrStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumMethodDefinition(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumObjectProperty(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseSumObjectProperty(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumParameter(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseSumParameter(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumProgram(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseSumProgram(const size_t start, const BinKind kind, const BinFields& fields);
@@ -143,8 +125,6 @@ JS::Result<ParseNode*> parseSumVariableDeclarationOrExpression(const size_t star
// ----- Interfaces (by lexicographical order) // ----- Interfaces (by lexicographical order)
// Implementations are autogenerated // Implementations are autogenerated
// `ParseNode*` may never be nullptr // `ParseNode*` may never be nullptr
JS::Result<ParseNode*> parseArrowExpressionContentsWithExpression();
JS::Result<ParseNode*> parseArrowExpressionContentsWithFunctionBody();
JS::Result<Ok> parseAssertedBlockScope(); JS::Result<Ok> parseAssertedBlockScope();
JS::Result<Ok> parseAssertedBoundName( JS::Result<Ok> parseAssertedBoundName(
AssertedScopeKind scopeKind); AssertedScopeKind scopeKind);
@@ -155,14 +135,10 @@ JS::Result<Ok> parseAssertedParameterScope(
MutableHandle<GCVector<JSAtom*>> positionalParams); MutableHandle<GCVector<JSAtom*>> positionalParams);
JS::Result<Ok> parseAssertedScriptGlobalScope(); JS::Result<Ok> parseAssertedScriptGlobalScope();
JS::Result<Ok> parseAssertedVarScope(); JS::Result<Ok> parseAssertedVarScope();
JS::Result<ParseNode*> parseAssignmentTargetIdentifier();
JS::Result<ParseNode*> parseBindingIdentifier(); JS::Result<ParseNode*> parseBindingIdentifier();
JS::Result<ParseNode*> parseBlock(); JS::Result<ParseNode*> parseBlock();
JS::Result<LexicalScopeNode*> parseCatchClause(); JS::Result<LexicalScopeNode*> parseCatchClause();
JS::Result<ParseNode*> parseClassElement();
JS::Result<ParseNode*> parseDirective(); JS::Result<ParseNode*> parseDirective();
JS::Result<ParseNode*> parseExportFromSpecifier();
JS::Result<ParseNode*> parseExportLocalSpecifier();
JS::Result<ListNode*> parseFormalParameters(); JS::Result<ListNode*> parseFormalParameters();
JS::Result<Ok> parseFunctionExpressionContents( JS::Result<Ok> parseFunctionExpressionContents(
uint32_t funLength, uint32_t funLength,
@@ -177,7 +153,6 @@ JS::Result<Ok> parseGetterContents(
ListNode** paramsOut, ListNode** paramsOut,
ListNode** bodyOut); ListNode** bodyOut);
JS::Result<ParseNode*> parseIdentifierExpression(); JS::Result<ParseNode*> parseIdentifierExpression();
JS::Result<ParseNode*> parseImportSpecifier();
JS::Result<Ok> parseSetterContents( JS::Result<Ok> parseSetterContents(
uint32_t funLength, uint32_t funLength,
ListNode** paramsOut, ListNode** paramsOut,
@@ -188,40 +163,30 @@ JS::Result<ParseNode*> parseVariableDeclarator();
JS::Result<ParseNode*> parseInterfaceArrayAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceArrayAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceArrayBinding(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceArrayBinding(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceArrayExpression(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceArrayExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceArrowExpressionContentsWithExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceArrowExpressionContentsWithFunctionBody(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<Ok> parseInterfaceAssertedBlockScope(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<Ok> parseInterfaceAssertedBlockScope(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<Ok> parseInterfaceAssertedBoundName(const size_t start, const BinKind kind, const BinFields& fields, JS::Result<Ok> parseInterfaceAssertedBoundName(const size_t start, const BinKind kind, const BinFields& fields,
AssertedScopeKind scopeKind); AssertedScopeKind scopeKind);
JS::Result<Ok> parseInterfaceAssertedBoundNamesScope(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<Ok> parseInterfaceAssertedBoundNamesScope(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<Ok> parseInterfaceAssertedDeclaredName(const size_t start, const BinKind kind, const BinFields& fields, JS::Result<Ok> parseInterfaceAssertedDeclaredName(const size_t start, const BinKind kind, const BinFields& fields,
AssertedScopeKind scopeKind); AssertedScopeKind scopeKind);
JS::Result<ParseNode*> parseInterfaceAssertedParameterName(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<Ok> parseInterfaceAssertedParameterScope(const size_t start, const BinKind kind, const BinFields& fields, JS::Result<Ok> parseInterfaceAssertedParameterScope(const size_t start, const BinKind kind, const BinFields& fields,
MutableHandle<GCVector<JSAtom*>> positionalParams); MutableHandle<GCVector<JSAtom*>> positionalParams);
JS::Result<Ok> parseInterfaceAssertedPositionalParameterName(const size_t start, const BinKind kind, const BinFields& fields, JS::Result<Ok> parseInterfaceAssertedPositionalParameterName(const size_t start, const BinKind kind, const BinFields& fields,
AssertedScopeKind scopeKind, AssertedScopeKind scopeKind,
MutableHandle<GCVector<JSAtom*>> positionalParams); MutableHandle<GCVector<JSAtom*>> positionalParams);
JS::Result<ParseNode*> parseInterfaceAssertedRestParameterName(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<Ok> parseInterfaceAssertedScriptGlobalScope(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<Ok> parseInterfaceAssertedScriptGlobalScope(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<Ok> parseInterfaceAssertedVarScope(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<Ok> parseInterfaceAssertedVarScope(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceAssignmentExpression(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceAssignmentExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceAssignmentTargetIdentifier(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceAssignmentTargetIdentifier(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceAssignmentTargetPropertyIdentifier(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceAssignmentTargetPropertyProperty(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceAssignmentTargetWithInitializer(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceAwaitExpression(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceAwaitExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceBinaryExpression(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceBinaryExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceBindingIdentifier(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceBindingIdentifier(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceBindingPropertyIdentifier(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceBindingPropertyProperty(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceBindingWithInitializer(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceBindingWithInitializer(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceBlock(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceBlock(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceBreakStatement(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceBreakStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceCallExpression(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceCallExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<LexicalScopeNode*> parseInterfaceCatchClause(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<LexicalScopeNode*> parseInterfaceCatchClause(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceClassDeclaration(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceClassDeclaration(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceClassElement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceClassExpression(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceClassExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceCompoundAssignmentExpression(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceCompoundAssignmentExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceComputedMemberAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceComputedMemberAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
@@ -241,13 +206,6 @@ JS::Result<ParseNode*> parseInterfaceEagerGetter(const size_t start, const BinKi
JS::Result<ParseNode*> parseInterfaceEagerMethod(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceEagerMethod(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceEagerSetter(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceEagerSetter(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceEmptyStatement(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceEmptyStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceExport(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceExportAllFrom(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceExportDefault(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceExportFrom(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceExportFromSpecifier(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceExportLocalSpecifier(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceExportLocals(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceExpressionStatement(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceExpressionStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceForInOfBinding(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceForInOfBinding(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceForInStatement(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceForInStatement(const size_t start, const BinKind kind, const BinFields& fields);
@@ -268,9 +226,6 @@ JS::Result<Ok> parseInterfaceGetterContents(const size_t start, const BinKind ki
ListNode** bodyOut); ListNode** bodyOut);
JS::Result<ParseNode*> parseInterfaceIdentifierExpression(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceIdentifierExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceIfStatement(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceIfStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceImport(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceImportNamespace(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceImportSpecifier(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLabelledStatement(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceLabelledStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLazyArrowExpressionWithExpression(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceLazyArrowExpressionWithExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLazyArrowExpressionWithFunctionBody(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceLazyArrowExpressionWithFunctionBody(const size_t start, const BinKind kind, const BinFields& fields);
@@ -307,7 +262,6 @@ JS::Result<CaseClause*> parseInterfaceSwitchCase(const size_t start, const BinKi
JS::Result<ParseNode*> parseInterfaceSwitchDefault(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceSwitchDefault(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceSwitchStatement(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceSwitchStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceSwitchStatementWithDefault(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceSwitchStatementWithDefault(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceTemplateElement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceTemplateExpression(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceTemplateExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceThisExpression(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceThisExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceThrowStatement(const size_t start, const BinKind kind, const BinFields& fields); JS::Result<ParseNode*> parseInterfaceThrowStatement(const size_t start, const BinKind kind, const BinFields& fields);
@@ -344,18 +298,8 @@ JS::Result<Ok> parseListOfAssertedDeclaredName(
JS::Result<Ok> parseListOfAssertedMaybePositionalParameterName( JS::Result<Ok> parseListOfAssertedMaybePositionalParameterName(
AssertedScopeKind scopeKind, AssertedScopeKind scopeKind,
MutableHandle<GCVector<JSAtom*>> positionalParams); MutableHandle<GCVector<JSAtom*>> positionalParams);
JS::Result<ParseNode*> parseListOfAssignmentTargetOrAssignmentTargetWithInitializer();
JS::Result<ParseNode*> parseListOfAssignmentTargetProperty();
JS::Result<ParseNode*> parseListOfBindingProperty();
JS::Result<ParseNode*> parseListOfClassElement();
JS::Result<ListNode*> parseListOfDirective(); JS::Result<ListNode*> parseListOfDirective();
JS::Result<ParseNode*> parseListOfExportFromSpecifier();
JS::Result<ParseNode*> parseListOfExportLocalSpecifier();
JS::Result<ParseNode*> parseListOfExpressionOrTemplateElement();
JS::Result<ParseNode*> parseListOfImportDeclarationOrExportDeclarationOrStatement();
JS::Result<ParseNode*> parseListOfImportSpecifier();
JS::Result<ListNode*> parseListOfObjectProperty(); JS::Result<ListNode*> parseListOfObjectProperty();
JS::Result<ParseNode*> parseListOfOptionalBindingOrBindingWithInitializer();
JS::Result<ListNode*> parseListOfOptionalSpreadElementOrExpression(); JS::Result<ListNode*> parseListOfOptionalSpreadElementOrExpression();
JS::Result<ListNode*> parseListOfParameter(); JS::Result<ListNode*> parseListOfParameter();
JS::Result<ListNode*> parseListOfStatement(); JS::Result<ListNode*> parseListOfStatement();
@@ -365,10 +309,8 @@ JS::Result<ListNode*> parseListOfVariableDeclarator();
// ----- Default values (by lexicographical order) // ----- Default values (by lexicographical order)
// Implementations are autogenerated // Implementations are autogenerated
JS::Result<ParseNode*> parseOptionalAssignmentTarget();
JS::Result<ParseNode*> parseOptionalBinding(); JS::Result<ParseNode*> parseOptionalBinding();
JS::Result<ParseNode*> parseOptionalBindingIdentifier(); JS::Result<ParseNode*> parseOptionalBindingIdentifier();
JS::Result<ParseNode*> parseOptionalBindingOrBindingWithInitializer();
JS::Result<LexicalScopeNode*> parseOptionalCatchClause(); JS::Result<LexicalScopeNode*> parseOptionalCatchClause();
JS::Result<ParseNode*> parseOptionalExpression(); JS::Result<ParseNode*> parseOptionalExpression();
JS::Result<ParseNode*> parseOptionalSpreadElementOrExpression(); JS::Result<ParseNode*> parseOptionalSpreadElementOrExpression();

View File

@@ -519,14 +519,6 @@ const INTERFACE_ARGS: &str =
const TOPLEVEL_INTERFACE: &str = const TOPLEVEL_INTERFACE: &str =
"Program"; "Program";
/// Get Rc<String> from NodeName.
///
/// FIXME: Do not clone the String itself, but just clone the Rc<String> inside
/// NodeName (Bug 1504597).
fn string_from_nodename(name: &NodeName) -> Rc<String> {
Rc::new(name.to_string().clone())
}
/// The actual exporter. /// The actual exporter.
struct CPPExporter { struct CPPExporter {
/// The syntax to export. /// The syntax to export.
@@ -643,12 +635,24 @@ impl CPPExporter {
// 1. Typesums // 1. Typesums
let sums_of_interfaces = self.syntax.resolved_sums_of_interfaces_by_name(); let sums_of_interfaces = self.syntax.resolved_sums_of_interfaces_by_name();
for (name, nodes) in sums_of_interfaces { for (name, nodes) in sums_of_interfaces {
let rules_for_this_sum = self.rules.get(name);
let mut edges: HashSet<Rc<String>> = HashSet::new(); let mut edges: HashSet<Rc<String>> = HashSet::new();
edges.insert(Rc::new(format!("Sum{}", name))); edges.insert(Rc::new(format!("Sum{}", name)));
refgraph.insert(string_from_nodename(name), edges); refgraph.insert(name.to_rc_string().clone(), edges);
let mut sum_edges: HashSet<Rc<String>> = HashSet::new(); let mut sum_edges: HashSet<Rc<String>> = HashSet::new();
for node in nodes { for node in nodes {
let rule_for_this_arm = rules_for_this_sum.by_sum.get(&node)
.cloned()
.unwrap_or_default();
// If this arm is disabled, we emit raiseError instead of
// call to parseInterface*. Do not add edge in that case.
if rule_for_this_arm.disabled {
continue;
}
sum_edges.insert(Rc::new(format!("Interface{}", node.to_string()))); sum_edges.insert(Rc::new(format!("Interface{}", node.to_string())));
} }
refgraph.insert(Rc::new(format!("Sum{}", name.to_string())), sum_edges); refgraph.insert(Rc::new(format!("Sum{}", name.to_string())), sum_edges);
@@ -657,11 +661,23 @@ impl CPPExporter {
// 2. Single interfaces // 2. Single interfaces
let interfaces_by_name = self.syntax.interfaces_by_name(); let interfaces_by_name = self.syntax.interfaces_by_name();
for (name, interface) in interfaces_by_name { for (name, interface) in interfaces_by_name {
let rules_for_this_interface = self.rules.get(name);
let is_implemented = rules_for_this_interface.build_result.is_some();
// If this interafce is not implemented, parse* method should
// not be called nor referenced in the graph.
if is_implemented {
let mut edges: HashSet<Rc<String>> = HashSet::new(); let mut edges: HashSet<Rc<String>> = HashSet::new();
edges.insert(Rc::new(format!("Interface{}", name))); edges.insert(Rc::new(format!("Interface{}", name)));
refgraph.insert(string_from_nodename(name), edges); refgraph.insert(name.to_rc_string().clone(), edges);
}
let mut interface_edges: HashSet<Rc<String>> = HashSet::new(); let mut interface_edges: HashSet<Rc<String>> = HashSet::new();
// If this interface is not implemented, we emit raiseError in
// parseInterface* method, instead of parse* for each fields.
// There can be reference to parseInterface* of this interface
// from sum interface, and this node needs to be represented in
// the reference graph.
if is_implemented {
for field in interface.contents().fields() { for field in interface.contents().fields() {
match field.type_().get_primitive(&self.syntax) { match field.type_().get_primitive(&self.syntax) {
Some(IsNullable { is_nullable: _, content: Primitive::Interface(_) }) Some(IsNullable { is_nullable: _, content: Primitive::Interface(_) })
@@ -675,19 +691,29 @@ impl CPPExporter {
_ => {} _ => {}
} }
} }
}
refgraph.insert(Rc::new(format!("Interface{}", name)), interface_edges); refgraph.insert(Rc::new(format!("Interface{}", name)), interface_edges);
} }
// 3. String Enums // 3. String Enums
for (kind, _) in self.syntax.string_enums_by_name() { for (kind, _) in self.syntax.string_enums_by_name() {
refgraph.insert(string_from_nodename(kind), HashSet::new()); refgraph.insert(kind.to_rc_string().clone(), HashSet::new());
} }
// 4. Lists // 4. Lists
for parser in &self.list_parsers_to_generate { for parser in &self.list_parsers_to_generate {
let name = &parser.name;
let rules_for_this_list = self.rules.get(name);
let is_implemented = rules_for_this_list.init.is_some();
// If this list is not implemented, this method should not be
// called nor referenced in the graph.
if !is_implemented {
continue;
}
let mut edges: HashSet<Rc<String>> = HashSet::new(); let mut edges: HashSet<Rc<String>> = HashSet::new();
edges.insert(string_from_nodename(&parser.elements)); edges.insert(parser.elements.to_rc_string().clone());
refgraph.insert(string_from_nodename(&parser.name), edges); refgraph.insert(name.to_rc_string().clone(), edges);
} }
// 5. Optional values // 5. Optional values
@@ -722,7 +748,7 @@ impl CPPExporter {
}, },
_ => {} _ => {}
} }
refgraph.insert(string_from_nodename(&parser.name), edges); refgraph.insert(parser.name.to_rc_string().clone(), edges);
} }
// 6. Primitive values. // 6. Primitive values.
@@ -983,7 +1009,7 @@ enum class BinVariant {
buffer.push_str("// Implementations are autogenerated\n"); buffer.push_str("// Implementations are autogenerated\n");
buffer.push_str("// `ParseNode*` may never be nullptr\n"); buffer.push_str("// `ParseNode*` may never be nullptr\n");
for &(ref name, _) in &sums_of_interfaces { for &(ref name, _) in &sums_of_interfaces {
if !self.refgraph.is_used(string_from_nodename(&name)) { if !self.refgraph.is_used(name.to_rc_string().clone()) {
continue; continue;
} }
@@ -1025,7 +1051,7 @@ enum class BinVariant {
let rules_for_this_interface = self.rules.get(name); let rules_for_this_interface = self.rules.get(name);
let extra_params = rules_for_this_interface.extra_params; let extra_params = rules_for_this_interface.extra_params;
if self.refgraph.is_used(string_from_nodename(name)) { if self.refgraph.is_used(name.to_rc_string().clone()) {
let outer = self.get_method_signature(name, "", "", &extra_params); let outer = self.get_method_signature(name, "", "", &extra_params);
outer_parsers.push(outer.reindent("")); outer_parsers.push(outer.reindent(""));
} }
@@ -1058,7 +1084,7 @@ enum class BinVariant {
.iter() .iter()
.sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str()));
for (kind, _) in string_enums_by_name { for (kind, _) in string_enums_by_name {
if !self.refgraph.is_used(string_from_nodename(kind)) { if !self.refgraph.is_used(kind.to_rc_string().clone()) {
continue; continue;
} }
@@ -1072,7 +1098,7 @@ enum class BinVariant {
buffer.push_str("\n\n// ----- Lists (by lexicographical order)\n"); buffer.push_str("\n\n// ----- Lists (by lexicographical order)\n");
buffer.push_str("// Implementations are autogenerated\n"); buffer.push_str("// Implementations are autogenerated\n");
for parser in &self.list_parsers_to_generate { for parser in &self.list_parsers_to_generate {
if !self.refgraph.is_used(string_from_nodename(&parser.name)) { if !self.refgraph.is_used(parser.name.to_rc_string().clone()) {
continue; continue;
} }
@@ -1089,7 +1115,7 @@ enum class BinVariant {
buffer.push_str("\n\n// ----- Default values (by lexicographical order)\n"); buffer.push_str("\n\n// ----- Default values (by lexicographical order)\n");
buffer.push_str("// Implementations are autogenerated\n"); buffer.push_str("// Implementations are autogenerated\n");
for parser in &self.option_parsers_to_generate { for parser in &self.option_parsers_to_generate {
if !self.refgraph.is_used(string_from_nodename(&parser.name)) { if !self.refgraph.is_used(parser.name.to_rc_string().clone()) {
continue; continue;
} }
@@ -1151,7 +1177,7 @@ impl CPPExporter {
.sorted(); .sorted();
let kind = name.to_class_cases(); let kind = name.to_class_cases();
if self.refgraph.is_used(string_from_nodename(name)) { if self.refgraph.is_used(name.to_rc_string().clone()) {
let rendered_bnf = format!("/*\n{name} ::= {nodes}\n*/", let rendered_bnf = format!("/*\n{name} ::= {nodes}\n*/",
nodes = nodes.iter() nodes = nodes.iter()
.format("\n "), .format("\n "),
@@ -1239,7 +1265,7 @@ impl CPPExporter {
/// Generate the implementation of a single list parser /// Generate the implementation of a single list parser
fn generate_implement_list(&self, buffer: &mut String, parser: &ListParserData) { fn generate_implement_list(&self, buffer: &mut String, parser: &ListParserData) {
if !self.refgraph.is_used(string_from_nodename(&parser.name)) { if !self.refgraph.is_used(parser.name.to_rc_string().clone()) {
return; return;
} }
@@ -1332,7 +1358,7 @@ impl CPPExporter {
debug!(target: "generate_spidermonkey", "Implementing optional value {} backed by {}", debug!(target: "generate_spidermonkey", "Implementing optional value {} backed by {}",
parser.name.to_str(), parser.elements.to_str()); parser.name.to_str(), parser.elements.to_str());
if !self.refgraph.is_used(string_from_nodename(&parser.name)) { if !self.refgraph.is_used(parser.name.to_rc_string().clone()) {
return; return;
} }
@@ -1583,7 +1609,7 @@ impl CPPExporter {
} }
} }
if self.refgraph.is_used(string_from_nodename(name)) { if self.refgraph.is_used(name.to_rc_string().clone()) {
// Generate comments // Generate comments
let comment = format!("\n/*\n{}*/\n", ToWebidl::interface(interface, "", " ")); let comment = format!("\n/*\n{}*/\n", ToWebidl::interface(interface, "", " "));
buffer.push_str(&comment); buffer.push_str(&comment);
@@ -1865,7 +1891,7 @@ impl CPPExporter {
.iter() .iter()
.sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str()));
for (kind, enum_) in string_enums_by_name { for (kind, enum_) in string_enums_by_name {
if !self.refgraph.is_used(string_from_nodename(kind)) { if !self.refgraph.is_used(kind.to_rc_string().clone()) {
continue; continue;
} }

View File

@@ -13,7 +13,7 @@
#include "gfxPrefs.h" #include "gfxPrefs.h"
#include "mozilla/layout/RenderFrameParent.h" #include "mozilla/layout/RenderFrame.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsGenericHTMLElement.h" #include "nsGenericHTMLElement.h"
@@ -46,7 +46,7 @@
#include "RetainedDisplayListBuilder.h" #include "RetainedDisplayListBuilder.h"
using namespace mozilla; using namespace mozilla;
using mozilla::layout::RenderFrameParent; using mozilla::layout::RenderFrame;
static bool sShowPreviousPage = true; static bool sShowPreviousPage = true;
@@ -333,9 +333,9 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
return; return;
nsFrameLoader* frameLoader = FrameLoader(); nsFrameLoader* frameLoader = FrameLoader();
RenderFrameParent* rfp = nullptr; RenderFrame* rf = nullptr;
if (frameLoader) { if (frameLoader) {
rfp = frameLoader->GetCurrentRenderFrame(); rf = frameLoader->GetCurrentRenderFrame();
} }
// If we are pointer-events:none then we don't need to HitTest background // If we are pointer-events:none then we don't need to HitTest background
@@ -344,7 +344,7 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (!aBuilder->IsForEventDelivery() || !pointerEventsNone) { if (!aBuilder->IsForEventDelivery() || !pointerEventsNone) {
nsDisplayListCollection decorations(aBuilder); nsDisplayListCollection decorations(aBuilder);
DisplayBorderBackgroundOutline(aBuilder, decorations); DisplayBorderBackgroundOutline(aBuilder, decorations);
if (rfp) { if (rf) {
// Wrap background colors of <iframe>s with remote subdocuments in their // Wrap background colors of <iframe>s with remote subdocuments in their
// own layer so we generate a ColorLayer. This is helpful for optimizing // own layer so we generate a ColorLayer. This is helpful for optimizing
// compositing; we can skip compositing the ColorLayer when the // compositing; we can skip compositing the ColorLayer when the
@@ -366,7 +366,7 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
return; return;
} }
if (rfp) { if (rf) {
// We're the subdoc for <browser remote="true"> and it has // We're the subdoc for <browser remote="true"> and it has
// painted content. Display its shadow layer tree. // painted content. Display its shadow layer tree.
DisplayListClipState::AutoSaveRestore clipState(aBuilder); DisplayListClipState::AutoSaveRestore clipState(aBuilder);
@@ -1081,8 +1081,8 @@ nsSubDocumentFrame::FrameLoader() const
return mFrameLoader; return mFrameLoader;
} }
mozilla::layout::RenderFrameParent* mozilla::layout::RenderFrame*
nsSubDocumentFrame::GetRenderFrameParent() const nsSubDocumentFrame::GetRenderFrame() const
{ {
return FrameLoader() ? FrameLoader()->GetCurrentRenderFrame() : nullptr; return FrameLoader() ? FrameLoader()->GetCurrentRenderFrame() : nullptr;
} }

View File

@@ -15,7 +15,7 @@
namespace mozilla { namespace mozilla {
namespace layout { namespace layout {
class RenderFrameParent; class RenderFrame;
} }
} }
@@ -140,7 +140,7 @@ public:
} }
} }
mozilla::layout::RenderFrameParent* GetRenderFrameParent() const; mozilla::layout::RenderFrame* GetRenderFrame() const;
protected: protected:
friend class AsyncFrameInit; friend class AsyncFrameInit;

View File

@@ -1,37 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=8 et :
*/
/* 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 protocol PBrowser;
include protocol PLayerTransaction;
using class nsRegion from "nsRegion.h";
namespace mozilla {
namespace layout {
/**
* PRenderFrame (in the layout sense of "frame") represents one web
* "page". It's used to graft content processes' layer trees into
* chrome's rendering path. The lifetime of a PRenderFrame is tied to
* its PresShell in the child process.
*
* The child process conceptually "owns" a PRenderFrame, because it
* only makes sense wrt documents loaded by the child.
*/
sync protocol PRenderFrame
{
manager PBrowser;
parent:
async NotifyCompositorTransaction();
async __delete__();
};
} // namespace layout
} // namespace mozilla

View File

@@ -6,34 +6,20 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "BasicLayers.h"
#include "gfxPrefs.h"
#include "mozilla/BrowserElementParent.h"
#include "mozilla/EventForwards.h" // for Modifiers
#include "mozilla/ViewportFrame.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentParent.h" #include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/TabParent.h" #include "mozilla/dom/TabParent.h"
#include "mozilla/layers/CompositorBridgeParent.h" #include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/LayerTransactionParent.h" #include "mozilla/layers/LayerTransactionParent.h"
#include "nsContentUtils.h"
#include "nsFocusManager.h"
#include "nsFrameLoader.h" #include "nsFrameLoader.h"
#include "nsIObserver.h"
#include "nsStyleStructInlines.h" #include "nsStyleStructInlines.h"
#include "nsSubDocumentFrame.h" #include "nsSubDocumentFrame.h"
#include "nsView.h" #include "RenderFrame.h"
#include "RenderFrameParent.h"
#include "mozilla/gfx/GPUProcessManager.h" #include "mozilla/gfx/GPUProcessManager.h"
#include "mozilla/layers/LayerManagerComposite.h"
#include "mozilla/layers/CompositorBridgeChild.h" #include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/layers/WebRenderLayerManager.h" #include "mozilla/layers/WebRenderLayerManager.h"
#include "mozilla/layers/WebRenderScrollData.h" #include "mozilla/layers/WebRenderScrollData.h"
#include "mozilla/webrender/WebRenderAPI.h" #include "mozilla/webrender/WebRenderAPI.h"
#include "ClientLayerManager.h"
#include "FrameLayerBuilder.h"
using namespace mozilla::dom; using namespace mozilla::dom;
using namespace mozilla::gfx; using namespace mozilla::gfx;
@@ -42,39 +28,6 @@ using namespace mozilla::layers;
namespace mozilla { namespace mozilla {
namespace layout { namespace layout {
typedef ScrollableLayerGuid::ViewID ViewID;
/**
* Gets the layer-pixel offset of aContainerFrame's content rect top-left
* from the nearest display item reference frame (which we assume will be inducing
* a ContainerLayer).
*/
static LayoutDeviceIntPoint
GetContentRectLayerOffset(nsIFrame* aContainerFrame, nsDisplayListBuilder* aBuilder)
{
nscoord auPerDevPixel = aContainerFrame->PresContext()->AppUnitsPerDevPixel();
// Offset to the content rect in case we have borders or padding
// Note that aContainerFrame could be a reference frame itself, so
// we need to be careful here to ensure that we call ToReferenceFrame
// on aContainerFrame and not its parent.
nsPoint frameOffset = aBuilder->ToReferenceFrame(aContainerFrame) +
aContainerFrame->GetContentRectRelativeToSelf().TopLeft();
return LayoutDeviceIntPoint::FromAppUnitsToNearest(frameOffset, auPerDevPixel);
}
// Return true iff |aManager| is a "temporary layer manager". They're
// used for small software rendering tasks, like drawWindow. That's
// currently implemented by a BasicLayerManager without a backing
// widget, and hence in non-retained mode.
inline static bool
IsTempLayerManager(LayerManager* aManager)
{
return (mozilla::layers::LayersBackend::LAYERS_BASIC == aManager->GetBackendType() &&
!static_cast<BasicLayerManager*>(aManager)->IsRetained());
}
static already_AddRefed<LayerManager> static already_AddRefed<LayerManager>
GetLayerManager(nsFrameLoader* aFrameLoader) GetLayerManager(nsFrameLoader* aFrameLoader)
{ {
@@ -92,124 +45,77 @@ GetLayerManager(nsFrameLoader* aFrameLoader)
return nsContentUtils::LayerManagerForDocument(doc); return nsContentUtils::LayerManagerForDocument(doc);
} }
RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader) RenderFrame::RenderFrame()
: mLayersId{0} : mLayersId{0}
, mFrameLoader(nullptr)
, mLayerManager(nullptr)
, mInitialized(false)
, mLayersConnected(false) , mLayersConnected(false)
, mFrameLoader(aFrameLoader)
, mFrameLoaderDestroyed(false)
, mAsyncPanZoomEnabled(false)
, mInitted(false)
{ {
mInitted = Init(aFrameLoader);
} }
RenderFrameParent::~RenderFrameParent() RenderFrame::~RenderFrame()
{} {
}
bool bool
RenderFrameParent::Init(nsFrameLoader* aFrameLoader) RenderFrame::Initialize(nsFrameLoader* aFrameLoader)
{ {
if (mInitted || !aFrameLoader) { if (mInitialized || !aFrameLoader) {
return false; return false;
} }
mFrameLoader = aFrameLoader; mFrameLoader = aFrameLoader;
RefPtr<LayerManager> lm = GetLayerManager(mFrameLoader); RefPtr<LayerManager> lm = GetLayerManager(mFrameLoader);
PCompositorBridgeChild* compositor = lm
? lm->GetCompositorBridgeChild()
: nullptr;
mAsyncPanZoomEnabled = lm && lm->AsyncPanZoomEnabled(); TabParent* browser = TabParent::GetFrom(aFrameLoader);
mTabProcessId = browser->Manager()->AsContentParent()->OtherPid();
TabParent* browser = TabParent::GetFrom(mFrameLoader);
if (XRE_IsParentProcess()) {
PCompositorBridgeChild* compositor = nullptr;
if (lm) {
compositor = lm->GetCompositorBridgeChild();
}
// Our remote frame will push layers updates to the compositor, // Our remote frame will push layers updates to the compositor,
// and we'll keep an indirect reference to that tree. // and we'll keep an indirect reference to that tree.
GPUProcessManager* gpm = GPUProcessManager::Get(); GPUProcessManager* gpm = GPUProcessManager::Get();
mLayersConnected = gpm->AllocateAndConnectLayerTreeId( mLayersConnected = gpm->AllocateAndConnectLayerTreeId(
compositor, compositor,
browser->Manager()->AsContentParent()->OtherPid(), mTabProcessId,
&mLayersId, &mLayersId,
&mCompositorOptions); &mCompositorOptions);
} else if (XRE_IsContentProcess()) {
ContentChild::GetSingleton()->SendAllocateLayerTreeId(browser->Manager()->ChildID(), browser->GetTabId(), &mLayersId);
mLayersConnected = CompositorBridgeChild::Get()->SendNotifyChildCreated(mLayersId, &mCompositorOptions);
}
mInitted = true; mInitialized = true;
return true; return true;
} }
bool
RenderFrameParent::IsInitted()
{
return mInitted;
}
void void
RenderFrameParent::Destroy() RenderFrame::Destroy()
{ {
mFrameLoaderDestroyed = true; if (mLayersId.IsValid()) {
GPUProcessManager::Get()->UnmapLayerTreeId(mLayersId, mTabProcessId);
}
mFrameLoader = nullptr;
mLayerManager = nullptr; mLayerManager = nullptr;
} }
already_AddRefed<Layer> void
RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder, RenderFrame::EnsureLayersConnected(CompositorOptions* aCompositorOptions)
nsIFrame* aFrame,
LayerManager* aManager,
nsDisplayItem* aItem,
const ContainerLayerParameters& aContainerParameters)
{ {
MOZ_ASSERT(aFrame, RefPtr<LayerManager> lm = GetLayerManager(mFrameLoader);
"makes no sense to have a shadow tree without a frame"); if (!lm) {
return;
if (IsTempLayerManager(aManager)) {
// This can happen if aManager is a "temporary" manager, or if the
// widget's layer manager changed out from under us. We need to
// FIXME handle the former case somehow, probably with an API to
// draw a manager's subtree. The latter is bad bad bad, but the the
// MOZ_ASSERT() above will flag it. Returning nullptr here will just
// cause the shadow subtree not to be rendered.
if (!aContainerParameters.mForEventsAndPluginsOnly) {
NS_WARNING("Remote iframe not rendered");
}
return nullptr;
} }
if (!mLayersId.IsValid()) { if (!lm->GetCompositorBridgeChild()) {
return nullptr; return;
} }
RefPtr<Layer> layer = mLayersConnected = lm->GetCompositorBridgeChild()->SendNotifyChildRecreated(mLayersId, &mCompositorOptions);
(aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aItem)); *aCompositorOptions = mCompositorOptions;
if (!layer) {
layer = aManager->CreateRefLayer();
}
if (!layer) {
// Probably a temporary layer manager that doesn't know how to
// use ref layers.
return nullptr;
}
static_cast<RefLayer*>(layer.get())->SetReferentId(mLayersId);
LayoutDeviceIntPoint offset = GetContentRectLayerOffset(aFrame, aBuilder);
// We can only have an offset if we're a child of an inactive
// container, but our display item is LAYER_ACTIVE_FORCE which
// forces all layers above to be active.
MOZ_ASSERT(aContainerParameters.mOffset == nsIntPoint());
gfx::Matrix4x4 m = gfx::Matrix4x4::Translation(offset.x, offset.y, 0.0);
// Remote content can't be repainted by us, so we multiply down
// the resolution that our container expects onto our container.
m.PreScale(aContainerParameters.mXScale, aContainerParameters.mYScale, 1.0);
layer->SetBaseTransform(m);
return layer.forget();
} }
LayerManager* LayerManager*
RenderFrameParent::AttachLayerManager() RenderFrame::AttachLayerManager()
{ {
RefPtr<LayerManager> lm; RefPtr<LayerManager> lm;
if (mFrameLoader) { if (mFrameLoader) {
@@ -227,7 +133,7 @@ RenderFrameParent::AttachLayerManager()
} }
void void
RenderFrameParent::OwnerContentChanged(nsIContent* aContent) RenderFrame::OwnerContentChanged(nsIContent* aContent)
{ {
MOZ_ASSERT(!mFrameLoader || mFrameLoader->GetOwnerContent() == aContent, MOZ_ASSERT(!mFrameLoader || mFrameLoader->GetOwnerContent() == aContent,
"Don't build new map if owner is same!"); "Don't build new map if owner is same!");
@@ -236,46 +142,7 @@ RenderFrameParent::OwnerContentChanged(nsIContent* aContent)
} }
void void
RenderFrameParent::ActorDestroy(ActorDestroyReason why) RenderFrame::GetTextureFactoryIdentifier(TextureFactoryIdentifier* aTextureFactoryIdentifier) const
{
if (mLayersId.IsValid()) {
if (XRE_IsParentProcess()) {
GPUProcessManager::Get()->UnmapLayerTreeId(mLayersId, OtherPid());
} else if (XRE_IsContentProcess()) {
TabParent* browser = TabParent::GetFrom(mFrameLoader);
ContentChild::GetSingleton()->SendDeallocateLayerTreeId(browser->Manager()->ChildID(), mLayersId);
}
}
mFrameLoader = nullptr;
mLayerManager = nullptr;
}
mozilla::ipc::IPCResult
RenderFrameParent::RecvNotifyCompositorTransaction()
{
TriggerRepaint();
return IPC_OK();
}
void
RenderFrameParent::TriggerRepaint()
{
nsIFrame* docFrame = mFrameLoader->GetPrimaryFrameOfOwningContent();
if (!docFrame) {
// Bad, but nothing we can do about it (XXX/cjones: or is there?
// maybe bug 589337?). When the new frame is created, we'll
// probably still be the current render frame and will get to draw
// our content then. Or, we're shutting down and this update goes
// to /dev/null.
return;
}
docFrame->InvalidateLayer(DisplayItemType::TYPE_REMOTE);
}
void
RenderFrameParent::GetTextureFactoryIdentifier(TextureFactoryIdentifier* aTextureFactoryIdentifier)
{ {
RefPtr<LayerManager> lm = mFrameLoader ? GetLayerManager(mFrameLoader) : nullptr; RefPtr<LayerManager> lm = mFrameLoader ? GetLayerManager(mFrameLoader) : nullptr;
// Perhaps the document containing this frame currently has no presentation? // Perhaps the document containing this frame currently has no presentation?
@@ -286,41 +153,40 @@ RenderFrameParent::GetTextureFactoryIdentifier(TextureFactoryIdentifier* aTextur
} }
} }
void
RenderFrameParent::TakeFocusForClickFromTap()
{
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (!fm) {
return;
}
RefPtr<Element> element = mFrameLoader->GetOwnerContent();
if (!element) {
return;
}
fm->SetFocus(element, nsIFocusManager::FLAG_BYMOUSE |
nsIFocusManager::FLAG_BYTOUCH |
nsIFocusManager::FLAG_NOSCROLL);
}
void
RenderFrameParent::EnsureLayersConnected(CompositorOptions* aCompositorOptions)
{
RefPtr<LayerManager> lm = GetLayerManager(mFrameLoader);
if (!lm) {
return;
}
if (!lm->GetCompositorBridgeChild()) {
return;
}
mLayersConnected = lm->GetCompositorBridgeChild()->SendNotifyChildRecreated(mLayersId, &mCompositorOptions);
*aCompositorOptions = mCompositorOptions;
}
} // namespace layout } // namespace layout
} // namespace mozilla } // namespace mozilla
/**
* Gets the layer-pixel offset of aContainerFrame's content rect top-left
* from the nearest display item reference frame (which we assume will be inducing
* a ContainerLayer).
*/
static mozilla::LayoutDeviceIntPoint
GetContentRectLayerOffset(nsIFrame* aContainerFrame, nsDisplayListBuilder* aBuilder)
{
nscoord auPerDevPixel = aContainerFrame->PresContext()->AppUnitsPerDevPixel();
// Offset to the content rect in case we have borders or padding
// Note that aContainerFrame could be a reference frame itself, so
// we need to be careful here to ensure that we call ToReferenceFrame
// on aContainerFrame and not its parent.
nsPoint frameOffset = aBuilder->ToReferenceFrame(aContainerFrame) +
aContainerFrame->GetContentRectRelativeToSelf().TopLeft();
return mozilla::LayoutDeviceIntPoint::FromAppUnitsToNearest(frameOffset, auPerDevPixel);
}
// Return true iff |aManager| is a "temporary layer manager". They're
// used for small software rendering tasks, like drawWindow. That's
// currently implemented by a BasicLayerManager without a backing
// widget, and hence in non-retained mode.
inline static bool
IsTempLayerManager(mozilla::layers::LayerManager* aManager)
{
return (mozilla::layers::LayersBackend::LAYERS_BASIC == aManager->GetBackendType() &&
!static_cast<BasicLayerManager*>(aManager)->IsRetained());
}
nsDisplayRemote::nsDisplayRemote(nsDisplayListBuilder* aBuilder, nsDisplayRemote::nsDisplayRemote(nsDisplayListBuilder* aBuilder,
nsSubDocumentFrame* aFrame) nsSubDocumentFrame* aFrame)
: nsDisplayItem(aBuilder, aFrame) : nsDisplayItem(aBuilder, aFrame)
@@ -337,7 +203,7 @@ nsDisplayRemote::nsDisplayRemote(nsDisplayListBuilder* aBuilder,
mEventRegionsOverride |= EventRegionsOverride::ForceDispatchToContent; mEventRegionsOverride |= EventRegionsOverride::ForceDispatchToContent;
} }
nsFrameLoader* frameLoader = GetRenderFrameParent()->FrameLoader(); nsFrameLoader* frameLoader = GetRenderFrame()->GetFrameLoader();
if (frameLoader) { if (frameLoader) {
TabParent* browser = TabParent::GetFrom(frameLoader); TabParent* browser = TabParent::GetFrom(frameLoader);
if (browser) { if (browser) {
@@ -351,7 +217,7 @@ nsDisplayRemote::GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager, LayerManager* aManager,
const ContainerLayerParameters& aParameters) const ContainerLayerParameters& aParameters)
{ {
if (mozilla::layout::IsTempLayerManager(aManager)) { if (IsTempLayerManager(aManager)) {
return mozilla::LAYER_NONE; return mozilla::LAYER_NONE;
} }
return mozilla::LAYER_ACTIVE_FORCE; return mozilla::LAYER_ACTIVE_FORCE;
@@ -360,8 +226,8 @@ nsDisplayRemote::GetLayerState(nsDisplayListBuilder* aBuilder,
bool bool
nsDisplayRemote::HasDeletedFrame() const nsDisplayRemote::HasDeletedFrame() const
{ {
// RenderFrameParent might change without invalidating nsSubDocumentFrame. // RenderFrame might change without invalidating nsSubDocumentFrame.
return !GetRenderFrameParent() || nsDisplayItem::HasDeletedFrame(); return !GetRenderFrame() || nsDisplayItem::HasDeletedFrame();
} }
already_AddRefed<Layer> already_AddRefed<Layer>
@@ -369,15 +235,57 @@ nsDisplayRemote::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager, LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) const ContainerLayerParameters& aContainerParameters)
{ {
MOZ_ASSERT(GetRenderFrameParent()); MOZ_ASSERT(GetRenderFrame());
MOZ_ASSERT(mFrame, "Makes no sense to have a shadow tree without a frame");
if (IsTempLayerManager(aManager)) {
// This can happen if aManager is a "temporary" manager, or if the
// widget's layer manager changed out from under us. We need to
// FIXME handle the former case somehow, probably with an API to
// draw a manager's subtree. The latter is bad bad bad, but the the
// MOZ_ASSERT() above will flag it. Returning nullptr here will just
// cause the shadow subtree not to be rendered.
if (!aContainerParameters.mForEventsAndPluginsOnly) {
NS_WARNING("Remote iframe not rendered");
}
return nullptr;
}
LayersId remoteId = GetRenderFrame()->GetLayersId();
if (!remoteId.IsValid()) {
return nullptr;
}
RefPtr<Layer> layer = RefPtr<Layer> layer =
GetRenderFrameParent()->BuildLayer(aBuilder, mFrame, aManager, aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, this);
this, aContainerParameters);
if (layer && layer->AsRefLayer()) { if (!layer) {
layer = aManager->CreateRefLayer();
}
if (!layer) {
// Probably a temporary layer manager that doesn't know how to
// use ref layers.
return nullptr;
}
static_cast<RefLayer*>(layer.get())->SetReferentId(remoteId);
LayoutDeviceIntPoint offset = GetContentRectLayerOffset(Frame(), aBuilder);
// We can only have an offset if we're a child of an inactive
// container, but our display item is LAYER_ACTIVE_FORCE which
// forces all layers above to be active.
MOZ_ASSERT(aContainerParameters.mOffset == nsIntPoint());
Matrix4x4 m = Matrix4x4::Translation(offset.x, offset.y, 0.0);
// Remote content can't be repainted by us, so we multiply down
// the resolution that our container expects onto our container.
m.PreScale(aContainerParameters.mXScale, aContainerParameters.mYScale, 1.0);
layer->SetBaseTransform(m);
if (layer->AsRefLayer()) {
layer->AsRefLayer()->SetEventRegionsOverride(mEventRegionsOverride); layer->AsRefLayer()->SetEventRegionsOverride(mEventRegionsOverride);
} }
return layer.forget(); return layer.forget();
} }
@@ -403,9 +311,9 @@ nsDisplayRemote::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuild
mozilla::layers::WebRenderLayerManager* aManager, mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder) nsDisplayListBuilder* aDisplayListBuilder)
{ {
mOffset = mozilla::layout::GetContentRectLayerOffset(mFrame, aDisplayListBuilder); mOffset = GetContentRectLayerOffset(mFrame, aDisplayListBuilder);
mozilla::LayoutDeviceRect rect = mozilla::LayoutDeviceRect::FromAppUnits( LayoutDeviceRect rect = LayoutDeviceRect::FromAppUnits(
mFrame->GetContentRectRelativeToSelf(), mFrame->PresContext()->AppUnitsPerDevPixel()); mFrame->GetContentRectRelativeToSelf(), mFrame->PresContext()->AppUnitsPerDevPixel());
rect += mOffset; rect += mOffset;
@@ -432,14 +340,14 @@ nsDisplayRemote::UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
LayersId LayersId
nsDisplayRemote::GetRemoteLayersId() const nsDisplayRemote::GetRemoteLayersId() const
{ {
MOZ_ASSERT(GetRenderFrameParent()); MOZ_ASSERT(GetRenderFrame());
return GetRenderFrameParent()->GetLayersId(); return GetRenderFrame()->GetLayersId();
} }
mozilla::layout::RenderFrameParent* mozilla::layout::RenderFrame*
nsDisplayRemote::GetRenderFrameParent() const nsDisplayRemote::GetRenderFrame() const
{ {
return mFrame return mFrame
? static_cast<nsSubDocumentFrame*>(mFrame)->GetRenderFrameParent() ? static_cast<nsSubDocumentFrame*>(mFrame)->GetRenderFrame()
: nullptr; : nullptr;
} }

134
layout/ipc/RenderFrame.h Normal file
View File

@@ -0,0 +1,134 @@
/* -*- 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 mozilla_layout_RenderFrame_h
#define mozilla_layout_RenderFrame_h
#include "base/process.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/ipc/IdType.h"
#include "mozilla/layers/CompositorOptions.h"
#include "mozilla/layers/LayersTypes.h"
#include "nsDisplayList.h"
class nsFrameLoader;
class nsSubDocumentFrame;
namespace mozilla {
namespace layers {
struct TextureFactoryIdentifier;
} // namespace layers
namespace layout {
class RenderFrame final
{
typedef mozilla::layers::CompositorOptions CompositorOptions;
typedef mozilla::layers::LayerManager LayerManager;
typedef mozilla::layers::LayersId LayersId;
typedef mozilla::layers::TextureFactoryIdentifier TextureFactoryIdentifier;
public:
RenderFrame();
virtual ~RenderFrame();
bool Initialize(nsFrameLoader* aFrameLoader);
void Destroy();
void EnsureLayersConnected(CompositorOptions* aCompositorOptions);
LayerManager* AttachLayerManager();
void OwnerContentChanged(nsIContent* aContent);
nsFrameLoader* GetFrameLoader() const { return mFrameLoader; }
LayersId GetLayersId() const { return mLayersId; }
CompositorOptions GetCompositorOptions() const { return mCompositorOptions; }
void GetTextureFactoryIdentifier(TextureFactoryIdentifier* aTextureFactoryIdentifier) const;
bool IsInitialized() const { return mInitialized; }
bool IsLayersConnected() const { return mLayersConnected; }
private:
base::ProcessId mTabProcessId;
// When our child frame is pushing transactions directly to the
// compositor, this is the ID of its layer tree in the compositor's
// context.
LayersId mLayersId;
// The compositor options for this layers id. This is only meaningful if
// the compositor actually knows about this layers id (i.e. when mLayersConnected
// is true).
CompositorOptions mCompositorOptions;
RefPtr<nsFrameLoader> mFrameLoader;
RefPtr<LayerManager> mLayerManager;
bool mInitialized;
// A flag that indicates whether or not the compositor knows about the
// layers id. In some cases this RenderFrame is not connected to the
// compositor and so this flag is false.
bool mLayersConnected;
};
} // namespace layout
} // namespace mozilla
/**
* A DisplayRemote exists solely to graft a child process's shadow
* layer tree (for a given RenderFrame) into its parent
* process's layer tree.
*/
class nsDisplayRemote final : public nsDisplayItem
{
typedef mozilla::dom::TabId TabId;
typedef mozilla::gfx::Matrix4x4 Matrix4x4;
typedef mozilla::layers::EventRegionsOverride EventRegionsOverride;
typedef mozilla::layers::Layer Layer;
typedef mozilla::layers::LayersId LayersId;
typedef mozilla::layers::RefLayer RefLayer;
typedef mozilla::layout::RenderFrame RenderFrame;
typedef mozilla::LayoutDeviceRect LayoutDeviceRect;
typedef mozilla::LayoutDeviceIntPoint LayoutDeviceIntPoint;
public:
nsDisplayRemote(nsDisplayListBuilder* aBuilder,
nsSubDocumentFrame* aFrame);
bool HasDeletedFrame() const override;
LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
already_AddRefed<Layer>
BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder) override;
bool UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
mozilla::layers::WebRenderLayerScrollData* aLayerData) override;
NS_DISPLAY_DECL_NAME("Remote", TYPE_REMOTE)
private:
LayersId GetRemoteLayersId() const;
RenderFrame* GetRenderFrame() const;
TabId mTabId;
LayoutDeviceIntPoint mOffset;
EventRegionsOverride mEventRegionsOverride;
};
#endif // mozilla_layout_RenderFrame_h

View File

@@ -1,34 +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 "RenderFrameChild.h"
#include "mozilla/layers/LayerTransactionChild.h"
using mozilla::layers::PLayerTransactionChild;
using mozilla::layers::LayerTransactionChild;
namespace mozilla {
namespace layout {
void
RenderFrameChild::ActorDestroy(ActorDestroyReason why)
{
mWasDestroyed = true;
}
void
RenderFrameChild::Destroy()
{
if (mWasDestroyed) {
return;
}
Send__delete__(this);
// WARNING: |this| is dead, hands off
}
} // namespace layout
} // namespace mozilla

View File

@@ -1,32 +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 mozilla_dom_RenderFrameChild_h
#define mozilla_dom_RenderFrameChild_h
#include "mozilla/layout/PRenderFrameChild.h"
namespace mozilla {
namespace layout {
class RenderFrameChild : public PRenderFrameChild
{
public:
RenderFrameChild() : mWasDestroyed(false) {}
virtual ~RenderFrameChild() {}
void ActorDestroy(ActorDestroyReason why) override;
void Destroy();
private:
bool mWasDestroyed;
};
} // namespace layout
} // namespace mozilla
#endif // mozilla_dom_RenderFrameChild_h

View File

@@ -1,189 +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 mozilla_layout_RenderFrameParent_h
#define mozilla_layout_RenderFrameParent_h
#include "mozilla/Attributes.h"
#include <map>
#include "mozilla/dom/ipc/IdType.h"
#include "mozilla/layers/APZUtils.h"
#include "mozilla/layers/CompositorOptions.h"
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/layout/PRenderFrameParent.h"
#include "nsDisplayList.h"
class nsFrameLoader;
class nsSubDocumentFrame;
namespace mozilla {
class InputEvent;
namespace layers {
class AsyncDragMetrics;
class TargetConfig;
struct TextureFactoryIdentifier;
struct ScrollableLayerGuid;
} // namespace layers
namespace layout {
class RenderFrameParent final : public PRenderFrameParent
{
typedef mozilla::layers::AsyncDragMetrics AsyncDragMetrics;
typedef mozilla::layers::FrameMetrics FrameMetrics;
typedef mozilla::layers::CompositorOptions CompositorOptions;
typedef mozilla::layers::ContainerLayer ContainerLayer;
typedef mozilla::layers::Layer Layer;
typedef mozilla::layers::LayerManager LayerManager;
typedef mozilla::layers::LayersId LayersId;
typedef mozilla::layers::TargetConfig TargetConfig;
typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
typedef mozilla::layers::TextureFactoryIdentifier TextureFactoryIdentifier;
typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
typedef mozilla::layers::TouchBehaviorFlags TouchBehaviorFlags;
typedef mozilla::layers::ZoomConstraints ZoomConstraints;
typedef ScrollableLayerGuid::ViewID ViewID;
public:
/**
* Select the desired scrolling behavior. If ASYNC_PAN_ZOOM is
* chosen, then RenderFrameParent will watch input events and use
* them to asynchronously pan and zoom.
*/
explicit RenderFrameParent(nsFrameLoader* aFrameLoader);
virtual ~RenderFrameParent();
bool Init(nsFrameLoader* aFrameLoader);
bool IsInitted();
void Destroy();
already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
LayerManager* aManager,
nsDisplayItem* aItem,
const ContainerLayerParameters& aContainerParameters);
void OwnerContentChanged(nsIContent* aContent);
bool HitTest(const nsRect& aRect);
void GetTextureFactoryIdentifier(TextureFactoryIdentifier* aTextureFactoryIdentifier);
inline LayersId GetLayersId() const { return mLayersId; }
inline bool IsLayersConnected() const { return mLayersConnected; }
inline CompositorOptions GetCompositorOptions() const { return mCompositorOptions; }
void TakeFocusForClickFromTap();
void EnsureLayersConnected(CompositorOptions* aCompositorOptions);
LayerManager* AttachLayerManager();
nsFrameLoader* FrameLoader() const
{
return mFrameLoader;
}
protected:
void ActorDestroy(ActorDestroyReason why) override;
virtual mozilla::ipc::IPCResult RecvNotifyCompositorTransaction() override;
private:
void TriggerRepaint();
void DispatchEventForPanZoomController(const InputEvent& aEvent);
// When our child frame is pushing transactions directly to the
// compositor, this is the ID of its layer tree in the compositor's
// context.
LayersId mLayersId;
// A flag that indicates whether or not the compositor knows about the
// layers id. In some cases this RenderFrameParent is not connected to the
// compositor and so this flag is false.
bool mLayersConnected;
// The compositor options for this layers id. This is only meaningful if
// the compositor actually knows about this layers id (i.e. when mLayersConnected
// is true).
CompositorOptions mCompositorOptions;
RefPtr<nsFrameLoader> mFrameLoader;
RefPtr<LayerManager> mLayerManager;
// True after Destroy() has been called, which is triggered
// originally by nsFrameLoader::Destroy(). After this point, we can
// no longer safely ask the frame loader to find its nearest layer
// manager, because it may have been disconnected from the DOM.
// It's still OK to *tell* the frame loader that we've painted after
// it's destroyed; it'll just ignore us, and we won't be able to
// find an nsIFrame to invalidate. See ShadowLayersUpdated().
//
// Prefer the extra bit of state to null'ing out mFrameLoader in
// Destroy() so that less code needs to be special-cased for after
// Destroy().
//
// It's possible for mFrameLoader==null and
// mFrameLoaderDestroyed==false.
bool mFrameLoaderDestroyed;
bool mAsyncPanZoomEnabled;
bool mInitted;
};
} // namespace layout
} // namespace mozilla
/**
* A DisplayRemote exists solely to graft a child process's shadow
* layer tree (for a given RenderFrameParent) into its parent
* process's layer tree.
*/
class nsDisplayRemote final : public nsDisplayItem
{
typedef mozilla::layout::RenderFrameParent RenderFrameParent;
public:
nsDisplayRemote(nsDisplayListBuilder* aBuilder,
nsSubDocumentFrame* aFrame);
bool HasDeletedFrame() const override;
LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
already_AddRefed<Layer>
BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder) override;
bool UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
mozilla::layers::WebRenderLayerScrollData* aLayerData) override;
NS_DISPLAY_DECL_NAME("Remote", TYPE_REMOTE)
private:
mozilla::layers::LayersId GetRemoteLayersId() const;
RenderFrameParent* GetRenderFrameParent() const;
mozilla::dom::TabId mTabId;
mozilla::LayoutDeviceIntPoint mOffset;
mozilla::layers::EventRegionsOverride mEventRegionsOverride;
};
#endif // mozilla_layout_RenderFrameParent_h

View File

@@ -8,15 +8,13 @@ with Files('**'):
BUG_COMPONENT = ('Core', 'Web Painting') BUG_COMPONENT = ('Core', 'Web Painting')
EXPORTS.mozilla.layout += [ EXPORTS.mozilla.layout += [
'RenderFrameChild.h', 'RenderFrame.h',
'RenderFrameParent.h',
'VsyncChild.h', 'VsyncChild.h',
'VsyncParent.h', 'VsyncParent.h',
] ]
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [
'RenderFrameChild.cpp', 'RenderFrame.cpp',
'RenderFrameParent.cpp',
] ]
SOURCES += [ SOURCES += [
@@ -25,7 +23,6 @@ SOURCES += [
] ]
IPDL_SOURCES = [ IPDL_SOURCES = [
'PRenderFrame.ipdl',
'PVsync.ipdl', 'PVsync.ipdl',
] ]

View File

@@ -439,6 +439,13 @@ VARCACHE_PREF(
RelaxedAtomicBool, false RelaxedAtomicBool, false
) )
// Block multiple window.open() per single event.
VARCACHE_PREF(
"dom.block_multiple_popups",
dom_block_multiple_popups,
bool, true
)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Clear-Site-Data prefs // Clear-Site-Data prefs
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

15
mozilla-config.h.in Normal file → Executable file
View File

@@ -45,6 +45,21 @@
*/ */
#if defined(CHROMIUM_SANDBOX_BUILD) && defined(XP_WIN) #if defined(CHROMIUM_SANDBOX_BUILD) && defined(XP_WIN)
#include "base/win/sdkdecls.h" #include "base/win/sdkdecls.h"
#ifdef __MINGW32__
/*
* MinGW doesn't support __try / __except. There are a few mechanisms available
* to hack around it and pseudo-support it, but these are untested in Firefox.
* What is tested (and works) is replacing them with if(true) and else.
*/
#define __try if(true)
#define __except(x) else
#ifdef GetExceptionCode
#undef GetExceptionCode
#endif
#define GetExceptionCode() 0
#endif /* __MINGW32__ */
#endif /* defined(CHROMIUM_SANDBOX_BUILD) && defined(XP_WIN) */ #endif /* defined(CHROMIUM_SANDBOX_BUILD) && defined(XP_WIN) */
#endif /* MOZILLA_CONFIG_H */ #endif /* MOZILLA_CONFIG_H */

View File

@@ -0,0 +1,51 @@
# HG changeset patch
# User Tom Ritter <tom@mozilla.com>
# Date 1516389982 21600
# Fri Jan 19 13:26:22 2018 -0600
# Node ID 3ca7306d73ebc1ce47ccdc62ee8cbb69a9bfbb2c
# Parent 6aa6c7d894609140ccde2e9e50eba8c25a9caeb5
Bug 1431803 Disable a specific __try block on MinGW r?bobowen
This function is a technique to name a thread for debugging purposes,
and it always throws an exception (and then continues). On MinGW
we don't want it to throw an exception, so we do nothing.
This means on MinGW we won't get nice thread naming during debugging,
but we'll limp along.
MozReview-Commit-ID: JRKY4wp7sdu
diff --git a/security/sandbox/chromium/base/threading/platform_thread_win.cc b/security/sandbox/chromium/base/threading/platform_thread_win.cc
--- a/security/sandbox/chromium/base/threading/platform_thread_win.cc
+++ b/security/sandbox/chromium/base/threading/platform_thread_win.cc
@@ -32,27 +32,30 @@ typedef struct tagTHREADNAME_INFO {
} THREADNAME_INFO;
// The SetThreadDescription API was brought in version 1607 of Windows 10.
typedef HRESULT(WINAPI* SetThreadDescription)(HANDLE hThread,
PCWSTR lpThreadDescription);
// This function has try handling, so it is separated out of its caller.
void SetNameInternal(PlatformThreadId thread_id, const char* name) {
+ //This function is only used for debugging purposes, as you can find by its caller
+#ifndef __MINGW32__
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = name;
info.dwThreadID = thread_id;
info.dwFlags = 0;
__try {
RaiseException(kVCThreadNameException, 0, sizeof(info)/sizeof(DWORD),
reinterpret_cast<DWORD_PTR*>(&info));
} __except(EXCEPTION_CONTINUE_EXECUTION) {
}
+#endif
}
struct ThreadParams {
PlatformThread::Delegate* delegate;
bool joinable;
ThreadPriority priority;
};

View File

@@ -17,4 +17,5 @@ mingw_copy_s.patch
mingw_operator_new.patch mingw_operator_new.patch
mingw_cast_getprocaddress.patch mingw_cast_getprocaddress.patch
mingw_capitalization.patch mingw_capitalization.patch
mingw_disable_one_try.patch
mingw_offsetof.patch mingw_offsetof.patch

View File

@@ -37,6 +37,8 @@ typedef HRESULT(WINAPI* SetThreadDescription)(HANDLE hThread,
// This function has try handling, so it is separated out of its caller. // This function has try handling, so it is separated out of its caller.
void SetNameInternal(PlatformThreadId thread_id, const char* name) { void SetNameInternal(PlatformThreadId thread_id, const char* name) {
//This function is only used for debugging purposes, as you can find by its caller
#ifndef __MINGW32__
THREADNAME_INFO info; THREADNAME_INFO info;
info.dwType = 0x1000; info.dwType = 0x1000;
info.szName = name; info.szName = name;
@@ -48,6 +50,7 @@ void SetNameInternal(PlatformThreadId thread_id, const char* name) {
reinterpret_cast<DWORD_PTR*>(&info)); reinterpret_cast<DWORD_PTR*>(&info));
} __except(EXCEPTION_CONTINUE_EXECUTION) { } __except(EXCEPTION_CONTINUE_EXECUTION) {
} }
#endif
} }
struct ThreadParams { struct ThreadParams {

View File

@@ -55,14 +55,8 @@ class DeviceRunner(BaseRunner):
@property @property
def command(self): def command(self):
cmd = [self.app_ctx.adb] # command built by mozdevice -- see start() below
if self.app_ctx.device_serial: return None
cmd.extend(['-s', self.app_ctx.device_serial])
cmd.append('shell')
for k, v in self._device_env.iteritems():
cmd.append('%s=%s' % (k, v))
cmd.append(self.app_ctx.remote_binary)
return cmd
def start(self, *args, **kwargs): def start(self, *args, **kwargs):
if isinstance(self.device, BaseEmulator) and not self.device.connected: if isinstance(self.device, BaseEmulator) and not self.device.connected:
@@ -70,15 +64,18 @@ class DeviceRunner(BaseRunner):
self.device.connect() self.device.connect()
self.device.setup_profile(self.profile) self.device.setup_profile(self.profile)
# TODO: this doesn't work well when the device is running but dropped app = self.app_ctx.remote_process
# wifi for some reason. It would be good to probe the state of the device args = ["-no-remote", "-profile", self.app_ctx.remote_profile]
# to see if we have the homescreen running, or something, before waiting here args.extend(self.cmdargs)
self.device.wait_for_net() env = self._device_env
url = None
if not self.device.wait_for_net(): if 'geckoview' in app:
raise Exception("Network did not come up when starting device") activity = "TestRunnerActivity"
self.app_ctx.device.launch_activity(app, activity, e10s=True, moz_env=env,
pid = BaseRunner.start(self, *args, **kwargs) extra_args=args, url=url)
else:
self.app_ctx.device.launch_fennec(
app, moz_env=env, extra_args=args, url=url)
timeout = 10 # seconds timeout = 10 # seconds
end_time = datetime.datetime.now() + datetime.timedelta(seconds=timeout) end_time = datetime.datetime.now() + datetime.timedelta(seconds=timeout)
@@ -87,10 +84,6 @@ class DeviceRunner(BaseRunner):
if not self.is_running(): if not self.is_running():
print("timed out waiting for '%s' process to start" % self.app_ctx.remote_process) print("timed out waiting for '%s' process to start" % self.app_ctx.remote_process)
if not self.device.wait_for_net():
raise Exception("Failed to get a network connection")
return pid
def stop(self, sig=None): def stop(self, sig=None):
if not sig and self.is_running(): if not sig and self.is_running():
self.app_ctx.stop_application() self.app_ctx.stop_application()
@@ -184,20 +177,3 @@ class FennecRunner(DeviceRunner):
def __init__(self, cmdargs=None, **kwargs): def __init__(self, cmdargs=None, **kwargs):
super(FennecRunner, self).__init__(**kwargs) super(FennecRunner, self).__init__(**kwargs)
self.cmdargs = cmdargs or [] self.cmdargs = cmdargs or []
@property
def command(self):
cmd = [self.app_ctx.adb]
if self.app_ctx.device_serial:
cmd.extend(["-s", self.app_ctx.device_serial])
cmd.append("shell")
app = "%s/org.mozilla.gecko.BrowserApp" % self.app_ctx.remote_process
am_subcommand = ["am", "start", "-a", "android.activity.MAIN", "-n", app]
app_params = ["-no-remote", "-profile", self.app_ctx.remote_profile]
app_params.extend(self.cmdargs)
am_subcommand.extend(["--es", "args", "'%s'" % " ".join(app_params)])
# Append env variables in the form |--es env0 MOZ_CRASHREPORTER=1|
for (count, (k, v)) in enumerate(self._device_env.iteritems()):
am_subcommand.extend(["--es", "env%d" % count, "%s=%s" % (k, v)])
cmd.append("%s" % " ".join(am_subcommand))
return cmd

View File

@@ -107,6 +107,7 @@ user_pref("dom.ipc.reportProcessHangs", false); // process hang monitor
user_pref("dom.ipc.tabs.shutdownTimeoutSecs", 0); user_pref("dom.ipc.tabs.shutdownTimeoutSecs", 0);
user_pref("dom.min_background_timeout_value", 1000); user_pref("dom.min_background_timeout_value", 1000);
user_pref("dom.popup_maximum", -1); user_pref("dom.popup_maximum", -1);
user_pref("dom.block_multiple_popups", false);
user_pref("dom.presentation.testing.simulate-receiver", false); user_pref("dom.presentation.testing.simulate-receiver", false);
// Prevent connection to the push server for tests. // Prevent connection to the push server for tests.
user_pref("dom.push.connection.enabled", false); user_pref("dom.push.connection.enabled", false);

View File

@@ -1,23 +1,4 @@
[createImageBitmap-origin.sub.html] [createImageBitmap-origin.sub.html]
prefs: [network.http.send_window_size:0] prefs: [network.http.send_window_size:0]
[cross-origin HTMLImageElement]
expected: FAIL
[cross-origin SVGImageElement]
expected: FAIL
[cross-origin HTMLVideoElement]
expected: FAIL
[unclean HTMLCanvasElement]
expected: FAIL
[unclean ImageBitmap]
expected: FAIL
[redirected to cross-origin HTMLVideoElement]
expected: FAIL
[redirected to same-origin HTMLVideoElement] [redirected to same-origin HTMLVideoElement]
expected: FAIL expected: FAIL

View File

@@ -213,7 +213,7 @@ class FennecBrowser(FirefoxBrowser):
process_class=ProcessHandler, process_class=ProcessHandler,
process_args={"processOutputLine": [self.on_output]}) process_args={"processOutputLine": [self.on_output]})
self.logger.debug("Starting Fennec") self.logger.debug("Starting %s" % self.package_name)
# connect to a running emulator # connect to a running emulator
self.runner.device.connect() self.runner.device.connect()
@@ -225,7 +225,7 @@ class FennecBrowser(FirefoxBrowser):
local="tcp:{}".format(self.marionette_port), local="tcp:{}".format(self.marionette_port),
remote="tcp:{}".format(self.marionette_port)) remote="tcp:{}".format(self.marionette_port))
self.logger.debug("Fennec Started") self.logger.debug("%s Started" % self.package_name)
def stop(self, force=False): def stop(self, force=False):
if self.runner is not None: if self.runner is not None:

View File

@@ -227,7 +227,9 @@ class XPCShellTestThread(Thread):
Simple wrapper to get the return code for a given process. Simple wrapper to get the return code for a given process.
On a remote system we overload this to work with the remote process management. On a remote system we overload this to work with the remote process management.
""" """
if proc is not None and hasattr(proc, "returncode"):
return proc.returncode return proc.returncode
return -1
def communicate(self, proc): def communicate(self, proc):
""" """
@@ -284,7 +286,10 @@ class XPCShellTestThread(Thread):
self.log.info("%s | environment: %s" % (name, list(changedEnv))) self.log.info("%s | environment: %s" % (name, list(changedEnv)))
def killTimeout(self, proc): def killTimeout(self, proc):
if proc is not None and hasattr(proc, "pid"):
mozcrash.kill_and_get_minidump(proc.pid, self.tempDir, utility_path=self.utility_path) mozcrash.kill_and_get_minidump(proc.pid, self.tempDir, utility_path=self.utility_path)
else:
self.log.info("not killing -- proc or pid unknown")
def postCheck(self, proc): def postCheck(self, proc):
"""Checks for a still-running test process, kills it and fails the test if found. """Checks for a still-running test process, kills it and fails the test if found.

View File

@@ -147,7 +147,7 @@ Lock::Find(void* aNativeLock)
// When diverged from the recording, don't allow uses of locks that are // When diverged from the recording, don't allow uses of locks that are
// held by idling threads that have not diverged from the recording. // held by idling threads that have not diverged from the recording.
// This will cause the process to deadlock, so rewind instead. // This will cause the process to deadlock, so rewind instead.
if (lock->mOwner && Thread::GetById(lock->mOwner)->IsIdle()) { if (lock->mOwner && Thread::GetById(lock->mOwner)->ShouldIdle()) {
ex.reset(); ex.reset();
EnsureNotDivergedFromRecording(); EnsureNotDivergedFromRecording();
Unreachable(); Unreachable();

View File

@@ -302,9 +302,9 @@ public:
// Allow a single thread to resume execution. // Allow a single thread to resume execution.
static void ResumeSingleIdleThread(size_t aId); static void ResumeSingleIdleThread(size_t aId);
// Return whether this thread is in the idle state entered after // Return whether this thread will remain in the idle state entered after
// WaitForIdleThreads. // WaitForIdleThreads.
bool IsIdle() { return mIdle; } bool ShouldIdle() { return mShouldIdle; }
}; };
// This uses a stack pointer instead of TLS to make sure events are passed // This uses a stack pointer instead of TLS to make sure events are passed

View File

@@ -151,6 +151,7 @@ void
Channel::SendMessage(const Message& aMsg) Channel::SendMessage(const Message& aMsg)
{ {
MOZ_RELEASE_ASSERT(NS_IsMainThread() || MOZ_RELEASE_ASSERT(NS_IsMainThread() ||
aMsg.mType == MessageType::BeginFatalError ||
aMsg.mType == MessageType::FatalError || aMsg.mType == MessageType::FatalError ||
aMsg.mType == MessageType::MiddlemanCallRequest); aMsg.mType == MessageType::MiddlemanCallRequest);

View File

@@ -109,8 +109,13 @@ namespace recordreplay {
\ \
/* A critical error occurred and execution cannot continue. The child will */ \ /* A critical error occurred and execution cannot continue. The child will */ \
/* stop executing after sending this message and will wait to be terminated. */ \ /* stop executing after sending this message and will wait to be terminated. */ \
/* A minidump for the child has been generated. */ \
_Macro(FatalError) \ _Macro(FatalError) \
\ \
/* Sent when a fatal error has occurred, but before the minidump has been */ \
/* generated. */ \
_Macro(BeginFatalError) \
\
/* The child's graphics were repainted. */ \ /* The child's graphics were repainted. */ \
_Macro(Paint) \ _Macro(Paint) \
\ \
@@ -371,6 +376,8 @@ struct FatalErrorMessage : public Message
const char* Error() const { return Data<FatalErrorMessage, const char>(); } const char* Error() const { return Data<FatalErrorMessage, const char>(); }
}; };
typedef EmptyMessage<MessageType::BeginFatalError> BeginFatalErrorMessage;
// The format for graphics data which will be sent to the middleman process. // The format for graphics data which will be sent to the middleman process.
// This needs to match the format expected for canvas image data, to avoid // This needs to match the format expected for canvas image data, to avoid
// transforming the data before rendering it in the middleman process. // transforming the data before rendering it in the middleman process.

View File

@@ -108,8 +108,9 @@ ChannelMessageHandler(Message* aMsg)
PrintSpew("Terminate message received, exiting...\n"); PrintSpew("Terminate message received, exiting...\n");
_exit(0); _exit(0);
} else { } else {
MOZ_CRASH("Hanged replaying process"); ReportFatalError(Nothing(), "Hung replaying process");
} }
break;
} }
case MessageType::SetIsActive: { case MessageType::SetIsActive: {
const SetIsActiveMessage& nmsg = (const SetIsActiveMessage&) *aMsg; const SetIsActiveMessage& nmsg = (const SetIsActiveMessage&) *aMsg;
@@ -350,6 +351,10 @@ CreateCheckpoint()
void void
ReportFatalError(const Maybe<MinidumpInfo>& aMinidump, const char* aFormat, ...) ReportFatalError(const Maybe<MinidumpInfo>& aMinidump, const char* aFormat, ...)
{ {
// Notify the middleman that we are crashing and are going to try to write a
// minidump.
gChannel->SendMessage(BeginFatalErrorMessage());
// Unprotect any memory which might be written while producing the minidump. // Unprotect any memory which might be written while producing the minidump.
UnrecoverableSnapshotFailure(); UnrecoverableSnapshotFailure();

View File

@@ -40,6 +40,8 @@ ChildProcessInfo::ChildProcessInfo(UniquePtr<ChildRole> aRole,
, mNumRecoveredMessages(0) , mNumRecoveredMessages(0)
, mRole(std::move(aRole)) , mRole(std::move(aRole))
, mPauseNeeded(false) , mPauseNeeded(false)
, mHasBegunFatalError(false)
, mHasFatalError(false)
{ {
MOZ_RELEASE_ASSERT(NS_IsMainThread()); MOZ_RELEASE_ASSERT(NS_IsMainThread());
@@ -199,7 +201,11 @@ ChildProcessInfo::OnIncomingMessage(size_t aChannelId, const Message& aMsg)
} }
// Always handle fatal errors in the same way. // Always handle fatal errors in the same way.
if (aMsg.mType == MessageType::FatalError) { if (aMsg.mType == MessageType::BeginFatalError) {
mHasBegunFatalError = true;
return;
} else if (aMsg.mType == MessageType::FatalError) {
mHasFatalError = true;
const FatalErrorMessage& nmsg = static_cast<const FatalErrorMessage&>(aMsg); const FatalErrorMessage& nmsg = static_cast<const FatalErrorMessage&>(aMsg);
OnCrash(nmsg.Error()); OnCrash(nmsg.Error());
return; return;
@@ -527,12 +533,23 @@ ChildProcessInfo::OnCrash(const char* aWhy)
{ {
MOZ_RELEASE_ASSERT(NS_IsMainThread()); MOZ_RELEASE_ASSERT(NS_IsMainThread());
// If a child process crashes or hangs then annotate the crash report and // If a child process crashes or hangs then annotate the crash report.
// shut down cleanly so that we don't mask the report with our own crash.
// We want the crash to happen quickly so the user doesn't get a hanged tab.
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::RecordReplayError, CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::RecordReplayError,
nsAutoCString(aWhy)); nsAutoCString(aWhy));
// If we received a FatalError message then the child generated a minidump.
// Shut down cleanly so that we don't mask the report with our own crash.
if (mHasFatalError) {
Shutdown(); Shutdown();
}
// Indicate when we crash if the child tried to send us a fatal error message
// but had a problem either unprotecting system memory or generating the
// minidump.
MOZ_RELEASE_ASSERT(!mHasBegunFatalError);
// The child crashed without producing a minidump, produce one ourselves.
MOZ_CRASH("Unexpected child crash");
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@@ -613,7 +630,7 @@ ChildProcessInfo::WaitUntil(const std::function<bool()>& aCallback)
sentTerminateMessage = true; sentTerminateMessage = true;
} else { } else {
// The child is still non-responsive after sending the terminate // The child is still non-responsive after sending the terminate
// message, fail without producing a minidump. // message.
OnCrash("Child process non-responsive"); OnCrash("Child process non-responsive");
} }
} }

View File

@@ -38,7 +38,6 @@ HandleMessageInMiddleman(ipc::Side aSide, const IPC::Message& aMessage)
// Graphics messages that affect both processes. // Graphics messages that affect both processes.
type == dom::PBrowser::Msg_InitRendering__ID || type == dom::PBrowser::Msg_InitRendering__ID ||
type == dom::PBrowser::Msg_SetDocShellIsActive__ID || type == dom::PBrowser::Msg_SetDocShellIsActive__ID ||
type == dom::PBrowser::Msg_PRenderFrameConstructor__ID ||
type == dom::PBrowser::Msg_RenderLayers__ID || type == dom::PBrowser::Msg_RenderLayers__ID ||
type == dom::PBrowser::Msg_UpdateDimensions__ID || type == dom::PBrowser::Msg_UpdateDimensions__ID ||
// These messages perform some graphics related initialization. // These messages perform some graphics related initialization.

View File

@@ -201,23 +201,6 @@ UpdateGraphicsInUIProcess(const PaintMessage* aMsg)
} }
} }
void
UpdateGraphicsOverlay()
{
if (!gLastPaintWidth || !gLastPaintHeight) {
return;
}
AutoSafeJSContext cx;
JSAutoRealm ar(cx, *gGraphicsSandbox);
RootedValue rval(cx);
if (!JS_CallFunctionName(cx, *gGraphicsSandbox, "UpdateOverlay",
JS::HandleValueArray::empty(), &rval)) {
MOZ_CRASH("UpdateGraphicsOverlay");
}
}
static void static void
MaybeTriggerExplicitPaint() MaybeTriggerExplicitPaint()
{ {

View File

@@ -611,12 +611,6 @@ SwitchActiveChild(ChildProcessInfo* aChild, bool aRecoverPosition = true)
oldActiveChild->RecoverToCheckpoint(oldActiveChild->MostRecentSavedCheckpoint()); oldActiveChild->RecoverToCheckpoint(oldActiveChild->MostRecentSavedCheckpoint());
oldActiveChild->SetRole(MakeUnique<ChildRoleStandby>()); oldActiveChild->SetRole(MakeUnique<ChildRoleStandby>());
} }
// The graphics overlay is affected when we switch between recording and
// replaying children.
if (aChild->IsRecording() != oldActiveChild->IsRecording()) {
UpdateGraphicsOverlay();
}
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@@ -1187,10 +1181,6 @@ RecvHitCheckpoint(const HitCheckpointMessage& aMsg)
UpdateCheckpointTimes(aMsg); UpdateCheckpointTimes(aMsg);
MaybeUpdateGraphicsAtCheckpoint(aMsg.mCheckpointId); MaybeUpdateGraphicsAtCheckpoint(aMsg.mCheckpointId);
if (!gActiveChild->IsRecording()) {
UpdateGraphicsOverlay();
}
// Resume either forwards or backwards. Break the resume off into a separate // Resume either forwards or backwards. Break the resume off into a separate
// runnable, to avoid starving any code already on the stack and waiting for // runnable, to avoid starving any code already on the stack and waiting for
// the process to pause. Immediately resume if the main thread is blocked. // the process to pause. Immediately resume if the main thread is blocked.

View File

@@ -94,9 +94,6 @@ void SendGraphicsMemoryToChild();
// an unhandled recording divergence. // an unhandled recording divergence.
void UpdateGraphicsInUIProcess(const PaintMessage* aMsg); void UpdateGraphicsInUIProcess(const PaintMessage* aMsg);
// Update the overlay shown over the tab's graphics.
void UpdateGraphicsOverlay();
// If necessary, update graphics after the active child sends a paint message // If necessary, update graphics after the active child sends a paint message
// or reaches a checkpoint. // or reaches a checkpoint.
void MaybeUpdateGraphicsAtPaint(const PaintMessage& aMsg); void MaybeUpdateGraphicsAtPaint(const PaintMessage& aMsg);
@@ -274,6 +271,11 @@ class ChildProcessInfo
// Whether we need this child to pause while the recording is updated. // Whether we need this child to pause while the recording is updated.
bool mPauseNeeded; bool mPauseNeeded;
// Flags for whether we have received messages from the child indicating it
// is crashing.
bool mHasBegunFatalError;
bool mHasFatalError;
void OnIncomingMessage(size_t aChannelId, const Message& aMsg); void OnIncomingMessage(size_t aChannelId, const Message& aMsg);
void OnIncomingRecoveryMessage(const Message& aMsg); void OnIncomingRecoveryMessage(const Message& aMsg);
void SendNextRecoveryMessage(); void SendNextRecoveryMessage();

View File

@@ -2758,9 +2758,12 @@ public:
bool bool
Visit(nsPurpleBuffer& aBuffer, nsPurpleBufferEntry* aEntry) Visit(nsPurpleBuffer& aBuffer, nsPurpleBufferEntry* aEntry)
{ {
// Ignore any slice budget we have when recording/replaying, as it behaves // The cycle collector does not collect anything when recording/replaying.
// non-deterministically. if (recordreplay::IsRecordingOrReplaying()) {
if (mBudget && !recordreplay::IsRecordingOrReplaying()) { return true;
}
if (mBudget) {
if (mBudget->isOverBudget()) { if (mBudget->isOverBudget()) {
return false; return false;
} }