Fix flutter#40068 Redraw issues on resize/minimize/maximize on Windows and startup in release (#20357)

* Fix redraw issues

* Address CR feedback.

* Fix build

* CR feedback
diff --git a/shell/platform/windows/angle_surface_manager.cc b/shell/platform/windows/angle_surface_manager.cc
index cc04628..eda082c 100644
--- a/shell/platform/windows/angle_surface_manager.cc
+++ b/shell/platform/windows/angle_surface_manager.cc
@@ -169,14 +169,22 @@
   }
 }
 
-bool AngleSurfaceManager::CreateSurface(WindowsRenderTarget* render_target) {
+bool AngleSurfaceManager::CreateSurface(WindowsRenderTarget* render_target,
+                                        EGLint width,
+                                        EGLint height) {
   if (!render_target || !initialize_succeeded_) {
     return false;
   }
 
   EGLSurface surface = EGL_NO_SURFACE;
 
-  const EGLint surfaceAttributes[] = {EGL_NONE};
+  // Disable Angle's automatic surface sizing logic and provide and exlicit
+  // size.  AngleSurfaceManager is responsible for initiating Angle surface size
+  // changes to avoid race conditions with rendering when automatic mode is
+  // used.
+  const EGLint surfaceAttributes[] = {
+      EGL_FIXED_SIZE_ANGLE, EGL_TRUE, EGL_WIDTH, width,
+      EGL_HEIGHT,           height,   EGL_NONE};
 
   surface = eglCreateWindowSurface(
       egl_display_, egl_config_,
@@ -190,6 +198,26 @@
   return true;
 }
 
+void AngleSurfaceManager::ResizeSurface(WindowsRenderTarget* render_target,
+                                        EGLint width,
+                                        EGLint height) {
+  EGLint existing_width, existing_height;
+  GetSurfaceDimensions(&existing_width, &existing_height);
+  if (width != existing_width || height != existing_height) {
+    // Destroy existing surface with previous stale dimensions and create new
+    // surface at new size. Since the Windows compositor retains the front
+    // buffer until the new surface has been presented, no need to manually
+    // preserve the previous surface contents. This resize approach could be
+    // further optimized if Angle exposed a public entrypoint for
+    // SwapChain11::reset or SwapChain11::resize.
+    DestroySurface();
+    if (!CreateSurface(render_target, width, height)) {
+      std::cerr << "AngleSurfaceManager::ResizeSurface failed to create surface"
+                << std::endl;
+    }
+  }
+}
+
 void AngleSurfaceManager::GetSurfaceDimensions(EGLint* width, EGLint* height) {
   if (render_surface_ == EGL_NO_SURFACE || !initialize_succeeded_) {
     width = 0;
diff --git a/shell/platform/windows/angle_surface_manager.h b/shell/platform/windows/angle_surface_manager.h
index a6a5fc2..60754c3 100644
--- a/shell/platform/windows/angle_surface_manager.h
+++ b/shell/platform/windows/angle_surface_manager.h
@@ -23,6 +23,8 @@
 // destroy surfaces
 class AngleSurfaceManager {
  public:
+  // Creates a new surface manager retaining reference to the passed-in target
+  // for the lifetime of the manager.
   AngleSurfaceManager();
   ~AngleSurfaceManager();
 
@@ -32,8 +34,19 @@
 
   // Creates an EGLSurface wrapper and backing DirectX 11 SwapChain
   // asociated with window, in the appropriate format for display.
-  // Target represents the visual entity to bind to.
-  bool CreateSurface(WindowsRenderTarget* render_target);
+  // Target represents the visual entity to bind to.  Width and
+  // height represent dimensions surface is created at.
+  bool CreateSurface(WindowsRenderTarget* render_target,
+                     EGLint width,
+                     EGLint height);
+
+  // Resizes backing surface from current size to newly requested size
+  // based on width and height for the specific case when width and height do
+  // not match current surface dimensions.  Target represents the visual entity
+  // to bind to.
+  void ResizeSurface(WindowsRenderTarget* render_target,
+                     EGLint width,
+                     EGLint height);
 
   // queries EGL for the dimensions of surface in physical
   // pixels returning width and height as out params.
diff --git a/shell/platform/windows/flutter_windows.cc b/shell/platform/windows/flutter_windows.cc
index f35a4c1..1e997da 100644
--- a/shell/platform/windows/flutter_windows.cc
+++ b/shell/platform/windows/flutter_windows.cc
@@ -65,6 +65,9 @@
       return nullptr;
     }
   }
+
+  // Must happen after engine is running.
+  state->view->SendInitialBounds();
   return state.release();
 }
 
diff --git a/shell/platform/windows/flutter_windows_view.cc b/shell/platform/windows/flutter_windows_view.cc
index 9c463c3..5736ce9 100644
--- a/shell/platform/windows/flutter_windows_view.cc
+++ b/shell/platform/windows/flutter_windows_view.cc
@@ -52,6 +52,7 @@
 
 void FlutterWindowsView::OnWindowSizeChanged(size_t width,
                                              size_t height) const {
+  surface_manager_->ResizeSurface(GetRenderTarget(), width, height);
   SendWindowMetrics(width, height, binding_handler_->GetDpiScale());
 }
 
@@ -127,6 +128,13 @@
   auto result = FlutterEngineSendWindowMetricsEvent(engine_->engine(), &event);
 }
 
+void FlutterWindowsView::SendInitialBounds() {
+  PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds();
+
+  SendWindowMetrics(bounds.width, bounds.height,
+                    binding_handler_->GetDpiScale());
+}
+
 // Set's |event_data|'s phase to either kMove or kHover depending on the current
 // primary mouse button state.
 void FlutterWindowsView::SetEventPhaseFromCursorButtonState(
@@ -263,7 +271,9 @@
 }
 
 void FlutterWindowsView::CreateRenderSurface() {
-  surface_manager_->CreateSurface(render_target_.get());
+  PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds();
+  surface_manager_->CreateSurface(GetRenderTarget(), bounds.width,
+                                  bounds.height);
 }
 
 void FlutterWindowsView::DestroyRenderSurface() {
@@ -272,7 +282,7 @@
   }
 }
 
-WindowsRenderTarget* FlutterWindowsView::GetRenderTarget() {
+WindowsRenderTarget* FlutterWindowsView::GetRenderTarget() const {
   return render_target_.get();
 }
 
diff --git a/shell/platform/windows/flutter_windows_view.h b/shell/platform/windows/flutter_windows_view.h
index 13ff056..5df86e4 100644
--- a/shell/platform/windows/flutter_windows_view.h
+++ b/shell/platform/windows/flutter_windows_view.h
@@ -52,7 +52,7 @@
   void DestroyRenderSurface();
 
   // Return the currently configured WindowsRenderTarget.
-  WindowsRenderTarget* GetRenderTarget();
+  WindowsRenderTarget* GetRenderTarget() const;
 
   // Returns the engine backing this view.
   FlutterWindowsEngine* GetEngine();
@@ -63,6 +63,9 @@
   bool MakeResourceCurrent();
   bool SwapBuffers();
 
+  // Send initial bounds to embedder.  Must occur after engine has initialized.
+  void SendInitialBounds();
+
   // |WindowBindingHandlerDelegate|
   void OnWindowSizeChanged(size_t width, size_t height) const override;