Edit

kc3-lang/angle/src/libANGLE/OverlayWidgets.h

Branch :

  • Show log

    Commit

  • Author : Shahbaz Youssefi
    Date : 2019-06-30 03:26:18
    Hash : 050b124d
    Message : Reland "Vulkan: Debug overlay" This is a reland of e54d0f90d1a165404236fd7abd1b05ddd041a686 This was reverted due to a build failure as a result of a missing virtual destructor in the widget base class. Original change's description: > Vulkan: Debug overlay > > A debug overlay system for the Vulkan backend designed with efficiency > and runtime configurability in mind. Overlay widgets are of two > fundamental types: > > - Text widgets: A single line of text with small, medium or large font. > - Graph widgets: A bar graph of data. > > Built on these, various overlay widget types are defined that gather > statistics. Five such types are defined with one widget per type as > example: > > - Count: A widget that counts something. VulkanValidationMessageCount > is an overlay widget of this type that shows the number of validation > messages received from the validation layers. > - Text: A generic text. VulkanLastValidationMessage is an overlay > widget of this type that shows the last validation message. > - PerSecond: A value that gets reset every second automatically. FPS is > an overlay widget of this type that simply gets incremented on every > swap(). > - RunningGraph: A graph of last N values. VulkanCommandGraphSize is an > overlay of this type. On every vkQueueSubmit, the number of nodes in > the command graph is accumulated. On every present(), the value is > taken as the number of nodes for the whole duration of the frame. > - RunningHistogram: A histogram of last N values. Input values are in > the [0, 1] range and they are ranked to N buckets for histogram > calculation. VulkanSecondaryCommandBufferPoolWaste is an overlay > widget of this type. On vkQueueSubmit, the memory waste from command > buffer pool allocations is recorded in the histogram. > > Overlay font is placed in libANGLE/overlay/ which gen_overlay_fonts.py > processes to create an array of bits, which is processed at runtime to > create the actual font image (an image with 3 layers). > > The overlay widget layout is defined in overlay_widgets.json which > gen_overlay_widgets.py processes to generate an array of widgetss, each > of its respective type, and sets their properties, such as color and > bounding box. The json file allows widgets to align against other > widgets as well as against the framebuffer edges. > > Two compute shaders are implemented to efficiently render the UI: > > - OverlayCull: This shader creates a bitset of Text and Graph widgets > whose bounding boxes intersect a corresponding subgroup processed by > OverlayDraw. This is done only when the enabled overlay widgets are > changed (a feature that is not yet implemented) or the surface is > resized. > - OverlayDraw: Using the bitsets generated by OverlayCull, values that > are uniform for each workgroup (set to be equal to hardware subgroup > size), this shader loops over enabled widgets that can possibly > intersect the pixel being processed and renders and blends in texts > and graphs. This is done once per frame on present(). > > Currently, to enable overlay widgets an environment variable is used. > For example: > > $ export ANGLE_OVERLAY=FPS:VulkanSecondaryCommandBufferPoolWaste > $ ./hello_triangle --use-angle=vulkan > > Possible future work: > > - On Android, add settings in developer options and enable widgets based > on those. > - Spawn a small server in ANGLE and write an application that sends > enable/disable commands remotely. > - Implement overlay for other backends. > > Bug: angleproject:3757 > Change-Id: If9c6974d1935c18f460ec569e79b41188bd7afcc > Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1729440 > Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> > Reviewed-by: Jamie Madill <jmadill@chromium.org> Bug: angleproject:3757 Change-Id: I47915d88b37b6f882c686c2de13fca309a10b572 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1780897 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>

  • src/libANGLE/OverlayWidgets.h
  • //
    // Copyright 2019 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    // OverlayWidgets.h:
    //    Defines the Overlay* widget classes and corresponding enums.
    //
    
    #ifndef LIBANGLE_OVERLAYWIDGETS_H_
    #define LIBANGLE_OVERLAYWIDGETS_H_
    
    #include "common/angleutils.h"
    
    namespace gl
    {
    class Overlay;
    class OverlayState;
    
    namespace overlay_impl
    {
    class AppendWidgetDataHelper;
    }
    
    enum class WidgetType
    {
        // Text types:
    
        // A total count of some event.
        Count,
        // A single line of ASCII text.  Retains content until changed.
        Text,
        // A per-second value.
        PerSecond,
    
        // Graph types:
    
        // A graph of the last N values.
        RunningGraph,
        // A histogram of the last N values (values between 0 and 1).
        RunningHistogram,
    
        InvalidEnum,
        EnumCount = InvalidEnum,
    };
    
    enum class WidgetId
    {
        // Front-end widgets:
    
        // Frames per second (PerSecond).
        FPS,
    
        // Vulkan backend:
    
        // Last validation error (Text).
        VulkanLastValidationMessage,
        // Number of validation errors and warnings (Count).
        VulkanValidationMessageCount,
        // Number of nodes in command graph (RunningGraph).
        VulkanCommandGraphSize,
        // Secondary Command Buffer pool memory waste (RunningHistogram).
        VulkanSecondaryCommandBufferPoolWaste,
    
        InvalidEnum,
        EnumCount = InvalidEnum,
    };
    
    namespace overlay
    {
    class Widget
    {
      public:
        virtual ~Widget() {}
    
      protected:
        WidgetType type;
        // Whether this item should be drawn.
        bool enabled = false;
    
        // For text items, size of the font.  This is a value in [0, overlay::kFontCount) which
        // determines the font size to use.
        int fontSize;
    
        // The area covered by the item, predetermined by the overlay class.  Negative values
        // indicate offset from the left/bottom of the image.
        int32_t coords[4];
        float color[4];
    
        friend class gl::Overlay;
        friend class gl::OverlayState;
        friend class overlay_impl::AppendWidgetDataHelper;
    };
    
    class Count : public Widget
    {
      public:
        ~Count() override {}
        void add(size_t n) { count += n; }
        void reset() { count = 0; }
    
      protected:
        size_t count = 0;
    
        friend class gl::Overlay;
        friend class overlay_impl::AppendWidgetDataHelper;
    };
    
    class PerSecond : public Count
    {
      public:
        ~PerSecond() override {}
    
      protected:
        size_t lastPerSecondCount = 0;
    
        friend class gl::Overlay;
        friend class overlay_impl::AppendWidgetDataHelper;
    };
    
    class Text : public Widget
    {
      public:
        ~Text() override {}
        void set(std::string &&str) { text = std::move(str); }
    
      protected:
        std::string text;
    
        friend class overlay_impl::AppendWidgetDataHelper;
    };
    
    class RunningGraph : public Widget
    {
      public:
        // Out of line constructor to satisfy chromium-style.
        RunningGraph(size_t n);
        ~RunningGraph() override;
        void add(size_t n) { runningValues[lastValueIndex] += n; }
        void next()
        {
            lastValueIndex                = (lastValueIndex + 1) % runningValues.size();
            runningValues[lastValueIndex] = 0;
        }
    
      protected:
        std::vector<size_t> runningValues;
        size_t lastValueIndex = 0;
        Text description;
    
        friend class gl::Overlay;
        friend class gl::OverlayState;
        friend class overlay_impl::AppendWidgetDataHelper;
    };
    
    class RunningHistogram : public RunningGraph
    {
      public:
        RunningHistogram(size_t n) : RunningGraph(n) {}
        ~RunningHistogram() override {}
        void set(float n)
        {
            ASSERT(n >= 0.0f && n <= 1.0f);
            size_t rank =
                n == 1.0f ? runningValues.size() - 1 : static_cast<size_t>(n * runningValues.size());
    
            runningValues[lastValueIndex] = rank;
        }
    };
    
    // If overlay is disabled, all the above classes would be replaced with Dummy, turning them into
    // noop.
    class Dummy
    {
      public:
        void reset() const {}
        template <typename T>
        void set(T) const
        {}
        template <typename T>
        void add(T) const
        {}
        void next() const {}
    };
    
    }  // namespace overlay
    
    }  // namespace gl
    
    #endif  // LIBANGLE_OVERLAYWIDGETS_H_