9 #include "flutter/fml/logging.h" 
   15 int Manager::instance_count_ = 0;
 
   18   std::unique_ptr<Manager> manager;
 
   19   manager.reset(
new Manager(gpu_preference));
 
   20   if (!manager->IsValid()) {
 
   23   return std::move(manager);
 
   29   if (!InitializeDisplay(gpu_preference)) {
 
   33   if (!InitializeConfig()) {
 
   37   if (!InitializeContexts()) {
 
   49 bool Manager::InitializeDisplay(
GpuPreference gpu_preference) {
 
   53   std::optional<LUID> luid = std::nullopt;
 
   60   const EGLint d3d11_display_attributes_with_luid[] = {
 
   61       EGL_PLATFORM_ANGLE_TYPE_ANGLE,
 
   62       EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
 
   67       EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
 
   72       EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE,
 
   73       EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE,
 
   76       EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE,
 
   77       static_cast<EGLint
>(luid.has_value() ? luid->HighPart : 0),
 
   78       EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE,
 
   79       static_cast<EGLint
>(luid.has_value() ? luid->LowPart : 0),
 
   86   const EGLint d3d11_display_attributes[] = {
 
   87       EGL_PLATFORM_ANGLE_TYPE_ANGLE,
 
   88       EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
 
   93       EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
 
   98       EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE,
 
   99       EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE,
 
  106   const EGLint d3d11_fl_9_3_display_attributes[] = {
 
  107       EGL_PLATFORM_ANGLE_TYPE_ANGLE,
 
  108       EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
 
  109       EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE,
 
  111       EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE,
 
  113       EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
 
  120   const EGLint d3d11_warp_display_attributes[] = {
 
  121       EGL_PLATFORM_ANGLE_TYPE_ANGLE,
 
  122       EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
 
  123       EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE,
 
  128   std::vector<const EGLint*> display_attributes_configs;
 
  132     display_attributes_configs.push_back(d3d11_display_attributes_with_luid);
 
  134   display_attributes_configs.push_back(d3d11_display_attributes);
 
  135   display_attributes_configs.push_back(d3d11_fl_9_3_display_attributes);
 
  136   display_attributes_configs.push_back(d3d11_warp_display_attributes);
 
  138   PFNEGLGETPLATFORMDISPLAYEXTPROC egl_get_platform_display_EXT =
 
  139       reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC
>(
 
  140           ::eglGetProcAddress(
"eglGetPlatformDisplayEXT"));
 
  141   if (!egl_get_platform_display_EXT) {
 
  142     LogEGLError(
"eglGetPlatformDisplayEXT not available");
 
  148   for (
auto config : display_attributes_configs) {
 
  149     bool is_last = (config == display_attributes_configs.back());
 
  151     display_ = egl_get_platform_display_EXT(EGL_PLATFORM_ANGLE_ANGLE,
 
  152                                             EGL_DEFAULT_DISPLAY, config);
 
  154     if (display_ == EGL_NO_DISPLAY) {
 
  156         LogEGLError(
"Failed to get a compatible EGLdisplay");
 
  164     if (::eglInitialize(display_, 
nullptr, 
nullptr) == EGL_FALSE) {
 
  180 bool Manager::InitializeConfig() {
 
  181   const EGLint config_attributes[] = {EGL_RED_SIZE,   8, EGL_GREEN_SIZE,   8,
 
  182                                       EGL_BLUE_SIZE,  8, EGL_ALPHA_SIZE,   8,
 
  183                                       EGL_DEPTH_SIZE, 8, EGL_STENCIL_SIZE, 8,
 
  186   EGLint num_config = 0;
 
  189       ::eglChooseConfig(display_, config_attributes, &config_, 1, &num_config);
 
  191   if (result == EGL_TRUE && num_config > 0) {
 
  199 bool Manager::InitializeContexts() {
 
  200   const EGLint context_attributes[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
 
  203       ::eglCreateContext(display_, config_, EGL_NO_CONTEXT, context_attributes);
 
  205     LogEGLError(
"Failed to create EGL render context");
 
  210       ::eglCreateContext(display_, config_, 
render_context, context_attributes);
 
  212     LogEGLError(
"Failed to create EGL resource context");
 
  216   render_context_ = std::make_unique<Context>(display_, 
render_context);
 
  221 bool Manager::InitializeDevice() {
 
  222   const auto query_display_attrib_EXT =
 
  223       reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC
>(
 
  224           ::eglGetProcAddress(
"eglQueryDisplayAttribEXT"));
 
  225   const auto query_device_attrib_EXT =
 
  226       reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC
>(
 
  227           ::eglGetProcAddress(
"eglQueryDeviceAttribEXT"));
 
  229   if (query_display_attrib_EXT == 
nullptr ||
 
  230       query_device_attrib_EXT == 
nullptr) {
 
  234   EGLAttrib egl_device = 0;
 
  235   EGLAttrib angle_device = 0;
 
  237   auto result = query_display_attrib_EXT(display_, EGL_DEVICE_EXT, &egl_device);
 
  238   if (result != EGL_TRUE) {
 
  242   result = query_device_attrib_EXT(
reinterpret_cast<EGLDeviceEXT
>(egl_device),
 
  243                                    EGL_D3D11_DEVICE_ANGLE, &angle_device);
 
  244   if (result != EGL_TRUE) {
 
  248   resolved_device_ = 
reinterpret_cast<ID3D11Device*
>(angle_device);
 
  252 void Manager::CleanUp() {
 
  253   EGLBoolean result = EGL_FALSE;
 
  256   resolved_device_.Reset();
 
  259   render_context_.reset();
 
  260   resource_context_.reset();
 
  262   if (display_ != EGL_NO_DISPLAY) {
 
  265     if (instance_count_ == 1) {
 
  266       ::eglTerminate(display_);
 
  268     display_ = EGL_NO_DISPLAY;
 
  279   if (!hwnd || !is_valid_) {
 
  286   const EGLint surface_attributes[] = {EGL_FIXED_SIZE_ANGLE,
 
  289                                        static_cast<EGLint
>(width),
 
  291                                        static_cast<EGLint
>(height),
 
  294   auto const surface = ::eglCreateWindowSurface(
 
  295       display_, config_, 
static_cast<EGLNativeWindowType
>(hwnd),
 
  297   if (surface == EGL_NO_SURFACE) {
 
  302   return std::make_unique<WindowSurface>(display_, render_context_->GetHandle(),
 
  303                                          surface, width, height);
 
  307   return ::eglGetCurrentContext() != EGL_NO_CONTEXT;
 
  311                                             EGLClientBuffer handle,
 
  312                                             const EGLint* attributes)
 const {
 
  313   return ::eglCreatePbufferFromClientBuffer(display_, handle_type, handle,
 
  314                                             config_, attributes);
 
  318   if (!resolved_device_) {
 
  319     if (!InitializeDevice()) {
 
  324   resolved_device_.CopyTo(device);
 
  325   return (resolved_device_ != 
nullptr);
 
  329   return render_context_.get();
 
  333   return resource_context_.get();
 
  337   Microsoft::WRL::ComPtr<IDXGIFactory1> factory1 = 
nullptr;
 
  338   Microsoft::WRL::ComPtr<IDXGIFactory6> factory6 = 
nullptr;
 
  339   Microsoft::WRL::ComPtr<IDXGIAdapter1> adapter = 
nullptr;
 
  340   HRESULT hr = ::CreateDXGIFactory1(IID_PPV_ARGS(&factory1));
 
  344   hr = factory1->QueryInterface(IID_PPV_ARGS(&factory6));
 
  350   hr = factory6->EnumAdapterByGpuPreference(
 
  351       0, DXGI_GPU_PREFERENCE_MINIMUM_POWER, IID_PPV_ARGS(&adapter));
 
  352   if (FAILED(hr) || adapter == 
nullptr) {
 
  356   DXGI_ADAPTER_DESC desc;
 
  357   hr = adapter->GetDesc(&desc);
 
  361   return std::make_optional(desc.AdapterLuid);