diff --git a/shell/platform/windows/angle_surface_manager.cc b/shell/platform/windows/angle_surface_manager.cc index d9e30c7d5dfdb..c7a07cb5d36bc 100644 --- a/shell/platform/windows/angle_surface_manager.cc +++ b/shell/platform/windows/angle_surface_manager.cc @@ -126,13 +126,37 @@ bool AngleSurfaceManager::Initialize() { return false; } + egl_resource_context_ = eglCreateContext( + egl_display_, egl_config_, egl_context_, display_context_attributes); + + if (egl_resource_context_ == EGL_NO_CONTEXT) { + OutputDebugString(L"EGL: Failed to create EGL resource context"); + return false; + } + return true; } void AngleSurfaceManager::CleanUp() { + EGLBoolean result = EGL_FALSE; + if (egl_display_ != EGL_NO_DISPLAY && egl_context_ != EGL_NO_CONTEXT) { - eglDestroyContext(egl_display_, egl_context_); + result = eglDestroyContext(egl_display_, egl_context_); egl_context_ = EGL_NO_CONTEXT; + + if (result == EGL_FALSE) { + OutputDebugString(L"EGL: Failed to destroy context"); + } + } + + if (egl_display_ != EGL_NO_DISPLAY && + egl_resource_context_ != EGL_NO_CONTEXT) { + result = eglDestroyContext(egl_display_, egl_resource_context_); + egl_resource_context_ = EGL_NO_CONTEXT; + + if (result == EGL_FALSE) { + OutputDebugString(L"EGL: Failed to destroy resource context"); + } } if (egl_display_ != EGL_NO_DISPLAY) { @@ -184,6 +208,11 @@ bool AngleSurfaceManager::MakeCurrent(const EGLSurface surface) { EGL_TRUE); } +bool AngleSurfaceManager::MakeResourceCurrent() { + return (eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE, + egl_resource_context_) == EGL_TRUE); +} + EGLBoolean AngleSurfaceManager::SwapBuffers(const EGLSurface surface) { return (eglSwapBuffers(egl_display_, surface)); } diff --git a/shell/platform/windows/angle_surface_manager.h b/shell/platform/windows/angle_surface_manager.h index 7400c7207f162..21c0648203a73 100644 --- a/shell/platform/windows/angle_surface_manager.h +++ b/shell/platform/windows/angle_surface_manager.h @@ -46,6 +46,10 @@ class AngleSurfaceManager { // surfaces returning a boolean result reflecting success. bool MakeCurrent(const EGLSurface surface); + // Binds egl_resource_context_ to the current rendering thread and to the draw + // and read surfaces returning a boolean result reflecting success. + bool MakeResourceCurrent(); + // Swaps the front and back buffers of the DX11 swapchain backing surface if // not null. EGLBoolean SwapBuffers(const EGLSurface surface); @@ -55,13 +59,17 @@ class AngleSurfaceManager { void CleanUp(); private: - // EGL representation of native display + // EGL representation of native display. EGLDisplay egl_display_; - // EGL representation of current rendering context + // EGL representation of current rendering context. EGLContext egl_context_; - // current frame buffer configuration + // EGL representation of current rendering context used for async texture + // uploads. + EGLContext egl_resource_context_; + + // current frame buffer configuration. EGLConfig egl_config_; // State representing success or failure of display initialization used when diff --git a/shell/platform/windows/flutter_windows.cc b/shell/platform/windows/flutter_windows.cc index d062538acbe56..beff9bed1ac7f 100644 --- a/shell/platform/windows/flutter_windows.cc +++ b/shell/platform/windows/flutter_windows.cc @@ -69,6 +69,10 @@ static FLUTTER_API_SYMBOL(FlutterEngine) const char* what) -> void* { return eglGetProcAddress(what); }; + config.open_gl.make_resource_current = [](void* user_data) -> bool { + auto host = static_cast(user_data); + return host->MakeResourceCurrent(); + }; FlutterProjectArgs args = {}; args.struct_size = sizeof(FlutterProjectArgs); diff --git a/shell/platform/windows/win32_flutter_window.cc b/shell/platform/windows/win32_flutter_window.cc index 7e4f6bcfefabf..edd40d989309c 100644 --- a/shell/platform/windows/win32_flutter_window.cc +++ b/shell/platform/windows/win32_flutter_window.cc @@ -279,6 +279,10 @@ bool Win32FlutterWindow::MakeCurrent() { return surface_manager->MakeCurrent(render_surface); } +bool Win32FlutterWindow::MakeResourceCurrent() { + return surface_manager->MakeResourceCurrent(); +} + bool Win32FlutterWindow::ClearContext() { return surface_manager->MakeCurrent(nullptr); } diff --git a/shell/platform/windows/win32_flutter_window.h b/shell/platform/windows/win32_flutter_window.h index 3b36321b5b2cf..bd5f40c9b94ad 100644 --- a/shell/platform/windows/win32_flutter_window.h +++ b/shell/platform/windows/win32_flutter_window.h @@ -85,6 +85,7 @@ class Win32FlutterWindow : public Win32Window { // Callbacks for clearing context, settings context and swapping buffers. bool ClearContext(); bool MakeCurrent(); + bool MakeResourceCurrent(); bool SwapBuffers(); // Sends a window metrics update to the Flutter engine using current window