// 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_LIB_UI_PAINTING_DISPLAY_LIST_DEFERRED_IMAGE_GPU_SKIA_H_
#define FLUTTER_LIB_UI_PAINTING_DISPLAY_LIST_DEFERRED_IMAGE_GPU_SKIA_H_

#include <memory>
#include <mutex>

#include "flutter/common/graphics/texture.h"
#include "flutter/display_list/display_list.h"
#include "flutter/display_list/display_list_image.h"
#include "flutter/flow/layers/layer_tree.h"
#include "flutter/flow/skia_gpu_object.h"
#include "flutter/fml/macros.h"
#include "flutter/fml/memory/weak_ptr.h"
#include "flutter/lib/ui/io_manager.h"
#include "flutter/lib/ui/snapshot_delegate.h"

namespace flutter {

class DlDeferredImageGPUSkia final : public DlImage {
 public:
  static sk_sp<DlDeferredImageGPUSkia> Make(
      const SkImageInfo& image_info,
      sk_sp<DisplayList> display_list,
      fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
      const fml::RefPtr<fml::TaskRunner>& raster_task_runner,
      fml::RefPtr<SkiaUnrefQueue> unref_queue);

  static sk_sp<DlDeferredImageGPUSkia> MakeFromLayerTree(
      const SkImageInfo& image_info,
      std::shared_ptr<LayerTree> layer_tree,
      fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
      const fml::RefPtr<fml::TaskRunner>& raster_task_runner,
      fml::RefPtr<SkiaUnrefQueue> unref_queue);

  // |DlImage|
  ~DlDeferredImageGPUSkia() override;

  // |DlImage|
  // This method is only safe to call from the raster thread.
  // Callers must not hold long term references to this image and
  // only use it for the immediate painting operation. It must be
  // collected on the raster task runner.
  sk_sp<SkImage> skia_image() const override;

  // |DlImage|
  std::shared_ptr<impeller::Texture> impeller_texture() const override;

  // |DlImage|
  bool isOpaque() const override;

  // |DlImage|
  bool isTextureBacked() const override;

  // |DlImage|
  SkISize dimensions() const override;

  // |DlImage|
  virtual size_t GetApproximateByteSize() const override;

  // |DlImage|
  // This method is safe to call from any thread.
  std::optional<std::string> get_error() const override;

  // |DlImage|
  OwningContext owning_context() const override {
    return OwningContext::kRaster;
  }

 private:
  class ImageWrapper final : public std::enable_shared_from_this<ImageWrapper>,
                             public ContextListener {
   public:
    static std::shared_ptr<ImageWrapper> Make(
        const SkImageInfo& image_info,
        sk_sp<DisplayList> display_list,
        fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
        fml::RefPtr<fml::TaskRunner> raster_task_runner,
        fml::RefPtr<SkiaUnrefQueue> unref_queue);

    static std::shared_ptr<ImageWrapper> MakeFromLayerTree(
        const SkImageInfo& image_info,
        std::shared_ptr<LayerTree> layer_tree,
        fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
        fml::RefPtr<fml::TaskRunner> raster_task_runner,
        fml::RefPtr<SkiaUnrefQueue> unref_queue);

    const SkImageInfo image_info() const { return image_info_; }
    const GrBackendTexture& texture() const { return texture_; }
    bool isTextureBacked() const;
    std::optional<std::string> get_error();
    sk_sp<SkImage> CreateSkiaImage() const;
    void Unregister();
    void DeleteTexture();

   private:
    const SkImageInfo image_info_;
    sk_sp<DisplayList> display_list_;
    fml::WeakPtr<SnapshotDelegate> snapshot_delegate_;
    fml::RefPtr<fml::TaskRunner> raster_task_runner_;
    fml::RefPtr<SkiaUnrefQueue> unref_queue_;
    std::shared_ptr<TextureRegistry> texture_registry_;

    mutable std::mutex error_mutex_;
    std::optional<std::string> error_;

    GrBackendTexture texture_;
    sk_sp<GrDirectContext> context_;
    // May be used if this image is not texture backed.
    sk_sp<SkImage> image_;

    ImageWrapper(const SkImageInfo& image_info,
                 sk_sp<DisplayList> display_list,
                 fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
                 fml::RefPtr<fml::TaskRunner> raster_task_runner,
                 fml::RefPtr<SkiaUnrefQueue> unref_queue);

    // If a layer tree is provided, it will be flattened during the raster
    // thread task spwaned by this method. After being flattened into a display
    // list, the image wrapper will be updated to hold this display list and the
    // layer tree can be dropped.
    void SnapshotDisplayList(std::shared_ptr<LayerTree> layer_tree = nullptr);

    // |ContextListener|
    void OnGrContextCreated() override;

    // |ContextListener|
    void OnGrContextDestroyed() override;
  };

  const std::shared_ptr<ImageWrapper> image_wrapper_;

  fml::RefPtr<fml::TaskRunner> raster_task_runner_;

  DlDeferredImageGPUSkia(std::shared_ptr<ImageWrapper> image_wrapper,
                         fml::RefPtr<fml::TaskRunner> raster_task_runner);

  FML_DISALLOW_COPY_AND_ASSIGN(DlDeferredImageGPUSkia);
};

}  // namespace flutter

#endif  // FLUTTER_LIB_UI_PAINTING_DISPLAY_LIST_DEFERRED_IMAGE_GPU_SKIA_H_
