5#include "flutter/shell/platform/windows/egl/manager.h"
9#include "flutter/fml/logging.h"
10#include "flutter/shell/platform/windows/egl/egl.h"
15int Manager::instance_count_ = 0;
18 std::unique_ptr<Manager>
manager;
29 if (!InitializeDisplay()) {
33 if (!InitializeConfig(enable_impeller)) {
37 if (!InitializeContexts()) {
49bool Manager::InitializeDisplay() {
53 const EGLint d3d11_display_attributes[] = {
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[] = {
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[] = {
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());
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) {
143bool 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) {
189bool 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);
211bool 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);
232 result = query_device_attrib_EXT(
reinterpret_cast<EGLDeviceEXT
>(egl_device),
233 EGL_D3D11_DEVICE_ANGLE, &angle_device);
238 resolved_device_ =
reinterpret_cast<ID3D11Device*
>(angle_device);
242void 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(),
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();
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE
#define EGL_PLATFORM_ANGLE_ANGLE
virtual Context * resource_context() const
static std::unique_ptr< Manager > Create(bool enable_impeller)
EGLSurface CreateSurfaceFromHandle(EGLenum handle_type, EGLClientBuffer handle, const EGLint *attributes) const
Manager(bool enable_impeller)
virtual Context * render_context() const
virtual std::unique_ptr< WindowSurface > CreateWindowSurface(HWND hwnd, size_t width, size_t height)
bool GetDevice(ID3D11Device **device)
#define FML_UNREACHABLE()
void LogEGLError(std::string_view message)
Log the last EGL error with an error message.
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font manager