Flutter Impeller
impeller::egl::Display Class Reference

A connection to an EGL display. Only one connection per application instance is sufficient. More...

#include <display.h>

Public Member Functions

 Display ()
 
virtual ~Display ()
 
virtual bool IsValid () const
 
virtual std::unique_ptr< ConfigChooseConfig (ConfigDescriptor config) const
 Choose a config that most closely matches a given descriptor. If there are no matches, this method returns nullptr. More...
 
virtual std::unique_ptr< ContextCreateContext (const Config &config, const Context *share_context)
 Create a context with a supported config. The supported config can be obtained via a successful call to ChooseConfig. More...
 
virtual std::unique_ptr< SurfaceCreateWindowSurface (const Config &config, EGLNativeWindowType window)
 Create a window surface. The window is an opaque pointer whose value value is platform specific. For instance, ANativeWindow on Android. More...
 
virtual std::unique_ptr< SurfaceCreatePixelBufferSurface (const Config &config, size_t width, size_t height)
 Create an offscreen pixelbuffer surface. These are of limited use except in the context where applications need to render to a texture in an offscreen context. In such cases, a 1x1 pixel buffer surface is created to obtain a surface that can be used to make the context current on the background thread. More...
 
const EGLDisplay & GetHandle () const
 

Detailed Description

A connection to an EGL display. Only one connection per application instance is sufficient.

The display connection is used to first choose a config from among the available, create a context from that config, and then use that context with a surface on one (and only one) thread at a time.

Definition at line 28 of file display.h.

Constructor & Destructor Documentation

◆ Display()

impeller::egl::Display::Display ( )

Definition at line 16 of file display.cc.

16  {
17  EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
18 
19  if (::eglInitialize(display, nullptr, nullptr) != EGL_TRUE) {
21  return;
22  }
23  display_ = display;
24 }
#define IMPELLER_LOG_EGL_ERROR
Definition: egl.h:25

References IMPELLER_LOG_EGL_ERROR.

◆ ~Display()

impeller::egl::Display::~Display ( )
virtual

Definition at line 26 of file display.cc.

26  {
27  if (display_ != EGL_NO_DISPLAY) {
28  if (::eglTerminate(display_) != EGL_TRUE) {
30  }
31  }
32 }

References IMPELLER_LOG_EGL_ERROR.

Member Function Documentation

◆ ChooseConfig()

std::unique_ptr< Config > impeller::egl::Display::ChooseConfig ( ConfigDescriptor  config) const
virtual

Choose a config that most closely matches a given descriptor. If there are no matches, this method returns nullptr.

Parameters
[in]configThe configuration
Returns
A config that matches a descriptor if one is available. nullptr otherwise.

Definition at line 73 of file display.cc.

73  {
74  if (!display_) {
75  return nullptr;
76  }
77 
78  std::vector<EGLint> attributes;
79 
80  {
81  attributes.push_back(EGL_RENDERABLE_TYPE);
82  switch (config.api) {
83  case API::kOpenGL:
84  attributes.push_back(EGL_OPENGL_BIT);
85  break;
86  case API::kOpenGLES2:
87  attributes.push_back(EGL_OPENGL_ES2_BIT);
88  break;
89  case API::kOpenGLES3:
90  attributes.push_back(EGL_OPENGL_ES3_BIT);
91  break;
92  }
93  }
94 
95  {
96  attributes.push_back(EGL_SURFACE_TYPE);
97  switch (config.surface_type) {
99  attributes.push_back(EGL_WINDOW_BIT);
100  break;
102  attributes.push_back(EGL_PBUFFER_BIT);
103  break;
104  }
105  }
106 
107  {
108  switch (config.color_format) {
110  attributes.push_back(EGL_RED_SIZE);
111  attributes.push_back(8);
112  attributes.push_back(EGL_GREEN_SIZE);
113  attributes.push_back(8);
114  attributes.push_back(EGL_BLUE_SIZE);
115  attributes.push_back(8);
116  attributes.push_back(EGL_ALPHA_SIZE);
117  attributes.push_back(8);
118  break;
120  attributes.push_back(EGL_RED_SIZE);
121  attributes.push_back(5);
122  attributes.push_back(EGL_GREEN_SIZE);
123  attributes.push_back(6);
124  attributes.push_back(EGL_BLUE_SIZE);
125  attributes.push_back(5);
126  break;
127  }
128  }
129 
130  {
131  attributes.push_back(EGL_DEPTH_SIZE);
132  attributes.push_back(static_cast<EGLint>(config.depth_bits));
133  }
134 
135  {
136  attributes.push_back(EGL_STENCIL_SIZE);
137  attributes.push_back(static_cast<EGLint>(config.stencil_bits));
138  }
139 
140  {
141  const auto sample_count = static_cast<EGLint>(config.samples);
142  if (sample_count > 1) {
143  attributes.push_back(EGL_SAMPLE_BUFFERS);
144  attributes.push_back(1);
145  attributes.push_back(EGL_SAMPLES);
146  attributes.push_back(sample_count);
147  }
148  }
149 
150  // termination sentinel must be present.
151  attributes.push_back(EGL_NONE);
152 
153  EGLConfig config_out = nullptr;
154  EGLint config_count_out = 0;
155  if (::eglChooseConfig(display_, // display
156  attributes.data(), // attributes (null terminated)
157  &config_out, // matched configs
158  1, // configs array size
159  &config_count_out // match configs count
160  ) != EGL_TRUE) {
162  return nullptr;
163  }
164 
165  if (config_count_out < 1) {
166  return nullptr;
167  }
168 
169  return std::make_unique<Config>(config, config_out);
170 }

