| 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
5 #include "impeller/toolkit/egl/context.h"
6
7 #include "impeller/toolkit/egl/surface.h"
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) {
18 IMPELLER_LOG_EGL_ERROR;
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) {
55 IMPELLER_LOG_EGL_ERROR;
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) {
69 IMPELLER_LOG_EGL_ERROR;
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
impeller::ReaderLock
Definition: thread.h:92
impeller::WriterLock
Definition: thread.h:113
impeller::egl::Context::LifecycleListener
std::function< void(LifecycleEvent)> LifecycleListener
Definition: context.h:75
impeller::egl::Surface
An instance of an EGL surface. There is no ability to create surfaces directly. Instead,...
Definition: surface.h:18
impeller::egl::Surface::GetHandle
const EGLSurface & GetHandle() const
Definition: surface.cc:21
IMPELLER_LOG_EGL_ERROR
#define IMPELLER_LOG_EGL_ERROR
Definition: egl.h:25
impeller::egl::EGLMakeCurrentIfNecessary
static EGLBoolean EGLMakeCurrentIfNecessary(EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext context)
Definition: context.cc:31
impeller
Definition: allocation.cc:12
impeller::UniqueID
Definition: comparable.h:16
context.h
surface.h