[Impeller] Commands that don't specify their own viewports get the viewport of the render pass.

Fixes https://github.com/flutter/flutter/issues/176945
diff --git a/engine/src/flutter/impeller/renderer/backend/gles/render_pass_gles.cc b/engine/src/flutter/impeller/renderer/backend/gles/render_pass_gles.cc
index 4c5aa20..af256c8 100644
--- a/engine/src/flutter/impeller/renderer/backend/gles/render_pass_gles.cc
+++ b/engine/src/flutter/impeller/renderer/backend/gles/render_pass_gles.cc
@@ -189,6 +189,38 @@
   gl.StencilMaskSeparate(GL_BACK, 0xFFFFFFFF);
 }
 
+static void EncodeViewport(const ProcTableGLES& gl,
+                           const RenderPassData& pass_data,
+                           const std::optional<Viewport>& command_viewport,
+                           const ISize& target_size,
+                           std::optional<Viewport>& current_viewport) {
+  auto new_viewport = command_viewport.value_or(pass_data.viewport);
+
+  if (current_viewport.has_value() &&
+      current_viewport.value() == new_viewport) {
+    // The viewport is the same as the last command. Skip an unnecessary call.
+    return;
+  }
+
+  current_viewport = new_viewport;
+
+  gl.Viewport(new_viewport.rect.GetX(),  // x
+              target_size.height - new_viewport.rect.GetY() -
+                  new_viewport.rect.GetHeight(),  // y
+              new_viewport.rect.GetWidth(),       // width
+              new_viewport.rect.GetHeight()       // height
+  );
+  if (pass_data.depth_attachment) {
+    if (gl.DepthRangef.IsAvailable()) {
+      gl.DepthRangef(new_viewport.depth_range.z_near,
+                     new_viewport.depth_range.z_far);
+    } else {
+      gl.DepthRange(new_viewport.depth_range.z_near,
+                    new_viewport.depth_range.z_far);
+    }
+  }
+}
+
 [[nodiscard]] bool EncodeCommandsInReactor(
     const RenderPassData& pass_data,
     const ReactorGLES& reactor,
@@ -303,24 +335,7 @@
   // is bottom left origin, so we convert the coordinates here.
   ISize target_size = pass_data.color_attachment->GetSize();
 
-  //--------------------------------------------------------------------------
-  /// Setup the viewport.
-  ///
-  const auto& viewport = pass_data.viewport;
-  gl.Viewport(viewport.rect.GetX(),  // x
-              target_size.height - viewport.rect.GetY() -
-                  viewport.rect.GetHeight(),  // y
-              viewport.rect.GetWidth(),       // width
-              viewport.rect.GetHeight()       // height
-  );
-  if (pass_data.depth_attachment) {
-    if (gl.DepthRangef.IsAvailable()) {
-      gl.DepthRangef(viewport.depth_range.z_near, viewport.depth_range.z_far);
-    } else {
-      gl.DepthRange(viewport.depth_range.z_near, viewport.depth_range.z_far);
-    }
-  }
-
+  std::optional<Viewport> current_viewport;
   CullMode current_cull_mode = CullMode::kNone;
   WindingOrder current_winding_order = WindingOrder::kClockwise;
   gl.FrontFace(GL_CW);
@@ -372,23 +387,12 @@
     //--------------------------------------------------------------------------
     /// Setup the viewport.
     ///
-    if (command.viewport.has_value()) {
-      gl.Viewport(viewport.rect.GetX(),  // x
-                  target_size.height - viewport.rect.GetY() -
-                      viewport.rect.GetHeight(),  // y
-                  viewport.rect.GetWidth(),       // width
-                  viewport.rect.GetHeight()       // height
-      );
-      if (pass_data.depth_attachment) {
-        if (gl.DepthRangef.IsAvailable()) {
-          gl.DepthRangef(viewport.depth_range.z_near,
-                         viewport.depth_range.z_far);
-        } else {
-          gl.DepthRange(viewport.depth_range.z_near,
-                        viewport.depth_range.z_far);
-        }
-      }
-    }
+    EncodeViewport(gl,                //
+                   pass_data,         //
+                   command.viewport,  //
+                   target_size,       //
+                   current_viewport   //
+    );
 
     //--------------------------------------------------------------------------
     /// Setup the scissor rect.