summaryrefslogtreecommitdiffstats
path: root/layout/tools/reftest/ReftestFissionParent.sys.mjs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /layout/tools/reftest/ReftestFissionParent.sys.mjs
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'layout/tools/reftest/ReftestFissionParent.sys.mjs')
-rw-r--r--layout/tools/reftest/ReftestFissionParent.sys.mjs295
1 files changed, 295 insertions, 0 deletions
diff --git a/layout/tools/reftest/ReftestFissionParent.sys.mjs b/layout/tools/reftest/ReftestFissionParent.sys.mjs
new file mode 100644
index 0000000000..044f3de54d
--- /dev/null
+++ b/layout/tools/reftest/ReftestFissionParent.sys.mjs
@@ -0,0 +1,295 @@
+export class ReftestFissionParent extends JSWindowActorParent {
+ tellChildrenToFlushRendering(
+ browsingContext,
+ ignoreThrottledAnimations,
+ needsAnimationFrame
+ ) {
+ let promises = [];
+ this.tellChildrenToFlushRenderingRecursive(
+ browsingContext,
+ ignoreThrottledAnimations,
+ needsAnimationFrame,
+ promises
+ );
+ return Promise.allSettled(promises);
+ }
+
+ tellChildrenToFlushRenderingRecursive(
+ browsingContext,
+ ignoreThrottledAnimations,
+ needsAnimationFrame,
+ promises
+ ) {
+ let cwg = browsingContext.currentWindowGlobal;
+ if (cwg && cwg.isProcessRoot) {
+ let a = cwg.getActor("ReftestFission");
+ if (a) {
+ let responsePromise = a.sendQuery("FlushRendering", {
+ ignoreThrottledAnimations,
+ needsAnimationFrame,
+ });
+ promises.push(responsePromise);
+ }
+ }
+
+ for (let context of browsingContext.children) {
+ this.tellChildrenToFlushRenderingRecursive(
+ context,
+ ignoreThrottledAnimations,
+ needsAnimationFrame,
+ 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 };
+ }
+
+ tellChildrenToSetupDisplayport(browsingContext, promises) {
+ let cwg = browsingContext.currentWindowGlobal;
+ if (cwg && cwg.isProcessRoot) {
+ let a = cwg.getActor("ReftestFission");
+ if (a) {
+ let responsePromise = a.sendQuery("SetupDisplayport");
+ promises.push(responsePromise);
+ }
+ }
+
+ for (let context of browsingContext.children) {
+ this.tellChildrenToSetupDisplayport(context, promises);
+ }
+ }
+
+ tellChildrenToSetupAsyncScrollOffsets(
+ browsingContext,
+ allowFailure,
+ promises
+ ) {
+ let cwg = browsingContext.currentWindowGlobal;
+ if (cwg && cwg.isProcessRoot) {
+ let a = cwg.getActor("ReftestFission");
+ if (a) {
+ let responsePromise = a.sendQuery("SetupAsyncScrollOffsets", {
+ allowFailure,
+ });
+ promises.push(responsePromise);
+ }
+ }
+
+ for (let context of browsingContext.children) {
+ this.tellChildrenToSetupAsyncScrollOffsets(
+ context,
+ allowFailure,
+ promises
+ );
+ }
+ }
+
+ 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,
+ msg.data.needsAnimationFrame
+ );
+ 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);
+ }
+ case "TellChildrenToSetupDisplayport": {
+ let promises = [];
+ this.tellChildrenToSetupDisplayport(msg.data.browsingContext, promises);
+ return Promise.allSettled(promises).then(function (results) {
+ let errorStrings = [];
+ let infoStrings = [];
+ for (let r of results) {
+ if (r.status != "fulfilled") {
+ // We expect actors to go away causing sendQuery's to fail, so
+ // just note it.
+ infoStrings.push(
+ "SetupDisplayport sendQuery to child promise rejected: " +
+ r.reason
+ );
+ continue;
+ }
+
+ errorStrings.push(...r.value.errorStrings);
+ infoStrings.push(...r.value.infoStrings);
+ }
+ return { errorStrings, infoStrings };
+ });
+ }
+
+ case "SetupAsyncScrollOffsets": {
+ let promises = [];
+ this.tellChildrenToSetupAsyncScrollOffsets(
+ this.manager.browsingContext,
+ msg.data.allowFailure,
+ promises
+ );
+ return Promise.allSettled(promises).then(function (results) {
+ let errorStrings = [];
+ let infoStrings = [];
+ let updatedAny = false;
+ for (let r of results) {
+ if (r.status != "fulfilled") {
+ // We expect actors to go away causing sendQuery's to fail, so
+ // just note it.
+ infoStrings.push(
+ "SetupAsyncScrollOffsets sendQuery to child promise rejected: " +
+ r.reason
+ );
+ continue;
+ }
+
+ errorStrings.push(...r.value.errorStrings);
+ infoStrings.push(...r.value.infoStrings);
+ if (r.value.updatedAny) {
+ updatedAny = true;
+ }
+ }
+ return { errorStrings, infoStrings, updatedAny };
+ });
+ }
+ }
+ return undefined;
+ }
+}