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 
90   private:
91     template <typename Widget, WidgetType Type>
getWidgetAs(WidgetId id)92     Widget *getWidgetAs(WidgetId id) const
93     {
94         ASSERT(mState.mOverlayWidgets[id] != nullptr);
95         ASSERT(mState.mOverlayWidgets[id]->type == Type);
96         return rx::GetAs<Widget>(mState.mOverlayWidgets[id].get());
97     }
98     void initOverlayWidgets();
99     void enableOverlayWidgetsFromEnvironment();
100 
101     // Time tracking for PerSecond items.
102     mutable double mLastPerSecondUpdate;
103 
104     OverlayState mState;
105     std::unique_ptr<rx::OverlayImpl> mImplementation;
106 };
107 
108 class DummyOverlay
109 {
110   public:
111     DummyOverlay(rx::GLImplFactory *implFactory);
112     ~DummyOverlay();
113 
init(const Context * context)114     angle::Result init(const Context *context) { return angle::Result::Continue; }
destroy(const Context * context)115     void destroy(const Context *context) {}
116 
onSwap()117     void onSwap() const {}
118 
getTextWidget(WidgetId id)119     const overlay::Dummy *getTextWidget(WidgetId id) const { return &mDummy; }
getCountWidget(WidgetId id)120     const overlay::Dummy *getCountWidget(WidgetId id) const { return &mDummy; }
getPerSecondWidget(WidgetId id)121     const overlay::Dummy *getPerSecondWidget(WidgetId id) const { return &mDummy; }
getRunningGraphWidget(WidgetId id)122     const overlay::Dummy *getRunningGraphWidget(WidgetId id) const { return &mDummy; }
getRunningHistogramWidget(WidgetId id)123     const overlay::Dummy *getRunningHistogramWidget(WidgetId id) const { return &mDummy; }
124 
125   private:
126     overlay::Dummy mDummy;
127 };
128 
129 #if ANGLE_ENABLE_OVERLAY
130 using OverlayType            = Overlay;
131 using CountWidget            = overlay::Count;
132 using PerSecondWidget        = overlay::PerSecond;
133 using RunningGraphWidget     = overlay::RunningGraph;
134 using RunningHistogramWidget = overlay::RunningHistogram;
135 using TextWidget             = overlay::Text;
136 #else   // !ANGLE_ENABLE_OVERLAY
137 using OverlayType            = DummyOverlay;
138 using CountWidget            = const overlay::Dummy;
139 using PerSecondWidget        = const overlay::Dummy;
140 using RunningGraphWidget     = const overlay::Dummy;
141 using RunningHistogramWidget = const overlay::Dummy;
142 using TextWidget             = const overlay::Dummy;
143 #endif  // ANGLE_ENABLE_OVERLAY
144 
145 }  // namespace gl
146 
147 #endif  // LIBANGLE_OVERLAY_H_
148