xref: /aosp_15_r20/external/angle/doc/DebugOverlayInVulkanBackend.md (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1# Debug Overlay in ANGLE's Vulkan Backend
2
3## Motivation
4
5A complex application has frequently changing performance characteristics due to
6both a varying number of objects to draw and different effects that need to be
7applied to them. When characterizing the performance of an application, it can
8be easy to miss scenes which need optimization, especially if they are
9ephemeral.
10
11A debug overlay that shows on-the-fly statistics from the running application
12can greatly aid the developer in finding where the bottlenecks are and which
13scenes need further investigation and profiling.
14
15ANGLE's Vulkan debug overlay implements this. The initial implementation
16includes a few pieces of information for demonstration purposes. Here's the
17glmark2 *terrain* scene with these overlay items enabled:
18
19![glmark2 terrain scene](img/VangleDebugOverlay.png)
20
21This is a screenshot of a debug build, hence the low FPS. The command graph size
22widget no longer applies to current ANGLE code.
23
24## Implementation
25
26Overlay items are of two fundamental types:
27
28* Text items: A single line of text with small or large font.
29* Graph items: A bar graph of data. These each have a Text item attached
30  that is automatically rendered with the graph item.
31
32Built on these, various overlay item types are defined that gather statistics.
33Five such types are defined with one item per type as example:
34
35* **Count**: An item that counts something. **VulkanValidationMessageCount**
36  is an overlay item of this type that shows the number of validation messages
37  received from the validation layers.
38* **Text**: A generic text widget. **VulkanLastValidationMessage** is an overlay
39  item of this type that shows the last validation message.
40* **PerSecond**: A value that gets reset every second automatically. **FPS** is
41  an overlay item of this type that simply gets incremented on every `swap()`.
42* **RunningGraph**: A graph of the last N values. **VulkanRenderPassCount** is an
43  overlay of this type. This counter reports the number of RenderPasses rendered
44  in each vkQueueSubmit call.
45* **RunningHistogram**: A histogram of last N values. Input values are in the
46  [0, 1] range and they are ranked to N buckets for histogram calculation.
47  **VulkanSecondaryCommandBufferPoolWaste** is an overlay item of this type.
48  On `vkQueueSubmit()`, the memory waste from command buffer pool allocations
49  is recorded in the histogram.
50
51Overlay font is placed in [libANGLE/overlay/](../src/libANGLE/overlay/) which
52[gen_overlay_fonts.py](../src/libANGLE/gen_overlay_fonts.py) processes to create
53an array of rasterized font data, which is used at runtime to create the font
54image (an image with one layer per character, and one mip level per font size).
55
56The overlay widget layout is defined in
57[overlay_widgets.json](../src/libANGLE/overlay_widgets.json)
58which [gen_overlay_widgets.py](../src/libANGLE/gen_overlay_widgets.py)
59processes to generate an array of widgets, each of its respective type,
60and sets their properties, such as color and bounding box.
61The json file allows widgets to align against other widgets as well as against
62the framebuffer edges. The following is a part of this file:
63
64```json
65{
66    "name": "VulkanValidationMessageCount",
67    "type": "Count",
68    "color": [255, 0, 0, 255],
69    "coords": [10, "VulkanLastValidationMessage.top.adjacent"],
70    "font": "small",
71    "length": 25
72},
73{
74    "name": "VulkanSecondaryCommandBufferPoolWaste",
75    "type": "RunningHistogram(50)",
76    "color": [255, 200, 75, 200],
77    "coords": [-50, 100],
78    "bar_width": 6,
79    "height": 100,
80    "description": {
81        "color": [255, 200, 75, 255],
82        "coords": ["VulkanSecondaryCommandBufferPoolWaste.left.align",
83                   "VulkanSecondaryCommandBufferPoolWaste.top.adjacent"],
84        "font": "small",
85        "length": 40
86    }
87}
88```
89
90Negative coordinates in this file indicate alignment to the right/bottom of the
91framebuffer. `OtherItem.edge.mode` lets an item be aligned with another.
92If `mode` is `align`, the item has the same origin as `OtherItem` and expands
93in the same direction. If `adjacent`, the item expands in the opposite
94direction.
95
96The UI is rendered in two passes, one draw call for all graph widgets and
97another draw call for all text widgets. The vertex shader in these draw calls
98generates 4 vertices for each instance (one instance per widget) based on the
99widget bounding box. The fragment shader renders font or a graph based on widget
100data. This is done once per frame on `present()`, and the result is blended into
101the swapchain image.
102
103To build ANGLE with overlay capability, `angle_enable_overlay = true` must be
104placed in `args.gn`.
105
106Currently, to enable overlay items an environment variable is used. For example:
107
108On Desktop:
109
110```commandline
111$ export ANGLE_OVERLAY=FPS:Vulkan*PipelineCache*
112$ ./hello_triangle --use-angle=vulkan
113```
114
115On Android:
116
117```
118$ adb shell setprop debug.angle.overlay FPS:Vulkan*PipelineCache*
119$ ./hello_triangle --use-angle=vulkan
120```
121
122## Future Work
123
124Possible future work:
125
126* On Android, add settings in developer options and enable items based on those.
127* Spawn a small server in ANGLE and write an application that sends
128  enable/disable commands remotely.
129* Move the Overlay rendering functionality to the front-end to benefit all
130  backends.
131* Add more overlay widgets.
132* Implement automatic widget layout to remove the need to specify positions in
133  the overlay widgets JSON.
134