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

#include <algorithm>
#include <vector>

#include "flutter/flow/layers/layer_tree.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"

namespace flutter_runner {

class ScopedFrame final : public flutter::CompositorContext::ScopedFrame {
 public:
  ScopedFrame(CompositorContext& context,
              GrDirectContext* gr_context,
              SkCanvas* canvas,
              flutter::ExternalViewEmbedder* view_embedder,
              const SkMatrix& root_surface_transformation,
              bool instrumentation_enabled,
              bool surface_supports_readback,
              fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger,
              DefaultSessionConnection& session_connection,
              VulkanSurfaceProducer& surface_producer,
              std::shared_ptr<flutter::SceneUpdateContext> scene_update_context)
      : flutter::CompositorContext::ScopedFrame(context,
                                                surface_producer.gr_context(),
                                                canvas,
                                                view_embedder,
                                                root_surface_transformation,
                                                instrumentation_enabled,
                                                surface_supports_readback,
                                                raster_thread_merger),
        session_connection_(session_connection),
        surface_producer_(surface_producer),
        scene_update_context_(scene_update_context) {}

 private:
  DefaultSessionConnection& session_connection_;
  VulkanSurfaceProducer& surface_producer_;
  std::shared_ptr<flutter::SceneUpdateContext> scene_update_context_;

  flutter::RasterStatus Raster(flutter::LayerTree& layer_tree,
                               bool ignore_raster_cache) override {
    std::vector<flutter::SceneUpdateContext::PaintTask> frame_paint_tasks;
    std::vector<std::unique_ptr<SurfaceProducerSurface>> frame_surfaces;

    {
      // Preroll the Flutter layer tree. This allows Flutter to perform
      // pre-paint optimizations.
      TRACE_EVENT0("flutter", "Preroll");
      layer_tree.Preroll(*this, ignore_raster_cache);
    }

    {
      // Traverse the Flutter layer tree so that the necessary session ops to
      // represent the frame are enqueued in the underlying session.
      TRACE_EVENT0("flutter", "UpdateScene");
      layer_tree.UpdateScene(scene_update_context_);
    }

    {
      // Flush all pending session ops: create surfaces and enqueue session
      // Image ops for the frame's paint tasks, then Present.
      TRACE_EVENT0("flutter", "SessionPresent");
      frame_paint_tasks = scene_update_context_->GetPaintTasks();

      const SkISize& frame_size = layer_tree.frame_size();
      for (auto& task : frame_paint_tasks) {
        // Clamp the logical size to the logical frame size in order to avoid
        // huge surfaces.
        const SkISize logical_size = SkISize::Make(
            std::clamp(task.scale_x * task.paint_bounds.width(), 0.f,
                       static_cast<float>(frame_size.width())),
            std::clamp(task.scale_y * task.paint_bounds.height(), 0.f,
                       static_cast<float>(frame_size.height())));

        SkISize physical_size = SkISize::Make(
            layer_tree.device_pixel_ratio() * logical_size.width(),
            layer_tree.device_pixel_ratio() * logical_size.height());
        if (physical_size.width() == 0 || physical_size.height() == 0) {
          frame_surfaces.emplace_back(nullptr);
          continue;
        }

        std::unique_ptr<SurfaceProducerSurface> surface =
            surface_producer_.ProduceSurface(physical_size);
        if (!surface) {
          FML_LOG(ERROR)
              << "Could not acquire a surface from the surface producer "
                 "of size: "
              << physical_size.width() << "x" << physical_size.height();
        } else {
          task.material.SetTexture(surface->GetImageId());
        }

        frame_surfaces.emplace_back(std::move(surface));
      }

      session_connection_.Present();
    }

    {
      // Execute paint tasks in parallel with Scenic's side of the Present, then
      // signal fences.
      TRACE_EVENT0("flutter", "ExecutePaintTasks");
      size_t surface_index = 0;
      for (auto& task : frame_paint_tasks) {
        std::unique_ptr<SurfaceProducerSurface>& task_surface =
            frame_surfaces[surface_index++];
        if (!task_surface) {
          continue;
        }

        SkCanvas* canvas = task_surface->GetSkiaSurface()->getCanvas();
        flutter::Layer::PaintContext paint_context = {
            canvas,
            canvas,
            gr_context(),
            nullptr,
            context().raster_time(),
            context().ui_time(),
            context().texture_registry(),
            &context().raster_cache(),
            false,
            layer_tree.device_pixel_ratio()};
        canvas->restoreToCount(1);
        canvas->save();
        canvas->clear(task.background_color);
        canvas->scale(layer_tree.device_pixel_ratio() * task.scale_x,
                      layer_tree.device_pixel_ratio() * task.scale_y);
        canvas->translate(-task.paint_bounds.left(), -task.paint_bounds.top());
        for (flutter::Layer* layer : task.layers) {
          layer->Paint(paint_context);
        }
      }

      // Tell the surface producer that a present has occurred so it can perform
      // book-keeping on buffer caches.
      surface_producer_.OnSurfacesPresented(std::move(frame_surfaces));
    }

    return flutter::RasterStatus::kSuccess;
  }

  FML_DISALLOW_COPY_AND_ASSIGN(ScopedFrame);
};

CompositorContext::CompositorContext(
    DefaultSessionConnection& session_connection,
    VulkanSurfaceProducer& surface_producer,
    std::shared_ptr<flutter::SceneUpdateContext> scene_update_context)
    : session_connection_(session_connection),
      surface_producer_(surface_producer),
      scene_update_context_(scene_update_context) {}

CompositorContext::~CompositorContext() = default;

std::unique_ptr<flutter::CompositorContext::ScopedFrame>
CompositorContext::AcquireFrame(
    GrDirectContext* gr_context,
    SkCanvas* canvas,
    flutter::ExternalViewEmbedder* view_embedder,
    const SkMatrix& root_surface_transformation,
    bool instrumentation_enabled,
    bool surface_supports_readback,
    fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
  return std::make_unique<flutter_runner::ScopedFrame>(
      *this, gr_context, canvas, view_embedder, root_surface_transformation,
      instrumentation_enabled, surface_supports_readback, raster_thread_merger,
      session_connection_, surface_producer_, scene_update_context_);
}

}  // namespace flutter_runner
