Winscope: group surfaceflinger trace properties 1/2
Make it easier to understand surface flinger traces by: - grouping similar properties - adding tooltips demystifying some of the derived properties - cleaning up property names Test: go/winscope load traces Bug: 200284593 Change-Id: Ia8ea55b4b4c2bef1fc38228d3e9738231be403bb
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
:summarizer="summarizer"
|
||||
:presentTags="[]"
|
||||
:presentErrors="[]"
|
||||
:propertyGroups="false"
|
||||
/>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
:file="file"
|
||||
:presentTags="[]"
|
||||
:presentErrors="[]"
|
||||
:propertyGroups="false"
|
||||
ref="view"
|
||||
/>
|
||||
<div v-else>
|
||||
|
||||
307
tools/winscope/src/SurfaceFlingerPropertyGroups.vue
Normal file
307
tools/winscope/src/SurfaceFlingerPropertyGroups.vue
Normal file
@@ -0,0 +1,307 @@
|
||||
<!-- Copyright (C) 2022 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.
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<div class="group">
|
||||
<span class="group-header">Geometry</span>
|
||||
<div class="left-column">
|
||||
<div class="column-header">Calculated</div>
|
||||
<span class="key">Transform:</span>
|
||||
<TransformMatrix :transform="layer.transform" />
|
||||
<div />
|
||||
<span class="key"
|
||||
>Crop:<md-tooltip
|
||||
>Raw value read from proto.bounds. This is the buffer size or
|
||||
requested crop cropped by parent bounds.</md-tooltip
|
||||
>
|
||||
</span>
|
||||
<span class="value">{{ layer.bounds }}</span>
|
||||
<div />
|
||||
<span class="key"
|
||||
>Final Bounds:<md-tooltip
|
||||
>Raw value read from proto.screenBounds. This is the calculated crop
|
||||
transformed.</md-tooltip
|
||||
></span
|
||||
>
|
||||
<span class="value">{{ layer.screenBounds }}</span>
|
||||
</div>
|
||||
<div class="right-column">
|
||||
<div class="column-header">Requested</div>
|
||||
<span class="key">Transform:</span>
|
||||
<TransformMatrix :transform="layer.requestedTransform" />
|
||||
<div />
|
||||
<span class="key">Crop:</span>
|
||||
<span class="value">{{ layer.crop ? layer.crop : "[empty]" }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group">
|
||||
<span class="group-header">
|
||||
<span class="group-heading">Buffer</span>
|
||||
</span>
|
||||
<div v-if="layer.isBufferLayer" class="left-column">
|
||||
<div />
|
||||
<span class="key">Size:</span>
|
||||
<span class="value">{{ layer.activeBuffer }}</span>
|
||||
<div />
|
||||
<span class="key">Frame Number:</span>
|
||||
<span class="value">{{ layer.currFrame }}</span>
|
||||
<div />
|
||||
<span class="key"
|
||||
>Transform:<md-tooltip
|
||||
>Rotates or flips the buffer in place. Used with display transform
|
||||
hint to cancel out any buffer transformation when sending to
|
||||
HWC.</md-tooltip
|
||||
></span
|
||||
>
|
||||
<span class="value">{{ layer.bufferTransform }}</span>
|
||||
</div>
|
||||
<div v-if="layer.isBufferLayer" class="right-column">
|
||||
<div />
|
||||
<span class="key"
|
||||
>Destination Frame:<md-tooltip
|
||||
>Scales buffer to the frame by overriding the requested transform
|
||||
for this layer.</md-tooltip
|
||||
></span
|
||||
>
|
||||
<span class="value">{{ layer.proto.destinationFrame }}</span>
|
||||
<div />
|
||||
<span
|
||||
v-if="(layer.flags & 0x400) /*eIgnoreDestinationFrame*/ === 0x400"
|
||||
class="value"
|
||||
>Destination Frame ignored because layer has eIgnoreDestinationFrame
|
||||
flag set.</span
|
||||
>
|
||||
</div>
|
||||
<div v-if="layer.isContainerLayer" class="left-column">
|
||||
<span class="key"></span> <span class="value">Container layer</span>
|
||||
</div>
|
||||
<div v-if="layer.isEffectLayer" class="left-column">
|
||||
<span class="key"></span> <span class="value">Effect layer</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group">
|
||||
<span class="group-header">
|
||||
<span class="group-heading">Hierarchy</span>
|
||||
</span>
|
||||
<div class="left-column">
|
||||
<div />
|
||||
<span class="key">z-order:</span>
|
||||
<span class="value">{{ layer.z }}</span>
|
||||
<div />
|
||||
<span class="key"
|
||||
>relative parent:<md-tooltip
|
||||
>Layer is z-ordered relative to its relative parents but its bounds
|
||||
and other properties are inherited from its parents.</md-tooltip
|
||||
></span
|
||||
>
|
||||
<span class="value">{{
|
||||
layer.zOrderRelativeOfId == -1 ? "none" : layer.zOrderRelativeOfId
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group">
|
||||
<span class="group-header">
|
||||
<span class="group-heading">Effects</span>
|
||||
</span>
|
||||
<div class="left-column">
|
||||
<div class="column-header">Calculated</div>
|
||||
<span class="key">Color:</span>
|
||||
<span class="value">{{ layer.color }}</span>
|
||||
<div />
|
||||
<span class="key">Shadow:</span>
|
||||
<span class="value">{{ layer.shadowRadius }} px</span>
|
||||
<div />
|
||||
<span class="key">Corner Radius:</span>
|
||||
<span class="value"
|
||||
>radius:{{ formatFloat(layer.cornerRadius) }} px</span
|
||||
>
|
||||
<div />
|
||||
<span class="key"
|
||||
>Corner Radius Crop:<md-tooltip
|
||||
>Crop used to define the bounds of the corner radii. If the bounds
|
||||
are greater than the layer bounds then the rounded corner will not
|
||||
be visible.</md-tooltip
|
||||
></span
|
||||
>
|
||||
<span class="value">{{ layer.cornerRadiusCrop }}</span>
|
||||
<div />
|
||||
<span class="key">Blur:</span>
|
||||
<span class="value"
|
||||
>{{
|
||||
layer.proto.backgroundBlurRadius
|
||||
? layer.proto.backgroundBlurRadius
|
||||
: 0
|
||||
}}
|
||||
px</span
|
||||
>
|
||||
</div>
|
||||
<div class="right-column">
|
||||
<div class="column-header">Requested</div>
|
||||
<span class="key">Color:</span>
|
||||
<span class="value">{{ layer.requestedColor }}</span>
|
||||
<div />
|
||||
<span class="key">Shadow:</span>
|
||||
<span class="value"
|
||||
>{{
|
||||
layer.proto.requestedShadowRadius
|
||||
? layer.proto.requestedShadowRadius
|
||||
: 0
|
||||
}}
|
||||
px</span
|
||||
>
|
||||
<div />
|
||||
<span class="key">Corner Radius:</span>
|
||||
<span class="value"
|
||||
>{{
|
||||
layer.proto.requestedCornerRadius
|
||||
? formatFloat(layer.proto.requestedCornerRadius)
|
||||
: 0
|
||||
}}
|
||||
px</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group">
|
||||
<span class="group-header">
|
||||
<span class="group-heading">Input</span>
|
||||
</span>
|
||||
<div v-if="layer.proto.inputWindowInfo" class="left-column">
|
||||
<span class="key">To Display Transform:</span>
|
||||
<TransformMatrix :transform="layer.inputTransform" />
|
||||
<div />
|
||||
<span class="key">Touchable Region:</span>
|
||||
<span class="value">{{ layer.inputRegion }}</span>
|
||||
</div>
|
||||
<div v-if="layer.proto.inputWindowInfo" class="right-column">
|
||||
<span class="key">Config:</span>
|
||||
<span class="value"></span>
|
||||
<div />
|
||||
<span class="key">Focusable:</span>
|
||||
<span class="value">{{ layer.proto.inputWindowInfo.focusable }}</span>
|
||||
<div />
|
||||
<span class="key">Crop touch region with layer:</span>
|
||||
<span class="value">{{
|
||||
layer.proto.inputWindowInfo.cropLayerId <= 0
|
||||
? "none"
|
||||
: layer.proto.inputWindowInfo.cropLayerId
|
||||
}}</span>
|
||||
<div />
|
||||
<span class="key">Replace touch region with crop:</span>
|
||||
<span class="value">{{
|
||||
layer.proto.inputWindowInfo.replaceTouchableRegionWithCrop
|
||||
}}</span>
|
||||
</div>
|
||||
<div v-if="!layer.proto.inputWindowInfo" class="left-column">
|
||||
<span class="key"></span>
|
||||
<span class="value">No input channel set</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="group">
|
||||
<span class="group-header">
|
||||
<span class="group-heading">Visibility</span>
|
||||
</span>
|
||||
<div class="left-column">
|
||||
<span class="key">Flags:</span>
|
||||
<span class="value">{{ layer.flags }}</span>
|
||||
<div />
|
||||
<div v-if="visibilityReason">
|
||||
<div v-for="reason in visibilityReason" v-bind:key="reason.key">
|
||||
<span class="key">{{ reason.key }}:</span>
|
||||
<span class="value">{{ reason.value }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TransformMatrix from "@/TransformMatrix.vue";
|
||||
|
||||
export default {
|
||||
name: "SurfaceFlingerPropertyGroups",
|
||||
props: ["layer", "visibilityReason"],
|
||||
components: {
|
||||
TransformMatrix,
|
||||
},
|
||||
methods: {
|
||||
formatFloat(num) {
|
||||
return Math.round(num * 100) / 100;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.group {
|
||||
padding: 0.5rem;
|
||||
border-bottom: thin solid rgba(0, 0, 0, 0.12);
|
||||
flex-direction: row;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.group .key {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.group .value {
|
||||
color: rgba(0, 0, 0, 0.75);
|
||||
}
|
||||
|
||||
.group-header {
|
||||
justify-content: center;
|
||||
padding: 0px 5px;
|
||||
width: 80px;
|
||||
display: inline-block;
|
||||
font-size: bigger;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.left-column {
|
||||
width: 320px;
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
overflow: auto;
|
||||
border-right: 5px solid rgba(#000, 0.12);
|
||||
padding-right: 20px;
|
||||
}
|
||||
.right-column {
|
||||
width: 320px;
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
overflow: auto;
|
||||
border: 1px solid rgba(#000, 0.12);
|
||||
}
|
||||
|
||||
.column-header {
|
||||
font-weight: lighter;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.element-summary {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.element-summary .key {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.element-summary .value {
|
||||
color: rgba(0, 0, 0, 0.75);
|
||||
}
|
||||
</style>
|
||||
@@ -20,6 +20,7 @@
|
||||
:summarizer="summarizer"
|
||||
:presentTags="presentTags"
|
||||
:presentErrors="presentErrors"
|
||||
:propertyGroups="true"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -36,7 +37,7 @@ export default {
|
||||
summarizer(layer) {
|
||||
const summary = [];
|
||||
|
||||
if (layer?.visibilityReason) {
|
||||
if (layer?.visibilityReason.length > 0) {
|
||||
let reason = "";
|
||||
if (Array.isArray(layer.visibilityReason)) {
|
||||
reason = layer.visibilityReason.join(", ");
|
||||
|
||||
@@ -111,12 +111,17 @@
|
||||
</md-field>
|
||||
</md-content>
|
||||
<div class="properties-content">
|
||||
<div v-if="elementSummary" class="element-summary">
|
||||
<div v-if="elementSummary && !propertyGroups" class="element-summary">
|
||||
<div v-for="elem in elementSummary" v-bind:key="elem.key">
|
||||
<!-- eslint-disable-next-line max-len -->
|
||||
<span class="key">{{ elem.key }}:</span> <span class="value">{{ elem.value }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="selectedTree && propertyGroups" class="element-summary">
|
||||
<sf-property-groups
|
||||
:layer="this.hierarchySelected"
|
||||
:visibilityReason="elementSummary"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="selectedTree" class="tree-view-wrapper">
|
||||
<tree-view
|
||||
class="treeview"
|
||||
@@ -143,6 +148,7 @@ import TreeView from './TreeView.vue';
|
||||
import Rects from './Rects.vue';
|
||||
import FlatCard from './components/FlatCard.vue';
|
||||
import PropertiesTreeElement from './PropertiesTreeElement.vue';
|
||||
import SurfaceFlingerPropertyGroups from '@/SurfaceFlingerPropertyGroups.vue';
|
||||
|
||||
import {ObjectTransformer} from './transform.js';
|
||||
import {DiffGenerator, defaultModifiedCheck} from './utils/diff.js';
|
||||
@@ -179,7 +185,7 @@ function findEntryInTree(tree, id) {
|
||||
|
||||
export default {
|
||||
name: 'traceview',
|
||||
props: ['store', 'file', 'summarizer', 'presentTags', 'presentErrors'],
|
||||
props: ['store', 'file', 'summarizer', 'presentTags', 'presentErrors', 'propertyGroups'],
|
||||
data() {
|
||||
return {
|
||||
propertyFilterString: '',
|
||||
@@ -437,6 +443,7 @@ export default {
|
||||
'tree-view': TreeView,
|
||||
'rects': Rects,
|
||||
'flat-card': FlatCard,
|
||||
'sf-property-groups': SurfaceFlingerPropertyGroups,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -478,7 +485,7 @@ function getFilter(filterString) {
|
||||
flex: 1;
|
||||
margin: 8px;
|
||||
min-width: 400px;
|
||||
min-height: 50rem;
|
||||
min-height: 70rem;
|
||||
}
|
||||
|
||||
.rects,
|
||||
|
||||
59
tools/winscope/src/TransformMatrix.vue
Normal file
59
tools/winscope/src/TransformMatrix.vue
Normal file
@@ -0,0 +1,59 @@
|
||||
<!-- Copyright (C) 2022 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.
|
||||
-->
|
||||
<template>
|
||||
<div class="matrix">
|
||||
<md-tooltip>{{ transform.getTypeAsString() }}</md-tooltip>
|
||||
<div class="cell">{{ formatFloat(transform.matrix.dsdx) }}</div>
|
||||
<div class="cell">{{ formatFloat(transform.matrix.dsdy) }}</div>
|
||||
<div class="cell">
|
||||
{{ formatFloat(transform.matrix.tx) }}<md-tooltip>Translate x</md-tooltip>
|
||||
</div>
|
||||
|
||||
<div class="cell">{{ formatFloat(transform.matrix.dtdx) }}</div>
|
||||
<div class="cell">{{ formatFloat(transform.matrix.dtdy) }}</div>
|
||||
<div class="cell">
|
||||
{{ formatFloat(transform.matrix.ty) }}<md-tooltip>Translate y</md-tooltip>
|
||||
</div>
|
||||
|
||||
<div class="cell">0</div>
|
||||
<div class="cell">0</div>
|
||||
<div class="cell">1</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "TransformMatrix",
|
||||
props: ["transform"],
|
||||
methods: {
|
||||
formatFloat(num) {
|
||||
return Math.round(num * 100) / 100;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.matrix {
|
||||
display: grid;
|
||||
grid-gap: 1px;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
|
||||
.cell {
|
||||
padding-left: 10px;
|
||||
background-color: rgba(158, 192, 200, 0.281);
|
||||
}
|
||||
</style>
|
||||
@@ -20,6 +20,7 @@
|
||||
:summarizer="summarizer"
|
||||
:presentTags="presentTags"
|
||||
:presentErrors="presentErrors"
|
||||
:propertyGroups="false"
|
||||
/>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -31,6 +31,14 @@ Layer.fromProto = function (proto: any): Layer {
|
||||
const bufferTransform = Transform.fromProto(proto.bufferTransform, /* position */ null)
|
||||
const hwcCrop = toRectF(proto.hwcCrop)
|
||||
const hwcFrame = toRect(proto.hwcFrame)
|
||||
const requestedColor = toColor(proto.requestedColor)
|
||||
const requestedTransform =
|
||||
Transform.fromProto(proto.requestedTransform, proto.requestedPosition)
|
||||
const cornerRadiusCrop = toRectF(proto.cornerRadiusCrop)
|
||||
const inputTransform =
|
||||
Transform.fromProto(proto.inputWindowInfo ? proto.inputWindowInfo.transform : null)
|
||||
const inputRegion =
|
||||
toRegion(proto.inputWindowInfo ? proto.inputWindowInfo.touchableRegion : null)
|
||||
let crop: Rect
|
||||
if (proto.crop) {
|
||||
crop = toRect(proto.crop)
|
||||
@@ -63,7 +71,12 @@ Layer.fromProto = function (proto: any): Layer {
|
||||
crop,
|
||||
proto.isRelativeOf,
|
||||
proto.zOrderRelativeOf,
|
||||
proto.layerStack
|
||||
proto.layerStack,
|
||||
requestedTransform,
|
||||
requestedColor,
|
||||
cornerRadiusCrop,
|
||||
inputTransform,
|
||||
inputRegion,
|
||||
);
|
||||
|
||||
addAttributes(entry, proto);
|
||||
|
||||
Reference in New Issue
Block a user