References impeller::egl::ConfigDescriptor::api, impeller::egl::ConfigDescriptor::color_format, impeller::egl::ConfigDescriptor::depth_bits, IMPELLER_LOG_EGL_ERROR, impeller::egl::kOpenGL, impeller::egl::kOpenGLES2, impeller::egl::kOpenGLES3, impeller::egl::kPBuffer, impeller::egl::kRGB565, impeller::egl::kRGBA8888, impeller::egl::kWindow, impeller::egl::ConfigDescriptor::samples, impeller::egl::ConfigDescriptor::stencil_bits, and impeller::egl::ConfigDescriptor::surface_type.

◆ CreateContext()

std::unique_ptr< Context > impeller::egl::Display::CreateContext ( const Config config,
const Context share_context 
)
virtual

Create a context with a supported config. The supported config can be obtained via a successful call to ChooseConfig.

Parameters
[in]configThe configuration.
[in]share_contextThe share context. Context within the same share-group use the same handle table. The contexts should still only be used exclusively on each thread however.
Returns
A context if one can be created. nullptr otherwise.

Definition at line 38 of file display.cc.

39  {
40  const auto& desc = config.GetDescriptor();
41 
42  std::vector<EGLint> attributes;
43  switch (desc.api) {
44  case API::kOpenGL:
45  break;
46  case API::kOpenGLES2:
47  attributes.push_back(EGL_CONTEXT_CLIENT_VERSION);
48  attributes.push_back(2);
49  break;
50  case API::kOpenGLES3:
51  attributes.push_back(EGL_CONTEXT_CLIENT_VERSION);
52  attributes.push_back(3);
53  break;
54  }
55  // Termination sentinel must be present.
56  attributes.push_back(EGL_NONE);
57 
58  auto context = ::eglCreateContext(
59  display_, // display
60  config.GetHandle(), // config
61  share_context != nullptr ? share_context->GetHandle() : nullptr, // share
62  attributes.data() // attributes
63  );
64 
65  if (context == EGL_NO_CONTEXT) {
67  return nullptr;
68  }
69 
70  return std::unique_ptr<Context>(new Context(display_, context));
71 }

References impeller::egl::Config::GetDescriptor(), impeller::egl::Config::GetHandle(), impeller::egl::Context::GetHandle(), IMPELLER_LOG_EGL_ERROR, impeller::egl::kOpenGL, impeller::egl::kOpenGLES2, and impeller::egl::kOpenGLES3.

◆ CreatePixelBufferSurface()

std::unique_ptr< Surface > impeller::egl::Display::CreatePixelBufferSurface ( const Config config,
size_t  width,
size_t  height 
)
virtual

Create an offscreen pixelbuffer surface. These are of limited use except in the context where applications need to render to a texture in an offscreen context. In such cases, a 1x1 pixel buffer surface is created to obtain a surface that can be used to make the context current on the background thread.

Parameters
[in]configThe configuration
[in]widthThe width
[in]heightThe height
Returns
A valid pixel buffer surface if one can be created. nullptr otherwise.

Definition at line 188 of file display.cc.

190  {
191  // clang-format off
192  const EGLint attribs[] = {
193  EGL_WIDTH, static_cast<EGLint>(width),
194  EGL_HEIGHT, static_cast<EGLint>(height),
195  EGL_NONE
196  };
197  // clang-format on
198  auto surface = ::eglCreatePbufferSurface(display_, // display
199  config.GetHandle(), // config
200  attribs // attrib_list
201  );
202  if (surface == EGL_NO_SURFACE) {
204  return nullptr;
205  }
206  return std::unique_ptr<Surface>(new Surface(display_, surface));
207 }

References impeller::egl::Config::GetHandle(), and IMPELLER_LOG_EGL_ERROR.

◆ CreateWindowSurface()

std::unique_ptr< Surface > impeller::egl::Display::CreateWindowSurface ( const Config config,
EGLNativeWindowType  window 
)
virtual

Create a window surface. The window is an opaque pointer whose value value is platform specific. For instance, ANativeWindow on Android.

Parameters
[in]configA valid configuration. One can be obtained via ChooseConfig.
[in]windowAn opaque pointer to a platform specific window handle.
Returns
A valid window surface if one can be created. nullptr otherwise.

Definition at line 172 of file display.cc.

174  {
175  const EGLint attribs[] = {EGL_NONE};
176  auto surface = ::eglCreateWindowSurface(display_, // display
177  config.GetHandle(), // config
178  window, // window
179  attribs // attrib_list
180  );
181  if (surface == EGL_NO_SURFACE) {
183  return nullptr;
184  }
185  return std::unique_ptr<Surface>(new Surface(display_, surface));
186 }

References impeller::egl::Config::GetHandle(), and IMPELLER_LOG_EGL_ERROR.

◆ GetHandle()

const EGLDisplay & impeller::egl::Display::GetHandle ( ) const

Definition at line 209 of file display.cc.

209  {
210  return display_;
211 }

◆ IsValid()

bool impeller::egl::Display::IsValid ( ) const
virtual
Returns
True if the display connection is valid.

Definition at line 34 of file display.cc.

34  {
35  return display_ != EGL_NO_DISPLAY;
36 }

The documentation for this class was generated from the following files: