9 #include "flutter/fml/logging.h"
14 EGLint error = eglGetError();
15 FML_LOG(ERROR) <<
"EGL: " <<
message;
16 FML_LOG(ERROR) <<
"EGL: eglGetError returned " << error;
21 int AngleSurfaceManager::instance_count_ = 0;
24 bool enable_impeller) {
25 std::unique_ptr<AngleSurfaceManager> manager;
27 if (!manager->initialize_succeeded_) {
30 return std::move(manager);
34 : egl_config_(nullptr),
35 egl_display_(EGL_NO_DISPLAY),
36 egl_context_(EGL_NO_CONTEXT) {
37 initialize_succeeded_ = Initialize(enable_impeller);
46 bool AngleSurfaceManager::InitializeEGL(
47 PFNEGLGETPLATFORMDISPLAYEXTPROC egl_get_platform_display_EXT,
50 egl_display_ = egl_get_platform_display_EXT(EGL_PLATFORM_ANGLE_ANGLE,
51 EGL_DEFAULT_DISPLAY, config);
53 if (egl_display_ == EGL_NO_DISPLAY) {
55 LogEglError(
"Failed to get a compatible EGLdisplay");
60 if (eglInitialize(egl_display_,
nullptr,
nullptr) == EGL_FALSE) {
70 bool AngleSurfaceManager::Initialize(
bool enable_impeller) {
71 const EGLint config_attributes[] = {EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8,
72 EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8,
73 EGL_DEPTH_SIZE, 8, EGL_STENCIL_SIZE, 8,
76 const EGLint impeller_config_attributes[] = {
77 EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8,
78 EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 8,
79 EGL_SAMPLE_BUFFERS, 1, EGL_SAMPLES, 4, EGL_NONE};
80 const EGLint impeller_config_attributes_no_msaa[] = {
81 EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8,
82 EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 8,
85 const EGLint display_context_attributes[] = {EGL_CONTEXT_CLIENT_VERSION, 2,
91 const EGLint d3d11_display_attributes[] = {
92 EGL_PLATFORM_ANGLE_TYPE_ANGLE,
93 EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
98 EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
103 EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE,
104 EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE,
111 const EGLint d3d11_fl_9_3_display_attributes[] = {
112 EGL_PLATFORM_ANGLE_TYPE_ANGLE,
113 EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
114 EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE,
116 EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE,
118 EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
125 const EGLint d3d11_warp_display_attributes[] = {
126 EGL_PLATFORM_ANGLE_TYPE_ANGLE,
127 EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
128 EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
133 std::vector<const EGLint*> display_attributes_configs = {
134 d3d11_display_attributes,
135 d3d11_fl_9_3_display_attributes,
136 d3d11_warp_display_attributes,
139 PFNEGLGETPLATFORMDISPLAYEXTPROC egl_get_platform_display_EXT =
140 reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC
>(
141 eglGetProcAddress(
"eglGetPlatformDisplayEXT"));
142 if (!egl_get_platform_display_EXT) {
143 LogEglError(
"eglGetPlatformDisplayEXT not available");
149 for (
auto config : display_attributes_configs) {
150 bool should_log = (config == display_attributes_configs.back());
151 if (InitializeEGL(egl_get_platform_display_EXT, config, should_log)) {
156 EGLint numConfigs = 0;
157 if (enable_impeller) {
159 if ((eglChooseConfig(egl_display_, impeller_config_attributes, &egl_config_,
160 1, &numConfigs) == EGL_FALSE) ||
163 if ((eglChooseConfig(egl_display_, impeller_config_attributes_no_msaa,
164 &egl_config_, 1, &numConfigs) == EGL_FALSE) ||
171 if ((eglChooseConfig(egl_display_, config_attributes, &egl_config_, 1,
172 &numConfigs) == EGL_FALSE) ||
179 egl_context_ = eglCreateContext(egl_display_, egl_config_, EGL_NO_CONTEXT,
180 display_context_attributes);
181 if (egl_context_ == EGL_NO_CONTEXT) {
186 egl_resource_context_ = eglCreateContext(
187 egl_display_, egl_config_, egl_context_, display_context_attributes);
189 if (egl_resource_context_ == EGL_NO_CONTEXT) {
190 LogEglError(
"Failed to create EGL resource context");
197 void AngleSurfaceManager::CleanUp() {
198 EGLBoolean result = EGL_FALSE;
201 resolved_device_.Reset();
203 if (egl_display_ != EGL_NO_DISPLAY && egl_context_ != EGL_NO_CONTEXT) {
204 result = eglDestroyContext(egl_display_, egl_context_);
205 egl_context_ = EGL_NO_CONTEXT;
207 if (result == EGL_FALSE) {
212 if (egl_display_ != EGL_NO_DISPLAY &&
213 egl_resource_context_ != EGL_NO_CONTEXT) {
214 result = eglDestroyContext(egl_display_, egl_resource_context_);
215 egl_resource_context_ = EGL_NO_CONTEXT;
217 if (result == EGL_FALSE) {
222 if (egl_display_ != EGL_NO_DISPLAY) {
225 if (instance_count_ == 1) {
226 eglTerminate(egl_display_);
228 egl_display_ = EGL_NO_DISPLAY;
235 bool vsync_enabled) {
236 if (!render_target || !initialize_succeeded_) {
240 EGLSurface surface = EGL_NO_SURFACE;
242 const EGLint surfaceAttributes[] = {
243 EGL_FIXED_SIZE_ANGLE, EGL_TRUE, EGL_WIDTH, width,
244 EGL_HEIGHT, height, EGL_NONE};
246 surface = eglCreateWindowSurface(
247 egl_display_, egl_config_,
248 static_cast<EGLNativeWindowType
>(std::get<HWND>(*render_target)),
250 if (surface == EGL_NO_SURFACE) {
255 surface_width_ = width;
256 surface_height_ = height;
257 render_surface_ = surface;
260 LogEglError(
"Unable to make surface current to update the swap interval");
271 bool vsync_enabled) {
272 EGLint existing_width, existing_height;
274 if (width != existing_width || height != existing_height) {
275 surface_width_ = width;
276 surface_height_ = height;
280 if (!
CreateSurface(render_target, width, height, vsync_enabled)) {
282 <<
"AngleSurfaceManager::ResizeSurface failed to create surface";
288 if (render_surface_ == EGL_NO_SURFACE || !initialize_succeeded_) {
297 *width = surface_width_;
298 *height = surface_height_;
302 if (egl_display_ != EGL_NO_DISPLAY && render_surface_ != EGL_NO_SURFACE) {
303 eglDestroySurface(egl_display_, render_surface_);
305 render_surface_ = EGL_NO_SURFACE;
309 return eglGetCurrentContext() != EGL_NO_CONTEXT;
313 return (eglMakeCurrent(egl_display_, render_surface_, render_surface_,
314 egl_context_) == EGL_TRUE);
318 return (eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE,
319 EGL_NO_CONTEXT) == EGL_TRUE);
323 return (eglMakeCurrent(egl_display_,
nullptr,
nullptr, egl_context_) ==
328 return (eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE,
329 egl_resource_context_) == EGL_TRUE);
333 return (eglSwapBuffers(egl_display_, render_surface_));
338 EGLClientBuffer handle,
339 const EGLint* attributes)
const {
340 return eglCreatePbufferFromClientBuffer(egl_display_, handle_type, handle,
341 egl_config_, attributes);
350 if (eglSwapInterval(egl_display_, enabled ? 1 : 0) != EGL_TRUE) {
357 if (!resolved_device_) {
358 PFNEGLQUERYDISPLAYATTRIBEXTPROC egl_query_display_attrib_EXT =
359 reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC
>(
360 eglGetProcAddress(
"eglQueryDisplayAttribEXT"));
362 PFNEGLQUERYDEVICEATTRIBEXTPROC egl_query_device_attrib_EXT =
363 reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC
>(
364 eglGetProcAddress(
"eglQueryDeviceAttribEXT"));
366 if (!egl_query_display_attrib_EXT || !egl_query_device_attrib_EXT) {
370 EGLAttrib egl_device = 0;
371 EGLAttrib angle_device = 0;
372 if (egl_query_display_attrib_EXT(egl_display_, EGL_DEVICE_EXT,
373 &egl_device) == EGL_TRUE) {
374 if (egl_query_device_attrib_EXT(
375 reinterpret_cast<EGLDeviceEXT
>(egl_device),
376 EGL_D3D11_DEVICE_ANGLE, &angle_device) == EGL_TRUE) {
377 resolved_device_ =
reinterpret_cast<ID3D11Device*
>(angle_device);
382 resolved_device_.CopyTo(device);
383 return (resolved_device_ !=
nullptr);