// 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_SHELL_COMMON_RASTERIZER_H_
#define FLUTTER_SHELL_COMMON_RASTERIZER_H_

#include <memory>
#include <optional>
#include <unordered_map>

#include "flutter/common/settings.h"
#include "flutter/common/task_runners.h"
#include "flutter/display_list/image/dl_image.h"
#include "flutter/flow/compositor_context.h"
#include "flutter/flow/embedded_views.h"
#include "flutter/flow/frame_timings.h"
#include "flutter/flow/layers/layer_tree.h"
#include "flutter/flow/surface.h"
#include "flutter/fml/closure.h"
#include "flutter/fml/memory/weak_ptr.h"
#include "flutter/fml/raster_thread_merger.h"
#include "flutter/fml/synchronization/sync_switch.h"
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/fml/time/time_delta.h"
#include "flutter/fml/time/time_point.h"
#if IMPELLER_SUPPORTS_RENDERING
// GN is having trouble understanding how this works in the Fuchsia builds.
#include "impeller/aiks/aiks_context.h"  // nogncheck
#include "impeller/renderer/context.h"   // nogncheck
#include "impeller/typographer/backends/skia/typographer_context_skia.h"  // nogncheck
#endif  // IMPELLER_SUPPORTS_RENDERING
#include "flutter/lib/ui/snapshot_delegate.h"
#include "flutter/shell/common/pipeline.h"
#include "flutter/shell/common/snapshot_controller.h"
#include "flutter/shell/common/snapshot_surface_producer.h"
#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"

#if !IMPELLER_SUPPORTS_RENDERING
namespace impeller {
class Context;
class AiksContext;
}  // namespace impeller
#endif  // !IMPELLER_SUPPORTS_RENDERING

