Revert "[Impeller] Reland 2: Implement draw order optimization. (#54268) (#54325)

Manual revert of https://github.com/flutter/engine/pull/54268, since the time expired for automatic reverting.

@jason-simmons found this patch to be causing a regression in a downstream app. Some draws are getting clipped away, and disabling the scissor fixes it. So there is likely still a case not being handled correctly with the clip replay or subpass draw deferral behavior.
diff --git a/ci/licenses_golden/excluded_files b/ci/licenses_golden/excluded_files
index 65321d1..4420a94 100644
--- a/ci/licenses_golden/excluded_files
+++ b/ci/licenses_golden/excluded_files
@@ -165,7 +165,6 @@
 ../../../flutter/impeller/entity/contents/host_buffer_unittests.cc
 ../../../flutter/impeller/entity/contents/test
 ../../../flutter/impeller/entity/contents/tiled_texture_contents_unittests.cc
-../../../flutter/impeller/entity/draw_order_resolver_unittests.cc
 ../../../flutter/impeller/entity/entity_pass_target_unittests.cc
 ../../../flutter/impeller/entity/entity_pass_unittests.cc
 ../../../flutter/impeller/entity/entity_unittests.cc
diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter
index 28bbe47..bd838fd 100644
--- a/ci/licenses_golden/licenses_flutter
+++ b/ci/licenses_golden/licenses_flutter
@@ -42127,8 +42127,6 @@
 ORIGIN: ../../../flutter/impeller/entity/contents/tiled_texture_contents.h + ../../../flutter/LICENSE
 ORIGIN: ../../../flutter/impeller/entity/contents/vertices_contents.cc + ../../../flutter/LICENSE
 ORIGIN: ../../../flutter/impeller/entity/contents/vertices_contents.h + ../../../flutter/LICENSE
-ORIGIN: ../../../flutter/impeller/entity/draw_order_resolver.cc + ../../../flutter/LICENSE
-ORIGIN: ../../../flutter/impeller/entity/draw_order_resolver.h + ../../../flutter/LICENSE
 ORIGIN: ../../../flutter/impeller/entity/entity.cc + ../../../flutter/LICENSE
 ORIGIN: ../../../flutter/impeller/entity/entity.h + ../../../flutter/LICENSE
 ORIGIN: ../../../flutter/impeller/entity/entity_pass.cc + ../../../flutter/LICENSE
@@ -45011,8 +45009,6 @@
 FILE: ../../../flutter/impeller/entity/contents/tiled_texture_contents.h
 FILE: ../../../flutter/impeller/entity/contents/vertices_contents.cc
 FILE: ../../../flutter/impeller/entity/contents/vertices_contents.h
-FILE: ../../../flutter/impeller/entity/draw_order_resolver.cc
-FILE: ../../../flutter/impeller/entity/draw_order_resolver.h
 FILE: ../../../flutter/impeller/entity/entity.cc
 FILE: ../../../flutter/impeller/entity/entity.h
 FILE: ../../../flutter/impeller/entity/entity_pass.cc
diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn
index c75ca72..d91d56c 100644
--- a/impeller/entity/BUILD.gn
+++ b/impeller/entity/BUILD.gn
@@ -166,8 +166,6 @@
     "contents/tiled_texture_contents.h",
     "contents/vertices_contents.cc",
     "contents/vertices_contents.h",
-    "draw_order_resolver.cc",
-    "draw_order_resolver.h",
     "entity.cc",
     "entity.h",
     "entity_pass.cc",
@@ -250,7 +248,6 @@
     "contents/filters/matrix_filter_contents_unittests.cc",
     "contents/host_buffer_unittests.cc",
     "contents/tiled_texture_contents_unittests.cc",
-    "draw_order_resolver_unittests.cc",
     "entity_pass_target_unittests.cc",
     "entity_pass_unittests.cc",
     "entity_playground.cc",
diff --git a/impeller/entity/contents/color_source_contents.h b/impeller/entity/contents/color_source_contents.h
index 008674a..5f72b13 100644
--- a/impeller/entity/contents/color_source_contents.h
+++ b/impeller/entity/contents/color_source_contents.h
@@ -213,11 +213,6 @@
     pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer));
     options.primitive_type = geometry_result.type;
 
-    // Enable depth writing for all opaque entities in order to allow
-    // reordering. Opaque entities are coerced to source blending by
-    // `EntityPass::AddEntity`.
-    options.depth_write_enabled = options.blend_mode == BlendMode::kSource;
-
     // Take the pre-populated vertex shader uniform struct and set managed
     // values.
     frame_info.mvp = geometry_result.transform;
diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc
index cf39b60..3fa906e 100644
--- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc
+++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc
@@ -575,16 +575,16 @@
                   const ContentContext& renderer, const Entity& entity,
                   RenderPass& pass) mutable {
                 bool result = true;
+                blur_entity.SetClipDepth(entity.GetClipDepth());
+                blur_entity.SetTransform(entity.GetTransform() *
+                                         blurred_transform);
+                result = result && blur_entity.Render(renderer, pass);
                 snapshot_entity.SetTransform(
                     entity.GetTransform() *
                     Matrix::MakeScale(1.f / source_space_scalar) *
                     snapshot_transform);
                 snapshot_entity.SetClipDepth(entity.GetClipDepth());
                 result = result && snapshot_entity.Render(renderer, pass);
-                blur_entity.SetClipDepth(entity.GetClipDepth());
-                blur_entity.SetTransform(entity.GetTransform() *
-                                         blurred_transform);
-                result = result && blur_entity.Render(renderer, pass);
                 return result;
               }),
           fml::MakeCopyable([blur_entity = blur_entity.Clone(),
diff --git a/impeller/entity/contents/texture_contents.cc b/impeller/entity/contents/texture_contents.cc
index 7cc6bef..a2af33e 100644
--- a/impeller/entity/contents/texture_contents.cc
+++ b/impeller/entity/contents/texture_contents.cc
@@ -153,9 +153,6 @@
   }
   pipeline_options.primitive_type = PrimitiveType::kTriangleStrip;
 
-  pipeline_options.depth_write_enabled =
-      stencil_enabled_ && pipeline_options.blend_mode == BlendMode::kSource;
-
   pass.SetPipeline(strict_source_rect_enabled_
                        ? renderer.GetTextureStrictSrcPipeline(pipeline_options)
                        : renderer.GetTexturePipeline(pipeline_options));
diff --git a/impeller/entity/draw_order_resolver.cc b/impeller/entity/draw_order_resolver.cc
deleted file mode 100644
index 5afdf43..0000000
--- a/impeller/entity/draw_order_resolver.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2013 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "impeller/entity/draw_order_resolver.h"
-
-#include "flutter/fml/logging.h"
-#include "impeller/base/validation.h"
-
-namespace impeller {
-
-DrawOrderResolver::DrawOrderResolver() : draw_order_layers_({{}}){};
-
-void DrawOrderResolver::AddElement(size_t element_index, bool is_opaque) {
-  DrawOrderLayer& layer = draw_order_layers_.back();
-  if (is_opaque) {
-    layer.opaque_elements.push_back(element_index);
-  } else {
-    layer.dependent_elements.push_back(element_index);
-  }
-}
-void DrawOrderResolver::PushClip(size_t element_index) {
-  draw_order_layers_.back().dependent_elements.push_back(element_index);
-  draw_order_layers_.push_back({});
-};
-
-void DrawOrderResolver::PopClip() {
-  if (draw_order_layers_.size() == 1u) {
-    // This is likely recoverable, so don't assert.
-    VALIDATION_LOG
-        << "Attemped to pop the first draw order clip layer. This is a bug in "
-           "`EntityPass`.";
-    return;
-  }
-
-  DrawOrderLayer& layer = draw_order_layers_.back();
-  DrawOrderLayer& parent_layer =
-      draw_order_layers_[draw_order_layers_.size() - 2];
-
-  layer.WriteCombinedDraws(parent_layer.dependent_elements, 0, 0);
-
-  draw_order_layers_.pop_back();
-}
-
-void DrawOrderResolver::Flush() {
-  FML_DCHECK(draw_order_layers_.size() >= 1u);
-
-  size_t layer_count = draw_order_layers_.size();
-
-  // Pop all clip layers.
-  while (draw_order_layers_.size() > 1u) {
-    PopClip();
-  }
-
-  // Move the root layer items into the sorted list.
-  DrawOrderLayer& layer = draw_order_layers_.back();
-  if (!first_root_flush_.has_value()) {
-    // Record the first flush.
-    first_root_flush_ = std::move(layer);
-    layer = {};
-  } else {
-    // Write subsequent flushes into the sorted root list.
-    layer.WriteCombinedDraws(sorted_elements_, 0, 0);
-    layer.opaque_elements.clear();
-    layer.dependent_elements.clear();
-  }
-
-  // Refill with empty layers.
-  draw_order_layers_.resize(layer_count);
-}
-
-DrawOrderResolver::ElementRefs DrawOrderResolver::GetSortedDraws(
-    size_t opaque_skip_count,
-    size_t translucent_skip_count) const {
-  FML_DCHECK(draw_order_layers_.size() == 1u)
-      << "Attempted to get sorted draws before all clips were popped.";
-
-  ElementRefs sorted_elements;
-  sorted_elements.reserve(
-      (first_root_flush_.has_value()
-           ? first_root_flush_->opaque_elements.size() +
-                 first_root_flush_->dependent_elements.size()
-           : 0u) +
-      sorted_elements_.size() +
-      draw_order_layers_.back().opaque_elements.size() +
-      draw_order_layers_.back().dependent_elements.size());
-
-  // Write all flushed items.
-  if (first_root_flush_.has_value()) {
-    first_root_flush_->WriteCombinedDraws(sorted_elements, opaque_skip_count,
-                                          translucent_skip_count);
-  }
-  sorted_elements.insert(sorted_elements.end(), sorted_elements_.begin(),
-                         sorted_elements_.end());
-
-  // Write any remaining non-flushed items.
-  draw_order_layers_.back().WriteCombinedDraws(
-      sorted_elements, first_root_flush_.has_value() ? 0 : opaque_skip_count,
-      first_root_flush_.has_value() ? 0 : translucent_skip_count);
-
-  return sorted_elements;
-}
-
-void DrawOrderResolver::DrawOrderLayer::WriteCombinedDraws(
-    ElementRefs& destination,
-    size_t opaque_skip_count,
-    size_t translucent_skip_count) const {
-  FML_DCHECK(opaque_skip_count <= opaque_elements.size());
-  FML_DCHECK(translucent_skip_count <= dependent_elements.size());
-
-  destination.reserve(destination.size() +                          //
-                      opaque_elements.size() - opaque_skip_count +  //
-                      dependent_elements.size() - translucent_skip_count);
-
-  // Draw backdrop-independent elements in reverse order first.
-  destination.insert(destination.end(), opaque_elements.rbegin(),
-                     opaque_elements.rend() - opaque_skip_count);
-  // Then, draw backdrop-dependent elements in their original order.
-  destination.insert(destination.end(),
-                     dependent_elements.begin() + translucent_skip_count,
-                     dependent_elements.end());
-}
-
-}  // namespace impeller
diff --git a/impeller/entity/draw_order_resolver.h b/impeller/entity/draw_order_resolver.h
deleted file mode 100644
index 5c8d7a9..0000000
--- a/impeller/entity/draw_order_resolver.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2013 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef FLUTTER_IMPELLER_ENTITY_DRAW_ORDER_RESOLVER_H_
-#define FLUTTER_IMPELLER_ENTITY_DRAW_ORDER_RESOLVER_H_
-
-#include <optional>
-#include <vector>
-
-namespace impeller {
-
-/// Helper that records draw indices in painter's order and sorts the draws into
-/// an optimized order based on translucency and clips.
-class DrawOrderResolver {
- public:
-  using ElementRefs = std::vector<size_t>;
-
-  DrawOrderResolver();
-
-  void AddElement(size_t element_index, bool is_opaque);
-
-  void PushClip(size_t element_index);
-
-  void PopClip();
-
-  void Flush();
-
-  //-------------------------------------------------------------------------
-  /// @brief      Returns the sorted draws for the current draw order layer.
-  ///             This should only be called after all recording has finished.
-  ///
-  /// @param[in]  opaque_skip_count       The number of opaque elements to skip
-  ///                                     when appending the combined elements.
-  ///                                     This is used for the "clear color"
-  ///                                     optimization.
-  /// @param[in]  translucent_skip_count  The number of translucent elements to
-  ///                                     skip when appending the combined
-  ///                                     elements. This is used for the
-  ///                                     "clear color" optimization.
-  ///
-  ElementRefs GetSortedDraws(size_t opaque_skip_count,
-                             size_t translucent_skip_count) const;
-
- private:
-  /// A data structure for collecting sorted draws for a given "draw order
-  /// layer". Currently these layers just correspond to the local clip stack.
-  struct DrawOrderLayer {
-    /// The list of backdrop-independent elements (always just opaque). These
-    /// are order independent, and so we render these elements in reverse
-    /// painter's order so that they cull one another.
-    ElementRefs opaque_elements;
-
-    /// The list of backdrop-dependent elements with respect to this draw
-    /// order layer. These elements are drawn after all of the independent
-    /// elements.
-    ElementRefs dependent_elements;
-
-    //-----------------------------------------------------------------------
-    /// @brief      Appends the combined opaque and transparent elements into
-    ///             a final destination buffer.
-    ///
-    /// @param[in]  destination             The buffer to append the combined
-    ///                                     elements to.
-    /// @param[in]  opaque_skip_count       The number of opaque elements to
-    ///                                     skip when appending the combined
-    ///                                     elements. This is used for the
-    ///                                     "clear color" optimization.
-    /// @param[in]  translucent_skip_count  The number of translucent elements
-    ///                                     to skip when appending the combined
-    ///                                     elements. This is used for the
-    ///                                     "clear color" optimization.
-    ///
-    void WriteCombinedDraws(ElementRefs& destination,
-                            size_t opaque_skip_count,
-                            size_t translucent_skip_count) const;
-  };
-  std::vector<DrawOrderLayer> draw_order_layers_;
-
-  // The first time the root layer is flushed, the layer contents are stored
-  // here. This is done to enable element skipping for the clear color
-  // optimization.
-  std::optional<DrawOrderLayer> first_root_flush_;
-  // All subsequent root flushes are stored here.
-  ElementRefs sorted_elements_;
-
-  DrawOrderResolver(const DrawOrderResolver&) = delete;
-
-  DrawOrderResolver& operator=(const DrawOrderResolver&) = delete;
-};
-
-}  // namespace impeller
-
-#endif  // FLUTTER_IMPELLER_ENTITY_DRAW_ORDER_RESOLVER_H_
diff --git a/impeller/entity/draw_order_resolver_unittests.cc b/impeller/entity/draw_order_resolver_unittests.cc
deleted file mode 100644
index c19e781..0000000
--- a/impeller/entity/draw_order_resolver_unittests.cc
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2013 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "flutter/testing/testing.h"
-#include "impeller/entity/draw_order_resolver.h"
-#include "third_party/googletest/googletest/include/gtest/gtest.h"
-
-namespace impeller {
-namespace testing {
-
-TEST(DrawOrderResolverTest, GetSortedDrawsReturnsCorrectOrderWithNoClips) {
-  DrawOrderResolver resolver;
-
-  // Opaque items.
-  resolver.AddElement(0, true);
-  resolver.AddElement(1, true);
-  // Translucent items.
-  resolver.AddElement(2, false);
-  resolver.AddElement(3, false);
-
-  auto sorted_elements = resolver.GetSortedDraws(0, 0);
-
-  EXPECT_EQ(sorted_elements.size(), 4u);
-  // First, the opaque items are drawn in reverse order.
-  EXPECT_EQ(sorted_elements[0], 1u);
-  EXPECT_EQ(sorted_elements[1], 0u);
-  // Then the translucent items are drawn.
-  EXPECT_EQ(sorted_elements[2], 2u);
-  EXPECT_EQ(sorted_elements[3], 3u);
-}
-
-TEST(DrawOrderResolverTest, GetSortedDrawsReturnsCorrectOrderWithClips) {
-  DrawOrderResolver resolver;
-
-  // Items before clip.
-  resolver.AddElement(0, false);
-  resolver.AddElement(1, true);
-  resolver.AddElement(2, false);
-  resolver.AddElement(3, true);
-
-  // Clip.
-  resolver.PushClip(4);
-  {
-    // Clipped items.
-    resolver.AddElement(5, false);
-    resolver.AddElement(6, false);
-    // Clipped translucent items.
-    resolver.AddElement(7, true);
-    resolver.AddElement(8, true);
-  }
-  resolver.PopClip();
-
-  // Items after clip.
-  resolver.AddElement(9, true);
-  resolver.AddElement(10, false);
-  resolver.AddElement(11, true);
-  resolver.AddElement(12, false);
-
-  auto sorted_elements = resolver.GetSortedDraws(0, 0);
-
-  EXPECT_EQ(sorted_elements.size(), 13u);
-  // First, all the non-clipped opaque items are drawn in reverse order.
-  EXPECT_EQ(sorted_elements[0], 11u);
-  EXPECT_EQ(sorted_elements[1], 9u);
-  EXPECT_EQ(sorted_elements[2], 3u);
-  EXPECT_EQ(sorted_elements[3], 1u);
-  // Then, non-clipped translucent items that came before the clip are drawn in
-  // their original order.
-  EXPECT_EQ(sorted_elements[4], 0u);
-  EXPECT_EQ(sorted_elements[5], 2u);
-
-  // Then, the clip and its sorted child items are drawn.
-  EXPECT_EQ(sorted_elements[6], 4u);
-  {
-    // Opaque clipped items are drawn in reverse order.
-    EXPECT_EQ(sorted_elements[7], 8u);
-    EXPECT_EQ(sorted_elements[8], 7u);
-    // Translucent clipped items are drawn.
-    EXPECT_EQ(sorted_elements[9], 5u);
-    EXPECT_EQ(sorted_elements[10], 6u);
-  }
-  // Finally, the non-clipped translucent items which came after the clip are
-  // drawn in their original order.
-  EXPECT_EQ(sorted_elements[11], 10u);
-  EXPECT_EQ(sorted_elements[12], 12u);
-}
-
-TEST(DrawOrderResolverTest, GetSortedDrawsRespectsSkipCounts) {
-  DrawOrderResolver resolver;
-
-  // These items will be skipped.
-  resolver.AddElement(0, false);
-  resolver.AddElement(1, true);
-  resolver.AddElement(2, false);
-  // These ones will be included in the final draw list.
-  resolver.AddElement(3, false);
-  resolver.AddElement(4, true);
-  resolver.AddElement(5, true);
-
-  // Form the draw list, skipping elements 0, 1, and 2.
-  // This emulates what happens when entitypass applies the clear color
-  // optimization.
-  auto sorted_elements = resolver.GetSortedDraws(1, 2);
-
-  EXPECT_EQ(sorted_elements.size(), 3u);
-  // First, opaque items are drawn in reverse order.
-  EXPECT_EQ(sorted_elements[0], 5u);
-  EXPECT_EQ(sorted_elements[1], 4u);
-  // Then, translucent items are drawn.
-  EXPECT_EQ(sorted_elements[2], 3u);
-}
-
-TEST(DrawOrderResolverTest, GetSortedDrawsReturnsCorrectOrderWithFlush) {
-  DrawOrderResolver resolver;
-
-  resolver.AddElement(0, false);
-  resolver.AddElement(1, true);
-  resolver.AddElement(2, false);
-  resolver.AddElement(3, true);
-
-  resolver.Flush();
-
-  resolver.AddElement(4, false);
-  resolver.AddElement(5, true);
-  resolver.AddElement(6, false);
-  resolver.AddElement(7, true);
-
-  resolver.Flush();
-
-  resolver.AddElement(8, false);
-  resolver.AddElement(9, true);
-  resolver.AddElement(10, false);
-  resolver.AddElement(11, true);
-
-  auto sorted_elements = resolver.GetSortedDraws(1, 1);
-
-  EXPECT_EQ(sorted_elements.size(), 10u);
-
-  // Skipped draws apply to the first flush.
-  EXPECT_EQ(sorted_elements[0], 3u);
-  EXPECT_EQ(sorted_elements[1], 2u);
-
-  EXPECT_EQ(sorted_elements[2], 7u);
-  EXPECT_EQ(sorted_elements[3], 5u);
-  EXPECT_EQ(sorted_elements[4], 4u);
-  EXPECT_EQ(sorted_elements[5], 6u);
-
-  EXPECT_EQ(sorted_elements[6], 11u);
-  EXPECT_EQ(sorted_elements[7], 9u);
-  EXPECT_EQ(sorted_elements[8], 8u);
-  EXPECT_EQ(sorted_elements[9], 10u);
-}
-
-}  // namespace testing
-}  // namespace impeller
diff --git a/impeller/entity/entity.cc b/impeller/entity/entity.cc
index 2e5229d..cb33689 100644
--- a/impeller/entity/entity.cc
+++ b/impeller/entity/entity.cc
@@ -43,8 +43,6 @@
 
 Entity::Entity(const Entity&) = default;
 
-Entity& Entity::operator=(Entity&&) = default;
-
 const Matrix& Entity::GetTransform() const {
   return transform_;
 }
diff --git a/impeller/entity/entity.h b/impeller/entity/entity.h
index daaac14..95f8b29 100644
--- a/impeller/entity/entity.h
+++ b/impeller/entity/entity.h
@@ -73,8 +73,6 @@
 
   Entity(Entity&&);
 
-  Entity& operator=(Entity&&);
-
   /// @brief  Get the global transform matrix for this Entity.
   const Matrix& GetTransform() const;
 
diff --git a/impeller/entity/entity_pass.cc b/impeller/entity/entity_pass.cc
index cd29877..bd1e070 100644
--- a/impeller/entity/entity_pass.cc
+++ b/impeller/entity/entity_pass.cc
@@ -20,7 +20,6 @@
 #include "impeller/entity/contents/filters/inputs/filter_input.h"
 #include "impeller/entity/contents/framebuffer_blend_contents.h"
 #include "impeller/entity/contents/texture_contents.h"
-#include "impeller/entity/draw_order_resolver.h"
 #include "impeller/entity/entity.h"
 #include "impeller/entity/entity_pass_clip_stack.h"
 #include "impeller/entity/inline_pass_context.h"
@@ -45,10 +44,6 @@
 }
 }  // namespace
 
-bool EntityPass::IsSubpass(const Element& element) {
-  return std::holds_alternative<std::unique_ptr<EntityPass>>(element);
-}
-
 EntityPass::EntityPass() = default;
 
 EntityPass::~EntityPass() = default;
@@ -111,14 +106,11 @@
   if (entity.GetBlendMode() > Entity::kLastPipelineBlendMode) {
     advanced_blend_reads_from_pass_texture_ = true;
   }
-  draw_order_resolver_.AddElement(elements_.size(),
-                                  entity.GetBlendMode() == BlendMode::kSource);
   elements_.emplace_back(std::move(entity));
 }
 
 void EntityPass::PushClip(Entity entity) {
   elements_.emplace_back(std::move(entity));
-  draw_order_resolver_.PushClip(elements_.size() - 1);
   active_clips_.emplace_back(elements_.size() - 1);
 }
 
@@ -137,7 +129,6 @@
     FML_DCHECK(element);
     element->SetClipDepth(depth);
     active_clips_.pop_back();
-    draw_order_resolver_.PopClip();
   }
 }
 
@@ -280,14 +271,8 @@
   FML_DCHECK(pass->superpass_ == nullptr);
   pass->superpass_ = this;
 
-  bool has_backdrop_filter = pass->backdrop_filter_proc_ != nullptr;
-  if (has_backdrop_filter) {
+  if (pass->backdrop_filter_proc_) {
     backdrop_filter_reads_from_pass_texture_ = true;
-
-    // Since backdrop filters trigger the RenderPass to end and lose all depth
-    // information for opaque draws, this is a hard barrier for the draw order
-    // optimization. Flush all sorted draws accumulated up to this point.
-    draw_order_resolver_.Flush();
   }
   if (pass->blend_mode_ > Entity::kLastPipelineBlendMode) {
     advanced_blend_reads_from_pass_texture_ = true;
@@ -295,12 +280,6 @@
 
   auto subpass_pointer = pass.get();
   elements_.emplace_back(std::move(pass));
-
-  draw_order_resolver_.AddElement(elements_.size() - 1, false);
-  if (has_backdrop_filter) {
-    draw_order_resolver_.Flush();
-  }
-
   return subpass_pointer;
 }
 
@@ -765,55 +744,6 @@
                                ContentContext& renderer,
                                EntityPassClipStack& clip_coverage_stack,
                                Point global_pass_position) const {
-  // Setup advanced blends.
-  if (element_entity.GetBlendMode() > Entity::kLastPipelineBlendMode) {
-    if (renderer.GetDeviceCapabilities().SupportsFramebufferFetch()) {
-      auto src_contents = element_entity.GetContents();
-      auto contents = std::make_shared<FramebufferBlendContents>();
-      contents->SetChildContents(src_contents);
-      contents->SetBlendMode(element_entity.GetBlendMode());
-      element_entity.SetContents(std::move(contents));
-      element_entity.SetBlendMode(BlendMode::kSource);
-    } else {
-      // End the active pass and flush the buffer before rendering
-      // "advanced" blends. Advanced blends work by binding the current
-      // render target texture as an input ("destination"), blending with a
-      // second texture input ("source"), writing the result to an
-      // intermediate texture, and finally copying the data from the
-      // intermediate texture back to the render target texture. And so all
-      // of the commands that have written to the render target texture so
-      // far need to execute before it's bound for blending (otherwise the
-      // blend pass will end up executing before all the previous commands
-      // in the active pass).
-
-      if (!pass_context.EndPass()) {
-        VALIDATION_LOG
-            << "Failed to end the current render pass in order to read "
-               "from "
-               "the backdrop texture and apply an advanced blend.";
-        return false;
-      }
-
-      // Amend an advanced blend filter to the contents, attaching the pass
-      // texture.
-      auto texture = pass_context.GetTexture();
-      if (!texture) {
-        VALIDATION_LOG << "Failed to fetch the color texture in order to "
-                          "apply an advanced blend.";
-        return false;
-      }
-
-      FilterInput::Vector inputs = {
-          FilterInput::Make(texture, element_entity.GetTransform().Invert()),
-          FilterInput::Make(element_entity.GetContents())};
-      auto contents =
-          ColorFilterContents::MakeBlend(element_entity.GetBlendMode(), inputs);
-      contents->SetCoverageHint(element_entity.GetCoverage());
-      element_entity.SetContents(std::move(contents));
-      element_entity.SetBlendMode(BlendMode::kSource);
-    }
-  }
-
   auto result = pass_context.GetRenderPass(pass_depth);
   if (!result.pass) {
     // Failure to produce a render pass should be explained by specific errors
@@ -846,19 +776,15 @@
   }
 
   if (result.just_created) {
-    clip_coverage_stack.ActivateClipReplay();
-  }
-
-  // If there are any pending clips to replay, render any that may affect
-  // the entity we're about to render.
-  while (const EntityPassClipStack::ReplayResult* next_replay_clip =
-             clip_coverage_stack.GetNextReplayResult(element_entity)) {
-    auto& replay_entity = next_replay_clip->entity;
-    SetClipScissor(clip_coverage_stack.CurrentClipCoverage(), *result.pass,
-                   global_pass_position);
-    if (!replay_entity.Render(renderer, *result.pass)) {
-      VALIDATION_LOG << "Failed to render entity for clip replay.";
-      return false;
+    // Restore any clips that were recorded before the backdrop filter was
+    // applied.
+    auto& replay_entities = clip_coverage_stack.GetReplayEntities();
+    for (const auto& replay : replay_entities) {
+      SetClipScissor(clip_coverage_stack.CurrentClipCoverage(), *result.pass,
+                     global_pass_position);
+      if (!replay.entity.Render(renderer, *result.pass)) {
+        VALIDATION_LOG << "Failed to render entity for clip restore.";
+      }
     }
   }
 
@@ -965,87 +891,21 @@
                   renderer, clip_coverage_stack, global_pass_position);
   }
 
-  bool should_collapse_clear_colors =
-      !collapsed_parent_pass &&
-      // Backdrop filters act as a entity before
-      // everything and disrupt the optimization.
-      !backdrop_filter_proc_;
-
-  // Count the number of elements eaten by the clear color optimization. Break
-  // it down in terms of opaque and translucent elements so that we can skip
-  // over these entities when applying the clear color optimization.
-  size_t opaque_clear_entity_count = 0;
-  size_t translucent_clear_entity_count = 0;
-  if (should_collapse_clear_colors) {
-    for (const auto& element : elements_) {
-      if (const Entity* entity = std::get_if<Entity>(&element)) {
-        std::optional<Color> entity_color =
-            entity->AsBackgroundColor(clear_color_size);
-        if (entity_color.has_value()) {
-          if (entity->GetBlendMode() == BlendMode::kSource) {
-            opaque_clear_entity_count++;
-          } else {
-            translucent_clear_entity_count++;
-          }
-          // We've found an entity that replaces the whole background color of
-          // this layer, so continue counting.
-          continue;
-        }
+  bool is_collapsing_clear_colors = !collapsed_parent_pass &&
+                                    // Backdrop filters act as a entity before
+                                    // everything and disrupt the optimization.
+                                    !backdrop_filter_proc_;
+  for (const auto& element : elements_) {
+    // Skip elements that are incorporated into the clear color.
+    if (is_collapsing_clear_colors) {
+      auto [entity_color, _] =
+          ElementAsBackgroundColor(element, clear_color_size);
+      if (entity_color.has_value()) {
+        continue;
       }
-      // We came across an element that doesn't replace the background color of
-      // this layer, so stop counting.
-      break;
+      is_collapsing_clear_colors = false;
     }
-  }
 
-  using ElementCallback = std::function<bool(const Element&)>;
-  using ElementIterator = std::function<bool(const ElementCallback&)>;
-
-  ElementIterator element_iterator;
-
-  if (renderer.GetDeviceCapabilities().SupportsFramebufferFetch()) {
-    element_iterator =
-        [this, &opaque_clear_entity_count,
-         &translucent_clear_entity_count](const ElementCallback& callback) {
-          const auto& sorted_elements = draw_order_resolver_.GetSortedDraws(
-              opaque_clear_entity_count, translucent_clear_entity_count);
-
-          for (const auto& element_ref : sorted_elements) {
-            const Element& element = elements_[element_ref];
-            if (!callback(element)) {
-              return false;
-            }
-          }
-          return true;
-        };
-  } else {
-    // If framebuffer fetch isn't supported, just disable the draw order
-    // optimization. We could technically make it work by flushing each time
-    // we encounter an advanced blend at recording time down the road.
-    element_iterator = [this, &opaque_clear_entity_count,
-                        &translucent_clear_entity_count](
-                           const ElementCallback& callback) {
-      size_t skips = opaque_clear_entity_count + translucent_clear_entity_count;
-      for (const auto& element : elements_) {
-        if (skips > 0) {
-          skips--;
-          continue;
-        }
-        if (!callback(element)) {
-          return false;
-        }
-      }
-      return true;
-    };
-  }
-
-  const auto& render_element = [&, this](Entity& entity) {
-    return RenderElement(entity, clip_height_floor, pass_context, pass_depth,
-                         renderer, clip_coverage_stack, global_pass_position);
-  };
-
-  std::optional<Entity> deferred_entity;
-  bool result = element_iterator([&](const Element& element) {
     EntityResult result =
         GetEntityForElement(element,               // element
                             renderer,              // renderer
@@ -1064,36 +924,70 @@
         // in `GetEntityForElement()`.
         return false;
       case EntityResult::kSkip:
-        return true;
+        continue;
     };
 
-    if (deferred_entity.has_value() &&
-        result.entity.GetBlendMode() != BlendMode::kSource) {
-      if (!render_element(*deferred_entity)) {
-        return false;
-      }
-      deferred_entity.reset();
-    }
+    //--------------------------------------------------------------------------
+    /// Setup advanced blends.
+    ///
 
-    if (IsSubpass(element)) {
-      if (deferred_entity.has_value()) {
-        if (!render_element(*deferred_entity)) {
+    if (result.entity.GetBlendMode() > Entity::kLastPipelineBlendMode) {
+      if (renderer.GetDeviceCapabilities().SupportsFramebufferFetch()) {
+        auto src_contents = result.entity.GetContents();
+        auto contents = std::make_shared<FramebufferBlendContents>();
+        contents->SetChildContents(src_contents);
+        contents->SetBlendMode(result.entity.GetBlendMode());
+        result.entity.SetContents(std::move(contents));
+        result.entity.SetBlendMode(BlendMode::kSource);
+      } else {
+        // End the active pass and flush the buffer before rendering "advanced"
+        // blends. Advanced blends work by binding the current render target
+        // texture as an input ("destination"), blending with a second texture
+        // input ("source"), writing the result to an intermediate texture, and
+        // finally copying the data from the intermediate texture back to the
+        // render target texture. And so all of the commands that have written
+        // to the render target texture so far need to execute before it's bound
+        // for blending (otherwise the blend pass will end up executing before
+        // all the previous commands in the active pass).
+
+        if (!pass_context.EndPass()) {
+          VALIDATION_LOG
+              << "Failed to end the current render pass in order to read from "
+                 "the backdrop texture and apply an advanced blend.";
           return false;
         }
+
+        // Amend an advanced blend filter to the contents, attaching the pass
+        // texture.
+        auto texture = pass_context.GetTexture();
+        if (!texture) {
+          VALIDATION_LOG << "Failed to fetch the color texture in order to "
+                            "apply an advanced blend.";
+          return false;
+        }
+
+        FilterInput::Vector inputs = {
+            FilterInput::Make(texture, result.entity.GetTransform().Invert()),
+            FilterInput::Make(result.entity.GetContents())};
+        auto contents = ColorFilterContents::MakeBlend(
+            result.entity.GetBlendMode(), inputs);
+        contents->SetCoverageHint(result.entity.GetCoverage());
+        result.entity.SetContents(std::move(contents));
+        result.entity.SetBlendMode(BlendMode::kSource);
       }
-      deferred_entity = std::move(result.entity);
-      return true;
     }
 
-    return render_element(result.entity);
-  });
-  if (!result) {
-    return false;
+    //--------------------------------------------------------------------------
+    /// Render the Element.
+    ///
+    if (!RenderElement(result.entity, clip_height_floor, pass_context,
+                       pass_depth, renderer, clip_coverage_stack,
+                       global_pass_position)) {
+      // Specific validation logs are handled in `render_element()`.
+      return false;
+    }
   }
 
-  if (deferred_entity.has_value() && !render_element(*deferred_entity)) {
-    return false;
-  }
   return true;
 }
 
diff --git a/impeller/entity/entity_pass.h b/impeller/entity/entity_pass.h
index 38e5d28..8773160 100644
--- a/impeller/entity/entity_pass.h
+++ b/impeller/entity/entity_pass.h
@@ -13,7 +13,6 @@
 
 #include "impeller/entity/contents/contents.h"
 #include "impeller/entity/contents/filters/filter_contents.h"
-#include "impeller/entity/draw_order_resolver.h"
 #include "impeller/entity/entity.h"
 #include "impeller/entity/entity_pass_clip_stack.h"
 #include "impeller/entity/entity_pass_delegate.h"
@@ -54,8 +53,6 @@
   /// `GetEntityForElement()`.
   using Element = std::variant<Entity, std::unique_ptr<EntityPass>>;
 
-  static bool IsSubpass(const Element& element);
-
   using BackdropFilterProc = std::function<std::shared_ptr<FilterContents>(
       FilterInput::Ref,
       const Matrix& effect_transform,
@@ -217,7 +214,8 @@
       kSkip,
     };
 
-    /// @brief  The resulting entity that should be rendered.
+    /// @brief  The resulting entity that should be rendered. If `std::nullopt`,
+    ///         there is nothing to render.
     Entity entity;
     /// @brief  This is set to `false` if there was an unexpected rendering
     ///         error while resolving the Entity.
@@ -318,12 +316,10 @@
   /// evaluated and recorded to an `EntityPassTarget` by the `OnRender` method.
   std::vector<Element> elements_;
 
-  DrawOrderResolver draw_order_resolver_;
-
   /// The stack of currently active clips (during Aiks recording time). Each
-  /// entry is an index into the `elements_` list. The depth value of a clip
-  /// is the max of all the entities it affects, so assignment of the depth
-  /// value is deferred until clip restore or end of the EntityPass.
+  /// entry is an index into the `elements_` list. The depth value of a clip is
+  /// the max of all the entities it affects, so assignment of the depth value
+  /// is deferred until clip restore or end of the EntityPass.
   std::vector<size_t> active_clips_;
 
   EntityPass* superpass_ = nullptr;
@@ -342,8 +338,8 @@
   ///   1. An entity with an "advanced blend" is added to the pass.
   ///   2. A subpass with a backdrop filter is added to the pass.
   /// These are tracked as separate values because we may ignore
-  /// `blend_reads_from_pass_texture_` if the device supports framebuffer
-  /// based advanced blends.
+  /// `blend_reads_from_pass_texture_` if the device supports framebuffer based
+  /// advanced blends.
   bool advanced_blend_reads_from_pass_texture_ = false;
   bool backdrop_filter_reads_from_pass_texture_ = false;
 
diff --git a/impeller/entity/entity_pass_clip_stack.cc b/impeller/entity/entity_pass_clip_stack.cc
index 1cef7a1..eab0565 100644
--- a/impeller/entity/entity_pass_clip_stack.cc
+++ b/impeller/entity/entity_pass_clip_stack.cc
@@ -3,8 +3,6 @@
 // found in the LICENSE file.
 
 #include "impeller/entity/entity_pass_clip_stack.h"
-
-#include "flutter/fml/logging.h"
 #include "impeller/entity/contents/clip_contents.h"
 #include "impeller/entity/entity.h"
 
@@ -39,12 +37,10 @@
                                 .clip_height = clip_height},
           },
   });
-  next_replay_index_ = 0;
 }
 
 void EntityPassClipStack::PopSubpass() {
   subpass_state_.pop_back();
-  next_replay_index_ = subpass_state_.back().rendered_clip_entities.size();
 }
 
 const std::vector<ClipCoverageLayer>
