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 // Overlay.h:
7 //    Defines the Overlay class that handles overlay widgets.
8 //
9 
10 #ifndef LIBANGLE_OVERLAY_H_
11 #define LIBANGLE_OVERLAY_H_
12 
13 #include "common/PackedEnums.h"
14 #include "common/angleutils.h"
15 #include "libANGLE/Error.h"
16 #include "libANGLE/OverlayWidgets.h"
17 #include "libANGLE/angletypes.h"
18 
19 namespace rx
20 {
21 class OverlayImpl;
22 class GLImplFactory;
23 }  // namespace rx
24 
25 namespace gl
26 {
27 class Context;
28 
29 class OverlayState : angle::NonCopyable
30 {
31   public:
32     OverlayState();
33     ~OverlayState();
34 
35     size_t getWidgetCoordinatesBufferSize() const;
36     size_t getTextWidgetsBufferSize() const;
37     size_t getGraphWidgetsBufferSize() const;
38 
39     void initFontData(uint8_t *fontData) const;
40     void fillEnabledWidgetCoordinates(const gl::Extents &imageExtents,
41                                       uint8_t *enabledWidgetsPtr) const;
42     void fillWidgetData(const gl::Extents &imageExtents,
43                         uint8_t *textData,
44                         uint8_t *graphData) const;
45 
getEnabledWidgetCount()46     uint32_t getEnabledWidgetCount() const { return mEnabledWidgetCount; }
47 
48   private:
49     friend class Overlay;
50 
51     uint32_t mEnabledWidgetCount;
52 
53     angle::PackedEnumMap<WidgetId, std::unique_ptr<overlay::Widget>> mOverlayWidgets;
54 };
55 
56 class Overlay : angle::NonCopyable
57 {
58   public:
59     Overlay(rx::GLImplFactory *implFactory);
60     ~Overlay();
61 
62     angle::Result init(const Context *context);
63     void destroy(const gl::Context *context);
64 
65     void onSwap() const;
66 
getTextWidget(WidgetId id)67     overlay::Text *getTextWidget(WidgetId id) const
68     {
69         return getWidgetAs<overlay::Text, WidgetType::Text>(id);
70     }
getCountWidget(WidgetId id)71     overlay::Count *getCountWidget(WidgetId id) const
72     {
73         return getWidgetAs<overlay::Count, WidgetType::Count>(id);
74     }
getPerSecondWidget(WidgetId id)75     overlay::PerSecond *getPerSecondWidget(WidgetId id) const
76     {
77         return getWidgetAs<overlay::PerSecond, WidgetType::PerSecond>(id);
78     }
getRunningGraphWidget(WidgetId id)79     overlay::RunningGraph *getRunningGraphWidget(WidgetId id) const
80     {
81         return getWidgetAs<overlay::RunningGraph, WidgetType::RunningGraph>(id);
82     }
getRunningHistogramWidget(WidgetId id)83     overlay::RunningHistogram *getRunningHistogramWidget(WidgetId id) const
84     {
85         return getWidgetAs<overlay::RunningHistogram, WidgetType::RunningHistogram>(id);
86     }
87 
getImplementation()88     rx::OverlayImpl *getImplementation() const { return mImplementation.get(); }
89 
isEnabled()90     bool isEnabled() const { return mImplementation != nullptr; }
91 
92   private:
93     template <typename Widget, WidgetType Type>
getWidgetAs(WidgetId id)94     Widget *getWidgetAs(WidgetId id) const
95     {
96         ASSERT(mState.mOverlayWidgets[id] != nullptr);
97         ASSERT(mState.mOverlayWidgets[id]->type == Type);
98         return rx::GetAs<Widget>(mState.mOverlayWidgets[id].get());
99     }
100     void initOverlayWidgets();
101     void enableOverlayWidgetsFromEnvironment();
102 
103     // Time tracking for PerSecond items.
104     mutable double mLastPerSecondUpdate;
105 
106     OverlayState mState;
107     std::unique_ptr<rx::OverlayImpl> mImplementation;
108 };
109 
110 class MockOverlay
111 {
112   public:
113     MockOverlay(rx::GLImplFactory *implFactory);
114     ~MockOverlay();
115 
init(const Context * context)116     angle::Result init(const Context *context) { return angle::Result::Continue; }
destroy(const Context * context)117     void destroy(const Context *context) {}
118 
onSwap()119     void onSwap() const {}
120 
getTextWidget(WidgetId id)121     const overlay::Mock *getTextWidget(WidgetId id) const { return &mMock; }
getCountWidget(WidgetId id)122     const overlay::Mock *getCountWidget(WidgetId id) const { return &mMock; }
getPerSecondWidget(WidgetId id)123     const overlay::Mock *getPerSecondWidget(WidgetId id) const { return &mMock; }
getRunningGraphWidget(WidgetId id)124     const overlay::Mock *getRunningGraphWidget(WidgetId id) const { return &mMock; }
getRunningHistogramWidget(WidgetId id)125     const overlay::Mock *getRunningHistogramWidget(WidgetId id) const { return &mMock; }
126 
isEnabled()127     bool isEnabled() const { return false; }
128 
129   private:
130     overlay::Mock mMock;
131 };
132 
133 #if ANGLE_ENABLE_OVERLAY
134 using OverlayType            = Overlay;
135 using CountWidget            = overlay::Count;
136 using PerSecondWidget        = overlay::PerSecond;
137 using RunningGraphWidget     = overlay::RunningGraph;
138 using RunningHistogramWidget = overlay::RunningHistogram;
139 using TextWidget             = overlay::Text;
140 #else   // !ANGLE_ENABLE_OVERLAY
141 using OverlayType            = MockOverlay;
142 using CountWidget            = const overlay::Mock;
143 using PerSecondWidget        = const overlay::Mock;
144 using RunningGraphWidget     = const overlay::Mock;
145 using RunningHistogramWidget = const overlay::Mock;
146 using TextWidget             = const overlay::Mock;
147 #endif  // ANGLE_ENABLE_OVERLAY
148 
149 }  // namespace gl
150 
151 #endif  // LIBANGLE_OVERLAY_H_
152