зеркало из https://github.com/mozilla/gecko-dev.git
161 строка
5.6 KiB
JavaScript
161 строка
5.6 KiB
JavaScript
var EXPORTED_SYMBOLS = ["ReftestFissionParent"];
|
|
|
|
class ReftestFissionParent extends JSWindowActorParent {
|
|
|
|
tellChildrenToFlushRendering(browsingContext, ignoreThrottledAnimations) {
|
|
let promises = [];
|
|
this.tellChildrenToFlushRenderingRecursive(browsingContext, ignoreThrottledAnimations, promises);
|
|
return Promise.allSettled(promises);
|
|
}
|
|
|
|
tellChildrenToFlushRenderingRecursive(browsingContext, ignoreThrottledAnimations, promises) {
|
|
let cwg = browsingContext.currentWindowGlobal;
|
|
if (cwg && cwg.isProcessRoot) {
|
|
let a = cwg.getActor("ReftestFission");
|
|
if (a) {
|
|
let responsePromise = a.sendQuery("FlushRendering", {ignoreThrottledAnimations});
|
|
promises.push(responsePromise);
|
|
}
|
|
}
|
|
|
|
for (let context of browsingContext.children) {
|
|
this.tellChildrenToFlushRenderingRecursive(context, ignoreThrottledAnimations, promises);
|
|
}
|
|
}
|
|
|
|
// not including browsingContext
|
|
getNearestProcessRootProperDescendants(browsingContext) {
|
|
let result = [];
|
|
for (let context of browsingContext.children) {
|
|
this.getNearestProcessRootProperDescendantsRecursive(context, result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
getNearestProcessRootProperDescendantsRecursive(browsingContext, result) {
|
|
let cwg = browsingContext.currentWindowGlobal;
|
|
if (cwg && cwg.isProcessRoot) {
|
|
result.push(browsingContext);
|
|
return;
|
|
}
|
|
for (let context of browsingContext.children) {
|
|
this.getNearestProcessRootProperDescendantsRecursive(context, result);
|
|
}
|
|
}
|
|
|
|
// tell children and itself
|
|
async tellChildrenToUpdateLayerTree(browsingContext) {
|
|
let errorStrings = [];
|
|
let infoStrings = [];
|
|
|
|
let cwg = browsingContext.currentWindowGlobal;
|
|
if (!cwg || !cwg.isProcessRoot) {
|
|
if (cwg) {
|
|
errorStrings.push("tellChildrenToUpdateLayerTree called on a non process root?");
|
|
}
|
|
return {errorStrings, infoStrings};
|
|
}
|
|
|
|
let actor = cwg.getActor("ReftestFission");
|
|
if (!actor) {
|
|
return {errorStrings, infoStrings};
|
|
}
|
|
|
|
// When we paint a document we also update the EffectsInfo visible rect in
|
|
// nsSubDocumentFrame for any remote subdocuments. This visible rect is
|
|
// used to limit painting for the subdocument in the subdocument's process.
|
|
// So we want to ensure that the IPC message that updates the visible rect
|
|
// to the subdocument's process arrives before we paint the subdocument
|
|
// (otherwise our painting might not be up to date). We do this by sending,
|
|
// and waiting for reply, an "EmptyMessage" to every direct descendant that
|
|
// is in another process. Since we send the "EmptyMessage" after the
|
|
// visible rect update message we know that the visible rect will be
|
|
// updated by the time we hear back from the "EmptyMessage". Then we can
|
|
// ask the subdocument process to paint.
|
|
|
|
try {
|
|
let result = await actor.sendQuery("UpdateLayerTree");
|
|
errorStrings.push(...result.errorStrings);
|
|
} catch (e) {
|
|
infoStrings.push("tellChildrenToUpdateLayerTree UpdateLayerTree msg to child rejected: " + e);
|
|
}
|
|
|
|
let descendants = actor.getNearestProcessRootProperDescendants(browsingContext);
|
|
for (let context of descendants) {
|
|
let cwg2 = context.currentWindowGlobal;
|
|
if (cwg2) {
|
|
if (!cwg2.isProcessRoot) {
|
|
errorStrings.push("getNearestProcessRootProperDescendants returned a non process root?");
|
|
}
|
|
let actor2 = cwg2.getActor("ReftestFission");
|
|
if (actor2) {
|
|
try {
|
|
await actor2.sendQuery("EmptyMessage");
|
|
} catch(e) {
|
|
infoStrings.push("tellChildrenToUpdateLayerTree EmptyMessage msg to child rejected: " + e);
|
|
}
|
|
|
|
try {
|
|
let result2 = await actor2.tellChildrenToUpdateLayerTree(context);
|
|
errorStrings.push(...result2.errorStrings);
|
|
infoStrings.push(...result2.infoStrings);
|
|
} catch (e) {
|
|
errorStrings.push("tellChildrenToUpdateLayerTree recursive tellChildrenToUpdateLayerTree call rejected: " + e);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
return {errorStrings, infoStrings};
|
|
}
|
|
|
|
receiveMessage(msg) {
|
|
switch (msg.name) {
|
|
case "ForwardAfterPaintEvent":
|
|
{
|
|
let cwg = msg.data.toBrowsingContext.currentWindowGlobal;
|
|
if (cwg) {
|
|
let a = cwg.getActor("ReftestFission");
|
|
if (a) {
|
|
a.sendAsyncMessage("ForwardAfterPaintEventToSelfAndParent", msg.data);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case "FlushRendering":
|
|
{
|
|
let promise = this.tellChildrenToFlushRendering(msg.data.browsingContext, msg.data.ignoreThrottledAnimations);
|
|
return promise.then(function (results) {
|
|
let errorStrings = [];
|
|
let warningStrings = [];
|
|
let infoStrings = [];
|
|
for (let r of results) {
|
|
if (r.status != "fulfilled") {
|
|
if (r.status == "pending") {
|
|
errorStrings.push("FlushRendering sendQuery to child promise still pending?");
|
|
} else {
|
|
// We expect actors to go away causing sendQuery's to fail, so
|
|
// just note it.
|
|
infoStrings.push("FlushRendering sendQuery to child promise rejected: " + r.reason);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
errorStrings.push(...r.value.errorStrings);
|
|
warningStrings.push(...r.value.warningStrings);
|
|
infoStrings.push(...r.value.infoStrings);
|
|
}
|
|
return {errorStrings, warningStrings, infoStrings};
|
|
});
|
|
}
|
|
case "UpdateLayerTree":
|
|
{
|
|
return this.tellChildrenToUpdateLayerTree(msg.data.browsingContext);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
}
|