[Impeller] fixed nested save layer mipmap counts (#49778)

resolves https://github.com/flutter/engine/pull/49607#discussion_r1450982660

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc
index c2b0739..3858ff0 100644
--- a/impeller/aiks/aiks_unittests.cc
+++ b/impeller/aiks/aiks_unittests.cc
@@ -3794,5 +3794,31 @@
   EXPECT_EQ(max_mip_count, 1lu);
 }
 
+TEST_P(AiksTest, GaussianBlurMipMapNestedLayer) {
+  Canvas canvas;
+  canvas.DrawPaint({.color = Color::Wheat()});
+  canvas.SaveLayer({.blend_mode = BlendMode::kMultiply});
+  canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
+  canvas.SaveLayer({}, std::nullopt,
+                   ImageFilter::MakeBlur(Sigma(30), Sigma(30),
+                                         FilterContents::BlurStyle::kNormal,
+                                         Entity::TileMode::kClamp));
+  canvas.DrawCircle({200, 200}, 50, {.color = Color::Chartreuse()});
+
+  Picture picture = canvas.EndRecordingAsPicture();
+  std::shared_ptr<RenderTargetCache> cache =
+      std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
+  AiksContext aiks_context(GetContext(), nullptr, cache);
+  picture.ToImage(aiks_context, {100, 100});
+
+  size_t max_mip_count = 0;
+  for (auto it = cache->GetTextureDataBegin(); it != cache->GetTextureDataEnd();
+       ++it) {
+    max_mip_count =
+        std::max(it->texture->GetTextureDescriptor().mip_count, max_mip_count);
+  }
+  EXPECT_EQ(max_mip_count, 1lu);
+}
+
 }  // namespace testing
 }  // namespace impeller
diff --git a/impeller/entity/entity_pass.cc b/impeller/entity/entity_pass.cc
index 576c3a9..dec9a98 100644
--- a/impeller/entity/entity_pass.cc
+++ b/impeller/entity/entity_pass.cc
@@ -325,23 +325,13 @@
                   Rect::MakeSize(root_render_target.GetRenderTargetSize()),
                   {.readonly = true});
 
-  int32_t required_mip_count = 1;
-  IterateAllElements(
-      [&required_mip_count, lazy_glyph_atlas = renderer.GetLazyGlyphAtlas()](
-          const Element& element) {
-        if (auto entity = std::get_if<Entity>(&element)) {
-          if (const auto& contents = entity->GetContents()) {
-            contents->PopulateGlyphAtlas(lazy_glyph_atlas,
-                                         entity->DeriveTextScale());
-          }
-        }
-        if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
-          const EntityPass* entity_pass = subpass->get();
-          required_mip_count =
-              std::max(required_mip_count, entity_pass->GetRequiredMipCount());
-        }
-        return true;
-      });
+  IterateAllEntities([lazy_glyph_atlas =
+                          renderer.GetLazyGlyphAtlas()](const Entity& entity) {
+    if (const auto& contents = entity.GetContents()) {
+      contents->PopulateGlyphAtlas(lazy_glyph_atlas, entity.DeriveTextScale());
+    }
+    return true;
+  });
 
   ClipCoverageStack clip_coverage_stack = {ClipCoverageLayer{
       .coverage = Rect::MakeSize(root_render_target.GetRenderTargetSize()),
@@ -353,7 +343,8 @@
   // there's no need to set up a stencil attachment on the root render target.
   if (reads_from_onscreen_backdrop) {
     EntityPassTarget offscreen_target = CreateRenderTarget(
-        renderer, root_render_target.GetRenderTargetSize(), required_mip_count,
+        renderer, root_render_target.GetRenderTargetSize(),
+        GetBackdropFilterMipCount(),
         GetClearColorOrDefault(render_target.GetRenderTargetSize()));
 
     if (!OnRender(renderer,  // renderer
@@ -615,7 +606,7 @@
     auto subpass_target = CreateRenderTarget(
         renderer,      // renderer
         subpass_size,  // size
-        /*mip_count=*/1,
+        subpass->GetBackdropFilterMipCount(),
         subpass->GetClearColorOrDefault(subpass_size));  // clear_color
 
     if (!subpass_target.IsValid()) {
@@ -1200,6 +1191,16 @@
   enable_offscreen_debug_checkerboard_ = enabled;
 }
 
+int32_t EntityPass::GetBackdropFilterMipCount() const {
+  int32_t result = 1;
+  for (auto& element : elements_) {
+    if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
+      result = std::max(result, subpass->get()->GetRequiredMipCount());
+    }
+  }
+  return result;
+}
+
 EntityPassClipRecorder::EntityPassClipRecorder() {}
 
 void EntityPassClipRecorder::RecordEntity(const Entity& entity,
diff --git a/impeller/entity/entity_pass.h b/impeller/entity/entity_pass.h
index 7de68d0..cacf457 100644
--- a/impeller/entity/entity_pass.h
+++ b/impeller/entity/entity_pass.h
@@ -157,6 +157,10 @@
     required_mip_count_ = mip_count;
   }
 
+  /// Returns the mip map count that should be required for the render target
+  /// receiving this EntityPass.
+  int32_t GetBackdropFilterMipCount() const;
+
   //----------------------------------------------------------------------------
   /// @brief  Computes the coverage of a given subpass. This is used to
   ///         determine the texture size of a given subpass before it's rendered