tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

OverlayWidgets.cpp (30948B)


      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 
     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 
     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 
    109 void GetWidgetColor(const float srcColor[4], float dstColor[4])
    110 {
    111    memcpy(dstColor, srcColor, 4 * sizeof(dstColor[0]));
    112 }
    113 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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
    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 
    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 
    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 
    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 
    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 
    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 
    413 void AppendWidgetDataHelper::AppendVulkanRenderPassBufferCount(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 << "RP VkBuffers (Max: " << maxValue << ")";
    422        return text.str();
    423    };
    424 
    425    AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
    426 }
    427 
    428 void AppendWidgetDataHelper::AppendVulkanWriteDescriptorSetCount(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 << "WriteDescriptorSet Count: " << maxValue;
    437        return text.str();
    438    };
    439 
    440    AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
    441 }
    442 
    443 void AppendWidgetDataHelper::AppendVulkanDescriptorSetAllocations(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 << "Descriptor Set Allocations: " << maxValue;
    452        return text.str();
    453    };
    454 
    455    AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
    456 }
    457 
    458 void AppendWidgetDataHelper::AppendVulkanShaderResourceDSHitRate(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 << "Shader Resource DS Hit Rate (Max: " << maxValue << "%)";
    467        return text.str();
    468    };
    469 
    470    AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
    471 }
    472 
    473 void AppendWidgetDataHelper::AppendVulkanDynamicBufferAllocations(const overlay::Widget *widget,
    474                                                                  const gl::Extents &imageExtent,
    475                                                                  TextWidgetData *textWidget,
    476                                                                  GraphWidgetData *graphWidget,
    477                                                                  OverlayWidgetCounts *widgetCounts)
    478 {
    479    auto format = [](uint64_t curValue, uint64_t maxValue) {
    480        std::ostringstream text;
    481        text << "DynamicBuffer Allocations (Max: " << maxValue << ")";
    482        return text.str();
    483    };
    484 
    485    AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
    486 }
    487 
    488 void AppendWidgetDataHelper::AppendVulkanTextureDescriptorCacheSize(
    489    const overlay::Widget *widget,
    490    const gl::Extents &imageExtent,
    491    TextWidgetData *textWidget,
    492    GraphWidgetData *graphWidget,
    493    OverlayWidgetCounts *widgetCounts)
    494 {
    495    auto format = [](uint64_t curValue, uint64_t maxValue) {
    496        std::ostringstream text;
    497        text << "Total Texture Descriptor Cache Size: " << curValue;
    498        return text.str();
    499    };
    500 
    501    AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
    502 }
    503 
    504 void AppendWidgetDataHelper::AppendVulkanUniformDescriptorCacheSize(
    505    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 Uniform Descriptor Cache Size: " << curValue;
    514        return text.str();
    515    };
    516 
    517    AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
    518 }
    519 
    520 void AppendWidgetDataHelper::AppendVulkanDescriptorCacheSize(const overlay::Widget *widget,
    521                                                             const gl::Extents &imageExtent,
    522                                                             TextWidgetData *textWidget,
    523                                                             GraphWidgetData *graphWidget,
    524                                                             OverlayWidgetCounts *widgetCounts)
    525 {
    526    auto format = [](uint64_t curValue, uint64_t maxValue) {
    527        std::ostringstream text;
    528        text << "Total Descriptor Cache Size: " << curValue;
    529        return text.str();
    530    };
    531 
    532    AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
    533 }
    534 
    535 void AppendWidgetDataHelper::AppendVulkanDescriptorCacheKeySize(const overlay::Widget *widget,
    536                                                                const gl::Extents &imageExtent,
    537                                                                TextWidgetData *textWidget,
    538                                                                GraphWidgetData *graphWidget,
    539                                                                OverlayWidgetCounts *widgetCounts)
    540 {
    541    const overlay::Count *countWidget = static_cast<const overlay::Count *>(widget);
    542    std::ostringstream text;
    543    double kb = static_cast<double>(countWidget->count) / 1000.0;
    544    text << "DS Cache Key Size: " << std::fixed << std::setprecision(1) << kb << " kb";
    545 
    546    AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
    547 }
    548 
    549 void AppendWidgetDataHelper::AppendVulkanAttemptedSubmissions(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 << "Attempted submissions (peak): " << maxValue;
    558        return text.str();
    559    };
    560 
    561    AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
    562 }
    563 
    564 void AppendWidgetDataHelper::AppendVulkanActualSubmissions(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 << "Actual submissions (peak): " << maxValue;
    573        return text.str();
    574    };
    575 
    576    AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
    577 }
    578 
    579 void AppendWidgetDataHelper::AppendVulkanPipelineCacheLookups(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 Lookups (peak): " << maxValue;
    588        return text.str();
    589    };
    590 
    591    AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
    592 }
    593 
    594 void AppendWidgetDataHelper::AppendVulkanPipelineCacheMisses(const overlay::Widget *widget,
    595                                                             const gl::Extents &imageExtent,
    596                                                             TextWidgetData *textWidget,
    597                                                             GraphWidgetData *graphWidget,
    598                                                             OverlayWidgetCounts *widgetCounts)
    599 {
    600    auto format = [](uint64_t curValue, uint64_t maxValue) {
    601        std::ostringstream text;
    602        text << "Pipeline Cache Misses (peak): " << maxValue;
    603        return text.str();
    604    };
    605 
    606    AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
    607 }
    608 
    609 void AppendWidgetDataHelper::AppendVulkanTotalPipelineCacheHitTimeMs(
    610    const overlay::Widget *widget,
    611    const gl::Extents &imageExtent,
    612    TextWidgetData *textWidget,
    613    GraphWidgetData *graphWidget,
    614    OverlayWidgetCounts *widgetCounts)
    615 {
    616    const overlay::Count *totalTime = static_cast<const overlay::Count *>(widget);
    617    std::ostringstream text;
    618    text << "Total Pipeline Cache Hit Time: ";
    619    OutputCount(text, totalTime);
    620    text << "ms";
    621 
    622    AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
    623 }
    624 
    625 void AppendWidgetDataHelper::AppendVulkanTotalPipelineCacheMissTimeMs(
    626    const overlay::Widget *widget,
    627    const gl::Extents &imageExtent,
    628    TextWidgetData *textWidget,
    629    GraphWidgetData *graphWidget,
    630    OverlayWidgetCounts *widgetCounts)
    631 {
    632    const overlay::Count *totalTime = static_cast<const overlay::Count *>(widget);
    633    std::ostringstream text;
    634    text << "Total Pipeline Cache Miss Time: ";
    635    OutputCount(text, totalTime);
    636    text << "ms";
    637 
    638    AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
    639 }
    640 
    641 std::ostream &AppendWidgetDataHelper::OutputPerSecond(std::ostream &out,
    642                                                      const overlay::PerSecond *perSecond)
    643 {
    644    return out << perSecond->lastPerSecondCount;
    645 }
    646 
    647 std::ostream &AppendWidgetDataHelper::OutputText(std::ostream &out, const overlay::Text *text)
    648 {
    649    return out << text->text;
    650 }
    651 
    652 std::ostream &AppendWidgetDataHelper::OutputCount(std::ostream &out, const overlay::Count *count)
    653 {
    654    return out << count->count;
    655 }
    656 }  // namespace overlay_impl
    657 
    658 namespace
    659 {
    660 #define ANGLE_APPEND_WIDGET_MAP_PROC(WIDGET_ID) \
    661    {WidgetId::WIDGET_ID, overlay_impl::AppendWidgetDataHelper::Append##WIDGET_ID},
    662 
    663 constexpr angle::PackedEnumMap<WidgetId, AppendWidgetDataFunc> kWidgetIdToAppendDataFuncMap = {
    664    ANGLE_WIDGET_ID_X(ANGLE_APPEND_WIDGET_MAP_PROC)};
    665 }  // namespace
    666 
    667 namespace overlay
    668 {
    669 const Text *Widget::getDescriptionWidget() const
    670 {
    671    return nullptr;
    672 }
    673 RunningGraph::RunningGraph(size_t n) : runningValues(n, 0) {}
    674 RunningGraph::~RunningGraph() = default;
    675 const Text *RunningGraph::getDescriptionWidget() const
    676 {
    677    return &description;
    678 }
    679 }  // namespace overlay
    680 
    681 size_t OverlayState::getWidgetCoordinatesBufferSize() const
    682 {
    683    return sizeof(WidgetCoordinates);
    684 }
    685 
    686 size_t OverlayState::getTextWidgetsBufferSize() const
    687 {
    688    return sizeof(TextWidgets);
    689 }
    690 
    691 size_t OverlayState::getGraphWidgetsBufferSize() const
    692 {
    693    return sizeof(GraphWidgets);
    694 }
    695 
    696 void OverlayState::fillWidgetData(const gl::Extents &imageExtents,
    697                                  uint8_t *textData,
    698                                  uint8_t *graphData,
    699                                  uint32_t *activeTextWidgetCountOut,
    700                                  uint32_t *activeGraphWidgetCountOut) const
    701 {
    702    TextWidgets *textWidgets   = reinterpret_cast<TextWidgets *>(textData);
    703    GraphWidgets *graphWidgets = reinterpret_cast<GraphWidgets *>(graphData);
    704 
    705    memset(textWidgets, overlay::kFontCharacters, sizeof(*textWidgets));
    706    memset(graphWidgets, 0, sizeof(*graphWidgets));
    707 
    708    OverlayWidgetCounts widgetCounts = {};
    709 
    710    for (WidgetId id : angle::AllEnums<WidgetId>())
    711    {
    712        const std::unique_ptr<overlay::Widget> &widget = mOverlayWidgets[id];
    713        if (!widget->enabled)
    714        {
    715            continue;
    716        }
    717 
    718        WidgetInternalType internalType = kWidgetTypeToInternalMap[widget->type];
    719        ASSERT(internalType != WidgetInternalType::InvalidEnum);
    720 
    721        if (widgetCounts[internalType] >= kWidgetInternalTypeMaxWidgets[internalType])
    722        {
    723            continue;
    724        }
    725 
    726        AppendWidgetDataFunc appendFunc = kWidgetIdToAppendDataFuncMap[id];
    727        ASSERT(appendFunc);
    728        appendFunc(widget.get(), imageExtents,
    729                   &textWidgets->widgets[widgetCounts[WidgetInternalType::Text]],
    730                   &graphWidgets->widgets[widgetCounts[WidgetInternalType::Graph]], &widgetCounts);
    731    }
    732 
    733    *activeTextWidgetCountOut  = widgetCounts[WidgetInternalType::Text];
    734    *activeGraphWidgetCountOut = widgetCounts[WidgetInternalType::Graph];
    735 }
    736 
    737 }  // namespace gl