Flutter Impeller
context.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef FLUTTER_IMPELLER_TOOLKIT_EGL_CONTEXT_H_
6 #define FLUTTER_IMPELLER_TOOLKIT_EGL_CONTEXT_H_
7 
8 #include <functional>
9 
11 #include "impeller/base/thread.h"
13 
14 namespace impeller {
15 namespace egl {
16 
17 class Surface;
18 class Display;
19 
20 //------------------------------------------------------------------------------
21 /// @brief An instance of an EGL context.
22 ///
23 /// An EGL context can only be used on a single thread at a given
24 /// time. A thread can only have a single context current at any
25 /// given time.
26 ///
27 /// Context cannot be created directly. Only a valid instance of an
28 /// egl::Display can create a context.
29 ///
30 class Context {
31  public:
32  ~Context();
33 
34  //----------------------------------------------------------------------------
35  /// @brief Determines if a valid context could be created. The context
36  /// still needs to be made current on the thread for it to be
37  /// useful.
38  ///
39  /// @return True if valid, False otherwise.
40  ///
41  bool IsValid() const;
42 
43  //----------------------------------------------------------------------------
44  /// @brief Get the underlying handle to the EGL context.
45  ///
46  /// @return The handle.
47  ///
48  const EGLContext& GetHandle() const;
49 
50  //----------------------------------------------------------------------------
51  /// @brief Make the context current on the calling thread. It is the
52  /// caller responsibility to ensure that any context previously
53  /// current on the thread must be cleared via `ClearCurrent`.
54  ///
55  /// @important The config used to create the surface must match the config
56  /// used to create this context instance.
57  ///
58  /// @param[in] surface The surface to use to make the context current.
59  ///
60  /// @return If the context could be made current on the callers thread.
61  ///
62  bool MakeCurrent(const Surface& surface) const;
63 
64  //----------------------------------------------------------------------------
65  /// @brief Clear the thread association of this context.
66  ///
67  /// @return If the thread association could be cleared.
68  ///
69  bool ClearCurrent() const;
70 
71  enum class LifecycleEvent {
74  };
75  using LifecycleListener = std::function<void(LifecycleEvent)>;
76  //----------------------------------------------------------------------------
77  /// @brief Add a listener that gets invoked when the context is made and
78  /// cleared current from the thread. Applications typically use
79  /// this to manage workers that schedule OpenGL API calls that
80  /// need to be careful about the context being current when
81  /// called.
82  ///
83  /// @param[in] listener The listener
84  ///
85  /// @return A unique ID for the listener that can used used in
86  /// `RemoveLifecycleListener` to remove a previously added
87  /// listener.
88  ///
89  std::optional<UniqueID> AddLifecycleListener(
90  const LifecycleListener& listener);
91 
92  //----------------------------------------------------------------------------
93  /// @brief Remove a previously added context listener.
94  ///
95  /// @param[in] id The identifier obtained via a previous call to
96  /// `AddLifecycleListener`.
97  ///
98  /// @return True if the listener could be removed.
99  ///
101 
102  //----------------------------------------------------------------------------
103  /// @return True if the context is current and attached to any surface,
104  /// False otherwise.
105  ///
106  bool IsCurrent() const;
107 
108  private:
109  friend class Display;
110 
111  EGLDisplay display_ = EGL_NO_DISPLAY;
112  EGLContext context_ = EGL_NO_CONTEXT;
113  mutable RWMutex listeners_mutex_;
114  std::map<UniqueID, LifecycleListener> listeners_ IPLR_GUARDED_BY(
115  listeners_mutex_);
116 
117  Context(EGLDisplay display, EGLContext context);
118 
119  void DispatchLifecyleEvent(LifecycleEvent event) const;
120 
121  Context(const Context&) = delete;
122 
123  Context& operator=(const Context&) = delete;
124 };
125 
126 } // namespace egl
127 } // namespace impeller
128 
129 #endif // FLUTTER_IMPELLER_TOOLKIT_EGL_CONTEXT_H_
An instance of an EGL context.
Definition: context.h:30
const EGLContext & GetHandle() const
Get the underlying handle to the EGL context.
Definition: context.cc:27
bool IsCurrent() const
Definition: context.cc:102
std::function< void(LifecycleEvent)> LifecycleListener
Definition: context.h:75
std::optional< UniqueID > AddLifecycleListener(const LifecycleListener &listener)
Add a listener that gets invoked when the context is made and cleared current from the thread....
Definition: context.cc:74
bool MakeCurrent(const Surface &surface) const
Make the context current on the calling thread. It is the caller responsibility to ensure that any co...
Definition: context.cc:45
bool ClearCurrent() const
Clear the thread association of this context.
Definition: context.cc:61
bool IsValid() const
Determines if a valid context could be created. The context still needs to be made current on the thr...
Definition: context.cc:23
bool RemoveLifecycleListener(UniqueID id)
Remove a previously added context listener.
Definition: context.cc:85
A connection to an EGL display. Only one connection per application instance is sufficient.
Definition: display.h:28
An instance of an EGL surface. There is no ability to create surfaces directly. Instead,...
Definition: surface.h:18
#define IPLR_GUARDED_BY(x)
Definition: thread_safety.h:19