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

#include "flutter/lib/ui/painting/image.h"

namespace flutter {

void ConvertImageToRasterSkia(
    const sk_sp<DlImage>& dl_image,
    std::function<void(sk_sp<SkImage>)> encode_task,
    const fml::RefPtr<fml::TaskRunner>& raster_task_runner,
    const fml::RefPtr<fml::TaskRunner>& io_task_runner,
    const fml::WeakPtr<GrDirectContext>& resource_context,
    const fml::TaskRunnerAffineWeakPtr<SnapshotDelegate>& snapshot_delegate,
    const std::shared_ptr<const fml::SyncSwitch>& is_gpu_disabled_sync_switch) {
  // If the owning_context is kRaster, we can't access it on this task runner.
  if (dl_image->owning_context() != DlImage::OwningContext::kRaster) {
    auto image = dl_image->skia_image();

    // Check validity of the image.
    if (image == nullptr) {
      FML_LOG(ERROR) << "Image was null.";
      encode_task(nullptr);
      return;
    }

    auto dimensions = image->dimensions();

    if (dimensions.isEmpty()) {
      FML_LOG(ERROR) << "Image dimensions were empty.";
      encode_task(nullptr);
      return;
    }

    SkPixmap pixmap;
    if (image->peekPixels(&pixmap)) {
      // This is already a raster image.
      encode_task(image);
      return;
    }

    if (sk_sp<SkImage> raster_image = image->makeRasterImage()) {
      // The image can be converted to a raster image.
      encode_task(raster_image);
      return;
    }
  }

  if (!raster_task_runner) {
    FML_LOG(ERROR) << "Raster task runner was null.";
    encode_task(nullptr);
    return;
  }

  if (!io_task_runner) {
    FML_LOG(ERROR) << "IO task runner was null.";
    encode_task(nullptr);
    return;
  }

  // Cross-context images do not support makeRasterImage. Convert these images
  // by drawing them into a surface.  This must be done on the raster thread
  // to prevent concurrent usage of the image on both the IO and raster threads.
  raster_task_runner->PostTask([dl_image, encode_task = std::move(encode_task),
                                resource_context, snapshot_delegate,
                                io_task_runner, is_gpu_disabled_sync_switch,
                                raster_task_runner]() {
    auto image = dl_image->skia_image();
    if (!image || !snapshot_delegate) {
      io_task_runner->PostTask(
          [encode_task = encode_task]() mutable { encode_task(nullptr); });
      return;
    }

    sk_sp<SkImage> raster_image =
        snapshot_delegate->ConvertToRasterImage(image);

    io_task_runner->PostTask([image, encode_task = encode_task,
                              raster_image = std::move(raster_image),
                              resource_context, is_gpu_disabled_sync_switch,
                              owning_context = dl_image->owning_context(),
                              raster_task_runner]() mutable {
      if (!raster_image) {
        // The rasterizer was unable to render the cross-context image
        // (presumably because it does not have a GrContext).  In that case,
        // convert the image on the IO thread using the resource context.
        raster_image = ConvertToRasterUsingResourceContext(
            image, resource_context, is_gpu_disabled_sync_switch);
      }
      encode_task(raster_image);
      if (owning_context == DlImage::OwningContext::kRaster) {
        raster_task_runner->PostTask([image = std::move(image)]() {});
      }
    });
  });
}

}  // namespace flutter