namespace flutter {

// The result status of Rasterizer::Draw. This is only used for unit tests.
enum class DrawStatus {
  // The drawing was done without any specified status.
  kDone,
  // Failed to rasterize the frame because the Rasterizer is not set up.
  kNotSetUp,
  // Nothing was done, because the call was not on the raster thread. Yielded to
  // let this frame be serviced on the right thread.
  kYielded,
  // Nothing was done, because the pipeline was empty.
  kPipelineEmpty,
  // Nothing was done, because the GPU was unavailable.
  kGpuUnavailable,
};

// The result status of drawing to a view. This is only used for unit tests.
enum class DrawSurfaceStatus {
  // The layer tree was successfully rasterized.
  kSuccess,
  // The layer tree must be submitted again.
  //
  // This can occur on Android when switching the background surface to
  // FlutterImageView.  On Android, the first frame doesn't make the image
  // available to the ImageReader right away. The second frame does.
  // TODO(egarciad): https://github.com/flutter/flutter/issues/65652
  //
  // This can also occur when the frame is dropped to wait for the thread
  // merger to merge the raster and platform threads.
  kRetry,
  // Failed to rasterize the frame.
  kFailed,
  // Layer tree was discarded because its size does not match the view size.
  // This typically occurs during resizing.
  kDiscarded,
};

// The information to draw to all views of a frame.
struct FrameItem {
  FrameItem(std::vector<std::unique_ptr<LayerTreeTask>> tasks,
            std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder)
      : layer_tree_tasks(std::move(tasks)),
        frame_timings_recorder(std::move(frame_timings_recorder)) {}
  std::vector<std::unique_ptr<LayerTreeTask>> layer_tree_tasks;
  std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder;
};

using FramePipeline = Pipeline<FrameItem>;

//------------------------------------------------------------------------------
/// The rasterizer is a component owned by the shell that resides on the raster
/// task runner. Each shell owns exactly one instance of a rasterizer. The
/// rasterizer may only be created, used and collected on the raster task
/// runner.
///
/// The rasterizer owns the instance of the currently active on-screen render
/// surface. On this surface, it renders the contents of layer trees submitted
/// to it by the `Engine` (which lives on the UI task runner).
///
/// The primary components owned by the rasterizer are the compositor context
/// and the on-screen render surface. The compositor context has all the GPU
/// state necessary to render frames to the render surface.
///
class Rasterizer final : public SnapshotDelegate,
                         public Stopwatch::RefreshRateUpdater,
                         public SnapshotController::Delegate {
 public:
  //----------------------------------------------------------------------------
  /// @brief      Used to forward events from the rasterizer to interested
  ///             subsystems. Currently, the shell sets itself up as the
  ///             rasterizer delegate to listen for frame rasterization events.
  ///             It can then forward these events to the engine.
  ///
  ///             Like all rasterizer operation, the rasterizer delegate call
  ///             are made on the raster task runner. Any delegate must ensure
  ///             that they can handle the threading implications.
  ///
  class Delegate {
   public:
    //--------------------------------------------------------------------------
    /// @brief      Notifies the delegate that a frame has been rendered. The
    ///             rasterizer collects profiling information for each part of
    ///             the frame workload. This profiling information is made
    ///             available to the delegate for forwarding to subsystems
    ///             interested in collecting such profiles. Currently, the shell
    ///             (the delegate) forwards this to the engine where Dart code
    ///             can react to this information.
    ///
    /// @see        `FrameTiming`
    ///
    /// @param[in]  frame_timing  Instrumentation information for each phase of
    ///                           the frame workload.
    ///
    virtual void OnFrameRasterized(const FrameTiming& frame_timing) = 0;

    /// Time limit for a smooth frame.
    ///
    /// See: `DisplayManager::GetMainDisplayRefreshRate`.
    virtual fml::Milliseconds GetFrameBudget() = 0;

    /// Target time for the latest frame. See also `Shell::OnAnimatorBeginFrame`
    /// for when this time gets updated.
    virtual fml::TimePoint GetLatestFrameTargetTime() const = 0;

    /// Task runners used by the shell.
    virtual const TaskRunners& GetTaskRunners() const = 0;

    /// The raster thread merger from parent shell's rasterizer.
    virtual const fml::RefPtr<fml::RasterThreadMerger>
    GetParentRasterThreadMerger() const = 0;

    /// Accessor for the shell's GPU sync switch, which determines whether GPU
    /// operations are allowed on the current thread.
    ///
    /// For example, on some platforms when the application is backgrounded it
    /// is critical that GPU operations are not processed.
    virtual std::shared_ptr<const fml::SyncSwitch> GetIsGpuDisabledSyncSwitch()
        const = 0;

    virtual const Settings& GetSettings() const = 0;

    virtual bool ShouldDiscardLayerTree(int64_t view_id,
                                        const flutter::LayerTree& tree) = 0;
  };

  //----------------------------------------------------------------------------
  /// @brief     How to handle calls to MakeSkiaGpuImage.
  enum class MakeGpuImageBehavior {
    /// MakeSkiaGpuImage returns a GPU resident image, if possible.
    kGpu,
    /// MakeSkiaGpuImage returns a checkerboard bitmap. This is useful in test
    /// contexts where no GPU surface is available.
    kBitmap,
  };

  //----------------------------------------------------------------------------
  /// @brief      Creates a new instance of a rasterizer. Rasterizers may only
  ///             be created on the raster task runner. Rasterizers are
  ///             currently only created by the shell (which also sets itself up
  ///             as the rasterizer delegate).
  ///
  /// @param[in]  delegate                   The rasterizer delegate.
  /// @param[in]  gpu_image_behavior         How to handle calls to
  ///                                        MakeSkiaGpuImage.
  ///
  explicit Rasterizer(
      Delegate& delegate,
      MakeGpuImageBehavior gpu_image_behavior = MakeGpuImageBehavior::kGpu);

  //----------------------------------------------------------------------------
  /// @brief      Destroys the rasterizer. This must happen on the raster task
  ///             runner. All GPU resources are collected before this call
  ///             returns. Any context set up by the embedder to hold these
  ///             resources can be immediately collected as well.
  ///
  ~Rasterizer();

  void SetImpellerContext(std::weak_ptr<impeller::Context> impeller_context);

  //----------------------------------------------------------------------------
  /// @brief      Rasterizers may be created well before an on-screen surface is
  ///             available for rendering. Shells usually create a rasterizer in
  ///             their constructors. Once an on-screen surface is available
  ///             however, one may be provided to the rasterizer using this
  ///             call. No rendering may occur before this call. The surface is
  ///             held till the balancing call to `Rasterizer::Teardown` is
  ///             made. Calling a setup before tearing down the previous surface
  ///             (if this is not the first time the surface has been set up) is
  ///             user error.
  ///
  /// @see        `Rasterizer::Teardown`
  ///
  /// @param[in]  surface  The on-screen render surface.
  ///
  void Setup(std::unique_ptr<Surface> surface);

  //----------------------------------------------------------------------------
  /// @brief      Releases the previously set up on-screen render surface and
  ///             collects associated resources. No more rendering may occur
  ///             till the next call to `Rasterizer::Setup` with a new render
  ///             surface. Calling a teardown without a setup is user error.
  ///             Calling this method multiple times is safe.
  ///
  void Teardown();

  //----------------------------------------------------------------------------
  /// @brief      Releases any resource used by the external view embedder.
  ///             For example, overlay surfaces or Android views.
  ///             On Android, this method post a task to the platform thread,
  ///             and waits until it completes.
  void TeardownExternalViewEmbedder();

  //----------------------------------------------------------------------------
  /// @brief      Notifies the rasterizer that there is a low memory situation
  ///             and it must purge as many unnecessary resources as possible.
  ///             Currently, the Skia context associated with onscreen rendering
  ///             is told to free GPU resources.
  ///
  void NotifyLowMemoryWarning() const;

  //----------------------------------------------------------------------------
  /// @brief      Gets a weak pointer to the rasterizer. The rasterizer may only
  ///             be accessed on the raster task runner.
  ///
  /// @return     The weak pointer to the rasterizer.
  ///
  fml::TaskRunnerAffineWeakPtr<Rasterizer> GetWeakPtr() const;

  fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> GetSnapshotDelegate() const;

  //----------------------------------------------------------------------------
  /// @brief      Deallocate the resources for displaying a view.
  ///
  ///             This method must be called when a view is removed.
  ///
  ///             The rasterizer don't need views to be registered. Last-frame
  ///             states for views are recorded when layer trees are rasterized
  ///             to the view and used during `Rasterizer::DrawLastLayerTrees`.
  ///
  /// @param[in]  view_id  The ID of the view.
  ///
  void CollectView(int64_t view_id);

  //----------------------------------------------------------------------------
  /// @brief      Returns the last successfully drawn layer tree for the given
  ///             view, or nullptr if there isn't any. This is useful during
  ///             `DrawLastLayerTrees` and computing frame damage.
  ///
  /// @bug        https://github.com/flutter/flutter/issues/33939
  ///
  /// @return     A pointer to the last layer or `nullptr` if this rasterizer
  ///             has never rendered a frame to the given view.
  ///
  flutter::LayerTree* GetLastLayerTree(int64_t view_id);

  //----------------------------------------------------------------------------
  /// @brief      Draws the last layer trees with their last configuration. This
  ///             may seem entirely redundant at first glance. After all, on
  ///             surface loss and re-acquisition, the framework generates a new
  ///             layer tree. Otherwise, why render the same contents to the
  ///             screen again? This is used as an optimization in cases where
  ///             there are external textures (video or camera streams for
  ///             example) in referenced in the layer tree. These textures may
  ///             be updated at a cadence different from that of the Flutter
  ///             application. Flutter can re-render the layer tree with just
  ///             the updated textures instead of waiting for the framework to
  ///             do the work to generate the layer tree describing the same
  ///             contents.
  ///
  ///             Calling this method clears all last layer trees
  ///             (GetLastLayerTree).
  ///
  void DrawLastLayerTrees(
      std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder);

  // |SnapshotDelegate|
  GrDirectContext* GetGrContext() override;

  std::shared_ptr<flutter::TextureRegistry> GetTextureRegistry() override;

  //----------------------------------------------------------------------------
  /// @brief      Takes the next item from the layer tree pipeline and executes
  ///             the raster thread frame workload for that pipeline item to
  ///             render a frame on the on-screen surface.
  ///
  ///             Why does the draw call take a layer tree pipeline and not the
  ///             layer tree directly?
  ///
  ///             The pipeline is the way book-keeping of frame workloads
  ///             distributed across the multiple threads is managed. The
  ///             rasterizer deals with the pipelines directly (instead of layer
  ///             trees which is what it actually renders) because the pipeline
  ///             consumer's workload must be accounted for within the pipeline
  ///             itself. If the rasterizer took the layer tree directly, it
  ///             would have to be taken out of the pipeline. That would signal
  ///             the end of the frame workload and the pipeline would be ready
  ///             for new frames. But the last frame has not been rendered by
  ///             the frame yet! On the other hand, the pipeline must own the
  ///             layer tree it renders because it keeps a reference to the last
  ///             layer tree around till a new frame is rendered. So a simple
  ///             reference wont work either. The `Rasterizer::DoDraw` method
  ///             actually performs the GPU operations within the layer tree
  ///             pipeline.
  ///
  /// @see        `Rasterizer::DoDraw`
  ///
  /// @param[in]  pipeline  The layer tree pipeline to take the next layer tree
  ///                       to render from.
  ///
  DrawStatus Draw(const std::shared_ptr<FramePipeline>& pipeline);

  //----------------------------------------------------------------------------
  /// @brief      The type of the screenshot to obtain of the previously
  ///             rendered layer tree.
  ///
  enum class ScreenshotType {
    // NOLINTBEGIN(readability-identifier-naming)
    //--------------------------------------------------------------------------
    /// A format used to denote a Skia picture. A Skia picture is a serialized
    /// representation of an `SkPicture` that can be used to introspect the
    /// series of commands used to draw that picture.
    ///
    /// Skia pictures are typically stored as files with the .skp extension on
    /// disk. These files may be viewed in an interactive debugger available at
    /// https://debugger.skia.org/
    ///
    SkiaPicture,

    //--------------------------------------------------------------------------
    /// A format used to denote uncompressed image data. This format
    /// is 32 bits per pixel, 8 bits per component and
    /// denoted by the `kN32_SkColorType ` Skia color type.
    ///
    UncompressedImage,

    //--------------------------------------------------------------------------
    /// A format used to denote compressed image data. The PNG compressed
    /// container is used.
    ///
    CompressedImage,

    //--------------------------------------------------------------------------
    /// Reads the data directly from the Rasterizer's surface. The pixel format
    /// is determined from the surface. This is the only way to read wide gamut
    /// color data, but isn't supported everywhere.
    SurfaceData,
    // NOLINTEND(readability-identifier-naming)
  };

  //----------------------------------------------------------------------------
  /// @brief      A POD type used to return the screenshot data along with the
  ///             size of the frame.
  ///
  struct Screenshot {
    //--------------------------------------------------------------------------
    /// The data used to describe the screenshot. The data format depends on the
    /// type of screenshot taken and any further encoding done to the same.
    ///
    /// @see      `ScreenshotType`
    ///
    sk_sp<SkData> data;

    //--------------------------------------------------------------------------
    /// The size of the screenshot in texels.
    ///
    SkISize frame_size = SkISize::MakeEmpty();

    //--------------------------------------------------------------------------
    /// Characterization of the format of the data in `data`.
    ///
    std::string format;

    //--------------------------------------------------------------------------
    /// @brief      Creates an empty screenshot
    ///
    Screenshot();

    //--------------------------------------------------------------------------
    /// @brief      Creates a screenshot with the specified data and size.
    ///
    /// @param[in]  p_data  The screenshot data
    /// @param[in]  p_size  The screenshot size.
    /// @param[in]  p_format  The screenshot format.
    ///
    Screenshot(sk_sp<SkData> p_data,
               SkISize p_size,
               const std::string& p_format);

    //--------------------------------------------------------------------------
    /// @brief      The copy constructor for a screenshot.
    ///
    /// @param[in]  other  The screenshot to copy from.
    ///
    Screenshot(const Screenshot& other);

    //--------------------------------------------------------------------------
    /// @brief      Destroys the screenshot object and releases underlying data.
    ///
    ~Screenshot();
  };

  //----------------------------------------------------------------------------
  /// @brief      Screenshots the last layer tree to one of the supported
  ///             screenshot types and optionally Base 64 encodes that data for
  ///             easier transmission and packaging (usually over the service
  ///             protocol for instrumentation tools running on the host).
  ///
  /// @param[in]  type           The type of the screenshot to gather.
  /// @param[in]  base64_encode  Whether Base 64 encoding must be applied to the
  ///                            data after a screenshot has been captured.
  ///
  /// @return     A non-empty screenshot if one could be captured. A screenshot
  ///             capture may fail if there were no layer trees previously
  ///             rendered by this rasterizer, or, due to an unspecified
  ///             internal error. Internal error will be logged to the console.
  ///
  Screenshot ScreenshotLastLayerTree(ScreenshotType type, bool base64_encode);

  //----------------------------------------------------------------------------
  /// @brief      Sets a callback that will be executed when the next layer tree
  ///             in rendered to the on-screen surface. This is used by
  ///             embedders to listen for one time operations like listening for
  ///             when the first frame is rendered so that they may hide splash
  ///             screens.
  ///
  ///             The callback is only executed once and dropped on the GPU
  ///             thread when executed (lambda captures must be able to deal
  ///             with the threading repercussions of this behavior).
  ///
  /// @param[in]  callback  The callback to execute when the next layer tree is
  ///                       rendered on-screen.
  ///
  void SetNextFrameCallback(const fml::closure& callback);

  //----------------------------------------------------------------------------
  /// @brief Set the External View Embedder. This is done on shell
  ///        initialization. This is non-null on platforms that support
  ///        embedding externally composited views.
  ///
  /// @param[in] view_embedder The external view embedder object.
  ///
  void SetExternalViewEmbedder(
      const std::shared_ptr<ExternalViewEmbedder>& view_embedder);

  //----------------------------------------------------------------------------
  /// @brief Set the snapshot surface producer. This is done on shell
  ///        initialization. This is non-null on platforms that support taking
  ///        GPU accelerated raster snapshots in the background.
  ///
  /// @param[in]  producer  A surface producer for raster snapshotting when the
  ///                       onscreen surface is not available.
  ///
  void SetSnapshotSurfaceProducer(
      std::unique_ptr<SnapshotSurfaceProducer> producer);

  //----------------------------------------------------------------------------
  /// @brief      Returns a pointer to the compositor context used by this
  ///             rasterizer. This pointer will never be `nullptr`.
  ///
  /// @return     The compositor context used by this rasterizer.
  ///
  flutter::CompositorContext* compositor_context() {
    return compositor_context_.get();
  }

  //----------------------------------------------------------------------------
  /// @brief      Returns the raster thread merger used by this rasterizer.
  ///             This may be `nullptr`.
  ///
  /// @return     The raster thread merger used by this rasterizer.
  ///
  fml::RefPtr<fml::RasterThreadMerger> GetRasterThreadMerger();

  //----------------------------------------------------------------------------
  /// @brief      Skia has no notion of time. To work around the performance
  ///             implications of this, it may cache GPU resources to reference
  ///             them from one frame to the next. Using this call, embedders
  ///             may set the maximum bytes cached by Skia in its caches
  ///             dedicated to on-screen rendering.
  ///
  /// @attention  This cache setting will be invalidated when the surface is
  ///             torn down via `Rasterizer::Teardown`. This call must be made
  ///             again with new limits after surface re-acquisition.
  ///
  /// @attention  This cache does not describe the entirety of GPU resources
  ///             that may be cached. The `RasterCache` also holds very large
  ///             GPU resources.
  ///
  /// @see        `RasterCache`
  ///
  /// @param[in]  max_bytes  The maximum byte size of resource that may be
  ///                        cached for GPU rendering.
  /// @param[in]  from_user  Whether this request was from user code, e.g. via
  ///                        the flutter/skia message channel, in which case
  ///                        it should not be overridden by the platform.
  ///
  void SetResourceCacheMaxBytes(size_t max_bytes, bool from_user);

  //----------------------------------------------------------------------------
  /// @brief      The current value of Skia's resource cache size, if a surface
  ///             is present.
  ///
  /// @attention  This cache does not describe the entirety of GPU resources
  ///             that may be cached. The `RasterCache` also holds very large
  ///             GPU resources.
  ///
  /// @see        `RasterCache`
  ///
  /// @return     The size of Skia's resource cache, if available.
  ///
  std::optional<size_t> GetResourceCacheMaxBytes() const;

  //----------------------------------------------------------------------------
  /// @brief      Enables the thread merger if the external view embedder
  ///             supports dynamic thread merging.
  ///
  /// @attention  This method is thread-safe. When the thread merger is enabled,
  ///             the raster task queue can run in the platform thread at any
  ///             time.
  ///
  /// @see        `ExternalViewEmbedder`
  ///
  void EnableThreadMergerIfNeeded();

  //----------------------------------------------------------------------------
  /// @brief      Disables the thread merger if the external view embedder
  ///             supports dynamic thread merging.
  ///
  /// @attention  This method is thread-safe. When the thread merger is
  ///             disabled, the raster task queue will continue to run in the
  ///             same thread until |EnableThreadMergerIfNeeded| is called.
  ///
  /// @see        `ExternalViewEmbedder`
  ///
  void DisableThreadMergerIfNeeded();

  //----------------------------------------------------------------------------
  /// @brief      Returns whether TearDown has been called.
  ///
  ///             This method is used only in unit tests.
  ///
  bool IsTornDown();

  //----------------------------------------------------------------------------
  /// @brief      Returns the last status of drawing the specific view.
  ///
  ///             This method is used only in unit tests.
  ///
  std::optional<DrawSurfaceStatus> GetLastDrawStatus(int64_t view_id);

 private:
  // The result status of DoDraw, DrawToSurfaces, and DrawToSurfacesUnsafe.
  enum class DoDrawStatus {
    // The drawing was done without any specified status.
    kDone,
    // Frame has been successfully rasterized, but there are additional items
    // in the pipeline waiting to be consumed. This is currently only used when
    // thread configuration change occurs.
    kEnqueuePipeline,
    // Failed to rasterize the frame because the Rasterizer is not set up.
    kNotSetUp,
    // Nothing was done, because GPU was unavailable.
    kGpuUnavailable,
  };

  // The result of DoDraw.
  struct DoDrawResult {
    // The overall status of the drawing process.
    //
    // The status of drawing a specific view is available at GetLastDrawStatus.
    DoDrawStatus status = DoDrawStatus::kDone;

    // The frame item that needs to be submitted again.
    //
    // See RasterStatus::kResubmit and kSkipAndRetry for when it happens.
    //
    // If `resubmitted_item` is not null, its `tasks` is guaranteed to be
    // non-empty.
    std::unique_ptr<FrameItem> resubmitted_item;
  };

  struct ViewRecord {
    std::unique_ptr<LayerTreeTask> last_successful_task;
    std::optional<DrawSurfaceStatus> last_draw_status;
  };

  // |SnapshotDelegate|
  std::unique_ptr<GpuImageResult> MakeSkiaGpuImage(
      sk_sp<DisplayList> display_list,
      const SkImageInfo& image_info) override;

  // |SnapshotDelegate|
  sk_sp<DlImage> MakeRasterSnapshot(sk_sp<DisplayList> display_list,
                                    SkISize picture_size) override;

  // |SnapshotDelegate|
  sk_sp<SkImage> ConvertToRasterImage(sk_sp<SkImage> image) override;

  // |Stopwatch::Delegate|
  /// Time limit for a smooth frame.
  ///
  /// See: `DisplayManager::GetMainDisplayRefreshRate`.
  fml::Milliseconds GetFrameBudget() const override;

  // |SnapshotController::Delegate|
  const std::unique_ptr<Surface>& GetSurface() const override {
    return surface_;
  }

  // |SnapshotController::Delegate|
  std::shared_ptr<impeller::AiksContext> GetAiksContext() const override {
#if IMPELLER_SUPPORTS_RENDERING
    if (surface_) {
      return surface_->GetAiksContext();
    }
    if (auto context = impeller_context_.lock()) {
      return std::make_shared<impeller::AiksContext>(
          context, impeller::TypographerContextSkia::Make());
    }
#endif
    return nullptr;
  }

  // |SnapshotController::Delegate|
  const std::unique_ptr<SnapshotSurfaceProducer>& GetSnapshotSurfaceProducer()
      const override {
    return snapshot_surface_producer_;
  }

  // |SnapshotController::Delegate|
  std::shared_ptr<const fml::SyncSwitch> GetIsGpuDisabledSyncSwitch()
      const override {
    return delegate_.GetIsGpuDisabledSyncSwitch();
  }

  sk_sp<SkData> ScreenshotLayerTreeAsImage(
      flutter::LayerTree* tree,
      flutter::CompositorContext& compositor_context,
      GrDirectContext* surface_context,
      bool compressed);

  // This method starts with the frame timing recorder at build end. This
  // method might push it to raster end and get the recorded time, or abort in
  // the middle and not get the recorded time.
  DoDrawResult DoDraw(
      std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder,
      std::vector<std::unique_ptr<LayerTreeTask>> tasks);

  // This method pushes the frame timing recorder from build end to raster end.
  DoDrawResult DrawToSurfaces(
      FrameTimingsRecorder& frame_timings_recorder,
      std::vector<std::unique_ptr<LayerTreeTask>> tasks);

  // Draws the specified layer trees to views, assuming we have access to the
  // GPU.
  //
  // If any layer trees need resubmitting, this method returns the frame item to
  // be resubmitted. Otherwise, it returns nullptr.
  //
  // Unsafe because it assumes we have access to the GPU which isn't the case
  // when iOS is backgrounded, for example.
  //
  // This method pushes the frame timing recorder from build end to raster end.
  std::unique_ptr<FrameItem> DrawToSurfacesUnsafe(
      FrameTimingsRecorder& frame_timings_recorder,
      std::vector<std::unique_ptr<LayerTreeTask>> tasks);

  // Draws the layer tree to the specified view, assuming we have access to the
  // GPU.
  //
  // This method is not affiliated with the frame timing recorder, but must be
  // included between the RasterStart and RasterEnd.
  DrawSurfaceStatus DrawToSurfaceUnsafe(
      int64_t view_id,
      flutter::LayerTree& layer_tree,
      float device_pixel_ratio,
      std::optional<fml::TimePoint> presentation_time);

  ViewRecord& EnsureViewRecord(int64_t view_id);

  void FireNextFrameCallbackIfPresent();

  static bool ShouldResubmitFrame(const DoDrawResult& result);
  static DrawStatus ToDrawStatus(DoDrawStatus status);

  bool is_torn_down_ = false;
  Delegate& delegate_;
  MakeGpuImageBehavior gpu_image_behavior_;
  std::weak_ptr<impeller::Context> impeller_context_;
  std::unique_ptr<Surface> surface_;
  std::unique_ptr<SnapshotSurfaceProducer> snapshot_surface_producer_;
  std::unique_ptr<flutter::CompositorContext> compositor_context_;
  std::unordered_map<int64_t, ViewRecord> view_records_;
  fml::closure next_frame_callback_;
  bool user_override_resource_cache_bytes_ = false;
  std::optional<size_t> max_cache_bytes_;
  fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger_;
  std::shared_ptr<ExternalViewEmbedder> external_view_embedder_;
  std::unique_ptr<SnapshotController> snapshot_controller_;

  // WeakPtrFactory must be the last member.
  fml::TaskRunnerAffineWeakPtrFactory<Rasterizer> weak_factory_;
  FML_DISALLOW_COPY_AND_ASSIGN(Rasterizer);
};

}  // namespace flutter

#endif  // FLUTTER_SHELL_COMMON_RASTERIZER_H_