@@ -142,22 +138,12 @@
     case Contents::ClipCoverage::Type::kNoChange:
       return;
     case Contents::ClipCoverage::Type::kAppend:
-      FML_DCHECK(next_replay_index_ ==
-                 subpass_state.rendered_clip_entities.size())
-          << "Not all clips have been replayed before appending new clip.";
       subpass_state.rendered_clip_entities.push_back(
           {.entity = entity.Clone(), .clip_coverage = clip_coverage});
-      next_replay_index_++;
       break;
     case Contents::ClipCoverage::Type::kRestore:
-      FML_DCHECK(next_replay_index_ <=
-                 subpass_state.rendered_clip_entities.size());
       if (!subpass_state.rendered_clip_entities.empty()) {
         subpass_state.rendered_clip_entities.pop_back();
-
-        if (next_replay_index_ > subpass_state.rendered_clip_entities.size()) {
-          next_replay_index_ = subpass_state.rendered_clip_entities.size();
-        }
       }
       break;
   }
@@ -173,27 +159,4 @@
   return subpass_state_.back().rendered_clip_entities;
 }
 
-void EntityPassClipStack::ActivateClipReplay() {
-  next_replay_index_ = 0;
-}
-
-const EntityPassClipStack::ReplayResult*
-EntityPassClipStack::GetNextReplayResult(const Entity& entity) {
-  if (next_replay_index_ >=
-      subpass_state_.back().rendered_clip_entities.size()) {
-    // No clips need to be replayed.
-    return nullptr;
-  }
-  ReplayResult* next_replay =
-      &subpass_state_.back().rendered_clip_entities[next_replay_index_];
-  if (next_replay->entity.GetClipDepth() < entity.GetClipDepth()) {
-    // The next replay clip doesn't affect the current entity, so don't replay
-    // it yet.
-    return nullptr;
-  }
-
-  next_replay_index_++;
-  return next_replay;
-}
-
 }  // namespace impeller
diff --git a/impeller/entity/entity_pass_clip_stack.h b/impeller/entity/entity_pass_clip_stack.h
index df230fd..de1f1c9 100644
--- a/impeller/entity/entity_pass_clip_stack.h
+++ b/impeller/entity/entity_pass_clip_stack.h
@@ -62,14 +62,9 @@
                     Contents::ClipCoverage::Type type,
                     std::optional<Rect> clip_coverage);
 
+  // Visible for testing.
   const std::vector<ReplayResult>& GetReplayEntities() const;
 
-  void ActivateClipReplay();
-
-  /// @brief Returns the next Entity that should be replayed. If there are no
-  ///        enities to replay, then nullptr is returned.
-  const ReplayResult* GetNextReplayResult(const Entity& entity);
-
   // Visible for testing.
   const std::vector<ClipCoverageLayer> GetClipCoverageLayers() const;
 
@@ -82,7 +77,6 @@
   SubpassState& GetCurrentSubpassState();
 
   std::vector<SubpassState> subpass_state_;
-  size_t next_replay_index_ = 0;
 };
 
 }  // namespace impeller