mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-18 07:45:30 +00:00
Merge mozilla-central to autoland. CLOSED TREE
This commit is contained in:
commit
0f3ea39692
@ -10,6 +10,7 @@ skip-if = os == "linux" # Bug 952422
|
||||
[browser_iframe_gone_mid_download.js]
|
||||
[browser_indicatorDrop.js]
|
||||
[browser_libraryDrop.js]
|
||||
skip-if = (os == 'win' && os_version == '10.0' && ccov) # Bug 1306510
|
||||
[browser_library_clearall.js]
|
||||
[browser_downloads_panel_block.js]
|
||||
skip-if = true # Bug 1352792
|
||||
|
@ -25,8 +25,7 @@ Cu.evalInSandbox(
|
||||
);
|
||||
|
||||
// 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
|
||||
// can be displayed over that canvas.
|
||||
// This method fills them in with a canvas filling the tab.
|
||||
function setupContents(window) {
|
||||
// The middlemanCanvas element fills the tab's contents.
|
||||
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
|
||||
var EXPORTED_SYMBOLS = [
|
||||
"UpdateCanvas",
|
||||
"UpdateOverlay",
|
||||
];
|
||||
|
@ -82,7 +82,7 @@
|
||||
#include "mozilla/dom/FrameLoaderBinding.h"
|
||||
#include "mozilla/gfx/CrossProcessPaint.h"
|
||||
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
|
||||
#include "mozilla/layout/RenderFrameParent.h"
|
||||
#include "mozilla/layout/RenderFrame.h"
|
||||
#include "mozilla/ServoCSSParser.h"
|
||||
#include "mozilla/ServoStyleSet.h"
|
||||
#include "nsGenericHTMLFrameElement.h"
|
||||
@ -853,12 +853,12 @@ nsFrameLoader::ShowRemoteFrame(const ScreenIntSize& size,
|
||||
return false;
|
||||
}
|
||||
|
||||
RenderFrameParent* rfp = GetCurrentRenderFrame();
|
||||
if (!rfp) {
|
||||
RenderFrame* rf = GetCurrentRenderFrame();
|
||||
if (!rf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!rfp->AttachLayerManager()) {
|
||||
if (!rf->AttachLayerManager()) {
|
||||
// This is just not going to work.
|
||||
return false;
|
||||
}
|
||||
@ -1806,7 +1806,7 @@ nsFrameLoader::SetOwnerContent(Element* aContent)
|
||||
Unused << NS_WARN_IF(rv.Failed());
|
||||
}
|
||||
|
||||
if (RenderFrameParent* rfp = GetCurrentRenderFrame()) {
|
||||
if (RenderFrame* rfp = GetCurrentRenderFrame()) {
|
||||
rfp->OwnerContentChanged(aContent);
|
||||
}
|
||||
}
|
||||
@ -2616,8 +2616,8 @@ nsFrameLoader::TryRemoteBrowser()
|
||||
if (!mRemoteBrowser) {
|
||||
return false;
|
||||
}
|
||||
// Now that mRemoteBrowser is set, we can initialize the RenderFrameParent
|
||||
mRemoteBrowser->InitRenderFrame();
|
||||
// Now that mRemoteBrowser is set, we can initialize the RenderFrame
|
||||
mRemoteBrowser->InitRendering();
|
||||
|
||||
MaybeUpdatePrimaryTabParent(eTabParentChanged);
|
||||
|
||||
@ -2670,7 +2670,7 @@ nsFrameLoader::GetRemoteBrowser() const
|
||||
return mRemoteBrowser;
|
||||
}
|
||||
|
||||
RenderFrameParent*
|
||||
RenderFrame*
|
||||
nsFrameLoader::GetCurrentRenderFrame() const
|
||||
{
|
||||
if (mRemoteBrowser) {
|
||||
@ -2941,6 +2941,7 @@ nsFrameLoader::SetRemoteBrowser(nsITabParent* aTabParent)
|
||||
MaybeUpdatePrimaryTabParent(eTabParentChanged);
|
||||
ReallyLoadFrameScripts();
|
||||
InitializeBrowserAPI();
|
||||
mRemoteBrowser->InitRendering();
|
||||
ShowRemoteFrame(ScreenIntSize(0, 0));
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ class StructuredCloneData;
|
||||
} // namespace dom
|
||||
|
||||
namespace layout {
|
||||
class RenderFrameParent;
|
||||
class RenderFrame;
|
||||
} // namespace layout
|
||||
} // namespace mozilla
|
||||
|
||||
@ -86,7 +86,7 @@ class nsFrameLoader final : public nsStubMutationObserver,
|
||||
friend class AutoResetInFrameSwap;
|
||||
typedef mozilla::dom::PBrowserParent PBrowserParent;
|
||||
typedef mozilla::dom::TabParent TabParent;
|
||||
typedef mozilla::layout::RenderFrameParent RenderFrameParent;
|
||||
typedef mozilla::layout::RenderFrame RenderFrame;
|
||||
|
||||
public:
|
||||
static nsFrameLoader* Create(mozilla::dom::Element* aOwner,
|
||||
@ -296,7 +296,7 @@ public:
|
||||
* returned. (In-process <browser> behaves similarly, and this
|
||||
* behavior seems desirable.)
|
||||
*/
|
||||
RenderFrameParent* GetCurrentRenderFrame() const;
|
||||
RenderFrame* GetCurrentRenderFrame() const;
|
||||
|
||||
mozilla::dom::ChromeMessageSender* GetFrameMessageManager() { return mMessageManager; }
|
||||
|
||||
|
@ -5478,6 +5478,14 @@ nsGlobalWindowOuter::RevisePopupAbuseLevel(PopupControlState aControl)
|
||||
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;
|
||||
}
|
||||
|
||||
@ -5514,7 +5522,7 @@ nsGlobalWindowOuter::FireAbuseEvents(const nsAString &aPopupURL,
|
||||
ios->NewURI(NS_ConvertUTF16toUTF8(aPopupURL), nullptr, baseURL,
|
||||
getter_AddRefs(popupURI));
|
||||
|
||||
// fire an event chock full of informative URIs
|
||||
// fire an event block full of informative URIs
|
||||
FirePopupBlockedEvent(topDoc, popupURI, aPopupWindowName,
|
||||
aPopupWindowFeatures);
|
||||
}
|
||||
|
@ -57,3 +57,5 @@ skip-if = verify
|
||||
[browser_timeout_throttling_with_audio_playback.js]
|
||||
[browser_bug1303838.js]
|
||||
[browser_inputStream_structuredClone.js]
|
||||
[browser_multiple_popups.js]
|
||||
support-files = browser_multiple_popups.html
|
||||
|
54
dom/base/test/browser_multiple_popups.html
Normal file
54
dom/base/test/browser_multiple_popups.html
Normal 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>
|
362
dom/base/test/browser_multiple_popups.js
Normal file
362
dom/base/test/browser_multiple_popups.js
Normal 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);
|
||||
});
|
@ -22,7 +22,6 @@
|
||||
#include "nsVariant.h"
|
||||
#include "mozilla/dom/BrowserElementDictionariesBinding.h"
|
||||
#include "mozilla/dom/CustomEvent.h"
|
||||
#include "mozilla/layout/RenderFrameParent.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@ -177,12 +176,9 @@ BrowserElementParent::DispatchOpenWindowEvent(Element* aOpenerFrameElement,
|
||||
BrowserElementParent::OpenWindowResult
|
||||
BrowserElementParent::OpenWindowOOP(TabParent* aOpenerTabParent,
|
||||
TabParent* aPopupTabParent,
|
||||
PRenderFrameParent* aRenderFrame,
|
||||
const nsAString& aURL,
|
||||
const nsAString& aName,
|
||||
const nsAString& aFeatures,
|
||||
TextureFactoryIdentifier* aTextureFactoryIdentifier,
|
||||
layers::LayersId* aLayersId)
|
||||
const nsAString& aFeatures)
|
||||
{
|
||||
// Create an iframe owned by the same document which owns openerFrameElement.
|
||||
nsCOMPtr<Element> openerFrameElement = aOpenerTabParent->GetOwnerElement();
|
||||
@ -217,12 +213,6 @@ BrowserElementParent::OpenWindowOOP(TabParent* aOpenerTabParent,
|
||||
popupFrameElement->AllowCreateFrameLoader();
|
||||
popupFrameElement->CreateRemoteFrameLoader(aPopupTabParent);
|
||||
|
||||
RenderFrameParent* rfp = static_cast<RenderFrameParent*>(aRenderFrame);
|
||||
if (!aPopupTabParent->SetRenderFrame(rfp) ||
|
||||
!aPopupTabParent->GetRenderFrameInfo(aTextureFactoryIdentifier, aLayersId)) {
|
||||
return BrowserElementParent::OPEN_WINDOW_IGNORED;
|
||||
}
|
||||
|
||||
return opened;
|
||||
}
|
||||
|
||||
|
@ -22,14 +22,6 @@ namespace dom {
|
||||
class TabParent;
|
||||
} // namespace dom
|
||||
|
||||
namespace layers {
|
||||
struct TextureFactoryIdentifier;
|
||||
} // namespace layers
|
||||
|
||||
namespace layout {
|
||||
class PRenderFrameParent;
|
||||
} // namespace layout
|
||||
|
||||
/**
|
||||
* BrowserElementParent implements a portion of the parent-process side of
|
||||
* <iframe mozbrowser>.
|
||||
@ -95,12 +87,9 @@ public:
|
||||
static OpenWindowResult
|
||||
OpenWindowOOP(dom::TabParent* aOpenerTabParent,
|
||||
dom::TabParent* aPopupTabParent,
|
||||
layout::PRenderFrameParent* aRenderFrame,
|
||||
const nsAString& aURL,
|
||||
const nsAString& aName,
|
||||
const nsAString& aFeatures,
|
||||
layers::TextureFactoryIdentifier* aTextureFactoryIdentifier,
|
||||
layers::LayersId* aLayersId);
|
||||
const nsAString& aFeatures);
|
||||
|
||||
/**
|
||||
* Handle a window.open call from an in-process <iframe mozbrowser>.
|
||||
|
@ -1079,6 +1079,7 @@ CanvasRenderingContext2D::CanvasRenderingContext2D(layers::LayersBackend aCompos
|
||||
, mIsCapturedFrameInvalid(false)
|
||||
, mPathTransformWillUpdate(false)
|
||||
, mInvalidateCount(0)
|
||||
, mWriteOnly(false)
|
||||
{
|
||||
if (!sMaxContextsInitialized) {
|
||||
sMaxContexts = gfxPrefs::CanvasAzureAcceleratedLimit();
|
||||
@ -2565,7 +2566,8 @@ CanvasRenderingContext2D::CreatePattern(const CanvasImageSource& aSource,
|
||||
// nullptr and set CORSUsed to true for passing the security check in
|
||||
// CanvasUtils::DoDrawImageSecurityCheck().
|
||||
RefPtr<CanvasPattern> pat =
|
||||
new CanvasPattern(this, srcSurf, repeatMode, nullptr, false, true);
|
||||
new CanvasPattern(this, srcSurf, repeatMode, nullptr,
|
||||
imgBitmap.IsWriteOnly(), true);
|
||||
|
||||
return pat.forget();
|
||||
}
|
||||
@ -4920,6 +4922,10 @@ CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
|
||||
aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (canvas->IsWriteOnly()) {
|
||||
SetWriteOnly();
|
||||
}
|
||||
} else if (aImage.IsImageBitmap()) {
|
||||
ImageBitmap& imageBitmap = aImage.GetAsImageBitmap();
|
||||
srcSurf = imageBitmap.PrepareForDrawTarget(mTarget);
|
||||
@ -4928,6 +4934,10 @@ CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
|
||||
return;
|
||||
}
|
||||
|
||||
if (imageBitmap.IsWriteOnly()) {
|
||||
SetWriteOnly();
|
||||
}
|
||||
|
||||
imgSize = gfx::IntSize(imageBitmap.Width(), imageBitmap.Height());
|
||||
}
|
||||
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,
|
||||
// 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)
|
||||
aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
|
@ -41,6 +41,7 @@ class SourceSurface;
|
||||
namespace dom {
|
||||
class HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap;
|
||||
typedef HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmap CanvasImageSource;
|
||||
class ImageBitmap;
|
||||
class ImageData;
|
||||
class StringOrCanvasGradientOrCanvasPattern;
|
||||
class OwningStringOrCanvasGradientOrCanvasPattern;
|
||||
@ -1192,6 +1193,19 @@ protected:
|
||||
|
||||
friend struct CanvasBidiProcessor;
|
||||
friend class CanvasDrawObserver;
|
||||
friend class ImageBitmap;
|
||||
|
||||
void SetWriteOnly()
|
||||
{
|
||||
mWriteOnly = true;
|
||||
}
|
||||
|
||||
bool IsWriteOnly() const
|
||||
{
|
||||
return mWriteOnly;
|
||||
}
|
||||
|
||||
bool mWriteOnly;
|
||||
};
|
||||
|
||||
size_t BindingJSObjectMallocBytes(CanvasRenderingContext2D* aContext);
|
||||
|
@ -471,7 +471,8 @@ CheckSecurityForElements(const nsLayoutUtils::SurfaceFromElementResult& aRes)
|
||||
*/
|
||||
template<class ElementType>
|
||||
static already_AddRefed<SourceSurface>
|
||||
GetSurfaceFromElement(nsIGlobalObject* aGlobal, ElementType& aElement, ErrorResult& aRv)
|
||||
GetSurfaceFromElement(nsIGlobalObject* aGlobal, ElementType& aElement,
|
||||
bool* aWriteOnly, ErrorResult& aRv)
|
||||
{
|
||||
nsLayoutUtils::SurfaceFromElementResult res =
|
||||
nsLayoutUtils::SurfaceFromElement(&aElement, nsLayoutUtils::SFE_WANT_FIRST_FRAME_IF_IMAGE);
|
||||
@ -483,17 +484,14 @@ GetSurfaceFromElement(nsIGlobalObject* aGlobal, ElementType& aElement, ErrorResu
|
||||
}
|
||||
|
||||
|
||||
// check origin-clean
|
||||
if (!CheckSecurityForElements(res)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
// check write-only mode
|
||||
*aWriteOnly = !CheckSecurityForElements(res);
|
||||
|
||||
return surface.forget();
|
||||
}
|
||||
|
||||
ImageBitmap::ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
|
||||
gfxAlphaType aAlphaType)
|
||||
bool aWriteOnly, gfxAlphaType aAlphaType)
|
||||
: mParent(aGlobal)
|
||||
, mData(aData)
|
||||
, mSurface(nullptr)
|
||||
@ -501,6 +499,7 @@ ImageBitmap::ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
|
||||
, mPictureRect(0, 0, aData->GetSize().width, aData->GetSize().height)
|
||||
, mAlphaType(aAlphaType)
|
||||
, mAllocatedImageData(false)
|
||||
, mWriteOnly(aWriteOnly)
|
||||
{
|
||||
MOZ_ASSERT(aData, "aData is null in ImageBitmap constructor.");
|
||||
|
||||
@ -763,6 +762,7 @@ ImageBitmap::ToCloneData() const
|
||||
RefPtr<SourceSurface> surface = mData->GetAsSourceSurface();
|
||||
result->mSurface = surface->GetDataSurface();
|
||||
MOZ_ASSERT(result->mSurface);
|
||||
result->mWriteOnly = mWriteOnly;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -773,7 +773,8 @@ ImageBitmap::CreateFromSourceSurface(nsIGlobalObject* aGlobal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
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;
|
||||
return ret.forget();
|
||||
}
|
||||
@ -784,7 +785,8 @@ ImageBitmap::CreateFromCloneData(nsIGlobalObject* aGlobal,
|
||||
{
|
||||
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;
|
||||
|
||||
@ -798,11 +800,8 @@ ImageBitmap::CreateFromOffscreenCanvas(nsIGlobalObject* aGlobal,
|
||||
OffscreenCanvas& aOffscreenCanvas,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// Check origin-clean.
|
||||
if (aOffscreenCanvas.IsWriteOnly()) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
// Check write-only mode.
|
||||
bool writeOnly = aOffscreenCanvas.IsWriteOnly();
|
||||
|
||||
nsLayoutUtils::SurfaceFromElementResult res =
|
||||
nsLayoutUtils::SurfaceFromOffscreenCanvas(&aOffscreenCanvas,
|
||||
@ -818,7 +817,7 @@ ImageBitmap::CreateFromOffscreenCanvas(nsIGlobalObject* aGlobal,
|
||||
RefPtr<layers::Image> data =
|
||||
CreateImageFromSurface(surface);
|
||||
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
|
||||
|
||||
ret->mAllocatedImageData = true;
|
||||
|
||||
@ -835,9 +834,12 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool writeOnly = true;
|
||||
|
||||
// Get the SourceSurface out from the image element and then do security
|
||||
// checking.
|
||||
RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aImageEl, aRv);
|
||||
RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aImageEl,
|
||||
&writeOnly, aRv);
|
||||
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
@ -851,7 +853,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
|
||||
|
||||
// Set the picture rectangle.
|
||||
if (ret && aCropRect.isSome()) {
|
||||
@ -865,9 +867,12 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl
|
||||
ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, SVGImageElement& aImageEl,
|
||||
const Maybe<IntRect>& aCropRect, ErrorResult& aRv)
|
||||
{
|
||||
bool writeOnly = true;
|
||||
|
||||
// Get the SourceSurface out from the image element and then do security
|
||||
// checking.
|
||||
RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aImageEl, aRv);
|
||||
RefPtr<SourceSurface> surface = GetSurfaceFromElement(aGlobal, aImageEl,
|
||||
&writeOnly, aRv);
|
||||
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
@ -881,7 +886,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, SVGImageElement& aImageEl,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
|
||||
|
||||
// Set the picture rectangle.
|
||||
if (ret && aCropRect.isSome()) {
|
||||
@ -913,10 +918,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl
|
||||
// Check security.
|
||||
nsCOMPtr<nsIPrincipal> principal = aVideoEl.GetCurrentVideoPrincipal();
|
||||
bool CORSUsed = aVideoEl.GetCORSMode() != CORS_NONE;
|
||||
if (!CheckSecurityForElements(false, CORSUsed, principal)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
bool writeOnly = !CheckSecurityForElements(false, CORSUsed, principal);
|
||||
|
||||
// Create ImageBitmap.
|
||||
RefPtr<layers::Image> data = aVideoEl.GetCurrentImage();
|
||||
@ -924,7 +926,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl
|
||||
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
|
||||
|
||||
// Set the picture rectangle.
|
||||
if (ret && aCropRect.isSome()) {
|
||||
@ -943,12 +945,18 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvas
|
||||
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())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!writeOnly) {
|
||||
writeOnly = aCanvasEl.IsWriteOnly();
|
||||
}
|
||||
|
||||
// Crop the source surface if needed.
|
||||
RefPtr<SourceSurface> croppedSurface;
|
||||
IntRect cropRect = aCropRect.valueOr(IntRect());
|
||||
@ -982,7 +990,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvas
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, writeOnly);
|
||||
|
||||
if (needToReportMemoryAllocation) {
|
||||
ret->mAllocatedImageData = true;
|
||||
@ -1047,7 +1055,8 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageData& aImageData,
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
@ -1070,11 +1079,8 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, CanvasRenderingContext2D&
|
||||
|
||||
window->GetExtantDoc()->WarnOnceAbout(nsIDocument::eCreateImageBitmapCanvasRenderingContext2D);
|
||||
|
||||
// Check origin-clean.
|
||||
if (aCanvasCtx.GetCanvas()->IsWriteOnly()) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
// Check write-only mode.
|
||||
bool writeOnly = aCanvasCtx.GetCanvas()->IsWriteOnly() || aCanvasCtx.IsWriteOnly();
|
||||
|
||||
RefPtr<SourceSurface> surface = aCanvasCtx.GetSurfaceSnapshot();
|
||||
|
||||
@ -1096,7 +1102,8 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, CanvasRenderingContext2D&
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
|
||||
RefPtr<ImageBitmap> ret =
|
||||
new ImageBitmap(aGlobal, data, writeOnly);
|
||||
|
||||
ret->mAllocatedImageData = true;
|
||||
|
||||
@ -1118,7 +1125,9 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageBitmap& aImageBitmap,
|
||||
}
|
||||
|
||||
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.
|
||||
if (ret && aCropRect.isSome()) {
|
||||
@ -1432,16 +1441,14 @@ ImageBitmap::ReadStructuredClone(JSContext* aCx,
|
||||
uint32_t picRectWidth_;
|
||||
uint32_t picRectHeight_;
|
||||
uint32_t alphaType_;
|
||||
uint32_t dummy;
|
||||
uint32_t writeOnly;
|
||||
|
||||
if (!JS_ReadUint32Pair(aReader, &picRectX_, &picRectY_) ||
|
||||
!JS_ReadUint32Pair(aReader, &picRectWidth_, &picRectHeight_) ||
|
||||
!JS_ReadUint32Pair(aReader, &alphaType_, &dummy)) {
|
||||
!JS_ReadUint32Pair(aReader, &alphaType_, &writeOnly)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(dummy == 0);
|
||||
|
||||
int32_t picRectX = BitwiseCast<int32_t>(picRectX_);
|
||||
int32_t picRectY = BitwiseCast<int32_t>(picRectY_);
|
||||
int32_t picRectWidth = BitwiseCast<int32_t>(picRectWidth_);
|
||||
@ -1465,7 +1472,8 @@ ImageBitmap::ReadStructuredClone(JSContext* aCx,
|
||||
}
|
||||
#endif
|
||||
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;
|
||||
imageBitmap->SetPictureRect(IntRect(picRectX, picRectY,
|
||||
@ -1505,7 +1513,7 @@ ImageBitmap::WriteStructuredClone(JSStructuredCloneWriter* aWriter,
|
||||
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, picRectWidth, picRectHeight)) ||
|
||||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, alphaType, 0))) {
|
||||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, alphaType, aImageBitmap->mWriteOnly))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1839,7 +1847,8 @@ CreateImageBitmapFromBlob::MimeTypeAndDecodeAndCropBlobCompletedOwningThread(lay
|
||||
}
|
||||
|
||||
// Create ImageBitmap object.
|
||||
RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(mGlobalObject, aImage);
|
||||
RefPtr<ImageBitmap> imageBitmap =
|
||||
new ImageBitmap(mGlobalObject, aImage, false /* write-only */);
|
||||
|
||||
if (mCropRect.isSome()) {
|
||||
ErrorResult rv;
|
||||
|
@ -60,6 +60,7 @@ struct ImageBitmapCloneData final
|
||||
RefPtr<gfx::DataSourceSurface> mSurface;
|
||||
gfx::IntRect mPictureRect;
|
||||
gfxAlphaType mAlphaType;
|
||||
bool mWriteOnly;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -152,6 +153,11 @@ public:
|
||||
|
||||
void OnShutdown();
|
||||
|
||||
bool IsWriteOnly() const
|
||||
{
|
||||
return mWriteOnly;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/*
|
||||
@ -174,6 +180,7 @@ protected:
|
||||
* CreateInternal(from ImageData) method.
|
||||
*/
|
||||
ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
|
||||
bool aWriteOnly,
|
||||
gfxAlphaType aAlphaType = gfxAlphaType::Premult);
|
||||
|
||||
virtual ~ImageBitmap();
|
||||
@ -255,6 +262,13 @@ protected:
|
||||
* Whether this object allocated allocated and owns the image data.
|
||||
*/
|
||||
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
|
||||
|
@ -245,8 +245,11 @@ struct TexImageSourceAdapter final : public TexImageSource
|
||||
mPboOffset = pboOffset;
|
||||
}
|
||||
|
||||
TexImageSourceAdapter(const dom::ImageBitmap* imageBitmap, ErrorResult*) {
|
||||
TexImageSourceAdapter(const dom::ImageBitmap* imageBitmap,
|
||||
ErrorResult* out_error)
|
||||
{
|
||||
mImageBitmap = imageBitmap;
|
||||
mOut_error = out_error;
|
||||
}
|
||||
|
||||
TexImageSourceAdapter(const dom::ImageData* imageData, ErrorResult*) {
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "GLBlitHelper.h"
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/dom/HTMLCanvasElement.h"
|
||||
#include "mozilla/dom/HTMLVideoElement.h"
|
||||
#include "mozilla/dom/ImageBitmap.h"
|
||||
#include "mozilla/dom/ImageData.h"
|
||||
@ -222,11 +223,16 @@ FromPboOffset(WebGLContext* webgl, TexImageTarget target,
|
||||
static UniquePtr<webgl::TexUnpackBlob>
|
||||
FromImageBitmap(WebGLContext* webgl, TexImageTarget target,
|
||||
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();
|
||||
if (!cloneData) {
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const RefPtr<gfx::DataSourceSurface> surf = cloneData->mSurface;
|
||||
@ -300,6 +306,14 @@ WebGLContext::FromDomElem(TexImageTarget target, uint32_t width,
|
||||
uint32_t height, uint32_t depth, const dom::Element& elem,
|
||||
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
|
||||
// animated images. The webgl spec doesn't mention the issue, so we do the
|
||||
// same as drawImage.
|
||||
@ -421,7 +435,7 @@ WebGLContext::From(TexImageTarget target, GLsizei rawWidth,
|
||||
|
||||
if (src.mImageBitmap) {
|
||||
return FromImageBitmap(this, target, width, height, depth,
|
||||
*(src.mImageBitmap));
|
||||
*(src.mImageBitmap), src.mOut_error);
|
||||
}
|
||||
|
||||
if (src.mImageData) {
|
||||
|
@ -270,13 +270,22 @@ function testSecurityErrors() {
|
||||
}
|
||||
|
||||
function checkPromiseFailedWithSecurityError(p) {
|
||||
return p.then( function(reason) { ok(false, "Did not get SecurityError with unclean source. ImageBitmap was created successfully."); },
|
||||
function(reason) { if (reason == "SecurityError: The operation is insecure.") {
|
||||
ok(true, reason);
|
||||
}
|
||||
else {
|
||||
ok(false, "Did not get SecurityError with unclean source. Error Message: " + reason);
|
||||
}});
|
||||
return p.then(imageBitmap => {
|
||||
ok(!!imageBitmap, "ImageBitmaps are always created");
|
||||
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 {
|
||||
ok(false, "Did not get SecurityError with unclean source. Error Message: " + ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.all([
|
||||
|
@ -1083,7 +1083,7 @@ HTMLCanvasElement::GetSize()
|
||||
}
|
||||
|
||||
bool
|
||||
HTMLCanvasElement::IsWriteOnly()
|
||||
HTMLCanvasElement::IsWriteOnly() const
|
||||
{
|
||||
return mWriteOnly;
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ public:
|
||||
/**
|
||||
* Determine whether the canvas is write-only.
|
||||
*/
|
||||
bool IsWriteOnly();
|
||||
bool IsWriteOnly() const;
|
||||
|
||||
/**
|
||||
* Force the canvas to be write-only.
|
||||
|
@ -68,7 +68,6 @@
|
||||
#include "mozilla/layers/CompositorManagerChild.h"
|
||||
#include "mozilla/layers/ContentProcessController.h"
|
||||
#include "mozilla/layers/ImageBridgeChild.h"
|
||||
#include "mozilla/layout/RenderFrameChild.h"
|
||||
#include "mozilla/loader/ScriptCacheActors.h"
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "mozilla/net/CookieServiceChild.h"
|
||||
@ -972,9 +971,6 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
|
||||
tabId, TabId(0), *ipcContext, aChromeFlags,
|
||||
GetID(), IsForBrowser());
|
||||
|
||||
|
||||
PRenderFrameChild* renderFrame = newChild->SendPRenderFrameConstructor();
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> parentTopInnerWindow;
|
||||
if (aParent) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> parentTopWindow =
|
||||
@ -995,9 +991,6 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
|
||||
*aWindowIsNew = info.windowOpened();
|
||||
nsTArray<FrameScriptInfo> frameScripts(info.frameScripts());
|
||||
nsCString urlToLoad = info.urlToLoad();
|
||||
TextureFactoryIdentifier textureFactoryIdentifier = info.textureFactoryIdentifier();
|
||||
layers::LayersId layersId = info.layersId();
|
||||
CompositorOptions compositorOptions = info.compositorOptions();
|
||||
uint32_t maxTouchPoints = info.maxTouchPoints();
|
||||
DimensionInfo dimensionInfo = info.dimensions();
|
||||
bool hasSiblings = info.hasSiblings();
|
||||
@ -1026,10 +1019,6 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!layersId.IsValid()) { // if renderFrame is invalid.
|
||||
renderFrame = nullptr;
|
||||
}
|
||||
|
||||
ShowInfo showInfo(EmptyString(), false, false, true, false, 0, 0, 0);
|
||||
auto* opener = nsPIDOMWindowOuter::From(aParent);
|
||||
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
|
||||
// pretty bogus; see bug 763602.
|
||||
newChild->DoFakeShow(textureFactoryIdentifier, layersId, compositorOptions,
|
||||
renderFrame, showInfo);
|
||||
newChild->DoFakeShow(showInfo);
|
||||
|
||||
newChild->RecvUpdateDimensions(dimensionInfo);
|
||||
|
||||
@ -1102,7 +1090,7 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
|
||||
|
||||
// NOTE: BrowserFrameOpenWindowPromise is the same type as
|
||||
// CreateWindowPromise, and this code depends on that fact.
|
||||
newChild->SendBrowserFrameOpenWindow(aTabOpener, renderFrame,
|
||||
newChild->SendBrowserFrameOpenWindow(aTabOpener,
|
||||
NS_ConvertUTF8toUTF16(url),
|
||||
name, NS_ConvertUTF8toUTF16(features),
|
||||
std::move(resolve), std::move(reject));
|
||||
@ -1125,7 +1113,7 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
|
||||
uriToLoad = mozilla::void_t();
|
||||
}
|
||||
|
||||
SendCreateWindow(aTabOpener, newChild, renderFrame,
|
||||
SendCreateWindow(aTabOpener, newChild,
|
||||
aChromeFlags, aCalledFromJS, aPositionSpecified,
|
||||
aSizeSpecified, uriToLoad, features, baseURIString,
|
||||
fullZoom, Principal(triggeringPrincipal), referrerPolicy,
|
||||
|
@ -83,7 +83,6 @@
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/layers/ImageBridgeParent.h"
|
||||
#include "mozilla/layers/LayerTreeOwnerTracker.h"
|
||||
#include "mozilla/layout/RenderFrameParent.h"
|
||||
#include "mozilla/loader/ScriptCacheActors.h"
|
||||
#include "mozilla/LoginReputationIPC.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
@ -1261,7 +1260,6 @@ ContentParent::CreateBrowser(const TabContext& aContext,
|
||||
}
|
||||
RefPtr<TabParent> tp(new TabParent(constructorSender, tabId,
|
||||
aContext, chromeFlags));
|
||||
tp->SetInitedByParent();
|
||||
|
||||
PBrowserParent* browser =
|
||||
constructorSender->SendPBrowserConstructor(
|
||||
@ -1657,81 +1655,6 @@ ContentParent::ProcessingError(Result aCode, const char* aReason)
|
||||
#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 {
|
||||
|
||||
void
|
||||
@ -5161,7 +5084,6 @@ ContentParent::CommonCreateWindow(PBrowserParent* aThisTab,
|
||||
mozilla::ipc::IPCResult
|
||||
ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
|
||||
PBrowserParent* aNewTab,
|
||||
PRenderFrameParent* aRenderFrame,
|
||||
const uint32_t& aChromeFlags,
|
||||
const bool& aCalledFromJS,
|
||||
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.
|
||||
cwi.windowOpened() = true;
|
||||
cwi.layersId() = LayersId{0};
|
||||
cwi.maxTouchPoints() = 0;
|
||||
cwi.hasSiblings() = false;
|
||||
|
||||
@ -5237,13 +5158,7 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
|
||||
MOZ_ASSERT(TabParent::GetFrom(newRemoteTab) == newTab);
|
||||
|
||||
newTab->SwapFrameScriptsFrom(cwi.frameScripts());
|
||||
|
||||
RenderFrameParent* rfp = static_cast<RenderFrameParent*>(aRenderFrame);
|
||||
if (!newTab->SetRenderFrame(rfp) ||
|
||||
!newTab->GetRenderFrameInfo(&cwi.textureFactoryIdentifier(), &cwi.layersId())) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
cwi.compositorOptions() = rfp->GetCompositorOptions();
|
||||
newTab->MaybeShowFrame();
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = newTab->GetWidget();
|
||||
if (widget) {
|
||||
|
@ -92,10 +92,6 @@ namespace layers {
|
||||
struct TextureFactoryIdentifier;
|
||||
} // namespace layers
|
||||
|
||||
namespace layout {
|
||||
class PRenderFrameParent;
|
||||
} // namespace layout
|
||||
|
||||
namespace dom {
|
||||
|
||||
class Element;
|
||||
@ -543,7 +539,6 @@ public:
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvCreateWindow(PBrowserParent* aThisTabParent,
|
||||
PBrowserParent* aNewTab,
|
||||
layout::PRenderFrameParent* aRenderFrame,
|
||||
const uint32_t& aChromeFlags,
|
||||
const bool& aCalledFromJS,
|
||||
const bool& aPositionSpecified,
|
||||
@ -570,8 +565,6 @@ public:
|
||||
const IPC::Principal& aTriggeringPrincipal,
|
||||
const uint32_t& aReferrerPolicy) override;
|
||||
|
||||
static bool AllocateLayerTreeId(TabParent* aTabParent, layers::LayersId* aId);
|
||||
|
||||
static void
|
||||
BroadcastBlobURLRegistration(const nsACString& aURI,
|
||||
BlobImpl* aBlobImpl,
|
||||
@ -870,10 +863,6 @@ private:
|
||||
|
||||
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|.
|
||||
*/
|
||||
@ -1140,13 +1129,6 @@ public:
|
||||
|
||||
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
|
||||
|
@ -25,9 +25,6 @@ using CSSRect from "Units.h";
|
||||
using CSSSize from "Units.h";
|
||||
using mozilla::LayoutDeviceIntPoint from "Units.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";
|
||||
|
||||
|
||||
@ -120,9 +117,6 @@ struct CreatedWindowInfo
|
||||
bool windowOpened;
|
||||
FrameScriptInfo[] frameScripts;
|
||||
nsCString urlToLoad;
|
||||
TextureFactoryIdentifier textureFactoryIdentifier;
|
||||
LayersId layersId;
|
||||
CompositorOptions compositorOptions;
|
||||
uint32_t maxTouchPoints;
|
||||
DimensionInfo dimensions;
|
||||
bool hasSiblings;
|
||||
|
@ -11,7 +11,6 @@ include protocol PContentBridge;
|
||||
include protocol PDocAccessible;
|
||||
include protocol PFilePicker;
|
||||
include protocol PIndexedDBPermissionRequest;
|
||||
include protocol PRenderFrame;
|
||||
include protocol PPluginWidget;
|
||||
include protocol PRemotePrintJob;
|
||||
include protocol PChildToParentStream;
|
||||
@ -117,7 +116,6 @@ nested(upto inside_cpow) sync protocol PBrowser
|
||||
manages PDocAccessible;
|
||||
manages PFilePicker;
|
||||
manages PIndexedDBPermissionRequest;
|
||||
manages PRenderFrame;
|
||||
manages PPluginWidget;
|
||||
manages PPaymentRequest;
|
||||
|
||||
@ -125,12 +123,6 @@ both:
|
||||
async AsyncMessage(nsString aMessage, CpowEntry[] aCpows,
|
||||
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:
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
async BrowserFrameOpenWindow(PBrowser opener, PRenderFrame renderFrame,
|
||||
async BrowserFrameOpenWindow(PBrowser opener,
|
||||
nsString aURL, nsString aName, nsString aFeatures)
|
||||
returns (CreatedWindowInfo window);
|
||||
|
||||
@ -534,6 +526,11 @@ parent:
|
||||
*/
|
||||
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
|
||||
* events. This is sent when the TabChild is created.
|
||||
@ -600,8 +597,7 @@ child:
|
||||
async InitRendering(TextureFactoryIdentifier textureFactoryIdentifier,
|
||||
LayersId layersId,
|
||||
CompositorOptions compositorOptions,
|
||||
bool layersConnected,
|
||||
nullable PRenderFrame renderFrame);
|
||||
bool layersConnected);
|
||||
|
||||
async LoadURL(nsCString uri, ShowInfo info);
|
||||
|
||||
|
@ -32,7 +32,6 @@ include protocol PPrinting;
|
||||
include protocol PChildToParentStream;
|
||||
include protocol PParentToChildStream;
|
||||
include protocol POfflineCacheUpdate;
|
||||
include protocol PRenderFrame;
|
||||
include protocol PSpeechSynthesis;
|
||||
include protocol PTestShell;
|
||||
include protocol PJavaScript;
|
||||
@ -913,11 +912,6 @@ parent:
|
||||
|
||||
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.
|
||||
* @param recordingStatus starting or shutdown
|
||||
@ -1054,7 +1048,6 @@ parent:
|
||||
|
||||
async CreateWindow(nullable PBrowser aThisTab,
|
||||
PBrowser aNewTab,
|
||||
PRenderFrame aRenderFrame,
|
||||
uint32_t aChromeFlags,
|
||||
bool aCalledFromJS,
|
||||
bool aPositionSpecified,
|
||||
|
@ -42,8 +42,6 @@
|
||||
#include "mozilla/layers/LayerTransactionChild.h"
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
#include "mozilla/layers/WebRenderLayerManager.h"
|
||||
#include "mozilla/layout/RenderFrameChild.h"
|
||||
#include "mozilla/layout/RenderFrameParent.h"
|
||||
#include "mozilla/plugins/PPluginWidgetChild.h"
|
||||
#include "mozilla/recordreplay/ParentIPC.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
@ -397,7 +395,6 @@ TabChild::TabChild(nsIContentChild* aManager,
|
||||
uint32_t aChromeFlags)
|
||||
: TabContext(aContext)
|
||||
, mTabGroup(aTabGroup)
|
||||
, mRemoteFrame(nullptr)
|
||||
, mManager(aManager)
|
||||
, mChromeFlags(aChromeFlags)
|
||||
, mMaxTouchPoints(0)
|
||||
@ -808,10 +805,10 @@ TabChild::SetStatusWithContext(uint32_t aStatusType,
|
||||
const nsAString& aStatusText,
|
||||
nsISupports* aStatusContext)
|
||||
{
|
||||
// We can only send the status after the ipc machinery is set up,
|
||||
// mRemoteFrame is a good indicator.
|
||||
if (mRemoteFrame)
|
||||
// We can only send the status after the ipc machinery is set up
|
||||
if (IPCOpen()) {
|
||||
SendSetStatus(aStatusType, nsString(aStatusText));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1026,18 +1023,11 @@ TabChild::DestroyWindow()
|
||||
if (baseWindow)
|
||||
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) {
|
||||
mPuppetWidget->Destroy();
|
||||
}
|
||||
|
||||
if (mRemoteFrame) {
|
||||
mRemoteFrame->Destroy();
|
||||
mRemoteFrame = nullptr;
|
||||
}
|
||||
|
||||
mLayersConnected = Nothing();
|
||||
|
||||
if (mLayersId.IsValid()) {
|
||||
StaticMutexAutoLock lock(sTabChildrenMutex);
|
||||
@ -1129,13 +1119,8 @@ TabChild::RecvLoadURL(const nsCString& aURI,
|
||||
}
|
||||
|
||||
void
|
||||
TabChild::DoFakeShow(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
|
||||
const layers::LayersId& aLayersId,
|
||||
const CompositorOptions& aCompositorOptions,
|
||||
PRenderFrameChild* aRenderFrame, const ShowInfo& aShowInfo)
|
||||
TabChild::DoFakeShow(const ShowInfo& aShowInfo)
|
||||
{
|
||||
mLayersConnected = aRenderFrame ? Some(true) : Some(false);
|
||||
InitRenderingState(aTextureFactoryIdentifier, aLayersId, aCompositorOptions, aRenderFrame);
|
||||
RecvShow(ScreenIntSize(0, 0), aShowInfo, mParentIsActive, nsSizeMode_Normal);
|
||||
mDidFakeShow = true;
|
||||
}
|
||||
@ -1236,13 +1221,10 @@ mozilla::ipc::IPCResult
|
||||
TabChild::RecvInitRendering(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
|
||||
const layers::LayersId& aLayersId,
|
||||
const CompositorOptions& aCompositorOptions,
|
||||
const bool& aLayersConnected,
|
||||
PRenderFrameChild* aRenderFrame)
|
||||
const bool& aLayersConnected)
|
||||
{
|
||||
MOZ_ASSERT((!mDidFakeShow && aRenderFrame) || (mDidFakeShow && !aRenderFrame));
|
||||
|
||||
mLayersConnected = Some(aLayersConnected);
|
||||
InitRenderingState(aTextureFactoryIdentifier, aLayersId, aCompositorOptions, aRenderFrame);
|
||||
InitRenderingState(aTextureFactoryIdentifier, aLayersId, aCompositorOptions);
|
||||
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
|
||||
// date on the compositor used in this process.
|
||||
if (!mRemoteFrame && !recordreplay::IsRecordingOrReplaying()) {
|
||||
if (mLayersConnected.isNothing() && !recordreplay::IsRecordingOrReplaying()) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
@ -2731,19 +2713,6 @@ TabChild::RecvHandledWindowedPluginKeyEvent(
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
PRenderFrameChild*
|
||||
TabChild::AllocPRenderFrameChild()
|
||||
{
|
||||
return new RenderFrameChild();
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::DeallocPRenderFrameChild(PRenderFrameChild* aFrame)
|
||||
{
|
||||
delete aFrame;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::InitTabChildMessageManager()
|
||||
{
|
||||
@ -2780,17 +2749,10 @@ TabChild::InitTabChildMessageManager()
|
||||
void
|
||||
TabChild::InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
|
||||
const layers::LayersId& aLayersId,
|
||||
const CompositorOptions& aCompositorOptions,
|
||||
PRenderFrameChild* aRenderFrame)
|
||||
const CompositorOptions& aCompositorOptions)
|
||||
{
|
||||
mPuppetWidget->InitIMEState();
|
||||
|
||||
if (!aRenderFrame) {
|
||||
mLayersConnected = Some(false);
|
||||
NS_WARNING("failed to construct RenderFrame");
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aLayersId.IsValid());
|
||||
mTextureFactoryIdentifier = aTextureFactoryIdentifier;
|
||||
|
||||
@ -2805,7 +2767,6 @@ TabChild::InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIden
|
||||
|
||||
mCompositorOptions = Some(aCompositorOptions);
|
||||
|
||||
mRemoteFrame = static_cast<RenderFrameChild*>(aRenderFrame);
|
||||
if (aLayersId.IsValid()) {
|
||||
StaticMutexAutoLock lock(sTabChildrenMutex);
|
||||
|
||||
@ -2923,7 +2884,7 @@ TabChild::NotifyPainted()
|
||||
if (!mNotified) {
|
||||
// Recording/replaying processes have a compositor but not a remote frame.
|
||||
if (!recordreplay::IsRecordingOrReplaying()) {
|
||||
mRemoteFrame->SendNotifyCompositorTransaction();
|
||||
SendNotifyCompositorTransaction();
|
||||
}
|
||||
mNotified = true;
|
||||
}
|
||||
@ -3302,7 +3263,7 @@ TabChild::RecvRequestNotifyAfterRemotePaint()
|
||||
|
||||
// Tell the CompositorBridgeChild that, when it gets a RemotePaintIsReady
|
||||
// message that it should forward it us so that we can bounce it to our
|
||||
// RenderFrameParent.
|
||||
// TabParent.
|
||||
compositor->RequestNotifyAfterRemotePaint(this);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -54,9 +54,6 @@ template<typename T> class nsPtrHashKey;
|
||||
|
||||
namespace mozilla {
|
||||
class AbstractThread;
|
||||
namespace layout {
|
||||
class RenderFrameChild;
|
||||
} // namespace layout
|
||||
|
||||
namespace layers {
|
||||
class APZChild;
|
||||
@ -211,7 +208,6 @@ class TabChild final : public TabChildBase,
|
||||
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
|
||||
typedef mozilla::dom::CoalescedMouseData CoalescedMouseData;
|
||||
typedef mozilla::dom::CoalescedWheelData CoalescedWheelData;
|
||||
typedef mozilla::layout::RenderFrameChild RenderFrameChild;
|
||||
typedef mozilla::layers::APZEventState APZEventState;
|
||||
typedef mozilla::layers::SetAllowedTouchBehaviorCallback SetAllowedTouchBehaviorCallback;
|
||||
typedef mozilla::layers::TouchBehaviorFlags TouchBehaviorFlags;
|
||||
@ -307,8 +303,7 @@ public:
|
||||
RecvInitRendering(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
|
||||
const layers::LayersId& aLayersId,
|
||||
const mozilla::layers::CompositorOptions& aCompositorOptions,
|
||||
const bool& aLayersConnected,
|
||||
PRenderFrameChild* aRenderFrame) override;
|
||||
const bool& aLayersConnected) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvUpdateDimensions(const mozilla::dom::DimensionInfo& aDimensionInfo) override;
|
||||
@ -606,11 +601,7 @@ public:
|
||||
virtual ScreenIntSize GetInnerSize() override;
|
||||
|
||||
// Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow().
|
||||
void DoFakeShow(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
|
||||
const layers::LayersId& aLayersId,
|
||||
const mozilla::layers::CompositorOptions& aCompositorOptions,
|
||||
PRenderFrameChild* aRenderFrame,
|
||||
const ShowInfo& aShowInfo);
|
||||
void DoFakeShow(const ShowInfo& aShowInfo);
|
||||
|
||||
void ContentReceivedInputBlock(const ScrollableLayerGuid& aGuid,
|
||||
uint64_t aInputBlockId,
|
||||
@ -714,10 +705,6 @@ public:
|
||||
protected:
|
||||
virtual ~TabChild();
|
||||
|
||||
virtual PRenderFrameChild* AllocPRenderFrameChild() override;
|
||||
|
||||
virtual bool DeallocPRenderFrameChild(PRenderFrameChild* aFrame) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvDestroy() override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvSetDocShellIsActive(const bool& aIsActive) override;
|
||||
@ -775,8 +762,7 @@ private:
|
||||
|
||||
void InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
|
||||
const layers::LayersId& aLayersId,
|
||||
const mozilla::layers::CompositorOptions& aCompositorOptions,
|
||||
PRenderFrameChild* aRenderFrame);
|
||||
const mozilla::layers::CompositorOptions& aCompositorOptions);
|
||||
void InitAPZState();
|
||||
|
||||
void DestroyWindow();
|
||||
@ -826,7 +812,6 @@ private:
|
||||
RefPtr<mozilla::dom::TabGroup> mTabGroup;
|
||||
RefPtr<PuppetWidget> mPuppetWidget;
|
||||
nsCOMPtr<nsIURI> mLastURI;
|
||||
RenderFrameChild* mRemoteFrame;
|
||||
RefPtr<nsIContentChild> mManager;
|
||||
uint32_t mChromeFlags;
|
||||
uint32_t mMaxTouchPoints;
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
|
||||
#include "mozilla/layers/AsyncDragMetrics.h"
|
||||
#include "mozilla/layers/InputAPZContext.h"
|
||||
#include "mozilla/layout/RenderFrameParent.h"
|
||||
#include "mozilla/layout/RenderFrame.h"
|
||||
#include "mozilla/plugins/PPluginWidgetParent.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
@ -156,7 +156,6 @@ TabParent::TabParent(nsIContentParent* aManager,
|
||||
, mIsDestroyed(false)
|
||||
, mChromeFlags(aChromeFlags)
|
||||
, mDragValid(false)
|
||||
, mInitedByParent(false)
|
||||
, mTabId(aTabId)
|
||||
, mCreatingWindow(false)
|
||||
, mCursor(eCursorInvalid)
|
||||
@ -359,11 +358,6 @@ TabParent::DestroyInternal()
|
||||
// destroy itself and send back __delete__().
|
||||
Unused << SendDestroy();
|
||||
|
||||
if (RenderFrameParent* frame = GetRenderFrame()) {
|
||||
RemoveTabParentFromTable(frame->GetLayersId());
|
||||
frame->Destroy();
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
// Let all PluginWidgets know we are tearing down. Prevents
|
||||
// these objects from sending async events after the child side
|
||||
@ -406,8 +400,8 @@ TabParent::Destroy()
|
||||
mozilla::ipc::IPCResult
|
||||
TabParent::RecvEnsureLayersConnected(CompositorOptions* aCompositorOptions)
|
||||
{
|
||||
if (RenderFrameParent* frame = GetRenderFrame()) {
|
||||
frame->EnsureLayersConnected(aCompositorOptions);
|
||||
if (mRenderFrame.IsInitialized()) {
|
||||
mRenderFrame.EnsureLayersConnected(aCompositorOptions);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
@ -433,6 +427,14 @@ TabParent::Recv__delete__()
|
||||
void
|
||||
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
|
||||
// case of a crash.
|
||||
IMEStateManager::OnTabParentDestroying(this);
|
||||
@ -630,35 +632,38 @@ TabParent::LoadURL(nsIURI* aURI)
|
||||
}
|
||||
|
||||
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();
|
||||
MOZ_ASSERT(frameLoader);
|
||||
if (frameLoader) {
|
||||
RenderFrameParent* renderFrame = new RenderFrameParent(frameLoader);
|
||||
MOZ_ASSERT(renderFrame->IsInitted());
|
||||
layers::LayersId layersId = renderFrame->GetLayersId();
|
||||
AddTabParentToTable(layersId, this);
|
||||
if (!SendPRenderFrameConstructor(renderFrame)) {
|
||||
return;
|
||||
}
|
||||
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
|
||||
|
||||
TextureFactoryIdentifier textureFactoryIdentifier;
|
||||
renderFrame->GetTextureFactoryIdentifier(&textureFactoryIdentifier);
|
||||
Unused << SendInitRendering(textureFactoryIdentifier, layersId,
|
||||
renderFrame->GetCompositorOptions(),
|
||||
renderFrame->IsLayersConnected(), renderFrame);
|
||||
}
|
||||
} else {
|
||||
// Otherwise, the child should have constructed the RenderFrame,
|
||||
// and we should already know about it.
|
||||
MOZ_ASSERT(GetRenderFrame());
|
||||
MOZ_ASSERT(!mRenderFrame.IsInitialized());
|
||||
MOZ_ASSERT(frameLoader);
|
||||
|
||||
if (!frameLoader) {
|
||||
return;
|
||||
}
|
||||
|
||||
mRenderFrame.Initialize(frameLoader);
|
||||
MOZ_ASSERT(mRenderFrame.IsInitialized());
|
||||
|
||||
layers::LayersId layersId = mRenderFrame.GetLayersId();
|
||||
AddTabParentToTable(layersId, this);
|
||||
|
||||
TextureFactoryIdentifier textureFactoryIdentifier;
|
||||
mRenderFrame.GetTextureFactoryIdentifier(&textureFactoryIdentifier);
|
||||
Unused << SendInitRendering(textureFactoryIdentifier, layersId,
|
||||
mRenderFrame.GetCompositorOptions(),
|
||||
mRenderFrame.IsLayersConnected());
|
||||
}
|
||||
|
||||
void
|
||||
TabParent::MaybeShowFrame()
|
||||
{
|
||||
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
|
||||
if (!frameLoader) {
|
||||
return;
|
||||
}
|
||||
frameLoader->MaybeShowFrame();
|
||||
}
|
||||
|
||||
void
|
||||
@ -669,7 +674,7 @@ TabParent::Show(const ScreenIntSize& size, bool aParentIsActive)
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(GetRenderFrame());
|
||||
MOZ_ASSERT(mRenderFrame.IsInitialized());
|
||||
|
||||
nsCOMPtr<nsISupports> container = mFrameElement->OwnerDoc()->GetContainer();
|
||||
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(container);
|
||||
@ -1654,9 +1659,19 @@ TabParent::SendHandleTap(TapType aType,
|
||||
if (mIsDestroyed || !mIsReadyToHandleInputEvents) {
|
||||
return false;
|
||||
}
|
||||
if ((aType == TapType::eSingleTap || aType == TapType::eSecondTap) &&
|
||||
GetRenderFrame()) {
|
||||
GetRenderFrame()->TakeFocusForClickFromTap();
|
||||
if ((aType == TapType::eSingleTap || aType == TapType::eSecondTap)) {
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
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();
|
||||
return Manager()->AsContentParent()->IsInputPriorityEventEnabled()
|
||||
@ -2368,13 +2383,13 @@ TabParent::GetTabIdFrom(nsIDocShell *docShell)
|
||||
return TabId(0);
|
||||
}
|
||||
|
||||
RenderFrameParent*
|
||||
RenderFrame*
|
||||
TabParent::GetRenderFrame()
|
||||
{
|
||||
PRenderFrameParent* p = LoneManagedOrNullAsserts(ManagedPRenderFrameParent());
|
||||
RenderFrameParent* frame = static_cast<RenderFrameParent*>(p);
|
||||
|
||||
return frame;
|
||||
if (!mRenderFrame.IsInitialized()) {
|
||||
return nullptr;
|
||||
}
|
||||
return &mRenderFrame;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
@ -2597,68 +2612,6 @@ TabParent::DeallocPColorPickerParent(PColorPickerParent* actor)
|
||||
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>
|
||||
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
|
||||
// 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.
|
||||
if (RenderFrameParent* rfp = GetRenderFrame()) {
|
||||
if (aOutTargetGuid->mLayersId != rfp->GetLayersId()) {
|
||||
*aOutTargetGuid = ScrollableLayerGuid(rfp->GetLayersId(), 0, ScrollableLayerGuid::NULL_SCROLL_ID);
|
||||
if (mRenderFrame.IsInitialized()) {
|
||||
if (aOutTargetGuid->mLayersId != mRenderFrame.GetLayersId()) {
|
||||
*aOutTargetGuid = ScrollableLayerGuid(mRenderFrame.GetLayersId(), 0, ScrollableLayerGuid::NULL_SCROLL_ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2756,7 +2709,6 @@ TabParent::ApzAwareEventRoutingToChild(ScrollableLayerGuid* aOutTargetGuid,
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabParent::RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
|
||||
PRenderFrameParent* aRenderFrame,
|
||||
const nsString& aURL,
|
||||
const nsString& aName,
|
||||
const nsString& aFeatures,
|
||||
@ -2764,16 +2716,11 @@ TabParent::RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
|
||||
{
|
||||
CreatedWindowInfo cwi;
|
||||
cwi.rv() = NS_OK;
|
||||
cwi.layersId() = LayersId{0};
|
||||
cwi.maxTouchPoints() = 0;
|
||||
|
||||
BrowserElementParent::OpenWindowResult opened =
|
||||
BrowserElementParent::OpenWindowOOP(TabParent::GetFrom(aOpener),
|
||||
this, aRenderFrame, aURL, aName, aFeatures,
|
||||
&cwi.textureFactoryIdentifier(),
|
||||
&cwi.layersId());
|
||||
cwi.compositorOptions() =
|
||||
static_cast<RenderFrameParent*>(aRenderFrame)->GetCompositorOptions();
|
||||
this, aURL, aName, aFeatures);
|
||||
cwi.windowOpened() = (opened == BrowserElementParent::OPEN_WINDOW_ADDED);
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (widget) {
|
||||
@ -3184,6 +3131,30 @@ TabParent::RecvRemotePaintIsReady()
|
||||
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
|
||||
TabParent::RecvRemoteIsReadyToHandleInputEvents()
|
||||
{
|
||||
@ -3555,8 +3526,8 @@ TabParent::StartApzAutoscroll(float aAnchorX, float aAnchorY,
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
if (RenderFrameParent* renderFrame = GetRenderFrame()) {
|
||||
layers::LayersId layersId = renderFrame->GetLayersId();
|
||||
if (mRenderFrame.IsInitialized()) {
|
||||
layers::LayersId layersId = mRenderFrame.GetLayersId();
|
||||
if (nsCOMPtr<nsIWidget> widget = GetWidget()) {
|
||||
ScrollableLayerGuid guid{layersId, aPresShellId, aScrollId};
|
||||
|
||||
@ -3583,8 +3554,8 @@ TabParent::StopApzAutoscroll(nsViewID aScrollId, uint32_t aPresShellId)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (RenderFrameParent* renderFrame = GetRenderFrame()) {
|
||||
layers::LayersId layersId = renderFrame->GetLayersId();
|
||||
if (mRenderFrame.IsInitialized()) {
|
||||
layers::LayersId layersId = mRenderFrame.GetLayersId();
|
||||
if (nsCOMPtr<nsIWidget> widget = GetWidget()) {
|
||||
ScrollableLayerGuid guid{layersId, aPresShellId, aScrollId};
|
||||
widget->StopAsyncAutoscroll(guid);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/gfx/CrossProcessPaint.h"
|
||||
#include "mozilla/layers/CompositorBridgeParent.h"
|
||||
#include "mozilla/layout/RenderFrame.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "nsCOMPtr.h"
|
||||
@ -55,10 +56,6 @@ namespace layers {
|
||||
struct TextureFactoryIdentifier;
|
||||
} // namespace layers
|
||||
|
||||
namespace layout {
|
||||
class RenderFrameParent;
|
||||
} // namespace layout
|
||||
|
||||
namespace widget {
|
||||
struct IMENotification;
|
||||
} // namespace widget
|
||||
@ -162,7 +159,6 @@ public:
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
|
||||
PRenderFrameParent* aRenderFrame,
|
||||
const nsString& aURL,
|
||||
const nsString& aName,
|
||||
const nsString& aFeatures,
|
||||
@ -333,7 +329,8 @@ public:
|
||||
|
||||
void LoadURL(nsIURI* aURI);
|
||||
|
||||
void InitRenderFrame();
|
||||
void InitRendering();
|
||||
void MaybeShowFrame();
|
||||
|
||||
// XXX/cjones: it's not clear what we gain by hiding these
|
||||
// message-sending functions under a layer of indirection and
|
||||
@ -554,10 +551,6 @@ public:
|
||||
virtual bool
|
||||
DeallocPPaymentRequestParent(PPaymentRequestParent* aActor) override;
|
||||
|
||||
void SetInitedByParent() { mInitedByParent = true; }
|
||||
|
||||
bool IsInitedByParent() const { return mInitedByParent; }
|
||||
|
||||
bool SendLoadRemoteScript(const nsString& aURL,
|
||||
const bool& aRunInGlobalScope);
|
||||
|
||||
@ -580,11 +573,7 @@ public:
|
||||
bool TakeDragVisualization(RefPtr<mozilla::gfx::SourceSurface>& aSurface,
|
||||
LayoutDeviceIntRect* aDragRect);
|
||||
|
||||
layout::RenderFrameParent* GetRenderFrame();
|
||||
|
||||
bool SetRenderFrame(PRenderFrameParent* aRFParent);
|
||||
bool GetRenderFrameInfo(TextureFactoryIdentifier* aTextureFactoryIdentifier,
|
||||
layers::LayersId* aLayersId);
|
||||
layout::RenderFrame* GetRenderFrame();
|
||||
|
||||
mozilla::ipc::IPCResult RecvEnsureLayersConnected(CompositorOptions* aCompositorOptions) override;
|
||||
|
||||
@ -620,12 +609,10 @@ protected:
|
||||
Element* mFrameElement;
|
||||
nsCOMPtr<nsIBrowserDOMWindow> mBrowserDOMWindow;
|
||||
|
||||
virtual PRenderFrameParent* AllocPRenderFrameParent() override;
|
||||
|
||||
virtual bool DeallocPRenderFrameParent(PRenderFrameParent* aFrame) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvRemotePaintIsReady() override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvNotifyCompositorTransaction() override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvRemoteIsReadyToHandleInputEvents() override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvPaintWhileInterruptingJSNoOp(const LayersObserverEpoch& aEpoch) override;
|
||||
@ -697,10 +684,6 @@ private:
|
||||
LayoutDeviceIntRect mDragRect;
|
||||
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;
|
||||
|
||||
// We keep a strong reference to the frameloader after we've sent the
|
||||
@ -772,6 +755,7 @@ private:
|
||||
|
||||
static void RemoveTabParentFromTable(layers::LayersId aLayersId);
|
||||
|
||||
layout::RenderFrame mRenderFrame;
|
||||
LayersObserverEpoch mLayerTreeEpoch;
|
||||
|
||||
// If this flag is set, then the tab's layers will be preserved even when
|
||||
|
@ -63,6 +63,7 @@ struct ID2D1Device;
|
||||
struct IDWriteFactory;
|
||||
struct IDWriteRenderingParams;
|
||||
struct IDWriteFontFace;
|
||||
struct IDWriteFontCollection;
|
||||
|
||||
class GrContext;
|
||||
class SkCanvas;
|
||||
@ -1860,9 +1861,9 @@ public:
|
||||
static RefPtr<ID2D1Device> GetD2D1Device(uint32_t* aOutSeqNo = nullptr);
|
||||
static bool HasD2D1Device();
|
||||
static RefPtr<IDWriteFactory> GetDWriteFactory();
|
||||
static bool SetDWriteFactory(IDWriteFactory *aFactory);
|
||||
static RefPtr<IDWriteFactory> EnsureDWriteFactory();
|
||||
static bool SupportsD2D1();
|
||||
static RefPtr<IDWriteFontCollection> GetDWriteSystemFonts(bool aUpdate = false);
|
||||
|
||||
static uint64_t GetD2DVRAMUsageDrawTarget();
|
||||
static uint64_t GetD2DVRAMUsageSourceSurface();
|
||||
@ -1886,6 +1887,7 @@ private:
|
||||
static StaticRefPtr<ID3D11Device> mD3D11Device;
|
||||
static StaticRefPtr<IDWriteFactory> mDWriteFactory;
|
||||
static bool mDWriteFactoryInitialized;
|
||||
static StaticRefPtr<IDWriteFontCollection> mDWriteSystemFonts;
|
||||
|
||||
protected:
|
||||
// This guards access to the singleton devices above, as well as the
|
||||
|
@ -229,6 +229,7 @@ StaticRefPtr<ID3D11Device> Factory::mD3D11Device;
|
||||
StaticRefPtr<ID2D1Device> Factory::mD2D1Device;
|
||||
StaticRefPtr<IDWriteFactory> Factory::mDWriteFactory;
|
||||
bool Factory::mDWriteFactoryInitialized = false;
|
||||
StaticRefPtr<IDWriteFontCollection> Factory::mDWriteSystemFonts;
|
||||
StaticMutex Factory::mDeviceLock;
|
||||
StaticMutex Factory::mDTDependencyLock;
|
||||
#endif
|
||||
@ -951,6 +952,30 @@ Factory::EnsureDWriteFactory()
|
||||
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
|
||||
Factory::SupportsD2D1()
|
||||
{
|
||||
|
@ -385,6 +385,18 @@ UnscaledFontDWrite::GetWRFontDescriptor(WRFontDescriptorOutput aCb, void* aBaton
|
||||
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
|
||||
// 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
|
||||
|
@ -612,10 +612,10 @@ GPUProcessManager::HandleProcessLost()
|
||||
// (b) [CONTENT] TabChild::ReinitRendering
|
||||
// (c) [CONTENT] TabChild::SendEnsureLayersConnected
|
||||
// (d) [UI] TabParent::RecvEnsureLayersConnected
|
||||
// (e) [UI] RenderFrameParent::EnsureLayersConnected
|
||||
// (e) [UI] RenderFrame::EnsureLayersConnected
|
||||
// (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
|
||||
// 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
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "mozilla/dom/EventTarget.h" // for EventTarget
|
||||
#include "mozilla/dom/TabParent.h" // for TabParent
|
||||
#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 "nsIPresShell.h" // for nsIPresShell
|
||||
#include "nsLayoutUtils.h" // for nsLayoutUtils
|
||||
@ -166,16 +166,16 @@ FocusTarget::FocusTarget(nsIPresShell* aRootPresShell,
|
||||
|
||||
// Check if the key event target is a remote browser
|
||||
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
|
||||
if (rfp) {
|
||||
if (rf) {
|
||||
FT_LOG("Creating reflayer target with seq=%" PRIu64 ", kl=%d, lt=%" PRIu64 "\n",
|
||||
aFocusSequenceNumber,
|
||||
mFocusHasKeyEventListeners,
|
||||
rfp->GetLayersId());
|
||||
rf->GetLayersId());
|
||||
|
||||
mData = AsVariant<LayersId>(rfp->GetLayersId());
|
||||
mData = AsVariant<LayersId>(rf->GetLayersId());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,6 @@
|
||||
#include "mozilla/layers/RemoteContentController.h"
|
||||
#include "mozilla/layers/WebRenderBridgeParent.h"
|
||||
#include "mozilla/layers/AsyncImagePipelineManager.h"
|
||||
#include "mozilla/layout/RenderFrameParent.h"
|
||||
#include "mozilla/webrender/WebRenderAPI.h"
|
||||
#include "mozilla/media/MediaSystemResourceService.h" // for MediaSystemResourceService
|
||||
#include "mozilla/mozalloc.h" // for operator new, etc
|
||||
|
@ -15,10 +15,6 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace layout {
|
||||
class RenderFrameChild;
|
||||
} // namespace layout
|
||||
|
||||
namespace layers {
|
||||
|
||||
class ShadowLayerForwarder;
|
||||
@ -73,7 +69,6 @@ protected:
|
||||
Release();
|
||||
}
|
||||
friend class CompositorBridgeChild;
|
||||
friend class layout::RenderFrameChild;
|
||||
|
||||
ShadowLayerForwarder* mForwarder;
|
||||
bool mIPCOpen;
|
||||
|
@ -39,8 +39,6 @@
|
||||
#include "mozilla/layers/TextureHost.h"
|
||||
#include "mozilla/layers/AsyncCompositionManager.h"
|
||||
|
||||
using mozilla::layout::RenderFrameParent;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
|
@ -22,10 +22,6 @@ namespace ipc {
|
||||
class Shmem;
|
||||
} // namespace ipc
|
||||
|
||||
namespace layout {
|
||||
class RenderFrameParent;
|
||||
} // namespace layout
|
||||
|
||||
namespace layers {
|
||||
|
||||
class Layer;
|
||||
@ -39,7 +35,6 @@ class LayerTransactionParent final : public PLayerTransactionParent,
|
||||
public CompositableParentManager,
|
||||
public ShmemAllocator
|
||||
{
|
||||
typedef mozilla::layout::RenderFrameParent RenderFrameParent;
|
||||
typedef InfallibleTArray<Edit> EditArray;
|
||||
typedef InfallibleTArray<OpDestroy> OpDestroyArray;
|
||||
typedef InfallibleTArray<PluginWindowData> PluginsArray;
|
||||
@ -168,7 +163,6 @@ protected:
|
||||
}
|
||||
friend class CompositorBridgeParent;
|
||||
friend class CrossProcessCompositorBridgeParent;
|
||||
friend class layout::RenderFrameParent;
|
||||
|
||||
private:
|
||||
// This is a function so we can log or breakpoint on why hit
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
include LayersSurfaces;
|
||||
include protocol PCompositorBridge;
|
||||
include protocol PRenderFrame;
|
||||
include protocol PTexture;
|
||||
|
||||
include "gfxipc/ShadowLayerUtils.h";
|
||||
|
@ -8,7 +8,6 @@
|
||||
include LayersSurfaces;
|
||||
include LayersMessages;
|
||||
include protocol PCompositorBridge;
|
||||
include protocol PRenderFrame;
|
||||
include protocol PTexture;
|
||||
|
||||
include "mozilla/GfxMessageUtils.h";
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "mozilla/layers/APZCCallbackHelper.h"
|
||||
#include "mozilla/layers/APZCTreeManagerParent.h" // for APZCTreeManagerParent
|
||||
#include "mozilla/layers/APZThreadUtils.h"
|
||||
#include "mozilla/layout/RenderFrameParent.h"
|
||||
#include "mozilla/gfx/GPUProcessManager.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "Units.h"
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "Layers.h"
|
||||
#include "LayersLogging.h"
|
||||
#include "mozilla/layers/WebRenderLayerManager.h"
|
||||
#include "mozilla/layout/RenderFrameParent.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "nsTArray.h"
|
||||
|
@ -1057,8 +1057,10 @@ gfxDWriteFontList::InitFontListForPlatform()
|
||||
mFontSubstitutes.Clear();
|
||||
mNonExistingFonts.Clear();
|
||||
|
||||
hr = Factory::GetDWriteFactory()->
|
||||
GetGdiInterop(getter_AddRefs(mGDIInterop));
|
||||
RefPtr<IDWriteFactory> factory =
|
||||
Factory::GetDWriteFactory();
|
||||
|
||||
hr = factory->GetGdiInterop(getter_AddRefs(mGDIInterop));
|
||||
if (FAILED(hr)) {
|
||||
Telemetry::Accumulate(Telemetry::DWRITEFONT_INIT_PROBLEM,
|
||||
uint32_t(errGDIInterop));
|
||||
@ -1067,11 +1069,8 @@ gfxDWriteFontList::InitFontListForPlatform()
|
||||
|
||||
QueryPerformanceCounter(&t2); // base-class/interop initialization
|
||||
|
||||
RefPtr<IDWriteFactory> factory =
|
||||
Factory::GetDWriteFactory();
|
||||
|
||||
hr = factory->GetSystemFontCollection(getter_AddRefs(mSystemFonts));
|
||||
NS_ASSERTION(SUCCEEDED(hr), "GetSystemFontCollection failed!");
|
||||
mSystemFonts = Factory::GetDWriteSystemFonts(true);
|
||||
NS_ASSERTION(mSystemFonts != nullptr, "GetSystemFontCollection failed!");
|
||||
|
||||
if (FAILED(hr)) {
|
||||
Telemetry::Accumulate(Telemetry::DWRITEFONT_INIT_PROBLEM,
|
||||
|
@ -882,8 +882,6 @@ description =
|
||||
description =
|
||||
[PContent::NotifyKeywordSearchLoading]
|
||||
description =
|
||||
[PContent::AllocateLayerTreeId]
|
||||
description =
|
||||
[PContent::BeginDriverCrashGuard]
|
||||
description =
|
||||
[PContent::EndDriverCrashGuard]
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -93,19 +93,10 @@ JS::Result<Ok> parseAssertedMaybePositionalParameterName(
|
||||
AssertedScopeKind scopeKind,
|
||||
MutableHandle<GCVector<JSAtom*>> positionalParams);
|
||||
JS::Result<ParseNode*> parseAssignmentTarget();
|
||||
JS::Result<ParseNode*> parseAssignmentTargetOrAssignmentTargetWithInitializer();
|
||||
JS::Result<ParseNode*> parseAssignmentTargetProperty();
|
||||
JS::Result<ParseNode*> parseBinding();
|
||||
JS::Result<ParseNode*> parseBindingOrBindingWithInitializer();
|
||||
JS::Result<ParseNode*> parseBindingProperty();
|
||||
JS::Result<ParseNode*> parseExpression();
|
||||
JS::Result<ParseNode*> parseExpressionOrSuper();
|
||||
JS::Result<ParseNode*> parseExpressionOrTemplateElement();
|
||||
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*> parseParameter();
|
||||
JS::Result<ParseNode*> parseProgram();
|
||||
@ -117,19 +108,10 @@ JS::Result<Ok> parseSumAssertedMaybePositionalParameterName(const size_t start,
|
||||
AssertedScopeKind scopeKind,
|
||||
MutableHandle<GCVector<JSAtom*>> positionalParams);
|
||||
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*> 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*> 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*> 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*> 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);
|
||||
@ -143,8 +125,6 @@ JS::Result<ParseNode*> parseSumVariableDeclarationOrExpression(const size_t star
|
||||
// ----- Interfaces (by lexicographical order)
|
||||
// Implementations are autogenerated
|
||||
// `ParseNode*` may never be nullptr
|
||||
JS::Result<ParseNode*> parseArrowExpressionContentsWithExpression();
|
||||
JS::Result<ParseNode*> parseArrowExpressionContentsWithFunctionBody();
|
||||
JS::Result<Ok> parseAssertedBlockScope();
|
||||
JS::Result<Ok> parseAssertedBoundName(
|
||||
AssertedScopeKind scopeKind);
|
||||
@ -155,14 +135,10 @@ JS::Result<Ok> parseAssertedParameterScope(
|
||||
MutableHandle<GCVector<JSAtom*>> positionalParams);
|
||||
JS::Result<Ok> parseAssertedScriptGlobalScope();
|
||||
JS::Result<Ok> parseAssertedVarScope();
|
||||
JS::Result<ParseNode*> parseAssignmentTargetIdentifier();
|
||||
JS::Result<ParseNode*> parseBindingIdentifier();
|
||||
JS::Result<ParseNode*> parseBlock();
|
||||
JS::Result<LexicalScopeNode*> parseCatchClause();
|
||||
JS::Result<ParseNode*> parseClassElement();
|
||||
JS::Result<ParseNode*> parseDirective();
|
||||
JS::Result<ParseNode*> parseExportFromSpecifier();
|
||||
JS::Result<ParseNode*> parseExportLocalSpecifier();
|
||||
JS::Result<ListNode*> parseFormalParameters();
|
||||
JS::Result<Ok> parseFunctionExpressionContents(
|
||||
uint32_t funLength,
|
||||
@ -177,7 +153,6 @@ JS::Result<Ok> parseGetterContents(
|
||||
ListNode** paramsOut,
|
||||
ListNode** bodyOut);
|
||||
JS::Result<ParseNode*> parseIdentifierExpression();
|
||||
JS::Result<ParseNode*> parseImportSpecifier();
|
||||
JS::Result<Ok> parseSetterContents(
|
||||
uint32_t funLength,
|
||||
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*> 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*> 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> parseInterfaceAssertedBoundName(const size_t start, const BinKind kind, const BinFields& fields,
|
||||
AssertedScopeKind scopeKind);
|
||||
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,
|
||||
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,
|
||||
MutableHandle<GCVector<JSAtom*>> positionalParams);
|
||||
JS::Result<Ok> parseInterfaceAssertedPositionalParameterName(const size_t start, const BinKind kind, const BinFields& fields,
|
||||
AssertedScopeKind scopeKind,
|
||||
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> 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*> 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*> 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*> 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*> 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*> 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<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*> 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);
|
||||
@ -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*> 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*> 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*> 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);
|
||||
@ -268,9 +226,6 @@ JS::Result<Ok> parseInterfaceGetterContents(const size_t start, const BinKind ki
|
||||
ListNode** bodyOut);
|
||||
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*> 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*> 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);
|
||||
@ -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*> 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*> 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*> 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);
|
||||
@ -344,18 +298,8 @@ JS::Result<Ok> parseListOfAssertedDeclaredName(
|
||||
JS::Result<Ok> parseListOfAssertedMaybePositionalParameterName(
|
||||
AssertedScopeKind scopeKind,
|
||||
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<ParseNode*> parseListOfExportFromSpecifier();
|
||||
JS::Result<ParseNode*> parseListOfExportLocalSpecifier();
|
||||
JS::Result<ParseNode*> parseListOfExpressionOrTemplateElement();
|
||||
JS::Result<ParseNode*> parseListOfImportDeclarationOrExportDeclarationOrStatement();
|
||||
JS::Result<ParseNode*> parseListOfImportSpecifier();
|
||||
JS::Result<ListNode*> parseListOfObjectProperty();
|
||||
JS::Result<ParseNode*> parseListOfOptionalBindingOrBindingWithInitializer();
|
||||
JS::Result<ListNode*> parseListOfOptionalSpreadElementOrExpression();
|
||||
JS::Result<ListNode*> parseListOfParameter();
|
||||
JS::Result<ListNode*> parseListOfStatement();
|
||||
@ -365,10 +309,8 @@ JS::Result<ListNode*> parseListOfVariableDeclarator();
|
||||
|
||||
// ----- Default values (by lexicographical order)
|
||||
// Implementations are autogenerated
|
||||
JS::Result<ParseNode*> parseOptionalAssignmentTarget();
|
||||
JS::Result<ParseNode*> parseOptionalBinding();
|
||||
JS::Result<ParseNode*> parseOptionalBindingIdentifier();
|
||||
JS::Result<ParseNode*> parseOptionalBindingOrBindingWithInitializer();
|
||||
JS::Result<LexicalScopeNode*> parseOptionalCatchClause();
|
||||
JS::Result<ParseNode*> parseOptionalExpression();
|
||||
JS::Result<ParseNode*> parseOptionalSpreadElementOrExpression();
|
||||
|
@ -519,14 +519,6 @@ const INTERFACE_ARGS: &str =
|
||||
const TOPLEVEL_INTERFACE: &str =
|
||||
"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.
|
||||
struct CPPExporter {
|
||||
/// The syntax to export.
|
||||
@ -643,12 +635,24 @@ impl CPPExporter {
|
||||
// 1. Typesums
|
||||
let sums_of_interfaces = self.syntax.resolved_sums_of_interfaces_by_name();
|
||||
for (name, nodes) in sums_of_interfaces {
|
||||
let rules_for_this_sum = self.rules.get(name);
|
||||
|
||||
let mut edges: HashSet<Rc<String>> = HashSet::new();
|
||||
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();
|
||||
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())));
|
||||
}
|
||||
refgraph.insert(Rc::new(format!("Sum{}", name.to_string())), sum_edges);
|
||||
@ -657,22 +661,35 @@ impl CPPExporter {
|
||||
// 2. Single interfaces
|
||||
let interfaces_by_name = self.syntax.interfaces_by_name();
|
||||
for (name, interface) in interfaces_by_name {
|
||||
let mut edges: HashSet<Rc<String>> = HashSet::new();
|
||||
edges.insert(Rc::new(format!("Interface{}", name)));
|
||||
refgraph.insert(string_from_nodename(name), edges);
|
||||
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();
|
||||
edges.insert(Rc::new(format!("Interface{}", name)));
|
||||
refgraph.insert(name.to_rc_string().clone(), edges);
|
||||
}
|
||||
|
||||
let mut interface_edges: HashSet<Rc<String>> = HashSet::new();
|
||||
for field in interface.contents().fields() {
|
||||
match field.type_().get_primitive(&self.syntax) {
|
||||
Some(IsNullable { is_nullable: _, content: Primitive::Interface(_) })
|
||||
| None => {
|
||||
let typename = TypeName::type_(field.type_());
|
||||
interface_edges.insert(Rc::new(typename.to_string()));
|
||||
},
|
||||
// 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() {
|
||||
match field.type_().get_primitive(&self.syntax) {
|
||||
Some(IsNullable { is_nullable: _, content: Primitive::Interface(_) })
|
||||
| None => {
|
||||
let typename = TypeName::type_(field.type_());
|
||||
interface_edges.insert(Rc::new(typename.to_string()));
|
||||
},
|
||||
|
||||
// Don't have to handle other type of fields (string,
|
||||
// number, bool, etc).
|
||||
_ => {}
|
||||
// Don't have to handle other type of fields (string,
|
||||
// number, bool, etc).
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
refgraph.insert(Rc::new(format!("Interface{}", name)), interface_edges);
|
||||
@ -680,14 +697,23 @@ impl CPPExporter {
|
||||
|
||||
// 3. String Enums
|
||||
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
|
||||
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();
|
||||
edges.insert(string_from_nodename(&parser.elements));
|
||||
refgraph.insert(string_from_nodename(&parser.name), edges);
|
||||
edges.insert(parser.elements.to_rc_string().clone());
|
||||
refgraph.insert(name.to_rc_string().clone(), edges);
|
||||
}
|
||||
|
||||
// 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.
|
||||
@ -983,7 +1009,7 @@ enum class BinVariant {
|
||||
buffer.push_str("// Implementations are autogenerated\n");
|
||||
buffer.push_str("// `ParseNode*` may never be nullptr\n");
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1025,7 +1051,7 @@ enum class BinVariant {
|
||||
let rules_for_this_interface = self.rules.get(name);
|
||||
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);
|
||||
outer_parsers.push(outer.reindent(""));
|
||||
}
|
||||
@ -1058,7 +1084,7 @@ enum class BinVariant {
|
||||
.iter()
|
||||
.sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str()));
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1072,7 +1098,7 @@ enum class BinVariant {
|
||||
buffer.push_str("\n\n// ----- Lists (by lexicographical order)\n");
|
||||
buffer.push_str("// Implementations are autogenerated\n");
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1089,7 +1115,7 @@ enum class BinVariant {
|
||||
buffer.push_str("\n\n// ----- Default values (by lexicographical order)\n");
|
||||
buffer.push_str("// Implementations are autogenerated\n");
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1151,7 +1177,7 @@ impl CPPExporter {
|
||||
.sorted();
|
||||
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*/",
|
||||
nodes = nodes.iter()
|
||||
.format("\n "),
|
||||
@ -1239,7 +1265,7 @@ impl CPPExporter {
|
||||
|
||||
/// Generate the implementation of a single list parser
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1332,7 +1358,7 @@ impl CPPExporter {
|
||||
debug!(target: "generate_spidermonkey", "Implementing optional value {} backed by {}",
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
let comment = format!("\n/*\n{}*/\n", ToWebidl::interface(interface, "", " "));
|
||||
buffer.push_str(&comment);
|
||||
@ -1865,7 +1891,7 @@ impl CPPExporter {
|
||||
.iter()
|
||||
.sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str()));
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
#include "gfxPrefs.h"
|
||||
|
||||
#include "mozilla/layout/RenderFrameParent.h"
|
||||
#include "mozilla/layout/RenderFrame.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
@ -46,7 +46,7 @@
|
||||
#include "RetainedDisplayListBuilder.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using mozilla::layout::RenderFrameParent;
|
||||
using mozilla::layout::RenderFrame;
|
||||
|
||||
static bool sShowPreviousPage = true;
|
||||
|
||||
@ -333,9 +333,9 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
return;
|
||||
|
||||
nsFrameLoader* frameLoader = FrameLoader();
|
||||
RenderFrameParent* rfp = nullptr;
|
||||
RenderFrame* rf = nullptr;
|
||||
if (frameLoader) {
|
||||
rfp = frameLoader->GetCurrentRenderFrame();
|
||||
rf = frameLoader->GetCurrentRenderFrame();
|
||||
}
|
||||
|
||||
// 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) {
|
||||
nsDisplayListCollection decorations(aBuilder);
|
||||
DisplayBorderBackgroundOutline(aBuilder, decorations);
|
||||
if (rfp) {
|
||||
if (rf) {
|
||||
// Wrap background colors of <iframe>s with remote subdocuments in their
|
||||
// own layer so we generate a ColorLayer. This is helpful for optimizing
|
||||
// compositing; we can skip compositing the ColorLayer when the
|
||||
@ -366,7 +366,7 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
return;
|
||||
}
|
||||
|
||||
if (rfp) {
|
||||
if (rf) {
|
||||
// We're the subdoc for <browser remote="true"> and it has
|
||||
// painted content. Display its shadow layer tree.
|
||||
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
|
||||
@ -1081,8 +1081,8 @@ nsSubDocumentFrame::FrameLoader() const
|
||||
return mFrameLoader;
|
||||
}
|
||||
|
||||
mozilla::layout::RenderFrameParent*
|
||||
nsSubDocumentFrame::GetRenderFrameParent() const
|
||||
mozilla::layout::RenderFrame*
|
||||
nsSubDocumentFrame::GetRenderFrame() const
|
||||
{
|
||||
return FrameLoader() ? FrameLoader()->GetCurrentRenderFrame() : nullptr;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
class RenderFrameParent;
|
||||
class RenderFrame;
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,7 +140,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::layout::RenderFrameParent* GetRenderFrameParent() const;
|
||||
mozilla::layout::RenderFrame* GetRenderFrame() const;
|
||||
|
||||
protected:
|
||||
friend class AsyncFrameInit;
|
||||
|
@ -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
|
@ -6,34 +6,20 @@
|
||||
|
||||
#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/Element.h"
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
#include "mozilla/layers/CompositorBridgeParent.h"
|
||||
#include "mozilla/layers/CompositorTypes.h"
|
||||
#include "mozilla/layers/LayerTransactionParent.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsFrameLoader.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsStyleStructInlines.h"
|
||||
#include "nsSubDocumentFrame.h"
|
||||
#include "nsView.h"
|
||||
#include "RenderFrameParent.h"
|
||||
#include "RenderFrame.h"
|
||||
#include "mozilla/gfx/GPUProcessManager.h"
|
||||
#include "mozilla/layers/LayerManagerComposite.h"
|
||||
#include "mozilla/layers/CompositorBridgeChild.h"
|
||||
#include "mozilla/layers/WebRenderLayerManager.h"
|
||||
#include "mozilla/layers/WebRenderScrollData.h"
|
||||
#include "mozilla/webrender/WebRenderAPI.h"
|
||||
#include "ClientLayerManager.h"
|
||||
#include "FrameLayerBuilder.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::gfx;
|
||||
@ -42,39 +28,6 @@ using namespace mozilla::layers;
|
||||
namespace mozilla {
|
||||
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>
|
||||
GetLayerManager(nsFrameLoader* aFrameLoader)
|
||||
{
|
||||
@ -92,124 +45,77 @@ GetLayerManager(nsFrameLoader* aFrameLoader)
|
||||
return nsContentUtils::LayerManagerForDocument(doc);
|
||||
}
|
||||
|
||||
RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader)
|
||||
RenderFrame::RenderFrame()
|
||||
: mLayersId{0}
|
||||
, mFrameLoader(nullptr)
|
||||
, mLayerManager(nullptr)
|
||||
, mInitialized(false)
|
||||
, mLayersConnected(false)
|
||||
, mFrameLoader(aFrameLoader)
|
||||
, mFrameLoaderDestroyed(false)
|
||||
, mAsyncPanZoomEnabled(false)
|
||||
, mInitted(false)
|
||||
{
|
||||
mInitted = Init(aFrameLoader);
|
||||
}
|
||||
|
||||
RenderFrameParent::~RenderFrameParent()
|
||||
{}
|
||||
RenderFrame::~RenderFrame()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
RenderFrameParent::Init(nsFrameLoader* aFrameLoader)
|
||||
RenderFrame::Initialize(nsFrameLoader* aFrameLoader)
|
||||
{
|
||||
if (mInitted || !aFrameLoader) {
|
||||
if (mInitialized || !aFrameLoader) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mFrameLoader = aFrameLoader;
|
||||
|
||||
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,
|
||||
// and we'll keep an indirect reference to that tree.
|
||||
GPUProcessManager* gpm = GPUProcessManager::Get();
|
||||
mLayersConnected = gpm->AllocateAndConnectLayerTreeId(
|
||||
compositor,
|
||||
mTabProcessId,
|
||||
&mLayersId,
|
||||
&mCompositorOptions);
|
||||
|
||||
// Our remote frame will push layers updates to the compositor,
|
||||
// and we'll keep an indirect reference to that tree.
|
||||
GPUProcessManager* gpm = GPUProcessManager::Get();
|
||||
mLayersConnected = gpm->AllocateAndConnectLayerTreeId(
|
||||
compositor,
|
||||
browser->Manager()->AsContentParent()->OtherPid(),
|
||||
&mLayersId,
|
||||
&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;
|
||||
}
|
||||
|
||||
bool
|
||||
RenderFrameParent::IsInitted()
|
||||
{
|
||||
return mInitted;
|
||||
}
|
||||
|
||||
void
|
||||
RenderFrameParent::Destroy()
|
||||
RenderFrame::Destroy()
|
||||
{
|
||||
mFrameLoaderDestroyed = true;
|
||||
if (mLayersId.IsValid()) {
|
||||
GPUProcessManager::Get()->UnmapLayerTreeId(mLayersId, mTabProcessId);
|
||||
}
|
||||
|
||||
mFrameLoader = nullptr;
|
||||
mLayerManager = nullptr;
|
||||
}
|
||||
|
||||
already_AddRefed<Layer>
|
||||
RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame,
|
||||
LayerManager* aManager,
|
||||
nsDisplayItem* aItem,
|
||||
const ContainerLayerParameters& aContainerParameters)
|
||||
void
|
||||
RenderFrame::EnsureLayersConnected(CompositorOptions* aCompositorOptions)
|
||||
{
|
||||
MOZ_ASSERT(aFrame,
|
||||
"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;
|
||||
RefPtr<LayerManager> lm = GetLayerManager(mFrameLoader);
|
||||
if (!lm) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mLayersId.IsValid()) {
|
||||
return nullptr;
|
||||
if (!lm->GetCompositorBridgeChild()) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<Layer> layer =
|
||||
(aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aItem));
|
||||
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();
|
||||
mLayersConnected = lm->GetCompositorBridgeChild()->SendNotifyChildRecreated(mLayersId, &mCompositorOptions);
|
||||
*aCompositorOptions = mCompositorOptions;
|
||||
}
|
||||
|
||||
LayerManager*
|
||||
RenderFrameParent::AttachLayerManager()
|
||||
RenderFrame::AttachLayerManager()
|
||||
{
|
||||
RefPtr<LayerManager> lm;
|
||||
if (mFrameLoader) {
|
||||
@ -227,7 +133,7 @@ RenderFrameParent::AttachLayerManager()
|
||||
}
|
||||
|
||||
void
|
||||
RenderFrameParent::OwnerContentChanged(nsIContent* aContent)
|
||||
RenderFrame::OwnerContentChanged(nsIContent* aContent)
|
||||
{
|
||||
MOZ_ASSERT(!mFrameLoader || mFrameLoader->GetOwnerContent() == aContent,
|
||||
"Don't build new map if owner is same!");
|
||||
@ -236,46 +142,7 @@ RenderFrameParent::OwnerContentChanged(nsIContent* aContent)
|
||||
}
|
||||
|
||||
void
|
||||
RenderFrameParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
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)
|
||||
RenderFrame::GetTextureFactoryIdentifier(TextureFactoryIdentifier* aTextureFactoryIdentifier) const
|
||||
{
|
||||
RefPtr<LayerManager> lm = mFrameLoader ? GetLayerManager(mFrameLoader) : nullptr;
|
||||
// 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 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,
|
||||
nsSubDocumentFrame* aFrame)
|
||||
: nsDisplayItem(aBuilder, aFrame)
|
||||
@ -337,7 +203,7 @@ nsDisplayRemote::nsDisplayRemote(nsDisplayListBuilder* aBuilder,
|
||||
mEventRegionsOverride |= EventRegionsOverride::ForceDispatchToContent;
|
||||
}
|
||||
|
||||
nsFrameLoader* frameLoader = GetRenderFrameParent()->FrameLoader();
|
||||
nsFrameLoader* frameLoader = GetRenderFrame()->GetFrameLoader();
|
||||
if (frameLoader) {
|
||||
TabParent* browser = TabParent::GetFrom(frameLoader);
|
||||
if (browser) {
|
||||
@ -351,7 +217,7 @@ nsDisplayRemote::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const ContainerLayerParameters& aParameters)
|
||||
{
|
||||
if (mozilla::layout::IsTempLayerManager(aManager)) {
|
||||
if (IsTempLayerManager(aManager)) {
|
||||
return mozilla::LAYER_NONE;
|
||||
}
|
||||
return mozilla::LAYER_ACTIVE_FORCE;
|
||||
@ -360,8 +226,8 @@ nsDisplayRemote::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
bool
|
||||
nsDisplayRemote::HasDeletedFrame() const
|
||||
{
|
||||
// RenderFrameParent might change without invalidating nsSubDocumentFrame.
|
||||
return !GetRenderFrameParent() || nsDisplayItem::HasDeletedFrame();
|
||||
// RenderFrame might change without invalidating nsSubDocumentFrame.
|
||||
return !GetRenderFrame() || nsDisplayItem::HasDeletedFrame();
|
||||
}
|
||||
|
||||
already_AddRefed<Layer>
|
||||
@ -369,15 +235,57 @@ nsDisplayRemote::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
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 =
|
||||
GetRenderFrameParent()->BuildLayer(aBuilder, mFrame, aManager,
|
||||
this, aContainerParameters);
|
||||
aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, this);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
@ -403,9 +311,9 @@ nsDisplayRemote::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuild
|
||||
mozilla::layers::WebRenderLayerManager* aManager,
|
||||
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());
|
||||
rect += mOffset;
|
||||
|
||||
@ -432,14 +340,14 @@ nsDisplayRemote::UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
|
||||
LayersId
|
||||
nsDisplayRemote::GetRemoteLayersId() const
|
||||
{
|
||||
MOZ_ASSERT(GetRenderFrameParent());
|
||||
return GetRenderFrameParent()->GetLayersId();
|
||||
MOZ_ASSERT(GetRenderFrame());
|
||||
return GetRenderFrame()->GetLayersId();
|
||||
}
|
||||
|
||||
mozilla::layout::RenderFrameParent*
|
||||
nsDisplayRemote::GetRenderFrameParent() const
|
||||
mozilla::layout::RenderFrame*
|
||||
nsDisplayRemote::GetRenderFrame() const
|
||||
{
|
||||
return mFrame
|
||||
? static_cast<nsSubDocumentFrame*>(mFrame)->GetRenderFrameParent()
|
||||
? static_cast<nsSubDocumentFrame*>(mFrame)->GetRenderFrame()
|
||||
: nullptr;
|
||||
}
|
134
layout/ipc/RenderFrame.h
Normal file
134
layout/ipc/RenderFrame.h
Normal 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
|
@ -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
|
@ -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
|
@ -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
|
@ -8,15 +8,13 @@ with Files('**'):
|
||||
BUG_COMPONENT = ('Core', 'Web Painting')
|
||||
|
||||
EXPORTS.mozilla.layout += [
|
||||
'RenderFrameChild.h',
|
||||
'RenderFrameParent.h',
|
||||
'RenderFrame.h',
|
||||
'VsyncChild.h',
|
||||
'VsyncParent.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'RenderFrameChild.cpp',
|
||||
'RenderFrameParent.cpp',
|
||||
'RenderFrame.cpp',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
@ -25,7 +23,6 @@ SOURCES += [
|
||||
]
|
||||
|
||||
IPDL_SOURCES = [
|
||||
'PRenderFrame.ipdl',
|
||||
'PVsync.ipdl',
|
||||
]
|
||||
|
||||
|
@ -445,6 +445,13 @@ VARCACHE_PREF(
|
||||
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
|
||||
//---------------------------------------------------------------------------
|
||||
|
15
mozilla-config.h.in
Normal file → Executable file
15
mozilla-config.h.in
Normal file → Executable file
@ -45,6 +45,21 @@
|
||||
*/
|
||||
#if defined(CHROMIUM_SANDBOX_BUILD) && defined(XP_WIN)
|
||||
#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 /* MOZILLA_CONFIG_H */
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -17,4 +17,5 @@ mingw_copy_s.patch
|
||||
mingw_operator_new.patch
|
||||
mingw_cast_getprocaddress.patch
|
||||
mingw_capitalization.patch
|
||||
mingw_disable_one_try.patch
|
||||
mingw_offsetof.patch
|
||||
|
@ -37,6 +37,8 @@ typedef HRESULT(WINAPI* SetThreadDescription)(HANDLE hThread,
|
||||
|
||||
// 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;
|
||||
@ -48,6 +50,7 @@ void SetNameInternal(PlatformThreadId thread_id, const char* name) {
|
||||
reinterpret_cast<DWORD_PTR*>(&info));
|
||||
} __except(EXCEPTION_CONTINUE_EXECUTION) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
struct ThreadParams {
|
||||
|
@ -55,14 +55,8 @@ class DeviceRunner(BaseRunner):
|
||||
|
||||
@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')
|
||||
for k, v in self._device_env.iteritems():
|
||||
cmd.append('%s=%s' % (k, v))
|
||||
cmd.append(self.app_ctx.remote_binary)
|
||||
return cmd
|
||||
# command built by mozdevice -- see start() below
|
||||
return None
|
||||
|
||||
def start(self, *args, **kwargs):
|
||||
if isinstance(self.device, BaseEmulator) and not self.device.connected:
|
||||
@ -70,15 +64,18 @@ class DeviceRunner(BaseRunner):
|
||||
self.device.connect()
|
||||
self.device.setup_profile(self.profile)
|
||||
|
||||
# TODO: this doesn't work well when the device is running but dropped
|
||||
# wifi for some reason. It would be good to probe the state of the device
|
||||
# to see if we have the homescreen running, or something, before waiting here
|
||||
self.device.wait_for_net()
|
||||
|
||||
if not self.device.wait_for_net():
|
||||
raise Exception("Network did not come up when starting device")
|
||||
|
||||
pid = BaseRunner.start(self, *args, **kwargs)
|
||||
app = self.app_ctx.remote_process
|
||||
args = ["-no-remote", "-profile", self.app_ctx.remote_profile]
|
||||
args.extend(self.cmdargs)
|
||||
env = self._device_env
|
||||
url = None
|
||||
if 'geckoview' in app:
|
||||
activity = "TestRunnerActivity"
|
||||
self.app_ctx.device.launch_activity(app, activity, e10s=True, moz_env=env,
|
||||
extra_args=args, url=url)
|
||||
else:
|
||||
self.app_ctx.device.launch_fennec(
|
||||
app, moz_env=env, extra_args=args, url=url)
|
||||
|
||||
timeout = 10 # seconds
|
||||
end_time = datetime.datetime.now() + datetime.timedelta(seconds=timeout)
|
||||
@ -87,10 +84,6 @@ class DeviceRunner(BaseRunner):
|
||||
if not self.is_running():
|
||||
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):
|
||||
if not sig and self.is_running():
|
||||
self.app_ctx.stop_application()
|
||||
@ -184,20 +177,3 @@ class FennecRunner(DeviceRunner):
|
||||
def __init__(self, cmdargs=None, **kwargs):
|
||||
super(FennecRunner, self).__init__(**kwargs)
|
||||
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
|
||||
|
@ -107,6 +107,7 @@ user_pref("dom.ipc.reportProcessHangs", false); // process hang monitor
|
||||
user_pref("dom.ipc.tabs.shutdownTimeoutSecs", 0);
|
||||
user_pref("dom.min_background_timeout_value", 1000);
|
||||
user_pref("dom.popup_maximum", -1);
|
||||
user_pref("dom.block_multiple_popups", false);
|
||||
user_pref("dom.presentation.testing.simulate-receiver", false);
|
||||
// Prevent connection to the push server for tests.
|
||||
user_pref("dom.push.connection.enabled", false);
|
||||
|
@ -1,23 +1,4 @@
|
||||
[createImageBitmap-origin.sub.html]
|
||||
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]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -213,7 +213,7 @@ class FennecBrowser(FirefoxBrowser):
|
||||
process_class=ProcessHandler,
|
||||
process_args={"processOutputLine": [self.on_output]})
|
||||
|
||||
self.logger.debug("Starting Fennec")
|
||||
self.logger.debug("Starting %s" % self.package_name)
|
||||
# connect to a running emulator
|
||||
self.runner.device.connect()
|
||||
|
||||
@ -225,7 +225,7 @@ class FennecBrowser(FirefoxBrowser):
|
||||
local="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):
|
||||
if self.runner is not None:
|
||||
|
@ -227,7 +227,9 @@ class XPCShellTestThread(Thread):
|
||||
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.
|
||||
"""
|
||||
return proc.returncode
|
||||
if proc is not None and hasattr(proc, "returncode"):
|
||||
return proc.returncode
|
||||
return -1
|
||||
|
||||
def communicate(self, proc):
|
||||
"""
|
||||
@ -284,7 +286,10 @@ class XPCShellTestThread(Thread):
|
||||
self.log.info("%s | environment: %s" % (name, list(changedEnv)))
|
||||
|
||||
def killTimeout(self, proc):
|
||||
mozcrash.kill_and_get_minidump(proc.pid, self.tempDir, utility_path=self.utility_path)
|
||||
if proc is not None and hasattr(proc, "pid"):
|
||||
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):
|
||||
"""Checks for a still-running test process, kills it and fails the test if found.
|
||||
|
@ -147,7 +147,7 @@ Lock::Find(void* aNativeLock)
|
||||
// When diverged from the recording, don't allow uses of locks that are
|
||||
// held by idling threads that have not diverged from the recording.
|
||||
// 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();
|
||||
EnsureNotDivergedFromRecording();
|
||||
Unreachable();
|
||||
|
@ -302,9 +302,9 @@ public:
|
||||
// Allow a single thread to resume execution.
|
||||
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.
|
||||
bool IsIdle() { return mIdle; }
|
||||
bool ShouldIdle() { return mShouldIdle; }
|
||||
};
|
||||
|
||||
// This uses a stack pointer instead of TLS to make sure events are passed
|
||||
|
@ -151,6 +151,7 @@ void
|
||||
Channel::SendMessage(const Message& aMsg)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread() ||
|
||||
aMsg.mType == MessageType::BeginFatalError ||
|
||||
aMsg.mType == MessageType::FatalError ||
|
||||
aMsg.mType == MessageType::MiddlemanCallRequest);
|
||||
|
||||
|
@ -109,8 +109,13 @@ namespace recordreplay {
|
||||
\
|
||||
/* A critical error occurred and execution cannot continue. The child will */ \
|
||||
/* stop executing after sending this message and will wait to be terminated. */ \
|
||||
/* A minidump for the child has been generated. */ \
|
||||
_Macro(FatalError) \
|
||||
\
|
||||
/* Sent when a fatal error has occurred, but before the minidump has been */ \
|
||||
/* generated. */ \
|
||||
_Macro(BeginFatalError) \
|
||||
\
|
||||
/* The child's graphics were repainted. */ \
|
||||
_Macro(Paint) \
|
||||
\
|
||||
@ -371,6 +376,8 @@ struct FatalErrorMessage : public Message
|
||||
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.
|
||||
// This needs to match the format expected for canvas image data, to avoid
|
||||
// transforming the data before rendering it in the middleman process.
|
||||
|
@ -108,8 +108,9 @@ ChannelMessageHandler(Message* aMsg)
|
||||
PrintSpew("Terminate message received, exiting...\n");
|
||||
_exit(0);
|
||||
} else {
|
||||
MOZ_CRASH("Hanged replaying process");
|
||||
ReportFatalError(Nothing(), "Hung replaying process");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MessageType::SetIsActive: {
|
||||
const SetIsActiveMessage& nmsg = (const SetIsActiveMessage&) *aMsg;
|
||||
@ -350,6 +351,10 @@ CreateCheckpoint()
|
||||
void
|
||||
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.
|
||||
UnrecoverableSnapshotFailure();
|
||||
|
||||
|
@ -40,6 +40,8 @@ ChildProcessInfo::ChildProcessInfo(UniquePtr<ChildRole> aRole,
|
||||
, mNumRecoveredMessages(0)
|
||||
, mRole(std::move(aRole))
|
||||
, mPauseNeeded(false)
|
||||
, mHasBegunFatalError(false)
|
||||
, mHasFatalError(false)
|
||||
{
|
||||
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.
|
||||
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);
|
||||
OnCrash(nmsg.Error());
|
||||
return;
|
||||
@ -527,12 +533,23 @@ ChildProcessInfo::OnCrash(const char* aWhy)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
|
||||
// If a child process crashes or hangs then annotate the crash report and
|
||||
// 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.
|
||||
// If a child process crashes or hangs then annotate the crash report.
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::RecordReplayError,
|
||||
nsAutoCString(aWhy));
|
||||
Shutdown();
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
// 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;
|
||||
} else {
|
||||
// The child is still non-responsive after sending the terminate
|
||||
// message, fail without producing a minidump.
|
||||
// message.
|
||||
OnCrash("Child process non-responsive");
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,6 @@ HandleMessageInMiddleman(ipc::Side aSide, const IPC::Message& aMessage)
|
||||
// Graphics messages that affect both processes.
|
||||
type == dom::PBrowser::Msg_InitRendering__ID ||
|
||||
type == dom::PBrowser::Msg_SetDocShellIsActive__ID ||
|
||||
type == dom::PBrowser::Msg_PRenderFrameConstructor__ID ||
|
||||
type == dom::PBrowser::Msg_RenderLayers__ID ||
|
||||
type == dom::PBrowser::Msg_UpdateDimensions__ID ||
|
||||
// These messages perform some graphics related initialization.
|
||||
|
@ -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
|
||||
MaybeTriggerExplicitPaint()
|
||||
{
|
||||
|
@ -611,12 +611,6 @@ SwitchActiveChild(ChildProcessInfo* aChild, bool aRecoverPosition = true)
|
||||
oldActiveChild->RecoverToCheckpoint(oldActiveChild->MostRecentSavedCheckpoint());
|
||||
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);
|
||||
MaybeUpdateGraphicsAtCheckpoint(aMsg.mCheckpointId);
|
||||
|
||||
if (!gActiveChild->IsRecording()) {
|
||||
UpdateGraphicsOverlay();
|
||||
}
|
||||
|
||||
// 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
|
||||
// the process to pause. Immediately resume if the main thread is blocked.
|
||||
|
@ -94,9 +94,6 @@ void SendGraphicsMemoryToChild();
|
||||
// an unhandled recording divergence.
|
||||
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
|
||||
// or reaches a checkpoint.
|
||||
void MaybeUpdateGraphicsAtPaint(const PaintMessage& aMsg);
|
||||
@ -274,6 +271,11 @@ class ChildProcessInfo
|
||||
// Whether we need this child to pause while the recording is updated.
|
||||
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 OnIncomingRecoveryMessage(const Message& aMsg);
|
||||
void SendNextRecoveryMessage();
|
||||
|
@ -2758,9 +2758,12 @@ public:
|
||||
bool
|
||||
Visit(nsPurpleBuffer& aBuffer, nsPurpleBufferEntry* aEntry)
|
||||
{
|
||||
// Ignore any slice budget we have when recording/replaying, as it behaves
|
||||
// non-deterministically.
|
||||
if (mBudget && !recordreplay::IsRecordingOrReplaying()) {
|
||||
// The cycle collector does not collect anything when recording/replaying.
|
||||
if (recordreplay::IsRecordingOrReplaying()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mBudget) {
|
||||
if (mBudget->isOverBudget()) {
|
||||
return false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user