forked from mirrors/gecko-dev
Merge inbound to m-c a=merge
MozReview-Commit-ID: 6viJ4wRxLa8
This commit is contained in:
commit
22a72df7fe
177 changed files with 2135 additions and 2306 deletions
|
|
@ -313,24 +313,12 @@ nsAccessibilityService::ListenersChanged(nsIArray* aEventChanges)
|
|||
if (!node || !node->IsHTMLElement()) {
|
||||
continue;
|
||||
}
|
||||
nsCOMPtr<nsIArray> listenerNames;
|
||||
change->GetChangedListenerNames(getter_AddRefs(listenerNames));
|
||||
|
||||
uint32_t changeCount;
|
||||
rv = listenerNames->GetLength(&changeCount);
|
||||
change->GetCountOfEventListenerChangesAffectingAccessibility(&changeCount);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
for (uint32_t i = 0 ; i < changeCount ; i++) {
|
||||
nsCOMPtr<nsIAtom> listenerName = do_QueryElementAt(listenerNames, i);
|
||||
|
||||
// We are only interested in event listener changes which may
|
||||
// make an element accessible or inaccessible.
|
||||
if (listenerName != nsGkAtoms::onclick &&
|
||||
listenerName != nsGkAtoms::onmousedown &&
|
||||
listenerName != nsGkAtoms::onmouseup) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsIDocument* ownerDoc = node->OwnerDoc();
|
||||
DocAccessible* document = GetExistingDocAccessible(ownerDoc);
|
||||
|
||||
|
|
|
|||
|
|
@ -849,6 +849,9 @@ function makePreview(row) {
|
|||
var physWidth = 0, physHeight = 0;
|
||||
var width = 0, height = 0;
|
||||
|
||||
let serial = Components.classes["@mozilla.org/network/serialization-helper;1"]
|
||||
.getService(Components.interfaces.nsISerializationHelper);
|
||||
let loadingPrincipalStr = serial.serializeToString(gDocInfo.principal);
|
||||
if ((item.HTMLLinkElement || item.HTMLInputElement ||
|
||||
item.HTMLImageElement || item.SVGImageElement ||
|
||||
(item.HTMLObjectElement && mimeType && mimeType.startsWith("image/")) ||
|
||||
|
|
@ -907,12 +910,14 @@ function makePreview(row) {
|
|||
setItemValue("imagedimensiontext", imageSize);
|
||||
}, {once: true});
|
||||
|
||||
newImage.setAttribute("loadingprincipal", loadingPrincipalStr);
|
||||
newImage.setAttribute("src", url);
|
||||
} else {
|
||||
// Handle the case where newImage is not used for width & height
|
||||
if (item.HTMLVideoElement && isProtocolAllowed) {
|
||||
newImage = document.createElementNS("http://www.w3.org/1999/xhtml", "video");
|
||||
newImage.id = "thepreviewimage";
|
||||
newImage.setAttribute("loadingprincipal", loadingPrincipalStr);
|
||||
newImage.src = url;
|
||||
newImage.controls = true;
|
||||
width = physWidth = item.videoWidth;
|
||||
|
|
@ -923,6 +928,7 @@ function makePreview(row) {
|
|||
} else if (item.HTMLAudioElement && isProtocolAllowed) {
|
||||
newImage = new Audio;
|
||||
newImage.id = "thepreviewimage";
|
||||
newImage.setAttribute("loadingprincipal", loadingPrincipalStr);
|
||||
newImage.src = url;
|
||||
newImage.controls = true;
|
||||
isAudio = true;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,12 @@
|
|||
[browser_pageInfo.js]
|
||||
support-files =
|
||||
../general/feed_tab.html
|
||||
[browser_pageinfo_firstPartyIsolation.js]
|
||||
support-files =
|
||||
image.html
|
||||
../general/audio.ogg
|
||||
../general/moz.png
|
||||
../general/video.ogg
|
||||
[browser_pageinfo_images.js]
|
||||
[browser_pageinfo_image_info.js]
|
||||
skip-if = (os == 'linux' && e10s) # bug 1161699
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
const {classes: Cc, interfaces: Ci, manager: Cm} = Components;
|
||||
|
||||
function waitForEvent(elem, event) {
|
||||
return new Promise(resolve => {
|
||||
elem.addEventListener(event, resolve, {capture: true, once: true});
|
||||
});
|
||||
}
|
||||
|
||||
function testFirstPartyDomain(pageInfo) {
|
||||
return new Promise(resolve => {
|
||||
const EXPECTED_DOMAIN = "example.com";
|
||||
info("pageInfo load");
|
||||
pageInfo.onFinished.push(async function() {
|
||||
info("pageInfo onfinished");
|
||||
let tree = pageInfo.document.getElementById("imagetree");
|
||||
Assert.ok(!!tree, "should have imagetree element");
|
||||
|
||||
// i=0: <img>
|
||||
// i=1: <video>
|
||||
// i=2: <audio>
|
||||
for (let i = 0; i < 3; i++) {
|
||||
info("imagetree select " + i);
|
||||
tree.view.selection.select(i);
|
||||
tree.treeBoxObject.ensureRowIsVisible(i);
|
||||
tree.focus();
|
||||
|
||||
let preview = pageInfo.document.getElementById("thepreviewimage");
|
||||
info("preview.src=" + preview.src);
|
||||
|
||||
// For <img>, we will query imgIRequest.imagePrincipal later, so we wait
|
||||
// for loadend event. For <audio> and <video>, so far we only can get
|
||||
// the loadingprincipal attribute on the node, so we simply wait for
|
||||
// loadstart.
|
||||
if (i == 0) {
|
||||
await waitForEvent(preview, "loadend");
|
||||
} else {
|
||||
await waitForEvent(preview, "loadstart");
|
||||
}
|
||||
|
||||
info("preview load " + i);
|
||||
|
||||
// Originally thepreviewimage is loaded with SystemPrincipal, therefore
|
||||
// it won't have origin attributes, now we've changed to loadingPrincipal
|
||||
// to the content in bug 1376971, it should have firstPartyDomain set.
|
||||
if (i == 0) {
|
||||
let req = preview.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST);
|
||||
Assert.equal(req.imagePrincipal.originAttributes.firstPartyDomain, EXPECTED_DOMAIN,
|
||||
"imagePrincipal should have firstPartyDomain set to " + EXPECTED_DOMAIN);
|
||||
}
|
||||
|
||||
// Check the node has the attribute 'loadingprincipal'.
|
||||
let serial = Components.classes["@mozilla.org/network/serialization-helper;1"]
|
||||
.getService(Components.interfaces.nsISerializationHelper);
|
||||
let loadingPrincipalStr = preview.getAttribute("loadingprincipal");
|
||||
let loadingPrincipal = serial.deserializeObject(loadingPrincipalStr);
|
||||
Assert.equal(loadingPrincipal.originAttributes.firstPartyDomain, EXPECTED_DOMAIN,
|
||||
"loadingPrincipal should have firstPartyDomain set to " + EXPECTED_DOMAIN);
|
||||
|
||||
}
|
||||
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
Services.prefs.setBoolPref("privacy.firstparty.isolate", true);
|
||||
registerCleanupFunction(function() {
|
||||
Services.prefs.clearUserPref("privacy.firstparty.isolate");
|
||||
});
|
||||
|
||||
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
|
||||
content.location = "https://example.com/browser/browser/base/content/test/pageinfo/image.html";
|
||||
await waitForEvent(gBrowser.selectedBrowser, "load");
|
||||
|
||||
let spec = gBrowser.selectedBrowser.currentURI.spec;
|
||||
let pageInfo = BrowserPageInfo(spec, "mediaTab");
|
||||
info("waitForEvent pageInfo");
|
||||
await waitForEvent(pageInfo, "load");
|
||||
|
||||
info("calling testFirstPartyDomain");
|
||||
await testFirstPartyDomain(pageInfo);
|
||||
|
||||
pageInfo.close();
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
5
browser/base/content/test/pageinfo/image.html
Normal file
5
browser/base/content/test/pageinfo/image.html
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<html>
|
||||
<img src='moz.png' height=100 width=150 id='test-image'>
|
||||
<video src='video.ogg' id='test-video'></video>
|
||||
<audio src='audio.ogg' id='test-audio'></audio>
|
||||
</html>
|
||||
|
|
@ -53,7 +53,8 @@ NS_IMETHODIMP
|
|||
BasePrincipal::GetOriginNoSuffix(nsACString& aOrigin)
|
||||
{
|
||||
MOZ_ASSERT(mInitialized);
|
||||
return mOriginNoSuffix->ToUTF8String(aOrigin);
|
||||
mOriginNoSuffix->ToUTF8String(aOrigin);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -293,7 +294,8 @@ NS_IMETHODIMP
|
|||
BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes)
|
||||
{
|
||||
MOZ_ASSERT(mOriginSuffix);
|
||||
return mOriginSuffix->ToUTF8String(aOriginAttributes);
|
||||
mOriginSuffix->ToUTF8String(aOriginAttributes);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
|||
|
|
@ -453,13 +453,12 @@ Toolbox.prototype = {
|
|||
if (e.originalTarget.closest("input[type=text]") ||
|
||||
e.originalTarget.closest("input[type=search]") ||
|
||||
e.originalTarget.closest("input:not([type])") ||
|
||||
e.originalTarget.closest("textarea")
|
||||
) {
|
||||
e.originalTarget.closest("textarea")) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
this.openTextBoxContextMenu(e.screenX, e.screenY);
|
||||
}
|
||||
}, true);
|
||||
});
|
||||
|
||||
this.shortcuts = new KeyShortcuts({
|
||||
window: this.doc.defaultView
|
||||
|
|
|
|||
|
|
@ -1124,7 +1124,15 @@ Inspector.prototype = {
|
|||
},
|
||||
|
||||
_onContextMenu: function (e) {
|
||||
if (e.originalTarget.closest("input[type=text]") ||
|
||||
e.originalTarget.closest("input:not([type])") ||
|
||||
e.originalTarget.closest("textarea")) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
this._openMenu({
|
||||
screenX: e.screenX,
|
||||
screenY: e.screenY,
|
||||
|
|
|
|||
|
|
@ -397,6 +397,15 @@ CssRuleView.prototype = {
|
|||
* Context menu handler.
|
||||
*/
|
||||
_onContextMenu: function (event) {
|
||||
if (event.originalTarget.closest("input[type=text]") ||
|
||||
event.originalTarget.closest("input:not([type])") ||
|
||||
event.originalTarget.closest("textarea")) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
this._contextmenu.show(event);
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -26,10 +26,19 @@ add_task(function* () {
|
|||
|
||||
let [, win, doc] = yield createHost("bottom", TEST_URI);
|
||||
|
||||
info("Resizing window to have some space below the window.");
|
||||
info("Resize and move the window to have space below.");
|
||||
let originalWidth = win.top.outerWidth;
|
||||
let originalHeight = win.top.outerHeight;
|
||||
win.top.resizeBy(0, -100);
|
||||
win.top.resizeBy(-100, -200);
|
||||
let originalTop = win.top.screenTop;
|
||||
let originalLeft = win.top.screenLeft;
|
||||
win.top.moveTo(100, 100);
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
info("Restore original window dimensions and position.");
|
||||
win.top.resizeTo(originalWidth, originalHeight);
|
||||
win.top.moveTo(originalTop, originalLeft);
|
||||
});
|
||||
|
||||
info("Create HTML tooltip");
|
||||
let tooltip = new HTMLTooltip(doc, {useXulWrapper: true});
|
||||
|
|
@ -55,9 +64,6 @@ add_task(function* () {
|
|||
is(tooltip.isVisible(), false, "Tooltip is not visible");
|
||||
|
||||
tooltip.destroy();
|
||||
|
||||
info("Restore original window dimensions.");
|
||||
win.top.resizeTo(originalWidth, originalHeight);
|
||||
});
|
||||
|
||||
function checkTooltip(tooltip, position, height) {
|
||||
|
|
|
|||
|
|
@ -356,12 +356,13 @@ Editor.prototype = {
|
|||
});
|
||||
|
||||
cm.getWrapperElement().addEventListener("contextmenu", ev => {
|
||||
ev.preventDefault();
|
||||
|
||||
if (!this.config.contextMenu) {
|
||||
return;
|
||||
}
|
||||
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
|
||||
let popup = this.config.contextMenu;
|
||||
if (typeof popup == "string") {
|
||||
popup = doc.getElementById(this.config.contextMenu);
|
||||
|
|
|
|||
|
|
@ -3,14 +3,10 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
:root {
|
||||
--markup-hidden-attr-color: var(--theme-comment);
|
||||
--markup-hidden-tag-color: #A1A1A4;
|
||||
--markup-outline: var(--theme-splitter-color);
|
||||
}
|
||||
|
||||
.theme-dark:root {
|
||||
--markup-hidden-attr-color: var(--theme-body-color-inactive);
|
||||
--markup-hidden-tag-color: var(--theme-content-color1);
|
||||
--markup-outline: var(--theme-selection-background);
|
||||
}
|
||||
|
||||
|
|
@ -336,16 +332,6 @@ ul.children + .tag-line::before {
|
|||
z-index: 1;
|
||||
}
|
||||
|
||||
|
||||
.not-displayed .attr-name,
|
||||
.not-displayed .attr-value {
|
||||
color: var(--markup-hidden-attr-color);
|
||||
}
|
||||
|
||||
.not-displayed .theme-fg-color3 {
|
||||
color: var(--markup-hidden-tag-color);
|
||||
}
|
||||
|
||||
/* Firebug Theme */
|
||||
|
||||
.theme-firebug .theme-fg-color3 {
|
||||
|
|
@ -367,12 +353,6 @@ ul.children + .tag-line::before {
|
|||
font-size: var(--theme-toolbar-font-size);
|
||||
}
|
||||
|
||||
/* In case a node isn't displayed in the page, we fade the syntax highlighting */
|
||||
.theme-firebug .not-displayed .open,
|
||||
.theme-firebug .not-displayed .close {
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
/* Selected nodes in the tree should have light selected text.
|
||||
theme-selected doesn't work in this case since the text is a
|
||||
sibling of the class, not a child. */
|
||||
|
|
@ -403,6 +383,12 @@ ul.children + .tag-line::before {
|
|||
color: #787878;
|
||||
}
|
||||
|
||||
/* In case a node isn't displayed in the page, we fade the syntax highlighting */
|
||||
.not-displayed .open,
|
||||
.not-displayed .close {
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
/* Events */
|
||||
.markupview-events {
|
||||
font-size: 8px;
|
||||
|
|
|
|||
|
|
@ -28,14 +28,13 @@ CustomElementCallback::Call()
|
|||
mOwnerData->mElementIsBeingCreated = true;
|
||||
|
||||
// The callback hasn't actually been invoked yet, but we need to flip
|
||||
// this now in order to enqueue the attached callback. This is a spec
|
||||
// this now in order to enqueue the connected callback. This is a spec
|
||||
// bug (w3c bug 27437).
|
||||
mOwnerData->mCreatedCallbackInvoked = true;
|
||||
|
||||
// If ELEMENT is in a document and this document has a browsing context,
|
||||
// enqueue attached callback for ELEMENT.
|
||||
// If ELEMENT is connected, enqueue connected callback for ELEMENT.
|
||||
nsIDocument* document = mThisObject->GetComposedDoc();
|
||||
if (document && document->GetDocShell()) {
|
||||
if (document) {
|
||||
NodeInfo* ni = mThisObject->NodeInfo();
|
||||
nsDependentAtomString extType(mOwnerData->mType);
|
||||
|
||||
|
|
@ -49,18 +48,18 @@ CustomElementCallback::Call()
|
|||
extType.IsEmpty() ? nullptr : &extType);
|
||||
|
||||
nsContentUtils::EnqueueLifecycleCallback(
|
||||
document, nsIDocument::eAttached, mThisObject, nullptr, definition);
|
||||
nsIDocument::eConnected, mThisObject, nullptr, definition);
|
||||
}
|
||||
|
||||
static_cast<LifecycleCreatedCallback *>(mCallback.get())->Call(mThisObject, rv);
|
||||
mOwnerData->mElementIsBeingCreated = false;
|
||||
break;
|
||||
}
|
||||
case nsIDocument::eAttached:
|
||||
static_cast<LifecycleAttachedCallback *>(mCallback.get())->Call(mThisObject, rv);
|
||||
case nsIDocument::eConnected:
|
||||
static_cast<LifecycleConnectedCallback *>(mCallback.get())->Call(mThisObject, rv);
|
||||
break;
|
||||
case nsIDocument::eDetached:
|
||||
static_cast<LifecycleDetachedCallback *>(mCallback.get())->Call(mThisObject, rv);
|
||||
case nsIDocument::eDisconnected:
|
||||
static_cast<LifecycleDisconnectedCallback *>(mCallback.get())->Call(mThisObject, rv);
|
||||
break;
|
||||
case nsIDocument::eAttributeChanged:
|
||||
static_cast<LifecycleAttributeChangedCallback *>(mCallback.get())->Call(mThisObject,
|
||||
|
|
@ -321,7 +320,7 @@ CustomElementRegistry::SetupCustomElement(Element* aElement,
|
|||
SyncInvokeReactions(nsIDocument::eCreated, aElement, definition);
|
||||
}
|
||||
|
||||
UniquePtr<CustomElementCallback>
|
||||
/* static */ UniquePtr<CustomElementCallback>
|
||||
CustomElementRegistry::CreateCustomElementCallback(
|
||||
nsIDocument::ElementCallbackType aType, Element* aCustomElement,
|
||||
LifecycleCallbackArgs* aArgs, CustomElementDefinition* aDefinition)
|
||||
|
|
@ -340,15 +339,15 @@ CustomElementRegistry::CreateCustomElementCallback(
|
|||
}
|
||||
break;
|
||||
|
||||
case nsIDocument::eAttached:
|
||||
if (aDefinition->mCallbacks->mAttachedCallback.WasPassed()) {
|
||||
func = aDefinition->mCallbacks->mAttachedCallback.Value();
|
||||
case nsIDocument::eConnected:
|
||||
if (aDefinition->mCallbacks->mConnectedCallback.WasPassed()) {
|
||||
func = aDefinition->mCallbacks->mConnectedCallback.Value();
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDocument::eDetached:
|
||||
if (aDefinition->mCallbacks->mDetachedCallback.WasPassed()) {
|
||||
func = aDefinition->mCallbacks->mDetachedCallback.Value();
|
||||
case nsIDocument::eDisconnected:
|
||||
if (aDefinition->mCallbacks->mDisconnectedCallback.WasPassed()) {
|
||||
func = aDefinition->mCallbacks->mDisconnectedCallback.Value();
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -395,7 +394,7 @@ CustomElementRegistry::SyncInvokeReactions(nsIDocument::ElementCallbackType aTyp
|
|||
}
|
||||
|
||||
UniquePtr<CustomElementReaction> reaction(Move(
|
||||
MakeUnique<CustomElementCallbackReaction>(this, aDefinition,
|
||||
MakeUnique<CustomElementCallbackReaction>(aDefinition,
|
||||
Move(callback))));
|
||||
|
||||
RefPtr<SyncInvokeReactionRunnable> runnable =
|
||||
|
|
@ -404,7 +403,7 @@ CustomElementRegistry::SyncInvokeReactions(nsIDocument::ElementCallbackType aTyp
|
|||
nsContentUtils::AddScriptRunner(runnable);
|
||||
}
|
||||
|
||||
void
|
||||
/* static */ void
|
||||
CustomElementRegistry::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
|
||||
Element* aCustomElement,
|
||||
LifecycleCallbackArgs* aArgs,
|
||||
|
|
@ -425,7 +424,7 @@ CustomElementRegistry::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType
|
|||
return;
|
||||
}
|
||||
|
||||
DocGroup* docGroup = mWindow->GetDocGroup();
|
||||
DocGroup* docGroup = aCustomElement->OwnerDoc()->GetDocGroup();
|
||||
if (!docGroup) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -440,7 +439,7 @@ CustomElementRegistry::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType
|
|||
|
||||
CustomElementReactionsStack* reactionsStack =
|
||||
docGroup->CustomElementReactionsStack();
|
||||
reactionsStack->EnqueueCallbackReaction(this, aCustomElement, definition,
|
||||
reactionsStack->EnqueueCallbackReaction(aCustomElement, definition,
|
||||
Move(callback));
|
||||
}
|
||||
|
||||
|
|
@ -480,7 +479,7 @@ CustomElementRegistry::UpgradeCandidates(nsIAtom* aKey,
|
|||
continue;
|
||||
}
|
||||
|
||||
reactionsStack->EnqueueUpgradeReaction(this, elem, aDefinition);
|
||||
reactionsStack->EnqueueUpgradeReaction(elem, aDefinition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -934,8 +933,7 @@ CustomElementRegistry::Upgrade(Element* aElement,
|
|||
(attrValue.IsEmpty() ? VoidString() : attrValue),
|
||||
(namespaceURI.IsEmpty() ? VoidString() : namespaceURI)
|
||||
};
|
||||
nsContentUtils::EnqueueLifecycleCallback(aElement->OwnerDoc(),
|
||||
nsIDocument::eAttributeChanged,
|
||||
nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eAttributeChanged,
|
||||
aElement,
|
||||
&args, aDefinition);
|
||||
}
|
||||
|
|
@ -943,7 +941,10 @@ CustomElementRegistry::Upgrade(Element* aElement,
|
|||
}
|
||||
|
||||
// Step 4.
|
||||
// TODO: Bug 1334043 - Implement connected lifecycle callbacks for custom elements
|
||||
if (aElement->IsInComposedDoc()) {
|
||||
nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eConnected, aElement,
|
||||
nullptr, aDefinition);
|
||||
}
|
||||
|
||||
// Step 5.
|
||||
AutoConstructionStackEntry acs(aDefinition->mConstructionStack,
|
||||
|
|
@ -965,8 +966,7 @@ CustomElementRegistry::Upgrade(Element* aElement,
|
|||
aElement->SetCustomElementDefinition(aDefinition);
|
||||
|
||||
// This is for old spec.
|
||||
nsContentUtils::EnqueueLifecycleCallback(aElement->OwnerDoc(),
|
||||
nsIDocument::eCreated,
|
||||
nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eCreated,
|
||||
aElement, nullptr, aDefinition);
|
||||
}
|
||||
|
||||
|
|
@ -1010,20 +1010,18 @@ CustomElementReactionsStack::PopAndInvokeElementQueue()
|
|||
}
|
||||
|
||||
void
|
||||
CustomElementReactionsStack::EnqueueUpgradeReaction(CustomElementRegistry* aRegistry,
|
||||
Element* aElement,
|
||||
CustomElementReactionsStack::EnqueueUpgradeReaction(Element* aElement,
|
||||
CustomElementDefinition* aDefinition)
|
||||
{
|
||||
Enqueue(aElement, new CustomElementUpgradeReaction(aRegistry, aDefinition));
|
||||
Enqueue(aElement, new CustomElementUpgradeReaction(aDefinition));
|
||||
}
|
||||
|
||||
void
|
||||
CustomElementReactionsStack::EnqueueCallbackReaction(CustomElementRegistry* aRegistry,
|
||||
Element* aElement,
|
||||
CustomElementReactionsStack::EnqueueCallbackReaction(Element* aElement,
|
||||
CustomElementDefinition* aDefinition,
|
||||
UniquePtr<CustomElementCallback> aCustomElementCallback)
|
||||
{
|
||||
Enqueue(aElement, new CustomElementCallbackReaction(aRegistry, aDefinition,
|
||||
Enqueue(aElement, new CustomElementCallbackReaction(aDefinition,
|
||||
Move(aCustomElementCallback)));
|
||||
}
|
||||
|
||||
|
|
@ -1036,14 +1034,14 @@ CustomElementReactionsStack::Enqueue(Element* aElement,
|
|||
|
||||
// Add element to the current element queue.
|
||||
if (!mReactionsStack.IsEmpty()) {
|
||||
mReactionsStack.LastElement()->AppendElement(do_GetWeakReference(aElement));
|
||||
mReactionsStack.LastElement()->AppendElement(aElement);
|
||||
elementData->mReactionQueue.AppendElement(aReaction);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the custom element reactions stack is empty, then:
|
||||
// Add element to the backup element queue.
|
||||
mBackupQueue.AppendElement(do_GetWeakReference(aElement));
|
||||
mBackupQueue.AppendElement(aElement);
|
||||
elementData->mReactionQueue.AppendElement(aReaction);
|
||||
|
||||
if (mIsBackupQueueProcessing) {
|
||||
|
|
@ -1081,14 +1079,18 @@ CustomElementReactionsStack::InvokeReactions(ElementQueue* aElementQueue,
|
|||
|
||||
// Note: It's possible to re-enter this method.
|
||||
for (uint32_t i = 0; i < aElementQueue->Length(); ++i) {
|
||||
nsCOMPtr<Element> element = do_QueryReferent(aElementQueue->ElementAt(i));
|
||||
Element* element = aElementQueue->ElementAt(i);
|
||||
|
||||
if (!element) {
|
||||
continue;
|
||||
}
|
||||
|
||||
RefPtr<CustomElementData> elementData = element->GetCustomElementData();
|
||||
MOZ_ASSERT(elementData, "CustomElementData should exist");
|
||||
if (!elementData) {
|
||||
// This happens when the document is destroyed and the element is already
|
||||
// unlinked, no need to fire the callbacks in this case.
|
||||
return;
|
||||
}
|
||||
|
||||
auto& reactions = elementData->mReactionQueue;
|
||||
for (uint32_t j = 0; j < reactions.Length(); ++j) {
|
||||
|
|
@ -1138,14 +1140,14 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CustomElementDefinition)
|
|||
cb.NoteXPCOMChild(callbacks->mCreatedCallback.Value());
|
||||
}
|
||||
|
||||
if (callbacks->mAttachedCallback.WasPassed()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCallbacks->mAttachedCallback");
|
||||
cb.NoteXPCOMChild(callbacks->mAttachedCallback.Value());
|
||||
if (callbacks->mConnectedCallback.WasPassed()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCallbacks->mConnectedCallback");
|
||||
cb.NoteXPCOMChild(callbacks->mConnectedCallback.Value());
|
||||
}
|
||||
|
||||
if (callbacks->mDetachedCallback.WasPassed()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCallbacks->mDetachedCallback");
|
||||
cb.NoteXPCOMChild(callbacks->mDetachedCallback.Value());
|
||||
if (callbacks->mDisconnectedCallback.WasPassed()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCallbacks->mDisconnectedCallback");
|
||||
cb.NoteXPCOMChild(callbacks->mDisconnectedCallback.Value());
|
||||
}
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mConstructor");
|
||||
|
|
@ -1184,7 +1186,7 @@ CustomElementDefinition::CustomElementDefinition(nsIAtom* aType,
|
|||
/* virtual */ void
|
||||
CustomElementUpgradeReaction::Invoke(Element* aElement, ErrorResult& aRv)
|
||||
{
|
||||
mRegistry->Upgrade(aElement, mDefinition, aRv);
|
||||
CustomElementRegistry::Upgrade(aElement, mDefinition, aRv);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -200,10 +200,8 @@ private:
|
|||
class CustomElementReaction
|
||||
{
|
||||
public:
|
||||
explicit CustomElementReaction(CustomElementRegistry* aRegistry,
|
||||
CustomElementDefinition* aDefinition)
|
||||
: mRegistry(aRegistry)
|
||||
, mDefinition(aDefinition)
|
||||
explicit CustomElementReaction(CustomElementDefinition* aDefinition)
|
||||
: mDefinition(aDefinition)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -214,16 +212,14 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
CustomElementRegistry* mRegistry;
|
||||
CustomElementDefinition* mDefinition;
|
||||
};
|
||||
|
||||
class CustomElementUpgradeReaction final : public CustomElementReaction
|
||||
{
|
||||
public:
|
||||
explicit CustomElementUpgradeReaction(CustomElementRegistry* aRegistry,
|
||||
CustomElementDefinition* aDefinition)
|
||||
: CustomElementReaction(aRegistry, aDefinition)
|
||||
explicit CustomElementUpgradeReaction(CustomElementDefinition* aDefinition)
|
||||
: CustomElementReaction(aDefinition)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -234,10 +230,9 @@ private:
|
|||
class CustomElementCallbackReaction final : public CustomElementReaction
|
||||
{
|
||||
public:
|
||||
CustomElementCallbackReaction(CustomElementRegistry* aRegistry,
|
||||
CustomElementDefinition* aDefinition,
|
||||
CustomElementCallbackReaction(CustomElementDefinition* aDefinition,
|
||||
UniquePtr<CustomElementCallback> aCustomElementCallback)
|
||||
: CustomElementReaction(aRegistry, aDefinition)
|
||||
: CustomElementReaction(aDefinition)
|
||||
, mCustomElementCallback(Move(aCustomElementCallback))
|
||||
{
|
||||
}
|
||||
|
|
@ -263,26 +258,25 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
// nsWeakPtr is a weak pointer of Element
|
||||
// Hold a strong reference of Element so that it does not get cycle collected
|
||||
// before the reactions in its reaction queue are invoked.
|
||||
// The element reaction queues are stored in CustomElementData.
|
||||
// We need to lookup ElementReactionQueueMap again to get relevant reaction queue.
|
||||
// The choice of 1 for the auto size here is based on gut feeling.
|
||||
typedef AutoTArray<nsWeakPtr, 1> ElementQueue;
|
||||
typedef AutoTArray<RefPtr<Element>, 1> ElementQueue;
|
||||
|
||||
/**
|
||||
* Enqueue a custom element upgrade reaction
|
||||
* https://html.spec.whatwg.org/multipage/scripting.html#enqueue-a-custom-element-upgrade-reaction
|
||||
*/
|
||||
void EnqueueUpgradeReaction(CustomElementRegistry* aRegistry,
|
||||
Element* aElement,
|
||||
void EnqueueUpgradeReaction(Element* aElement,
|
||||
CustomElementDefinition* aDefinition);
|
||||
|
||||
/**
|
||||
* Enqueue a custom element callback reaction
|
||||
* https://html.spec.whatwg.org/multipage/scripting.html#enqueue-a-custom-element-callback-reaction
|
||||
*/
|
||||
void EnqueueCallbackReaction(CustomElementRegistry* aRegistry,
|
||||
Element* aElement,
|
||||
void EnqueueCallbackReaction(Element* aElement,
|
||||
CustomElementDefinition* aDefinition,
|
||||
UniquePtr<CustomElementCallback> aCustomElementCallback);
|
||||
|
||||
|
|
@ -377,10 +371,10 @@ public:
|
|||
*/
|
||||
void SetupCustomElement(Element* aElement, const nsAString* aTypeExtension);
|
||||
|
||||
void EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
|
||||
Element* aCustomElement,
|
||||
LifecycleCallbackArgs* aArgs,
|
||||
CustomElementDefinition* aDefinition);
|
||||
static void EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
|
||||
Element* aCustomElement,
|
||||
LifecycleCallbackArgs* aArgs,
|
||||
CustomElementDefinition* aDefinition);
|
||||
|
||||
void GetCustomPrototype(nsIAtom* aAtom,
|
||||
JS::MutableHandle<JSObject*> aPrototype);
|
||||
|
|
@ -398,7 +392,7 @@ public:
|
|||
private:
|
||||
~CustomElementRegistry();
|
||||
|
||||
UniquePtr<CustomElementCallback> CreateCustomElementCallback(
|
||||
static UniquePtr<CustomElementCallback> CreateCustomElementCallback(
|
||||
nsIDocument::ElementCallbackType aType, Element* aCustomElement,
|
||||
LifecycleCallbackArgs* aArgs, CustomElementDefinition* aDefinition);
|
||||
|
||||
|
|
|
|||
|
|
@ -1620,14 +1620,11 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
|||
SetSubtreeRootPointer(aParent->SubtreeRoot());
|
||||
}
|
||||
|
||||
nsIDocument* composedDoc = GetComposedDoc();
|
||||
if (composedDoc) {
|
||||
// Attached callback must be enqueued whenever custom element is inserted into a
|
||||
// document and this document has a browsing context.
|
||||
if (GetCustomElementData() && composedDoc->GetDocShell()) {
|
||||
// Enqueue an attached callback for the custom element.
|
||||
nsContentUtils::EnqueueLifecycleCallback(
|
||||
composedDoc, nsIDocument::eAttached, this);
|
||||
if (CustomElementRegistry::IsCustomElementEnabled() && IsInComposedDoc()) {
|
||||
// Connected callback must be enqueued whenever a custom element becomes
|
||||
// connected.
|
||||
if (GetCustomElementData()) {
|
||||
nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eConnected, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1951,12 +1948,12 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
|
|||
|
||||
document->ClearBoxObjectFor(this);
|
||||
|
||||
// Detached must be enqueued whenever custom element is removed from
|
||||
// the document and this document has a browsing context.
|
||||
if (GetCustomElementData() && document->GetDocShell()) {
|
||||
// Enqueue a detached callback for the custom element.
|
||||
nsContentUtils::EnqueueLifecycleCallback(
|
||||
document, nsIDocument::eDetached, this);
|
||||
// Disconnected must be enqueued whenever a connected custom element becomes
|
||||
// disconnected.
|
||||
if (CustomElementRegistry::IsCustomElementEnabled() &&
|
||||
GetCustomElementData()) {
|
||||
nsContentUtils::EnqueueLifecycleCallback(nsIDocument::eDisconnected,
|
||||
this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2625,7 +2622,7 @@ Element::SetAttrAndNotify(int32_t aNamespaceID,
|
|||
}
|
||||
}
|
||||
|
||||
if (nsContentUtils::IsWebComponentsEnabled()) {
|
||||
if (CustomElementRegistry::IsCustomElementEnabled()) {
|
||||
if (CustomElementData* data = GetCustomElementData()) {
|
||||
if (CustomElementDefinition* definition =
|
||||
nsContentUtils::GetElementDefinitionIfObservingAttr(this,
|
||||
|
|
@ -2652,7 +2649,7 @@ Element::SetAttrAndNotify(int32_t aNamespaceID,
|
|||
};
|
||||
|
||||
nsContentUtils::EnqueueLifecycleCallback(
|
||||
OwnerDoc(), nsIDocument::eAttributeChanged, this, &args, definition);
|
||||
nsIDocument::eAttributeChanged, this, &args, definition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2929,7 +2926,7 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
}
|
||||
}
|
||||
|
||||
if (nsContentUtils::IsWebComponentsEnabled()) {
|
||||
if (CustomElementRegistry::IsCustomElementEnabled()) {
|
||||
if (CustomElementData* data = GetCustomElementData()) {
|
||||
if (CustomElementDefinition* definition =
|
||||
nsContentUtils::GetElementDefinitionIfObservingAttr(this,
|
||||
|
|
@ -2947,7 +2944,7 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
};
|
||||
|
||||
nsContentUtils::EnqueueLifecycleCallback(
|
||||
OwnerDoc(), nsIDocument::eAttributeChanged, this, &args, definition);
|
||||
nsIDocument::eAttributeChanged, this, &args, definition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10162,45 +10162,30 @@ nsContentUtils::EnqueueUpgradeReaction(Element* aElement,
|
|||
MOZ_ASSERT(aElement);
|
||||
|
||||
nsIDocument* doc = aElement->OwnerDoc();
|
||||
nsPIDOMWindowInner* window(doc->GetInnerWindow());
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<CustomElementRegistry> registry(window->CustomElements());
|
||||
if (!registry) {
|
||||
// No DocGroup means no custom element reactions stack.
|
||||
if (!doc->GetDocGroup()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CustomElementReactionsStack* stack =
|
||||
doc->GetDocGroup()->CustomElementReactionsStack();
|
||||
stack->EnqueueUpgradeReaction(registry, aElement, aDefinition);
|
||||
stack->EnqueueUpgradeReaction(aElement, aDefinition);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsContentUtils::EnqueueLifecycleCallback(nsIDocument* aDoc,
|
||||
nsIDocument::ElementCallbackType aType,
|
||||
nsContentUtils::EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
|
||||
Element* aCustomElement,
|
||||
LifecycleCallbackArgs* aArgs,
|
||||
CustomElementDefinition* aDefinition)
|
||||
{
|
||||
MOZ_ASSERT(aDoc);
|
||||
|
||||
if (!aDoc->GetDocShell()) {
|
||||
// No DocGroup means no custom element reactions stack.
|
||||
if (!aCustomElement->OwnerDoc()->GetDocGroup()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window(aDoc->GetInnerWindow());
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<CustomElementRegistry> registry(window->CustomElements());
|
||||
if (!registry) {
|
||||
return;
|
||||
}
|
||||
|
||||
registry->EnqueueLifecycleCallback(aType, aCustomElement, aArgs, aDefinition);
|
||||
CustomElementRegistry::EnqueueLifecycleCallback(aType, aCustomElement, aArgs,
|
||||
aDefinition);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
|
|
@ -10444,6 +10429,44 @@ nsContentUtils::AppendNativeAnonymousChildren(
|
|||
}
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
nsContentUtils::GetLoadingPrincipalForXULNode(nsIContent* aLoadingNode,
|
||||
nsIPrincipal** aLoadingPrincipal)
|
||||
{
|
||||
MOZ_ASSERT(aLoadingNode);
|
||||
MOZ_ASSERT(aLoadingPrincipal);
|
||||
|
||||
bool result = false;
|
||||
nsCOMPtr<nsIPrincipal> loadingPrincipal = aLoadingNode->NodePrincipal();
|
||||
nsAutoString loadingStr;
|
||||
aLoadingNode->GetAttr(kNameSpaceID_None, nsGkAtoms::loadingprincipal,
|
||||
loadingStr);
|
||||
if (loadingStr.IsEmpty()) {
|
||||
// Fall back to mContent's principal (SystemPrincipal) if 'loadingprincipal'
|
||||
// isn't specified.
|
||||
loadingPrincipal.forget(aLoadingPrincipal);
|
||||
return result;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> serializedPrincipal;
|
||||
NS_DeserializeObject(NS_ConvertUTF16toUTF8(loadingStr),
|
||||
getter_AddRefs(serializedPrincipal));
|
||||
loadingPrincipal = do_QueryInterface(serializedPrincipal);
|
||||
if (loadingPrincipal) {
|
||||
// We only allow specifying loadingprincipal attribute on a node loaded by
|
||||
// SystemPrincipal.
|
||||
MOZ_ASSERT(nsContentUtils::IsSystemPrincipal(aLoadingNode->NodePrincipal()),
|
||||
"aLoadingNode Should be loaded with SystemPrincipal");
|
||||
|
||||
result = true;
|
||||
} else {
|
||||
// Fallback if the deserialization is failed.
|
||||
loadingPrincipal = aLoadingNode->NodePrincipal();
|
||||
}
|
||||
|
||||
loadingPrincipal.forget(aLoadingPrincipal);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsContentUtils::GetContentPolicyTypeForUIImageLoading(nsIContent* aLoadingNode,
|
||||
|
|
@ -10453,38 +10476,23 @@ nsContentUtils::GetContentPolicyTypeForUIImageLoading(nsIContent* aLoadingNode,
|
|||
{
|
||||
MOZ_ASSERT(aRequestContextID);
|
||||
|
||||
// Use the serialized loadingPrincipal from the image element. Fall back
|
||||
// to mContent's principal (SystemPrincipal) if not available.
|
||||
aContentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE;
|
||||
nsCOMPtr<nsIPrincipal> loadingPrincipal = aLoadingNode->NodePrincipal();
|
||||
nsAutoString imageLoadingPrincipal;
|
||||
aLoadingNode->GetAttr(kNameSpaceID_None, nsGkAtoms::loadingprincipal,
|
||||
imageLoadingPrincipal);
|
||||
if (!imageLoadingPrincipal.IsEmpty()) {
|
||||
nsCOMPtr<nsISupports> serializedPrincipal;
|
||||
NS_DeserializeObject(NS_ConvertUTF16toUTF8(imageLoadingPrincipal),
|
||||
getter_AddRefs(serializedPrincipal));
|
||||
loadingPrincipal = do_QueryInterface(serializedPrincipal);
|
||||
bool result = GetLoadingPrincipalForXULNode(aLoadingNode, aLoadingPrincipal);
|
||||
if (result) {
|
||||
// Set the content policy type to TYPE_INTERNAL_IMAGE_FAVICON for
|
||||
// indicating it's a favicon loading.
|
||||
aContentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON;
|
||||
|
||||
if (loadingPrincipal) {
|
||||
// Set the content policy type to TYPE_INTERNAL_IMAGE_FAVICON for
|
||||
// indicating it's a favicon loading.
|
||||
aContentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON;
|
||||
|
||||
nsAutoString requestContextID;
|
||||
aLoadingNode->GetAttr(kNameSpaceID_None, nsGkAtoms::requestcontextid,
|
||||
requestContextID);
|
||||
nsresult rv;
|
||||
int64_t val = requestContextID.ToInteger64(&rv);
|
||||
*aRequestContextID = NS_SUCCEEDED(rv)
|
||||
? val
|
||||
: 0;
|
||||
} else {
|
||||
// Fallback if the deserialization is failed.
|
||||
loadingPrincipal = aLoadingNode->NodePrincipal();
|
||||
}
|
||||
nsAutoString requestContextID;
|
||||
aLoadingNode->GetAttr(kNameSpaceID_None, nsGkAtoms::requestcontextid,
|
||||
requestContextID);
|
||||
nsresult rv;
|
||||
int64_t val = requestContextID.ToInteger64(&rv);
|
||||
*aRequestContextID = NS_SUCCEEDED(rv)
|
||||
? val
|
||||
: 0;
|
||||
} else {
|
||||
aContentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE;
|
||||
}
|
||||
loadingPrincipal.forget(aLoadingPrincipal);
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
|
|
|
|||
|
|
@ -3005,8 +3005,7 @@ public:
|
|||
static void EnqueueUpgradeReaction(Element* aElement,
|
||||
mozilla::dom::CustomElementDefinition* aDefinition);
|
||||
|
||||
static void EnqueueLifecycleCallback(nsIDocument* aDoc,
|
||||
nsIDocument::ElementCallbackType aType,
|
||||
static void EnqueueLifecycleCallback(nsIDocument::ElementCallbackType aType,
|
||||
Element* aCustomElement,
|
||||
mozilla::dom::LifecycleCallbackArgs* aArgs = nullptr,
|
||||
mozilla::dom::CustomElementDefinition* aDefinition = nullptr);
|
||||
|
|
@ -3038,6 +3037,19 @@ public:
|
|||
nsTArray<nsIContent*>& aKids,
|
||||
uint32_t aFlags);
|
||||
|
||||
/**
|
||||
* Query loadingPrincipal if it is specified as 'loadingprincipal' attribute on
|
||||
* aLoadingNode, otherwise the NodePrincipal of aLoadingNode is returned
|
||||
* (which is System Principal).
|
||||
*
|
||||
* Return true if aLoadingPrincipal has 'loadingprincipal' attributes, and
|
||||
* the value 'loadingprincipal' is also successfully deserialized, otherwise
|
||||
* return false.
|
||||
*/
|
||||
static bool
|
||||
GetLoadingPrincipalForXULNode(nsIContent* aLoadingNode,
|
||||
nsIPrincipal** aLoadingPrincipal);
|
||||
|
||||
/**
|
||||
* Returns the content policy type that should be used for loading images
|
||||
* for displaying in the UI. The sources of such images can be <xul:image>,
|
||||
|
|
|
|||
|
|
@ -361,31 +361,6 @@ static uint32_t gThrottledIdlePeriodLength;
|
|||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
#define FORWARD_TO_OUTER_CHROME(method, args, err_rval) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (IsInnerWindow()) { \
|
||||
nsGlobalWindow *outer = GetOuterWindowInternal(); \
|
||||
if (!AsInner()->HasActiveDocument()) { \
|
||||
NS_WARNING(outer ? \
|
||||
"Inner window does not have active document." : \
|
||||
"No outer window available!"); \
|
||||
return err_rval; \
|
||||
} \
|
||||
return ((nsGlobalChromeWindow *)outer)->method args; \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
#define FORWARD_TO_INNER_CHROME(method, args, err_rval) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (IsOuterWindow()) { \
|
||||
if (!mInnerWindow) { \
|
||||
NS_WARNING("No inner window available!"); \
|
||||
return err_rval; \
|
||||
} \
|
||||
return ((nsGlobalChromeWindow *)nsGlobalWindow::Cast(mInnerWindow))->method args; \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
#define FORWARD_TO_OUTER_MODAL_CONTENT_WINDOW(method, args, err_rval) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (IsInnerWindow()) { \
|
||||
|
|
@ -1753,6 +1728,20 @@ nsGlobalWindow::~nsGlobalWindow()
|
|||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (IsChromeWindow()) {
|
||||
MOZ_ASSERT(mCleanMessageManager,
|
||||
"chrome windows may always disconnect the msg manager");
|
||||
|
||||
DisconnectAndClearGroupMessageManagers();
|
||||
|
||||
if (mChromeFields.mMessageManager) {
|
||||
static_cast<nsFrameMessageManager *>(
|
||||
mChromeFields.mMessageManager.get())->Disconnect();
|
||||
}
|
||||
|
||||
mCleanMessageManager = false;
|
||||
}
|
||||
|
||||
DisconnectEventTargetObjects();
|
||||
|
||||
// We have to check if sWindowsById isn't null because ::Shutdown might have
|
||||
|
|
@ -2040,10 +2029,9 @@ nsGlobalWindow::CleanUp()
|
|||
|
||||
if (mCleanMessageManager) {
|
||||
MOZ_ASSERT(mIsChrome, "only chrome should have msg manager cleaned");
|
||||
nsGlobalChromeWindow *asChrome = static_cast<nsGlobalChromeWindow*>(this);
|
||||
if (asChrome->mMessageManager) {
|
||||
if (mChromeFields.mMessageManager) {
|
||||
static_cast<nsFrameMessageManager*>(
|
||||
asChrome->mMessageManager.get())->Disconnect();
|
||||
mChromeFields.mMessageManager.get())->Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2215,6 +2203,9 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindow)
|
|||
if (aIID.Equals(NS_GET_IID(mozIDOMWindowProxy)) && IsOuterWindow()) {
|
||||
foundInterface = AsOuter();
|
||||
} else
|
||||
if (aIID.Equals(NS_GET_IID(nsIDOMChromeWindow)) && IsChromeWindow()) {
|
||||
foundInterface = static_cast<nsIDOMChromeWindow*>(this);
|
||||
} else
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
|
@ -2355,6 +2346,11 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
|
|||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIntlUtils)
|
||||
|
||||
tmp->TraverseHostObjectURIs(cb);
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeFields.mBrowserDOMWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeFields.mMessageManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeFields.mGroupMessageManagers)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeFields.mOpenerForInitialContentBrowser)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow)
|
||||
|
|
@ -2437,6 +2433,18 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow)
|
|||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIdleRequestExecutor)
|
||||
tmp->DisableIdleCallbackRequests();
|
||||
|
||||
if (tmp->IsChromeWindow()) {
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeFields.mBrowserDOMWindow)
|
||||
if (tmp->mChromeFields.mMessageManager) {
|
||||
static_cast<nsFrameMessageManager*>(
|
||||
tmp->mChromeFields.mMessageManager.get())->Disconnect();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeFields.mMessageManager)
|
||||
}
|
||||
tmp->DisconnectAndClearGroupMessageManagers();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeFields.mGroupMessageManagers)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeFields.mOpenerForInitialContentBrowser)
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
|
|
@ -3125,7 +3133,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
|
|||
newInnerGlobal = newInnerWindow->GetWrapperPreserveColor();
|
||||
} else {
|
||||
if (thisChrome) {
|
||||
newInnerWindow = nsGlobalChromeWindow::Create(this);
|
||||
newInnerWindow = nsGlobalWindow::CreateChrome(this);
|
||||
} else {
|
||||
newInnerWindow = nsGlobalWindow::Create(this);
|
||||
}
|
||||
|
|
@ -7309,12 +7317,11 @@ nsGlobalWindow::SetWidgetFullscreen(FullscreenReason aReason, bool aIsFullscreen
|
|||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
|
||||
if (!NS_WARN_IF(!IsChromeWindow())) {
|
||||
auto chromeWin = static_cast<nsGlobalChromeWindow*>(this);
|
||||
if (!NS_WARN_IF(chromeWin->mFullscreenPresShell)) {
|
||||
if (!NS_WARN_IF(mChromeFields.mFullscreenPresShell)) {
|
||||
if (nsIPresShell* shell = mDocShell->GetPresShell()) {
|
||||
if (nsRefreshDriver* rd = shell->GetRefreshDriver()) {
|
||||
chromeWin->mFullscreenPresShell = do_GetWeakReference(shell);
|
||||
MOZ_ASSERT(chromeWin->mFullscreenPresShell);
|
||||
mChromeFields.mFullscreenPresShell = do_GetWeakReference(shell);
|
||||
MOZ_ASSERT(mChromeFields.mFullscreenPresShell);
|
||||
rd->SetIsResizeSuppressed();
|
||||
rd->Freeze();
|
||||
}
|
||||
|
|
@ -7362,13 +7369,12 @@ nsGlobalWindow::FinishFullscreenChange(bool aIsFullscreen)
|
|||
DispatchCustomEvent(NS_LITERAL_STRING("fullscreen"));
|
||||
|
||||
if (!NS_WARN_IF(!IsChromeWindow())) {
|
||||
auto chromeWin = static_cast<nsGlobalChromeWindow*>(this);
|
||||
if (nsCOMPtr<nsIPresShell> shell =
|
||||
do_QueryReferent(chromeWin->mFullscreenPresShell)) {
|
||||
do_QueryReferent(mChromeFields.mFullscreenPresShell)) {
|
||||
if (nsRefreshDriver* rd = shell->GetRefreshDriver()) {
|
||||
rd->Thaw();
|
||||
}
|
||||
chromeWin->mFullscreenPresShell = nullptr;
|
||||
mChromeFields.mFullscreenPresShell = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -9362,8 +9368,7 @@ nsGlobalWindow::CanClose()
|
|||
|
||||
if (mIsChrome) {
|
||||
nsCOMPtr<nsIBrowserDOMWindow> bwin;
|
||||
nsIDOMChromeWindow* chromeWin = static_cast<nsGlobalChromeWindow*>(this);
|
||||
chromeWin->GetBrowserDOMWindow(getter_AddRefs(bwin));
|
||||
GetBrowserDOMWindow(getter_AddRefs(bwin));
|
||||
|
||||
bool canClose = true;
|
||||
if (bwin && NS_SUCCEEDED(bwin->CanClose(&canClose))) {
|
||||
|
|
@ -14015,44 +14020,13 @@ nsGlobalWindow::DispatchVRDisplayPresentChange(uint32_t aDisplayID)
|
|||
}
|
||||
}
|
||||
|
||||
// nsGlobalChromeWindow implementation
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalChromeWindow)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsGlobalChromeWindow,
|
||||
nsGlobalWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowserDOMWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGroupMessageManagers)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOpenerForInitialContentBrowser)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsGlobalChromeWindow,
|
||||
nsGlobalWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowserDOMWindow)
|
||||
if (tmp->mMessageManager) {
|
||||
static_cast<nsFrameMessageManager*>(
|
||||
tmp->mMessageManager.get())->Disconnect();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager)
|
||||
}
|
||||
tmp->DisconnectAndClearGroupMessageManagers();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGroupMessageManagers)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOpenerForInitialContentBrowser)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
// QueryInterface implementation for nsGlobalChromeWindow
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalChromeWindow)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMChromeWindow)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsGlobalWindow)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsGlobalChromeWindow, nsGlobalWindow)
|
||||
NS_IMPL_RELEASE_INHERITED(nsGlobalChromeWindow, nsGlobalWindow)
|
||||
|
||||
/* static */ already_AddRefed<nsGlobalChromeWindow>
|
||||
nsGlobalChromeWindow::Create(nsGlobalWindow *aOuterWindow)
|
||||
/* static */ already_AddRefed<nsGlobalWindow>
|
||||
nsGlobalWindow::CreateChrome(nsGlobalWindow *aOuterWindow)
|
||||
{
|
||||
RefPtr<nsGlobalChromeWindow> window = new nsGlobalChromeWindow(aOuterWindow);
|
||||
RefPtr<nsGlobalWindow> window = new nsGlobalWindow(aOuterWindow);
|
||||
window->mIsChrome = true;
|
||||
window->mCleanMessageManager = true;
|
||||
|
||||
window->InitWasOffline();
|
||||
return window.forget();
|
||||
}
|
||||
|
|
@ -14102,7 +14076,7 @@ nsGlobalWindow::IsFullyOccluded()
|
|||
void
|
||||
nsGlobalWindow::Maximize()
|
||||
{
|
||||
MOZ_ASSERT(IsInnerWindow());
|
||||
MOZ_RELEASE_ASSERT(IsInnerWindow());
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = GetMainWidget();
|
||||
|
||||
|
|
@ -14114,7 +14088,7 @@ nsGlobalWindow::Maximize()
|
|||
void
|
||||
nsGlobalWindow::Minimize()
|
||||
{
|
||||
MOZ_ASSERT(IsInnerWindow());
|
||||
MOZ_RELEASE_ASSERT(IsInnerWindow());
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = GetMainWidget();
|
||||
|
||||
|
|
@ -14126,7 +14100,7 @@ nsGlobalWindow::Minimize()
|
|||
void
|
||||
nsGlobalWindow::Restore()
|
||||
{
|
||||
MOZ_ASSERT(IsInnerWindow());
|
||||
MOZ_RELEASE_ASSERT(IsInnerWindow());
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = GetMainWidget();
|
||||
|
||||
|
|
@ -14271,9 +14245,10 @@ nsGlobalWindow::SetCursor(const nsAString& aCursor, ErrorResult& aError)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalChromeWindow::GetBrowserDOMWindow(nsIBrowserDOMWindow **aBrowserWindow)
|
||||
nsGlobalWindow::GetBrowserDOMWindow(nsIBrowserDOMWindow **aBrowserWindow)
|
||||
{
|
||||
FORWARD_TO_INNER_CHROME(GetBrowserDOMWindow, (aBrowserWindow), NS_ERROR_UNEXPECTED);
|
||||
MOZ_RELEASE_ASSERT(IsChromeWindow());
|
||||
FORWARD_TO_INNER(GetBrowserDOMWindow, (aBrowserWindow), NS_ERROR_UNEXPECTED);
|
||||
|
||||
ErrorResult rv;
|
||||
NS_IF_ADDREF(*aBrowserWindow = GetBrowserDOMWindow(rv));
|
||||
|
|
@ -14285,7 +14260,7 @@ nsGlobalWindow::GetBrowserDOMWindowOuter()
|
|||
{
|
||||
MOZ_RELEASE_ASSERT(IsOuterWindow());
|
||||
MOZ_ASSERT(IsChromeWindow());
|
||||
return static_cast<nsGlobalChromeWindow*>(this)->mBrowserDOMWindow;
|
||||
return mChromeFields.mBrowserDOMWindow;
|
||||
}
|
||||
|
||||
nsIBrowserDOMWindow*
|
||||
|
|
@ -14299,7 +14274,7 @@ nsGlobalWindow::SetBrowserDOMWindowOuter(nsIBrowserDOMWindow* aBrowserWindow)
|
|||
{
|
||||
MOZ_RELEASE_ASSERT(IsOuterWindow());
|
||||
MOZ_ASSERT(IsChromeWindow());
|
||||
static_cast<nsGlobalChromeWindow*>(this)->mBrowserDOMWindow = aBrowserWindow;
|
||||
mChromeFields.mBrowserDOMWindow = aBrowserWindow;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -14359,9 +14334,9 @@ nsGlobalWindow::NotifyDefaultButtonLoaded(Element& aDefaultButton,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalChromeWindow::GetMessageManager(nsIMessageBroadcaster** aManager)
|
||||
nsGlobalWindow::GetMessageManager(nsIMessageBroadcaster** aManager)
|
||||
{
|
||||
FORWARD_TO_INNER_CHROME(GetMessageManager, (aManager), NS_ERROR_UNEXPECTED);
|
||||
FORWARD_TO_INNER(GetMessageManager, (aManager), NS_ERROR_UNEXPECTED);
|
||||
|
||||
ErrorResult rv;
|
||||
NS_IF_ADDREF(*aManager = GetMessageManager(rv));
|
||||
|
|
@ -14373,23 +14348,23 @@ nsGlobalWindow::GetMessageManager(ErrorResult& aError)
|
|||
{
|
||||
MOZ_ASSERT(IsChromeWindow());
|
||||
MOZ_RELEASE_ASSERT(IsInnerWindow());
|
||||
nsGlobalChromeWindow* myself = static_cast<nsGlobalChromeWindow*>(this);
|
||||
if (!myself->mMessageManager) {
|
||||
if (!mChromeFields.mMessageManager) {
|
||||
nsCOMPtr<nsIMessageBroadcaster> globalMM =
|
||||
do_GetService("@mozilla.org/globalmessagemanager;1");
|
||||
myself->mMessageManager =
|
||||
mChromeFields.mMessageManager =
|
||||
new nsFrameMessageManager(nullptr,
|
||||
static_cast<nsFrameMessageManager*>(globalMM.get()),
|
||||
MM_CHROME | MM_BROADCASTER);
|
||||
}
|
||||
return myself->mMessageManager;
|
||||
return mChromeFields.mMessageManager;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalChromeWindow::GetGroupMessageManager(const nsAString& aGroup,
|
||||
nsIMessageBroadcaster** aManager)
|
||||
nsGlobalWindow::GetGroupMessageManager(const nsAString& aGroup,
|
||||
nsIMessageBroadcaster** aManager)
|
||||
{
|
||||
FORWARD_TO_INNER_CHROME(GetGroupMessageManager, (aGroup, aManager), NS_ERROR_UNEXPECTED);
|
||||
MOZ_RELEASE_ASSERT(IsChromeWindow());
|
||||
FORWARD_TO_INNER(GetGroupMessageManager, (aGroup, aManager), NS_ERROR_UNEXPECTED);
|
||||
|
||||
ErrorResult rv;
|
||||
NS_IF_ADDREF(*aManager = GetGroupMessageManager(aGroup, rv));
|
||||
|
|
@ -14403,9 +14378,8 @@ nsGlobalWindow::GetGroupMessageManager(const nsAString& aGroup,
|
|||
MOZ_ASSERT(IsChromeWindow());
|
||||
MOZ_RELEASE_ASSERT(IsInnerWindow());
|
||||
|
||||
nsGlobalChromeWindow* myself = static_cast<nsGlobalChromeWindow*>(this);
|
||||
nsCOMPtr<nsIMessageBroadcaster> messageManager =
|
||||
myself->mGroupMessageManagers.LookupForAdd(aGroup).OrInsert(
|
||||
mChromeFields.mGroupMessageManagers.LookupForAdd(aGroup).OrInsert(
|
||||
[this, &aError] () {
|
||||
nsFrameMessageManager* parent =
|
||||
static_cast<nsFrameMessageManager*>(GetMessageManager(aError));
|
||||
|
|
@ -14418,20 +14392,22 @@ nsGlobalWindow::GetGroupMessageManager(const nsAString& aGroup,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsGlobalChromeWindow::SetOpenerForInitialContentBrowser(mozIDOMWindowProxy* aOpenerWindow)
|
||||
nsGlobalWindow::SetOpenerForInitialContentBrowser(mozIDOMWindowProxy* aOpenerWindow)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(IsChromeWindow());
|
||||
MOZ_RELEASE_ASSERT(IsOuterWindow());
|
||||
MOZ_ASSERT(!mOpenerForInitialContentBrowser);
|
||||
mOpenerForInitialContentBrowser = aOpenerWindow;
|
||||
MOZ_ASSERT(!mChromeFields.mOpenerForInitialContentBrowser);
|
||||
mChromeFields.mOpenerForInitialContentBrowser = aOpenerWindow;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGlobalChromeWindow::TakeOpenerForInitialContentBrowser(mozIDOMWindowProxy** aOpenerWindow)
|
||||
nsGlobalWindow::TakeOpenerForInitialContentBrowser(mozIDOMWindowProxy** aOpenerWindow)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(IsChromeWindow());
|
||||
MOZ_RELEASE_ASSERT(IsOuterWindow());
|
||||
// Intentionally forget our own member
|
||||
mOpenerForInitialContentBrowser.forget(aOpenerWindow);
|
||||
mChromeFields.mOpenerForInitialContentBrowser.forget(aOpenerWindow);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -260,6 +260,9 @@ private:
|
|||
class nsGlobalWindow : public mozilla::dom::EventTarget,
|
||||
public nsPIDOMWindow<nsISupports>,
|
||||
private nsIDOMWindow,
|
||||
// NOTE: This interface is private, as it's only
|
||||
// implemented on chrome windows.
|
||||
private nsIDOMChromeWindow,
|
||||
public nsIScriptGlobalObject,
|
||||
public nsIScriptObjectPrincipal,
|
||||
public nsSupportsWeakReference,
|
||||
|
|
@ -342,6 +345,9 @@ public:
|
|||
// nsIDOMWindow
|
||||
NS_DECL_NSIDOMWINDOW
|
||||
|
||||
// nsIDOMChromeWindow (only implemented on chrome windows)
|
||||
NS_DECL_NSIDOMCHROMEWINDOW
|
||||
|
||||
nsresult
|
||||
OpenJS(const nsAString& aUrl, const nsAString& aName,
|
||||
const nsAString& aOptions, nsPIDOMWindowOuter **_retval);
|
||||
|
|
@ -486,6 +492,7 @@ public:
|
|||
|
||||
// Object Management
|
||||
static already_AddRefed<nsGlobalWindow> Create(nsGlobalWindow *aOuterWindow);
|
||||
static already_AddRefed<nsGlobalWindow> CreateChrome(nsGlobalWindow *aOuterWindow);
|
||||
|
||||
static nsGlobalWindow *FromSupports(nsISupports *supports)
|
||||
{
|
||||
|
|
@ -1251,7 +1258,7 @@ public:
|
|||
|
||||
|
||||
// ChromeWindow bits. Do NOT call these unless your window is in
|
||||
// fact an nsGlobalChromeWindow.
|
||||
// fact chrome.
|
||||
uint16_t WindowState();
|
||||
bool IsFullyOccluded();
|
||||
nsIBrowserDOMWindow* GetBrowserDOMWindowOuter();
|
||||
|
|
@ -1783,6 +1790,19 @@ private:
|
|||
|
||||
void SetIsBackgroundInternal(bool aIsBackground);
|
||||
|
||||
// NOTE: Chrome Only
|
||||
void DisconnectAndClearGroupMessageManagers()
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(IsChromeWindow());
|
||||
for (auto iter = mChromeFields.mGroupMessageManagers.Iter(); !iter.Done(); iter.Next()) {
|
||||
nsIMessageBroadcaster* mm = iter.UserData();
|
||||
if (mm) {
|
||||
static_cast<nsFrameMessageManager*>(mm)->Disconnect();
|
||||
}
|
||||
}
|
||||
mChromeFields.mGroupMessageManagers.Clear();
|
||||
}
|
||||
|
||||
public:
|
||||
// Dispatch a runnable related to the global.
|
||||
virtual nsresult Dispatch(mozilla::TaskCategory aCategory,
|
||||
|
|
@ -2025,6 +2045,23 @@ protected:
|
|||
|
||||
RefPtr<mozilla::dom::IntlUtils> mIntlUtils;
|
||||
|
||||
// Members in the mChromeFields member should only be used in chrome windows.
|
||||
// All accesses to this field should be guarded by a check of mIsChrome.
|
||||
struct ChromeFields {
|
||||
ChromeFields()
|
||||
: mGroupMessageManagers(1)
|
||||
{}
|
||||
|
||||
nsCOMPtr<nsIBrowserDOMWindow> mBrowserDOMWindow;
|
||||
nsCOMPtr<nsIMessageBroadcaster> mMessageManager;
|
||||
nsInterfaceHashtable<nsStringHashKey, nsIMessageBroadcaster> mGroupMessageManagers;
|
||||
// A weak pointer to the nsPresShell that we are doing fullscreen for.
|
||||
// The pointer being set indicates we've set the IsInFullscreenChange
|
||||
// flag on this pres shell.
|
||||
nsWeakPtr mFullscreenPresShell;
|
||||
nsCOMPtr<mozIDOMWindowProxy> mOpenerForInitialContentBrowser;
|
||||
} mChromeFields;
|
||||
|
||||
friend class nsDOMScriptableHelper;
|
||||
friend class nsDOMWindowUtils;
|
||||
friend class mozilla::dom::PostMessageEvent;
|
||||
|
|
@ -2047,84 +2084,6 @@ ToCanonicalSupports(nsGlobalWindow *p)
|
|||
return static_cast<nsIDOMEventTarget*>(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* nsGlobalChromeWindow inherits from nsGlobalWindow. It is the global
|
||||
* object created for a Chrome Window only.
|
||||
*/
|
||||
class nsGlobalChromeWindow : public nsGlobalWindow,
|
||||
public nsIDOMChromeWindow
|
||||
{
|
||||
public:
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIDOMChromeWindow interface
|
||||
NS_DECL_NSIDOMCHROMEWINDOW
|
||||
|
||||
static already_AddRefed<nsGlobalChromeWindow> Create(nsGlobalWindow *aOuterWindow);
|
||||
|
||||
void DisconnectAndClearGroupMessageManagers()
|
||||
{
|
||||
for (auto iter = mGroupMessageManagers.Iter(); !iter.Done(); iter.Next()) {
|
||||
nsIMessageBroadcaster* mm = iter.UserData();
|
||||
if (mm) {
|
||||
static_cast<nsFrameMessageManager*>(mm)->Disconnect();
|
||||
}
|
||||
}
|
||||
mGroupMessageManagers.Clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit nsGlobalChromeWindow(nsGlobalWindow *aOuterWindow)
|
||||
: nsGlobalWindow(aOuterWindow),
|
||||
mGroupMessageManagers(1)
|
||||
{
|
||||
mIsChrome = true;
|
||||
mCleanMessageManager = true;
|
||||
}
|
||||
|
||||
~nsGlobalChromeWindow()
|
||||
{
|
||||
MOZ_ASSERT(mCleanMessageManager,
|
||||
"chrome windows may always disconnect the msg manager");
|
||||
|
||||
DisconnectAndClearGroupMessageManagers();
|
||||
|
||||
if (mMessageManager) {
|
||||
static_cast<nsFrameMessageManager *>(
|
||||
mMessageManager.get())->Disconnect();
|
||||
}
|
||||
|
||||
mCleanMessageManager = false;
|
||||
}
|
||||
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsGlobalChromeWindow,
|
||||
nsGlobalWindow)
|
||||
|
||||
using nsGlobalWindow::GetBrowserDOMWindow;
|
||||
using nsGlobalWindow::SetBrowserDOMWindow;
|
||||
using nsGlobalWindow::GetAttention;
|
||||
using nsGlobalWindow::GetAttentionWithCycleCount;
|
||||
using nsGlobalWindow::SetCursor;
|
||||
using nsGlobalWindow::Maximize;
|
||||
using nsGlobalWindow::Minimize;
|
||||
using nsGlobalWindow::Restore;
|
||||
using nsGlobalWindow::NotifyDefaultButtonLoaded;
|
||||
using nsGlobalWindow::GetMessageManager;
|
||||
using nsGlobalWindow::GetGroupMessageManager;
|
||||
using nsGlobalWindow::BeginWindowMove;
|
||||
|
||||
nsCOMPtr<nsIBrowserDOMWindow> mBrowserDOMWindow;
|
||||
nsCOMPtr<nsIMessageBroadcaster> mMessageManager;
|
||||
nsInterfaceHashtable<nsStringHashKey, nsIMessageBroadcaster> mGroupMessageManagers;
|
||||
// A weak pointer to the nsPresShell that we are doing fullscreen for.
|
||||
// The pointer being set indicates we've set the IsInFullscreenChange
|
||||
// flag on this pres shell.
|
||||
nsWeakPtr mFullscreenPresShell;
|
||||
nsCOMPtr<mozIDOMWindowProxy> mOpenerForInitialContentBrowser;
|
||||
};
|
||||
|
||||
/* factory function */
|
||||
inline already_AddRefed<nsGlobalWindow>
|
||||
NS_NewScriptGlobalObject(bool aIsChrome)
|
||||
|
|
@ -2132,7 +2091,7 @@ NS_NewScriptGlobalObject(bool aIsChrome)
|
|||
RefPtr<nsGlobalWindow> global;
|
||||
|
||||
if (aIsChrome) {
|
||||
global = nsGlobalChromeWindow::Create(nullptr);
|
||||
global = nsGlobalWindow::CreateChrome(nullptr);
|
||||
} else {
|
||||
global = nsGlobalWindow::Create(nullptr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2742,8 +2742,8 @@ public:
|
|||
|
||||
enum ElementCallbackType {
|
||||
eCreated,
|
||||
eAttached,
|
||||
eDetached,
|
||||
eConnected,
|
||||
eDisconnected,
|
||||
eAttributeChanged
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1018,8 +1018,6 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
|||
"Principal mismatch?");
|
||||
#endif
|
||||
|
||||
nsContentPolicyType policyType = PolicyTypeForLoad(aImageLoadType);
|
||||
|
||||
nsLoadFlags loadFlags = aLoadFlags;
|
||||
int32_t corsmode = GetCORSMode();
|
||||
if (corsmode == CORS_ANONYMOUS) {
|
||||
|
|
@ -1040,12 +1038,24 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
|||
RefPtr<imgRequestProxy>& req = PrepareNextRequest(aImageLoadType);
|
||||
nsCOMPtr<nsIContent> content =
|
||||
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
|
||||
nsCOMPtr<nsIPrincipal> loadingPrincipal;
|
||||
bool result =
|
||||
nsContentUtils::GetLoadingPrincipalForXULNode(content,
|
||||
getter_AddRefs(loadingPrincipal));
|
||||
|
||||
// If result is true, which means this node has specified 'loadingprincipal'
|
||||
// attribute on it, so we use favicon as the policy type.
|
||||
nsContentPolicyType policyType = result ?
|
||||
nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON:
|
||||
PolicyTypeForLoad(aImageLoadType);
|
||||
|
||||
nsCOMPtr<nsINode> thisNode =
|
||||
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
nsresult rv = nsContentUtils::LoadImage(aNewURI,
|
||||
thisNode,
|
||||
aDocument,
|
||||
aDocument->NodePrincipal(),
|
||||
loadingPrincipal,
|
||||
0,
|
||||
aDocument->GetDocumentURI(),
|
||||
referrerPolicy,
|
||||
|
|
|
|||
|
|
@ -2732,8 +2732,7 @@ class AttrDefiner(PropertyDefiner):
|
|||
|
||||
def flags(attr):
|
||||
unforgeable = " | JSPROP_PERMANENT" if self.unforgeable else ""
|
||||
enumerable = " | %s" % EnumerabilityFlags(attr)
|
||||
return ("JSPROP_SHARED" + enumerable + unforgeable)
|
||||
return EnumerabilityFlags(attr) + unforgeable
|
||||
|
||||
def getter(attr):
|
||||
if self.static:
|
||||
|
|
|
|||
|
|
@ -2399,7 +2399,6 @@ WebGLContext::StartVRPresentation()
|
|||
gl::GLScreenBuffer::CreateFactory(gl,
|
||||
caps,
|
||||
vrmc,
|
||||
vrmc->GetBackendType(),
|
||||
TextureFlags::ORIGIN_BOTTOM_LEFT);
|
||||
|
||||
if (factory) {
|
||||
|
|
|
|||
|
|
@ -1660,7 +1660,7 @@ Console::PopulateConsoleNotificationInTheTargetScope(JSContext* aCx,
|
|||
if (NS_WARN_IF(!JS_DefineProperty(aCx, eventObj, "stacktrace",
|
||||
JS_DATA_TO_FUNC_PTR(JSNative, funObj.get()),
|
||||
nullptr,
|
||||
JSPROP_ENUMERATE | JSPROP_SHARED |
|
||||
JSPROP_ENUMERATE |
|
||||
JSPROP_GETTER | JSPROP_SETTER))) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "mozilla/EventListenerManager.h"
|
||||
#include "mozilla/JSEventHandler.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "nsIXPConnect.h"
|
||||
|
|
@ -54,10 +55,28 @@ EventListenerChange::GetTarget(nsIDOMEventTarget** aTarget)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
EventListenerChange::GetChangedListenerNames(nsIArray** aEventNames)
|
||||
EventListenerChange::GetCountOfEventListenerChangesAffectingAccessibility(
|
||||
uint32_t* aCount)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEventNames);
|
||||
NS_ADDREF(*aEventNames = mChangedListenerNames);
|
||||
*aCount = 0;
|
||||
|
||||
uint32_t length;
|
||||
nsresult rv = mChangedListenerNames->GetLength(&length);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
nsCOMPtr<nsIAtom> listenerName =
|
||||
do_QueryElementAt(mChangedListenerNames, i);
|
||||
|
||||
// These are the event listener changes which may make an element
|
||||
// accessible or inaccessible.
|
||||
if (listenerName == nsGkAtoms::onclick ||
|
||||
listenerName == nsGkAtoms::onmousedown ||
|
||||
listenerName == nsGkAtoms::onmouseup) {
|
||||
*aCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,14 +10,16 @@ interface nsIDOMEventTarget;
|
|||
interface nsIArray;
|
||||
|
||||
/**
|
||||
* Contains an event target along with an array of nsIAtom in form "oneventname"
|
||||
* representing changed event listener names.
|
||||
* Contains an event target along with a count of event listener changes
|
||||
* affecting accessibility.
|
||||
*/
|
||||
[scriptable, uuid(07222b02-da12-4cf4-b2f7-761da007a8d8)]
|
||||
interface nsIEventListenerChange : nsISupports
|
||||
{
|
||||
readonly attribute nsIDOMEventTarget target;
|
||||
[noscript] readonly attribute nsIArray changedListenerNames;
|
||||
|
||||
[noscript]
|
||||
readonly attribute uint32_t countOfEventListenerChangesAffectingAccessibility;
|
||||
};
|
||||
|
||||
[scriptable, function, uuid(aa7c95f6-d3b5-44b3-9597-1d9f19b9c5f2)]
|
||||
|
|
|
|||
|
|
@ -472,7 +472,7 @@ FetchBodyConsumer<Derived>::BeginConsumeBodyMainThread()
|
|||
|
||||
nsCOMPtr<nsIInputStreamPump> pump;
|
||||
nsresult rv = NS_NewInputStreamPump(getter_AddRefs(pump),
|
||||
mBodyStream, -1, -1, 0, 0, false,
|
||||
mBodyStream, 0, 0, false,
|
||||
mMainThreadEventTarget);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -224,8 +224,6 @@ FetchStream::RequestDataCallback(JSContext* aCx,
|
|||
|
||||
nsCOMPtr<nsITransport> transport;
|
||||
rv = sts->CreateInputTransport(stream->mOriginalInputStream,
|
||||
/* aStartOffset */ 0,
|
||||
/* aReadLimit */ -1,
|
||||
/* aCloseWhenDone */ true,
|
||||
getter_AddRefs(transport));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
|
|
|
|||
|
|
@ -400,8 +400,6 @@ FileReader::ReadFileContent(Blob& aBlob,
|
|||
|
||||
nsCOMPtr<nsITransport> transport;
|
||||
aRv = sts->CreateInputTransport(stream,
|
||||
/* aStartOffset */ 0,
|
||||
/* aReadLimit */ -1,
|
||||
/* aCloseWhenDone */ true,
|
||||
getter_AddRefs(transport));
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
|
|
|
|||
|
|
@ -651,8 +651,6 @@ IPCBlobInputStream::EnsureAsyncRemoteStream()
|
|||
|
||||
nsCOMPtr<nsITransport> transport;
|
||||
rv = sts->CreateInputTransport(mRemoteStream,
|
||||
/* aStartOffset */ 0,
|
||||
/* aReadLimit */ -1,
|
||||
/* aCloseWhenDone */ true,
|
||||
getter_AddRefs(transport));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
|
|
|
|||
|
|
@ -1191,19 +1191,31 @@ public:
|
|||
? nsIContentPolicy::TYPE_INTERNAL_AUDIO :
|
||||
nsIContentPolicy::TYPE_INTERNAL_VIDEO;
|
||||
|
||||
// If aElement has 'loadingprincipal' attribute, we will use the value as
|
||||
// loadingPrincipal for the channel, otherwise it will default to use
|
||||
// aElement->NodePrincipal().
|
||||
// This function returns true when aElement has 'loadingprincipal', so if
|
||||
// setAttrs is true we will override the origin attributes on the channel
|
||||
// later.
|
||||
nsCOMPtr<nsIPrincipal> loadingPrincipal;
|
||||
bool setAttrs = nsContentUtils::GetLoadingPrincipalForXULNode(aElement,
|
||||
getter_AddRefs(loadingPrincipal));
|
||||
|
||||
nsCOMPtr<nsILoadGroup> loadGroup = aElement->GetDocumentLoadGroup();
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
nsresult rv = NS_NewChannel(getter_AddRefs(channel),
|
||||
aElement->mLoadingSrc,
|
||||
static_cast<Element*>(aElement),
|
||||
securityFlags,
|
||||
contentPolicyType,
|
||||
loadGroup,
|
||||
nullptr, // aCallbacks
|
||||
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY |
|
||||
nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE |
|
||||
nsIChannel::LOAD_CLASSIFY_URI |
|
||||
nsIChannel::LOAD_CALL_CONTENT_SNIFFERS);
|
||||
nsresult rv =
|
||||
NS_NewChannelWithTriggeringPrincipal(getter_AddRefs(channel),
|
||||
aElement->mLoadingSrc,
|
||||
static_cast<Element*>(aElement),
|
||||
loadingPrincipal,
|
||||
securityFlags,
|
||||
contentPolicyType,
|
||||
loadGroup,
|
||||
nullptr, // aCallbacks
|
||||
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY |
|
||||
nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE |
|
||||
nsIChannel::LOAD_CLASSIFY_URI |
|
||||
nsIChannel::LOAD_CALL_CONTENT_SNIFFERS);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
// Notify load error so the element will try next resource candidate.
|
||||
|
|
@ -1211,6 +1223,14 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
if (setAttrs) {
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
|
||||
if (loadInfo) {
|
||||
// The function simply returns NS_OK, so we ignore the return value.
|
||||
Unused << loadInfo->SetOriginAttributes(loadingPrincipal->OriginAttributesRef());
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(channel));
|
||||
if (cos) {
|
||||
if (aElement->mUseUrgentStartForChannel) {
|
||||
|
|
|
|||
|
|
@ -317,7 +317,7 @@ nsGenericHTMLElement::GetOffsetRect(CSSIntRect& aRect)
|
|||
// Add the parent's origin to our own to get to the
|
||||
// right coordinate system.
|
||||
const bool isOffsetParent = !isPositioned && IsOffsetParent(parent);
|
||||
if (!isAbsolutelyPositioned && !isOffsetParent) {
|
||||
if (!isOffsetParent) {
|
||||
origin += parent->GetPositionIgnoringScrolling();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -88,8 +88,10 @@
|
|||
#include "nsIXULRuntime.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsPIWindowRoot.h"
|
||||
#include "nsPointerHashKeys.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsTHashtable.h"
|
||||
#include "nsThreadManager.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsViewManager.h"
|
||||
|
|
@ -164,7 +166,7 @@ NS_IMPL_ISUPPORTS(TabChildSHistoryListener,
|
|||
|
||||
static const char BEFORE_FIRST_PAINT[] = "before-first-paint";
|
||||
|
||||
nsTArray<TabChild*>* TabChild::sActiveTabs;
|
||||
nsTHashtable<nsPtrHashKey<TabChild>>* TabChild::sActiveTabs;
|
||||
|
||||
typedef nsDataHashtable<nsUint64HashKey, TabChild*> TabChildMap;
|
||||
static TabChildMap* sTabChildren;
|
||||
|
|
@ -1120,7 +1122,7 @@ TabChild::ActorDestroy(ActorDestroyReason why)
|
|||
TabChild::~TabChild()
|
||||
{
|
||||
if (sActiveTabs) {
|
||||
sActiveTabs->RemoveElement(this);
|
||||
sActiveTabs->RemoveEntry(this);
|
||||
if (sActiveTabs->IsEmpty()) {
|
||||
delete sActiveTabs;
|
||||
sActiveTabs = nullptr;
|
||||
|
|
@ -2589,12 +2591,12 @@ TabChild::InternalSetDocShellIsActive(bool aIsActive, bool aPreserveLayers)
|
|||
|
||||
if (aIsActive) {
|
||||
if (!sActiveTabs) {
|
||||
sActiveTabs = new nsTArray<TabChild*>();
|
||||
sActiveTabs = new nsTHashtable<nsPtrHashKey<TabChild>>();
|
||||
}
|
||||
sActiveTabs->AppendElement(this);
|
||||
sActiveTabs->PutEntry(this);
|
||||
} else {
|
||||
if (sActiveTabs) {
|
||||
sActiveTabs->RemoveElement(this);
|
||||
sActiveTabs->RemoveEntry(this);
|
||||
// We don't delete sActiveTabs here when it's empty since that
|
||||
// could cause a lot of churn. Instead, we wait until ~TabChild.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,9 @@ class nsIDOMWindowUtils;
|
|||
class nsIHttpChannel;
|
||||
class nsISerialEventTarget;
|
||||
|
||||
template<typename T> class nsTHashtable;
|
||||
template<typename T> class nsPtrHashKey;
|
||||
|
||||
namespace mozilla {
|
||||
class AbstractThread;
|
||||
namespace layout {
|
||||
|
|
@ -762,7 +765,7 @@ public:
|
|||
// open. There can also be zero foreground TabChilds if the foreground tab is
|
||||
// in a different content process. Note that this function should only be
|
||||
// called if HasActiveTabs() returns true.
|
||||
static const nsTArray<TabChild*>& GetActiveTabs()
|
||||
static const nsTHashtable<nsPtrHashKey<TabChild>>& GetActiveTabs()
|
||||
{
|
||||
MOZ_ASSERT(HasActiveTabs());
|
||||
return *sActiveTabs;
|
||||
|
|
@ -964,7 +967,7 @@ private:
|
|||
// the foreground). There may be more than one if there are multiple browser
|
||||
// windows open. There may be none if this process does not host any
|
||||
// foreground tabs.
|
||||
static nsTArray<TabChild*>* sActiveTabs;
|
||||
static nsTHashtable<nsPtrHashKey<TabChild>>* sActiveTabs;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -750,16 +750,36 @@ ChannelMediaResource::RecreateChannel()
|
|||
nsContentPolicyType contentPolicyType = element->IsHTMLElement(nsGkAtoms::audio) ?
|
||||
nsIContentPolicy::TYPE_INTERNAL_AUDIO : nsIContentPolicy::TYPE_INTERNAL_VIDEO;
|
||||
|
||||
nsresult rv = NS_NewChannel(getter_AddRefs(mChannel),
|
||||
mURI,
|
||||
element,
|
||||
securityFlags,
|
||||
contentPolicyType,
|
||||
loadGroup,
|
||||
nullptr, // aCallbacks
|
||||
loadFlags);
|
||||
// If element has 'loadingprincipal' attribute, we will use the value as
|
||||
// loadingPrincipal for the channel, otherwise it will default to use
|
||||
// aElement->NodePrincipal().
|
||||
// This function returns true when element has 'loadingprincipal', so if
|
||||
// setAttrs is true we will override the origin attributes on the channel
|
||||
// later.
|
||||
nsCOMPtr<nsIPrincipal> loadingPrincipal;
|
||||
bool setAttrs =
|
||||
nsContentUtils::GetLoadingPrincipalForXULNode(element,
|
||||
getter_AddRefs(loadingPrincipal));
|
||||
|
||||
nsresult rv = NS_NewChannelWithTriggeringPrincipal(getter_AddRefs(mChannel),
|
||||
mURI,
|
||||
element,
|
||||
loadingPrincipal,
|
||||
securityFlags,
|
||||
contentPolicyType,
|
||||
loadGroup,
|
||||
nullptr, // aCallbacks
|
||||
loadFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (setAttrs) {
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
|
||||
if (loadInfo) {
|
||||
// The function simply returns NS_OK, so we ignore the return value.
|
||||
Unused << loadInfo->SetOriginAttributes(loadingPrincipal->OriginAttributesRef());
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(mChannel));
|
||||
if (cos) {
|
||||
// Unconditionally disable throttling since we want the media to fluently
|
||||
|
|
|
|||
|
|
@ -991,7 +991,7 @@ TCPSocket::CreateInputStreamPump()
|
|||
mInputStreamPump = do_CreateInstance("@mozilla.org/network/input-stream-pump;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mInputStreamPump->Init(mSocketInputStream, -1, -1, 0, 0, false, nullptr);
|
||||
rv = mInputStreamPump->Init(mSocketInputStream, 0, 0, false, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
uint64_t suspendCount = mSuspendCount;
|
||||
|
|
|
|||
|
|
@ -282,7 +282,7 @@ PresentationTCPSessionTransport::CreateInputStreamPump()
|
|||
return rv;
|
||||
}
|
||||
|
||||
rv = mInputStreamPump->Init(mSocketInputStream, -1, -1, 0, 0, false, nullptr);
|
||||
rv = mInputStreamPump->Init(mSocketInputStream, 0, 0, false, nullptr);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -663,7 +663,7 @@ TCPControlChannel.prototype = {
|
|||
this._direction); // jshint ignore:line
|
||||
this._pump = Cc["@mozilla.org/network/input-stream-pump;1"].
|
||||
createInstance(Ci.nsIInputStreamPump);
|
||||
this._pump.init(this._input, -1, -1, 0, 0, false);
|
||||
this._pump.init(this._input, 0, 0, false);
|
||||
this._pump.asyncRead(this, null);
|
||||
this._stateMachine.onChannelReady();
|
||||
},
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ function getInLAProc(aBrowser) {
|
|||
|
||||
async function largeAllocSuccessTests() {
|
||||
// I'm terrible and put this set of tests into a single file, so I need a longer timeout
|
||||
requestLongerTimeout(2);
|
||||
requestLongerTimeout(4);
|
||||
|
||||
// Check if we are on win32
|
||||
let isWin32 = /Windows/.test(navigator.userAgent) && !/x64/.test(navigator.userAgent);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1102502
|
|||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var attachedCallbackCount = 0;
|
||||
var connectedCallbackCount = 0;
|
||||
|
||||
var p = Object.create(HTMLElement.prototype);
|
||||
|
||||
|
|
@ -24,12 +24,12 @@ p.createdCallback = function() {
|
|||
ok(true, "createdCallback called.");
|
||||
};
|
||||
|
||||
p.attachedCallback = function() {
|
||||
ok(true, "attachedCallback should be called when the parser creates an element in the document.");
|
||||
attachedCallbackCount++;
|
||||
// attachedCallback should be called twice, once for the element created for innerHTML and
|
||||
p.connectedCallback = function() {
|
||||
ok(true, "connectedCallback should be called when the parser creates an element in the document.");
|
||||
connectedCallbackCount++;
|
||||
// connectedCallback should be called twice, once for the element created for innerHTML and
|
||||
// once for the element created in this document.
|
||||
if (attachedCallbackCount == 2) {
|
||||
if (connectedCallbackCount == 2) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@
|
|||
*/
|
||||
|
||||
callback LifecycleCreatedCallback = void();
|
||||
callback LifecycleAttachedCallback = void();
|
||||
callback LifecycleDetachedCallback = void();
|
||||
callback LifecycleConnectedCallback = void();
|
||||
callback LifecycleDisconnectedCallback = void();
|
||||
callback LifecycleAttributeChangedCallback = void(DOMString attrName,
|
||||
DOMString? oldValue,
|
||||
DOMString? newValue,
|
||||
|
|
@ -20,8 +20,8 @@ callback LifecycleAttributeChangedCallback = void(DOMString attrName,
|
|||
|
||||
dictionary LifecycleCallbacks {
|
||||
LifecycleCreatedCallback? createdCallback;
|
||||
LifecycleAttachedCallback? attachedCallback;
|
||||
LifecycleDetachedCallback? detachedCallback;
|
||||
LifecycleConnectedCallback? connectedCallback;
|
||||
LifecycleDisconnectedCallback? disconnectedCallback;
|
||||
LifecycleAttributeChangedCallback? attributeChangedCallback;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1725,8 +1725,6 @@ CacheScriptLoader::ResolvedCallback(JSContext* aCx,
|
|||
MOZ_ASSERT(!mPump);
|
||||
rv = NS_NewInputStreamPump(getter_AddRefs(mPump),
|
||||
inputStream,
|
||||
-1, /* default streamPos */
|
||||
-1, /* default streamLen */
|
||||
0, /* default segsize */
|
||||
0, /* default segcount */
|
||||
false, /* default closeWhenDone */
|
||||
|
|
|
|||
|
|
@ -1159,8 +1159,6 @@ CompareCache::ManageValueResult(JSContext* aCx, JS::Handle<JS::Value> aValue)
|
|||
MOZ_ASSERT(!mPump);
|
||||
rv = NS_NewInputStreamPump(getter_AddRefs(mPump),
|
||||
inputStream,
|
||||
-1, /* default streamPos */
|
||||
-1, /* default streamLen */
|
||||
0, /* default segsize */
|
||||
0, /* default segcount */
|
||||
false, /* default closeWhenDone */
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ public:
|
|||
const char16_t* GetName() const { return mName; }
|
||||
|
||||
unsigned AccessorAttributes() const {
|
||||
return JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER |
|
||||
return JSPROP_GETTER | JSPROP_SETTER |
|
||||
(mJSAttributes & (JSPROP_ENUMERATE | JSPROP_PERMANENT));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ nsXBLProtoImplProperty::CompileMember(AutoJSAPI& jsapi, const nsString& aClassSt
|
|||
mGetter.SetJSFunction(getterObject);
|
||||
|
||||
if (mGetter.GetJSFunction() && NS_SUCCEEDED(rv)) {
|
||||
mJSAttributes |= JSPROP_GETTER | JSPROP_SHARED;
|
||||
mJSAttributes |= JSPROP_GETTER;
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
mGetter.SetJSFunction(nullptr);
|
||||
|
|
@ -259,7 +259,7 @@ nsXBLProtoImplProperty::CompileMember(AutoJSAPI& jsapi, const nsString& aClassSt
|
|||
mSetter.SetJSFunction(setterObject);
|
||||
|
||||
if (mSetter.GetJSFunction() && NS_SUCCEEDED(rv)) {
|
||||
mJSAttributes |= JSPROP_SETTER | JSPROP_SHARED;
|
||||
mJSAttributes |= JSPROP_SETTER;
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
mSetter.SetJSFunction(nullptr);
|
||||
|
|
@ -308,7 +308,7 @@ nsXBLProtoImplProperty::Read(nsIObjectInputStream* aStream,
|
|||
nsresult rv = XBL_DeserializeFunction(aStream, &getterObject);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mJSAttributes |= JSPROP_GETTER | JSPROP_SHARED;
|
||||
mJSAttributes |= JSPROP_GETTER;
|
||||
}
|
||||
mGetter.SetJSFunction(getterObject);
|
||||
|
||||
|
|
@ -318,7 +318,7 @@ nsXBLProtoImplProperty::Read(nsIObjectInputStream* aStream,
|
|||
nsresult rv = XBL_DeserializeFunction(aStream, &setterObject);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mJSAttributes |= JSPROP_SETTER | JSPROP_SHARED;
|
||||
mJSAttributes |= JSPROP_SETTER;
|
||||
}
|
||||
mSetter.SetJSFunction(setterObject);
|
||||
|
||||
|
|
|
|||
|
|
@ -68,72 +68,63 @@ GLScreenBuffer::CreateFactory(GLContext* gl,
|
|||
KnowsCompositor* compositorConnection,
|
||||
const layers::TextureFlags& flags)
|
||||
{
|
||||
return CreateFactory(gl, caps, compositorConnection->GetTextureForwarder(),
|
||||
compositorConnection->GetCompositorBackendType(), flags);
|
||||
}
|
||||
LayersIPCChannel* ipcChannel = compositorConnection->GetTextureForwarder();
|
||||
const layers::LayersBackend backend = compositorConnection->GetCompositorBackendType();
|
||||
const bool useANGLE = compositorConnection->GetCompositorUseANGLE();
|
||||
|
||||
const bool useGl = !gfxPrefs::WebGLForceLayersReadback() &&
|
||||
(backend == layers::LayersBackend::LAYERS_OPENGL ||
|
||||
(backend == layers::LayersBackend::LAYERS_WR && !useANGLE));
|
||||
const bool useD3D = !gfxPrefs::WebGLForceLayersReadback() &&
|
||||
(backend == layers::LayersBackend::LAYERS_D3D11 ||
|
||||
(backend == layers::LayersBackend::LAYERS_WR && useANGLE));
|
||||
|
||||
/* static */ UniquePtr<SurfaceFactory>
|
||||
GLScreenBuffer::CreateFactory(GLContext* gl,
|
||||
const SurfaceCaps& caps,
|
||||
LayersIPCChannel* ipcChannel,
|
||||
const mozilla::layers::LayersBackend backend,
|
||||
const layers::TextureFlags& flags)
|
||||
{
|
||||
UniquePtr<SurfaceFactory> factory = nullptr;
|
||||
if (!gfxPrefs::WebGLForceLayersReadback()) {
|
||||
switch (backend) {
|
||||
case mozilla::layers::LayersBackend::LAYERS_OPENGL: {
|
||||
if (useGl) {
|
||||
#if defined(XP_MACOSX)
|
||||
factory = SurfaceFactory_IOSurface::Create(gl, caps, ipcChannel, flags);
|
||||
factory = SurfaceFactory_IOSurface::Create(gl, caps, ipcChannel, flags);
|
||||
#elif defined(GL_PROVIDER_GLX)
|
||||
if (sGLXLibrary.UseTextureFromPixmap())
|
||||
factory = SurfaceFactory_GLXDrawable::Create(gl, caps, ipcChannel, flags);
|
||||
if (sGLXLibrary.UseTextureFromPixmap())
|
||||
factory = SurfaceFactory_GLXDrawable::Create(gl, caps, ipcChannel, flags);
|
||||
#elif defined(MOZ_WIDGET_UIKIT)
|
||||
factory = MakeUnique<SurfaceFactory_GLTexture>(mGLContext, caps, ipcChannel, mFlags);
|
||||
factory = MakeUnique<SurfaceFactory_GLTexture>(mGLContext, caps, ipcChannel, mFlags);
|
||||
#elif defined(MOZ_WIDGET_ANDROID)
|
||||
if (XRE_IsParentProcess() && !gfxPrefs::WebGLSurfaceTextureEnabled()) {
|
||||
factory = SurfaceFactory_EGLImage::Create(gl, caps, ipcChannel, flags);
|
||||
} else {
|
||||
factory = SurfaceFactory_SurfaceTexture::Create(gl, caps, ipcChannel, flags);
|
||||
}
|
||||
if (XRE_IsParentProcess() && !gfxPrefs::WebGLSurfaceTextureEnabled()) {
|
||||
factory = SurfaceFactory_EGLImage::Create(gl, caps, ipcChannel, flags);
|
||||
} else {
|
||||
factory = SurfaceFactory_SurfaceTexture::Create(gl, caps, ipcChannel, flags);
|
||||
}
|
||||
#else
|
||||
if (gl->GetContextType() == GLContextType::EGL) {
|
||||
if (XRE_IsParentProcess()) {
|
||||
factory = SurfaceFactory_EGLImage::Create(gl, caps, ipcChannel, flags);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
if (gl->GetContextType() == GLContextType::EGL) {
|
||||
if (XRE_IsParentProcess()) {
|
||||
factory = SurfaceFactory_EGLImage::Create(gl, caps, ipcChannel, flags);
|
||||
}
|
||||
case mozilla::layers::LayersBackend::LAYERS_D3D11: {
|
||||
}
|
||||
#endif
|
||||
} else if (useD3D) {
|
||||
#ifdef XP_WIN
|
||||
// Enable surface sharing only if ANGLE and compositing devices
|
||||
// are both WARP or both not WARP
|
||||
gfx::DeviceManagerDx* dm = gfx::DeviceManagerDx::Get();
|
||||
if (gl->IsANGLE() &&
|
||||
(gl->IsWARP() == dm->IsWARP()) &&
|
||||
dm->TextureSharingWorks())
|
||||
{
|
||||
factory = SurfaceFactory_ANGLEShareHandle::Create(gl, caps, ipcChannel, flags);
|
||||
}
|
||||
|
||||
if (!factory && gfxPrefs::WebGLDXGLEnabled()) {
|
||||
factory = SurfaceFactory_D3D11Interop::Create(gl, caps, ipcChannel, flags);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
// Enable surface sharing only if ANGLE and compositing devices
|
||||
// are both WARP or both not WARP
|
||||
gfx::DeviceManagerDx* dm = gfx::DeviceManagerDx::Get();
|
||||
if (gl->IsANGLE() &&
|
||||
(gl->IsWARP() == dm->IsWARP()) &&
|
||||
dm->TextureSharingWorks())
|
||||
{
|
||||
factory = SurfaceFactory_ANGLEShareHandle::Create(gl, caps, ipcChannel, flags);
|
||||
}
|
||||
|
||||
#ifdef GL_PROVIDER_GLX
|
||||
if (!factory && sGLXLibrary.UseTextureFromPixmap()) {
|
||||
factory = SurfaceFactory_GLXDrawable::Create(gl, caps, ipcChannel, flags);
|
||||
if (!factory && gfxPrefs::WebGLDXGLEnabled()) {
|
||||
factory = SurfaceFactory_D3D11Interop::Create(gl, caps, ipcChannel, flags);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef GL_PROVIDER_GLX
|
||||
if (!factory && sGLXLibrary.UseTextureFromPixmap()) {
|
||||
factory = SurfaceFactory_GLXDrawable::Create(gl, caps, ipcChannel, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -140,12 +140,6 @@ public:
|
|||
const SurfaceCaps& caps,
|
||||
layers::KnowsCompositor* compositorConnection,
|
||||
const layers::TextureFlags& flags);
|
||||
static UniquePtr<SurfaceFactory>
|
||||
CreateFactory(GLContext* gl,
|
||||
const SurfaceCaps& caps,
|
||||
layers::LayersIPCChannel* ipcChannel,
|
||||
const mozilla::layers::LayersBackend backend,
|
||||
const layers::TextureFlags& flags);
|
||||
|
||||
protected:
|
||||
GLContext* const mGL; // Owns us.
|
||||
|
|
|
|||
|
|
@ -93,6 +93,11 @@ GPUParent::Init(base::ProcessId aParentPid,
|
|||
|
||||
nsDebugImpl::SetMultiprocessMode("GPU");
|
||||
|
||||
// This must be sent before any IPDL message, which may hit sentinel
|
||||
// errors due to parent and content processes having different
|
||||
// versions.
|
||||
GetIPCChannel()->SendBuildID();
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
// Init crash reporter support.
|
||||
CrashReporterClient::InitSingleton(this);
|
||||
|
|
|
|||
|
|
@ -225,16 +225,13 @@ GPUProcessManager::EnsureProtocolsReady()
|
|||
void
|
||||
GPUProcessManager::EnsureCompositorManagerChild()
|
||||
{
|
||||
base::ProcessId gpuPid = EnsureGPUReady()
|
||||
? mGPUChild->OtherPid()
|
||||
: base::GetCurrentProcId();
|
||||
|
||||
if (CompositorManagerChild::IsInitialized(gpuPid)) {
|
||||
bool gpuReady = EnsureGPUReady();
|
||||
if (CompositorManagerChild::IsInitialized(mProcessToken)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!EnsureGPUReady()) {
|
||||
CompositorManagerChild::InitSameProcess(AllocateNamespace());
|
||||
if (!gpuReady) {
|
||||
CompositorManagerChild::InitSameProcess(AllocateNamespace(), mProcessToken);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -251,7 +248,8 @@ GPUProcessManager::EnsureCompositorManagerChild()
|
|||
}
|
||||
|
||||
mGPUChild->SendInitCompositorManager(Move(parentPipe));
|
||||
CompositorManagerChild::Init(Move(childPipe), AllocateNamespace());
|
||||
CompositorManagerChild::Init(Move(childPipe), AllocateNamespace(),
|
||||
mProcessToken);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -523,7 +521,7 @@ GPUProcessManager::OnProcessUnexpectedShutdown(GPUProcessHost* aHost)
|
|||
{
|
||||
MOZ_ASSERT(mProcess && mProcess == aHost);
|
||||
|
||||
CompositorManagerChild::OnGPUProcessLost();
|
||||
CompositorManagerChild::OnGPUProcessLost(aHost->GetProcessToken());
|
||||
DestroyProcess();
|
||||
|
||||
if (mNumProcessAttempts > uint32_t(gfxPrefs::GPUProcessMaxRestarts())) {
|
||||
|
|
|
|||
|
|
@ -111,37 +111,34 @@ GPUVideoTextureHost::CreateRenderTexture(const wr::ExternalImageId& aExternalIma
|
|||
mWrappedTextureHost->CreateRenderTexture(aExternalImageId);
|
||||
}
|
||||
|
||||
void
|
||||
GPUVideoTextureHost::GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
|
||||
const std::function<wr::ImageKey()>& aImageKeyAllocator)
|
||||
uint32_t
|
||||
GPUVideoTextureHost::NumSubTextures() const
|
||||
{
|
||||
MOZ_ASSERT(mWrappedTextureHost);
|
||||
MOZ_ASSERT(aImageKeys.IsEmpty());
|
||||
|
||||
mWrappedTextureHost->GetWRImageKeys(aImageKeys, aImageKeyAllocator);
|
||||
return mWrappedTextureHost->NumSubTextures();
|
||||
}
|
||||
|
||||
void
|
||||
GPUVideoTextureHost::AddWRImage(wr::ResourceUpdateQueue& aResources,
|
||||
Range<const wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID)
|
||||
GPUVideoTextureHost::PushResourceUpdates(wr::ResourceUpdateQueue& aResources,
|
||||
ResourceUpdateOp aOp,
|
||||
const Range<wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID)
|
||||
{
|
||||
MOZ_ASSERT(mWrappedTextureHost);
|
||||
|
||||
mWrappedTextureHost->AddWRImage(aResources, aImageKeys, aExtID);
|
||||
mWrappedTextureHost->PushResourceUpdates(aResources, aOp, aImageKeys, aExtID);
|
||||
}
|
||||
|
||||
void
|
||||
GPUVideoTextureHost::PushExternalImage(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
Range<const wr::ImageKey>& aImageKeys)
|
||||
GPUVideoTextureHost::PushDisplayItems(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
const Range<wr::ImageKey>& aImageKeys)
|
||||
{
|
||||
MOZ_ASSERT(mWrappedTextureHost);
|
||||
MOZ_ASSERT(aImageKeys.length() > 0);
|
||||
|
||||
mWrappedTextureHost->PushExternalImage(aBuilder,
|
||||
mWrappedTextureHost->PushDisplayItems(aBuilder,
|
||||
aBounds,
|
||||
aClip,
|
||||
aFilter,
|
||||
|
|
|
|||
|
|
@ -48,18 +48,18 @@ public:
|
|||
|
||||
virtual void CreateRenderTexture(const wr::ExternalImageId& aExternalImageId) override;
|
||||
|
||||
virtual void GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
|
||||
const std::function<wr::ImageKey()>& aImageKeyAllocator) override;
|
||||
virtual uint32_t NumSubTextures() const override;
|
||||
|
||||
virtual void AddWRImage(wr::ResourceUpdateQueue& aResources,
|
||||
Range<const wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID) override;
|
||||
virtual void PushResourceUpdates(wr::ResourceUpdateQueue& aResources,
|
||||
ResourceUpdateOp aOp,
|
||||
const Range<wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID) override;
|
||||
|
||||
virtual void PushExternalImage(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
Range<const wr::ImageKey>& aImageKeys) override;
|
||||
virtual void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
const Range<wr::ImageKey>& aImageKeys) override;
|
||||
|
||||
protected:
|
||||
RefPtr<TextureHost> mWrappedTextureHost;
|
||||
|
|
|
|||
|
|
@ -566,67 +566,51 @@ BufferTextureHost::CreateRenderTexture(const wr::ExternalImageId& aExternalImage
|
|||
wr::RenderThread::Get()->RegisterExternalImage(wr::AsUint64(aExternalImageId), texture.forget());
|
||||
}
|
||||
|
||||
void
|
||||
BufferTextureHost::GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
|
||||
const std::function<wr::ImageKey()>& aImageKeyAllocator)
|
||||
uint32_t
|
||||
BufferTextureHost::NumSubTextures() const
|
||||
{
|
||||
MOZ_ASSERT(aImageKeys.IsEmpty());
|
||||
|
||||
if (GetFormat() != gfx::SurfaceFormat::YUV) {
|
||||
// 1 image key
|
||||
aImageKeys.AppendElement(aImageKeyAllocator());
|
||||
MOZ_ASSERT(aImageKeys.Length() == 1);
|
||||
} else {
|
||||
// 3 image key
|
||||
aImageKeys.AppendElement(aImageKeyAllocator());
|
||||
aImageKeys.AppendElement(aImageKeyAllocator());
|
||||
aImageKeys.AppendElement(aImageKeyAllocator());
|
||||
MOZ_ASSERT(aImageKeys.Length() == 3);
|
||||
if (GetFormat() == gfx::SurfaceFormat::YUV) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
BufferTextureHost::AddWRImage(wr::ResourceUpdateQueue& aResources,
|
||||
Range<const wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID)
|
||||
BufferTextureHost::PushResourceUpdates(wr::ResourceUpdateQueue& aResources,
|
||||
ResourceUpdateOp aOp,
|
||||
const Range<wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID)
|
||||
{
|
||||
auto method = aOp == TextureHost::ADD_IMAGE ? &wr::ResourceUpdateQueue::AddExternalImage
|
||||
: &wr::ResourceUpdateQueue::UpdateExternalImage;
|
||||
auto bufferType = wr::WrExternalImageBufferType::ExternalBuffer;
|
||||
|
||||
if (GetFormat() != gfx::SurfaceFormat::YUV) {
|
||||
MOZ_ASSERT(aImageKeys.length() == 1);
|
||||
|
||||
wr::ImageDescriptor descriptor(GetSize(),
|
||||
ImageDataSerializer::ComputeRGBStride(GetFormat(), GetSize().width),
|
||||
GetFormat());
|
||||
aResources.AddExternalImageBuffer(aImageKeys[0], descriptor, aExtID);
|
||||
(aResources.*method)(aImageKeys[0], descriptor, aExtID, bufferType, 0);
|
||||
} else {
|
||||
MOZ_ASSERT(aImageKeys.length() == 3);
|
||||
|
||||
const layers::YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor();
|
||||
wr::ImageDescriptor yDescriptor(desc.ySize(), desc.ySize().width, gfx::SurfaceFormat::A8);
|
||||
wr::ImageDescriptor cbcrDescriptor(desc.cbCrSize(), desc.cbCrSize().width, gfx::SurfaceFormat::A8);
|
||||
aResources.AddExternalImage(aImageKeys[0],
|
||||
yDescriptor,
|
||||
aExtID,
|
||||
wr::WrExternalImageBufferType::ExternalBuffer,
|
||||
0);
|
||||
aResources.AddExternalImage(aImageKeys[1],
|
||||
cbcrDescriptor,
|
||||
aExtID,
|
||||
wr::WrExternalImageBufferType::ExternalBuffer,
|
||||
1);
|
||||
aResources.AddExternalImage(aImageKeys[2],
|
||||
cbcrDescriptor,
|
||||
aExtID,
|
||||
wr::WrExternalImageBufferType::ExternalBuffer,
|
||||
2);
|
||||
(aResources.*method)(aImageKeys[0], yDescriptor, aExtID, bufferType, 0);
|
||||
(aResources.*method)(aImageKeys[1], cbcrDescriptor, aExtID, bufferType, 1);
|
||||
(aResources.*method)(aImageKeys[2], cbcrDescriptor, aExtID, bufferType, 2);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BufferTextureHost::PushExternalImage(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
Range<const wr::ImageKey>& aImageKeys)
|
||||
BufferTextureHost::PushDisplayItems(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
const Range<wr::ImageKey>& aImageKeys)
|
||||
{
|
||||
if (GetFormat() != gfx::SurfaceFormat::YUV) {
|
||||
MOZ_ASSERT(aImageKeys.length() == 1);
|
||||
|
|
|
|||
|
|
@ -621,35 +621,32 @@ public:
|
|||
MOZ_RELEASE_ASSERT(false, "No CreateRenderTexture() implementation for this TextureHost type.");
|
||||
}
|
||||
|
||||
// Create all necessary image keys for this textureHost rendering.
|
||||
// @param aImageKeys - [out] The set of ImageKeys used for this textureHost
|
||||
// composing.
|
||||
// @param aImageKeyAllocator - [in] The function which is used for creating
|
||||
// the new ImageKey.
|
||||
virtual void GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
|
||||
const std::function<wr::ImageKey()>& aImageKeyAllocator)
|
||||
{
|
||||
MOZ_ASSERT(aImageKeys.IsEmpty());
|
||||
MOZ_ASSERT_UNREACHABLE("No GetWRImageKeys() implementation for this TextureHost type.");
|
||||
}
|
||||
/// Returns the number of actual textures that will be used to render this.
|
||||
/// For example in a lot of YUV cases it will be 3
|
||||
virtual uint32_t NumSubTextures() const { return 1; }
|
||||
|
||||
enum ResourceUpdateOp {
|
||||
ADD_IMAGE,
|
||||
UPDATE_IMAGE,
|
||||
};
|
||||
|
||||
// Add all necessary TextureHost informations to the resource update queue.
|
||||
// Then, WR will use this informations to read from the TextureHost.
|
||||
virtual void AddWRImage(wr::ResourceUpdateQueue& aResources,
|
||||
Range<const wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID)
|
||||
virtual void PushResourceUpdates(wr::ResourceUpdateQueue& aResources,
|
||||
ResourceUpdateOp aOp,
|
||||
const Range<wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID)
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("No AddWRImage() implementation for this TextureHost type.");
|
||||
MOZ_ASSERT_UNREACHABLE("Unimplemented");
|
||||
}
|
||||
|
||||
// Put all necessary WR commands into DisplayListBuilder for this textureHost rendering.
|
||||
virtual void PushExternalImage(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
Range<const wr::ImageKey>& aKeys)
|
||||
virtual void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
const Range<wr::ImageKey>& aKeys)
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("No PushExternalImage() implementation for this TextureHost type.");
|
||||
MOZ_ASSERT_UNREACHABLE("No PushDisplayItems() implementation for this TextureHost type.");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -747,18 +744,18 @@ public:
|
|||
|
||||
virtual void CreateRenderTexture(const wr::ExternalImageId& aExternalImageId) override;
|
||||
|
||||
virtual void GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
|
||||
const std::function<wr::ImageKey()>& aImageKeyAllocator) override;
|
||||
virtual uint32_t NumSubTextures() const override;
|
||||
|
||||
virtual void AddWRImage(wr::ResourceUpdateQueue& aResources,
|
||||
Range<const wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID) override;
|
||||
virtual void PushResourceUpdates(wr::ResourceUpdateQueue& aResources,
|
||||
ResourceUpdateOp aOp,
|
||||
const Range<wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID) override;
|
||||
|
||||
virtual void PushExternalImage(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
Range<const wr::ImageKey>& aImageKeys) override;
|
||||
virtual void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
const Range<wr::ImageKey>& aImageKeys) override;
|
||||
|
||||
protected:
|
||||
bool Upload(nsIntRegion *aRegion = nullptr);
|
||||
|
|
|
|||
|
|
@ -1042,41 +1042,36 @@ DXGITextureHostD3D11::CreateRenderTexture(const wr::ExternalImageId& aExternalIm
|
|||
wr::RenderThread::Get()->RegisterExternalImage(wr::AsUint64(aExternalImageId), texture.forget());
|
||||
}
|
||||
|
||||
void
|
||||
DXGITextureHostD3D11::GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
|
||||
const std::function<wr::ImageKey()>& aImageKeyAllocator)
|
||||
uint32_t
|
||||
DXGITextureHostD3D11::NumSubTextures() const
|
||||
{
|
||||
MOZ_ASSERT(aImageKeys.IsEmpty());
|
||||
|
||||
switch (GetFormat()) {
|
||||
case gfx::SurfaceFormat::R8G8B8X8:
|
||||
case gfx::SurfaceFormat::R8G8B8A8:
|
||||
case gfx::SurfaceFormat::B8G8R8A8:
|
||||
case gfx::SurfaceFormat::B8G8R8X8: {
|
||||
// 1 image key
|
||||
aImageKeys.AppendElement(aImageKeyAllocator());
|
||||
MOZ_ASSERT(aImageKeys.Length() == 1);
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
case gfx::SurfaceFormat::NV12: {
|
||||
// 2 image key
|
||||
aImageKeys.AppendElement(aImageKeyAllocator());
|
||||
aImageKeys.AppendElement(aImageKeyAllocator());
|
||||
MOZ_ASSERT(aImageKeys.Length() == 2);
|
||||
break;
|
||||
return 2;
|
||||
}
|
||||
default: {
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected format");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DXGITextureHostD3D11::AddWRImage(wr::ResourceUpdateQueue& aResources,
|
||||
Range<const wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID)
|
||||
DXGITextureHostD3D11::PushResourceUpdates(wr::ResourceUpdateQueue& aResources,
|
||||
ResourceUpdateOp aOp,
|
||||
const Range<wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID)
|
||||
{
|
||||
MOZ_ASSERT(mHandle);
|
||||
auto method = aOp == TextureHost::ADD_IMAGE ? &wr::ResourceUpdateQueue::AddExternalImage
|
||||
: &wr::ResourceUpdateQueue::UpdateExternalImage;
|
||||
auto bufferType = wr::WrExternalImageBufferType::TextureExternalHandle;
|
||||
|
||||
switch (mFormat) {
|
||||
case gfx::SurfaceFormat::R8G8B8X8:
|
||||
|
|
@ -1086,11 +1081,7 @@ DXGITextureHostD3D11::AddWRImage(wr::ResourceUpdateQueue& aResources,
|
|||
MOZ_ASSERT(aImageKeys.length() == 1);
|
||||
|
||||
wr::ImageDescriptor descriptor(GetSize(), GetFormat());
|
||||
aResources.AddExternalImage(aImageKeys[0],
|
||||
descriptor,
|
||||
aExtID,
|
||||
wr::WrExternalImageBufferType::Texture2DHandle,
|
||||
0);
|
||||
(aResources.*method)(aImageKeys[0], descriptor, aExtID, bufferType, 0);
|
||||
break;
|
||||
}
|
||||
case gfx::SurfaceFormat::NV12: {
|
||||
|
|
@ -1098,16 +1089,8 @@ DXGITextureHostD3D11::AddWRImage(wr::ResourceUpdateQueue& aResources,
|
|||
|
||||
wr::ImageDescriptor descriptor0(GetSize(), gfx::SurfaceFormat::A8);
|
||||
wr::ImageDescriptor descriptor1(GetSize() / 2, gfx::SurfaceFormat::R8G8);
|
||||
aResources.AddExternalImage(aImageKeys[0],
|
||||
descriptor0,
|
||||
aExtID,
|
||||
wr::WrExternalImageBufferType::TextureExternalHandle,
|
||||
0);
|
||||
aResources.AddExternalImage(aImageKeys[1],
|
||||
descriptor1,
|
||||
aExtID,
|
||||
wr::WrExternalImageBufferType::TextureExternalHandle,
|
||||
1);
|
||||
(aResources.*method)(aImageKeys[0], descriptor0, aExtID, bufferType, 0);
|
||||
(aResources.*method)(aImageKeys[1], descriptor1, aExtID, bufferType, 1);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
|
@ -1117,11 +1100,11 @@ DXGITextureHostD3D11::AddWRImage(wr::ResourceUpdateQueue& aResources,
|
|||
}
|
||||
|
||||
void
|
||||
DXGITextureHostD3D11::PushExternalImage(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
Range<const wr::ImageKey>& aImageKeys)
|
||||
DXGITextureHostD3D11::PushDisplayItems(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
const Range<wr::ImageKey>& aImageKeys)
|
||||
{
|
||||
switch (GetFormat()) {
|
||||
case gfx::SurfaceFormat::R8G8B8X8:
|
||||
|
|
@ -1312,20 +1295,10 @@ DXGIYCbCrTextureHostD3D11::CreateRenderTexture(const wr::ExternalImageId& aExter
|
|||
}
|
||||
|
||||
void
|
||||
DXGIYCbCrTextureHostD3D11::GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
|
||||
const std::function<wr::ImageKey()>& aImageKeyAllocator)
|
||||
{
|
||||
MOZ_ASSERT(aImageKeys.IsEmpty());
|
||||
|
||||
// 1 image key
|
||||
aImageKeys.AppendElement(aImageKeyAllocator());
|
||||
MOZ_ASSERT(aImageKeys.Length() == 1);
|
||||
}
|
||||
|
||||
void
|
||||
DXGIYCbCrTextureHostD3D11::AddWRImage(wr::ResourceUpdateQueue& aResources,
|
||||
Range<const wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID)
|
||||
DXGIYCbCrTextureHostD3D11::PushResourceUpdates(wr::ResourceUpdateQueue& aResources,
|
||||
ResourceUpdateOp aOp,
|
||||
const Range<wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID)
|
||||
{
|
||||
// TODO - This implementation is very slow (read-back, copy on the copy and re-upload).
|
||||
|
||||
|
|
@ -1351,17 +1324,21 @@ DXGIYCbCrTextureHostD3D11::AddWRImage(wr::ResourceUpdateQueue& aResources,
|
|||
wr::ImageDescriptor descriptor(size, map.mStride, dataSourceSurface->GetFormat());
|
||||
wr::Vec_u8 imgBytes;
|
||||
imgBytes.PushBytes(Range<uint8_t>(map.mData, size.height * map.mStride));
|
||||
aResources.AddImage(aImageKeys[0], descriptor, imgBytes);
|
||||
if (aOp == TextureHost::ADD_IMAGE) {
|
||||
aResources.AddImage(aImageKeys[0], descriptor, imgBytes);
|
||||
} else {
|
||||
aResources.UpdateImageBuffer(aImageKeys[0], descriptor, imgBytes);
|
||||
}
|
||||
|
||||
dataSourceSurface->Unmap();
|
||||
}
|
||||
|
||||
void
|
||||
DXGIYCbCrTextureHostD3D11::PushExternalImage(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
Range<const wr::ImageKey>& aImageKeys)
|
||||
DXGIYCbCrTextureHostD3D11::PushDisplayItems(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
const Range<wr::ImageKey>& aImageKeys)
|
||||
{
|
||||
// 1 image key
|
||||
MOZ_ASSERT(aImageKeys.length() == 1);
|
||||
|
|
|
|||
|
|
@ -335,18 +335,18 @@ public:
|
|||
|
||||
virtual void CreateRenderTexture(const wr::ExternalImageId& aExternalImageId) override;
|
||||
|
||||
virtual void GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
|
||||
const std::function<wr::ImageKey()>& aImageKeyAllocator) override;
|
||||
virtual uint32_t NumSubTextures() const override;
|
||||
|
||||
virtual void AddWRImage(wr::ResourceUpdateQueue& aAPI,
|
||||
Range<const wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID) override;
|
||||
virtual void PushResourceUpdates(wr::ResourceUpdateQueue& aResources,
|
||||
ResourceUpdateOp aOp,
|
||||
const Range<wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID) override;
|
||||
|
||||
virtual void PushExternalImage(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
Range<const wr::ImageKey>& aImageKeys) override;
|
||||
virtual void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
const Range<wr::ImageKey>& aImageKeys) override;
|
||||
|
||||
protected:
|
||||
bool LockInternal();
|
||||
|
|
@ -398,18 +398,16 @@ public:
|
|||
|
||||
virtual void CreateRenderTexture(const wr::ExternalImageId& aExternalImageId) override;
|
||||
|
||||
virtual void GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
|
||||
const std::function<wr::ImageKey()>& aImageKeyAllocator) override;
|
||||
virtual void PushResourceUpdates(wr::ResourceUpdateQueue& aResources,
|
||||
ResourceUpdateOp aOp,
|
||||
const Range<wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID) override;
|
||||
|
||||
virtual void AddWRImage(wr::ResourceUpdateQueue& aResources,
|
||||
Range<const wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID) override;
|
||||
|
||||
virtual void PushExternalImage(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
Range<const wr::ImageKey>& aImageKeys) override;
|
||||
virtual void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
const Range<wr::ImageKey>& aImageKeys) override;
|
||||
|
||||
private:
|
||||
bool EnsureTextureSource();
|
||||
|
|
|
|||
|
|
@ -24,37 +24,48 @@ using gfx::GPUProcessManager;
|
|||
StaticRefPtr<CompositorManagerChild> CompositorManagerChild::sInstance;
|
||||
|
||||
/* static */ bool
|
||||
CompositorManagerChild::IsInitialized(base::ProcessId aGPUPid)
|
||||
CompositorManagerChild::IsInitialized(uint64_t aProcessToken)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return sInstance && sInstance->CanSend() && sInstance->OtherPid() == aGPUPid;
|
||||
return sInstance && sInstance->CanSend() &&
|
||||
sInstance->mProcessToken == aProcessToken;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
CompositorManagerChild::InitSameProcess(uint32_t aNamespace)
|
||||
/* static */ void
|
||||
CompositorManagerChild::InitSameProcess(uint32_t aNamespace,
|
||||
uint64_t aProcessToken)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (NS_WARN_IF(IsInitialized(base::GetCurrentProcId()))) {
|
||||
MOZ_ASSERT_UNREACHABLE("Already initialized same process");
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<CompositorManagerParent> parent =
|
||||
CompositorManagerParent::CreateSameProcess();
|
||||
sInstance = new CompositorManagerChild(parent, aNamespace);
|
||||
return true;
|
||||
RefPtr<CompositorManagerChild> child =
|
||||
new CompositorManagerChild(parent, aProcessToken, aNamespace);
|
||||
if (NS_WARN_IF(!child->CanSend())) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(false, "Failed to open same process protocol");
|
||||
return;
|
||||
}
|
||||
|
||||
parent->BindComplete();
|
||||
sInstance = child.forget();
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
CompositorManagerChild::Init(Endpoint<PCompositorManagerChild>&& aEndpoint,
|
||||
uint32_t aNamespace)
|
||||
uint32_t aNamespace,
|
||||
uint64_t aProcessToken /* = 0 */)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (sInstance) {
|
||||
MOZ_ASSERT(sInstance->mNamespace != aNamespace);
|
||||
}
|
||||
|
||||
sInstance = new CompositorManagerChild(Move(aEndpoint), aNamespace);
|
||||
sInstance = new CompositorManagerChild(Move(aEndpoint), aProcessToken,
|
||||
aNamespace);
|
||||
return sInstance->CanSend();
|
||||
}
|
||||
|
||||
|
|
@ -73,14 +84,14 @@ CompositorManagerChild::Shutdown()
|
|||
}
|
||||
|
||||
/* static */ void
|
||||
CompositorManagerChild::OnGPUProcessLost()
|
||||
CompositorManagerChild::OnGPUProcessLost(uint64_t aProcessToken)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Since GPUChild and CompositorManagerChild will race on ActorDestroy, we
|
||||
// cannot know if the CompositorManagerChild is about to be released but has
|
||||
// yet to be. As such, we want to pre-emptively set mCanSend to false.
|
||||
if (sInstance) {
|
||||
if (sInstance && sInstance->mProcessToken == aProcessToken) {
|
||||
sInstance->mCanSend = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -162,10 +173,12 @@ CompositorManagerChild::CreateSameProcessWidgetCompositorBridge(LayerManager* aL
|
|||
}
|
||||
|
||||
CompositorManagerChild::CompositorManagerChild(CompositorManagerParent* aParent,
|
||||
uint64_t aProcessToken,
|
||||
uint32_t aNamespace)
|
||||
: mCanSend(false)
|
||||
: mProcessToken(aProcessToken)
|
||||
, mNamespace(aNamespace)
|
||||
, mResourceId(0)
|
||||
, mCanSend(false)
|
||||
{
|
||||
MOZ_ASSERT(aParent);
|
||||
|
||||
|
|
@ -182,10 +195,12 @@ CompositorManagerChild::CompositorManagerChild(CompositorManagerParent* aParent,
|
|||
}
|
||||
|
||||
CompositorManagerChild::CompositorManagerChild(Endpoint<PCompositorManagerChild>&& aEndpoint,
|
||||
uint64_t aProcessToken,
|
||||
uint32_t aNamespace)
|
||||
: mCanSend(false)
|
||||
: mProcessToken(aProcessToken)
|
||||
, mNamespace(aNamespace)
|
||||
, mResourceId(0)
|
||||
, mCanSend(false)
|
||||
{
|
||||
if (NS_WARN_IF(!aEndpoint.Bind(this))) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -24,12 +24,13 @@ class CompositorManagerChild : public PCompositorManagerChild
|
|||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorManagerChild)
|
||||
|
||||
public:
|
||||
static bool IsInitialized(base::ProcessId aPid);
|
||||
static bool InitSameProcess(uint32_t aNamespace);
|
||||
static bool IsInitialized(uint64_t aProcessToken);
|
||||
static void InitSameProcess(uint32_t aNamespace, uint64_t aProcessToken);
|
||||
static bool Init(Endpoint<PCompositorManagerChild>&& aEndpoint,
|
||||
uint32_t aNamespace);
|
||||
uint32_t aNamespace,
|
||||
uint64_t aProcessToken = 0);
|
||||
static void Shutdown();
|
||||
static void OnGPUProcessLost();
|
||||
static void OnGPUProcessLost(uint64_t aProcessToken);
|
||||
|
||||
static bool
|
||||
CreateContentCompositorBridge(uint32_t aNamespace);
|
||||
|
|
@ -73,9 +74,11 @@ private:
|
|||
static StaticRefPtr<CompositorManagerChild> sInstance;
|
||||
|
||||
CompositorManagerChild(CompositorManagerParent* aParent,
|
||||
uint64_t aProcessToken,
|
||||
uint32_t aNamespace);
|
||||
|
||||
CompositorManagerChild(Endpoint<PCompositorManagerChild>&& aEndpoint,
|
||||
uint64_t aProcessToken,
|
||||
uint32_t aNamespace);
|
||||
|
||||
~CompositorManagerChild() override
|
||||
|
|
@ -95,9 +98,10 @@ private:
|
|||
|
||||
void SetReplyTimeout();
|
||||
|
||||
bool mCanSend;
|
||||
uint64_t mProcessToken;
|
||||
uint32_t mNamespace;
|
||||
uint32_t mResourceId;
|
||||
bool mCanSend;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
|||
|
|
@ -42,18 +42,6 @@ CompositorManagerParent::CreateSameProcess()
|
|||
// on the main thread and complete before we return the manager handles.
|
||||
RefPtr<CompositorManagerParent> parent = new CompositorManagerParent();
|
||||
parent->SetOtherProcessId(base::GetCurrentProcId());
|
||||
|
||||
// CompositorManagerParent::Bind would normally add a reference for IPDL but
|
||||
// we don't use that in the same process case.
|
||||
parent.get()->AddRef();
|
||||
sInstance = parent;
|
||||
|
||||
#ifdef COMPOSITOR_MANAGER_PARENT_EXPLICIT_SHUTDOWN
|
||||
if (!sActiveActors) {
|
||||
sActiveActors = new nsTArray<CompositorManagerParent*>();
|
||||
}
|
||||
sActiveActors->AppendElement(parent);
|
||||
#endif
|
||||
return parent.forget();
|
||||
}
|
||||
|
||||
|
|
@ -133,12 +121,22 @@ CompositorManagerParent::Bind(Endpoint<PCompositorManagerParent>&& aEndpoint)
|
|||
return;
|
||||
}
|
||||
|
||||
BindComplete();
|
||||
}
|
||||
|
||||
void
|
||||
CompositorManagerParent::BindComplete()
|
||||
{
|
||||
// Add the IPDL reference to ourself, so we can't get freed until IPDL is
|
||||
// done with us.
|
||||
AddRef();
|
||||
|
||||
#ifdef COMPOSITOR_MANAGER_PARENT_EXPLICIT_SHUTDOWN
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
if (OtherPid() == base::GetCurrentProcId()) {
|
||||
sInstance = this;
|
||||
}
|
||||
|
||||
#ifdef COMPOSITOR_MANAGER_PARENT_EXPLICIT_SHUTDOWN
|
||||
if (!sActiveActors) {
|
||||
sActiveActors = new nsTArray<CompositorManagerParent*>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public:
|
|||
bool aUseExternalSurfaceSize,
|
||||
const gfx::IntSize& aSurfaceSize);
|
||||
|
||||
void BindComplete();
|
||||
void ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
bool DeallocPCompositorBridgeParent(PCompositorBridgeParent* aActor) override;
|
||||
|
|
|
|||
|
|
@ -22,9 +22,6 @@ namespace layers {
|
|||
static StaticRefPtr<CompositorThreadHolder> sCompositorThreadHolder;
|
||||
static bool sFinishedCompositorShutDown = false;
|
||||
|
||||
// See ImageBridgeChild.cpp
|
||||
void ReleaseImageBridgeParentSingleton();
|
||||
|
||||
CompositorThreadHolder* GetCompositorThreadHolder()
|
||||
{
|
||||
return sCompositorThreadHolder;
|
||||
|
|
@ -126,7 +123,7 @@ CompositorThreadHolder::Shutdown()
|
|||
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main Thread!");
|
||||
MOZ_ASSERT(sCompositorThreadHolder, "The compositor thread has already been shut down!");
|
||||
|
||||
ReleaseImageBridgeParentSingleton();
|
||||
ImageBridgeParent::Shutdown();
|
||||
gfx::ReleaseVRManagerParentSingleton();
|
||||
MediaSystemResourceService::Shutdown();
|
||||
CompositorManagerParent::Shutdown();
|
||||
|
|
|
|||
|
|
@ -240,13 +240,16 @@ ImageBridgeChild::ShutdownStep2(SynchronousTask* aTask)
|
|||
|
||||
MOZ_ASSERT(InImageBridgeChildThread(),
|
||||
"Should be in ImageBridgeChild thread.");
|
||||
Close();
|
||||
if (!mDestroyed) {
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ImageBridgeChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
mCanSend = false;
|
||||
mDestroyed = true;
|
||||
{
|
||||
MutexAutoLock lock(mContainerMapLock);
|
||||
mImageContainerListeners.Clear();
|
||||
|
|
@ -650,8 +653,6 @@ ImageBridgeChild::WillShutdown()
|
|||
|
||||
task.Wait();
|
||||
}
|
||||
|
||||
mDestroyed = true;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ std::map<base::ProcessId, ImageBridgeParent*> ImageBridgeParent::sImageBridges;
|
|||
|
||||
StaticAutoPtr<mozilla::Monitor> sImageBridgesLock;
|
||||
|
||||
static StaticRefPtr<ImageBridgeParent> sImageBridgeParentSingleton;
|
||||
|
||||
// defined in CompositorBridgeParent.cpp
|
||||
CompositorThreadHolder* GetCompositorThreadHolder();
|
||||
|
||||
|
|
@ -81,12 +83,6 @@ ImageBridgeParent::~ImageBridgeParent()
|
|||
{
|
||||
}
|
||||
|
||||
static StaticRefPtr<ImageBridgeParent> sImageBridgeParentSingleton;
|
||||
|
||||
void ReleaseImageBridgeParentSingleton() {
|
||||
sImageBridgeParentSingleton = nullptr;
|
||||
}
|
||||
|
||||
/* static */ ImageBridgeParent*
|
||||
ImageBridgeParent::CreateSameProcess()
|
||||
{
|
||||
|
|
@ -116,6 +112,36 @@ ImageBridgeParent::CreateForGPUProcess(Endpoint<PImageBridgeParent>&& aEndpoint)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
ImageBridgeParent::ShutdownInternal()
|
||||
{
|
||||
// We make a copy because we don't want to hold the lock while closing and we
|
||||
// don't want the object to get freed underneath us.
|
||||
nsTArray<RefPtr<ImageBridgeParent>> actors;
|
||||
{
|
||||
MonitorAutoLock lock(*sImageBridgesLock);
|
||||
for (const auto& iter : sImageBridges) {
|
||||
actors.AppendElement(iter.second);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto const& actor : actors) {
|
||||
MOZ_RELEASE_ASSERT(!actor->mClosed);
|
||||
actor->Close();
|
||||
}
|
||||
|
||||
sImageBridgeParentSingleton = nullptr;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
ImageBridgeParent::Shutdown()
|
||||
{
|
||||
CompositorThreadHolder::Loop()->PostTask(
|
||||
NS_NewRunnableFunction("ImageBridgeParent::Shutdown", []() -> void {
|
||||
ImageBridgeParent::ShutdownInternal();
|
||||
}));
|
||||
}
|
||||
|
||||
void
|
||||
ImageBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ public:
|
|||
static ImageBridgeParent* CreateSameProcess();
|
||||
static bool CreateForGPUProcess(Endpoint<PImageBridgeParent>&& aEndpoint);
|
||||
static bool CreateForContent(Endpoint<PImageBridgeParent>&& aEndpoint);
|
||||
static void Shutdown();
|
||||
|
||||
virtual ShmemAllocator* AsShmemAllocator() override { return this; }
|
||||
|
||||
|
|
@ -125,6 +126,8 @@ protected:
|
|||
void Bind(Endpoint<PImageBridgeParent>&& aEndpoint);
|
||||
|
||||
private:
|
||||
static void ShutdownInternal();
|
||||
|
||||
void DeferredDestroy();
|
||||
MessageLoop* mMessageLoop;
|
||||
// This keeps us alive until ActorDestroy(), at which point we do a
|
||||
|
|
|
|||
|
|
@ -125,48 +125,39 @@ MacIOSurfaceTextureHostOGL::CreateRenderTexture(const wr::ExternalImageId& aExte
|
|||
wr::RenderThread::Get()->RegisterExternalImage(wr::AsUint64(aExternalImageId), texture.forget());
|
||||
}
|
||||
|
||||
void
|
||||
MacIOSurfaceTextureHostOGL::GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
|
||||
const std::function<wr::ImageKey()>& aImageKeyAllocator)
|
||||
uint32_t
|
||||
MacIOSurfaceTextureHostOGL::NumSubTextures() const
|
||||
{
|
||||
MOZ_ASSERT(aImageKeys.IsEmpty());
|
||||
|
||||
switch (GetFormat()) {
|
||||
case gfx::SurfaceFormat::R8G8B8X8:
|
||||
case gfx::SurfaceFormat::R8G8B8A8:
|
||||
case gfx::SurfaceFormat::B8G8R8A8:
|
||||
case gfx::SurfaceFormat::B8G8R8X8: {
|
||||
// 1 image key
|
||||
aImageKeys.AppendElement(aImageKeyAllocator());
|
||||
MOZ_ASSERT(aImageKeys.Length() == 1);
|
||||
break;
|
||||
}
|
||||
case gfx::SurfaceFormat::B8G8R8X8:
|
||||
case gfx::SurfaceFormat::YUV422: {
|
||||
// 1 image key
|
||||
aImageKeys.AppendElement(aImageKeyAllocator());
|
||||
MOZ_ASSERT(aImageKeys.Length() == 1);
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
case gfx::SurfaceFormat::NV12: {
|
||||
// 2 image key
|
||||
aImageKeys.AppendElement(aImageKeyAllocator());
|
||||
aImageKeys.AppendElement(aImageKeyAllocator());
|
||||
MOZ_ASSERT(aImageKeys.Length() == 2);
|
||||
break;
|
||||
return 2;
|
||||
}
|
||||
default: {
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected format");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacIOSurfaceTextureHostOGL::AddWRImage(wr::ResourceUpdateQueue& aResources,
|
||||
Range<const wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID)
|
||||
MacIOSurfaceTextureHostOGL::PushResourceUpdates(wr::ResourceUpdateQueue& aResources,
|
||||
ResourceUpdateOp aOp,
|
||||
const Range<wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID)
|
||||
{
|
||||
MOZ_ASSERT(mSurface);
|
||||
|
||||
auto method = aOp == TextureHost::ADD_IMAGE ? &wr::ResourceUpdateQueue::AddExternalImage
|
||||
: &wr::ResourceUpdateQueue::UpdateExternalImage;
|
||||
auto bufferType = wr::WrExternalImageBufferType::TextureRectHandle;
|
||||
|
||||
switch (GetFormat()) {
|
||||
case gfx::SurfaceFormat::R8G8B8X8:
|
||||
case gfx::SurfaceFormat::R8G8B8A8:
|
||||
|
|
@ -175,11 +166,7 @@ MacIOSurfaceTextureHostOGL::AddWRImage(wr::ResourceUpdateQueue& aResources,
|
|||
MOZ_ASSERT(aImageKeys.length() == 1);
|
||||
MOZ_ASSERT(mSurface->GetPlaneCount() == 0);
|
||||
wr::ImageDescriptor descriptor(GetSize(), GetFormat());
|
||||
aResources.AddExternalImage(aImageKeys[0],
|
||||
descriptor,
|
||||
aExtID,
|
||||
wr::WrExternalImageBufferType::TextureRectHandle,
|
||||
0);
|
||||
(aResources.*method)(aImageKeys[0], descriptor, aExtID, bufferType, 0);
|
||||
break;
|
||||
}
|
||||
case gfx::SurfaceFormat::YUV422: {
|
||||
|
|
@ -190,11 +177,7 @@ MacIOSurfaceTextureHostOGL::AddWRImage(wr::ResourceUpdateQueue& aResources,
|
|||
MOZ_ASSERT(aImageKeys.length() == 1);
|
||||
MOZ_ASSERT(mSurface->GetPlaneCount() == 0);
|
||||
wr::ImageDescriptor descriptor(GetSize(), gfx::SurfaceFormat::R8G8B8X8);
|
||||
aResources.AddExternalImage(aImageKeys[0],
|
||||
descriptor,
|
||||
aExtID,
|
||||
wr::WrExternalImageBufferType::TextureRectHandle,
|
||||
0);
|
||||
(aResources.*method)(aImageKeys[0], descriptor, aExtID, bufferType, 0);
|
||||
break;
|
||||
}
|
||||
case gfx::SurfaceFormat::NV12: {
|
||||
|
|
@ -204,16 +187,8 @@ MacIOSurfaceTextureHostOGL::AddWRImage(wr::ResourceUpdateQueue& aResources,
|
|||
gfx::SurfaceFormat::A8);
|
||||
wr::ImageDescriptor descriptor1(gfx::IntSize(mSurface->GetDevicePixelWidth(1), mSurface->GetDevicePixelHeight(1)),
|
||||
gfx::SurfaceFormat::R8G8);
|
||||
aResources.AddExternalImage(aImageKeys[0],
|
||||
descriptor0,
|
||||
aExtID,
|
||||
wr::WrExternalImageBufferType::TextureRectHandle,
|
||||
0);
|
||||
aResources.AddExternalImage(aImageKeys[1],
|
||||
descriptor1,
|
||||
aExtID,
|
||||
wr::WrExternalImageBufferType::TextureRectHandle,
|
||||
1);
|
||||
(aResources.*method)(aImageKeys[0], descriptor0, aExtID, bufferType, 0);
|
||||
(aResources.*method)(aImageKeys[1], descriptor1, aExtID, bufferType, 1);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
|
@ -223,11 +198,11 @@ MacIOSurfaceTextureHostOGL::AddWRImage(wr::ResourceUpdateQueue& aResources,
|
|||
}
|
||||
|
||||
void
|
||||
MacIOSurfaceTextureHostOGL::PushExternalImage(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
Range<const wr::ImageKey>& aImageKeys)
|
||||
MacIOSurfaceTextureHostOGL::PushDisplayItems(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
const Range<wr::ImageKey>& aImageKeys)
|
||||
{
|
||||
switch (GetFormat()) {
|
||||
case gfx::SurfaceFormat::R8G8B8X8:
|
||||
|
|
|
|||
|
|
@ -64,18 +64,18 @@ public:
|
|||
|
||||
virtual void CreateRenderTexture(const wr::ExternalImageId& aExternalImageId) override;
|
||||
|
||||
virtual void GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
|
||||
const std::function<wr::ImageKey()>& aImageKeyAllocator) override;
|
||||
virtual uint32_t NumSubTextures() const override;
|
||||
|
||||
virtual void AddWRImage(wr::ResourceUpdateQueue& aResources,
|
||||
Range<const wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID) override;
|
||||
virtual void PushResourceUpdates(wr::ResourceUpdateQueue& aResources,
|
||||
ResourceUpdateOp aOp,
|
||||
const Range<wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID) override;
|
||||
|
||||
virtual void PushExternalImage(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
Range<const wr::ImageKey>& aImageKeys) override;
|
||||
virtual void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
const Range<wr::ImageKey>& aImageKeys) override;
|
||||
|
||||
protected:
|
||||
GLTextureSource* CreateTextureSourceForPlane(size_t aPlane);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include "mozilla/layers/WebRenderImageHost.h"
|
||||
#include "mozilla/layers/WebRenderTextureHost.h"
|
||||
#include "mozilla/webrender/WebRenderAPI.h"
|
||||
#include "mozilla/webrender/WebRenderTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
|
@ -42,29 +43,10 @@ void
|
|||
AsyncImagePipelineManager::Destroy()
|
||||
{
|
||||
MOZ_ASSERT(!mDestroyed);
|
||||
DeleteOldAsyncImages();
|
||||
mApi = nullptr;
|
||||
mDestroyed = true;
|
||||
}
|
||||
|
||||
bool
|
||||
AsyncImagePipelineManager::HasKeysToDelete()
|
||||
{
|
||||
return !mKeysToDelete.IsEmpty();
|
||||
}
|
||||
|
||||
void
|
||||
AsyncImagePipelineManager::DeleteOldAsyncImages()
|
||||
{
|
||||
MOZ_ASSERT(!mDestroyed);
|
||||
wr::ResourceUpdateQueue resources;
|
||||
for (wr::ImageKey key : mKeysToDelete) {
|
||||
resources.DeleteImage(key);
|
||||
}
|
||||
mApi->UpdateResources(resources);
|
||||
mKeysToDelete.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
AsyncImagePipelineManager::AddPipeline(const wr::PipelineId& aPipelineId)
|
||||
{
|
||||
|
|
@ -162,91 +144,108 @@ AsyncImagePipelineManager::UpdateAsyncImagePipeline(const wr::PipelineId& aPipel
|
|||
pipeline->mMixBlendMode = aMixBlendMode;
|
||||
}
|
||||
|
||||
bool
|
||||
AsyncImagePipelineManager::GenerateImageKeyForTextureHost(wr::ResourceUpdateQueue& aResources,
|
||||
TextureHost* aTexture,
|
||||
nsTArray<wr::ImageKey>& aKeys)
|
||||
Maybe<TextureHost::ResourceUpdateOp>
|
||||
AsyncImagePipelineManager::UpdateImageKeys(wr::ResourceUpdateQueue& aResources,
|
||||
AsyncImagePipeline* aPipeline,
|
||||
nsTArray<wr::ImageKey>& aKeys)
|
||||
{
|
||||
MOZ_ASSERT(aKeys.IsEmpty());
|
||||
MOZ_ASSERT(aTexture);
|
||||
|
||||
WebRenderTextureHost* wrTexture = aTexture->AsWebRenderTextureHost();
|
||||
|
||||
if (!gfxEnv::EnableWebRenderRecording() && wrTexture) {
|
||||
wrTexture->GetWRImageKeys(aKeys, std::bind(&AsyncImagePipelineManager::GenerateImageKey, this));
|
||||
MOZ_ASSERT(!aKeys.IsEmpty());
|
||||
Range<const wr::ImageKey> keys(&aKeys[0], aKeys.Length());
|
||||
wrTexture->AddWRImage(aResources, keys, wrTexture->GetExternalImageKey());
|
||||
return true;
|
||||
} else {
|
||||
RefPtr<gfx::DataSourceSurface> dSurf = aTexture->GetAsSurface();
|
||||
if (!dSurf) {
|
||||
NS_ERROR("TextureHost does not return DataSourceSurface");
|
||||
return false;
|
||||
}
|
||||
gfx::DataSourceSurface::MappedSurface map;
|
||||
if (!dSurf->Map(gfx::DataSourceSurface::MapType::READ, &map)) {
|
||||
NS_ERROR("DataSourceSurface failed to map");
|
||||
return false;
|
||||
}
|
||||
gfx::IntSize size = dSurf->GetSize();
|
||||
wr::Vec_u8 imgBytes;
|
||||
imgBytes.PushBytes(Range<uint8_t>(map.mData, size.height * map.mStride));
|
||||
wr::ImageDescriptor descriptor(size, map.mStride, dSurf->GetFormat());
|
||||
|
||||
wr::ImageKey key = GenerateImageKey();
|
||||
aKeys.AppendElement(key);
|
||||
aResources.AddImage(key, descriptor, imgBytes);
|
||||
dSurf->Unmap();
|
||||
MOZ_ASSERT(aPipeline);
|
||||
if (!aPipeline->mInitialised) {
|
||||
return Nothing();
|
||||
}
|
||||
return false;
|
||||
|
||||
TextureHost* texture = aPipeline->mImageHost->GetAsTextureHostForComposite();
|
||||
TextureHost* previousTexture = aPipeline->mCurrentTexture.get();
|
||||
|
||||
if (!aPipeline->mIsChanged && texture == previousTexture) {
|
||||
// The texture has not changed, just reuse previous ImageKeys.
|
||||
// No need to update DisplayList.
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
if (!texture) {
|
||||
// We don't have a new texture, there isn't much we can do.
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
aPipeline->mIsChanged = false;
|
||||
aPipeline->mCurrentTexture = texture;
|
||||
|
||||
WebRenderTextureHost* wrTexture = texture->AsWebRenderTextureHost();
|
||||
|
||||
bool useExternalImage = !gfxEnv::EnableWebRenderRecording() && wrTexture;
|
||||
aPipeline->mUseExternalImage = useExternalImage;
|
||||
|
||||
// The non-external image code path falls back to converting the texture into
|
||||
// an rgb image.
|
||||
auto numKeys = useExternalImage ? texture->NumSubTextures() : 1;
|
||||
|
||||
// If we already had a texture and the format hasn't changed, better to reuse the image keys
|
||||
// than create new ones.
|
||||
bool canUpdate = !!previousTexture
|
||||
&& previousTexture->GetFormat() == texture->GetFormat()
|
||||
&& aPipeline->mKeys.Length() == numKeys;
|
||||
|
||||
if (!canUpdate) {
|
||||
for (auto key : aPipeline->mKeys) {
|
||||
aResources.DeleteImage(key);
|
||||
}
|
||||
aPipeline->mKeys.Clear();
|
||||
for (uint32_t i = 0; i < numKeys; ++i) {
|
||||
aPipeline->mKeys.AppendElement(GenerateImageKey());
|
||||
}
|
||||
}
|
||||
|
||||
aKeys = aPipeline->mKeys;
|
||||
|
||||
auto op = canUpdate ? TextureHost::UPDATE_IMAGE : TextureHost::ADD_IMAGE;
|
||||
|
||||
if (!useExternalImage) {
|
||||
return UpdateWithoutExternalImage(aResources, texture, aKeys[0], op);
|
||||
}
|
||||
|
||||
Range<wr::ImageKey> keys(&aKeys[0], aKeys.Length());
|
||||
wrTexture->PushResourceUpdates(aResources, op, keys, wrTexture->GetExternalImageKey());
|
||||
|
||||
return Some(op);
|
||||
}
|
||||
|
||||
bool
|
||||
AsyncImagePipelineManager::UpdateImageKeys(wr::ResourceUpdateQueue& aResources,
|
||||
bool& aUseExternalImage,
|
||||
AsyncImagePipeline* aImageMgr,
|
||||
nsTArray<wr::ImageKey>& aKeys,
|
||||
nsTArray<wr::ImageKey>& aKeysToDelete)
|
||||
Maybe<TextureHost::ResourceUpdateOp>
|
||||
AsyncImagePipelineManager::UpdateWithoutExternalImage(wr::ResourceUpdateQueue& aResources,
|
||||
TextureHost* aTexture,
|
||||
wr::ImageKey aKey,
|
||||
TextureHost::ResourceUpdateOp aOp)
|
||||
{
|
||||
MOZ_ASSERT(aKeys.IsEmpty());
|
||||
MOZ_ASSERT(aImageMgr);
|
||||
TextureHost* texture = aImageMgr->mImageHost->GetAsTextureHostForComposite();
|
||||
MOZ_ASSERT(aTexture);
|
||||
|
||||
if (!aImageMgr->mInitialised) {
|
||||
return false;
|
||||
RefPtr<gfx::DataSourceSurface> dSurf = aTexture->GetAsSurface();
|
||||
if (!dSurf) {
|
||||
NS_ERROR("TextureHost does not return DataSourceSurface");
|
||||
return Nothing();
|
||||
}
|
||||
gfx::DataSourceSurface::MappedSurface map;
|
||||
if (!dSurf->Map(gfx::DataSourceSurface::MapType::READ, &map)) {
|
||||
NS_ERROR("DataSourceSurface failed to map");
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
// No change
|
||||
if (!aImageMgr->mIsChanged && texture == aImageMgr->mCurrentTexture) {
|
||||
// No need to update DisplayList.
|
||||
return false;
|
||||
gfx::IntSize size = dSurf->GetSize();
|
||||
wr::ImageDescriptor descriptor(size, map.mStride, dSurf->GetFormat());
|
||||
|
||||
// Costly copy right here...
|
||||
wr::Vec_u8 bytes;
|
||||
bytes.PushBytes(Range<uint8_t>(map.mData, size.height * map.mStride));
|
||||
|
||||
if (aOp == TextureHost::UPDATE_IMAGE) {
|
||||
aResources.UpdateImageBuffer(aKey, descriptor, bytes);
|
||||
} else {
|
||||
aResources.AddImage(aKey, descriptor, bytes);
|
||||
}
|
||||
|
||||
aImageMgr->mIsChanged = false;
|
||||
dSurf->Unmap();
|
||||
|
||||
if (texture == aImageMgr->mCurrentTexture) {
|
||||
// Reuse previous ImageKeys.
|
||||
aKeys.AppendElements(aImageMgr->mKeys);
|
||||
aUseExternalImage = aImageMgr->mUseExternalImage;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Delete old ImageKeys
|
||||
aKeysToDelete.AppendElements(aImageMgr->mKeys);
|
||||
aImageMgr->mKeys.Clear();
|
||||
aImageMgr->mCurrentTexture = nullptr;
|
||||
|
||||
// No txture to render
|
||||
if (!texture) {
|
||||
return true;
|
||||
}
|
||||
|
||||
aUseExternalImage = aImageMgr->mUseExternalImage = GenerateImageKeyForTextureHost(aResources, texture, aKeys);
|
||||
MOZ_ASSERT(!aKeys.IsEmpty());
|
||||
aImageMgr->mKeys.AppendElements(aKeys);
|
||||
aImageMgr->mCurrentTexture = texture;
|
||||
return true;
|
||||
return Some(aOp);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -258,67 +257,66 @@ AsyncImagePipelineManager::ApplyAsyncImages()
|
|||
|
||||
++mAsyncImageEpoch; // Update webrender epoch
|
||||
wr::Epoch epoch = wr::NewEpoch(mAsyncImageEpoch);
|
||||
nsTArray<wr::ImageKey> keysToDelete;
|
||||
|
||||
wr::ResourceUpdateQueue resourceUpdates;
|
||||
|
||||
// We use a pipeline with a very small display list for each video element.
|
||||
// Update each of them if needed.
|
||||
for (auto iter = mAsyncImagePipelines.Iter(); !iter.Done(); iter.Next()) {
|
||||
wr::ResourceUpdateQueue resourceUpdates;
|
||||
wr::PipelineId pipelineId = wr::AsPipelineId(iter.Key());
|
||||
AsyncImagePipeline* pipeline = iter.Data();
|
||||
|
||||
nsTArray<wr::ImageKey> keys;
|
||||
bool useExternalImage = false;
|
||||
bool updateDisplayList = UpdateImageKeys(resourceUpdates,
|
||||
useExternalImage,
|
||||
pipeline,
|
||||
keys,
|
||||
keysToDelete);
|
||||
if (!updateDisplayList) {
|
||||
auto op = UpdateImageKeys(resourceUpdates, pipeline, keys);
|
||||
|
||||
if (op != Some(TextureHost::ADD_IMAGE)) {
|
||||
// We don't need to update the display list, either because we can't or because
|
||||
// the previous one is still up to date.
|
||||
// We may, however, have updated some resources.
|
||||
mApi->UpdateResources(resourceUpdates);
|
||||
continue;
|
||||
}
|
||||
|
||||
wr::LayoutSize contentSize { pipeline->mScBounds.Width(), pipeline->mScBounds.Height() };
|
||||
wr::DisplayListBuilder builder(pipelineId, contentSize);
|
||||
|
||||
if (!keys.IsEmpty()) {
|
||||
MOZ_ASSERT(pipeline->mCurrentTexture.get());
|
||||
MOZ_ASSERT(!keys.IsEmpty());
|
||||
MOZ_ASSERT(pipeline->mCurrentTexture.get());
|
||||
|
||||
float opacity = 1.0f;
|
||||
builder.PushStackingContext(wr::ToLayoutRect(pipeline->mScBounds),
|
||||
0,
|
||||
&opacity,
|
||||
pipeline->mScTransform.IsIdentity() ? nullptr : &pipeline->mScTransform,
|
||||
wr::TransformStyle::Flat,
|
||||
nullptr,
|
||||
pipeline->mMixBlendMode,
|
||||
nsTArray<wr::WrFilterOp>(),
|
||||
true);
|
||||
float opacity = 1.0f;
|
||||
builder.PushStackingContext(wr::ToLayoutRect(pipeline->mScBounds),
|
||||
0,
|
||||
&opacity,
|
||||
pipeline->mScTransform.IsIdentity() ? nullptr : &pipeline->mScTransform,
|
||||
wr::TransformStyle::Flat,
|
||||
nullptr,
|
||||
pipeline->mMixBlendMode,
|
||||
nsTArray<wr::WrFilterOp>(),
|
||||
true);
|
||||
|
||||
LayerRect rect(0, 0, pipeline->mCurrentTexture->GetSize().width, pipeline->mCurrentTexture->GetSize().height);
|
||||
if (pipeline->mScaleToSize.isSome()) {
|
||||
rect = LayerRect(0, 0, pipeline->mScaleToSize.value().width, pipeline->mScaleToSize.value().height);
|
||||
}
|
||||
|
||||
if (useExternalImage) {
|
||||
MOZ_ASSERT(pipeline->mCurrentTexture->AsWebRenderTextureHost());
|
||||
Range<const wr::ImageKey> range_keys(&keys[0], keys.Length());
|
||||
pipeline->mCurrentTexture->PushExternalImage(builder,
|
||||
wr::ToLayoutRect(rect),
|
||||
wr::ToLayoutRect(rect),
|
||||
pipeline->mFilter,
|
||||
range_keys);
|
||||
HoldExternalImage(pipelineId, epoch, pipeline->mCurrentTexture->AsWebRenderTextureHost());
|
||||
} else {
|
||||
MOZ_ASSERT(keys.Length() == 1);
|
||||
builder.PushImage(wr::ToLayoutRect(rect),
|
||||
wr::ToLayoutRect(rect),
|
||||
true,
|
||||
pipeline->mFilter,
|
||||
keys[0]);
|
||||
}
|
||||
builder.PopStackingContext();
|
||||
LayerRect rect(0, 0, pipeline->mCurrentTexture->GetSize().width, pipeline->mCurrentTexture->GetSize().height);
|
||||
if (pipeline->mScaleToSize.isSome()) {
|
||||
rect = LayerRect(0, 0, pipeline->mScaleToSize.value().width, pipeline->mScaleToSize.value().height);
|
||||
}
|
||||
|
||||
if (pipeline->mUseExternalImage) {
|
||||
MOZ_ASSERT(pipeline->mCurrentTexture->AsWebRenderTextureHost());
|
||||
Range<wr::ImageKey> range_keys(&keys[0], keys.Length());
|
||||
pipeline->mCurrentTexture->PushDisplayItems(builder,
|
||||
wr::ToLayoutRect(rect),
|
||||
wr::ToLayoutRect(rect),
|
||||
pipeline->mFilter,
|
||||
range_keys);
|
||||
HoldExternalImage(pipelineId, epoch, pipeline->mCurrentTexture->AsWebRenderTextureHost());
|
||||
} else {
|
||||
MOZ_ASSERT(keys.Length() == 1);
|
||||
builder.PushImage(wr::ToLayoutRect(rect),
|
||||
wr::ToLayoutRect(rect),
|
||||
true,
|
||||
pipeline->mFilter,
|
||||
keys[0]);
|
||||
}
|
||||
builder.PopStackingContext();
|
||||
|
||||
wr::BuiltDisplayList dl;
|
||||
wr::LayoutSize builderContentSize;
|
||||
builder.Finalize(builderContentSize, dl);
|
||||
|
|
@ -327,8 +325,6 @@ AsyncImagePipelineManager::ApplyAsyncImages()
|
|||
dl.dl_desc, dl.dl.inner.data, dl.dl.inner.length,
|
||||
resourceUpdates);
|
||||
}
|
||||
DeleteOldAsyncImages();
|
||||
mKeysToDelete.SwapElements(keysToDelete);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ protected:
|
|||
|
||||
public:
|
||||
void Destroy();
|
||||
bool HasKeysToDelete();
|
||||
|
||||
void AddPipeline(const wr::PipelineId& aPipelineId);
|
||||
void RemovePipeline(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch);
|
||||
|
|
@ -92,7 +91,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
void DeleteOldAsyncImages();
|
||||
|
||||
uint32_t GetNextResourceId() { return ++mResourceId; }
|
||||
wr::IdNamespace GetNamespace() { return mIdNamespace; }
|
||||
|
|
@ -103,9 +101,6 @@ private:
|
|||
key.mHandle = GetNextResourceId();
|
||||
return key;
|
||||
}
|
||||
bool GenerateImageKeyForTextureHost(wr::ResourceUpdateQueue& aResources,
|
||||
TextureHost* aTexture,
|
||||
nsTArray<wr::ImageKey>& aKeys);
|
||||
|
||||
struct ForwardingTextureHost {
|
||||
ForwardingTextureHost(const wr::Epoch& aEpoch, TextureHost* aTexture)
|
||||
|
|
@ -138,11 +133,15 @@ private:
|
|||
nsTArray<wr::ImageKey> mKeys;
|
||||
};
|
||||
|
||||
bool UpdateImageKeys(wr::ResourceUpdateQueue& aResourceUpdates,
|
||||
bool& aUseExternalImage,
|
||||
AsyncImagePipeline* aImageMgr,
|
||||
nsTArray<wr::ImageKey>& aKeys,
|
||||
nsTArray<wr::ImageKey>& aKeysToDelete);
|
||||
Maybe<TextureHost::ResourceUpdateOp>
|
||||
UpdateImageKeys(wr::ResourceUpdateQueue& aResourceUpdates,
|
||||
AsyncImagePipeline* aPipeline,
|
||||
nsTArray<wr::ImageKey>& aKeys);
|
||||
Maybe<TextureHost::ResourceUpdateOp>
|
||||
UpdateWithoutExternalImage(wr::ResourceUpdateQueue& aResources,
|
||||
TextureHost* aTexture,
|
||||
wr::ImageKey aKey,
|
||||
TextureHost::ResourceUpdateOp);
|
||||
|
||||
RefPtr<wr::WebRenderAPI> mApi;
|
||||
wr::IdNamespace mIdNamespace;
|
||||
|
|
@ -151,7 +150,6 @@ private:
|
|||
nsClassHashtable<nsUint64HashKey, PipelineTexturesHolder> mPipelineTexturesHolders;
|
||||
nsClassHashtable<nsUint64HashKey, AsyncImagePipeline> mAsyncImagePipelines;
|
||||
uint32_t mAsyncImageEpoch;
|
||||
nsTArray<wr::ImageKey> mKeysToDelete;
|
||||
bool mDestroyed;
|
||||
|
||||
// Render time for the current composition.
|
||||
|
|
|
|||
|
|
@ -334,7 +334,7 @@ bool
|
|||
WebRenderBridgeParent::AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey aKey,
|
||||
wr::ResourceUpdateQueue& aResources)
|
||||
{
|
||||
Range<const wr::ImageKey> keys(&aKey, 1);
|
||||
Range<wr::ImageKey> keys(&aKey, 1);
|
||||
// Check if key is obsoleted.
|
||||
if (keys[0].mNamespace != mIdNamespace) {
|
||||
return true;
|
||||
|
|
@ -354,7 +354,8 @@ WebRenderBridgeParent::AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey
|
|||
}
|
||||
WebRenderTextureHost* wrTexture = texture->AsWebRenderTextureHost();
|
||||
if (wrTexture) {
|
||||
wrTexture->AddWRImage(aResources, keys, wrTexture->GetExternalImageKey());
|
||||
wrTexture->PushResourceUpdates(aResources, TextureHost::ADD_IMAGE, keys,
|
||||
wrTexture->GetExternalImageKey());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,16 +24,6 @@ void
|
|||
WebRenderCanvasRenderer::Initialize(const CanvasInitializeData& aData)
|
||||
{
|
||||
ShareableCanvasRenderer::Initialize(aData);
|
||||
|
||||
// XXX: Use basic surface factory until we support shared surface.
|
||||
if (!mGLContext || mGLFrontbuffer)
|
||||
return;
|
||||
|
||||
gl::GLScreenBuffer* screen = mGLContext->Screen();
|
||||
auto factory = MakeUnique<gl::SurfaceFactory_Basic>(mGLContext,
|
||||
screen->mCaps,
|
||||
mFlags);
|
||||
screen->Morph(Move(factory));
|
||||
}
|
||||
|
||||
WebRenderCanvasRendererSync::~WebRenderCanvasRendererSync()
|
||||
|
|
|
|||
|
|
@ -134,38 +134,36 @@ WebRenderTextureHost::GetRGBStride()
|
|||
return ImageDataSerializer::ComputeRGBStride(format, GetSize().width);
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderTextureHost::GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
|
||||
const std::function<wr::ImageKey()>& aImageKeyAllocator)
|
||||
uint32_t
|
||||
WebRenderTextureHost::NumSubTextures() const
|
||||
{
|
||||
MOZ_ASSERT(mWrappedTextureHost);
|
||||
MOZ_ASSERT(aImageKeys.IsEmpty());
|
||||
|
||||
mWrappedTextureHost->GetWRImageKeys(aImageKeys, aImageKeyAllocator);
|
||||
return mWrappedTextureHost->NumSubTextures();
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderTextureHost::AddWRImage(wr::ResourceUpdateQueue& aResources,
|
||||
Range<const wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID)
|
||||
WebRenderTextureHost::PushResourceUpdates(wr::ResourceUpdateQueue& aResources,
|
||||
ResourceUpdateOp aOp,
|
||||
const Range<wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID)
|
||||
{
|
||||
MOZ_ASSERT(mWrappedTextureHost);
|
||||
MOZ_ASSERT(mExternalImageId == aExtID);
|
||||
|
||||
mWrappedTextureHost->AddWRImage(aResources, aImageKeys, aExtID);
|
||||
mWrappedTextureHost->PushResourceUpdates(aResources, aOp, aImageKeys, aExtID);
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderTextureHost::PushExternalImage(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
Range<const wr::ImageKey>& aImageKeys)
|
||||
WebRenderTextureHost::PushDisplayItems(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
const Range<wr::ImageKey>& aImageKeys)
|
||||
{
|
||||
MOZ_ASSERT(mWrappedTextureHost);
|
||||
MOZ_ASSERT(aImageKeys.length() > 0);
|
||||
|
||||
mWrappedTextureHost->PushExternalImage(aBuilder,
|
||||
mWrappedTextureHost->PushDisplayItems(aBuilder,
|
||||
aBounds,
|
||||
aClip,
|
||||
aFilter,
|
||||
|
|
|
|||
|
|
@ -63,18 +63,18 @@ public:
|
|||
|
||||
int32_t GetRGBStride();
|
||||
|
||||
virtual void GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
|
||||
const std::function<wr::ImageKey()>& aImageKeyAllocator) override;
|
||||
virtual uint32_t NumSubTextures() const override;
|
||||
|
||||
virtual void AddWRImage(wr::ResourceUpdateQueue& aResources,
|
||||
Range<const wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID) override;
|
||||
virtual void PushResourceUpdates(wr::ResourceUpdateQueue& aResources,
|
||||
ResourceUpdateOp aOp,
|
||||
const Range<wr::ImageKey>& aImageKeys,
|
||||
const wr::ExternalImageId& aExtID) override;
|
||||
|
||||
virtual void PushExternalImage(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
Range<const wr::ImageKey>& aImageKeys) override;
|
||||
virtual void PushDisplayItems(wr::DisplayListBuilder& aBuilder,
|
||||
const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutRect& aClip,
|
||||
wr::ImageRendering aFilter,
|
||||
const Range<wr::ImageKey>& aImageKeys) override;
|
||||
|
||||
protected:
|
||||
void CreateRenderTextureHost(const SurfaceDescriptor& aDesc, TextureHost* aTexture);
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ nsIconChannel::AsyncOpen(nsIStreamListener* aListener,
|
|||
nsCOMPtr<nsIEventTarget> target =
|
||||
nsContentUtils::GetEventTargetByLoadInfo(mLoadInfo,
|
||||
mozilla::TaskCategory::Other);
|
||||
rv = mPump->Init(inStream, int64_t(-1), int64_t(-1), 0, 0, false, target);
|
||||
rv = mPump->Init(inStream, 0, 0, false, target);
|
||||
if (NS_FAILED(rv)) {
|
||||
mCallbacks = nullptr;
|
||||
return rv;
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ nsIconChannel::AsyncOpen(nsIStreamListener* aListener,
|
|||
nsCOMPtr<nsIEventTarget> target =
|
||||
nsContentUtils::GetEventTargetByLoadInfo(mLoadInfo,
|
||||
mozilla::TaskCategory::Other);
|
||||
rv = mPump->Init(inStream, int64_t(-1), int64_t(-1), 0, 0, false, target);
|
||||
rv = mPump->Init(inStream, 0, 0, false, target);
|
||||
if (NS_FAILED(rv)) {
|
||||
mCallbacks = nullptr;
|
||||
return rv;
|
||||
|
|
|
|||
|
|
@ -628,14 +628,15 @@ BackgroundChildImpl::RecvDispatchLocalStorageChange(
|
|||
}
|
||||
|
||||
bool
|
||||
BackgroundChildImpl::GetMessageSchedulerGroups(const Message& aMsg, nsTArray<RefPtr<SchedulerGroup>>& aGroups)
|
||||
BackgroundChildImpl::GetMessageSchedulerGroups(const Message& aMsg, SchedulerGroupSet& aGroups)
|
||||
{
|
||||
if (aMsg.type() == layout::PVsync::MessageType::Msg_Notify__ID) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
aGroups.Clear();
|
||||
if (dom::TabChild::HasActiveTabs()) {
|
||||
for (dom::TabChild* tabChild : dom::TabChild::GetActiveTabs()) {
|
||||
aGroups.AppendElement(tabChild->TabGroup());
|
||||
for (auto iter = dom::TabChild::GetActiveTabs().ConstIter();
|
||||
!iter.Done(); iter.Next()) {
|
||||
aGroups.Put(iter.Get()->GetKey()->TabGroup());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ protected:
|
|||
const bool& aIsPrivate) override;
|
||||
|
||||
bool
|
||||
GetMessageSchedulerGroups(const Message& aMsg, nsTArray<RefPtr<SchedulerGroup>>& aGroups) override;
|
||||
GetMessageSchedulerGroups(const Message& aMsg, SchedulerGroupSet& aGroups) override;
|
||||
};
|
||||
|
||||
class BackgroundChildImpl::ThreadLocal final
|
||||
|
|
|
|||
|
|
@ -1018,7 +1018,7 @@ MessageChannel::SendBuildID()
|
|||
MonitorAutoLock lock(*mMonitor);
|
||||
if (!Connected()) {
|
||||
ReportConnectionError("MessageChannel", msg);
|
||||
MOZ_CRASH();
|
||||
return;
|
||||
}
|
||||
mLink->SendMessage(msg.forget());
|
||||
}
|
||||
|
|
@ -2002,7 +2002,7 @@ MessageChannel::MessageTask::GetPriority(uint32_t* aPriority)
|
|||
}
|
||||
|
||||
bool
|
||||
MessageChannel::MessageTask::GetAffectedSchedulerGroups(nsTArray<RefPtr<SchedulerGroup>>& aGroups)
|
||||
MessageChannel::MessageTask::GetAffectedSchedulerGroups(SchedulerGroupSet& aGroups)
|
||||
{
|
||||
if (!mChannel) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -564,7 +564,7 @@ class MessageChannel : HasResultCodes, MessageLoop::DestructionObserver
|
|||
Message& Msg() { return mMessage; }
|
||||
const Message& Msg() const { return mMessage; }
|
||||
|
||||
bool GetAffectedSchedulerGroups(nsTArray<RefPtr<SchedulerGroup>>& aGroups) override;
|
||||
bool GetAffectedSchedulerGroups(SchedulerGroupSet& aGroups) override;
|
||||
|
||||
private:
|
||||
MessageTask() = delete;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "mozilla/NotNull.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "nsILabelableRunnable.h"
|
||||
|
||||
#if defined(ANDROID) && defined(DEBUG)
|
||||
#include <android/log.h>
|
||||
|
|
@ -268,6 +269,8 @@ protected:
|
|||
~IToplevelProtocol();
|
||||
|
||||
public:
|
||||
using SchedulerGroupSet = nsILabelableRunnable::SchedulerGroupSet;
|
||||
|
||||
void SetTransport(UniquePtr<Transport> aTrans)
|
||||
{
|
||||
mTrans = Move(aTrans);
|
||||
|
|
@ -388,7 +391,7 @@ public:
|
|||
// when it's difficult to determine an EventTarget ahead of time. See the
|
||||
// comment in nsILabelableRunnable.h for more information.
|
||||
virtual bool
|
||||
GetMessageSchedulerGroups(const Message& aMsg, nsTArray<RefPtr<SchedulerGroup>>& aGroups)
|
||||
GetMessageSchedulerGroups(const Message& aMsg, SchedulerGroupSet& aGroups)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ struct GCPointerPolicy
|
|||
return false;
|
||||
}
|
||||
static bool isValid(T v) {
|
||||
return js::gc::IsCellPointerValid(v);
|
||||
return js::gc::IsCellPointerValidOrNull(v);
|
||||
}
|
||||
};
|
||||
template <> struct GCPolicy<JS::Symbol*> : public GCPointerPolicy<JS::Symbol*> {};
|
||||
|
|
|
|||
|
|
@ -406,8 +406,6 @@ IsInsideNursery(const js::gc::Cell* cell)
|
|||
MOZ_ALWAYS_INLINE bool
|
||||
IsCellPointerValid(const void* cell)
|
||||
{
|
||||
if (!cell)
|
||||
return true;
|
||||
auto addr = uintptr_t(cell);
|
||||
if (addr < ChunkSize || addr % CellAlignBytes != 0)
|
||||
return false;
|
||||
|
|
@ -419,6 +417,14 @@ IsCellPointerValid(const void* cell)
|
|||
return false;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
IsCellPointerValidOrNull(const void* cell)
|
||||
{
|
||||
if (!cell)
|
||||
return true;
|
||||
return IsCellPointerValid(cell);
|
||||
}
|
||||
|
||||
} /* namespace gc */
|
||||
} /* namespace js */
|
||||
|
||||
|
|
|
|||
|
|
@ -402,7 +402,7 @@ class TenuredHeap : public js::HeapBase<T, TenuredHeap<T>>
|
|||
|
||||
void setPtr(T newPtr) {
|
||||
MOZ_ASSERT((reinterpret_cast<uintptr_t>(newPtr) & flagsMask) == 0);
|
||||
MOZ_ASSERT(js::gc::IsCellPointerValid(newPtr));
|
||||
MOZ_ASSERT(js::gc::IsCellPointerValidOrNull(newPtr));
|
||||
if (newPtr)
|
||||
AssertGCThingMustBeTenured(newPtr);
|
||||
bits = (bits & flagsMask) | reinterpret_cast<uintptr_t>(newPtr);
|
||||
|
|
|
|||
|
|
@ -317,9 +317,8 @@ function ModuleInstantiate()
|
|||
if (stack.length === 0 &&
|
||||
typeof(UnsafeGetReservedSlot(module, MODULE_OBJECT_ERROR_SLOT)) === "undefined")
|
||||
{
|
||||
// This can happen due to OOM when appending to the stack.
|
||||
assert(error === "out of memory",
|
||||
"Stack must contain module unless we hit OOM");
|
||||
// This can happen due to OOM when appending to the stack or
|
||||
// over-recursion errors.
|
||||
RecordModuleError(module, error);
|
||||
}
|
||||
|
||||
|
|
@ -542,9 +541,8 @@ function ModuleEvaluate()
|
|||
if (stack.length === 0 &&
|
||||
typeof(UnsafeGetReservedSlot(module, MODULE_OBJECT_ERROR_SLOT)) === "undefined")
|
||||
{
|
||||
// This can happen due to OOM when appending to the stack.
|
||||
assert(error === "out of memory",
|
||||
"Stack must contain module unless we hit OOM");
|
||||
// This can happen due to OOM when appending to the stack or
|
||||
// over-recursion errors.
|
||||
RecordModuleError(module, error);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "builtin/ModuleObject.h"
|
||||
|
||||
#include "mozilla/EnumSet.h"
|
||||
|
||||
#include "builtin/SelfHostingDefines.h"
|
||||
#include "frontend/ParseNode.h"
|
||||
#include "frontend/SharedContext.h"
|
||||
|
|
@ -889,29 +891,41 @@ ModuleObject::Freeze(JSContext* cx, HandleModuleObject self)
|
|||
#ifdef DEBUG
|
||||
|
||||
static inline bool
|
||||
IsObjectFrozen(JSContext* cx, HandleObject obj)
|
||||
CheckObjectFrozen(JSContext* cx, HandleObject obj, bool* result)
|
||||
{
|
||||
bool frozen = false;
|
||||
MOZ_ALWAYS_TRUE(TestIntegrityLevel(cx, obj, IntegrityLevel::Frozen, &frozen));
|
||||
return frozen;
|
||||
return TestIntegrityLevel(cx, obj, IntegrityLevel::Frozen, result);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsObjectPropertyFrozen(JSContext* cx, HandleNativeObject obj, uint32_t slot)
|
||||
CheckObjectPropertyFrozen(JSContext* cx, HandleNativeObject obj, uint32_t slot, bool* result)
|
||||
{
|
||||
RootedObject property(cx, &obj->getSlot(slot).toObject());
|
||||
return IsObjectFrozen(cx, property);
|
||||
return CheckObjectFrozen(cx, property, result);
|
||||
}
|
||||
|
||||
/* static */ inline bool
|
||||
ModuleObject::IsFrozen(JSContext* cx, HandleModuleObject self)
|
||||
ModuleObject::AssertFrozen(JSContext* cx, HandleModuleObject self)
|
||||
{
|
||||
return IsObjectPropertyFrozen(cx, self, RequestedModulesSlot) &&
|
||||
IsObjectPropertyFrozen(cx, self, ImportEntriesSlot) &&
|
||||
IsObjectPropertyFrozen(cx, self, LocalExportEntriesSlot) &&
|
||||
IsObjectPropertyFrozen(cx, self, IndirectExportEntriesSlot) &&
|
||||
IsObjectPropertyFrozen(cx, self, StarExportEntriesSlot) &&
|
||||
IsObjectFrozen(cx, self);
|
||||
static const mozilla::EnumSet<ModuleSlot> slotsToCheck = {
|
||||
RequestedModulesSlot,
|
||||
ImportEntriesSlot,
|
||||
LocalExportEntriesSlot,
|
||||
IndirectExportEntriesSlot,
|
||||
StarExportEntriesSlot
|
||||
};
|
||||
|
||||
bool frozen = false;
|
||||
for (auto slot : slotsToCheck) {
|
||||
if (!CheckObjectPropertyFrozen(cx, self, slot, &frozen))
|
||||
return false;
|
||||
MOZ_ASSERT(frozen);
|
||||
}
|
||||
|
||||
if (!CheckObjectFrozen(cx, self, &frozen))
|
||||
return false;
|
||||
MOZ_ASSERT(frozen);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1034,7 +1048,10 @@ ModuleObject::noteFunctionDeclaration(JSContext* cx, HandleAtom name, HandleFunc
|
|||
/* static */ bool
|
||||
ModuleObject::instantiateFunctionDeclarations(JSContext* cx, HandleModuleObject self)
|
||||
{
|
||||
MOZ_ASSERT(IsFrozen(cx, self));
|
||||
#ifdef DEBUG
|
||||
if (!AssertFrozen(cx, self))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
FunctionDeclarationVector* funDecls = self->functionDeclarations();
|
||||
if (!funDecls) {
|
||||
|
|
@ -1061,6 +1078,9 @@ ModuleObject::instantiateFunctionDeclarations(JSContext* cx, HandleModuleObject
|
|||
}
|
||||
}
|
||||
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
value = ObjectValue(*obj);
|
||||
if (!SetProperty(cx, env, funDecl.name->asPropertyName(), value))
|
||||
return false;
|
||||
|
|
@ -1074,7 +1094,10 @@ ModuleObject::instantiateFunctionDeclarations(JSContext* cx, HandleModuleObject
|
|||
/* static */ bool
|
||||
ModuleObject::execute(JSContext* cx, HandleModuleObject self, MutableHandleValue rval)
|
||||
{
|
||||
MOZ_ASSERT(IsFrozen(cx, self));
|
||||
#ifdef DEBUG
|
||||
if (!AssertFrozen(cx, self))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
RootedScript script(cx, self->script());
|
||||
RootedModuleEnvironmentObject scope(cx, self->environment());
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ using ModuleStatus = int32_t;
|
|||
class ModuleObject : public NativeObject
|
||||
{
|
||||
public:
|
||||
enum
|
||||
enum ModuleSlot
|
||||
{
|
||||
ScriptSlot = 0,
|
||||
InitialEnvironmentSlot,
|
||||
|
|
@ -284,7 +284,7 @@ class ModuleObject : public NativeObject
|
|||
HandleArrayObject starExportEntries);
|
||||
static bool Freeze(JSContext* cx, HandleModuleObject self);
|
||||
#ifdef DEBUG
|
||||
static bool IsFrozen(JSContext* cx, HandleModuleObject self);
|
||||
static bool AssertFrozen(JSContext* cx, HandleModuleObject self);
|
||||
#endif
|
||||
void fixEnvironmentsAfterCompartmentMerge();
|
||||
|
||||
|
|
|
|||
|
|
@ -6120,7 +6120,7 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsOb
|
|||
nameChars.twoByteChars(), name->length(),
|
||||
JS_DATA_TO_FUNC_PTR(JSNative, getterObj.get()),
|
||||
JS_DATA_TO_FUNC_PTR(JSNative, setterObj.get()),
|
||||
JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_GETTER | JSPROP_SETTER))
|
||||
JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_GETTER | JSPROP_SETTER))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ struct InternalGCPointerPolicy {
|
|||
TraceManuallyBarrieredEdge(trc, vp, name);
|
||||
}
|
||||
static bool isValid(T v) {
|
||||
return gc::IsCellPointerValid(v);
|
||||
return gc::IsCellPointerValidOrNull(v);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ ZoneGroup::enter(JSContext* cx)
|
|||
if (ownerContext().context() == cx) {
|
||||
MOZ_ASSERT(enterCount);
|
||||
} else {
|
||||
if (useExclusiveLocking) {
|
||||
if (useExclusiveLocking()) {
|
||||
MOZ_ASSERT(!usedByHelperThread());
|
||||
while (ownerContext().context() != nullptr) {
|
||||
cx->yieldToEmbedding();
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class ZoneGroup
|
|||
|
||||
// If this flag is true, then we may need to block before entering this zone
|
||||
// group. Blocking happens using JSContext::yieldToEmbedding.
|
||||
UnprotectedData<bool> useExclusiveLocking;
|
||||
UnprotectedData<bool> useExclusiveLocking_;
|
||||
|
||||
public:
|
||||
CooperatingContext& ownerContext() { return ownerContext_.ref(); }
|
||||
|
|
@ -102,8 +102,9 @@ class ZoneGroup
|
|||
inline bool isCollecting();
|
||||
inline bool isGCScheduled();
|
||||
|
||||
// See the useExclusiveLocking field above.
|
||||
void setUseExclusiveLocking() { useExclusiveLocking = true; }
|
||||
// See the useExclusiveLocking_ field above.
|
||||
void setUseExclusiveLocking() { useExclusiveLocking_ = true; }
|
||||
bool useExclusiveLocking() { return useExclusiveLocking_; }
|
||||
|
||||
// Delete an empty zone after its contents have been merged.
|
||||
void deleteEmptyZone(Zone* zone);
|
||||
|
|
|
|||
7
js/src/jit-test/tests/modules/bug-1402535.js
Normal file
7
js/src/jit-test/tests/modules/bug-1402535.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
if (!('stackTest' in this))
|
||||
quit();
|
||||
|
||||
stackTest(function() {
|
||||
let m = parseModule(``);
|
||||
m.declarationInstantiation();
|
||||
});
|
||||
15
js/src/jit-test/tests/modules/bug-1402649.js
Normal file
15
js/src/jit-test/tests/modules/bug-1402649.js
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
if (!('oomTest' in this))
|
||||
quit();
|
||||
|
||||
loadFile(`
|
||||
function parseAndEvaluate(source) {
|
||||
let m = parseModule(source);
|
||||
m.declarationInstantiation();
|
||||
}
|
||||
parseAndEvaluate("async function a() { await 2 + 3; }")
|
||||
`);
|
||||
function loadFile(lfVarx) {
|
||||
oomTest(function() {
|
||||
eval(lfVarx);
|
||||
});
|
||||
}
|
||||
|
|
@ -36,12 +36,12 @@ BEGIN_TEST(testDefineGetterSetterNonEnumerable)
|
|||
CHECK(JS_DefineProperty(cx, vObject, PROPERTY_NAME,
|
||||
JS_DATA_TO_FUNC_PTR(JSNative, (JSObject*) funGetObj),
|
||||
JS_DATA_TO_FUNC_PTR(JSNative, (JSObject*) funSetObj),
|
||||
JSPROP_GETTER | JSPROP_SETTER | JSPROP_SHARED | JSPROP_ENUMERATE));
|
||||
JSPROP_GETTER | JSPROP_SETTER | JSPROP_ENUMERATE));
|
||||
|
||||
CHECK(JS_DefineProperty(cx, vObject, PROPERTY_NAME,
|
||||
JS_DATA_TO_FUNC_PTR(JSNative, (JSObject*) funGetObj),
|
||||
JS_DATA_TO_FUNC_PTR(JSNative, (JSObject*) funSetObj),
|
||||
JSPROP_GETTER | JSPROP_SETTER | JSPROP_SHARED | JSPROP_PERMANENT));
|
||||
JSPROP_GETTER | JSPROP_SETTER | JSPROP_PERMANENT));
|
||||
|
||||
JS::Rooted<JS::PropertyDescriptor> desc(cx);
|
||||
CHECK(JS_GetOwnPropertyDescriptor(cx, vObject, PROPERTY_NAME, &desc));
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ BEGIN_TEST(testDefineProperty_bug564344)
|
|||
|
||||
JS::RootedObject obj(cx, x.toObjectOrNull());
|
||||
for (int i = 0; i < 2; i++)
|
||||
CHECK(JS_DefineProperty(cx, obj, "q", JS::UndefinedHandleValue, JSPROP_SHARED));
|
||||
CHECK(JS_DefineProperty(cx, obj, "q", JS::UndefinedHandleValue, 0));
|
||||
return true;
|
||||
}
|
||||
END_TEST(testDefineProperty_bug564344)
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ BEGIN_TEST(testDefinePropertyIgnoredAttributes)
|
|||
// aren't passing it.
|
||||
CHECK(JS_DefineProperty(cx, obj, "foo",
|
||||
Getter, nullptr,
|
||||
JSPROP_IGNORE_ENUMERATE | JSPROP_IGNORE_PERMANENT | JSPROP_SHARED));
|
||||
JSPROP_IGNORE_ENUMERATE | JSPROP_IGNORE_PERMANENT));
|
||||
|
||||
CHECK(JS_GetOwnPropertyDescriptor(cx, obj, "foo", &desc));
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ BEGIN_TEST(testDefinePropertyIgnoredAttributes)
|
|||
// Install another configurable property, so we can futz with it.
|
||||
CHECK(JS_DefineProperty(cx, obj, "bar",
|
||||
Getter, nullptr,
|
||||
JSPROP_IGNORE_ENUMERATE | JSPROP_SHARED));
|
||||
JSPROP_IGNORE_ENUMERATE));
|
||||
CHECK(JS_GetOwnPropertyDescriptor(cx, obj, "bar", &desc));
|
||||
CHECK(CheckDescriptor(desc, AccessorDescriptor, false, true, true));
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ BEGIN_TEST(testDefinePropertyIgnoredAttributes)
|
|||
// unchanged.
|
||||
CHECK(JS_DefineProperty(cx, obj, "bar",
|
||||
Getter, nullptr,
|
||||
JSPROP_IGNORE_PERMANENT | JSPROP_ENUMERATE | JSPROP_SHARED));
|
||||
JSPROP_IGNORE_PERMANENT | JSPROP_ENUMERATE));
|
||||
CHECK(JS_GetOwnPropertyDescriptor(cx, obj, "bar", &desc));
|
||||
CHECK(CheckDescriptor(desc, AccessorDescriptor, true, true, true));
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ BEGIN_TEST(testSetProperty_NativeGetterStubSetter)
|
|||
|
||||
CHECK(JS_DefineProperty(cx, obj, "prop",
|
||||
JS_PROPERTYOP_GETTER(NativeGet), nullptr,
|
||||
JSPROP_SHARED | JSPROP_PROPOP_ACCESSORS));
|
||||
JSPROP_PROPOP_ACCESSORS));
|
||||
|
||||
EXEC("'use strict'; \n"
|
||||
"var error, passed = false; \n"
|
||||
|
|
|
|||
|
|
@ -875,11 +875,6 @@ static const uint8_t JSPROP_GETTER = 0x10;
|
|||
/* property holds setter function */
|
||||
static const uint8_t JSPROP_SETTER = 0x20;
|
||||
|
||||
/* don't allocate a value slot for this property; don't copy the property on set
|
||||
of the same-named property in an object that delegates to a prototype
|
||||
containing this property */
|
||||
static const uint8_t JSPROP_SHARED = 0x40;
|
||||
|
||||
/* internal JS engine use only */
|
||||
static const uint8_t JSPROP_INTERNAL_USE_BIT = 0x80;
|
||||
|
||||
|
|
@ -2278,23 +2273,23 @@ inline int CheckIsSetterOp(JSSetterOp op);
|
|||
*/
|
||||
#define JS_PSG(name, getter, flags) \
|
||||
JS_PS_ACCESSOR_SPEC(name, JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(nullptr), flags, \
|
||||
JSPROP_SHARED)
|
||||
0)
|
||||
#define JS_PSGS(name, getter, setter, flags) \
|
||||
JS_PS_ACCESSOR_SPEC(name, JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(setter), flags, \
|
||||
JSPROP_SHARED)
|
||||
0)
|
||||
#define JS_SYM_GET(symbol, getter, flags) \
|
||||
JS_PS_ACCESSOR_SPEC(reinterpret_cast<const char*>(uint32_t(::JS::SymbolCode::symbol) + 1), \
|
||||
JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(nullptr), flags, JSPROP_SHARED)
|
||||
JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(nullptr), flags, 0)
|
||||
#define JS_SELF_HOSTED_GET(name, getterName, flags) \
|
||||
JS_PS_ACCESSOR_SPEC(name, SELFHOSTED_WRAPPER(getterName), JSNATIVE_WRAPPER(nullptr), flags, \
|
||||
JSPROP_SHARED | JSPROP_GETTER)
|
||||
JSPROP_GETTER)
|
||||
#define JS_SELF_HOSTED_GETSET(name, getterName, setterName, flags) \
|
||||
JS_PS_ACCESSOR_SPEC(name, SELFHOSTED_WRAPPER(getterName), SELFHOSTED_WRAPPER(setterName), \
|
||||
flags, JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER)
|
||||
flags, JSPROP_GETTER | JSPROP_SETTER)
|
||||
#define JS_SELF_HOSTED_SYM_GET(symbol, getterName, flags) \
|
||||
JS_PS_ACCESSOR_SPEC(reinterpret_cast<const char*>(uint32_t(::JS::SymbolCode::symbol) + 1), \
|
||||
SELFHOSTED_WRAPPER(getterName), JSNATIVE_WRAPPER(nullptr), flags, \
|
||||
JSPROP_SHARED | JSPROP_GETTER)
|
||||
JSPROP_GETTER)
|
||||
#define JS_STRING_PS(name, string, flags) \
|
||||
JS_PS_VALUE_SPEC(name, STRINGVALUE_WRAPPER(string), flags)
|
||||
#define JS_STRING_SYM_PS(symbol, string, flags) \
|
||||
|
|
@ -2864,7 +2859,6 @@ class WrappedPtrOperations<JS::PropertyDescriptor, Wrapper>
|
|||
}
|
||||
|
||||
bool hasGetterOrSetter() const { return desc().getter || desc().setter; }
|
||||
bool isShared() const { return has(JSPROP_SHARED); }
|
||||
|
||||
JS::HandleObject object() const {
|
||||
return JS::HandleObject::fromMarkedLocation(&desc().obj);
|
||||
|
|
@ -2881,14 +2875,12 @@ class WrappedPtrOperations<JS::PropertyDescriptor, Wrapper>
|
|||
JSPROP_IGNORE_VALUE |
|
||||
JSPROP_GETTER |
|
||||
JSPROP_SETTER |
|
||||
JSPROP_SHARED |
|
||||
JSPROP_REDEFINE_NONCONFIGURABLE |
|
||||
JSPROP_RESOLVING |
|
||||
SHADOWABLE)) == 0);
|
||||
MOZ_ASSERT(!hasAll(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE));
|
||||
MOZ_ASSERT(!hasAll(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT));
|
||||
if (isAccessorDescriptor()) {
|
||||
MOZ_ASSERT(has(JSPROP_SHARED));
|
||||
MOZ_ASSERT(!has(JSPROP_READONLY));
|
||||
MOZ_ASSERT(!has(JSPROP_IGNORE_READONLY));
|
||||
MOZ_ASSERT(!has(JSPROP_IGNORE_VALUE));
|
||||
|
|
@ -2917,7 +2909,6 @@ class WrappedPtrOperations<JS::PropertyDescriptor, Wrapper>
|
|||
JSPROP_READONLY |
|
||||
JSPROP_GETTER |
|
||||
JSPROP_SETTER |
|
||||
JSPROP_SHARED |
|
||||
JSPROP_REDEFINE_NONCONFIGURABLE |
|
||||
JSPROP_RESOLVING |
|
||||
SHADOWABLE)) == 0);
|
||||
|
|
@ -3018,12 +3009,12 @@ class MutableWrappedPtrOperations<JS::PropertyDescriptor, Wrapper>
|
|||
void setGetterObject(JSObject* obj) {
|
||||
desc().getter = reinterpret_cast<JSGetterOp>(obj);
|
||||
desc().attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY);
|
||||
desc().attrs |= JSPROP_GETTER | JSPROP_SHARED;
|
||||
desc().attrs |= JSPROP_GETTER;
|
||||
}
|
||||
void setSetterObject(JSObject* obj) {
|
||||
desc().setter = reinterpret_cast<JSSetterOp>(obj);
|
||||
desc().attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY);
|
||||
desc().attrs |= JSPROP_SETTER | JSPROP_SHARED;
|
||||
desc().attrs |= JSPROP_SETTER;
|
||||
}
|
||||
|
||||
JS::MutableHandleObject getterObject() {
|
||||
|
|
|
|||
|
|
@ -1047,7 +1047,7 @@ AddLengthProperty(JSContext* cx, HandleArrayObject obj)
|
|||
|
||||
return NativeObject::addProperty(cx, obj, lengthId, array_length_getter, array_length_setter,
|
||||
SHAPE_INVALID_SLOT,
|
||||
JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_SHADOWABLE,
|
||||
JSPROP_PERMANENT | JSPROP_SHADOWABLE,
|
||||
0, /* allowDictionary = */ false);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8081,13 +8081,19 @@ JS::AssertGCThingIsNotAnObjectSubclass(Cell* cell)
|
|||
JS_FRIEND_API(void)
|
||||
js::gc::AssertGCThingHasType(js::gc::Cell* cell, JS::TraceKind kind)
|
||||
{
|
||||
MOZ_ASSERT(IsCellPointerValid(cell));
|
||||
if (!cell)
|
||||
if (!cell) {
|
||||
MOZ_ASSERT(kind == JS::TraceKind::Null);
|
||||
else if (IsInsideNursery(cell))
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(IsCellPointerValid(cell));
|
||||
|
||||
if (IsInsideNursery(cell)) {
|
||||
MOZ_ASSERT(kind == JS::TraceKind::Object);
|
||||
else
|
||||
MOZ_ASSERT(MapAllocToTraceKind(cell->asTenured().getAllocKind()) == kind);
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(MapAllocToTraceKind(cell->asTenured().getAllocKind()) == kind);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -8651,7 +8657,7 @@ NewMemoryInfoObject(JSContext* cx)
|
|||
#endif
|
||||
if (!JS_DefineProperty(cx, obj, pair.name,
|
||||
getter, nullptr,
|
||||
JSPROP_ENUMERATE | JSPROP_SHARED))
|
||||
JSPROP_ENUMERATE))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -8686,7 +8692,7 @@ NewMemoryInfoObject(JSContext* cx)
|
|||
#endif
|
||||
if (!JS_DefineProperty(cx, zoneObj, pair.name,
|
||||
getter, nullptr,
|
||||
JSPROP_ENUMERATE | JSPROP_SHARED))
|
||||
JSPROP_ENUMERATE))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -361,7 +361,7 @@ js::ToPropertyDescriptor(JSContext* cx, HandleValue descval, bool checkAccessors
|
|||
js_getter_str);
|
||||
return false;
|
||||
}
|
||||
attrs |= JSPROP_GETTER | JSPROP_SHARED;
|
||||
attrs |= JSPROP_GETTER;
|
||||
}
|
||||
|
||||
// step 9
|
||||
|
|
@ -379,7 +379,7 @@ js::ToPropertyDescriptor(JSContext* cx, HandleValue descval, bool checkAccessors
|
|||
js_setter_str);
|
||||
return false;
|
||||
}
|
||||
attrs |= JSPROP_SETTER | JSPROP_SHARED;
|
||||
attrs |= JSPROP_SETTER;
|
||||
}
|
||||
|
||||
// step 10
|
||||
|
|
@ -395,7 +395,6 @@ js::ToPropertyDescriptor(JSContext* cx, HandleValue descval, bool checkAccessors
|
|||
|
||||
desc.setAttributes(attrs);
|
||||
MOZ_ASSERT_IF(attrs & JSPROP_READONLY, !(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
|
||||
MOZ_ASSERT_IF(attrs & (JSPROP_GETTER | JSPROP_SETTER), attrs & JSPROP_SHARED);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -425,7 +424,7 @@ js::CompletePropertyDescriptor(MutableHandle<PropertyDescriptor> desc)
|
|||
desc.setGetterObject(nullptr);
|
||||
if (!desc.hasSetterObject())
|
||||
desc.setSetterObject(nullptr);
|
||||
desc.attributesRef() |= JSPROP_GETTER | JSPROP_SETTER | JSPROP_SHARED;
|
||||
desc.attributesRef() |= JSPROP_GETTER | JSPROP_SETTER;
|
||||
}
|
||||
if (!desc.hasConfigurable())
|
||||
desc.attributesRef() |= JSPROP_PERMANENT;
|
||||
|
|
@ -3526,7 +3525,6 @@ DumpProperty(const NativeObject* obj, Shape& shape, js::GenericPrinter& out)
|
|||
if (attrs & JSPROP_ENUMERATE) out.put("enumerate ");
|
||||
if (attrs & JSPROP_READONLY) out.put("readonly ");
|
||||
if (attrs & JSPROP_PERMANENT) out.put("permanent ");
|
||||
if (attrs & JSPROP_SHARED) out.put("shared ");
|
||||
|
||||
if (shape.hasGetterValue())
|
||||
out.printf("getterValue=%p ", (void*) shape.getterObject());
|
||||
|
|
|
|||
|
|
@ -1447,6 +1447,9 @@ ConvertTranscodeResultToJSException(JSContext* cx, JS::TranscodeResult rv)
|
|||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
CooperativeThreadMayYield(JSContext* cx);
|
||||
|
||||
static bool
|
||||
Evaluate(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
|
|
@ -1538,14 +1541,25 @@ Evaluate(JSContext* cx, unsigned argc, Value* vp)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Find all eligible globals to execute in: any global in another
|
||||
// zone group which has not been entered by a cooperative thread.
|
||||
// Find all eligible globals to execute in.
|
||||
JS::AutoObjectVector eligibleGlobals(cx);
|
||||
for (CompartmentsIter c(cx->runtime(), SkipAtoms); !c.done(); c.next()) {
|
||||
if (!c->zone()->group()->ownerContext().context() &&
|
||||
c->maybeGlobal() &&
|
||||
!cx->runtime()->isSelfHostingGlobal(c->maybeGlobal()))
|
||||
{
|
||||
// Compartments without globals and the self hosting global may
|
||||
// not be entered.
|
||||
if (!c->maybeGlobal() || cx->runtime()->isSelfHostingGlobal(c->maybeGlobal()))
|
||||
continue;
|
||||
|
||||
// Globals in zone groups which are not in use by a cooperative
|
||||
// thread may be entered.
|
||||
if (!c->zone()->group()->ownerContext().context()) {
|
||||
if (!eligibleGlobals.append(c->maybeGlobal()))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Globals in zone groups which use exclusive locking may be
|
||||
// entered, in which case this thread will yield until the zone
|
||||
// group is available.
|
||||
if (c->zone()->group()->useExclusiveLocking() && CooperativeThreadMayYield(cx)) {
|
||||
if (!eligibleGlobals.append(c->maybeGlobal()))
|
||||
return false;
|
||||
}
|
||||
|
|
@ -3337,24 +3351,16 @@ CooperativeYield()
|
|||
}
|
||||
|
||||
static bool
|
||||
CooperativeYieldThread(JSContext* cx, unsigned argc, Value* vp)
|
||||
CooperativeThreadMayYield(JSContext* cx)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
if (!cx->runtime()->gc.canChangeActiveContext(cx)) {
|
||||
JS_ReportErrorASCII(cx, "Cooperating multithreading context switches are not currently allowed");
|
||||
if (!cx->runtime()->gc.canChangeActiveContext(cx))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GetShellContext(cx)->isWorker) {
|
||||
JS_ReportErrorASCII(cx, "Worker threads cannot yield");
|
||||
if (GetShellContext(cx)->isWorker)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cooperationState->singleThreaded) {
|
||||
JS_ReportErrorASCII(cx, "Yielding is not allowed while single threaded");
|
||||
if (cooperationState->singleThreaded)
|
||||
return false;
|
||||
}
|
||||
|
||||
// To avoid contention issues between threads, yields are not allowed while
|
||||
// a thread has access to zone groups other than its original one, i.e. if
|
||||
|
|
@ -3364,10 +3370,30 @@ CooperativeYieldThread(JSContext* cx, unsigned argc, Value* vp)
|
|||
// threads, whereas the browser has more control over which threads are
|
||||
// running at different times.
|
||||
for (ZoneGroupsIter group(cx->runtime()); !group.done(); group.next()) {
|
||||
if (group->ownerContext().context() == cx && group != cx->zone()->group()) {
|
||||
JS_ReportErrorASCII(cx, "Yielding is not allowed while owning multiple zone groups");
|
||||
if (group->ownerContext().context() == cx && group != cx->zone()->group())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
CooperativeYieldCallback(JSContext* cx)
|
||||
{
|
||||
MOZ_ASSERT(CooperativeThreadMayYield(cx));
|
||||
CooperativeBeginWait(cx);
|
||||
CooperativeYield();
|
||||
CooperativeEndWait(cx);
|
||||
}
|
||||
|
||||
static bool
|
||||
CooperativeYieldThread(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
if (!CooperativeThreadMayYield(cx)) {
|
||||
JS_ReportErrorASCII(cx, "Yielding is not currently allowed");
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -3467,6 +3493,8 @@ WorkerMain(void* arg)
|
|||
if (!cx)
|
||||
return;
|
||||
|
||||
SetCooperativeYieldCallback(cx, CooperativeYieldCallback);
|
||||
|
||||
UniquePtr<ShellContext> sc = MakeUnique<ShellContext>(cx);
|
||||
if (!sc)
|
||||
return;
|
||||
|
|
@ -7273,7 +7301,7 @@ static const JSJitInfo doFoo_methodinfo = {
|
|||
|
||||
static const JSPropertySpec dom_props[] = {
|
||||
{"x",
|
||||
JSPROP_SHARED | JSPROP_ENUMERATE,
|
||||
JSPROP_ENUMERATE,
|
||||
{ {
|
||||
{ { dom_genericGetter, &dom_x_getterinfo } },
|
||||
{ { dom_genericSetter, &dom_x_setterinfo } }
|
||||
|
|
@ -8645,6 +8673,7 @@ main(int argc, char** argv, char** envp)
|
|||
JS::SetSingleThreadedExecutionCallbacks(cx,
|
||||
CooperativeBeginSingleThreadedExecution,
|
||||
CooperativeEndSingleThreadedExecution);
|
||||
SetCooperativeYieldCallback(cx, CooperativeYieldCallback);
|
||||
|
||||
result = Shell(cx, &op, envp);
|
||||
|
||||
|
|
|
|||
|
|
@ -576,7 +576,7 @@ MappedArgumentsObject::obj_resolve(JSContext* cx, HandleObject obj, HandleId id,
|
|||
return true;
|
||||
}
|
||||
|
||||
unsigned attrs = JSPROP_SHARED | JSPROP_SHADOWABLE | JSPROP_RESOLVING;
|
||||
unsigned attrs = JSPROP_SHADOWABLE | JSPROP_RESOLVING;
|
||||
if (JSID_IS_INT(id)) {
|
||||
uint32_t arg = uint32_t(JSID_TO_INT(id));
|
||||
if (arg >= argsobj->initialLength() || argsobj->isElementDeleted(arg))
|
||||
|
|
@ -776,7 +776,7 @@ UnmappedArgumentsObject::obj_resolve(JSContext* cx, HandleObject obj, HandleId i
|
|||
return true;
|
||||
}
|
||||
|
||||
unsigned attrs = JSPROP_SHARED | JSPROP_SHADOWABLE;
|
||||
unsigned attrs = JSPROP_SHADOWABLE;
|
||||
GetterOp getter = UnmappedArgGetter;
|
||||
SetterOp setter = UnmappedArgSetter;
|
||||
|
||||
|
|
@ -793,7 +793,7 @@ UnmappedArgumentsObject::obj_resolve(JSContext* cx, HandleObject obj, HandleId i
|
|||
if (!JSID_IS_ATOM(id, cx->names().callee))
|
||||
return true;
|
||||
|
||||
attrs = JSPROP_PERMANENT | JSPROP_GETTER | JSPROP_SETTER | JSPROP_SHARED;
|
||||
attrs = JSPROP_PERMANENT | JSPROP_GETTER | JSPROP_SETTER;
|
||||
getter = CastAsGetterOp(argsobj->global().getThrowTypeError());
|
||||
setter = CastAsSetterOp(argsobj->global().getThrowTypeError());
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue