• 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<size_t> srcValues,size_t startIndex,float scale,uint32_t valuesOut[kMaxGraphDataSize])143 void GetGraphValues(const std::vector<size_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<size_t> values)157 std::vector<size_t> CreateHistogram(const std::vector<size_t> values)
158 {
159     std::vector<size_t> histogram(values.size(), 0);
160 
161     for (size_t rank : values)
162     {
163         ++histogram[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(size_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<size_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<size_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<size_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 
274     const size_t maxValue =
275         *std::max_element(graph->runningValues.begin(), graph->runningValues.end());
276     const int32_t graphHeight = std::abs(widget->coords[3] - widget->coords[1]);
277     const float graphScale    = static_cast<float>(graphHeight) / maxValue;
278 
279     const size_t graphSize  = graph->runningValues.size();
280     const size_t currentIdx = graph->lastValueIndex - 1;
281 
282     const size_t curValue = graph->runningValues[(graphSize + currentIdx) % graphSize];
283 
284     AppendGraphCommon(widget, imageExtent, graph->runningValues, graph->lastValueIndex + 1,
285                       graphScale, graphWidget, widgetCounts);
286 
287     if ((*widgetCounts)[WidgetInternalType::Text] <
288         kWidgetInternalTypeMaxWidgets[WidgetInternalType::Text])
289     {
290         // std::string text = formatFunc(maxValue);
291         std::string text = formatFunc(curValue);
292         AppendTextCommon(&graph->description, imageExtent, text, textWidget, widgetCounts);
293     }
294 }
295 
296 // static
AppendRunningHistogramCommon(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts,FormatHistogramTitleFunc formatFunc)297 void AppendWidgetDataHelper::AppendRunningHistogramCommon(const overlay::Widget *widget,
298                                                           const gl::Extents &imageExtent,
299                                                           TextWidgetData *textWidget,
300                                                           GraphWidgetData *graphWidget,
301                                                           OverlayWidgetCounts *widgetCounts,
302                                                           FormatHistogramTitleFunc formatFunc)
303 {
304     const overlay::RunningHistogram *runningHistogram =
305         static_cast<const overlay::RunningHistogram *>(widget);
306 
307     std::vector<size_t> histogram = CreateHistogram(runningHistogram->runningValues);
308     auto peakRangeIt              = std::max_element(histogram.rbegin(), histogram.rend());
309     const size_t peakRangeValue   = *peakRangeIt;
310     const int32_t graphHeight     = std::abs(widget->coords[3] - widget->coords[1]);
311     const float graphScale        = static_cast<float>(graphHeight) / peakRangeValue;
312     auto maxValueIter =
313         std::find_if(histogram.rbegin(), histogram.rend(), [](size_t value) { return value != 0; });
314 
315     AppendGraphCommon(widget, imageExtent, histogram, 0, graphScale, graphWidget, widgetCounts);
316 
317     if ((*widgetCounts)[WidgetInternalType::Text] <
318         kWidgetInternalTypeMaxWidgets[WidgetInternalType::Text])
319     {
320         size_t peakRange     = std::distance(peakRangeIt, histogram.rend() - 1);
321         size_t maxValueRange = std::distance(maxValueIter, histogram.rend() - 1);
322 
323         std::string text = formatFunc(peakRange, maxValueRange, histogram.size());
324         AppendTextCommon(&runningHistogram->description, imageExtent, text, textWidget,
325                          widgetCounts);
326     }
327 }
328 
AppendFPS(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)329 void AppendWidgetDataHelper::AppendFPS(const overlay::Widget *widget,
330                                        const gl::Extents &imageExtent,
331                                        TextWidgetData *textWidget,
332                                        GraphWidgetData *graphWidget,
333                                        OverlayWidgetCounts *widgetCounts)
334 {
335     const overlay::PerSecond *fps = static_cast<const overlay::PerSecond *>(widget);
336     std::ostringstream text;
337     text << "FPS: ";
338     OutputPerSecond(text, fps);
339 
340     AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
341 }
342 
AppendVulkanLastValidationMessage(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)343 void AppendWidgetDataHelper::AppendVulkanLastValidationMessage(const overlay::Widget *widget,
344                                                                const gl::Extents &imageExtent,
345                                                                TextWidgetData *textWidget,
346                                                                GraphWidgetData *graphWidget,
347                                                                OverlayWidgetCounts *widgetCounts)
348 {
349     const overlay::Text *lastValidationMessage = static_cast<const overlay::Text *>(widget);
350     std::ostringstream text;
351     text << "Last VVL Message: ";
352     OutputText(text, lastValidationMessage);
353 
354     AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
355 }
356 
AppendVulkanValidationMessageCount(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)357 void AppendWidgetDataHelper::AppendVulkanValidationMessageCount(const overlay::Widget *widget,
358                                                                 const gl::Extents &imageExtent,
359                                                                 TextWidgetData *textWidget,
360                                                                 GraphWidgetData *graphWidget,
361                                                                 OverlayWidgetCounts *widgetCounts)
362 {
363     const overlay::Count *validationMessageCount = static_cast<const overlay::Count *>(widget);
364     std::ostringstream text;
365     text << "VVL Message Count: ";
366     OutputCount(text, validationMessageCount);
367 
368     AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
369 }
370 
AppendVulkanRenderPassCount(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)371 void AppendWidgetDataHelper::AppendVulkanRenderPassCount(const overlay::Widget *widget,
372                                                          const gl::Extents &imageExtent,
373                                                          TextWidgetData *textWidget,
374                                                          GraphWidgetData *graphWidget,
375                                                          OverlayWidgetCounts *widgetCounts)
376 {
377     auto format = [](size_t maxValue) {
378         std::ostringstream text;
379         text << "RenderPass Count: " << maxValue;
380         return text.str();
381     };
382 
383     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
384 }
385 
AppendVulkanSecondaryCommandBufferPoolWaste(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)386 void AppendWidgetDataHelper::AppendVulkanSecondaryCommandBufferPoolWaste(
387     const overlay::Widget *widget,
388     const gl::Extents &imageExtent,
389     TextWidgetData *textWidget,
390     GraphWidgetData *graphWidget,
391     OverlayWidgetCounts *widgetCounts)
392 {
393     auto format = [](size_t peakRange, size_t maxValueRange, size_t numRanges) {
394         std::ostringstream text;
395         size_t peakPercent = (peakRange * 100 + 50) / numRanges;
396         text << "CB Pool Waste (Peak: " << peakPercent << "%)";
397         return text.str();
398     };
399 
400     AppendRunningHistogramCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts,
401                                  format);
402 }
403 
AppendVulkanRenderPassBufferCount(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)404 void AppendWidgetDataHelper::AppendVulkanRenderPassBufferCount(const overlay::Widget *widget,
405                                                                const gl::Extents &imageExtent,
406                                                                TextWidgetData *textWidget,
407                                                                GraphWidgetData *graphWidget,
408                                                                OverlayWidgetCounts *widgetCounts)
409 {
410     auto format = [](size_t peakRange, size_t maxValueRange, size_t numRanges) {
411         std::ostringstream text;
412         text << "RP VkBuffers (Peak: " << peakRange << ", Max: " << maxValueRange << ")";
413         return text.str();
414     };
415 
416     AppendRunningHistogramCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts,
417                                  format);
418 }
419 
AppendVulkanWriteDescriptorSetCount(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)420 void AppendWidgetDataHelper::AppendVulkanWriteDescriptorSetCount(const overlay::Widget *widget,
421                                                                  const gl::Extents &imageExtent,
422                                                                  TextWidgetData *textWidget,
423                                                                  GraphWidgetData *graphWidget,
424                                                                  OverlayWidgetCounts *widgetCounts)
425 {
426     auto format = [](size_t maxValue) {
427         std::ostringstream text;
428         text << "WriteDescriptorSet Count: " << maxValue;
429         return text.str();
430     };
431 
432     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
433 }
434 
AppendVulkanDescriptorSetAllocations(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)435 void AppendWidgetDataHelper::AppendVulkanDescriptorSetAllocations(const overlay::Widget *widget,
436                                                                   const gl::Extents &imageExtent,
437                                                                   TextWidgetData *textWidget,
438                                                                   GraphWidgetData *graphWidget,
439                                                                   OverlayWidgetCounts *widgetCounts)
440 {
441     auto format = [](size_t maxValue) {
442         std::ostringstream text;
443         text << "Descriptor Set Allocations: " << maxValue;
444         return text.str();
445     };
446 
447     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
448 }
449 
AppendVulkanShaderResourceDSHitRate(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)450 void AppendWidgetDataHelper::AppendVulkanShaderResourceDSHitRate(const overlay::Widget *widget,
451                                                                  const gl::Extents &imageExtent,
452                                                                  TextWidgetData *textWidget,
453                                                                  GraphWidgetData *graphWidget,
454                                                                  OverlayWidgetCounts *widgetCounts)
455 {
456     auto format = [](size_t maxValue) {
457         std::ostringstream text;
458         text << "Shader Resource DS Hit Rate (Max: " << maxValue << "%)";
459         return text.str();
460     };
461 
462     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
463 }
464 
AppendVulkanDynamicBufferAllocations(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)465 void AppendWidgetDataHelper::AppendVulkanDynamicBufferAllocations(const overlay::Widget *widget,
466                                                                   const gl::Extents &imageExtent,
467                                                                   TextWidgetData *textWidget,
468                                                                   GraphWidgetData *graphWidget,
469                                                                   OverlayWidgetCounts *widgetCounts)
470 {
471     auto format = [](size_t maxValue) {
472         std::ostringstream text;
473         text << "DynamicBuffer Allocations (Max: " << maxValue << ")";
474         return text.str();
475     };
476 
477     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
478 }
479 
AppendVulkanTextureDescriptorCacheSize(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)480 void AppendWidgetDataHelper::AppendVulkanTextureDescriptorCacheSize(
481     const overlay::Widget *widget,
482     const gl::Extents &imageExtent,
483     TextWidgetData *textWidget,
484     GraphWidgetData *graphWidget,
485     OverlayWidgetCounts *widgetCounts)
486 {
487     auto format = [](size_t curVal) {
488         std::ostringstream text;
489         text << "Total Texture Descriptor Cache Size: " << curVal;
490         return text.str();
491     };
492 
493     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
494 }
495 
AppendVulkanUniformDescriptorCacheSize(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)496 void AppendWidgetDataHelper::AppendVulkanUniformDescriptorCacheSize(
497     const overlay::Widget *widget,
498     const gl::Extents &imageExtent,
499     TextWidgetData *textWidget,
500     GraphWidgetData *graphWidget,
501     OverlayWidgetCounts *widgetCounts)
502 {
503     auto format = [](size_t curVal) {
504         std::ostringstream text;
505         text << "Total Uniform Descriptor Cache Size: " << curVal;
506         return text.str();
507     };
508 
509     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
510 }
511 
AppendVulkanDescriptorCacheSize(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)512 void AppendWidgetDataHelper::AppendVulkanDescriptorCacheSize(const overlay::Widget *widget,
513                                                              const gl::Extents &imageExtent,
514                                                              TextWidgetData *textWidget,
515                                                              GraphWidgetData *graphWidget,
516                                                              OverlayWidgetCounts *widgetCounts)
517 {
518     auto format = [](size_t curVal) {
519         std::ostringstream text;
520         text << "Total Descriptor Cache Size: " << curVal;
521         return text.str();
522     };
523 
524     AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
525 }
526 
AppendVulkanDescriptorCacheKeySize(const overlay::Widget * widget,const gl::Extents & imageExtent,TextWidgetData * textWidget,GraphWidgetData * graphWidget,OverlayWidgetCounts * widgetCounts)527 void AppendWidgetDataHelper::AppendVulkanDescriptorCacheKeySize(const overlay::Widget *widget,
528                                                                 const gl::Extents &imageExtent,
529                                                                 TextWidgetData *textWidget,
530                                                                 GraphWidgetData *graphWidget,
531                                                                 OverlayWidgetCounts *widgetCounts)
532 {
533     const overlay::Count *countWidget = static_cast<const overlay::Count *>(widget);
534     std::ostringstream text;
535     double kb = static_cast<double>(countWidget->count) / 1000.0;
536     text << "DS Cache Key Size: " << std::fixed << std::setprecision(1) << kb << " kb";
537 
538     AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
539 }
540 
OutputPerSecond(std::ostream & out,const overlay::PerSecond * perSecond)541 std::ostream &AppendWidgetDataHelper::OutputPerSecond(std::ostream &out,
542                                                       const overlay::PerSecond *perSecond)
543 {
544     return out << perSecond->lastPerSecondCount;
545 }
546 
OutputText(std::ostream & out,const overlay::Text * text)547 std::ostream &AppendWidgetDataHelper::OutputText(std::ostream &out, const overlay::Text *text)
548 {
549     return out << text->text;
550 }
551 
OutputCount(std::ostream & out,const overlay::Count * count)552 std::ostream &AppendWidgetDataHelper::OutputCount(std::ostream &out, const overlay::Count *count)
553 {
554     return out << count->count;
555 }
556 }  // namespace overlay_impl
557 
558 namespace
559 {
560 #define ANGLE_APPEND_WIDGET_MAP_PROC(WIDGET_ID) \
561     {WidgetId::WIDGET_ID, overlay_impl::AppendWidgetDataHelper::Append##WIDGET_ID},
562 
563 constexpr angle::PackedEnumMap<WidgetId, AppendWidgetDataFunc> kWidgetIdToAppendDataFuncMap = {
564     ANGLE_WIDGET_ID_X(ANGLE_APPEND_WIDGET_MAP_PROC)};
565 }  // namespace
566 
567 namespace overlay
568 {
RunningGraph(size_t n)569 RunningGraph::RunningGraph(size_t n) : runningValues(n, 0) {}
570 RunningGraph::~RunningGraph() = default;
571 }  // namespace overlay
572 
getWidgetCoordinatesBufferSize() const573 size_t OverlayState::getWidgetCoordinatesBufferSize() const
574 {
575     return sizeof(WidgetCoordinates);
576 }
577 
getTextWidgetsBufferSize() const578 size_t OverlayState::getTextWidgetsBufferSize() const
579 {
580     return sizeof(TextWidgets);
581 }
582 
getGraphWidgetsBufferSize() const583 size_t OverlayState::getGraphWidgetsBufferSize() const
584 {
585     return sizeof(GraphWidgets);
586 }
587 
fillWidgetData(const gl::Extents & imageExtents,uint8_t * textData,uint8_t * graphData,uint32_t * activeTextWidgetCountOut,uint32_t * activeGraphWidgetCountOut) const588 void OverlayState::fillWidgetData(const gl::Extents &imageExtents,
589                                   uint8_t *textData,
590                                   uint8_t *graphData,
591                                   uint32_t *activeTextWidgetCountOut,
592                                   uint32_t *activeGraphWidgetCountOut) const
593 {
594     TextWidgets *textWidgets   = reinterpret_cast<TextWidgets *>(textData);
595     GraphWidgets *graphWidgets = reinterpret_cast<GraphWidgets *>(graphData);
596 
597     memset(textWidgets, overlay::kFontCharacters, sizeof(*textWidgets));
598     memset(graphWidgets, 0, sizeof(*graphWidgets));
599 
600     OverlayWidgetCounts widgetCounts = {};
601 
602     for (WidgetId id : angle::AllEnums<WidgetId>())
603     {
604         const std::unique_ptr<overlay::Widget> &widget = mOverlayWidgets[id];
605         if (!widget->enabled)
606         {
607             continue;
608         }
609 
610         WidgetInternalType internalType = kWidgetTypeToInternalMap[widget->type];
611         ASSERT(internalType != WidgetInternalType::InvalidEnum);
612 
613         if (widgetCounts[internalType] >= kWidgetInternalTypeMaxWidgets[internalType])
614         {
615             continue;
616         }
617 
618         AppendWidgetDataFunc appendFunc = kWidgetIdToAppendDataFuncMap[id];
619         ASSERT(appendFunc);
620         appendFunc(widget.get(), imageExtents,
621                    &textWidgets->widgets[widgetCounts[WidgetInternalType::Text]],
622                    &graphWidgets->widgets[widgetCounts[WidgetInternalType::Graph]], &widgetCounts);
623     }
624 
625     *activeTextWidgetCountOut  = widgetCounts[WidgetInternalType::Text];
626     *activeGraphWidgetCountOut = widgetCounts[WidgetInternalType::Graph];
627 }
628 
629 }  // namespace gl
630