9 #include "flutter/fml/logging.h"
15 int Manager::instance_count_ = 0;
18 std::unique_ptr<Manager> manager;
19 manager.reset(
new Manager(enable_impeller));
20 if (!manager->IsValid()) {
23 return std::move(manager);
29 if (!InitializeDisplay()) {
33 if (!InitializeConfig(enable_impeller)) {
37 if (!InitializeContexts()) {
49 bool Manager::InitializeDisplay() {
53 const EGLint d3d11_display_attributes[] = {
54 EGL_PLATFORM_ANGLE_TYPE_ANGLE,
55 EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
60 EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
65 EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE,
66 EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE,
73 const EGLint d3d11_fl_9_3_display_attributes[] = {
74 EGL_PLATFORM_ANGLE_TYPE_ANGLE,
75 EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
76 EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE,
78 EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE,
80 EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
87 const EGLint d3d11_warp_display_attributes[] = {
88 EGL_PLATFORM_ANGLE_TYPE_ANGLE,
89 EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
90 EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
95 std::vector<const EGLint*> display_attributes_configs = {
96 d3d11_display_attributes,
97 d3d11_fl_9_3_display_attributes,
98 d3d11_warp_display_attributes,
101 PFNEGLGETPLATFORMDISPLAYEXTPROC egl_get_platform_display_EXT =
102 reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC
>(
103 ::eglGetProcAddress(
"eglGetPlatformDisplayEXT"));
104 if (!egl_get_platform_display_EXT) {
105 LogEGLError(
"eglGetPlatformDisplayEXT not available");
111 for (
auto config : display_attributes_configs) {
112 bool is_last = (config == display_attributes_configs.back());
114 display_ = egl_get_platform_display_EXT(EGL_PLATFORM_ANGLE_ANGLE,
115 EGL_DEFAULT_DISPLAY, config);
117 if (display_ == EGL_NO_DISPLAY) {
119 LogEGLError(
"Failed to get a compatible EGLdisplay");
127 if (::eglInitialize(display_,
nullptr,
nullptr) == EGL_FALSE) {
143 bool Manager::InitializeConfig(
bool enable_impeller) {
144 const EGLint config_attributes[] = {EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8,
145 EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8,
146 EGL_DEPTH_SIZE, 8, EGL_STENCIL_SIZE, 8,
149 const EGLint impeller_config_attributes[] = {
150 EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8,
151 EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 8,
152 EGL_SAMPLE_BUFFERS, 1, EGL_SAMPLES, 4, EGL_NONE};
153 const EGLint impeller_config_attributes_no_msaa[] = {
154 EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8,
155 EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 8,
159 EGLint num_config = 0;
161 if (enable_impeller) {
163 result = ::eglChooseConfig(display_, impeller_config_attributes, &config_,
166 if (result == EGL_TRUE && num_config > 0) {
171 result = ::eglChooseConfig(display_, impeller_config_attributes_no_msaa,
172 &config_, 1, &num_config);
173 if (result == EGL_TRUE && num_config == 0) {
177 result = ::eglChooseConfig(display_, config_attributes, &config_, 1,
180 if (result == EGL_TRUE && num_config > 0) {
189 bool Manager::InitializeContexts() {
190 const EGLint context_attributes[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
193 ::eglCreateContext(display_, config_, EGL_NO_CONTEXT, context_attributes);
195 LogEGLError(
"Failed to create EGL render context");
200 ::eglCreateContext(display_, config_,
render_context, context_attributes);
202 LogEGLError(
"Failed to create EGL resource context");
206 render_context_ = std::make_unique<Context>(display_,
render_context);
211 bool Manager::InitializeDevice() {
212 const auto query_display_attrib_EXT =
213 reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC
>(
214 ::eglGetProcAddress(
"eglQueryDisplayAttribEXT"));
215 const auto query_device_attrib_EXT =
216 reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC
>(
217 ::eglGetProcAddress(
"eglQueryDeviceAttribEXT"));
219 if (query_display_attrib_EXT ==
nullptr ||
220 query_device_attrib_EXT ==
nullptr) {
224 EGLAttrib egl_device = 0;
225 EGLAttrib angle_device = 0;
227 auto result = query_display_attrib_EXT(display_, EGL_DEVICE_EXT, &egl_device);
228 if (result != EGL_TRUE) {
232 result = query_device_attrib_EXT(
reinterpret_cast<EGLDeviceEXT
>(egl_device),
233 EGL_D3D11_DEVICE_ANGLE, &angle_device);
234 if (result != EGL_TRUE) {
238 resolved_device_ =
reinterpret_cast<ID3D11Device*
>(angle_device);
242 void Manager::CleanUp() {
243 EGLBoolean result = EGL_FALSE;
246 resolved_device_.Reset();
249 render_context_.reset();
250 resource_context_.reset();
252 if (display_ != EGL_NO_DISPLAY) {
255 if (instance_count_ == 1) {
256 ::eglTerminate(display_);
258 display_ = EGL_NO_DISPLAY;
269 if (!hwnd || !is_valid_) {
276 const EGLint surface_attributes[] = {EGL_FIXED_SIZE_ANGLE,
279 static_cast<EGLint
>(width),
281 static_cast<EGLint
>(height),
284 auto const surface = ::eglCreateWindowSurface(
285 display_, config_,
static_cast<EGLNativeWindowType
>(hwnd),
287 if (surface == EGL_NO_SURFACE) {
292 return std::make_unique<WindowSurface>(display_, render_context_->GetHandle(),
293 surface, width, height);
297 return ::eglGetCurrentContext() != EGL_NO_CONTEXT;
301 EGLClientBuffer handle,
302 const EGLint* attributes)
const {
303 return ::eglCreatePbufferFromClientBuffer(display_, handle_type, handle,
304 config_, attributes);
308 if (!resolved_device_) {
309 if (!InitializeDevice()) {
314 resolved_device_.CopyTo(device);
315 return (resolved_device_ !=
nullptr);
319 return render_context_.get();
323 return resource_context_.get();