// 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 "flatland_external_view_embedder.h"
#include <algorithm>
#include <cstdint>

#include "flutter/fml/trace_event.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkSurface.h"

namespace flutter_runner {
namespace {

// Since the flatland hit-region can be transformed (rotated, scaled or
// translated), we must ensure that the size of the hit-region will not cause
// overflows on operations (like FLT_MAX would).
constexpr float kMaxHitRegionSize = 1'000'000.f;

void AttachClipTransformChild(
    FlatlandConnection* flatland,
    FlatlandExternalViewEmbedder::ClipTransform* parent_clip_transform,
    const fuchsia::ui::composition::TransformId& child_transform_id) {
  flatland->flatland()->AddChild(parent_clip_transform->transform_id,
                                 child_transform_id);
  parent_clip_transform->children.push_back(child_transform_id);
}

void DetachClipTransformChildren(
    FlatlandConnection* flatland,
    FlatlandExternalViewEmbedder::ClipTransform* clip_transform) {
  for (auto& child : clip_transform->children) {
    flatland->flatland()->RemoveChild(clip_transform->transform_id, child);
  }
  clip_transform->children.clear();
}

}  // namespace

FlatlandExternalViewEmbedder::FlatlandExternalViewEmbedder(
    fuchsia::ui::views::ViewCreationToken view_creation_token,
    fuchsia::ui::views::ViewIdentityOnCreation view_identity,
    fuchsia::ui::composition::ViewBoundProtocols view_protocols,
    fidl::InterfaceRequest<fuchsia::ui::composition::ParentViewportWatcher>
        parent_viewport_watcher_request,
    std::shared_ptr<FlatlandConnection> flatland,
    std::shared_ptr<SurfaceProducer> surface_producer,
    bool intercept_all_input)
    : flatland_(flatland), surface_producer_(surface_producer) {
  flatland_->flatland()->CreateView2(
      std::move(view_creation_token), std::move(view_identity),
      std::move(view_protocols), std::move(parent_viewport_watcher_request));

  root_transform_id_ = flatland_->NextTransformId();
  flatland_->flatland()->CreateTransform(root_transform_id_);
  flatland_->flatland()->SetRootTransform(root_transform_id_);

  if (intercept_all_input) {
    input_interceptor_transform_ = flatland_->NextTransformId();
    flatland_->flatland()->CreateTransform(*input_interceptor_transform_);

    flatland_->flatland()->AddChild(root_transform_id_,
                                    *input_interceptor_transform_);
    child_transforms_.emplace_back(*input_interceptor_transform_);

    // Attach full-screen hit testing shield. Note that since the hit-region
    // may be transformed (translated, rotated), we do not want to set
    // width/height to FLT_MAX. This will cause a numeric overflow.
    flatland_->flatland()->SetHitRegions(
        *input_interceptor_transform_,
        {{{0, 0, kMaxHitRegionSize, kMaxHitRegionSize},
          fuchsia::ui::composition::HitTestInteraction::
              SEMANTICALLY_INVISIBLE}});
  }
}

FlatlandExternalViewEmbedder::~FlatlandExternalViewEmbedder() = default;

SkCanvas* FlatlandExternalViewEmbedder::GetRootCanvas() {
  auto found = frame_layers_.find(kRootLayerId);
  if (found == frame_layers_.end()) {
    FML_LOG(WARNING)
        << "No root canvas could be found. This is extremely unlikely and "
           "indicates that the external view embedder did not receive the "
           "notification to begin the frame.";
    return nullptr;
  }

  return found->second.canvas_spy->GetSpyingCanvas();
}

std::vector<SkCanvas*> FlatlandExternalViewEmbedder::GetCurrentCanvases() {
  std::vector<SkCanvas*> canvases;
  for (const auto& layer : frame_layers_) {
    // This method (for legacy reasons) expects non-root current canvases.
    if (layer.first.has_value()) {
      canvases.push_back(layer.second.canvas_spy->GetSpyingCanvas());
    }
  }
  return canvases;
}

std::vector<flutter::DisplayListBuilder*>
FlatlandExternalViewEmbedder::GetCurrentBuilders() {
  return std::vector<flutter::DisplayListBuilder*>();
}

void FlatlandExternalViewEmbedder::PrerollCompositeEmbeddedView(
    int view_id,
    std::unique_ptr<flutter::EmbeddedViewParams> params) {
  zx_handle_t handle = static_cast<zx_handle_t>(view_id);
  FML_CHECK(frame_layers_.count(handle) == 0);

  frame_layers_.emplace(std::make_pair(
      EmbedderLayerId{handle},
      EmbedderLayer(frame_size_, *params, flutter::RTreeFactory())));
  frame_composition_order_.push_back(handle);
}

flutter::EmbedderPaintContext
FlatlandExternalViewEmbedder::CompositeEmbeddedView(int view_id) {
  zx_handle_t handle = static_cast<zx_handle_t>(view_id);
  auto found = frame_layers_.find(handle);
  FML_CHECK(found != frame_layers_.end());

  return {found->second.canvas_spy->GetSpyingCanvas(), nullptr};
}

flutter::PostPrerollResult FlatlandExternalViewEmbedder::PostPrerollAction(
    fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
  return flutter::PostPrerollResult::kSuccess;
}

void FlatlandExternalViewEmbedder::BeginFrame(
    SkISize frame_size,
    GrDirectContext* context,
    double device_pixel_ratio,
    fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
  TRACE_EVENT0("flutter", "FlatlandExternalViewEmbedder::BeginFrame");

  // Reset for new frame.
  Reset();
  frame_size_ = frame_size;
  frame_dpr_ = device_pixel_ratio;

  // Create the root layer.
  frame_layers_.emplace(std::make_pair(
      kRootLayerId,
      EmbedderLayer(frame_size, std::nullopt, flutter::RTreeFactory())));
  frame_composition_order_.push_back(kRootLayerId);
}

void FlatlandExternalViewEmbedder::EndFrame(
    bool should_resubmit_frame,
    fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
  TRACE_EVENT0("flutter", "FlatlandExternalViewEmbedder::EndFrame");
}

void FlatlandExternalViewEmbedder::SubmitFrame(
    GrDirectContext* context,
    std::unique_ptr<flutter::SurfaceFrame> frame) {
  TRACE_EVENT0("flutter", "FlatlandExternalViewEmbedder::SubmitFrame");
  std::vector<std::unique_ptr<SurfaceProducerSurface>> frame_surfaces;
  std::unordered_map<EmbedderLayerId, size_t> frame_surface_indices;

  // Create surfaces for the frame and associate them with layer IDs.
  {
    TRACE_EVENT0("flutter", "CreateSurfaces");

    for (const auto& layer : frame_layers_) {
      if (!layer.second.canvas_spy->DidDrawIntoCanvas()) {
        continue;
      }

      auto surface =
          surface_producer_->ProduceSurface(layer.second.surface_size);
      if (!surface) {
        const std::string layer_id_str =
            layer.first.has_value() ? std::to_string(layer.first.value())
                                    : "Background";
        FML_LOG(ERROR) << "Failed to create surface for layer " << layer_id_str
                       << "; size (" << layer.second.surface_size.width()
                       << ", " << layer.second.surface_size.height() << ")";
        FML_DCHECK(false);
        continue;
      }

      // If we receive an unitialized surface, we need to first create flatland
      // resource.
      if (surface->GetImageId() == 0) {
        auto image_id = flatland_->NextContentId().value;
        const auto& size = surface->GetSize();
        fuchsia::ui::composition::ImageProperties image_properties;
        image_properties.set_size({static_cast<uint32_t>(size.width()),
                                   static_cast<uint32_t>(size.height())});
        flatland_->flatland()->CreateImage(
            {image_id}, surface->GetBufferCollectionImportToken(), 0,
            std::move(image_properties));

        surface->SetImageId(image_id);
        surface->SetReleaseImageCallback([flatland = flatland_, image_id]() {
          flatland->flatland()->ReleaseImage({image_id});
        });
      }

      // Enqueue fences for the next present.
      flatland_->EnqueueAcquireFence(surface->GetAcquireFence());
      flatland_->EnqueueReleaseFence(surface->GetReleaseFence());

      frame_surface_indices.emplace(
          std::make_pair(layer.first, frame_surfaces.size()));
      frame_surfaces.emplace_back(std::move(surface));
    }
  }

  // Finish recording SkPictures.
  {
    TRACE_EVENT0("flutter", "FinishRecordingPictures");

    for (const auto& surface_index : frame_surface_indices) {
      const auto& layer = frame_layers_.find(surface_index.first);
      FML_CHECK(layer != frame_layers_.end());
      layer->second.picture =
          layer->second.recorder->finishRecordingAsPicture();
      FML_CHECK(layer->second.picture != nullptr);
    }
  }

  // Submit layers and platform views to Scenic in composition order.
  {
    TRACE_EVENT0("flutter", "SubmitLayers");

    // First re-scale everything according to the DPR.
    const float inv_dpr = 1.0f / frame_dpr_;
    flatland_->flatland()->SetScale(root_transform_id_, {inv_dpr, inv_dpr});

    size_t flatland_layer_index = 0;
    for (const auto& layer_id : frame_composition_order_) {
      const auto& layer = frame_layers_.find(layer_id);
      FML_CHECK(layer != frame_layers_.end());

      // Draw the PlatformView associated with each layer first.
      if (layer_id.has_value()) {
        FML_CHECK(layer->second.embedded_view_params.has_value());
        auto& view_params = layer->second.embedded_view_params.value();

        // Get the FlatlandView structure corresponding to the platform view.
        auto found = flatland_views_.find(layer_id.value());
        FML_CHECK(found != flatland_views_.end())
            << "No FlatlandView for layer_id = " << layer_id.value()
            << ". This typically indicates that the Dart code in "
               "Fuchsia's fuchsia_scenic_flutter library failed to create "
               "the platform view, leading to a crash later down the road in "
               "the Flutter Engine code that tries to find that platform view. "
               "Check the Flutter Framework for changes to PlatformView that "
               "might have caused a regression.";
        auto& viewport = found->second;

        // Compute mutators, and size for the platform view.
        const ViewMutators view_mutators =
            ParseMutatorStack(view_params.mutatorsStack());
        const SkSize view_size = view_params.sizePoints();
        FML_CHECK(view_mutators.total_transform ==
                  view_params.transformMatrix());

        if (viewport.pending_create_viewport_callback) {
          if (view_size.fWidth && view_size.fHeight) {
            viewport.pending_create_viewport_callback(
                view_size, viewport.pending_occlusion_hint);
            viewport.size = view_size;
            viewport.occlusion_hint = viewport.pending_occlusion_hint;
          } else {
            FML_DLOG(WARNING)
                << "Failed to create viewport because width or height is zero.";
          }
        }

        // Set transform for the viewport.
        if (view_mutators.transform != viewport.mutators.transform) {
          flatland_->flatland()->SetTranslation(
              viewport.transform_id,
              {static_cast<int32_t>(view_mutators.transform.getTranslateX()),
               static_cast<int32_t>(view_mutators.transform.getTranslateY())});
          flatland_->flatland()->SetScale(
              viewport.transform_id, {view_mutators.transform.getScaleX(),
                                      view_mutators.transform.getScaleY()});
          viewport.mutators.transform = view_mutators.transform;
        }

        // Set clip regions.
        if (view_mutators.clips != viewport.mutators.clips) {
          // Expand the clip_transforms array to fit any new transforms.
          while (viewport.clip_transforms.size() < view_mutators.clips.size()) {
            ClipTransform clip_transform;
            clip_transform.transform_id = flatland_->NextTransformId();
            flatland_->flatland()->CreateTransform(clip_transform.transform_id);
            viewport.clip_transforms.emplace_back(std::move(clip_transform));
          }
          FML_CHECK(viewport.clip_transforms.size() >=
                    view_mutators.clips.size());

          // Adjust and re-parent all clip transforms.
          for (auto& clip_transform : viewport.clip_transforms) {
            DetachClipTransformChildren(flatland_.get(), &clip_transform);
          }

          for (size_t c = 0; c < view_mutators.clips.size(); c++) {
            const SkMatrix& clip_matrix = view_mutators.clips[c].transform;
            const SkRect& clip_rect = view_mutators.clips[c].rect;

            flatland_->flatland()->SetTranslation(
                viewport.clip_transforms[c].transform_id,
                {static_cast<int32_t>(clip_matrix.getTranslateX()),
                 static_cast<int32_t>(clip_matrix.getTranslateY())});
            flatland_->flatland()->SetScale(
                viewport.clip_transforms[c].transform_id,
                {clip_matrix.getScaleX(), clip_matrix.getScaleY()});
            fuchsia::math::Rect rect = {
                static_cast<int32_t>(clip_rect.x()),
                static_cast<int32_t>(clip_rect.y()),
                static_cast<int32_t>(clip_rect.width()),
                static_cast<int32_t>(clip_rect.height())};
            flatland_->flatland()->SetClipBoundary(
                viewport.clip_transforms[c].transform_id,
                std::make_unique<fuchsia::math::Rect>(std::move(rect)));

            const auto child_transform_id =
                c != (view_mutators.clips.size() - 1)
                    ? viewport.clip_transforms[c + 1].transform_id
                    : viewport.transform_id;
            AttachClipTransformChild(flatland_.get(),
                                     &(viewport.clip_transforms[c]),
                                     child_transform_id);
          }
          viewport.mutators.clips = view_mutators.clips;
        }

        // Set opacity.
        if (view_mutators.opacity != viewport.mutators.opacity) {
          flatland_->flatland()->SetOpacity(viewport.transform_id,
                                            view_mutators.opacity);
          viewport.mutators.opacity = view_mutators.opacity;
        }

        // Set size and occlusion hint.
        if (view_size != viewport.size ||
            viewport.pending_occlusion_hint != viewport.occlusion_hint) {
          fuchsia::ui::composition::ViewportProperties properties;
          properties.set_logical_size(
              {static_cast<uint32_t>(view_size.fWidth),
               static_cast<uint32_t>(view_size.fHeight)});
          properties.set_inset(
              {static_cast<int32_t>(viewport.pending_occlusion_hint.fTop),
               static_cast<int32_t>(viewport.pending_occlusion_hint.fRight),
               static_cast<int32_t>(viewport.pending_occlusion_hint.fBottom),
               static_cast<int32_t>(viewport.pending_occlusion_hint.fLeft)});
          flatland_->flatland()->SetViewportProperties(viewport.viewport_id,
                                                       std::move(properties));
          viewport.size = view_size;
          viewport.occlusion_hint = viewport.pending_occlusion_hint;
        }

        // Attach the FlatlandView to the main scene graph.
        const auto main_child_transform =
            viewport.mutators.clips.empty()
                ? viewport.transform_id
                : viewport.clip_transforms[0].transform_id;
        flatland_->flatland()->AddChild(root_transform_id_,
                                        main_child_transform);
        child_transforms_.emplace_back(main_child_transform);
      }

      // Acquire the surface associated with the layer.
      SurfaceProducerSurface* surface_for_layer = nullptr;
      if (layer->second.canvas_spy->DidDrawIntoCanvas()) {
        const auto& surface_index = frame_surface_indices.find(layer_id);
        if (surface_index != frame_surface_indices.end()) {
          FML_CHECK(surface_index->second < frame_surfaces.size());
          surface_for_layer = frame_surfaces[surface_index->second].get();
          FML_CHECK(surface_for_layer != nullptr);
        } else {
          const std::string layer_id_str =
              layer_id.has_value() ? std::to_string(layer_id.value())
                                   : "Background";
          FML_LOG(ERROR) << "Missing surface for layer " << layer_id_str
                         << "; skipping scene graph add of layer.";
          FML_DCHECK(false);
        }
      }

      // Draw the layer if we acquired a surface for it successfully.
      if (surface_for_layer != nullptr) {
        // Create a new layer if needed for the surface.
        FML_CHECK(flatland_layer_index <= flatland_layers_.size());
        if (flatland_layer_index == flatland_layers_.size()) {
          FlatlandLayer new_layer{.transform_id = flatland_->NextTransformId()};
          flatland_->flatland()->CreateTransform(new_layer.transform_id);
          flatland_layers_.emplace_back(std::move(new_layer));
        }

        // Update the image content and set size.
        flatland_->flatland()->SetContent(
            flatland_layers_[flatland_layer_index].transform_id,
            {surface_for_layer->GetImageId()});
        flatland_->flatland()->SetImageDestinationSize(
            {surface_for_layer->GetImageId()},
            {static_cast<uint32_t>(surface_for_layer->GetSize().width()),
             static_cast<uint32_t>(surface_for_layer->GetSize().height())});

        // Flutter Embedder lacks an API to detect if a layer has alpha or not.
        // For now, we assume any layer beyond the first has alpha.
        flatland_->flatland()->SetImageBlendingFunction(
            {surface_for_layer->GetImageId()},
            flatland_layer_index == 0
                ? fuchsia::ui::composition::BlendMode::SRC
                : fuchsia::ui::composition::BlendMode::SRC_OVER);

        // Set hit regions for this layer; these hit regions correspond to the
        // portions of the layer on which skia drew content.
        {
          FML_CHECK(layer->second.rtree);
          std::list<SkRect> intersection_rects =
              layer->second.rtree->searchNonOverlappingDrawnRects(
                  SkRect::Make(layer->second.surface_size));

          std::vector<fuchsia::ui::composition::HitRegion> hit_regions;
          for (const SkRect& rect : intersection_rects) {
            hit_regions.emplace_back();
            auto& new_hit_region = hit_regions.back();
            new_hit_region.region.x = rect.x();
            new_hit_region.region.y = rect.y();
            new_hit_region.region.width = rect.width();
            new_hit_region.region.height = rect.height();
            new_hit_region.hit_test =
                fuchsia::ui::composition::HitTestInteraction::DEFAULT;
          }

          flatland_->flatland()->SetHitRegions(
              flatland_layers_[flatland_layer_index].transform_id,
              std::move(hit_regions));
        }

        // Attach the FlatlandLayer to the main scene graph.
        flatland_->flatland()->AddChild(
            root_transform_id_,
            flatland_layers_[flatland_layer_index].transform_id);
        child_transforms_.emplace_back(
            flatland_layers_[flatland_layer_index].transform_id);
      }

      // Reset for the next pass:
      flatland_layer_index++;
    }

    // Set up the input interceptor at the top of the
    // scene, if applicable.  It will capture all input, and any unwanted input
    // will be reinjected into embedded views.
    if (input_interceptor_transform_.has_value()) {
      flatland_->flatland()->AddChild(root_transform_id_,
                                      *input_interceptor_transform_);
      child_transforms_.emplace_back(*input_interceptor_transform_);
    }
  }

  // Present the session to Scenic, along with surface acquire/release fences.
  {
    TRACE_EVENT0("flutter", "SessionPresent");

    flatland_->Present();
  }

  // Render the recorded SkPictures into the surfaces.
  {
    TRACE_EVENT0("flutter", "RasterizeSurfaces");

    for (const auto& surface_index : frame_surface_indices) {
      TRACE_EVENT0("flutter", "RasterizeSurface");

      FML_CHECK(surface_index.second < frame_surfaces.size());
      SurfaceProducerSurface* surface =
          frame_surfaces[surface_index.second].get();
      FML_CHECK(surface != nullptr);

      sk_sp<SkSurface> sk_surface = surface->GetSkiaSurface();
      FML_CHECK(sk_surface != nullptr);
      FML_CHECK(SkISize::Make(sk_surface->width(), sk_surface->height()) ==
                frame_size_);
      SkCanvas* canvas = sk_surface->getCanvas();
      FML_CHECK(canvas != nullptr);

      const auto& layer = frame_layers_.find(surface_index.first);
      FML_CHECK(layer != frame_layers_.end());

      canvas->setMatrix(SkMatrix::I());
      canvas->clear(SK_ColorTRANSPARENT);
      canvas->drawPicture(layer->second.picture);
      canvas->flush();
    }
  }

  // Flush deferred Skia work and inform Scenic that render targets are ready.
  {
    TRACE_EVENT0("flutter", "PresentSurfaces");

    surface_producer_->SubmitSurfaces(std::move(frame_surfaces));
  }

  // Submit the underlying render-backend-specific frame for processing.
  frame->Submit();
}

void FlatlandExternalViewEmbedder::CreateView(
    int64_t view_id,
    ViewCallback on_view_created,
    FlatlandViewCreatedCallback on_view_bound) {
  FML_CHECK(flatland_views_.find(view_id) == flatland_views_.end());

  const auto transform_id = flatland_->NextTransformId();
  const auto viewport_id = flatland_->NextContentId();
  FlatlandView new_view = {.transform_id = transform_id,
                           .viewport_id = viewport_id};
  flatland_->flatland()->CreateTransform(new_view.transform_id);
  fuchsia::ui::composition::ChildViewWatcherHandle child_view_watcher;
  new_view.pending_create_viewport_callback =
      [this, transform_id, viewport_id, view_id,
       child_view_watcher_request = child_view_watcher.NewRequest()](
          const SkSize& size, const SkRect& inset) mutable {
        fuchsia::ui::composition::ViewportProperties properties;
        properties.set_logical_size({static_cast<uint32_t>(size.fWidth),
                                     static_cast<uint32_t>(size.fHeight)});
        properties.set_inset({static_cast<int32_t>(inset.fTop),
                              static_cast<int32_t>(inset.fRight),
                              static_cast<int32_t>(inset.fBottom),
                              static_cast<int32_t>(inset.fLeft)});
        flatland_->flatland()->CreateViewport(
            viewport_id, {zx::channel((zx_handle_t)view_id)},
            std::move(properties), std::move(child_view_watcher_request));
        flatland_->flatland()->SetContent(transform_id, viewport_id);
      };

  on_view_created();
  on_view_bound(new_view.viewport_id, std::move(child_view_watcher));
  flatland_views_.emplace(std::make_pair(view_id, std::move(new_view)));
}

void FlatlandExternalViewEmbedder::DestroyView(
    int64_t view_id,
    FlatlandViewIdCallback on_view_unbound) {
  auto flatland_view = flatland_views_.find(view_id);
  FML_CHECK(flatland_view != flatland_views_.end());

  auto viewport_id = flatland_view->second.viewport_id;
  auto transform_id = flatland_view->second.transform_id;
  auto& clip_transforms = flatland_view->second.clip_transforms;
  if (!flatland_view->second.pending_create_viewport_callback) {
    flatland_->flatland()->ReleaseViewport(viewport_id, [](auto) {});
  }
  auto itr = std::find_if(
      child_transforms_.begin(), child_transforms_.end(),
      [transform_id,
       &clip_transforms](fuchsia::ui::composition::TransformId id) {
        return id.value == transform_id.value ||
               (!clip_transforms.empty() &&
                (id.value == clip_transforms[0].transform_id.value));
      });
  if (itr != child_transforms_.end()) {
    flatland_->flatland()->RemoveChild(root_transform_id_, *itr);
    child_transforms_.erase(itr);
  }
  for (auto& clip_transform : clip_transforms) {
    DetachClipTransformChildren(flatland_.get(), &clip_transform);
  }
  flatland_->flatland()->ReleaseTransform(transform_id);
  for (auto& clip_transform : clip_transforms) {
    flatland_->flatland()->ReleaseTransform(clip_transform.transform_id);
  }

  flatland_views_.erase(flatland_view);
  on_view_unbound(viewport_id);
}

void FlatlandExternalViewEmbedder::SetViewProperties(
    int64_t view_id,
    const SkRect& occlusion_hint,
    bool hit_testable,
    bool focusable) {
  auto found = flatland_views_.find(view_id);
  FML_CHECK(found != flatland_views_.end());

  // Note that pending_create_viewport_callback might not have run at this
  // point.
  auto& viewport = found->second;
  viewport.pending_occlusion_hint = occlusion_hint;
}

void FlatlandExternalViewEmbedder::Reset() {
  frame_layers_.clear();
  frame_composition_order_.clear();
  frame_size_ = SkISize::Make(0, 0);
  frame_dpr_ = 1.f;

  // Clear all children from root.
  for (const auto& transform : child_transforms_) {
    flatland_->flatland()->RemoveChild(root_transform_id_, transform);
  }
  child_transforms_.clear();

  // Clear images on all layers so they aren't cached unnecessarily.
  for (const auto& layer : flatland_layers_) {
    flatland_->flatland()->SetContent(layer.transform_id, {0});
  }
}

FlatlandExternalViewEmbedder::ViewMutators
FlatlandExternalViewEmbedder::ParseMutatorStack(
    const flutter::MutatorsStack& mutators_stack) {
  ViewMutators mutators;
  SkMatrix total_transform = SkMatrix::I();
  SkMatrix transform_accumulator = SkMatrix::I();

  for (auto i = mutators_stack.Begin(); i != mutators_stack.End(); ++i) {
    const auto& mutator = *i;
    switch (mutator->GetType()) {
      case flutter::MutatorType::kOpacity: {
        mutators.opacity *= std::clamp(mutator->GetAlphaFloat(), 0.f, 1.f);
      } break;
      case flutter::MutatorType::kTransform: {
        total_transform.preConcat(mutator->GetMatrix());
        transform_accumulator.preConcat(mutator->GetMatrix());
      } break;
      case flutter::MutatorType::kClipRect: {
        mutators.clips.emplace_back(TransformedClip{
            .transform = transform_accumulator,
            .rect = mutator->GetRect(),
        });
        transform_accumulator = SkMatrix::I();
      } break;
      case flutter::MutatorType::kClipRRect: {
        mutators.clips.emplace_back(TransformedClip{
            .transform = transform_accumulator,
            .rect = mutator->GetRRect().getBounds(),
        });
        transform_accumulator = SkMatrix::I();
      } break;
      case flutter::MutatorType::kClipPath: {
        mutators.clips.emplace_back(TransformedClip{
            .transform = transform_accumulator,
            .rect = mutator->GetPath().getBounds(),
        });
        transform_accumulator = SkMatrix::I();
      } break;
      default: {
        break;
      }
    }
  }
  mutators.total_transform = total_transform;
  mutators.transform = transform_accumulator;
  mutators.opacity = std::clamp(mutators.opacity, 0.f, 1.f);

  return mutators;
}

}  // namespace flutter_runner
