Merge m-c to autoland, a=merge

MozReview-Commit-ID: Kjjgw1Pdb3U
This commit is contained in:
Wes Kocher 2017-09-26 17:15:46 -07:00
commit 9d9610f6a3
194 changed files with 2395 additions and 3114 deletions

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2742,8 +2742,8 @@ public:
enum ElementCallbackType {
eCreated,
eAttached,
eDetached,
eConnected,
eDisconnected,
eAttributeChanged
};

View File

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

View File

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

View File

@ -2399,7 +2399,6 @@ WebGLContext::StartVRPresentation()
gl::GLScreenBuffer::CreateFactory(gl,
caps,
vrmc,
vrmc->GetBackendType(),
TextureFlags::ORIGIN_BOTTOM_LEFT);
if (factory) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -39,6 +39,7 @@ public:
bool aUseExternalSurfaceSize,
const gfx::IntSize& aSurfaceSize);
void BindComplete();
void ActorDestroy(ActorDestroyReason aReason) override;
bool DeallocPCompositorBridgeParent(PCompositorBridgeParent* aActor) override;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -127,7 +127,7 @@ struct InternalGCPointerPolicy {
TraceManuallyBarrieredEdge(trc, vp, name);
}
static bool isValid(T v) {
return gc::IsCellPointerValid(v);
return gc::IsCellPointerValidOrNull(v);
}
};

View File

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

View File

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

View File

@ -0,0 +1,7 @@
if (!('stackTest' in this))
quit();
stackTest(function() {
let m = parseModule(``);
m.declarationInstantiation();
});

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

View File

