Merge changes I85f52bd3,Ia91262e4,Ie084d288,I693815ff,If696d330, ...
* changes: WinScope: Support missing layers Winscope: Fix how layers with transforms and positions are rendered WinScope: Modify instead of replacing proto objects Support SF traces without any layers (needed when booting SF) Winscope: Translate layer flags in Surface flinger dump Update `Display default` checkbox label Add Type to transform objects. Fix visibility rule for SF traces on Winscope Allow SF traces to omit default values on the property list Fix "TypeError: Cannot read property 'x' of null" on SF traces Display only elements actually visible on the screen as "Visible" Display SF layer based on size, crop & parent instead of buffer size WinScope: Support boundless surfaces in WinScope Winscope: Use a unique stableId for all layers and wm entries Winscope: keep backwards compatibility prior to windowFrames
This commit is contained in:
@@ -17,6 +17,15 @@
|
||||
<md-whiteframe md-tag="md-toolbar">
|
||||
<h1 class="md-title" style="flex: 1">{{title}}</h1>
|
||||
|
||||
<div>
|
||||
<md-checkbox v-model="store.displayDefaults">Show default properties
|
||||
<md-tooltip md-direction="bottom">
|
||||
If checked, shows the value of all properties.
|
||||
Otherwise, hides all properties whose value is the default for its data type.
|
||||
</md-tooltip>
|
||||
</md-checkbox>
|
||||
</div>
|
||||
|
||||
<input type="file" @change="onLoadFile" id="upload-file" v-show="false"/>
|
||||
<label class="md-button md-accent md-raised md-theme-default" for="upload-file">Open File</label>
|
||||
|
||||
@@ -82,6 +91,7 @@ import LocalStore from './localstore.js'
|
||||
import {transform_json} from './transform.js'
|
||||
import {transform_layers, transform_layers_trace} from './transform_sf.js'
|
||||
import {transform_window_service, transform_window_trace} from './transform_wm.js'
|
||||
import {fill_transform_data, format_transform_type, is_simple_transform} from './matrix_utils.js'
|
||||
|
||||
|
||||
var protoDefs = protobuf.Root.fromJSON(jsonProtoDefs)
|
||||
@@ -98,14 +108,24 @@ function formatProto(obj) {
|
||||
if (!obj || !obj.$type) {
|
||||
return;
|
||||
}
|
||||
if (obj.$type.fullName === '.android.surfaceflinger.RectProto') {
|
||||
if (obj.$type.fullName === '.android.surfaceflinger.RectProto' ||
|
||||
obj.$type.fullName === '.android.graphics.RectProto') {
|
||||
return `(${obj.left}, ${obj.top}) - (${obj.right}, ${obj.bottom})`;
|
||||
} else if (obj.$type.fullName === '.android.surfaceflinger.PositionProto') {
|
||||
return `(${obj.x},${obj.y})`;
|
||||
} else if (obj.$type.fullName === '.android.surfaceflinger.FloatRectProto') {
|
||||
return `(${obj.left.toFixed(3)}, ${obj.top.toFixed(3)}) - (${obj.right.toFixed(3)}, ${obj.bottom.toFixed(3)})`;
|
||||
}
|
||||
else if (obj.$type.fullName === '.android.surfaceflinger.PositionProto') {
|
||||
return `(${obj.x.toFixed(3)}, ${obj.y.toFixed(3)})`;
|
||||
} else if (obj.$type.fullName === '.android.surfaceflinger.SizeProto') {
|
||||
return `${obj.w} x ${obj.h}`;
|
||||
} else if (obj.$type.fullName === '.android.surfaceflinger.ColorProto') {
|
||||
return `r:${obj.r} g:${obj.g} b:${obj.b} a:${obj.a}`;
|
||||
return `r:${obj.r} g:${obj.g} \n b:${obj.b} a:${obj.a}`;
|
||||
} else if (obj.$type.fullName === '.android.surfaceflinger.TransformProto') {
|
||||
var transform_type = format_transform_type(obj);
|
||||
if (is_simple_transform(obj)) {
|
||||
return `${transform_type}`;
|
||||
}
|
||||
return `${transform_type} dsdx:${obj.dsdx.toFixed(3)} dtdx:${obj.dtdx.toFixed(3)} dsdy:${obj.dsdy.toFixed(3)} dtdy:${obj.dtdy.toFixed(3)}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,6 +175,7 @@ export default {
|
||||
store: LocalStore('app', {
|
||||
flattened: false,
|
||||
onlyVisible: false,
|
||||
displayDefaults: true
|
||||
}),
|
||||
FILE_TYPES,
|
||||
fileType: "auto",
|
||||
@@ -189,9 +210,46 @@ export default {
|
||||
}
|
||||
this.title = this.filename + " (loading " + filetype.name + ")";
|
||||
|
||||
// Replace enum values with string representation and
|
||||
// add default values to the proto objects. This function also handles
|
||||
// a special case with TransformProtos where the matrix may be derived
|
||||
// from the transform type.
|
||||
function modifyProtoFields(protoObj, displayDefaults) {
|
||||
if (!protoObj || protoObj !== Object(protoObj) || !protoObj.$type) {
|
||||
return;
|
||||
}
|
||||
for (var fieldName in protoObj.$type.fields) {
|
||||
var fieldProperties = protoObj.$type.fields[fieldName];
|
||||
var field = protoObj[fieldName];
|
||||
|
||||
if (Array.isArray(field)) {
|
||||
field.forEach((item, _) => {
|
||||
modifyProtoFields(item, displayDefaults);
|
||||
})
|
||||
continue;
|
||||
}
|
||||
|
||||
if (displayDefaults && !(field)) {
|
||||
protoObj[fieldName] = fieldProperties.defaultValue;
|
||||
}
|
||||
|
||||
if (fieldProperties.type === 'TransformProto'){
|
||||
fill_transform_data(protoObj[fieldName]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fieldProperties.resolvedType && fieldProperties.resolvedType.valuesById) {
|
||||
protoObj[fieldName] = fieldProperties.resolvedType.valuesById[protoObj[fieldProperties.name]];
|
||||
continue;
|
||||
}
|
||||
|
||||
modifyProtoFields(protoObj[fieldName], displayDefaults);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
var decoded = filetype.protoType.decode(buffer);
|
||||
decoded = filetype.protoType.toObject(decoded, {enums: String, defaults: true});
|
||||
modifyProtoFields(decoded, this.store.displayDefaults);
|
||||
var transformed = filetype.transform(decoded);
|
||||
} catch (ex) {
|
||||
this.title = this.filename + " (loading " + filetype.name + "):" + ex;
|
||||
|
||||
@@ -65,7 +65,7 @@ export default {
|
||||
var w = this.s(r.right) - this.s(r.left);
|
||||
var h = this.s(r.bottom) - this.s(r.top);
|
||||
var t = r.transform;
|
||||
var tr = t ? `matrix(${t.dsdx}, ${t.dtdx}, ${t.dsdy}, ${t.dtdy}, 0, 0)` : '';
|
||||
var tr = t ? `matrix(${t.dsdx}, ${t.dtdx}, ${t.dsdy}, ${t.dtdy}, ${this.s(t.tx)}, ${this.s(t.ty)})` : '';
|
||||
return `top: ${y}px; left: ${x}px; height: ${h}px; width: ${w}px;` +
|
||||
`transform: ${tr}; transform-origin: 0 0;`
|
||||
},
|
||||
|
||||
175
tools/winscope/src/matrix_utils.js
Normal file
175
tools/winscope/src/matrix_utils.js
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright 2019, 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.
|
||||
*/
|
||||
|
||||
/* transform type flags */
|
||||
const TRANSLATE_VAL = 0x0001;
|
||||
const ROTATE_VAL = 0x0002;
|
||||
const SCALE_VAL = 0x0004;
|
||||
|
||||
/* orientation flags */
|
||||
const FLIP_H_VAL = 0x0100; // (1 << 0 << 8)
|
||||
const FLIP_V_VAL = 0x0200; // (1 << 1 << 8)
|
||||
const ROT_90_VAL = 0x0400; // (1 << 2 << 8)
|
||||
const ROT_INVALID_VAL = 0x8000; // (0x80 << 8)
|
||||
|
||||
function is_proto_2(transform) {
|
||||
/*
|
||||
* Checks if the loaded file was a stored with ProtoBuf2 or Protobuf3
|
||||
*
|
||||
* Proto2 files don't have a Type for the transform object but all other
|
||||
* fields of the transform are set.
|
||||
*
|
||||
* Proto3 has a type field for the transform but doesn't store default
|
||||
* values (0 for transform type), also, the framework/native implementation
|
||||
* doesn't write a transform in case it is an identity matrix.
|
||||
*/
|
||||
var propertyNames = Object.getOwnPropertyNames(transform);
|
||||
return (!propertyNames.includes("type") && propertyNames.includes("dsdx"));
|
||||
}
|
||||
|
||||
function is_simple_transform(transform) {
|
||||
transform = transform || {};
|
||||
if (is_proto_2(transform)) {
|
||||
return false;
|
||||
}
|
||||
return is_type_flag_clear(transform, ROT_INVALID_VAL|SCALE_VAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a transform type into readable format.
|
||||
* Adapted from the dump function from framework/native
|
||||
*
|
||||
* @param {*} transform Transform object ot be converter
|
||||
*/
|
||||
function format_transform_type(transform) {
|
||||
if (is_proto_2(transform)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (is_type_flag_clear(transform, SCALE_VAL | ROTATE_VAL | TRANSLATE_VAL)) {
|
||||
return "IDENTITY";
|
||||
}
|
||||
|
||||
var type_flags = [];
|
||||
if (is_type_flag_set(transform, SCALE_VAL)) {
|
||||
type_flags.push("SCALE");
|
||||
}
|
||||
if (is_type_flag_set(transform, TRANSLATE_VAL)) {
|
||||
type_flags.push("TRANSLATE");
|
||||
}
|
||||
|
||||
if (is_type_flag_set(transform, ROT_INVALID_VAL)) {
|
||||
type_flags.push("ROT_INVALID");
|
||||
} else if (is_type_flag_set(transform, ROT_90_VAL|FLIP_V_VAL|FLIP_H_VAL)) {
|
||||
type_flags.push("ROT_270");
|
||||
} else if (is_type_flag_set(transform, FLIP_V_VAL|FLIP_H_VAL)) {
|
||||
type_flags.push("ROT_180");
|
||||
} else {
|
||||
if (is_type_flag_set(transform, ROT_90_VAL)) {
|
||||
type_flags.push("ROT_90");
|
||||
}
|
||||
if (is_type_flag_set(transform, FLIP_V_VAL)) {
|
||||
type_flags.push("FLIP_V");
|
||||
}
|
||||
if (is_type_flag_set(transform, FLIP_H_VAL)) {
|
||||
type_flags.push("FLIP_H");
|
||||
}
|
||||
}
|
||||
|
||||
if (type_flags.length == 0) {
|
||||
throw "Unknown transform type " + transform ;
|
||||
}
|
||||
|
||||
return type_flags.join(', ');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ensures all values of the transform object are set.
|
||||
*/
|
||||
function fill_transform_data(transform) {
|
||||
function fill_simple_transform(transform) {
|
||||
// ROT_270 = ROT_90|FLIP_H|FLIP_V;
|
||||
if (is_type_flag_set(transform, ROT_90_VAL|FLIP_V_VAL|FLIP_H_VAL)) {
|
||||
transform.dsdx = 0.0;
|
||||
transform.dtdx = -1.0;
|
||||
transform.dsdy = 1.0;
|
||||
transform.dtdy = 0.0;
|
||||
return;
|
||||
}
|
||||
|
||||
// ROT_180 = FLIP_H|FLIP_V;
|
||||
if (is_type_flag_set(transform, FLIP_V_VAL|FLIP_H_VAL)) {
|
||||
transform.dsdx = -1.0;
|
||||
transform.dtdx = 0.0;
|
||||
transform.dsdy = 0.0;
|
||||
transform.dtdy = -1.0;
|
||||
return;
|
||||
}
|
||||
|
||||
// ROT_90
|
||||
if (is_type_flag_set(transform, ROT_90_VAL)) {
|
||||
transform.dsdx = 0.0;
|
||||
transform.dtdx = 1.0;
|
||||
transform.dsdy = -1.0;
|
||||
transform.dtdy = 0.0;
|
||||
return;
|
||||
}
|
||||
|
||||
// IDENTITY
|
||||
if (is_type_flag_clear(transform, SCALE_VAL | ROTATE_VAL)) {
|
||||
transform.dsdx = 1.0;
|
||||
transform.dtdx = 0.0;
|
||||
transform.dsdy = 0.0;
|
||||
transform.dtdy = 1.0;
|
||||
transform.type = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
throw "Unknown transform type " + transform;
|
||||
}
|
||||
|
||||
if (!transform) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_proto_2(transform)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_simple_transform(transform)){
|
||||
fill_simple_transform(transform);
|
||||
}
|
||||
|
||||
transform.dsdx = transform.dsdx || 0.0;
|
||||
transform.dtdx = transform.dtdx || 0.0;
|
||||
transform.dsdy = transform.dsdy || 0.0;
|
||||
transform.dtdy = transform.dtdy || 0.0;
|
||||
}
|
||||
|
||||
function is_type_flag_set(transform, bits) {
|
||||
transform = transform || {};
|
||||
var type = transform.type || 0;
|
||||
return (type & bits) === bits;
|
||||
}
|
||||
|
||||
function is_type_flag_clear(transform, bits) {
|
||||
transform = transform || {};
|
||||
var type = transform.type || 0;
|
||||
return (type & bits) === 0;
|
||||
}
|
||||
|
||||
export {format_transform_type, fill_transform_data, is_simple_transform};
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
function transform({obj, kind, name, children, timestamp, rect, bounds, highlight, rects_transform, chips, visible, flattened}) {
|
||||
function transform({obj, kind, name, children, timestamp, rect, bounds, highlight, rects_transform, chips, visible, flattened, stableId}) {
|
||||
function call(fn, arg) {
|
||||
return (typeof fn == 'function') ? fn(arg) : fn;
|
||||
}
|
||||
@@ -55,6 +55,9 @@ function transform({obj, kind, name, children, timestamp, rect, bounds, highligh
|
||||
var kindResolved = call(kind, obj);
|
||||
var nameResolved = call(name, obj);
|
||||
var rectResolved = call(rect, obj);
|
||||
var stableIdResolved = (stableId === undefined) ?
|
||||
kindResolved + '|-|' + nameResolved :
|
||||
call(stableId, obj);
|
||||
|
||||
var result = {
|
||||
kind: kindResolved,
|
||||
@@ -68,7 +71,7 @@ function transform({obj, kind, name, children, timestamp, rect, bounds, highligh
|
||||
rects: rects_transform(concat(rectResolved, transformed_children, (e) => e.rects)),
|
||||
highlight: call(highlight, obj),
|
||||
chips: call(chips, obj),
|
||||
stableId: kindResolved + "|-|" + nameResolved,
|
||||
stableId: stableIdResolved,
|
||||
visible: call(visible, obj),
|
||||
childrenVisible: transformed_children.some((c) => {
|
||||
return c.childrenVisible || c.visible
|
||||
|
||||
@@ -16,7 +16,11 @@
|
||||
|
||||
import {transform, nanos_to_string, get_visible_chip} from './transform.js'
|
||||
|
||||
const FLAG_HIDDEN = 0x1;
|
||||
// Layer flags
|
||||
const FLAG_HIDDEN = 0x01;
|
||||
const FLAG_OPAQUE = 0x02;
|
||||
const FLAG_SECURE = 0x80;
|
||||
|
||||
var RELATIVE_Z_CHIP = {short: 'RelZ',
|
||||
long: "Is relative Z-ordered to another surface",
|
||||
class: 'warn'};
|
||||
@@ -27,36 +31,139 @@ 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 || {};
|
||||
function transform_layer(layer, {parentBounds, parentHidden}) {
|
||||
|
||||
function get_size(layer) {
|
||||
var size = layer.size || {w: 0, h: 0};
|
||||
return {
|
||||
left: pos.x || 0,
|
||||
right: pos.x + size.w || 0,
|
||||
top: pos.y || 0,
|
||||
bottom: pos.y + size.h || 0,
|
||||
label: layer.name,
|
||||
transform: layer.transform,
|
||||
left: 0,
|
||||
right: size.w,
|
||||
top: 0,
|
||||
bottom: size.h
|
||||
};
|
||||
}
|
||||
|
||||
function get_crop(layer) {
|
||||
var crop = layer.crop || {left: 0, top: 0, right: 0 , bottom:0};
|
||||
return {
|
||||
left: crop.left || 0,
|
||||
right: crop.right || 0,
|
||||
top: crop.top || 0,
|
||||
bottom: crop.bottom || 0
|
||||
};
|
||||
}
|
||||
|
||||
function intersect(bounds, crop) {
|
||||
return {
|
||||
left: Math.max(crop.left, bounds.left),
|
||||
right: Math.min(crop.right, bounds.right),
|
||||
top: Math.max(crop.top, bounds.top),
|
||||
bottom: Math.min(crop.bottom, bounds.bottom),
|
||||
};
|
||||
}
|
||||
|
||||
function is_empty_rect(rect) {
|
||||
var right = rect.right || 0;
|
||||
var left = rect.left || 0;
|
||||
var top = rect.top || 0;
|
||||
var bottom = rect.bottom || 0;
|
||||
|
||||
return (right - left) <= 0 || (bottom - top) <= 0;
|
||||
}
|
||||
|
||||
function get_cropped_bounds(layer, parentBounds) {
|
||||
var size = get_size(layer);
|
||||
var crop = get_crop(layer);
|
||||
if (!is_empty_rect(size) && !is_empty_rect(crop)) {
|
||||
return intersect(size, crop);
|
||||
}
|
||||
if (!is_empty_rect(size)) {
|
||||
return size;
|
||||
}
|
||||
if (!is_empty_rect(crop)) {
|
||||
return crop;
|
||||
}
|
||||
return parentBounds || { left: 0, right: 0, top: 0, bottom: 0 };
|
||||
}
|
||||
|
||||
function offset_to(bounds, x, y) {
|
||||
return {
|
||||
right: bounds.right - (bounds.left - x),
|
||||
bottom: bounds.bottom - (bounds.top - y),
|
||||
left: x,
|
||||
top: y,
|
||||
};
|
||||
}
|
||||
|
||||
function transform_bounds(layer, parentBounds) {
|
||||
var result = layer.bounds || get_cropped_bounds(layer, parentBounds);
|
||||
var tx = (layer.position) ? layer.position.x || 0 : 0;
|
||||
var ty = (layer.position) ? layer.position.y || 0 : 0;
|
||||
result = offset_to(result, 0, 0);
|
||||
result.label = layer.name;
|
||||
result.transform = layer.transform;
|
||||
result.transform.tx = tx;
|
||||
result.transform.ty = ty;
|
||||
return result;
|
||||
}
|
||||
|
||||
function is_opaque(layer) {
|
||||
return layer.color == undefined || (layer.color.a || 0) > 0;
|
||||
}
|
||||
|
||||
function is_empty(region) {
|
||||
return region == undefined ||
|
||||
region.rect == undefined ||
|
||||
region.rect.length == 0 ||
|
||||
region.rect.every(function(r) { return is_empty_rect(r) } );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the layer is visible on screen according to its type,
|
||||
* active buffer content, alpha and visible regions.
|
||||
*
|
||||
* @param {layer} layer
|
||||
* @returns if the layer is visible on screen or not
|
||||
*/
|
||||
function is_visible(layer) {
|
||||
var visible = (layer.activeBuffer || layer.type === 'ColorLayer')
|
||||
&& !hidden && is_opaque(layer);
|
||||
visible &= !is_empty(layer.visibleRegion);
|
||||
return visible;
|
||||
}
|
||||
|
||||
function postprocess_flags(layer) {
|
||||
if (!layer.flags) return;
|
||||
var verboseFlags = [];
|
||||
if (layer.flags & FLAG_HIDDEN) {
|
||||
verboseFlags.push("HIDDEN");
|
||||
}
|
||||
if (layer.flags & FLAG_OPAQUE) {
|
||||
verboseFlags.push("OPAQUE");
|
||||
}
|
||||
if (layer.flags & FLAG_SECURE) {
|
||||
verboseFlags.push("SECURE");
|
||||
}
|
||||
|
||||
layer.flags = verboseFlags.join('|') + " (" + layer.flags + ")";
|
||||
}
|
||||
|
||||
var chips = [];
|
||||
var rect = transform_rect(layer);
|
||||
var rect = transform_bounds(layer, parentBounds);
|
||||
var hidden = (layer.flags & FLAG_HIDDEN) != 0 || parentHidden;
|
||||
var visible = (layer.activeBuffer || layer.type === 'ColorLayer')
|
||||
&& !hidden && layer.color.a > 0;
|
||||
var visible = is_visible(layer);
|
||||
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.name.startsWith("Display Root#0") && layer.sourceBounds) {
|
||||
bounds = {width: layer.sourceBounds.right, height: layer.sourceBounds.bottom};
|
||||
}
|
||||
if (layer.zOrderRelativeOf !== -1) {
|
||||
|
||||
if ((layer.zOrderRelativeOf || -1) !== -1) {
|
||||
chips.push(RELATIVE_Z_CHIP);
|
||||
}
|
||||
if (layer.zOrderRelativeParentOf !== undefined) {
|
||||
@@ -67,7 +174,9 @@ function transform_layer(layer, {parentHidden}) {
|
||||
}
|
||||
|
||||
var transform_layer_with_parent_hidden =
|
||||
(layer) => transform_layer(layer, {parentHidden: hidden});
|
||||
(layer) => transform_layer(layer, {parentBounds: rect, parentHidden: hidden});
|
||||
|
||||
postprocess_flags(layer);
|
||||
|
||||
return transform({
|
||||
obj: layer,
|
||||
@@ -89,16 +198,20 @@ function missingLayer(childId) {
|
||||
name: "layer #" + childId,
|
||||
missing: true,
|
||||
zOrderRelativeOf: -1,
|
||||
transform: {dsdx:1, dtdx:0, dsdy:0, dtdy:1},
|
||||
}
|
||||
}
|
||||
|
||||
function transform_layers(layers) {
|
||||
var idToItem = {};
|
||||
var isChild = {}
|
||||
layers.layers.forEach((e) => {
|
||||
|
||||
var layersList = layers.layers || [];
|
||||
|
||||
layersList.forEach((e) => {
|
||||
idToItem[e.id] = e;
|
||||
});
|
||||
layers.layers.forEach((e) => {
|
||||
layersList.forEach((e) => {
|
||||
e.resolvedChildren = [];
|
||||
if (Array.isArray(e.children)) {
|
||||
e.resolvedChildren = e.children.map(
|
||||
@@ -107,11 +220,12 @@ function transform_layers(layers) {
|
||||
isChild[childId] = true;
|
||||
});
|
||||
}
|
||||
if (e.zOrderRelativeOf !== -1) {
|
||||
if ((e.zOrderRelativeOf || -1) !== -1) {
|
||||
idToItem[e.zOrderRelativeOf].zOrderRelativeParentOf = e.id;
|
||||
}
|
||||
});
|
||||
var roots = layers.layers.filter((e) => !isChild[e.id]);
|
||||
|
||||
var roots = layersList.filter((e) => !isChild[e.id]);
|
||||
|
||||
function foreachTree(nodes, fun) {
|
||||
nodes.forEach((n) => {
|
||||
@@ -121,12 +235,15 @@ function transform_layers(layers) {
|
||||
}
|
||||
|
||||
var idToTransformed = {};
|
||||
var transformed_roots = roots.map(transform_layer);
|
||||
var transformed_roots = roots.map((r) =>
|
||||
transform_layer(r, {parentBounds: {left: 0, right: 0, top: 0, bottom: 0},
|
||||
parentHidden: false}));
|
||||
|
||||
foreachTree(transformed_roots, (n) => {
|
||||
idToTransformed[n.obj.id] = n;
|
||||
});
|
||||
var flattened = [];
|
||||
layers.layers.forEach((e) => {
|
||||
layersList.forEach((e) => {
|
||||
flattened.push(idToTransformed[e.id]);
|
||||
});
|
||||
|
||||
@@ -159,11 +276,12 @@ function transform_layers_entry(entry) {
|
||||
[[entry.layers], transform_layers],
|
||||
],
|
||||
timestamp: entry.elapsedRealtimeNanos,
|
||||
stableId: 'entry',
|
||||
});
|
||||
}
|
||||
|
||||
function transform_layers_trace(entries) {
|
||||
return transform({
|
||||
var r = transform({
|
||||
obj: entries,
|
||||
kind: 'layerstrace',
|
||||
name: 'layerstrace',
|
||||
@@ -171,6 +289,8 @@ function transform_layers_trace(entries) {
|
||||
[entries.entry, transform_layers_entry],
|
||||
],
|
||||
});
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
export {transform_layers, transform_layers_trace};
|
||||
|
||||
@@ -31,7 +31,7 @@ function transform_window(entry) {
|
||||
}
|
||||
}
|
||||
var name = renderIdentifier(entry.identifier)
|
||||
var rect = transform_rect(entry.windowFrames.frame, name);
|
||||
var rect = transform_rect((entry.windowFrames || entry).frame, name);
|
||||
|
||||
if (visible) {
|
||||
chips.push(get_visible_chip());
|
||||
@@ -182,6 +182,7 @@ function transform_entry(entry) {
|
||||
[[entry.windowManagerService.policy], transform_policy],
|
||||
],
|
||||
timestamp: entry.elapsedRealtimeNanos,
|
||||
stableId: 'entry',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user