// 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 "gfx_external_view_embedder.h"

#include <lib/ui/scenic/cpp/commands.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>
#include <zircon/types.h>

#include <algorithm>  // For std::clamp

#include "flutter/fml/logging.h"
#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 {

ViewMutators 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;
}

std::vector<fuchsia::ui::gfx::Plane3> ClipPlanesFromRect(SkRect rect) {
  // We will generate 4 oriented planes, one for each edge of the bounding rect.
  std::vector<fuchsia::ui::gfx::Plane3> clip_planes;
  clip_planes.resize(4);

  // Top plane.
  clip_planes[0].dist = rect.top();
  clip_planes[0].dir.x = 0.f;
  clip_planes[0].dir.y = 1.f;
  clip_planes[0].dir.z = 0.f;

  // Bottom plane.
  clip_planes[1].dist = -rect.bottom();
  clip_planes[1].dir.x = 0.f;
  clip_planes[1].dir.y = -1.f;
  clip_planes[1].dir.z = 0.f;

  // Left plane.
  clip_planes[2].dist = rect.left();
  clip_planes[2].dir.x = 1.f;
  clip_planes[2].dir.y = 0.f;
  clip_planes[2].dir.z = 0.f;

  // Right plane.
  clip_planes[3].dist = -rect.right();
  clip_planes[3].dir.x = -1.f;
  clip_planes[3].dir.y = 0.f;
  clip_planes[3].dir.z = 0.f;

  return clip_planes;
}

}  // namespace

GfxExternalViewEmbedder::GfxExternalViewEmbedder(
    std::string debug_label,
    fuchsia::ui::views::ViewToken view_token,
    scenic::ViewRefPair view_ref_pair,
    std::shared_ptr<GfxSessionConnection> session,
    std::shared_ptr<SurfaceProducer> surface_producer,
    bool intercept_all_input)
    : session_(session),
      surface_producer_(surface_producer),
      root_view_(session_->get(),
                 std::move(view_token),
                 std::move(view_ref_pair.control_ref),
                 std::move(view_ref_pair.view_ref),
                 debug_label),
      metrics_node_(session_->get()),
      layer_tree_node_(session_->get()) {
  layer_tree_node_.SetLabel("Flutter::LayerTree");
  metrics_node_.SetLabel("Flutter::MetricsWatcher");
  metrics_node_.SetEventMask(fuchsia::ui::gfx::kMetricsEventMask);
  metrics_node_.AddChild(layer_tree_node_);
  root_view_.AddChild(metrics_node_);

  // 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 (intercept_all_input) {
    input_interceptor_node_.emplace(session_->get());
    input_interceptor_node_->SetLabel("Flutter::InputInterceptor");
    input_interceptor_node_->SetHitTestBehavior(
        fuchsia::ui::gfx::HitTestBehavior::kDefault);
    input_interceptor_node_->SetSemanticVisibility(false);

    metrics_node_.AddChild(input_interceptor_node_.value());
  }

  session_->Present();
}

GfxExternalViewEmbedder::~GfxExternalViewEmbedder() = default;

flutter::DlCanvas* GfxExternalViewEmbedder::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();
}

