9 #include "flutter/fml/logging.h"
15 int Manager::instance_count_ = 0;
18 std::unique_ptr<Manager> manager;
20 if (!manager->IsValid()) {
23 return std::move(manager);
29 if (!InitializeDisplay()) {
33 if (!InitializeConfig()) {
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() {
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 EGLint num_config = 0;
152 ::eglChooseConfig(display_, config_attributes, &config_, 1, &num_config);
154 if (result == EGL_TRUE && num_config > 0) {
162 bool Manager::InitializeContexts() {
163 const EGLint context_attributes[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
166 ::eglCreateContext(display_, config_, EGL_NO_CONTEXT, context_attributes);
168 LogEGLError(
"Failed to create EGL render context");
173 ::eglCreateContext(display_, config_,
render_context, context_attributes);
175 LogEGLError(
"Failed to create EGL resource context");
179 render_context_ = std::make_unique<Context>(display_,
render_context);
184 bool Manager::InitializeDevice() {
185 const auto query_display_attrib_EXT =
186 reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC
>(
187 ::eglGetProcAddress(
"eglQueryDisplayAttribEXT"));
188 const auto query_device_attrib_EXT =
189 reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC
>(
190 ::eglGetProcAddress(
"eglQueryDeviceAttribEXT"));
192 if (query_display_attrib_EXT ==
nullptr ||
193 query_device_attrib_EXT ==
nullptr) {
197 EGLAttrib egl_device = 0;
198 EGLAttrib angle_device = 0;
200 auto result = query_display_attrib_EXT(display_, EGL_DEVICE_EXT, &egl_device);
201 if (result != EGL_TRUE) {
205 result = query_device_attrib_EXT(
reinterpret_cast<EGLDeviceEXT
>(egl_device),
206 EGL_D3D11_DEVICE_ANGLE, &angle_device);
207 if (result != EGL_TRUE) {
211 resolved_device_ =
reinterpret_cast<ID3D11Device*
>(angle_device);
215 void Manager::CleanUp() {
216 EGLBoolean result = EGL_FALSE;
219 resolved_device_.Reset();
222 render_context_.reset();
223 resource_context_.reset();
225 if (display_ != EGL_NO_DISPLAY) {
228 if (instance_count_ == 1) {
229 ::eglTerminate(display_);
231 display_ = EGL_NO_DISPLAY;
242 if (!hwnd || !is_valid_) {
249 const EGLint surface_attributes[] = {EGL_FIXED_SIZE_ANGLE,
252 static_cast<EGLint
>(width),
254 static_cast<EGLint
>(height),
257 auto const surface = ::eglCreateWindowSurface(
258 display_, config_,
static_cast<EGLNativeWindowType
>(hwnd),
260 if (surface == EGL_NO_SURFACE) {
265 return std::make_unique<WindowSurface>(display_, render_context_->GetHandle(),
266 surface, width, height);
270 return ::eglGetCurrentContext() != EGL_NO_CONTEXT;
274 EGLClientBuffer handle,
275 const EGLint* attributes)
const {
276 return ::eglCreatePbufferFromClientBuffer(display_, handle_type, handle,
277 config_, attributes);
281 if (!resolved_device_) {
282 if (!InitializeDevice()) {
287 resolved_device_.CopyTo(device);
288 return (resolved_device_ !=
nullptr);
292 return render_context_.get();
296 return resource_context_.get();