Merge mozilla-central to autoland. CLOSED TREE

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

View File

@ -10,6 +10,7 @@ skip-if = os == "linux" # Bug 952422
[browser_iframe_gone_mid_download.js]
[browser_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

View File

@ -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",
];

View File

@ -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));
}

View File

@ -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; }

View File

@ -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);
}

View File

@ -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

View File

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

View File

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

View File

@ -22,7 +22,6 @@
#include "nsVariant.h"
#include "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;
}

View File

@ -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>.

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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*) {

View File

@ -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) {

View File

@ -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([

View File

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

View File

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

View File

@ -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,

View File

@ -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) {

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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,

View File

@ -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();
}

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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()
{

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

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

View File

@ -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

View File

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

View File

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

View File

@ -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"

View File

@ -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"

View File

@ -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,

View File

@ -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

View File

@ -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();

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -1,37 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=8 et :
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PBrowser;
include protocol PLayerTransaction;
using class nsRegion from "nsRegion.h";
namespace mozilla {
namespace layout {
/**
* PRenderFrame (in the layout sense of "frame") represents one web
* "page". It's used to graft content processes' layer trees into
* chrome's rendering path. The lifetime of a PRenderFrame is tied to
* its PresShell in the child process.
*
* The child process conceptually "owns" a PRenderFrame, because it
* only makes sense wrt documents loaded by the child.
*/
sync protocol PRenderFrame
{
manager PBrowser;
parent:
async NotifyCompositorTransaction();
async __delete__();
};
} // namespace layout
} // namespace mozilla

View File

@ -6,34 +6,20 @@
#include "base/basictypes.h"
#include "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
View File

@ -0,0 +1,134 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_layout_RenderFrame_h
#define mozilla_layout_RenderFrame_h
#include "base/process.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/ipc/IdType.h"
#include "mozilla/layers/CompositorOptions.h"
#include "mozilla/layers/LayersTypes.h"
#include "nsDisplayList.h"
class nsFrameLoader;
class nsSubDocumentFrame;
namespace mozilla {
namespace layers {
struct TextureFactoryIdentifier;
} // namespace layers
namespace layout {
class RenderFrame final
{
typedef mozilla::layers::CompositorOptions CompositorOptions;
typedef mozilla::layers::LayerManager LayerManager;
typedef mozilla::layers::LayersId LayersId;
typedef mozilla::layers::TextureFactoryIdentifier TextureFactoryIdentifier;
public:
RenderFrame();
virtual ~RenderFrame();
bool Initialize(nsFrameLoader* aFrameLoader);
void Destroy();
void EnsureLayersConnected(CompositorOptions* aCompositorOptions);
LayerManager* AttachLayerManager();
void OwnerContentChanged(nsIContent* aContent);
nsFrameLoader* GetFrameLoader() const { return mFrameLoader; }
LayersId GetLayersId() const { return mLayersId; }
CompositorOptions GetCompositorOptions() const { return mCompositorOptions; }
void GetTextureFactoryIdentifier(TextureFactoryIdentifier* aTextureFactoryIdentifier) const;
bool IsInitialized() const { return mInitialized; }
bool IsLayersConnected() const { return mLayersConnected; }
private:
base::ProcessId mTabProcessId;
// When our child frame is pushing transactions directly to the
// compositor, this is the ID of its layer tree in the compositor's
// context.
LayersId mLayersId;
// The compositor options for this layers id. This is only meaningful if
// the compositor actually knows about this layers id (i.e. when mLayersConnected
// is true).
CompositorOptions mCompositorOptions;
RefPtr<nsFrameLoader> mFrameLoader;
RefPtr<LayerManager> mLayerManager;
bool mInitialized;
// A flag that indicates whether or not the compositor knows about the
// layers id. In some cases this RenderFrame is not connected to the
// compositor and so this flag is false.
bool mLayersConnected;
};
} // namespace layout
} // namespace mozilla
/**
* A DisplayRemote exists solely to graft a child process's shadow
* layer tree (for a given RenderFrame) into its parent
* process's layer tree.
*/
class nsDisplayRemote final : public nsDisplayItem
{
typedef mozilla::dom::TabId TabId;
typedef mozilla::gfx::Matrix4x4 Matrix4x4;
typedef mozilla::layers::EventRegionsOverride EventRegionsOverride;
typedef mozilla::layers::Layer Layer;
typedef mozilla::layers::LayersId LayersId;
typedef mozilla::layers::RefLayer RefLayer;
typedef mozilla::layout::RenderFrame RenderFrame;
typedef mozilla::LayoutDeviceRect LayoutDeviceRect;
typedef mozilla::LayoutDeviceIntPoint LayoutDeviceIntPoint;
public:
nsDisplayRemote(nsDisplayListBuilder* aBuilder,
nsSubDocumentFrame* aFrame);
bool HasDeletedFrame() const override;
LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
already_AddRefed<Layer>
BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder) override;
bool UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
mozilla::layers::WebRenderLayerScrollData* aLayerData) override;
NS_DISPLAY_DECL_NAME("Remote", TYPE_REMOTE)
private:
LayersId GetRemoteLayersId() const;
RenderFrame* GetRenderFrame() const;
TabId mTabId;
LayoutDeviceIntPoint mOffset;
EventRegionsOverride mEventRegionsOverride;
};
#endif // mozilla_layout_RenderFrame_h

View File

@ -1,34 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RenderFrameChild.h"
#include "mozilla/layers/LayerTransactionChild.h"
using mozilla::layers::PLayerTransactionChild;
using mozilla::layers::LayerTransactionChild;
namespace mozilla {
namespace layout {
void
RenderFrameChild::ActorDestroy(ActorDestroyReason why)
{
mWasDestroyed = true;
}
void
RenderFrameChild::Destroy()
{
if (mWasDestroyed) {
return;
}
Send__delete__(this);
// WARNING: |this| is dead, hands off
}
} // namespace layout
} // namespace mozilla

View File

@ -1,32 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_RenderFrameChild_h
#define mozilla_dom_RenderFrameChild_h
#include "mozilla/layout/PRenderFrameChild.h"
namespace mozilla {
namespace layout {
class RenderFrameChild : public PRenderFrameChild
{
public:
RenderFrameChild() : mWasDestroyed(false) {}
virtual ~RenderFrameChild() {}
void ActorDestroy(ActorDestroyReason why) override;
void Destroy();
private:
bool mWasDestroyed;
};
} // namespace layout
} // namespace mozilla
#endif // mozilla_dom_RenderFrameChild_h

View File

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

View File

@ -8,15 +8,13 @@ with Files('**'):
BUG_COMPONENT = ('Core', 'Web Painting')
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',
]

View File

@ -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
View 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 */

View File

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

View File

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

View File

@ -37,6 +37,8 @@ typedef HRESULT(WINAPI* SetThreadDescription)(HANDLE hThread,
// This function has try handling, so it is separated out of its caller.
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 {

View File

@ -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

View File

@ -107,6 +107,7 @@ user_pref("dom.ipc.reportProcessHangs", false); // process hang monitor
user_pref("dom.ipc.tabs.shutdownTimeoutSecs", 0);
user_pref("dom.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);

View File

@ -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

View File

@ -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:

View File

@ -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.

View File

@ -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();

View File

@ -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

View File

@ -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);

View File

@ -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.

View File

@ -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();

View File

@ -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");
}
}

View File

@ -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.

View File

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

View File

@ -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.

View File

@ -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();

View File

@ -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;
}