/*
* Copyright 2017, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {transform, nanos_to_string, get_visible_chip} from './transform.js'
const FLAG_HIDDEN = 0x1;
var RELATIVE_Z_CHIP = {short: 'RelZ',
long: "Is relative Z-ordered to another surface",
class: 'warn'};
var RELATIVE_Z_PARENT_CHIP = {short: 'RelZParent',
long: "Something is relative Z-ordered to this surface",
class: 'warn'};
var MISSING_LAYER = {short: 'MissingLayer',
long: "This layer was referenced from the parent, but not present in the trace",
class: 'error'};
function transform_layer(layer, {parentHidden}) {
function transform_rect(layer) {
var pos = layer.position || {};
var size = layer.size || {};
return {
left: pos.x || 0,
right: pos.x + size.w || 0,
top: pos.y || 0,
bottom: pos.y + size.h || 0,
label: layer.name,
}
}
var chips = [];
var rect = transform_rect(layer);
var hidden = (layer.flags & FLAG_HIDDEN) != 0 || parentHidden;
var visible = (layer.activeBuffer || layer.type === 'ColorLayer')
&& !hidden && layer.color.a > 0;
if (visible) {
chips.push(get_visible_chip());
} else {
rect = undefined;
}
var bounds = undefined;
if (layer.name.startsWith("Display Root#0")) {
bounds = {width: layer.size.w, height: layer.size.h};
}
if (layer.zOrderRelativeOf !== -1) {
chips.push(RELATIVE_Z_CHIP);
}
if (layer.zOrderRelativeParentOf !== undefined) {
chips.push(RELATIVE_Z_PARENT_CHIP);
}
if (layer.missing) {
chips.push(MISSING_LAYER);
}
var transform_layer_with_parent_hidden =
(layer) => transform_layer(layer, {parentHidden: hidden});
return transform({
obj: layer,
kind: 'layer',
name: layer.name,
children: [
[layer.resolvedChildren, transform_layer_with_parent_hidden],
],
rect,
bounds,
highlight: rect,
chips,
visible,
});
}
function missingLayer(childId) {
return {
name: "layer #" + childId,
missing: true,
zOrderRelativeOf: -1,
}
}
function transform_layers(layers) {
var idToItem = {};
var isChild = {}
layers.layers.forEach((e) => {
idToItem[e.id] = e;
});
layers.layers.forEach((e) => {
e.resolvedChildren = [];
if (Array.isArray(e.children)) {
e.resolvedChildren = e.children.map(
(childId) => idToItem[childId] || missingLayer(childId));
e.children.forEach((childId) => {
isChild[childId] = true;
});
}
if (e.zOrderRelativeOf !== -1) {
idToItem[e.zOrderRelativeOf].zOrderRelativeParentOf = e.id;
}
});
var roots = layers.layers.filter((e) => !isChild[e.id]);
function foreachTree(nodes, fun) {
nodes.forEach((n) => {
fun(n);
foreachTree(n.children, fun);
});
}
var idToTransformed = {};
var transformed_roots = roots.map(transform_layer);
foreachTree(transformed_roots, (n) => {
idToTransformed[n.obj.id] = n;
});
var flattened = [];
layers.layers.forEach((e) => {
flattened.push(idToTransformed[e.id]);
});
return transform({
obj: {},
kind: 'layers',
name: 'layers',
children: [
[transformed_roots, (c) => c],
],
rects_transform (r) {
var res = [];
flattened.forEach((l) => {
if (l.rect) {
res.push(l.rect);
}
});
return res.reverse();
},
flattened,
});
}
function transform_layers_entry(entry) {
return transform({
obj: entry,
kind: 'entry',
name: nanos_to_string(entry.elapsedRealtimeNanos) + " - " + entry.where,
children: [
[[entry.layers], transform_layers],
],
timestamp: entry.elapsedRealtimeNanos,
});
}
function transform_layers_trace(entries) {
return transform({
obj: entries,
kind: 'layerstrace',
name: 'layerstrace',
children: [
[entries.entry, transform_layers_entry],
],
});
}
export {transform_layers, transform_layers_trace};