Flutter Impeller
context.cc
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 
6 
8 
9 namespace impeller {
10 namespace egl {
11 
12 Context::Context(EGLDisplay display, EGLContext context)
13  : display_(display), context_(context) {}
14 
15 Context::~Context() {
16  if (context_ != EGL_NO_CONTEXT) {
17  if (::eglDestroyContext(display_, context_) != EGL_TRUE) {
19  }
20  }
21 }
22 
23 bool Context::IsValid() const {
24  return context_ != EGL_NO_CONTEXT;
25 }
26 
27 const EGLContext& Context::GetHandle() const {
28  return context_;
29 }
30 
31 static EGLBoolean EGLMakeCurrentIfNecessary(EGLDisplay display,
32  EGLSurface draw,
33  EGLSurface read,
34  EGLContext context) {
35  if (display != ::eglGetCurrentDisplay() ||
36  draw != ::eglGetCurrentSurface(EGL_DRAW) ||
37  read != ::eglGetCurrentSurface(EGL_READ) ||
38  context != ::eglGetCurrentContext()) {
39  return ::eglMakeCurrent(display, draw, read, context);
40  }
41  // The specified context configuration is already current.
42  return EGL_TRUE;
43 }
44 
45 bool Context::MakeCurrent(const Surface& surface) const {
46  if (context_ == EGL_NO_CONTEXT) {
47  return false;
48  }
49  const auto result = EGLMakeCurrentIfNecessary(display_, //
50  surface.GetHandle(), //
51  surface.GetHandle(), //
52  context_ //
53  ) == EGL_TRUE;
54  if (!result) {
56  }
57  DispatchLifecyleEvent(LifecycleEvent::kDidMakeCurrent);
58  return result;
59 }
60 
61 bool Context::ClearCurrent() const {
62  DispatchLifecyleEvent(LifecycleEvent::kWillClearCurrent);
63  const auto result = EGLMakeCurrentIfNecessary(display_, //
64  EGL_NO_SURFACE, //
65  EGL_NO_SURFACE, //
66  EGL_NO_CONTEXT //
67  ) == EGL_TRUE;
68  if (!result) {
70  }
71  return result;
72 }
73 
74 std::optional<UniqueID> Context::AddLifecycleListener(
75  const LifecycleListener& listener) {
76  if (!listener) {
77  return std::nullopt;
78  }
79  WriterLock lock(listeners_mutex_);
80  UniqueID id;
81  listeners_[id] = listener;
82  return id;
83 }
84 
85 bool Context::RemoveLifecycleListener(UniqueID id) {
86  WriterLock lock(listeners_mutex_);
87  auto found = listeners_.find(id);
88  if (found == listeners_.end()) {
89  return false;
90  }
91  listeners_.erase(found);
92  return true;
93 }
94 
95 void Context::DispatchLifecyleEvent(LifecycleEvent event) const {
96  ReaderLock lock(listeners_mutex_);
97  for (const auto& listener : listeners_) {
98  listener.second(event);
99  }
100 }
101 
102 bool Context::IsCurrent() const {
103  return ::eglGetCurrentContext() == context_;
104 }
105 
106 } // namespace egl
107 } // namespace impeller
std::function< void(LifecycleEvent)> LifecycleListener
Definition: context.h:75
An instance of an EGL surface. There is no ability to create surfaces directly. Instead,...
Definition: surface.h:18
const EGLSurface & GetHandle() const
Definition: surface.cc:21
#define IMPELLER_LOG_EGL_ERROR
Definition: egl.h:25
static EGLBoolean EGLMakeCurrentIfNecessary(EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext context)
Definition: context.cc:31