// 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 "flutter/lib/ui/painting/display_list_deferred_image_gpu_impeller.h"

#include <utility>

#include "display_list_deferred_image_gpu_impeller.h"
#include "flutter/fml/make_copyable.h"

namespace flutter {

sk_sp<DlDeferredImageGPUImpeller> DlDeferredImageGPUImpeller::Make(
    std::unique_ptr<LayerTree> layer_tree,
    fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> snapshot_delegate,
    const fml::RefPtr<fml::TaskRunner>& raster_task_runner) {
  return sk_sp<DlDeferredImageGPUImpeller>(new DlDeferredImageGPUImpeller(
      DlDeferredImageGPUImpeller::ImageWrapper::Make(
          std::move(layer_tree), std::move(snapshot_delegate),
          raster_task_runner)));
}

sk_sp<DlDeferredImageGPUImpeller> DlDeferredImageGPUImpeller::Make(
    sk_sp<DisplayList> display_list,
    const SkISize& size,
    fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> snapshot_delegate,
    const fml::RefPtr<fml::TaskRunner>& raster_task_runner) {
  return sk_sp<DlDeferredImageGPUImpeller>(new DlDeferredImageGPUImpeller(
      DlDeferredImageGPUImpeller::ImageWrapper::Make(
          std::move(display_list), size, std::move(snapshot_delegate),
          raster_task_runner)));
}

sk_sp<DlDeferredImageGPUImpeller> DlDeferredImageGPUImpeller::Make(
    const std::shared_ptr<const impeller::Picture>& impeller_picture,
    const SkISize& size,
    fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> snapshot_delegate,
    const fml::RefPtr<fml::TaskRunner>& raster_task_runner) {
  return sk_sp<DlDeferredImageGPUImpeller>(new DlDeferredImageGPUImpeller(
      DlDeferredImageGPUImpeller::ImageWrapper::Make(
          impeller_picture, size, std::move(snapshot_delegate),
          raster_task_runner)));
}

DlDeferredImageGPUImpeller::DlDeferredImageGPUImpeller(
    std::shared_ptr<ImageWrapper> wrapper)
    : wrapper_(std::move(wrapper)) {}

// |DlImage|
DlDeferredImageGPUImpeller::~DlDeferredImageGPUImpeller() = default;

// |DlImage|
sk_sp<SkImage> DlDeferredImageGPUImpeller::skia_image() const {
  return nullptr;
};

// |DlImage|
std::shared_ptr<impeller::Texture>
DlDeferredImageGPUImpeller::impeller_texture() const {
  if (!wrapper_) {
    return nullptr;
  }
  return wrapper_->texture();
}

// |DlImage|
bool DlDeferredImageGPUImpeller::isOpaque() const {
  // Impeller doesn't currently implement opaque alpha types.
  return false;
}

// |DlImage|
bool DlDeferredImageGPUImpeller::isTextureBacked() const {
  return wrapper_ && wrapper_->isTextureBacked();
}

// |DlImage|
bool DlDeferredImageGPUImpeller::isUIThreadSafe() const {
  return true;
}

// |DlImage|
SkISize DlDeferredImageGPUImpeller::dimensions() const {
  if (!wrapper_) {
    return SkISize::MakeEmpty();
  }
  return wrapper_->size();
}

// |DlImage|
size_t DlDeferredImageGPUImpeller::GetApproximateByteSize() const {
  auto size = sizeof(DlDeferredImageGPUImpeller);
  if (wrapper_) {
    if (wrapper_->texture()) {
      size += wrapper_->texture()
                  ->GetTextureDescriptor()
                  .GetByteSizeOfBaseMipLevel();
    } else {
      size += wrapper_->size().width() * wrapper_->size().height() * 4;
    }
  }
  return size;
}

std::shared_ptr<DlDeferredImageGPUImpeller::ImageWrapper>
DlDeferredImageGPUImpeller::ImageWrapper::Make(
    sk_sp<DisplayList> display_list,
    const SkISize& size,
    fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> snapshot_delegate,
    const fml::RefPtr<fml::TaskRunner>& raster_task_runner) {
  auto wrapper = std::shared_ptr<ImageWrapper>(
      new ImageWrapper(std::move(display_list), size,
                       std::move(snapshot_delegate), raster_task_runner));
  wrapper->SnapshotDisplayList();
  return wrapper;
}

std::shared_ptr<DlDeferredImageGPUImpeller::ImageWrapper>
DlDeferredImageGPUImpeller::ImageWrapper::Make(
    const std::shared_ptr<const impeller::Picture>& impeller_picture,
    const SkISize& size,
    fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> snapshot_delegate,
    const fml::RefPtr<fml::TaskRunner>& raster_task_runner) {
  auto wrapper = std::shared_ptr<ImageWrapper>(new ImageWrapper(size));
  wrapper->SnapshotPicture(impeller_picture, std::move(snapshot_delegate),
                           raster_task_runner);
  return wrapper;
}

std::shared_ptr<DlDeferredImageGPUImpeller::ImageWrapper>
DlDeferredImageGPUImpeller::ImageWrapper::Make(
    std::unique_ptr<LayerTree> layer_tree,
    fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> snapshot_delegate,
    const fml::RefPtr<fml::TaskRunner>& raster_task_runner) {
  if (layer_tree) {
    auto wrapper = std::shared_ptr<ImageWrapper>(
        new ImageWrapper(layer_tree->frame_size()));
    wrapper->SnapshotLayer(std::move(layer_tree), std::move(snapshot_delegate),
                           raster_task_runner);
    return wrapper;
  }
  auto wrapper = std::shared_ptr<ImageWrapper>(
      new ImageWrapper(sk_sp<DisplayList>(), layer_tree->frame_size(),
                       std::move(snapshot_delegate), raster_task_runner));
  wrapper->SnapshotDisplayList(std::move(layer_tree));
  return wrapper;
}

DlDeferredImageGPUImpeller::ImageWrapper::ImageWrapper(
    sk_sp<DisplayList> display_list,
    const SkISize& size,
    fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> snapshot_delegate,
    fml::RefPtr<fml::TaskRunner> raster_task_runner)
    : size_(size),
      display_list_(std::move(display_list)),
      snapshot_delegate_(std::move(snapshot_delegate)),
      raster_task_runner_(std::move(raster_task_runner)) {}

DlDeferredImageGPUImpeller::ImageWrapper::ImageWrapper(const SkISize& size)
    : size_(size) {}

void DlDeferredImageGPUImpeller::ImageWrapper::SnapshotPicture(
    const std::shared_ptr<const impeller::Picture>& impeller_picture,
    fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> snapshot_delegate,
    const fml::RefPtr<fml::TaskRunner>& raster_task_runner) {
  fml::TaskRunner::RunNowOrPostTask(
      raster_task_runner,
      fml::MakeCopyable([weak_this = weak_from_this(), impeller_picture,
                         snapshot_delegate = std::move(snapshot_delegate)]() {
        TRACE_EVENT0("flutter", "SnapshotPicture (impeller)");
        auto wrapper = weak_this.lock();
        if (!wrapper) {
          return;
        }
        if (!snapshot_delegate) {
          return;
        }

        wrapper->texture_registry_ = snapshot_delegate->GetTextureRegistry();

        auto snapshot = snapshot_delegate->MakeRasterSnapshot(impeller_picture,
                                                              wrapper->size_);
        if (!snapshot) {
          std::scoped_lock lock(wrapper->error_mutex_);
          wrapper->error_ = "Failed to create snapshot.";
          return;
        }
        wrapper->texture_ = snapshot->impeller_texture();
      }));
}

void DlDeferredImageGPUImpeller::ImageWrapper::SnapshotLayer(
    std::unique_ptr<LayerTree> layer_tree,
    fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> snapshot_delegate,
    const fml::RefPtr<fml::TaskRunner>& raster_task_runner) {
  fml::TaskRunner::RunNowOrPostTask(
      raster_task_runner,
      fml::MakeCopyable([weak_this = weak_from_this(),
                         layer_tree = std::move(layer_tree),
                         snapshot_delegate = std::move(snapshot_delegate)]() {
        TRACE_EVENT0("flutter", "SnapshotLayer (impeller)");
        auto wrapper = weak_this.lock();
        if (!wrapper) {
          return;
        }
        if (!snapshot_delegate) {
          return;
        }

        wrapper->texture_registry_ = snapshot_delegate->GetTextureRegistry();

        auto impeller_picture = layer_tree->FlattenToImpellerPicture(
            SkRect::MakeWH(wrapper->size_.width(), wrapper->size_.height()),
            wrapper->texture_registry_);
        auto snapshot = snapshot_delegate->MakeRasterSnapshot(impeller_picture,
                                                              wrapper->size_);
        if (!snapshot) {
          std::scoped_lock lock(wrapper->error_mutex_);
          wrapper->error_ = "Failed to create snapshot.";
          return;
        }
        wrapper->texture_ = snapshot->impeller_texture();
      }));
}

DlDeferredImageGPUImpeller::ImageWrapper::~ImageWrapper() {
  if (display_list_) {
    fml::TaskRunner::RunNowOrPostTask(
        raster_task_runner_,
        [id = reinterpret_cast<uintptr_t>(this),
         texture_registry = std::move(texture_registry_)]() {
          if (texture_registry) {
            texture_registry->UnregisterContextListener(id);
          }
        });
  }
}

void DlDeferredImageGPUImpeller::ImageWrapper::OnGrContextCreated() {
  FML_DCHECK(raster_task_runner_->RunsTasksOnCurrentThread());
  SnapshotDisplayList();
}

void DlDeferredImageGPUImpeller::ImageWrapper::OnGrContextDestroyed() {
  if (display_list_) {
    texture_.reset();
  }
}

bool DlDeferredImageGPUImpeller::ImageWrapper::isTextureBacked() const {
  return texture_ && texture_->IsValid();
}

void DlDeferredImageGPUImpeller::ImageWrapper::SnapshotDisplayList(
    std::unique_ptr<LayerTree> layer_tree) {
  FML_DCHECK(display_list_ || layer_tree);
  fml::TaskRunner::RunNowOrPostTask(
      raster_task_runner_,
      fml::MakeCopyable([weak_this = weak_from_this(),
                         layer_tree = std::move(layer_tree)]() {
        TRACE_EVENT0("flutter", "SnapshotDisplayList (impeller)");
        auto wrapper = weak_this.lock();
        if (!wrapper) {
          return;
        }
        auto snapshot_delegate = wrapper->snapshot_delegate_;
        if (!snapshot_delegate) {
          return;
        }

        wrapper->texture_registry_ = snapshot_delegate->GetTextureRegistry();
        wrapper->texture_registry_->RegisterContextListener(
            reinterpret_cast<uintptr_t>(wrapper.get()), weak_this);

        if (layer_tree) {
          wrapper->display_list_ = layer_tree->Flatten(
              SkRect::MakeWH(wrapper->size_.width(), wrapper->size_.height()),
              wrapper->texture_registry_);
        }
        auto snapshot = snapshot_delegate->MakeRasterSnapshot(
            wrapper->display_list_, wrapper->size_);
        if (!snapshot) {
          std::scoped_lock lock(wrapper->error_mutex_);
          wrapper->error_ = "Failed to create snapshot.";
          return;
        }
        wrapper->texture_ = snapshot->impeller_texture();
      }));
}

std::optional<std::string>
DlDeferredImageGPUImpeller::ImageWrapper::get_error() {
  std::scoped_lock lock(error_mutex_);
  return error_;
}

}  // namespace flutter
