• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // OverlayWidgets.cpp:
7 //    Implements functions that interpret widget data.  Data formats and limits correspond to the
8 //    Vulkan implementation (as the only implementation).  They are generic enough so other backends
9 //    could respect them too, if they implement the overlay.
10 //
11 
12 #include "libANGLE/Overlay.h"
13 #include "libANGLE/Overlay_font_autogen.h"
14 
15 #include <functional>
16 
17 namespace gl
18 {
19 namespace
20 {
21 // Internally, every widget is either Text or Graph.
22 enum class WidgetInternalType
23 {
24     Text,
25     Graph,
26 
27     InvalidEnum,
28     EnumCount = InvalidEnum,
29 };
30 
31 // A map that says how the API-facing widget types map to internal types.
32 constexpr angle::PackedEnumMap<WidgetType, WidgetInternalType> kWidgetTypeToInternalMap = {
33     {WidgetType::Count, WidgetInternalType::Text},
34     {WidgetType::Text, WidgetInternalType::Text},
35     {WidgetType::PerSecond, WidgetInternalType::Text},
36     {WidgetType::RunningGraph, WidgetInternalType::Graph},
37     {WidgetType::RunningHistogram, WidgetInternalType::Graph},
38 };
39 
40 // Structures and limits matching uniform buffers in vulkan/shaders/src/OverlayDraw.comp.  The size
41 // of text and graph widgets is chosen such that they could fit in uniform buffers with minimum
42 // required Vulkan size.
43 constexpr size_t kMaxRenderableTextWidgets  = 32;
44 constexpr size_t kMaxRenderableGraphWidgets = 32;
45 constexpr size_t kMaxTextLength             = 256;
46 constexpr size_t kMaxGraphDataSize          = 256;
47 
48 constexpr angle::PackedEnumMap<WidgetInternalType, size_t> kWidgetInternalTypeMaxWidgets = {
49     {WidgetInternalType::Text, kMaxRenderableTextWidgets},
50     {WidgetInternalType::Graph, kMaxRenderableGraphWidgets},
51 };
52 
53 ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
54 
55 // Structure matching buffer in vulkan/shaders/src/OverlayCull.comp.
56 struct WidgetCoordinates
57 {
58     uint32_t coordinates[kMaxRenderableTextWidgets + kMaxRenderableGraphWidgets][4];
59 };
60 
61 // Structures matching buffers in vulkan/shaders/src/OverlayDraw.comp.
62 struct TextWidgetData
63 {
64     uint32_t coordinates[4];
65     float color[4];
66     uint32_t fontSize[3];
67     uint32_t padding;
68     uint8_t text[kMaxTextLength];
69 };
70 
71 struct GraphWidgetData
72 {
73     uint32_t coordinates[4];
74     float color[4];
75     uint32_t valueWidth;
76     uint32_t padding[3];
77     uint32_t values[kMaxGraphDataSize];
78 };
79 
80 struct TextWidgets
81 {
82     TextWidgetData widgets[kMaxRenderableTextWidgets];
83 };
84 
85 struct GraphWidgets
86 {
87     GraphWidgetData widgets[kMaxRenderableGraphWidgets];
88 };
89 
90 ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
91 
GetWidgetCoord(int32_t src,uint32_t extent)92 uint32_t GetWidgetCoord(int32_t src, uint32_t extent)
93 {
94     int32_t dst = src < 0 ? extent + src : src;
95 
96     return std::min<uint32_t>(std::max(dst, 0), extent - 1);
97 }
98 
GetWidgetCoordinates(const int32_t srcCoords[4],const gl::Extents & imageExtent,uint32_t dstCoordsOut[4])99 void GetWidgetCoordinates(const int32_t srcCoords[4],
100                           const gl::Extents &imageExtent,
101                           uint32_t dstCoordsOut[4])
102 {
103     dstCoordsOut[0] = GetWidgetCoord(srcCoords[0], imageExtent.width);
104     dstCoordsOut[1] = GetWidgetCoord(srcCoords[1], imageExtent.height);
105     dstCoordsOut[2] = GetWidgetCoord(srcCoords[2], imageExtent.width);
106     dstCoordsOut[3] = GetWidgetCoord(srcCoords[3], imageExtent.height);
107 }
108 
GetWidgetColor(const float srcColor[4],float dstColor[4])109 void GetWidgetColor(const float srcColor[4], float dstColor[4])
110 {
111     memcpy(dstColor, srcColor, 4 * sizeof(dstColor[0]));
112 }
113 
GetTextFontSize(int srcFontSize,uint32_t dstFontSize[3])114 void GetTextFontSize(int srcFontSize, uint32_t dstFontSize[3])
115 {
116     // .xy contains the font glyph width/height
117     dstFontSize[0] = overlay::kFontGlyphWidth >> srcFontSize;
118     dstFontSize[1] = overlay::kFontGlyphHeight >> srcFontSize;
119     // .z contains the mip
120     dstFontSize[2] = srcFontSize;
121 }
122 
GetGraphValueWidth(const int32_t srcCoords[4],size_t valueCount,uint32_t * dstValueWidth)123 void GetGraphValueWidth(const int32_t srcCoords[4], size_t valueCount, uint32_t *dstValueWidth)
124 {
125     const int32_t graphWidth = std::abs(srcCoords[2] - srcCoords[0]);
126 
127     // If valueCount doesn't divide graphWidth, the graph bars won't fit well in its frame.
128     // Fix initOverlayWidgets() in that case.
129     ASSERT(graphWidth % valueCount == 0);
130 
131     *dstValueWidth = graphWidth / valueCount;
132 }
133 
GetTextString(const std::string & src,uint8_t textOut[kMaxTextLength])134 void GetTextString(const std::string &src, uint8_t textOut[kMaxTextLength])
135 {
136     for (size_t i = 0; i < src.length() && i < kMaxTextLength; ++i)
137     {
138         // The font image has 95 ASCII characters starting from ' '.
139         textOut[i] = src[i] - ' ';
140     }
141 }
142 
GetGraphValues(const std::vector<uint64_t> srcValues,size_t startIndex,float scale,uint32_t valuesOut[kMaxGraphDataSize])143 void GetGraphValues(const std::vector<uint64_t> srcValues,
144                     size_t startIndex,
145                     float scale,
146                     uint32_t valuesOut[kMaxGraphDataSize])
147 {
148     ASSERT(srcValues.size() <= kMaxGraphDataSize);
149 
150     for (size_t i = 0; i < srcValues.size(); ++i)
151     {
152         size_t index = (startIndex + i) % srcValues.size();
153         valuesOut[i] = static_cast<uint32_t>(srcValues[index] * scale);
154     }
155 }
156 
CreateHistogram(const std::vector<uint64_t> values)157 std::vector<uint64_t> CreateHistogram(const std::vector<uint64_t> values)
158 {
159     std::vector<uint64_t> histogram(values.size(), 0);
160 
161     for (uint64_t rank : values)
162     {
163         ++histogram[static_cast<size_t>(rank)];
164     }
165 
166     return histogram;
167 }
168 
169 using OverlayWidgetCounts  = angle::PackedEnumMap<WidgetInternalType, uint32_t>;
170 using AppendWidgetDataFunc = void (*)(const overlay::Widget *widget,
171                                       const gl::Extents &imageExtent,
172                                       TextWidgetData *textWidget,
173                                       GraphWidgetData *graphWidget,
174                                       OverlayWidgetCounts *widgetCounts);
175 }  // namespace
176 
177 namespace overlay_impl
178 {
179 #define ANGLE_DECLARE_APPEND_WIDGET_PROC(WIDGET_ID)                                              \
180     static void Append##WIDGET_ID(const overlay::Widget *widget, const gl::Extents &imageExtent, \
181                                   TextWidgetData *textWidget, GraphWidgetData *graphWidget,      \
182                                   OverlayWidgetCounts *widgetCounts);
183 
184 // This class interprets the generic data collected in every element into a human-understandable
185 // widget.  This often means generating text specific to this item and scaling graph data to
186 // something sensible.
187 class AppendWidgetDataHelper
188 {
189   public:
190     ANGLE_WIDGET_ID_X(ANGLE_DECLARE_APPEND_WIDGET_PROC)
191 
192   private:
193     static std::ostream &OutputPerSecond(std::ostream &out, const overlay::PerSecond *perSecond);
194 
195     static std::ostream &OutputText(std::ostream &out, const overlay::Text *text);
196 
197     static std::ostream &OutputCount(std::ostream &out, const overlay::Count *count);
198 
199     static void AppendTextCommon(const overlay::Widget *widget,
200                                  const gl::Extents &imageExtent,
201                                  const std::string &text,
202                                  TextWidgetData *textWidget,
203                                  OverlayWidgetCounts *widgetCounts);
204 
205     using FormatGraphTitleFunc = std::function<std::string(uint64_t curValue, uint64_t maxValue)>;
206     static void AppendRunningGraphCommon(const overlay::Widget *widget,
207                                          const gl::Extents &imageExtent,
208                                          TextWidgetData *textWidget,
209                                          GraphWidgetData *graphWidget,
210                                          OverlayWidgetCounts *widgetCounts,
211                                          FormatGraphTitleFunc formatFunc);
212 
213     using FormatHistogramTitleFunc =
214         std::function<std::string(size_t peakRange, size_t maxValueRange, size_t numRanges)>;
215     static void AppendRunningHistogramCommon(const overlay::Widget *widget,
216                                              const gl::Extents &imageExtent,
217                                              TextWidgetData *textWidget,
218                                              GraphWidgetData *graphWidget,
219                                              OverlayWidgetCounts *widgetCounts,
220                                              FormatHistogramTitleFunc formatFunc);
221 
222     static void AppendGraphCommon(const overlay::Widget *widget,
223                                   const gl::Extents &imageExtent,
224                                   const std::vector<uint64_t> runningValues,
225                                   size_t startIndex,
226                                   float scale,
227                                   GraphWidgetData *graphWidget,
228                                   OverlayWidgetCounts *widgetCounts);
229 };
230 
AppendTextCommon(const overlay::Widget * widget,const gl::Extents & imageExtent,const std::string & text,TextWidgetData * textWidget,OverlayWidgetCounts * widgetCounts)231 void AppendWidgetDataHelper::AppendTextCommon(const overlay::Widget *widget,
232                                               const gl::Extents &imageExtent,
233                                               const std::string &text,
234                                               TextWidgetData *textWidget,
235                                               OverlayWidgetCounts *widgetCounts)
236 {
237     GetWidgetCoordinates(widget->coords, imageExtent, textWidget->coordinates);
238     GetWidgetColor(widget->color, textWidget->color);
239     GetTextFontSize(widget->fontSize, textWidget->fontSize);
240     GetTextString(text, textWidget->text);
241 
242     ++(*widgetCounts)[WidgetInternalType::Text];
243 }
244 
AppendGraphCommon(const overlay::Widget * widget,const gl::Extents & imageExtent,const std::vector<uint64_t> runningValues,size_t startIndex,float scale,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)245 void AppendWidgetDataHelper::AppendGraphCommon(const overlay::Widget *widget,
246                                                const gl::Extents &imageExtent,
247                                                const std::vector<uint64_t> runningValues,
248                                                size_t startIndex,
249                                                float scale,
250                                                GraphWidgetData *graphWidget,
251                                                OverlayWidgetCounts *widgetCounts)
252 {
253     const overlay::RunningGraph *widgetAsGraph = static_cast<const overlay::RunningGraph *>(widget);
254 
255     GetWidgetCoordinates(widget->coords, imageExtent, graphWidget->coordinates);
256     GetWidgetColor(widget->color, graphWidget->color);
257     GetGraphValueWidth(widget->coords, widgetAsGraph->runningValues.size(),
258                        &graphWidget->valueWidth);
259     GetGraphValues(runningValues, startIndex, scale, graphWidget->values);
260 
261     ++(*widgetCounts)[WidgetInternalType::Graph];
262 }
263 
AppendRunningGraphCommon(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts,AppendWidgetDataHelper::FormatGraphTitleFunc formatFunc)264 void AppendWidgetDataHelper::AppendRunningGraphCommon(
265     const overlay::Widget *widget,
266     const gl::Extents &imageExtent,
267     TextWidgetData *textWidget,
268     GraphWidgetData *graphWidget,
269     OverlayWidgetCounts *widgetCounts,
270     AppendWidgetDataHelper::FormatGraphTitleFunc formatFunc)
271 {
272     const overlay::RunningGraph *graph   = static_cast<const overlay::RunningGraph *>(widget);
273     const overlay::Widget *matchToWidget = widget->matchToWidget;
274 
275     if (matchToWidget == nullptr)
276     {
277         matchToWidget = widget;
278     }
279     const overlay::RunningGraph *matchToGraph =
280         static_cast<const overlay::RunningGraph *>(matchToWidget);
281 
282     const uint64_t maxValue =
283         *std::max_element(graph->runningValues.begin(), graph->runningValues.end());
284     const uint64_t maxValueInMatchToGraph =
285         *std::max_element(matchToGraph->runningValues.begin(), matchToGraph->runningValues.end());
286     const int32_t graphHeight = std::abs(widget->coords[3] - widget->coords[1]);
287     const float graphScale    = static_cast<float>(graphHeight) / maxValueInMatchToGraph;
288 
289     const size_t graphSize  = graph->runningValues.size();
290     const size_t currentIdx = graph->lastValueIndex - 1;
291 
292     const uint64_t curValue = graph->runningValues[(graphSize + currentIdx) % graphSize];
293 
294     AppendGraphCommon(widget, imageExtent, graph->runningValues, graph->lastValueIndex + 1,
295                       graphScale, graphWidget, widgetCounts);
296 
297     if ((*widgetCounts)[WidgetInternalType::Text] <
298         kWidgetInternalTypeMaxWidgets[WidgetInternalType::Text])
299     {
300         std::string text = formatFunc(curValue, maxValue);
301         AppendTextCommon(&graph->description, imageExtent, text, textWidget, widgetCounts);
302     }
303 }
304 
305 // static
AppendRunningHistogramCommon(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts,FormatHistogramTitleFunc formatFunc)306 void AppendWidgetDataHelper::AppendRunningHistogramCommon(const overlay::Widget *widget,
307                                                           const gl::Extents &imageExtent,
308                                                           TextWidgetData *textWidget,
309                                                           GraphWidgetData *graphWidget,
310                                                           OverlayWidgetCounts *widgetCounts,
311                                                           FormatHistogramTitleFunc formatFunc)
312 {
313     const overlay::RunningHistogram *runningHistogram =
314         static_cast<const overlay::RunningHistogram *>(widget);
315 
316     std::vector<uint64_t> histogram = CreateHistogram(runningHistogram->runningValues);
317     auto peakRangeIt                = std::max_element(histogram.rbegin(), histogram.rend());
318     const uint64_t peakRangeValue   = *peakRangeIt;
319     const int32_t graphHeight       = std::abs(widget->coords[3] - widget->coords[1]);
320     const float graphScale          = static_cast<float>(graphHeight) / peakRangeValue;
321     auto maxValueIter               = std::find_if(histogram.rbegin(), histogram.rend(),
322                                                    [](uint64_t value) { return value != 0; });
323 
324     AppendGraphCommon(widget, imageExtent, histogram, 0, graphScale, graphWidget, widgetCounts);
325 
326     if ((*widgetCounts)[WidgetInternalType::Text] <
327         kWidgetInternalTypeMaxWidgets[WidgetInternalType::Text])
328     {
329         size_t peakRange     = std::distance(peakRangeIt, histogram.rend() - 1);
330         size_t maxValueRange = std::distance(maxValueIter, histogram.rend() - 1);
331 
332         std::string text = formatFunc(peakRange, maxValueRange, histogram.size());
333         AppendTextCommon(&runningHistogram->description, imageExtent, text, textWidget,
334                          widgetCounts);
335     }
336 }
337 
AppendFPS(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)338 void AppendWidgetDataHelper::AppendFPS(const overlay::Widget *widget,
339                                        const gl::Extents &imageExtent,
340                                        TextWidgetData *textWidget,
341                                        GraphWidgetData *graphWidget,
342                                        OverlayWidgetCounts *widgetCounts)
343 {
344     const overlay::PerSecond *fps = static_cast<const overlay::PerSecond *>(widget);
345     std::ostringstream text;
346     text << "FPS: ";
347     OutputPerSecond(text, fps);
348 
349     AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
350 }
351 
AppendVulkanLastValidationMessage(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)352 void AppendWidgetDataHelper::AppendVulkanLastValidationMessage(const overlay::Widget *widget,
353                                                                const gl::Extents &imageExtent,
354                                                                TextWidgetData *textWidget,
355                                                                GraphWidgetData *graphWidget,
356                                                                OverlayWidgetCounts *widgetCounts)
357 {
358     const overlay::Text *lastValidationMessage = static_cast<const overlay::Text *>(widget);
359     std::ostringstream text;
360     text << "Last VVL Message: ";
361     OutputText(text, lastValidationMessage);
362 
363     AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
364 }
365 
AppendVulkanValidationMessageCount(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)366 void AppendWidgetDataHelper::AppendVulkanValidationMessageCount(const overlay::Widget *widget,
367                                                                 const gl::Extents &imageExtent,
368                                                                 TextWidgetData *textWidget,
369                                                                 GraphWidgetData *graphWidget,
370                                                                 OverlayWidgetCounts *widgetCounts)
371 {
372     const overlay::Count *validationMessageCount = static_cast<const overlay::Count *>(widget);
373     std::ostringstream text;
374     text << "VVL Message Count: ";
375     OutputCount(text, validationMessageCount);
376 
377     AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
378 }
379 
AppendVulkanRenderPassCount(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)380 void AppendWidgetDataHelper::AppendVulkanRenderPassCount(const overlay::Widget *widget,
381                                                          const gl::Extents &imageExtent,
382                                                          TextWidgetData *textWidget,
383                                                          GraphWidgetData *graphWidget,
384                                                          OverlayWidgetCounts *widgetCounts)
385 {
386     auto format = [](uint64_t curValue, uint64_t maxValue) {
387         std::ostringstream text;
388         text << "RenderPass Count: " << maxValue;
389         return text.str();
390     };
391 
392     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
393 }
394 
AppendVulkanSecondaryCommandBufferPoolWaste(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)395 void AppendWidgetDataHelper::AppendVulkanSecondaryCommandBufferPoolWaste(
396     const overlay::Widget *widget,
397     const gl::Extents &imageExtent,
398     TextWidgetData *textWidget,
399     GraphWidgetData *graphWidget,
400     OverlayWidgetCounts *widgetCounts)
401 {
402     auto format = [](size_t peakRange, size_t maxValueRange, size_t numRanges) {
403         std::ostringstream text;
404         size_t peakPercent = (peakRange * 100 + 50) / numRanges;
405         text << "CB Pool Waste (Peak: " << peakPercent << "%)";
406         return text.str();
407     };
408 
409     AppendRunningHistogramCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts,
410                                  format);
411 }
412 
AppendVulkanWriteDescriptorSetCount(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)413 void AppendWidgetDataHelper::AppendVulkanWriteDescriptorSetCount(const overlay::Widget *widget,
414                                                                  const gl::Extents &imageExtent,
415                                                                  TextWidgetData *textWidget,
416                                                                  GraphWidgetData *graphWidget,
417                                                                  OverlayWidgetCounts *widgetCounts)
418 {
419     auto format = [](uint64_t curValue, uint64_t maxValue) {
420         std::ostringstream text;
421         text << "WriteDescriptorSet Count: " << maxValue;
422         return text.str();
423     };
424 
425     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
426 }
427 
AppendVulkanDescriptorSetAllocations(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)428 void AppendWidgetDataHelper::AppendVulkanDescriptorSetAllocations(const overlay::Widget *widget,
429                                                                   const gl::Extents &imageExtent,
430                                                                   TextWidgetData *textWidget,
431                                                                   GraphWidgetData *graphWidget,
432                                                                   OverlayWidgetCounts *widgetCounts)
433 {
434     auto format = [](uint64_t curValue, uint64_t maxValue) {
435         std::ostringstream text;
436         text << "Descriptor Set Allocations: " << maxValue;
437         return text.str();
438     };
439 
440     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
441 }
442 
AppendVulkanShaderResourceDSHitRate(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)443 void AppendWidgetDataHelper::AppendVulkanShaderResourceDSHitRate(const overlay::Widget *widget,
444                                                                  const gl::Extents &imageExtent,
445                                                                  TextWidgetData *textWidget,
446                                                                  GraphWidgetData *graphWidget,
447                                                                  OverlayWidgetCounts *widgetCounts)
448 {
449     auto format = [](uint64_t curValue, uint64_t maxValue) {
450         std::ostringstream text;
451         text << "Shader Resource DS Hit Rate (Max: " << maxValue << "%)";
452         return text.str();
453     };
454 
455     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
456 }
457 
AppendVulkanDynamicBufferAllocations(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)458 void AppendWidgetDataHelper::AppendVulkanDynamicBufferAllocations(const overlay::Widget *widget,
459                                                                   const gl::Extents &imageExtent,
460                                                                   TextWidgetData *textWidget,
461                                                                   GraphWidgetData *graphWidget,
462                                                                   OverlayWidgetCounts *widgetCounts)
463 {
464     auto format = [](uint64_t curValue, uint64_t maxValue) {
465         std::ostringstream text;
466         text << "DynamicBuffer Allocations (Max: " << maxValue << ")";
467         return text.str();
468     };
469 
470     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
471 }
472 
AppendVulkanTextureDescriptorCacheSize(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)473 void AppendWidgetDataHelper::AppendVulkanTextureDescriptorCacheSize(
474     const overlay::Widget *widget,
475     const gl::Extents &imageExtent,
476     TextWidgetData *textWidget,
477     GraphWidgetData *graphWidget,
478     OverlayWidgetCounts *widgetCounts)
479 {
480     auto format = [](uint64_t curValue, uint64_t maxValue) {
481         std::ostringstream text;
482         text << "Total Texture Descriptor Cache Size: " << curValue;
483         return text.str();
484     };
485 
486     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
487 }
488 
AppendVulkanUniformDescriptorCacheSize(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)489 void AppendWidgetDataHelper::AppendVulkanUniformDescriptorCacheSize(
490     const overlay::Widget *widget,
491     const gl::Extents &imageExtent,
492     TextWidgetData *textWidget,
493     GraphWidgetData *graphWidget,
494     OverlayWidgetCounts *widgetCounts)
495 {
496     auto format = [](uint64_t curValue, uint64_t maxValue) {
497         std::ostringstream text;
498         text << "Total Uniform Descriptor Cache Size: " << curValue;
499         return text.str();
500     };
501 
502     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
503 }
504 
AppendVulkanDescriptorCacheSize(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)505 void AppendWidgetDataHelper::AppendVulkanDescriptorCacheSize(const overlay::Widget *widget,
506                                                              const gl::Extents &imageExtent,
507                                                              TextWidgetData *textWidget,
508                                                              GraphWidgetData *graphWidget,
509                                                              OverlayWidgetCounts *widgetCounts)
510 {
511     auto format = [](uint64_t curValue, uint64_t maxValue) {
512         std::ostringstream text;
513         text << "Total Descriptor Cache Size: " << curValue;
514         return text.str();
515     };
516 
517     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
518 }
519 
AppendVulkanDescriptorCacheKeySize(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)520 void AppendWidgetDataHelper::AppendVulkanDescriptorCacheKeySize(const overlay::Widget *widget,
521                                                                 const gl::Extents &imageExtent,
522                                                                 TextWidgetData *textWidget,
523                                                                 GraphWidgetData *graphWidget,
524                                                                 OverlayWidgetCounts *widgetCounts)
525 {
526     const overlay::Count *countWidget = static_cast<const overlay::Count *>(widget);
527     std::ostringstream text;
528     double kb = static_cast<double>(countWidget->count) / 1000.0;
529     text << "DS Cache Key Size: " << std::fixed << std::setprecision(1) << kb << " kb";
530 
531     AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
532 }
533 
AppendVulkanAttemptedSubmissions(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)534 void AppendWidgetDataHelper::AppendVulkanAttemptedSubmissions(const overlay::Widget *widget,
535                                                               const gl::Extents &imageExtent,
536                                                               TextWidgetData *textWidget,
537                                                               GraphWidgetData *graphWidget,
538                                                               OverlayWidgetCounts *widgetCounts)
539 {
540     auto format = [](uint64_t curValue, uint64_t maxValue) {
541         std::ostringstream text;
542         text << "Attempted submissions (peak): " << maxValue;
543         return text.str();
544     };
545 
546     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
547 }
548 
AppendVulkanActualSubmissions(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)549 void AppendWidgetDataHelper::AppendVulkanActualSubmissions(const overlay::Widget *widget,
550                                                            const gl::Extents &imageExtent,
551                                                            TextWidgetData *textWidget,
552                                                            GraphWidgetData *graphWidget,
553                                                            OverlayWidgetCounts *widgetCounts)
554 {
555     auto format = [](uint64_t curValue, uint64_t maxValue) {
556         std::ostringstream text;
557         text << "Actual submissions (peak): " << maxValue;
558         return text.str();
559     };
560 
561     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
562 }
563 
AppendVulkanPipelineCacheLookups(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)564 void AppendWidgetDataHelper::AppendVulkanPipelineCacheLookups(const overlay::Widget *widget,
565                                                               const gl::Extents &imageExtent,
566                                                               TextWidgetData *textWidget,
567                                                               GraphWidgetData *graphWidget,
568                                                               OverlayWidgetCounts *widgetCounts)
569 {
570     auto format = [](uint64_t curValue, uint64_t maxValue) {
571         std::ostringstream text;
572         text << "Pipeline Cache Lookups (peak): " << maxValue;
573         return text.str();
574     };
575 
576     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
577 }
578 
AppendVulkanPipelineCacheMisses(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)579 void AppendWidgetDataHelper::AppendVulkanPipelineCacheMisses(const overlay::Widget *widget,
580                                                              const gl::Extents &imageExtent,
581                                                              TextWidgetData *textWidget,
582                                                              GraphWidgetData *graphWidget,
583                                                              OverlayWidgetCounts *widgetCounts)
584 {
585     auto format = [](uint64_t curValue, uint64_t maxValue) {
586         std::ostringstream text;
587         text << "Pipeline Cache Misses (peak): " << maxValue;
588         return text.str();
589     };
590 
591     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
592 }
593 
AppendVulkanTotalPipelineCacheHitTimeMs(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)594 void AppendWidgetDataHelper::AppendVulkanTotalPipelineCacheHitTimeMs(
595     const overlay::Widget *widget,
596     const gl::Extents &imageExtent,
597     TextWidgetData *textWidget,
598     GraphWidgetData *graphWidget,
599     OverlayWidgetCounts *widgetCounts)
600 {
601     const overlay::Count *totalTime = static_cast<const overlay::Count *>(widget);
602     std::ostringstream text;
603     text << "Total Pipeline Cache Hit Time: ";
604     OutputCount(text, totalTime);
605     text << "ms";
606 
607     AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
608 }
609 
AppendVulkanTotalPipelineCacheMissTimeMs(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)610 void AppendWidgetDataHelper::AppendVulkanTotalPipelineCacheMissTimeMs(
611     const overlay::Widget *widget,
612     const gl::Extents &imageExtent,
613     TextWidgetData *textWidget,
614     GraphWidgetData *graphWidget,
615     OverlayWidgetCounts *widgetCounts)
616 {
617     const overlay::Count *totalTime = static_cast<const overlay::Count *>(widget);
618     std::ostringstream text;
619     text << "Total Pipeline Cache Miss Time: ";
620     OutputCount(text, totalTime);
621     text << "ms";
622 
623     AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
624 }
625 
OutputPerSecond(std::ostream & out,const overlay::PerSecond * perSecond)626 std::ostream &AppendWidgetDataHelper::OutputPerSecond(std::ostream &out,
627                                                       const overlay::PerSecond *perSecond)
628 {
629     return out << perSecond->lastPerSecondCount;
630 }
631 
OutputText(std::ostream & out,const overlay::Text * text)632 std::ostream &AppendWidgetDataHelper::OutputText(std::ostream &out, const overlay::Text *text)
633 {
634     return out << text->text;
635 }
636 
OutputCount(std::ostream & out,const overlay::Count * count)637 std::ostream &AppendWidgetDataHelper::OutputCount(std::ostream &out, const overlay::Count *count)
638 {
639     return out << count->count;
640 }
641 }  // namespace overlay_impl
642 
643 namespace
644 {
645 #define ANGLE_APPEND_WIDGET_MAP_PROC(WIDGET_ID) \
646     {WidgetId::WIDGET_ID, overlay_impl::AppendWidgetDataHelper::Append##WIDGET_ID},
647 
648 constexpr angle::PackedEnumMap<WidgetId, AppendWidgetDataFunc> kWidgetIdToAppendDataFuncMap = {
649     ANGLE_WIDGET_ID_X(ANGLE_APPEND_WIDGET_MAP_PROC)};
650 }  // namespace
651 
652 namespace overlay
653 {
getDescriptionWidget() const654 const Text *Widget::getDescriptionWidget() const
655 {
656     return nullptr;
657 }
RunningGraph(size_t n)658 RunningGraph::RunningGraph(size_t n) : runningValues(n, 0) {}
659 RunningGraph::~RunningGraph() = default;
getDescriptionWidget() const660 const Text *RunningGraph::getDescriptionWidget() const
661 {
662     return &description;
663 }
664 }  // namespace overlay
665 
getWidgetCoordinatesBufferSize() const666 size_t OverlayState::getWidgetCoordinatesBufferSize() const
667 {
668     return sizeof(WidgetCoordinates);
669 }
670 
getTextWidgetsBufferSize() const671 size_t OverlayState::getTextWidgetsBufferSize() const
672 {
673     return sizeof(TextWidgets);
674 }
675 
getGraphWidgetsBufferSize() const676 size_t OverlayState::getGraphWidgetsBufferSize() const
677 {
678     return sizeof(GraphWidgets);
679 }
680 
fillWidgetData(const gl::Extents & imageExtents,uint8_t * textData,uint8_t * graphData,uint32_t * activeTextWidgetCountOut,uint32_t * activeGraphWidgetCountOut) const681 void OverlayState::fillWidgetData(const gl::Extents &imageExtents,
682                                   uint8_t *textData,
683                                   uint8_t *graphData,
684                                   uint32_t *activeTextWidgetCountOut,
685                                   uint32_t *activeGraphWidgetCountOut) const
686 {
687     TextWidgets *textWidgets   = reinterpret_cast<TextWidgets *>(textData);
688     GraphWidgets *graphWidgets = reinterpret_cast<GraphWidgets *>(graphData);
689 
690     memset(textWidgets, overlay::kFontCharacters, sizeof(*textWidgets));
691     memset(graphWidgets, 0, sizeof(*graphWidgets));
692 
693     OverlayWidgetCounts widgetCounts = {};
694 
695     for (WidgetId id : angle::AllEnums<WidgetId>())
696     {
697         const std::unique_ptr<overlay::Widget> &widget = mOverlayWidgets[id];
698         if (!widget->enabled)
699         {
700             continue;
701         }
702 
703         WidgetInternalType internalType = kWidgetTypeToInternalMap[widget->type];
704         ASSERT(internalType != WidgetInternalType::InvalidEnum);
705 
706         if (widgetCounts[internalType] >= kWidgetInternalTypeMaxWidgets[internalType])
707         {
708             continue;
709         }
710 
711         AppendWidgetDataFunc appendFunc = kWidgetIdToAppendDataFuncMap[id];
712         ASSERT(appendFunc);
713         appendFunc(widget.get(), imageExtents,
714                    &textWidgets->widgets[widgetCounts[WidgetInternalType::Text]],
715                    &graphWidgets->widgets[widgetCounts[WidgetInternalType::Graph]], &widgetCounts);
716     }
717 
718     *activeTextWidgetCountOut  = widgetCounts[WidgetInternalType::Text];
719     *activeGraphWidgetCountOut = widgetCounts[WidgetInternalType::Graph];
720 }
721 
722 }  // namespace gl
723