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