void GfxExternalViewEmbedder::PrerollCompositeEmbeddedView(
    int64_t 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::DlCanvas* GfxExternalViewEmbedder::CompositeEmbeddedView(
    int64_t 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();
}

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

void GfxExternalViewEmbedder::BeginFrame(
    SkISize frame_size,
    GrDirectContext* context,
    double device_pixel_ratio,
    fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
  TRACE_EVENT0("flutter", "GfxExternalViewEmbedder::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);

  // Set up the input interceptor at the top of the scene, if applicable.
  if (input_interceptor_node_.has_value()) {
    const uint64_t rect_hash =
        (static_cast<uint64_t>(frame_size_.width()) << 32) +
        frame_size_.height();

    // Create a new rect if needed for the interceptor.
    auto found_rect = scenic_interceptor_rects_.find(rect_hash);
    if (found_rect == scenic_interceptor_rects_.end()) {
      auto [emplaced_rect, success] =
          scenic_interceptor_rects_.emplace(std::make_pair(
              rect_hash, scenic::Rectangle(session_->get(), frame_size_.width(),
                                           frame_size_.height())));
      FML_CHECK(success);

      found_rect = std::move(emplaced_rect);
    }

    // TODO(fxb/): Don't hardcode elevation.
    input_interceptor_node_->SetTranslation(
        frame_size.width() * 0.5f, frame_size.height() * 0.5f,
        -kScenicElevationForInputInterceptor);
    input_interceptor_node_->SetShape(found_rect->second);
  }
}

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

void GfxExternalViewEmbedder::SubmitFrame(
    GrDirectContext* context,
    std::unique_ptr<flutter::SurfaceFrame> frame) {
  TRACE_EVENT0("flutter", "GfxExternalViewEmbedder::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;
      }

      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");

    std::unordered_map<uint64_t, size_t> scenic_rect_indices;
    size_t scenic_layer_index = 0;
    float embedded_views_height = 0.0f;

    // First re-scale everything according to the DPR.
    const float inv_dpr = 1.0f / frame_dpr_;
    layer_tree_node_.SetScale(inv_dpr, inv_dpr, 1.0f);

    bool first_layer = true;
    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 ScenicView structure corresponding to the platform view.
        auto found = scenic_views_.find(layer_id.value());
        FML_CHECK(found != scenic_views_.end());
        auto& view_holder = found->second;

        // Compute mutators, size, and elevation for the platform view.
        const ViewMutators view_mutators =
            ParseMutatorStack(view_params.mutatorsStack());
        const SkSize view_size = view_params.sizePoints();
        const float view_elevation =
            kScenicZElevationBetweenLayers * scenic_layer_index +
            embedded_views_height;

        // Verify that we're unpacking the mutators' transform matrix correctly
        // on debug builds Use built-in get method for SkMatrix to get values
        // See:
        // https://source.corp.google.com/piper///depot/google3/third_party/skia/HEAD/include/core/SkMatrix.h;l=391
#ifdef NDEBUG
        for (int index = 0; index < 9; index++) {
          const SkScalar mutators_transform_value =
              view_mutators.total_transform.get(index);
          const SkScalar params_transform_value =
              view_params.transformMatrix().get(index);
          if (!SkScalarNearlyEqual(mutators_transform_value,
                                   params_transform_value, 0.0005f)) {
            FML_LOG(FATAL)
                << "Assertion failed: view_mutators.total_transform[" << index
                << "] (" << mutators_transform_value
                << ") != view_params.transformMatrix()[" << index << "] ("
                << params_transform_value
                << "). This likely means there is a bug with the "
                << "logic for parsing embedded views' transform matrices.";
          }
        }
#endif

        // Set clips for the platform view.
        if (view_mutators.clips != view_holder.mutators.clips) {
          // Expand the clip_nodes array to fit any new nodes.
          while (view_holder.clip_nodes.size() < view_mutators.clips.size()) {
            view_holder.clip_nodes.emplace_back(
                scenic::EntityNode(session_->get()));
          }
          FML_CHECK(view_holder.clip_nodes.size() >=
                    view_mutators.clips.size());

          // Adjust and re-parent all clip rects.
          for (auto& clip_node : view_holder.clip_nodes) {
            clip_node.DetachChildren();
          }
          for (size_t c = 0; c < view_mutators.clips.size(); c++) {
            const SkMatrix& clip_transform = view_mutators.clips[c].transform;
            const SkRect& clip_rect = view_mutators.clips[c].rect;

            view_holder.clip_nodes[c].SetTranslation(
                clip_transform.getTranslateX(), clip_transform.getTranslateY(),
                0.f);
            view_holder.clip_nodes[c].SetScale(clip_transform.getScaleX(),
                                               clip_transform.getScaleY(), 1.f);
            view_holder.clip_nodes[c].SetClipPlanes(
                ClipPlanesFromRect(clip_rect));

            if (c != (view_mutators.clips.size() - 1)) {
              view_holder.clip_nodes[c].AddChild(view_holder.clip_nodes[c + 1]);
            } else {
              view_holder.clip_nodes[c].AddChild(view_holder.opacity_node);
            }
          }

          view_holder.mutators.clips = view_mutators.clips;
        }

        // Set transform and elevation for the platform view.
        if (view_mutators.transform != view_holder.mutators.transform ||
            view_elevation != view_holder.elevation) {
          view_holder.transform_node.SetTranslation(
              view_mutators.transform.getTranslateX(),
              view_mutators.transform.getTranslateY(), -view_elevation);
          view_holder.transform_node.SetScale(
              view_mutators.transform.getScaleX(),
              view_mutators.transform.getScaleY(), 1.f);

          view_holder.mutators.transform = view_mutators.transform;
          view_holder.elevation = view_elevation;
        }

        // Set HitTestBehavior for the platform view.
        if (view_holder.pending_hit_testable != view_holder.hit_testable) {
          view_holder.transform_node.SetHitTestBehavior(
              view_holder.pending_hit_testable
                  ? fuchsia::ui::gfx::HitTestBehavior::kDefault
                  : fuchsia::ui::gfx::HitTestBehavior::kSuppress);

          view_holder.hit_testable = view_holder.pending_hit_testable;
        }

        // Set opacity for the platform view.
        if (view_mutators.opacity != view_holder.mutators.opacity) {
          view_holder.opacity_node.SetOpacity(view_mutators.opacity);

          view_holder.mutators.opacity = view_mutators.opacity;
        }

        // Set size, occlusion hint, and focusable.
        if (view_size != view_holder.size ||
            view_holder.pending_occlusion_hint != view_holder.occlusion_hint ||
            view_holder.pending_focusable != view_holder.focusable) {
          view_holder.view_holder.SetViewProperties({
              .bounding_box =
                  {
                      .min = {.x = 0.f, .y = 0.f, .z = -1000.f},
                      .max = {.x = view_size.fWidth,
                              .y = view_size.fHeight,
                              .z = 0.f},
                  },
              .inset_from_min = {.x = view_holder.pending_occlusion_hint.fLeft,
                                 .y = view_holder.pending_occlusion_hint.fTop,
                                 .z = 0.f},
              .inset_from_max = {.x = view_holder.pending_occlusion_hint.fRight,
                                 .y =
                                     view_holder.pending_occlusion_hint.fBottom,
                                 .z = 0.f},
              .focus_change = view_holder.pending_focusable,
          });

          view_holder.size = view_size;
          view_holder.occlusion_hint = view_holder.pending_occlusion_hint;
          view_holder.focusable = view_holder.pending_focusable;
        }

        // Attach the ScenicView to the main scene graph.
        if (view_holder.mutators.clips.empty()) {
          layer_tree_node_.AddChild(view_holder.opacity_node);
        } else {
          layer_tree_node_.AddChild(view_holder.clip_nodes[0]);
        }

        // Account for the ScenicView's height when positioning the next layer.
        embedded_views_height += kScenicZElevationForPlatformView;
      }

      // 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(scenic_layer_index <= scenic_layers_.size());
        if (scenic_layer_index == scenic_layers_.size()) {
          ScenicLayer new_layer{
              .layer_node = scenic::EntityNode(session_->get()),
              .image =
                  ScenicImage{
                      .shape_node = scenic::ShapeNode(session_->get()),
                      .material = scenic::Material(session_->get()),
                  },
              // We'll set hit regions later.
              .hit_regions = {},
          };
          new_layer.layer_node.SetLabel("Flutter::Layer");
          new_layer.layer_node.AddChild(new_layer.image.shape_node);
          new_layer.image.shape_node.SetMaterial(new_layer.image.material);
          scenic_layers_.emplace_back(std::move(new_layer));
        }

        // Compute a hash and index for the rect.
        const uint64_t rect_hash =
            (static_cast<uint64_t>(layer->second.surface_size.width()) << 32) +
            layer->second.surface_size.height();
        size_t rect_index = 0;
        auto found_index = scenic_rect_indices.find(rect_hash);
        if (found_index == scenic_rect_indices.end()) {
          scenic_rect_indices.emplace(std::make_pair(rect_hash, 0));
        } else {
          rect_index = found_index->second + 1;
          scenic_rect_indices[rect_hash] = rect_index;
        }

        // Create a new rect if needed for the surface.
        auto found_rects = scenic_rects_.find(rect_hash);
        if (found_rects == scenic_rects_.end()) {
          auto [emplaced_rects, success] = scenic_rects_.emplace(
              std::make_pair(rect_hash, std::vector<scenic::Rectangle>()));
          FML_CHECK(success);

          found_rects = std::move(emplaced_rects);
        }
        FML_CHECK(rect_index <= found_rects->second.size());
        if (rect_index == found_rects->second.size()) {
          found_rects->second.emplace_back(scenic::Rectangle(
              session_->get(), layer->second.surface_size.width(),
              layer->second.surface_size.height()));
        }

        // Set layer shape and texture.
        // Scenic currently lacks an API to enable rendering of alpha channel;
        // Flutter Embedder also lacks an API to detect if a layer has alpha or
        // not. Alpha channels are only rendered if there is a OpacityNode
        // higher in the tree with opacity != 1. For now, assume any layer
        // beyond the first has alpha and clamp to a infinitesimally smaller
        // value than 1.  The first layer retains an opacity of 1 to avoid
        // blending with anything underneath.
        //
        // This does not cause visual problems in practice, but probably has
        // performance implications.
        const SkAlpha layer_opacity =
            first_layer ? kBackgroundLayerOpacity : kOverlayLayerOpacity;
        const float layer_elevation =
            kScenicZElevationBetweenLayers * scenic_layer_index +
            embedded_views_height;
        auto& scenic_layer = scenic_layers_[scenic_layer_index];
        auto& scenic_rect = found_rects->second[rect_index];
        auto& image = scenic_layer.image;
        image.shape_node.SetLabel("Flutter::Layer::Image");
        image.shape_node.SetShape(scenic_rect);
        image.shape_node.SetTranslation(
            layer->second.surface_size.width() * 0.5f,
            layer->second.surface_size.height() * 0.5f, -layer_elevation);
        image.material.SetColor(SK_AlphaOPAQUE, SK_AlphaOPAQUE, SK_AlphaOPAQUE,
                                layer_opacity);
        image.material.SetTexture(surface_for_layer->GetImageId());

        // We'll set hit regions expliclty on a separate ShapeNode, so the image
        // itself should be unhittable and semantically invisible.
        image.shape_node.SetHitTestBehavior(
            fuchsia::ui::gfx::HitTestBehavior::kSuppress);
        image.shape_node.SetSemanticVisibility(false);

        // Attach the ScenicLayer to the main scene graph.
        layer_tree_node_.AddChild(scenic_layer.layer_node);

        // Compute the set of non-overlapping set of bounding boxes for the
        // painted content in this layer.
        {
          FML_CHECK(layer->second.rtree);
          std::list<SkRect> intersection_rects =
              layer->second.rtree->searchNonOverlappingDrawnRects(
                  SkRect::Make(layer->second.surface_size));

          // SkRect joined_rect = SkRect::MakeEmpty();
          for (const SkRect& rect : intersection_rects) {
            auto paint_bounds =
                scenic::Rectangle(session_->get(), rect.width(), rect.height());
            auto hit_region = scenic::ShapeNode(session_->get());
            hit_region.SetLabel("Flutter::Layer::HitRegion");
            hit_region.SetShape(paint_bounds);
            hit_region.SetTranslation(rect.centerX(), rect.centerY(),
                                      -layer_elevation);
            hit_region.SetHitTestBehavior(
                fuchsia::ui::gfx::HitTestBehavior::kDefault);
            hit_region.SetSemanticVisibility(true);

            scenic_layer.layer_node.AddChild(hit_region);
            scenic_layer.hit_regions.push_back(std::move(hit_region));
          }
        }
      }

      // Reset for the next pass:
      //  +The next layer will not be the first layer.
      //  +Account for the current layer's height when positioning the next.
      first_layer = false;
      scenic_layer_index++;
    }
  }

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

    session_->Present();
  }

  // Flush pending skia operations.
  // NOTE: This operation MUST occur AFTER the `Present() ` call above. We
  // pipeline the Skia rendering work with scenic IPC, and scenic will delay
  // internally until Skia is finished. So, doing this work before calling
  // `Present()` would adversely affect performance.
  {
    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 GfxExternalViewEmbedder::EnableWireframe(bool enable) {
  session_->get()->Enqueue(
      scenic::NewSetEnableDebugViewBoundsCmd(root_view_.id(), enable));
  session_->Present();
}

void GfxExternalViewEmbedder::CreateView(int64_t view_id,
                                         ViewCallback on_view_created,
                                         GfxViewIdCallback on_view_bound) {
  FML_CHECK(scenic_views_.find(view_id) == scenic_views_.end());

  ScenicView new_view = {
      .opacity_node = scenic::OpacityNodeHACK(session_->get()),
      .transform_node = scenic::EntityNode(session_->get()),
      .view_holder = scenic::ViewHolder(
          session_->get(),
          scenic::ToViewHolderToken(zx::eventpair((zx_handle_t)view_id)),
          "Flutter::PlatformView"),
  };
  on_view_created();
  on_view_bound(new_view.view_holder.id());

  new_view.opacity_node.SetLabel("Flutter::PlatformView::OpacityMutator");
  new_view.opacity_node.AddChild(new_view.transform_node);
  new_view.transform_node.SetLabel("Flutter::PlatformView::TransformMutator");
  new_view.transform_node.SetTranslation(0.f, 0.f,
                                         -kScenicZElevationBetweenLayers);
  new_view.transform_node.Attach(new_view.view_holder);

  scenic_views_.emplace(std::make_pair(view_id, std::move(new_view)));
}

void GfxExternalViewEmbedder::DestroyView(int64_t view_id,
                                          GfxViewIdCallback on_view_unbound) {
  auto scenic_view = scenic_views_.find(view_id);
  FML_CHECK(scenic_view != scenic_views_.end());
  scenic::ResourceId resource_id = scenic_view->second.view_holder.id();

  scenic_views_.erase(scenic_view);
  on_view_unbound(resource_id);
}

void GfxExternalViewEmbedder::SetViewProperties(int64_t view_id,
                                                const SkRect& occlusion_hint,
                                                bool hit_testable,
                                                bool focusable) {
  auto found = scenic_views_.find(view_id);
  FML_CHECK(found != scenic_views_.end());
  auto& view_holder = found->second;

  view_holder.pending_occlusion_hint = occlusion_hint;
  view_holder.pending_hit_testable = hit_testable;
  view_holder.pending_focusable = focusable;
}

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

  // Detach the root node to prepare for the next frame.
  layer_tree_node_.DetachChildren();

  // Clear images on all layers so they aren't cached unnecessarily.
  for (auto& layer : scenic_layers_) {
    layer.image.material.SetTexture(0);

    // Detach hit regions; otherwise, they may persist across frames
    // incorrectly.
    for (auto& hit_region : layer.hit_regions) {
      hit_region.Detach();
    }

    // Remove cached hit regions so that we don't recreate stale ones.
    layer.hit_regions.clear();
  }
}

}  // namespace flutter_runner
