// 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_H_
#define FLUTTER_LIB_UI_PAINTING_DISPLAY_LIST_DEFERRED_IMAGE_GPU_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/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 DlDeferredImageGPU final : public DlImage {
 public:
  static sk_sp<DlDeferredImageGPU> 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);

  // |DlImage|
  ~DlDeferredImageGPU() 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 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);

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

    void SnapshotDisplayList();

    // |ContextListener|
    void OnGrContextCreated() override;

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

  const std::shared_ptr<ImageWrapper> image_wrapper_;

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

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

  FML_DISALLOW_COPY_AND_ASSIGN(DlDeferredImageGPU);
};

}  // namespace flutter

#endif  // FLUTTER_LIB_UI_PAINTING_DISPLAY_LIST_DEFERRED_IMAGE_GPU_H_
