Bug 1251608 - Add a root-content annotation to the APZ test data structure. r=botond
This patch adds the annotation in APZCTreeManager. It also changes the
tree-building code in apz_test_utils to link together the actual paint
structures rather than create new wrapper nodes. This is more foolproof
(fixes a latent bug where a grandchild node whose parent has not yet
been processed ends up with the parent forcibly made a child of the root),
and allows extra properties to seamlessly ride along into the "tree".
MozReview-Commit-ID: B4T4cYyglQ7
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -487,16 +487,20 @@ APZCTreeManager::PrepareNodeForLayer(con
if (apzc->HasNoParentWithSameLayersId()) {
aState.mPaintLogger.LogTestData(aMetrics.GetScrollId(),
"hasNoParentWithSameLayersId", true);
} else {
MOZ_ASSERT(apzc->GetParent());
aState.mPaintLogger.LogTestData(aMetrics.GetScrollId(),
"parentScrollId", apzc->GetParent()->GetGuid().mScrollId);
}
+ if (aMetrics.IsRootContent()) {
+ aState.mPaintLogger.LogTestData(aMetrics.GetScrollId(),
+ "isRootContent", true);
+ }
}
if (newApzc) {
auto it = mZoomConstraints.find(guid);
if (it != mZoomConstraints.end()) {
// We have a zoomconstraints for this guid, apply it.
apzc->UpdateZoomConstraints(it->second);
} else if (!apzc->HasNoParentWithSameLayersId()) {
--- a/gfx/layers/apz/test/mochitest/apz_test_utils.js
+++ b/gfx/layers/apz/test/mochitest/apz_test_utils.js
@@ -34,75 +34,56 @@ function convertBuckets(buckets) {
function convertTestData(testData) {
var result = {};
result.paints = convertBuckets(testData.paints);
result.repaintRequests = convertBuckets(testData.repaintRequests);
return result;
}
-// ----------------------------------------------------------------
-// Utilities for reconstructing the structure of the APZC tree from
-// 'parentScrollId' entries in the APZ test data.
-// ----------------------------------------------------------------
-
-// Create a node with scroll id 'id' in the APZC tree.
-function makeNode(id) {
- return {scrollId: id, children: []};
-}
-
-// Find a node with scroll id 'id' in the APZC tree rooted at 'root'.
-function findNode(root, id) {
- if (root.scrollId == id) {
- return root;
- }
- for (var i = 0; i < root.children.length; ++i) {
- var subtreeResult = findNode(root.children[i], id);
- if (subtreeResult != null) {
- return subtreeResult;
- }
- }
- return null;
-}
-
-// Add a child -> parent link to the APZC tree rooted at 'root'.
-function addLink(root, child, parent) {
- var parentNode = findNode(root, parent);
- if (parentNode == null) {
- parentNode = makeNode(parent);
- root.children.push(parentNode);
- }
- parentNode.children.push(makeNode(child));
-}
-
-// Add a root node to the APZC tree. It will become a direct
-// child of 'root'.
-function addRoot(root, id) {
- root.children.push(makeNode(id));
-}
-
// Given APZ test data for a single paint on the compositor side,
// reconstruct the APZC tree structure from the 'parentScrollId'
// entries that were logged. More specifically, the subset of the
// APZC tree structure corresponding to the layer subtree for the
// content process that triggered the paint, is reconstructed (as
// the APZ test data only contains information abot this subtree).
function buildApzcTree(paint) {
// The APZC tree can potentially have multiple root nodes,
// so we invent a node that is the parent of all roots.
// This 'root' does not correspond to an APZC.
- var root = makeNode(-1);
+ var root = {scrollId: -1, children: []};
for (var scrollId in paint) {
+ paint[scrollId].children = [];
+ paint[scrollId].scrollId = scrollId;
+ }
+ for (var scrollId in paint) {
+ var parentNode = null;
if ("hasNoParentWithSameLayersId" in paint[scrollId]) {
- addRoot(root, scrollId);
+ parentNode = root;
} else if ("parentScrollId" in paint[scrollId]) {
- addLink(root, scrollId, paint[scrollId]["parentScrollId"]);
+ parentNode = paint[paint[scrollId].parentScrollId];
+ }
+ parentNode.children.push(paint[scrollId]);
+ }
+ return root;
+}
+
+// Given an APZC tree produced by buildApzcTree, return the RCD node in
+// the tree, or null if there was none.
+function findRcdNode(apzcTree) {
+ if (!!apzcTree.isRootContent) { // isRootContent will be undefined or "1"
+ return apzcTree;
+ }
+ for (var i = 0; i < apzcTree.children.length; i++) {
+ var rcd = findRcdNode(apzcTree.children[i]);
+ if (rcd != null) {
+ return rcd;
}
}
- return root;
+ return null;
}
function flushApzRepaints(aCallback, aWindow = window) {
if (!aCallback) {
throw "A callback must be provided!";
}
var repaintDone = function() {
SpecialPowers.Services.obs.removeObserver(repaintDone, "apz-repaints-flushed", false);