// 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/image_encoding_impeller.h"

#include "flutter/lib/ui/painting/image.h"
#include "impeller/core/device_buffer.h"
#include "impeller/core/formats.h"
#include "impeller/renderer/command_buffer.h"
#include "impeller/renderer/context.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkImage.h"

namespace flutter {
namespace {

std::optional<SkColorType> ToSkColorType(impeller::PixelFormat format) {
  switch (format) {
    case impeller::PixelFormat::kR8G8B8A8UNormInt:
      return SkColorType::kRGBA_8888_SkColorType;
    case impeller::PixelFormat::kR16G16B16A16Float:
      return SkColorType::kRGBA_F16_SkColorType;
    case impeller::PixelFormat::kB8G8R8A8UNormInt:
      return SkColorType::kBGRA_8888_SkColorType;
    case impeller::PixelFormat::kB10G10R10XR:
      return SkColorType::kBGR_101010x_XR_SkColorType;
    case impeller::PixelFormat::kB10G10R10A10XR:
      return SkColorType::kBGRA_10101010_XR_SkColorType;
    default:
      return std::nullopt;
  }
}

sk_sp<SkImage> ConvertBufferToSkImage(
    const std::shared_ptr<impeller::DeviceBuffer>& buffer,
    SkColorType color_type,
    SkISize dimensions) {
  SkImageInfo image_info = SkImageInfo::Make(dimensions, color_type,
                                             SkAlphaType::kPremul_SkAlphaType);
  SkBitmap bitmap;
  auto func = [](void* addr, void* context) {
    auto buffer =
        static_cast<std::shared_ptr<impeller::DeviceBuffer>*>(context);
    buffer->reset();
    delete buffer;
  };
  auto bytes_per_pixel = image_info.bytesPerPixel();
  bitmap.installPixels(image_info, buffer->OnGetContents(),
                       dimensions.width() * bytes_per_pixel, func,
                       new std::shared_ptr<impeller::DeviceBuffer>(buffer));
  bitmap.setImmutable();

  sk_sp<SkImage> raster_image = SkImages::RasterFromBitmap(bitmap);
  return raster_image;
}

[[nodiscard]] fml::Status DoConvertImageToRasterImpeller(
    const sk_sp<DlImage>& dl_image,
    const std::function<void(fml::StatusOr<sk_sp<SkImage>>)>& encode_task,
    const std::shared_ptr<const fml::SyncSwitch>& is_gpu_disabled_sync_switch,
    const std::shared_ptr<impeller::Context>& impeller_context) {
  fml::Status result;
  is_gpu_disabled_sync_switch->Execute(
      fml::SyncSwitch::Handlers()
          .SetIfTrue([&result] {
            result =
                fml::Status(fml::StatusCode::kUnavailable, "GPU unavailable.");
          })
          .SetIfFalse([&dl_image, &encode_task, &impeller_context] {
            ImageEncodingImpeller::ConvertDlImageToSkImage(
                dl_image, encode_task, impeller_context);
          }));
  return result;
}

/// Same as `DoConvertImageToRasterImpeller` but it will attempt to retry the
/// operation if `DoConvertImageToRasterImpeller` returns kUnavailable when the
/// GPU becomes available again.
void DoConvertImageToRasterImpellerWithRetry(
    const sk_sp<DlImage>& dl_image,
    std::function<void(fml::StatusOr<sk_sp<SkImage>>)>&& encode_task,
    const std::shared_ptr<const fml::SyncSwitch>& is_gpu_disabled_sync_switch,
    const std::shared_ptr<impeller::Context>& impeller_context,
    const fml::RefPtr<fml::TaskRunner>& retry_runner) {
  fml::Status status = DoConvertImageToRasterImpeller(
      dl_image, encode_task, is_gpu_disabled_sync_switch, impeller_context);
  if (!status.ok()) {
    // If the conversion failed because of the GPU is unavailable, store the
    // task on the Context so it can be executed when the GPU becomes available.
    if (status.code() == fml::StatusCode::kUnavailable) {
      impeller_context->StoreTaskForGPU(
          [dl_image, encode_task = std::move(encode_task),
           is_gpu_disabled_sync_switch, impeller_context,
           retry_runner]() mutable {
            auto retry_task = [dl_image, encode_task = std::move(encode_task),
                               is_gpu_disabled_sync_switch, impeller_context] {
              fml::Status retry_status = DoConvertImageToRasterImpeller(
                  dl_image, encode_task, is_gpu_disabled_sync_switch,
                  impeller_context);
              if (!retry_status.ok()) {
                // The retry failed for some reason, maybe the GPU became
                // unavailable again. Don't retry again, just fail in this case.
                encode_task(retry_status);
              }
            };
            // If a `retry_runner` is specified, post the retry to it, otherwise
            // execute it directly.
            if (retry_runner) {
              retry_runner->PostTask(retry_task);
            } else {
              retry_task();
            }
          });
    } else {
      // Pass on errors that are not `kUnavailable`.
      encode_task(status);
    }
  }
}

}  // namespace

void ImageEncodingImpeller::ConvertDlImageToSkImage(
    const sk_sp<DlImage>& dl_image,
    std::function<void(fml::StatusOr<sk_sp<SkImage>>)> encode_task,
    const std::shared_ptr<impeller::Context>& impeller_context) {
  auto texture = dl_image->impeller_texture();

  if (impeller_context == nullptr) {
    encode_task(fml::Status(fml::StatusCode::kFailedPrecondition,
                            "Impeller context was null."));
    return;
  }

  if (texture == nullptr) {
    encode_task(
        fml::Status(fml::StatusCode::kFailedPrecondition, "Image was null."));
    return;
  }

  auto dimensions = dl_image->dimensions();
  auto color_type = ToSkColorType(texture->GetTextureDescriptor().format);

  if (dimensions.isEmpty()) {
    encode_task(fml::Status(fml::StatusCode::kFailedPrecondition,
                            "Image dimensions were empty."));
    return;
  }

  if (!color_type.has_value()) {
    encode_task(fml::Status(fml::StatusCode::kUnimplemented,
                            "Failed to get color type from pixel format."));
    return;
  }

  impeller::DeviceBufferDescriptor buffer_desc;
  buffer_desc.storage_mode = impeller::StorageMode::kHostVisible;
  buffer_desc.readback = true;  // set to false for testing.
  buffer_desc.size =
      texture->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
  auto buffer =
      impeller_context->GetResourceAllocator()->CreateBuffer(buffer_desc);
  auto command_buffer = impeller_context->CreateCommandBuffer();
  command_buffer->SetLabel("BlitTextureToBuffer Command Buffer");
  auto pass = command_buffer->CreateBlitPass();
  pass->SetLabel("BlitTextureToBuffer Blit Pass");
  pass->AddCopy(texture, buffer);
  pass->EncodeCommands(impeller_context->GetResourceAllocator());
  auto completion = [buffer, color_type = color_type.value(), dimensions,
                     encode_task = std::move(encode_task)](
                        impeller::CommandBuffer::Status status) {
    if (status != impeller::CommandBuffer::Status::kCompleted) {
      encode_task(fml::Status(fml::StatusCode::kUnknown, ""));
      return;
    }
    buffer->Invalidate();
    auto sk_image = ConvertBufferToSkImage(buffer, color_type, dimensions);
    encode_task(sk_image);
  };

  if (!impeller_context->GetCommandQueue()
           ->Submit({command_buffer}, completion)
           .ok()) {
    FML_LOG(ERROR) << "Failed to submit commands.";
  }
}

void ImageEncodingImpeller::ConvertImageToRaster(
    const sk_sp<DlImage>& dl_image,
    std::function<void(fml::StatusOr<sk_sp<SkImage>>)> encode_task,
    const fml::RefPtr<fml::TaskRunner>& raster_task_runner,
    const fml::RefPtr<fml::TaskRunner>& io_task_runner,
    const std::shared_ptr<const fml::SyncSwitch>& is_gpu_disabled_sync_switch,
    const std::shared_ptr<impeller::Context>& impeller_context) {
  auto original_encode_task = std::move(encode_task);
  encode_task = [original_encode_task = std::move(original_encode_task),
                 io_task_runner](fml::StatusOr<sk_sp<SkImage>> image) mutable {
    fml::TaskRunner::RunNowOrPostTask(
        io_task_runner,
        [original_encode_task = std::move(original_encode_task),
         image = std::move(image)]() { original_encode_task(image); });
  };

  if (dl_image->owning_context() != DlImage::OwningContext::kRaster) {
    DoConvertImageToRasterImpellerWithRetry(dl_image, std::move(encode_task),
                                            is_gpu_disabled_sync_switch,
                                            impeller_context,
                                            /*retry_runner=*/nullptr);
    return;
  }

  raster_task_runner->PostTask([dl_image, encode_task = std::move(encode_task),
                                io_task_runner, is_gpu_disabled_sync_switch,
                                impeller_context,
                                raster_task_runner]() mutable {
    DoConvertImageToRasterImpellerWithRetry(
        dl_image, std::move(encode_task), is_gpu_disabled_sync_switch,
        impeller_context, raster_task_runner);
  });
}

int ImageEncodingImpeller::GetColorSpace(
    const std::shared_ptr<impeller::Texture>& texture) {
  const impeller::TextureDescriptor& desc = texture->GetTextureDescriptor();
  switch (desc.format) {
    case impeller::PixelFormat::kB10G10R10XR:  // intentional_fallthrough
    case impeller::PixelFormat::kR16G16B16A16Float:
      return ColorSpace::kExtendedSRGB;
    default:
      return ColorSpace::kSRGB;
  }
}

}  // namespace flutter