@ -292,42 +292,6 @@ BaselineCacheIRCompiler::emitGuardCompartment()
return true;
}
bool
BaselineCacheIRCompiler::emitGuardAnyClass()
{
Register obj = allocator.useRegister(masm, reader.objOperandId());
AutoScratchRegister scratch(allocator, masm);
FailurePath* failure;
if (!addFailurePath(&failure))
return false;
Address testAddr(stubAddress(reader.stubOffset()));
masm.loadObjGroup(obj, scratch);
masm.loadPtr(Address(scratch, ObjectGroup::offsetOfClasp()), scratch);
masm.branchPtr(Assembler::NotEqual, testAddr, scratch, failure->label());
return true;
}
bool
BaselineCacheIRCompiler::emitGuardHasProxyHandler()
{
Register obj = allocator.useRegister(masm, reader.objOperandId());
AutoScratchRegister scratch(allocator, masm);
FailurePath* failure;
if (!addFailurePath(&failure))
return false;
Address testAddr(stubAddress(reader.stubOffset()));
masm.loadPtr(testAddr, scratch);
Address handlerAddr(obj, ProxyObject::offsetOfHandler());
masm.branchPtr(Assembler::NotEqual, handlerAddr, scratch, failure->label());
return true;
}
bool
BaselineCacheIRCompiler::emitGuardSpecificObject()
{
@ -403,54 +367,6 @@ BaselineCacheIRCompiler::emitGuardSpecificSymbol()
return true;
}
bool
BaselineCacheIRCompiler::emitGuardXrayExpandoShapeAndDefaultProto()
{
Register obj = allocator.useRegister(masm, reader.objOperandId());
bool hasExpando = reader.readBool();
Address shapeWrapperAddress(stubAddress(reader.stubOffset()));
AutoScratchRegister scratch(allocator, masm);
Maybe<AutoScratchRegister> scratch2;
if (hasExpando)
scratch2.emplace(allocator, masm);
FailurePath* failure;
if (!addFailurePath(&failure))
return false;
masm.loadPtr(Address(obj, ProxyObject::offsetOfReservedSlots()), scratch);
Address holderAddress(scratch, sizeof(Value) * GetXrayJitInfo()->xrayHolderSlot);
Address expandoAddress(scratch, NativeObject::getFixedSlotOffset(GetXrayJitInfo()->holderExpandoSlot));
if (hasExpando) {
masm.branchTestObject(Assembler::NotEqual, holderAddress, failure->label());
masm.unboxObject(holderAddress, scratch);
masm.branchTestObject(Assembler::NotEqual, expandoAddress, failure->label());
masm.unboxObject(expandoAddress, scratch);
// Unwrap the expando before checking its shape.
masm.loadPtr(Address(scratch, ProxyObject::offsetOfReservedSlots()), scratch);
masm.unboxObject(Address(scratch, detail::ProxyReservedSlots::offsetOfPrivateSlot()), scratch);
masm.loadPtr(shapeWrapperAddress, scratch2.ref());
LoadShapeWrapperContents(masm, scratch2.ref(), scratch2.ref(), failure->label());
masm.branchTestObjShape(Assembler::NotEqual, scratch, scratch2.ref(), failure->label());
// The reserved slots on the expando should all be in fixed slots.
Address protoAddress(scratch, NativeObject::getFixedSlotOffset(GetXrayJitInfo()->expandoProtoSlot));
masm.branchTestUndefined(Assembler::NotEqual, protoAddress, failure->label());
} else {
Label done;
masm.branchTestObject(Assembler::NotEqual, holderAddress, &done);
masm.unboxObject(holderAddress, scratch);
masm.branchTestObject(Assembler::Equal, expandoAddress, failure->label());
masm.bind(&done);
}
return true;
}
bool
BaselineCacheIRCompiler::emitLoadFixedSlotResult()
{

View File

@ -16,7 +16,6 @@
#include "vm/SelfHosting.h"
#include "jsobjinlines.h"
#include "jit/MacroAssembler-inl.h"
#include "vm/EnvironmentObject-inl.h"
#include "vm/UnboxedObject-inl.h"
@ -205,8 +204,6 @@ GetPropIRGenerator::tryAttachStub()
return true;
if (tryAttachCrossCompartmentWrapper(obj, objId, id))
return true;
if (tryAttachXrayCrossCompartmentWrapper(obj, objId, id))
return true;
if (tryAttachFunction(obj, objId, id))
return true;
if (tryAttachProxy(obj, objId, id))
@ -872,7 +869,7 @@ GetPropIRGenerator::tryAttachCrossCompartmentWrapper(HandleObject obj, ObjOperan
maybeEmitIdGuard(id);
writer.guardIsProxy(objId);
writer.guardHasProxyHandler(objId, Wrapper::wrapperHandler(obj));
writer.guardIsCrossCompartmentWrapper(objId);
// Load the object wrapped by the CCW
ObjOperandId wrapperTargetId = writer.loadWrapperTarget(objId);
@ -896,114 +893,6 @@ GetPropIRGenerator::tryAttachCrossCompartmentWrapper(HandleObject obj, ObjOperan
return true;
}
static bool
GetXrayExpandoShapeWrapper(JSContext* cx, HandleObject xray, MutableHandleObject wrapper)
{
Value v = GetProxyReservedSlot(xray, GetXrayJitInfo()->xrayHolderSlot);
if (v.isObject()) {
NativeObject* holder = &v.toObject().as<NativeObject>();
v = holder->getFixedSlot(GetXrayJitInfo()->holderExpandoSlot);
if (v.isObject()) {
RootedNativeObject expando(cx, &UncheckedUnwrap(&v.toObject())->as<NativeObject>());
wrapper.set(NewWrapperWithObjectShape(cx, expando));
return wrapper != nullptr;
}
}
wrapper.set(nullptr);
return true;
}
bool
GetPropIRGenerator::tryAttachXrayCrossCompartmentWrapper(HandleObject obj, ObjOperandId objId,
HandleId id)
{
if (!IsProxy(obj))
return false;
XrayJitInfo* info = GetXrayJitInfo();
if (!info || !info->isCrossCompartmentXray(GetProxyHandler(obj)))
return false;
if (!info->globalHasExclusiveExpandos(cx_->global()))
return false;
RootedObject target(cx_, UncheckedUnwrap(obj));
RootedObject expandoShapeWrapper(cx_);
if (!GetXrayExpandoShapeWrapper(cx_, obj, &expandoShapeWrapper)) {
cx_->recoverFromOutOfMemory();
return false;
}
// Look for a getter we can call on the xray or its prototype chain.
Rooted<PropertyDescriptor> desc(cx_);
RootedObject holder(cx_, obj);
AutoObjectVector prototypes(cx_);
AutoObjectVector prototypeExpandoShapeWrappers(cx_);
while (true) {
if (!GetOwnPropertyDescriptor(cx_, holder, id, &desc)) {
cx_->clearPendingException();
return false;
}
if (desc.object())
break;
if (!GetPrototype(cx_, holder, &holder)) {
cx_->clearPendingException();
return false;
}
if (!holder || !IsProxy(holder) || !info->isCrossCompartmentXray(GetProxyHandler(holder)))
return false;
RootedObject prototypeExpandoShapeWrapper(cx_);
if (!GetXrayExpandoShapeWrapper(cx_, holder, &prototypeExpandoShapeWrapper) ||
!prototypes.append(holder) ||
!prototypeExpandoShapeWrappers.append(prototypeExpandoShapeWrapper))
{
cx_->recoverFromOutOfMemory();
return false;
}
}
if (!desc.isAccessorDescriptor())
return false;
RootedObject getter(cx_, desc.getterObject());
if (!getter || !getter->is<JSFunction>() || !getter->as<JSFunction>().isNative())
return false;
maybeEmitIdGuard(id);
writer.guardIsProxy(objId);
writer.guardHasProxyHandler(objId, GetProxyHandler(obj));
// Load the object wrapped by the CCW
ObjOperandId wrapperTargetId = writer.loadWrapperTarget(objId);
// Test the wrapped object's class. The properties held by xrays or their
// prototypes will be invariant for objects of a given class, except for
// changes due to xray expandos or xray prototype mutations.
writer.guardAnyClass(wrapperTargetId, target->getClass());
// Make sure the expandos on the xray and its prototype chain match up with
// what we expect. The expando shape needs to be consistent, to ensure it
// has not had any shadowing properties added, and the expando cannot have
// any custom prototype (xray prototypes are stable otherwise).
//
// We can only do this for xrays with exclusive access to their expandos
// (as we checked earlier), which store a pointer to their expando
// directly. Xrays in other compartments may share their expandos with each
// other and a VM call is needed just to find the expando.
writer.guardXrayExpandoShapeAndDefaultProto(objId, expandoShapeWrapper);
for (size_t i = 0; i < prototypes.length(); i++) {
JSObject* proto = prototypes[i];
ObjOperandId protoId = writer.loadObject(proto);
writer.guardXrayExpandoShapeAndDefaultProto(protoId, prototypeExpandoShapeWrappers[i]);
}
writer.callNativeGetterResult(objId, &getter->as<JSFunction>());
writer.typeMonitorResult();
trackAttached("XrayGetter");
return true;
}
bool
GetPropIRGenerator::tryAttachGenericProxy(HandleObject obj, ObjOperandId objId, HandleId id,
bool handleDOMProxies)
@ -4376,40 +4265,3 @@ CompareIRGenerator::trackNotAttached()
}
#endif
}
// Class which holds a shape pointer for use when caches might reference data in other zones.
static const Class shapeContainerClass = {
"ShapeContainer",
JSCLASS_HAS_RESERVED_SLOTS(1)
};
static const size_t SHAPE_CONTAINER_SLOT = 0;
JSObject*
jit::NewWrapperWithObjectShape(JSContext* cx, HandleNativeObject obj)
{
MOZ_ASSERT(cx->compartment() != obj->compartment());
RootedObject wrapper(cx);
{
AutoCompartment ac(cx, obj);
wrapper = NewObjectWithClassProto(cx, &shapeContainerClass, nullptr);
if (!obj)
return nullptr;
wrapper->as<NativeObject>().setSlot(SHAPE_CONTAINER_SLOT, PrivateGCThingValue(obj->lastProperty()));
}
if (!JS_WrapObject(cx, &wrapper))
return nullptr;
MOZ_ASSERT(IsWrapper(wrapper));
return wrapper;
}
void
jit::LoadShapeWrapperContents(MacroAssembler& masm, Register obj, Register dst, Label* failure)
{
masm.loadPtr(Address(obj, ProxyObject::offsetOfReservedSlots()), dst);
Address privateAddr(dst, detail::ProxyReservedSlots::offsetOfPrivateSlot());
masm.branchTestObject(Assembler::NotEqual, privateAddr, failure);
masm.unboxObject(privateAddr, dst);
masm.unboxNonDouble(Address(dst, NativeObject::getFixedSlotOffset(SHAPE_CONTAINER_SLOT)), dst);
}

