~mmach/netext73/webkit2gtk

« back to all changes in this revision

Viewing changes to Source/ThirdParty/ANGLE/src/libANGLE/OverlayWidgets.cpp

  • Committer: mmach
  • Date: 2023-06-16 17:21:37 UTC
  • Revision ID: netbit73@gmail.com-20230616172137-2rqx6yr96ga9g3kp
1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
namespace gl
 
16
{
 
17
namespace
 
18
{
 
19
// Internally, every widget is either Text or Graph.
 
20
enum class WidgetInternalType
 
21
{
 
22
    Text,
 
23
    Graph,
 
24
 
 
25
    InvalidEnum,
 
26
    EnumCount = InvalidEnum,
 
27
};
 
28
 
 
29
// A map that says how the API-facing widget types map to internal types.
 
30
constexpr angle::PackedEnumMap<WidgetType, WidgetInternalType> kWidgetTypeToInternalMap = {
 
31
    {WidgetType::Count, WidgetInternalType::Text},
 
32
    {WidgetType::Text, WidgetInternalType::Text},
 
33
    {WidgetType::PerSecond, WidgetInternalType::Text},
 
34
    {WidgetType::RunningGraph, WidgetInternalType::Graph},
 
35
    {WidgetType::RunningHistogram, WidgetInternalType::Graph},
 
36
};
 
37
 
 
38
// Structures and limits matching uniform buffers in vulkan/shaders/src/OverlayDraw.comp.  The size
 
39
// of text and graph widgets is chosen such that they could fit in uniform buffers with minimum
 
40
// required Vulkan size.
 
41
constexpr size_t kMaxRenderableTextWidgets  = 32;
 
42
constexpr size_t kMaxRenderableGraphWidgets = 32;
 
43
constexpr size_t kMaxTextLength             = 256;
 
44
constexpr size_t kMaxGraphDataSize          = 64;
 
45
 
 
46
constexpr angle::PackedEnumMap<WidgetInternalType, size_t> kWidgetInternalTypeMaxWidgets = {
 
47
    {WidgetInternalType::Text, kMaxRenderableTextWidgets},
 
48
    {WidgetInternalType::Graph, kMaxRenderableGraphWidgets},
 
49
};
 
50
 
 
51
constexpr angle::PackedEnumMap<WidgetInternalType, size_t> kWidgetInternalTypeWidgetOffsets = {
 
52
    {WidgetInternalType::Text, 0},
 
53
    {WidgetInternalType::Graph, kMaxRenderableTextWidgets},
 
54
};
 
55
 
 
56
ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
 
57
 
 
58
// Structure matching buffer in vulkan/shaders/src/OverlayCull.comp.
 
59
struct WidgetCoordinates
 
60
{
 
61
    uint32_t coordinates[kMaxRenderableTextWidgets + kMaxRenderableGraphWidgets][4];
 
62
};
 
63
 
 
64
// Structures matching buffers in vulkan/shaders/src/OverlayDraw.comp.
 
65
struct TextWidgetData
 
66
{
 
67
    uint32_t coordinates[4];
 
68
    float color[4];
 
69
    uint32_t fontSize[3];
 
70
    uint32_t padding;
 
71
    uint8_t text[kMaxTextLength];
 
72
};
 
73
 
 
74
struct GraphWidgetData
 
75
{
 
76
    uint32_t coordinates[4];
 
77
    float color[4];
 
78
    uint32_t valueWidth;
 
79
    uint32_t padding[3];
 
80
    uint32_t values[kMaxGraphDataSize];
 
81
};
 
82
 
 
83
struct TextWidgets
 
84
{
 
85
    TextWidgetData widgets[kMaxRenderableTextWidgets];
 
86
};
 
87
 
 
88
struct GraphWidgets
 
89
{
 
90
    GraphWidgetData widgets[kMaxRenderableGraphWidgets];
 
91
};
 
92
 
 
93
ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
 
94
 
 
95
uint32_t GetWidgetCoord(int32_t src, uint32_t extent)
 
96
{
 
97
    int32_t dst = src < 0 ? extent + src : src;
 
98
 
 
99
    return std::min<uint32_t>(std::max(dst, 0), extent - 1);
 
100
}
 
101
 
 
102
void GetWidgetCoordinates(const int32_t srcCoords[4],
 
103
                          const gl::Extents &imageExtent,
 
104
                          uint32_t dstCoordsOut[4])
 
105
{
 
106
    dstCoordsOut[0] = GetWidgetCoord(srcCoords[0], imageExtent.width);
 
107
    dstCoordsOut[1] = GetWidgetCoord(srcCoords[1], imageExtent.height);
 
108
    dstCoordsOut[2] = GetWidgetCoord(srcCoords[2], imageExtent.width);
 
109
    dstCoordsOut[3] = GetWidgetCoord(srcCoords[3], imageExtent.height);
 
110
}
 
111
 
 
112
void GetWidgetColor(const float srcColor[4], float dstColor[4])
 
113
{
 
114
    memcpy(dstColor, srcColor, 4 * sizeof(dstColor[0]));
 
115
}
 
116
 
 
117
void GetTextFontSize(int srcFontSize, uint32_t dstFontSize[3])
 
118
{
 
119
    // .xy contains the font glyph width/height
 
120
    dstFontSize[0] = overlay::kFontGlyphWidths[srcFontSize];
 
121
    dstFontSize[1] = overlay::kFontGlyphHeights[srcFontSize];
 
122
    // .z contains the layer
 
123
    dstFontSize[2] = srcFontSize;
 
124
}
 
125
 
 
126
void GetGraphValueWidth(const int32_t srcCoords[4], size_t valueCount, uint32_t *dstValueWidth)
 
127
{
 
128
    const int32_t graphWidth = std::abs(srcCoords[2] - srcCoords[0]);
 
129
 
 
130
    // If valueCount doesn't divide graphWidth, the graph bars won't fit well in its frame.
 
131
    // Fix initOverlayWidgets() in that case.
 
132
    ASSERT(graphWidth % valueCount == 0);
 
133
 
 
134
    *dstValueWidth = graphWidth / valueCount;
 
135
}
 
136
 
 
137
void GetTextString(const std::string &src, uint8_t textOut[kMaxTextLength])
 
138
{
 
139
    for (size_t i = 0; i < src.length() && i < kMaxTextLength; ++i)
 
140
    {
 
141
        // The font image has 96 ASCII characters starting from ' '.
 
142
        textOut[i] = src[i] - ' ';
 
143
    }
 
144
}
 
145
 
 
146
void GetGraphValues(const std::vector<size_t> srcValues,
 
147
                    size_t startIndex,
 
148
                    float scale,
 
149
                    uint32_t valuesOut[kMaxGraphDataSize])
 
150
{
 
151
    ASSERT(srcValues.size() <= kMaxGraphDataSize);
 
152
 
 
153
    for (size_t i = 0; i < srcValues.size(); ++i)
 
154
    {
 
155
        size_t index = (startIndex + i) % srcValues.size();
 
156
        valuesOut[i] = static_cast<uint32_t>(srcValues[index] * scale);
 
157
    }
 
158
}
 
159
 
 
160
std::vector<size_t> CreateHistogram(const std::vector<size_t> values)
 
161
{
 
162
    std::vector<size_t> histogram(values.size(), 0);
 
163
 
 
164
    for (size_t rank : values)
 
165
    {
 
166
        ++histogram[rank];
 
167
    }
 
168
 
 
169
    return histogram;
 
170
}
 
171
 
 
172
using OverlayWidgetCounts  = angle::PackedEnumMap<WidgetInternalType, size_t>;
 
173
using AppendWidgetDataFunc = void (*)(const overlay::Widget *widget,
 
174
                                      const gl::Extents &imageExtent,
 
175
                                      TextWidgetData *textWidget,
 
176
                                      GraphWidgetData *graphWidget,
 
177
                                      OverlayWidgetCounts *widgetCounts);
 
178
}  // namespace
 
179
 
 
180
namespace overlay_impl
 
181
{
 
182
// This class interprets the generic data collected in every element into a human-understandable
 
183
// widget.  This often means generating text specific to this item and scaling graph data to
 
184
// something sensible.
 
185
class AppendWidgetDataHelper
 
186
{
 
187
  public:
 
188
    static void AppendFPS(const overlay::Widget *widget,
 
189
                          const gl::Extents &imageExtent,
 
190
                          TextWidgetData *textWidget,
 
191
                          GraphWidgetData *graphWidget,
 
192
                          OverlayWidgetCounts *widgetCounts);
 
193
    static void AppendVulkanLastValidationMessage(const overlay::Widget *widget,
 
194
                                                  const gl::Extents &imageExtent,
 
195
                                                  TextWidgetData *textWidget,
 
196
                                                  GraphWidgetData *graphWidget,
 
197
                                                  OverlayWidgetCounts *widgetCounts);
 
198
    static void AppendVulkanValidationMessageCount(const overlay::Widget *widget,
 
199
                                                   const gl::Extents &imageExtent,
 
200
                                                   TextWidgetData *textWidget,
 
201
                                                   GraphWidgetData *graphWidget,
 
202
                                                   OverlayWidgetCounts *widgetCounts);
 
203
    static void AppendVulkanCommandGraphSize(const overlay::Widget *widget,
 
204
                                             const gl::Extents &imageExtent,
 
205
                                             TextWidgetData *textWidget,
 
206
                                             GraphWidgetData *graphWidget,
 
207
                                             OverlayWidgetCounts *widgetCounts);
 
208
    static void AppendVulkanSecondaryCommandBufferPoolWaste(const overlay::Widget *widget,
 
209
                                                            const gl::Extents &imageExtent,
 
210
                                                            TextWidgetData *textWidget,
 
211
                                                            GraphWidgetData *graphWidget,
 
212
                                                            OverlayWidgetCounts *widgetCounts);
 
213
 
 
214
  private:
 
215
    static std::ostream &OutputPerSecond(std::ostream &out, const overlay::PerSecond *perSecond);
 
216
 
 
217
    static std::ostream &OutputText(std::ostream &out, const overlay::Text *text);
 
218
 
 
219
    static std::ostream &OutputCount(std::ostream &out, const overlay::Count *count);
 
220
 
 
221
    static void AppendTextCommon(const overlay::Widget *widget,
 
222
                                 const gl::Extents &imageExtent,
 
223
                                 const std::string &text,
 
224
                                 TextWidgetData *textWidget,
 
225
                                 OverlayWidgetCounts *widgetCounts);
 
226
 
 
227
    static void AppendGraphCommon(const overlay::Widget *widget,
 
228
                                  const gl::Extents &imageExtent,
 
229
                                  const std::vector<size_t> runningValues,
 
230
                                  size_t startIndex,
 
231
                                  float scale,
 
232
                                  GraphWidgetData *graphWidget,
 
233
                                  OverlayWidgetCounts *widgetCounts);
 
234
};
 
235
 
 
236
void AppendWidgetDataHelper::AppendTextCommon(const overlay::Widget *widget,
 
237
                                              const gl::Extents &imageExtent,
 
238
                                              const std::string &text,
 
239
                                              TextWidgetData *textWidget,
 
240
                                              OverlayWidgetCounts *widgetCounts)
 
241
{
 
242
    GetWidgetCoordinates(widget->coords, imageExtent, textWidget->coordinates);
 
243
    GetWidgetColor(widget->color, textWidget->color);
 
244
    GetTextFontSize(widget->fontSize, textWidget->fontSize);
 
245
    GetTextString(text, textWidget->text);
 
246
 
 
247
    ++(*widgetCounts)[WidgetInternalType::Text];
 
248
}
 
249
 
 
250
void AppendWidgetDataHelper::AppendGraphCommon(const overlay::Widget *widget,
 
251
                                               const gl::Extents &imageExtent,
 
252
                                               const std::vector<size_t> runningValues,
 
253
                                               size_t startIndex,
 
254
                                               float scale,
 
255
                                               GraphWidgetData *graphWidget,
 
256
                                               OverlayWidgetCounts *widgetCounts)
 
257
{
 
258
    const overlay::RunningGraph *widgetAsGraph = static_cast<const overlay::RunningGraph *>(widget);
 
259
 
 
260
    GetWidgetCoordinates(widget->coords, imageExtent, graphWidget->coordinates);
 
261
    GetWidgetColor(widget->color, graphWidget->color);
 
262
    GetGraphValueWidth(widget->coords, widgetAsGraph->runningValues.size(),
 
263
                       &graphWidget->valueWidth);
 
264
    GetGraphValues(runningValues, startIndex, scale, graphWidget->values);
 
265
 
 
266
    ++(*widgetCounts)[WidgetInternalType::Graph];
 
267
}
 
268
 
 
269
void AppendWidgetDataHelper::AppendFPS(const overlay::Widget *widget,
 
270
                                       const gl::Extents &imageExtent,
 
271
                                       TextWidgetData *textWidget,
 
272
                                       GraphWidgetData *graphWidget,
 
273
                                       OverlayWidgetCounts *widgetCounts)
 
274
{
 
275
    const overlay::PerSecond *fps = static_cast<const overlay::PerSecond *>(widget);
 
276
    std::ostringstream text;
 
277
    text << "FPS: ";
 
278
    OutputPerSecond(text, fps);
 
279
 
 
280
    AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
 
281
}
 
282
 
 
283
void AppendWidgetDataHelper::AppendVulkanLastValidationMessage(const overlay::Widget *widget,
 
284
                                                               const gl::Extents &imageExtent,
 
285
                                                               TextWidgetData *textWidget,
 
286
                                                               GraphWidgetData *graphWidget,
 
287
                                                               OverlayWidgetCounts *widgetCounts)
 
288
{
 
289
    const overlay::Text *lastValidationMessage = static_cast<const overlay::Text *>(widget);
 
290
    std::ostringstream text;
 
291
    text << "Last VVL Message: ";
 
292
    OutputText(text, lastValidationMessage);
 
293
 
 
294
    AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
 
295
}
 
296
 
 
297
void AppendWidgetDataHelper::AppendVulkanValidationMessageCount(const overlay::Widget *widget,
 
298
                                                                const gl::Extents &imageExtent,
 
299
                                                                TextWidgetData *textWidget,
 
300
                                                                GraphWidgetData *graphWidget,
 
301
                                                                OverlayWidgetCounts *widgetCounts)
 
302
{
 
303
    const overlay::Count *validationMessageCount = static_cast<const overlay::Count *>(widget);
 
304
    std::ostringstream text;
 
305
    text << "VVL Message Count: ";
 
306
    OutputCount(text, validationMessageCount);
 
307
 
 
308
    AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
 
309
}
 
310
 
 
311
void AppendWidgetDataHelper::AppendVulkanCommandGraphSize(const overlay::Widget *widget,
 
312
                                                          const gl::Extents &imageExtent,
 
313
                                                          TextWidgetData *textWidget,
 
314
                                                          GraphWidgetData *graphWidget,
 
315
                                                          OverlayWidgetCounts *widgetCounts)
 
316
{
 
317
    const overlay::RunningGraph *commandGraphSize =
 
318
        static_cast<const overlay::RunningGraph *>(widget);
 
319
 
 
320
    const size_t maxValue     = *std::max_element(commandGraphSize->runningValues.begin(),
 
321
                                              commandGraphSize->runningValues.end());
 
322
    const int32_t graphHeight = std::abs(widget->coords[3] - widget->coords[1]);
 
323
    const float graphScale    = static_cast<float>(graphHeight) / maxValue;
 
324
 
 
325
    AppendGraphCommon(widget, imageExtent, commandGraphSize->runningValues,
 
326
                      commandGraphSize->lastValueIndex + 1, graphScale, graphWidget, widgetCounts);
 
327
 
 
328
    if ((*widgetCounts)[WidgetInternalType::Text] <
 
329
        kWidgetInternalTypeMaxWidgets[WidgetInternalType::Text])
 
330
    {
 
331
        std::ostringstream text;
 
332
        text << "Command Graph Size (Max: " << maxValue << ")";
 
333
        AppendTextCommon(&commandGraphSize->description, imageExtent, text.str(), textWidget,
 
334
                         widgetCounts);
 
335
    }
 
336
}
 
337
 
 
338
void AppendWidgetDataHelper::AppendVulkanSecondaryCommandBufferPoolWaste(
 
339
    const overlay::Widget *widget,
 
340
    const gl::Extents &imageExtent,
 
341
    TextWidgetData *textWidget,
 
342
    GraphWidgetData *graphWidget,
 
343
    OverlayWidgetCounts *widgetCounts)
 
344
{
 
345
    const overlay::RunningHistogram *secondaryCommandBufferPoolWaste =
 
346
        static_cast<const overlay::RunningHistogram *>(widget);
 
347
 
 
348
    std::vector<size_t> histogram = CreateHistogram(secondaryCommandBufferPoolWaste->runningValues);
 
349
    auto maxValueIter             = std::max_element(histogram.rbegin(), histogram.rend());
 
350
    const size_t maxValue         = *maxValueIter;
 
351
    const int32_t graphHeight     = std::abs(widget->coords[3] - widget->coords[1]);
 
352
    const float graphScale        = static_cast<float>(graphHeight) / maxValue;
 
353
 
 
354
    AppendGraphCommon(widget, imageExtent, histogram, 0, graphScale, graphWidget, widgetCounts);
 
355
 
 
356
    if ((*widgetCounts)[WidgetInternalType::Text] <
 
357
        kWidgetInternalTypeMaxWidgets[WidgetInternalType::Text])
 
358
    {
 
359
        std::ostringstream text;
 
360
        size_t peak        = std::distance(maxValueIter, histogram.rend() - 1);
 
361
        size_t peakPercent = (peak * 100 + 50) / histogram.size();
 
362
 
 
363
        text << "CB Pool Waste (Peak: " << peakPercent << "%)";
 
364
        AppendTextCommon(&secondaryCommandBufferPoolWaste->description, imageExtent, text.str(),
 
365
                         textWidget, widgetCounts);
 
366
    }
 
367
}
 
368
 
 
369
std::ostream &AppendWidgetDataHelper::OutputPerSecond(std::ostream &out,
 
370
                                                      const overlay::PerSecond *perSecond)
 
371
{
 
372
    return out << perSecond->lastPerSecondCount;
 
373
}
 
374
 
 
375
std::ostream &AppendWidgetDataHelper::OutputText(std::ostream &out, const overlay::Text *text)
 
376
{
 
377
    return out << text->text;
 
378
}
 
379
 
 
380
std::ostream &AppendWidgetDataHelper::OutputCount(std::ostream &out, const overlay::Count *count)
 
381
{
 
382
    return out << count->count;
 
383
}
 
384
}  // namespace overlay_impl
 
385
 
 
386
namespace
 
387
{
 
388
constexpr angle::PackedEnumMap<WidgetId, AppendWidgetDataFunc> kWidgetIdToAppendDataFuncMap = {
 
389
    {WidgetId::FPS, overlay_impl::AppendWidgetDataHelper::AppendFPS},
 
390
    {WidgetId::VulkanLastValidationMessage,
 
391
     overlay_impl::AppendWidgetDataHelper::AppendVulkanLastValidationMessage},
 
392
    {WidgetId::VulkanValidationMessageCount,
 
393
     overlay_impl::AppendWidgetDataHelper::AppendVulkanValidationMessageCount},
 
394
    {WidgetId::VulkanCommandGraphSize,
 
395
     overlay_impl::AppendWidgetDataHelper::AppendVulkanCommandGraphSize},
 
396
    {WidgetId::VulkanSecondaryCommandBufferPoolWaste,
 
397
     overlay_impl::AppendWidgetDataHelper::AppendVulkanSecondaryCommandBufferPoolWaste},
 
398
};
 
399
}
 
400
 
 
401
namespace overlay
 
402
{
 
403
RunningGraph::RunningGraph(size_t n) : runningValues(n, 0) {}
 
404
RunningGraph::~RunningGraph() = default;
 
405
}  // namespace overlay
 
406
 
 
407
size_t OverlayState::getWidgetCoordinatesBufferSize() const
 
408
{
 
409
    return sizeof(WidgetCoordinates);
 
410
}
 
411
 
 
412
size_t OverlayState::getTextWidgetsBufferSize() const
 
413
{
 
414
    return sizeof(TextWidgets);
 
415
}
 
416
 
 
417
size_t OverlayState::getGraphWidgetsBufferSize() const
 
418
{
 
419
    return sizeof(GraphWidgets);
 
420
}
 
421
 
 
422
void OverlayState::fillEnabledWidgetCoordinates(const gl::Extents &imageExtents,
 
423
                                                uint8_t *enabledWidgetsPtr) const
 
424
{
 
425
    WidgetCoordinates *enabledWidgets = reinterpret_cast<WidgetCoordinates *>(enabledWidgetsPtr);
 
426
    memset(enabledWidgets, 0, sizeof(*enabledWidgets));
 
427
 
 
428
    OverlayWidgetCounts widgetCounts = {};
 
429
 
 
430
    for (const std::unique_ptr<overlay::Widget> &widget : mOverlayWidgets)
 
431
    {
 
432
        if (!widget->enabled)
 
433
        {
 
434
            continue;
 
435
        }
 
436
 
 
437
        WidgetInternalType internalType = kWidgetTypeToInternalMap[widget->type];
 
438
        ASSERT(internalType != WidgetInternalType::InvalidEnum);
 
439
 
 
440
        if (widgetCounts[internalType] >= kWidgetInternalTypeMaxWidgets[internalType])
 
441
        {
 
442
            continue;
 
443
        }
 
444
 
 
445
        size_t writeIndex =
 
446
            kWidgetInternalTypeWidgetOffsets[internalType] + widgetCounts[internalType]++;
 
447
 
 
448
        GetWidgetCoordinates(widget->coords, imageExtents, enabledWidgets->coordinates[writeIndex]);
 
449
 
 
450
        // Graph widgets have a text widget attached as well.
 
451
        if (internalType == WidgetInternalType::Graph)
 
452
        {
 
453
            WidgetInternalType textType = WidgetInternalType::Text;
 
454
            if (widgetCounts[textType] >= kWidgetInternalTypeMaxWidgets[textType])
 
455
            {
 
456
                continue;
 
457
            }
 
458
 
 
459
            const overlay::RunningGraph *widgetAsGraph =
 
460
                static_cast<const overlay::RunningGraph *>(widget.get());
 
461
            writeIndex = kWidgetInternalTypeWidgetOffsets[textType] + widgetCounts[textType]++;
 
462
 
 
463
            GetWidgetCoordinates(widgetAsGraph->description.coords, imageExtents,
 
464
                                 enabledWidgets->coordinates[writeIndex]);
 
465
        }
 
466
    }
 
467
}
 
468
 
 
469
void OverlayState::fillWidgetData(const gl::Extents &imageExtents,
 
470
                                  uint8_t *textData,
 
471
                                  uint8_t *graphData) const
 
472
{
 
473
    TextWidgets *textWidgets   = reinterpret_cast<TextWidgets *>(textData);
 
474
    GraphWidgets *graphWidgets = reinterpret_cast<GraphWidgets *>(graphData);
 
475
 
 
476
    memset(textWidgets, overlay::kFontCharacters, sizeof(*textWidgets));
 
477
    memset(graphWidgets, 0, sizeof(*graphWidgets));
 
478
 
 
479
    OverlayWidgetCounts widgetCounts = {};
 
480
 
 
481
    for (WidgetId id : angle::AllEnums<WidgetId>())
 
482
    {
 
483
        const std::unique_ptr<overlay::Widget> &widget = mOverlayWidgets[id];
 
484
        if (!widget->enabled)
 
485
        {
 
486
            continue;
 
487
        }
 
488
 
 
489
        WidgetInternalType internalType = kWidgetTypeToInternalMap[widget->type];
 
490
        ASSERT(internalType != WidgetInternalType::InvalidEnum);
 
491
 
 
492
        if (widgetCounts[internalType] >= kWidgetInternalTypeMaxWidgets[internalType])
 
493
        {
 
494
            continue;
 
495
        }
 
496
 
 
497
        AppendWidgetDataFunc appendFunc = kWidgetIdToAppendDataFuncMap[id];
 
498
        appendFunc(widget.get(), imageExtents,
 
499
                   &textWidgets->widgets[widgetCounts[WidgetInternalType::Text]],
 
500
                   &graphWidgets->widgets[widgetCounts[WidgetInternalType::Graph]], &widgetCounts);
 
501
    }
 
502
}
 
503
 
 
504
}  // namespace gl