// 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_SNAPSHOT_DELEGATE_H_
#define FLUTTER_LIB_UI_SNAPSHOT_DELEGATE_H_

#include <string>

#include "flutter/common/graphics/texture.h"
#include "flutter/display_list/display_list.h"
#include "flutter/flow/skia_gpu_object.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkPromiseImageTexture.h"
#include "third_party/skia/include/gpu/GrContextThreadSafeProxy.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"

namespace flutter {

class DlImage;

class SnapshotDelegate {
 public:
  //----------------------------------------------------------------------------
  /// @brief      A data structure used by the Skia implementation of deferred
  ///             GPU based images.
  struct GpuImageResult {
    GpuImageResult(const GrBackendTexture& p_texture,
                   sk_sp<GrDirectContext> p_context,
                   sk_sp<SkImage> p_image = nullptr,
                   const std::string& p_error = "")
        : texture(p_texture),
          context(std::move(p_context)),
          image(std::move(p_image)),
          error(p_error) {}

    const GrBackendTexture texture;
    // If texture.isValid() == true, this is a pointer to a GrDirectContext that
    // can be used to create an image from the texture.
    sk_sp<GrDirectContext> context;
    // If MakeGpuImage could not create a GPU resident image, a raster copy
    // is available in this member and texture.isValid() is false.
    sk_sp<SkImage> image;

    // A non-empty string containing an error message if neither a GPU backed
    // texture nor a raster backed image could be created.
    const std::string error;
  };

  //----------------------------------------------------------------------------
  /// @brief      Attempts to create a GrBackendTexture for the specified
  ///             DisplayList. May result in a raster bitmap if no GPU context
  ///             is available.
  virtual std::unique_ptr<GpuImageResult> MakeSkiaGpuImage(
      sk_sp<DisplayList> display_list,
      const SkImageInfo& image_info) = 0;

  //----------------------------------------------------------------------------
  /// @brief      Gets the registry of external textures currently in use by the
  ///             rasterizer. These textures may be updated at a cadence
  ///             different from that of the Flutter application. When an
  ///             external texture is referenced in the Flutter layer tree, that
  ///             texture is composited within the Flutter layer tree.
  ///
  /// @return     A pointer to the external texture registry.
  ///
  virtual std::shared_ptr<TextureRegistry> GetTextureRegistry() = 0;

  virtual GrDirectContext* GetGrContext() = 0;

  virtual sk_sp<DlImage> MakeRasterSnapshot(sk_sp<DisplayList> display_list,
                                            SkISize picture_size) = 0;

  virtual sk_sp<SkImage> ConvertToRasterImage(sk_sp<SkImage> image) = 0;
};

}  // namespace flutter

#endif  // FLUTTER_LIB_UI_SNAPSHOT_DELEGATE_H_