View File

@ -171,12 +171,11 @@ extern const char* CacheKindNames[];
_(GuardShape) \
_(GuardGroup) \
_(GuardProto) \
_(GuardClass) /* Guard an object class, per GuardClassKind */ \
_(GuardAnyClass) /* Guard an arbitrary class for an object */ \
_(GuardClass) \
_(GuardCompartment) \
_(GuardIsNativeFunction) \
_(GuardIsProxy) \
_(GuardHasProxyHandler) \
_(GuardIsCrossCompartmentWrapper) \
_(GuardNotDOMProxy) \
_(GuardSpecificObject) \
_(GuardSpecificAtom) \
@ -192,8 +191,6 @@ extern const char* CacheKindNames[];
_(GuardAndGetIterator) \
_(GuardHasGetterSetter) \
_(GuardGroupHasUnanalyzedNewScript) \
_(GuardIndexIsNonNegative) \
_(GuardXrayExpandoShapeAndDefaultProto) \
_(LoadStackValue) \
_(LoadObject) \
_(LoadProto) \
@ -358,14 +355,6 @@ enum class GuardClassKind : uint8_t
JSFunction,
};
// Some ops refer to shapes that might be in other zones. Instead of putting
// cross-zone pointers in the caches themselves (which would complicate tracing
// enormously), these ops instead contain wrappers for objects in the target
// zone, which refer to the actual shape via a reserved slot.
JSObject* NewWrapperWithObjectShape(JSContext* cx, HandleNativeObject obj);
void LoadShapeWrapperContents(MacroAssembler& masm, Register obj, Register dst, Label* failure);
// Class to record CacheIR + some additional metadata for code generation.
class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
{
@ -534,10 +523,6 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
writeOpWithOperandId(CacheOp::GuardShape, obj);
addStubField(uintptr_t(shape), StubField::Type::Shape);
}
void guardXrayExpandoShapeAndDefaultProto(ObjOperandId obj, JSObject* shapeWrapper) {
writeOpWithOperandId(CacheOp::GuardXrayExpandoShapeAndDefaultProto, obj);
buffer_.writeByte(uint32_t(!!shapeWrapper)); addStubField(uintptr_t(shapeWrapper), StubField::Type::JSObject);
}
void guardGroup(ObjOperandId obj, ObjectGroup* group) {
writeOpWithOperandId(CacheOp::GuardGroup, obj);
addStubField(uintptr_t(group), StubField::Type::ObjectGroup);
@ -552,10 +537,6 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
writeOpWithOperandId(CacheOp::GuardClass, obj);
buffer_.writeByte(uint32_t(kind));
}
void guardAnyClass(ObjOperandId obj, const Class* clasp) {
writeOpWithOperandId(CacheOp::GuardAnyClass, obj);
addStubField(uintptr_t(clasp), StubField::Type::RawWord);
}
void guardIsNativeFunction(ObjOperandId obj, JSNative nativeFunc) {
writeOpWithOperandId(CacheOp::GuardIsNativeFunction, obj);
writePointer(JS_FUNC_TO_DATA_PTR(void*, nativeFunc));
@ -563,9 +544,8 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
void guardIsProxy(ObjOperandId obj) {
writeOpWithOperandId(CacheOp::GuardIsProxy, obj);
}
void guardHasProxyHandler(ObjOperandId obj, const void* handler) {
writeOpWithOperandId(CacheOp::GuardHasProxyHandler, obj);
addStubField(uintptr_t(handler), StubField::Type::RawWord);
void guardIsCrossCompartmentWrapper(ObjOperandId obj) {
writeOpWithOperandId(CacheOp::GuardIsCrossCompartmentWrapper, obj);
}
void guardNotDOMProxy(ObjOperandId obj) {
writeOpWithOperandId(CacheOp::GuardNotDOMProxy, obj);
@ -634,10 +614,6 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter
addStubField(uintptr_t(group), StubField::Type::ObjectGroup);
}
void guardIndexIsNonNegative(Int32OperandId index) {
writeOpWithOperandId(CacheOp::GuardIndexIsNonNegative, index);
}
void loadFrameCalleeResult() {
writeOp(CacheOp::LoadFrameCalleeResult);
}
@ -1217,7 +1193,6 @@ class MOZ_RAII GetPropIRGenerator : public IRGenerator
bool tryAttachModuleNamespace(HandleObject obj, ObjOperandId objId, HandleId id);
bool tryAttachWindowProxy(HandleObject obj, ObjOperandId objId, HandleId id);
bool tryAttachCrossCompartmentWrapper(HandleObject obj, ObjOperandId objId, HandleId id);
bool tryAttachXrayCrossCompartmentWrapper(HandleObject obj, ObjOperandId objId, HandleId id);
bool tryAttachFunction(HandleObject obj, ObjOperandId objId, HandleId id);
bool tryAttachGenericProxy(HandleObject obj, ObjOperandId objId, HandleId id,

View File

@ -1435,6 +1435,22 @@ CacheIRCompiler::emitGuardIsProxy()
return true;
}
bool
CacheIRCompiler::emitGuardIsCrossCompartmentWrapper()
{
Register obj = allocator.useRegister(masm, reader.objOperandId());
AutoScratchRegister scratch(allocator, masm);
FailurePath* failure;
if (!addFailurePath(&failure))
return false;
Address handlerAddr(obj, ProxyObject::offsetOfHandler());
masm.branchPtr(Assembler::NotEqual, handlerAddr, ImmPtr(&CrossCompartmentWrapper::singleton),
failure->label());
return true;
}
bool
CacheIRCompiler::emitGuardNotDOMProxy()
{
@ -1912,19 +1928,6 @@ CacheIRCompiler::emitLoadDenseElementResult()
return true;
}
bool
CacheIRCompiler::emitGuardIndexIsNonNegative()
{
Register index = allocator.useRegister(masm, reader.int32OperandId());
FailurePath* failure;
if (!addFailurePath(&failure))
return false;
masm.branch32(Assembler::LessThan, index, Imm32(0), failure->label());
return true;
}
bool
CacheIRCompiler::emitLoadDenseElementHoleResult()
{

View File

@ -24,6 +24,7 @@ namespace jit {
_(GuardClass) \
_(GuardIsNativeFunction) \
_(GuardIsProxy) \
_(GuardIsCrossCompartmentWrapper) \
_(GuardNotDOMProxy) \
_(GuardSpecificInt32Immediate) \
_(GuardMagicValue) \
@ -32,7 +33,6 @@ namespace jit {
_(GuardNoDetachedTypedObjects) \
_(GuardNoDenseElements) \
_(GuardAndGetIndexFromString) \
_(GuardIndexIsNonNegative) \
_(LoadProto) \
_(LoadEnclosingEnvironment) \
_(LoadWrapperTarget) \

View File

@ -107,12 +107,6 @@ class MOZ_RAII IonCacheIRCompiler : public CacheIRCompiler
JSCompartment* compartmentStubField(uint32_t offset) {
return (JSCompartment*)readStubWord(offset, StubField::Type::RawWord);
}
const Class* classStubField(uintptr_t offset) {
return (const Class*)readStubWord(offset, StubField::Type::RawWord);
}
const void* proxyHandlerStubField(uintptr_t offset) {
return (const void*)readStubWord(offset, StubField::Type::RawWord);
}
jsid idStubField(uint32_t offset) {
return mozilla::BitwiseCast<jsid>(readStubWord(offset, StubField::Type::Id));
}
@ -669,37 +663,6 @@ IonCacheIRCompiler::emitGuardCompartment()
return true;
}
bool
IonCacheIRCompiler::emitGuardAnyClass()
{
Register obj = allocator.useRegister(masm, reader.objOperandId());
AutoScratchRegister scratch(allocator, masm);
const Class* clasp = classStubField(reader.stubOffset());
FailurePath* failure;
if (!addFailurePath(&failure))
return false;
masm.branchTestObjClass(Assembler::NotEqual, obj, scratch, clasp, failure->label());
return true;
}
bool
IonCacheIRCompiler::emitGuardHasProxyHandler()
{
Register obj = allocator.useRegister(masm, reader.objOperandId());
const void* handler = proxyHandlerStubField(reader.stubOffset());
FailurePath* failure;
if (!addFailurePath(&failure))
return false;
Address handlerAddr(obj, ProxyObject::offsetOfHandler());
masm.branchPtr(Assembler::NotEqual, handlerAddr, ImmPtr(handler), failure->label());
return true;
}
bool
IonCacheIRCompiler::emitGuardSpecificObject()
{
@ -773,55 +736,6 @@ IonCacheIRCompiler::emitGuardSpecificSymbol()
return true;
}
bool
IonCacheIRCompiler::emitGuardXrayExpandoShapeAndDefaultProto()
{
Register obj = allocator.useRegister(masm, reader.objOperandId());
bool hasExpando = reader.readBool();
JSObject* shapeWrapper = objectStubField(reader.stubOffset());
MOZ_ASSERT(hasExpando == !!shapeWrapper);
AutoScratchRegister scratch(allocator, masm);
Maybe<AutoScratchRegister> scratch2;
if (hasExpando)
scratch2.emplace(allocator, masm);
FailurePath* failure;
if (!addFailurePath(&failure))
return false;
masm.loadPtr(Address(obj, ProxyObject::offsetOfReservedSlots()), scratch);
Address holderAddress(scratch, sizeof(Value) * GetXrayJitInfo()->xrayHolderSlot);
Address expandoAddress(scratch, NativeObject::getFixedSlotOffset(GetXrayJitInfo()->holderExpandoSlot));
if (hasExpando) {
masm.branchTestObject(Assembler::NotEqual, holderAddress, failure->label());
masm.unboxObject(holderAddress, scratch);
masm.branchTestObject(Assembler::NotEqual, expandoAddress, failure->label());
masm.unboxObject(expandoAddress, scratch);
// Unwrap the expando before checking its shape.
masm.loadPtr(Address(scratch, ProxyObject::offsetOfReservedSlots()), scratch);
masm.unboxObject(Address(scratch, detail::ProxyReservedSlots::offsetOfPrivateSlot()), scratch);
masm.movePtr(ImmGCPtr(shapeWrapper), scratch2.ref());
LoadShapeWrapperContents(masm, scratch2.ref(), scratch2.ref(), failure->label());
masm.branchTestObjShape(Assembler::NotEqual, scratch, scratch2.ref(), failure->label());
// The reserved slots on the expando should all be in fixed slots.
Address protoAddress(scratch, NativeObject::getFixedSlotOffset(GetXrayJitInfo()->expandoProtoSlot));
masm.branchTestUndefined(Assembler::NotEqual, protoAddress, failure->label());
} else {
Label done;
masm.branchTestObject(Assembler::NotEqual, holderAddress, &done);
masm.unboxObject(holderAddress, scratch);
masm.branchTestObject(Assembler::Equal, expandoAddress, failure->label());
masm.bind(&done);
}
return true;
}
bool
IonCacheIRCompiler::emitLoadFixedSlotResult()
{

View File

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

View File

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

View File

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

View File

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

Some files were not shown because too many files have changed in this diff Show More